summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZachary Copley <zcopley@danube.local>2010-04-20 11:29:13 -0700
committerZach Copley <zach@status.net>2010-05-07 10:10:30 -0700
commitb407665b983297078f5361db24c60a7d46e0f4ba (patch)
treeb062bf9534be38c6f82e8a3a9a780e76121f9da3
parent4b0458801af03b40fa636849da0a7e96bbd3e860 (diff)
Initial work on API method for updating a group's profile info
-rw-r--r--actions/apigroupprofileupdate.php370
-rw-r--r--lib/router.php6
2 files changed, 376 insertions, 0 deletions
diff --git a/actions/apigroupprofileupdate.php b/actions/apigroupprofileupdate.php
new file mode 100644
index 000000000..0d3620c26
--- /dev/null
+++ b/actions/apigroupprofileupdate.php
@@ -0,0 +1,370 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Update a group's profile
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category API
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+require_once INSTALLDIR . '/lib/apiauth.php';
+
+class ApiValidationException extends Exception { }
+
+/**
+ * API analog to the group edit page
+ *
+ * @category API
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+class ApiGroupProfileUpdateAction extends ApiAuthAction
+{
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ *
+ */
+
+ function prepare($args)
+ {
+ parent::prepare($args);
+
+ $this->nickname = common_canonical_nickname($this->trimmed('nickname'));
+ $this->fullname = $this->trimmed('fullname');
+ $this->homepage = $this->trimmed('homepage');
+ $this->description = $this->trimmed('description');
+ $this->location = $this->trimmed('location');
+ $this->aliasstring = $this->trimmed('aliases');
+
+ $this->user = $this->auth_user;
+ $this->group = $this->getTargetGroup($this->arg('id'));
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * See which request params have been set, and update the profile
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
+
+ function handle($args)
+ {
+ parent::handle($args);
+
+ if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+ $this->clientError(
+ _('This method requires a POST.'),
+ 400, $this->format
+ );
+ return;
+ }
+
+ if (!in_array($this->format, array('xml', 'json'))) {
+ $this->clientError(
+ _('API method not found.'),
+ 404,
+ $this->format
+ );
+ return;
+ }
+
+ if (empty($this->user)) {
+ $this->clientError(_('No such user.'), 404, $this->format);
+ return;
+ }
+
+ if (empty($this->group)) {
+ $this->clientError(_('Group not found.'), 404, $this->format);
+ return false;
+ }
+
+ if (!$this->user->isAdmin($this->group)) {
+ $this->clientError(_('You must be an admin to edit the group.'), 403);
+ return false;
+ }
+
+ $this->group->query('BEGIN');
+
+ $orig = clone($this->group);
+
+ try {
+
+ if (!empty($this->nickname)) {
+ if ($this->validateNickname()) {
+ $this->group->nickname = $this->nickname;
+ $this->group->mainpage = common_local_url(
+ 'showgroup',
+ array('nickname' => $this->nickname)
+ );
+ }
+ }
+
+ if (!empty($this->fullname)) {
+ $this->validateFullname();
+ $this->group->fullname = $this->fullname;
+ }
+
+ if (!empty($this->homepage)) {
+ $this->validateHomepage();
+ $this->group->homepage = $this->hompage;
+ }
+
+ if (!empty($this->description)) {
+ $this->validateDescription();
+ $this->group->description = $this->decription;
+ }
+
+ if (!empty($this->location)) {
+ $this->validateLocation();
+ $this->group->location = $this->location;
+ }
+
+ } catch (ApiValidationException $ave) {
+ $this->clientError(
+ $ave->getMessage(),
+ 403,
+ $this->format
+ );
+ return;
+ }
+
+ $result = $this->group->update($orig);
+
+ if (!$result) {
+ common_log_db_error($this->group, 'UPDATE', __FILE__);
+ $this->serverError(_('Could not update group.'));
+ }
+
+ $aliases = null;
+
+ try {
+
+ if (!empty($this->aliasstring)) {
+ $aliases = $this->parseAliases();
+ }
+
+ } catch (ApiValidationException $ave) {
+ $this->clientError(
+ $ave->getMessage(),
+ 403,
+ $this->format
+ );
+ return;
+ }
+
+ $result = $this->group->setAliases($aliases);
+
+ if (!$result) {
+ $this->serverError(_('Could not create aliases.'));
+ }
+
+ if (!empty($this->nickname) && $this->nickname != $orig->nickname) {
+ common_log(LOG_INFO, "Saving local group info.");
+ $local = Local_group::staticGet('group_id', $this->group->id);
+ $local->setNickname($this->nickname);
+ }
+
+ $this->group->query('COMMIT');
+
+ switch($this->format) {
+ case 'xml':
+ $this->showSingleXmlGroup($this->group);
+ break;
+ case 'json':
+ $this->showSingleJsonGroup($this->group);
+ break;
+ default:
+ $this->clientError(_('API method not found.'), 404, $this->format);
+ break;
+ }
+ }
+
+ function nicknameExists($nickname)
+ {
+ $group = Local_group::staticGet('nickname', $nickname);
+
+ if (!empty($group) &&
+ $group->group_id != $this->group->id) {
+ return true;
+ }
+
+ $alias = Group_alias::staticGet('alias', $nickname);
+
+ if (!empty($alias) &&
+ $alias->group_id != $this->group->id) {
+ return true;
+ }
+
+ return false;
+ }
+
+ function validateNickname()
+ {
+ if (!Validate::string(
+ $this->nickname, array(
+ 'min_length' => 1,
+ 'max_length' => 64,
+ 'format' => NICKNAME_FMT
+ )
+ )
+ ) {
+ throw new ApiValidationException(
+ _(
+ 'Nickname must have only lowercase letters ' .
+ 'and numbers and no spaces.'
+ )
+ );
+ } else if ($this->nicknameExists($this->nickname)) {
+ throw new ApiValidationException(
+ _('Nickname already in use. Try another one.')
+ );
+ } else if (!User_group::allowedNickname($this->nickname)) {
+ throw new ApiValidationException(
+ _('Not a valid nickname.')
+ );
+ }
+ }
+
+ function validateHomepage()
+ {
+ if (!is_null($this->homepage)
+ && (strlen($this->homepage) > 0)
+ && !Validate::uri(
+ $this->homepage,
+ array('allowed_schemes' => array('http', 'https')
+ )
+ )
+ ) {
+ throw new ApiValidationException(
+ _('Homepage is not a valid URL.')
+ );
+ }
+ }
+
+ function validateFullname()
+ {
+ if (!is_null($this->fullname) && mb_strlen($this->fullname) > 255) {
+ throw new ApiValidationException(
+ _('Full name is too long (max 255 chars).')
+ );
+ }
+ }
+
+ function validateDescription()
+ {
+ if (User_group::descriptionTooLong($this->description)) {
+ throw new ApiValidationException(
+ sprintf(
+ _('description is too long (max %d chars).'),
+ User_group::maxDescription()
+ )
+ );
+ }
+ }
+
+ function validateLocation()
+ {
+ if (!is_null($this->location) && mb_strlen($this->location) > 255) {
+ throw new ApiValidationException(
+ _('Location is too long (max 255 chars).')
+ );
+ }
+ }
+
+ function validateAliases()
+ {
+ $aliases = array_map(
+ 'common_canonical_nickname',
+ array_unique(
+ preg_split('/[\s,]+/',
+ $this->aliasstring
+ )
+ )
+ );
+
+ if (empty($aliases)) {
+ $aliases = array();
+ }
+
+ if (count($aliases) > common_config('group', 'maxaliases')) {
+ throw new ApiValidationException(
+ sprintf(
+ _('Too many aliases! Maximum %d.'),
+ common_config('group', 'maxaliases')
+ )
+ );
+ }
+
+ foreach ($aliases as $alias) {
+ if (!Validate::string(
+ $alias, array(
+ 'min_length' => 1,
+ 'max_length' => 64,
+ 'format' => NICKNAME_FMT)
+ )
+ ) {
+ throw new ApiValidationException(
+ sprintf(
+ _('Invalid alias: "%s"'),
+ $alias
+ )
+ );
+ }
+
+ if ($this->nicknameExists($alias)) {
+ throw new ApiValidationException(
+ sprintf(
+ _('Alias "%s" already in use. Try another one.'),
+ $alias)
+ );
+ }
+
+ // XXX assumes alphanum nicknames
+ if (strcmp($alias, $nickname) == 0) {
+ throw new ApiValidationException(
+ _('Alias can\'t be the same as nickname.')
+ );
+ }
+ }
+
+ return $aliases;
+ }
+
+} \ No newline at end of file
diff --git a/lib/router.php b/lib/router.php
index a040abb83..faa26c861 100644
--- a/lib/router.php
+++ b/lib/router.php
@@ -650,6 +650,12 @@ class Router
$m->connect('api/statusnet/groups/create.:format',
array('action' => 'ApiGroupCreate',
'format' => '(xml|json)'));
+
+ $m->connect('api/statusnet/groups/update/:id.:format',
+ array('action' => 'ApiGroupProfileUpdate',
+ 'id' => '[a-zA-Z0-9]+',
+ 'format' => '(xml|json)'));
+
// Tags
$m->connect('api/statusnet/tags/timeline/:tag.:format',
array('action' => 'ApiTimelineTag',