EndCloseNoticeListItemElement: After the closing </li> of a notice list element
- $nli: The notice list item being shown
+
+StartGroupEditFormData: Beginning the group edit form entries
+- $form: The form widget being shown
+
+EndGroupEditFormData: Ending the group edit form entries
+- $form: The form widget being shown
+
+StartGroupSave: After initializing but before saving a group
+- &$group: group about to be saved
+
+EndGroupSave: After saving a group, aliases, and first member
+- $group: group that was saved
return;
}
- $nickname = Nickname::normalize($this->trimmed('nickname'));
- $fullname = $this->trimmed('fullname');
- $homepage = $this->trimmed('homepage');
- $description = $this->trimmed('description');
- $location = $this->trimmed('location');
- $aliasstring = $this->trimmed('aliases');
-
- if ($this->nicknameExists($nickname)) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Nickname already in use. Try another one.'));
- return;
- } else if (!User_group::allowedNickname($nickname)) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Not a valid nickname.'));
- return;
- } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
- !Validate::uri($homepage,
- array('allowed_schemes' =>
- array('http', 'https')))) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Homepage is not a valid URL.'));
- return;
- } else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Full name is too long (maximum 255 characters).'));
- return;
- } else if (User_group::descriptionTooLong($description)) {
- $this->showForm(sprintf(
- // TRANS: Group edit form validation error.
- _m('Description is too long (maximum %d character).',
- 'Description is too long (maximum %d characters).',
- User_group::maxDescription()),
- User_group::maxDescription()));
- return;
- } else if (!is_null($location) && mb_strlen($location) > 255) {
- // TRANS: Group edit form validation error.
- $this->showForm(_('Location is too long (maximum 255 characters).'));
- return;
- }
+ if (Event::handle('StartGroupSaveForm', array($this))) {
- if (!empty($aliasstring)) {
- $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring)));
- } else {
- $aliases = array();
- }
+ $nickname = Nickname::normalize($this->trimmed('nickname'));
+ $fullname = $this->trimmed('fullname');
+ $homepage = $this->trimmed('homepage');
+ $description = $this->trimmed('description');
+ $location = $this->trimmed('location');
+ $aliasstring = $this->trimmed('aliases');
- if (count($aliases) > common_config('group', 'maxaliases')) {
- // TRANS: Group edit form validation error.
- // TRANS: %d is the maximum number of allowed aliases.
- $this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.',
- 'Too many aliases! Maximum %d allowed.',
- common_config('group', 'maxaliases')),
- common_config('group', 'maxaliases')));
- return;
- }
-
- foreach ($aliases as $alias) {
- if (!Nickname::isValid($alias)) {
+ if ($this->nicknameExists($nickname)) {
// TRANS: Group edit form validation error.
- $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias));
+ $this->showForm(_('Nickname already in use. Try another one.'));
return;
- }
- if ($this->nicknameExists($alias)) {
+ } else if (!User_group::allowedNickname($nickname)) {
+ // TRANS: Group edit form validation error.
+ $this->showForm(_('Not a valid nickname.'));
+ return;
+ } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
+ !Validate::uri($homepage,
+ array('allowed_schemes' =>
+ array('http', 'https')))) {
+ // TRANS: Group edit form validation error.
+ $this->showForm(_('Homepage is not a valid URL.'));
+ return;
+ } else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
// TRANS: Group edit form validation error.
- $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'),
- $alias));
+ $this->showForm(_('Full name is too long (maximum 255 characters).'));
+ return;
+ } else if (User_group::descriptionTooLong($description)) {
+ $this->showForm(sprintf(
+ // TRANS: Group edit form validation error.
+ _m('Description is too long (maximum %d character).',
+ 'Description is too long (maximum %d characters).',
+ User_group::maxDescription()),
+ User_group::maxDescription()));
+ return;
+ } else if (!is_null($location) && mb_strlen($location) > 255) {
+ // TRANS: Group edit form validation error.
+ $this->showForm(_('Location is too long (maximum 255 characters).'));
return;
}
- // XXX assumes alphanum nicknames
- if (strcmp($alias, $nickname) == 0) {
+
+ if (!empty($aliasstring)) {
+ $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring)));
+ } else {
+ $aliases = array();
+ }
+
+ if (count($aliases) > common_config('group', 'maxaliases')) {
// TRANS: Group edit form validation error.
- $this->showForm(_('Alias can\'t be the same as nickname.'));
+ // TRANS: %d is the maximum number of allowed aliases.
+ $this->showForm(sprintf(_m('Too many aliases! Maximum %d allowed.',
+ 'Too many aliases! Maximum %d allowed.',
+ common_config('group', 'maxaliases')),
+ common_config('group', 'maxaliases')));
return;
}
- }
- $this->group->query('BEGIN');
+ foreach ($aliases as $alias) {
+ if (!Nickname::isValid($alias)) {
+ // TRANS: Group edit form validation error.
+ $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias));
+ return;
+ }
+ if ($this->nicknameExists($alias)) {
+ // TRANS: Group edit form validation error.
+ $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'),
+ $alias));
+ return;
+ }
+ // XXX assumes alphanum nicknames
+ if (strcmp($alias, $nickname) == 0) {
+ // TRANS: Group edit form validation error.
+ $this->showForm(_('Alias can\'t be the same as nickname.'));
+ return;
+ }
+ }
+
+ $this->group->query('BEGIN');
- $orig = clone($this->group);
+ $orig = clone($this->group);
- $this->group->nickname = $nickname;
- $this->group->fullname = $fullname;
- $this->group->homepage = $homepage;
- $this->group->description = $description;
- $this->group->location = $location;
- $this->group->mainpage = common_local_url('showgroup', array('nickname' => $nickname));
+ $this->group->nickname = $nickname;
+ $this->group->fullname = $fullname;
+ $this->group->homepage = $homepage;
+ $this->group->description = $description;
+ $this->group->location = $location;
+ $this->group->mainpage = common_local_url('showgroup', array('nickname' => $nickname));
- $result = $this->group->update($orig);
+ $result = $this->group->update($orig);
- if (!$result) {
- common_log_db_error($this->group, 'UPDATE', __FILE__);
- // TRANS: Server error displayed when editing a group fails.
- $this->serverError(_('Could not update group.'));
- }
+ if (!$result) {
+ common_log_db_error($this->group, 'UPDATE', __FILE__);
+ // TRANS: Server error displayed when editing a group fails.
+ $this->serverError(_('Could not update group.'));
+ }
- $result = $this->group->setAliases($aliases);
+ $result = $this->group->setAliases($aliases);
- if (!$result) {
- // TRANS: Server error displayed when group aliases could not be added.
- $this->serverError(_('Could not create aliases.'));
- }
+ if (!$result) {
+ // TRANS: Server error displayed when group aliases could not be added.
+ $this->serverError(_('Could not create aliases.'));
+ }
- if ($nickname != $orig->nickname) {
- common_log(LOG_INFO, "Saving local group info.");
- $local = Local_group::staticGet('group_id', $this->group->id);
- $local->setNickname($nickname);
- }
+ if ($nickname != $orig->nickname) {
+ common_log(LOG_INFO, "Saving local group info.");
+ $local = Local_group::staticGet('group_id', $this->group->id);
+ $local->setNickname($nickname);
+ }
- $this->group->query('COMMIT');
+ $this->group->query('COMMIT');
+
+ Event::handle('EndGroupSaveForm', array($this));
+ }
if ($this->group->nickname != $orig->nickname) {
common_redirect(common_local_url('editgroup',
$group->mainpage = $mainpage;
$group->created = common_sql_now();
- $result = $group->insert();
+ if (Event::handle('StartGroupSave', array(&$group))) {
- if (!$result) {
- common_log_db_error($group, 'INSERT', __FILE__);
- // TRANS: Server exception thrown when creating a group failed.
- throw new ServerException(_('Could not create group.'));
- }
+ $result = $group->insert();
- if (!isset($uri) || empty($uri)) {
- $orig = clone($group);
- $group->uri = common_local_url('groupbyid', array('id' => $group->id));
- $result = $group->update($orig);
if (!$result) {
- common_log_db_error($group, 'UPDATE', __FILE__);
- // TRANS: Server exception thrown when updating a group URI failed.
- throw new ServerException(_('Could not set group URI.'));
+ common_log_db_error($group, 'INSERT', __FILE__);
+ // TRANS: Server exception thrown when creating a group failed.
+ throw new ServerException(_('Could not create group.'));
}
- }
- $result = $group->setAliases($aliases);
+ if (!isset($uri) || empty($uri)) {
+ $orig = clone($group);
+ $group->uri = common_local_url('groupbyid', array('id' => $group->id));
+ $result = $group->update($orig);
+ if (!$result) {
+ common_log_db_error($group, 'UPDATE', __FILE__);
+ // TRANS: Server exception thrown when updating a group URI failed.
+ throw new ServerException(_('Could not set group URI.'));
+ }
+ }
- if (!$result) {
- // TRANS: Server exception thrown when creating group aliases failed.
- throw new ServerException(_('Could not create aliases.'));
- }
+ $result = $group->setAliases($aliases);
- $member = new Group_member();
+ if (!$result) {
+ // TRANS: Server exception thrown when creating group aliases failed.
+ throw new ServerException(_('Could not create aliases.'));
+ }
- $member->group_id = $group->id;
- $member->profile_id = $userid;
- $member->is_admin = 1;
- $member->created = $group->created;
+ $member = new Group_member();
- $result = $member->insert();
+ $member->group_id = $group->id;
+ $member->profile_id = $userid;
+ $member->is_admin = 1;
+ $member->created = $group->created;
- if (!$result) {
- common_log_db_error($member, 'INSERT', __FILE__);
- // TRANS: Server exception thrown when setting group membership failed.
- throw new ServerException(_('Could not set group membership.'));
- }
+ $result = $member->insert();
- if ($local) {
- $local_group = new Local_group();
+ if (!$result) {
+ common_log_db_error($member, 'INSERT', __FILE__);
+ // TRANS: Server exception thrown when setting group membership failed.
+ throw new ServerException(_('Could not set group membership.'));
+ }
- $local_group->group_id = $group->id;
- $local_group->nickname = $nickname;
- $local_group->created = common_sql_now();
+ if ($local) {
+ $local_group = new Local_group();
- $result = $local_group->insert();
+ $local_group->group_id = $group->id;
+ $local_group->nickname = $nickname;
+ $local_group->created = common_sql_now();
- if (!$result) {
- common_log_db_error($local_group, 'INSERT', __FILE__);
- // TRANS: Server exception thrown when saving local group information failed.
- throw new ServerException(_('Could not save local group info.'));
+ $result = $local_group->insert();
+
+ if (!$result) {
+ common_log_db_error($local_group, 'INSERT', __FILE__);
+ // TRANS: Server exception thrown when saving local group information failed.
+ throw new ServerException(_('Could not save local group info.'));
+ }
}
+
+ $group->query('COMMIT');
+
+ Event::handle('EndGroupSave', array($group));
}
- $group->query('COMMIT');
return $group;
}
}
$this->out->elementStart('ul', 'form_data');
- $this->out->elementStart('li');
- $this->out->hidden('groupid', $id);
- $this->out->input('nickname', _('Nickname'),
- ($this->out->arg('nickname')) ? $this->out->arg('nickname') : $nickname,
- _('1-64 lowercase letters or numbers, no punctuation or spaces.'));
- $this->out->elementEnd('li');
- $this->out->elementStart('li');
- $this->out->input('fullname', _('Full name'),
- ($this->out->arg('fullname')) ? $this->out->arg('fullname') : $fullname);
- $this->out->elementEnd('li');
- $this->out->elementStart('li');
- $this->out->input('homepage', _('Homepage'),
- ($this->out->arg('homepage')) ? $this->out->arg('homepage') : $homepage,
- _('URL of the homepage or blog of the group or topic.'));
- $this->out->elementEnd('li');
- $this->out->elementStart('li');
- $desclimit = User_group::maxDescription();
- if ($desclimit == 0) {
- $descinstr = _('Describe the group or topic');
- } else {
- $descinstr = sprintf(_m('Describe the group or topic in %d character or less.',
- 'Describe the group or topic in %d characters or less.',
- $desclimit),
- $desclimit);
- }
- $this->out->textarea('description', _('Description'),
- ($this->out->arg('description')) ? $this->out->arg('description') : $description,
- $descinstr);
- $this->out->elementEnd('li');
- $this->out->elementStart('li');
- $this->out->input('location', _('Location'),
- ($this->out->arg('location')) ? $this->out->arg('location') : $location,
- _('Location for the group, if any, like "City, State (or Region), Country".'));
- $this->out->elementEnd('li');
- if (common_config('group', 'maxaliases') > 0) {
- $aliases = (empty($this->group)) ? array() : $this->group->getAliases();
+ if (Event::handle('StartGroupEditFormData', array($this))) {
+ $this->out->elementStart('li');
+ $this->out->hidden('groupid', $id);
+ $this->out->input('nickname', _('Nickname'),
+ ($this->out->arg('nickname')) ? $this->out->arg('nickname') : $nickname,
+ _('1-64 lowercase letters or numbers, no punctuation or spaces'));
+ $this->out->elementEnd('li');
+ $this->out->elementStart('li');
+ $this->out->input('fullname', _('Full name'),
+ ($this->out->arg('fullname')) ? $this->out->arg('fullname') : $fullname);
+ $this->out->elementEnd('li');
+ $this->out->elementStart('li');
+ $this->out->input('homepage', _('Homepage'),
+ ($this->out->arg('homepage')) ? $this->out->arg('homepage') : $homepage,
+ _('URL of the homepage or blog of the group or topic.'));
+ $this->out->elementEnd('li');
+ $this->out->elementStart('li');
+ $desclimit = User_group::maxDescription();
+ if ($desclimit == 0) {
+ $descinstr = _('Describe the group or topic');
+ } else {
+ $descinstr = sprintf(_m('Describe the group or topic in %d character or less',
+ 'Describe the group or topic in %d characters or less',
+ $desclimit),
+ $desclimit);
+ }
+ $this->out->textarea('description', _('Description'),
+ ($this->out->arg('description')) ? $this->out->arg('description') : $description,
+ $descinstr);
+ $this->out->elementEnd('li');
$this->out->elementStart('li');
- $this->out->input('aliases', _('Aliases'),
- ($this->out->arg('aliases')) ? $this->out->arg('aliases') :
- (!empty($aliases)) ? implode(' ', $aliases) : '',
- sprintf(_m('Extra nicknames for the group, separated with commas or spaces. Maximum %d alias allowed.',
- 'Extra nicknames for the group, separated with commas or spaces. Maximum %d aliases allowed.',
- common_config('group', 'maxaliases')),
- common_config('group', 'maxaliases')));;
+ $this->out->input('location', _('Location'),
+ ($this->out->arg('location')) ? $this->out->arg('location') : $location,
+ _('Location for the group, if any, like "City, State (or Region), Country".'));
$this->out->elementEnd('li');
+ if (common_config('group', 'maxaliases') > 0) {
+ $aliases = (empty($this->group)) ? array() : $this->group->getAliases();
+ $this->out->elementStart('li');
+ $this->out->input('aliases', _('Aliases'),
+ ($this->out->arg('aliases')) ? $this->out->arg('aliases') :
+ (!empty($aliases)) ? implode(' ', $aliases) : '',
+ sprintf(_m('Extra nicknames for the group, separated with commas or spaces. Maximum %d alias allowed.',
+ 'Extra nicknames for the group, separated with commas or spaces. Maximum %d aliases allowed.',
+ common_config('group', 'maxaliases')),
+ common_config('group', 'maxaliases')));;
+ $this->out->elementEnd('li');
+ }
+ Event::handle('EndGroupEditFormData', array($this));
}
$this->out->elementEnd('ul');
}
--- /dev/null
+<?php
+/**
+ * Data class for group inbox info
+ *
+ * PHP version 5
+ *
+ * @category Data
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
+ * @link http://status.net/
+ *
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * 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/>.
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
+
+/**
+ * Data class for counting greetings
+ *
+ * We use the DB_DataObject framework for data classes in StatusNet. Each
+ * table maps to a particular data class, making it easier to manipulate
+ * data.
+ *
+ * Data classes should extend Memcached_DataObject, the (slightly misnamed)
+ * extension of DB_DataObject that provides caching, internationalization,
+ * and other bits of good functionality to StatusNet-specific data classes.
+ *
+ * @category Action
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
+ * @link http://status.net/
+ *
+ * @see DB_DataObject
+ */
+
+class Group_message extends Memcached_DataObject
+{
+ public $__table = 'user_greeting_count'; // table name
+ public $user_id; // int(4) primary_key not_null
+ public $greeting_count; // int(4)
+
+ /**
+ * Get an instance by key
+ *
+ * This is a utility method to get a single instance with a given key value.
+ *
+ * @param string $k Key to use to lookup (usually 'user_id' for this class)
+ * @param mixed $v Value to lookup
+ *
+ * @return Group_message object found, or null for no hits
+ *
+ */
+ function staticGet($k, $v=null)
+ {
+ return Memcached_DataObject::staticGet('Group_message', $k, $v);
+ }
+
+ /**
+ * return table definition for DB_DataObject
+ *
+ * DB_DataObject needs to know something about the table to manipulate
+ * instances. This method provides all the DB_DataObject needs to know.
+ *
+ * @return array array of column definitions
+ */
+ function table()
+ {
+ return array('user_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+ 'greeting_count' => DB_DATAOBJECT_INT);
+ }
+
+ /**
+ * return key definitions for DB_DataObject
+ *
+ * DB_DataObject needs to know about keys that the table has, since it
+ * won't appear in StatusNet's own keys list. In most cases, this will
+ * simply reference your keyTypes() function.
+ *
+ * @return array list of key field names
+ */
+ function keys()
+ {
+ return array_keys($this->keyTypes());
+ }
+
+ /**
+ * return key definitions for Memcached_DataObject
+ *
+ * Our caching system uses the same key definitions, but uses a different
+ * method to get them. This key information is used to store and clear
+ * cached data, so be sure to list any key that will be used for static
+ * lookups.
+ *
+ * @return array associative array of key definitions, field name to type:
+ * 'K' for primary key: for compound keys, add an entry for each component;
+ * 'U' for unique keys: compound keys are not well supported here.
+ */
+ function keyTypes()
+ {
+ return array('user_id' => 'K');
+ }
+
+ /**
+ * Magic formula for non-autoincrementing integer primary keys
+ *
+ * If a table has a single integer column as its primary key, DB_DataObject
+ * assumes that the column is auto-incrementing and makes a sequence table
+ * to do this incrementation. Since we don't need this for our class, we
+ * overload this method and return the magic formula that DB_DataObject needs.
+ *
+ * @return array magic three-false array that stops auto-incrementing.
+ */
+ function sequenceKey()
+ {
+ return array(false, false, false);
+ }
+
+ /**
+ * Increment a user's greeting count and return instance
+ *
+ * This method handles the ins and outs of creating a new greeting_count for a
+ * user or fetching the existing greeting count and incrementing its value.
+ *
+ * @param integer $user_id ID of the user to get a count for
+ *
+ * @return Group_message instance for this user, with count already incremented.
+ */
+ static function inc($user_id)
+ {
+ $gc = Group_message::staticGet('user_id', $user_id);
+
+ if (empty($gc)) {
+
+ $gc = new Group_message();
+
+ $gc->user_id = $user_id;
+ $gc->greeting_count = 1;
+
+ $result = $gc->insert();
+
+ if (!$result) {
+ // TRANS: Exception thrown when the user greeting count could not be saved in the database.
+ // TRANS: %d is a user ID (number).
+ throw Exception(sprintf(_m("Could not save new greeting count for %d."),
+ $user_id));
+ }
+ } else {
+ $orig = clone($gc);
+
+ $gc->greeting_count++;
+
+ $result = $gc->update($orig);
+
+ if (!$result) {
+ // TRANS: Exception thrown when the user greeting count could not be saved in the database.
+ // TRANS: %d is a user ID (number).
+ throw Exception(sprintf(_m("Could not increment greeting count for %d."),
+ $user_id));
+ }
+ }
+
+ return $gc;
+ }
+}
--- /dev/null
+<?php
+/**
+ * Data class for group privacy settings
+ *
+ * PHP version 5
+ *
+ * @category Data
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
+ * @link http://status.net/
+ *
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2011, StatusNet, Inc.
+ *
+ * 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/>.
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Data class for group privacy
+ *
+ * Stores admin preferences about the group.
+ *
+ * @category Action
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
+ * @link http://status.net/
+ *
+ * @see DB_DataObject
+ */
+
+class Group_privacy_settings extends Memcached_DataObject
+{
+ public $__table = 'group_privacy_settings';
+ /** ID of the group. */
+ public $group_id;
+ /** When to allow privacy: always, sometimes, or never. */
+ public $allow_privacy;
+ /** Who can send private messages: everyone, member, admin */
+ public $allow_sender;
+ /** row creation timestamp */
+ public $created;
+ /** Last-modified timestamp */
+ public $modified;
+
+ /** NEVER is */
+
+ const SOMETIMES = -1;
+ const NEVER = 0;
+ const ALWAYS = 1;
+
+ /** These are bit-mappy, as a hedge against the future. */
+
+ const EVERYONE = 1;
+ const MEMBER = 2;
+ const ADMIN = 4;
+
+ /**
+ * Get an instance by key
+ *
+ * This is a utility method to get a single instance with a given key value.
+ *
+ * @param string $k Key to use to lookup (usually 'user_id' for this class)
+ * @param mixed $v Value to lookup
+ *
+ * @return User_greeting_count object found, or null for no hits
+ */
+
+ function staticGet($k, $v=null)
+ {
+ return Memcached_DataObject::staticGet('Group_privacy_settings', $k, $v);
+ }
+
+ /**
+ * return table definition for DB_DataObject
+ *
+ * DB_DataObject needs to know something about the table to manipulate
+ * instances. This method provides all the DB_DataObject needs to know.
+ *
+ * @return array array of column definitions
+ */
+
+ function table()
+ {
+ return array('group_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+ 'allow_privacy' => DB_DATAOBJECT_INT,
+ 'allow_sender' => DB_DATAOBJECT_INT,
+ 'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
+ 'modified' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL);
+
+ }
+
+ /**
+ * return key definitions for DB_DataObject
+ *
+ * DB_DataObject needs to know about keys that the table has, since it
+ * won't appear in StatusNet's own keys list. In most cases, this will
+ * simply reference your keyTypes() function.
+ *
+ * @return array list of key field names
+ */
+
+ function keys()
+ {
+ return array_keys($this->keyTypes());
+ }
+
+ /**
+ * return key definitions for Memcached_DataObject
+ *
+ * @return array associative array of key definitions, field name to type:
+ * 'K' for primary key: for compound keys, add an entry for each component;
+ * 'U' for unique keys: compound keys are not well supported here.
+ */
+
+ function keyTypes()
+ {
+ return array('group_id' => 'K');
+ }
+
+ /**
+ * Magic formula for non-autoincrementing integer primary keys
+ *
+ * @return array magic three-false array that stops auto-incrementing.
+ */
+
+ function sequenceKey()
+ {
+ return array(false, false, false);
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Private groups for StatusNet 0.9.x
+ *
+ * PHP version 5
+ *
+ * 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 Privacy
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * Private groups
+ *
+ * This plugin allows users to send private messages to a group.
+ *
+ * @category Privacy
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class PrivateGroupPlugin extends Plugin
+{
+ /**
+ * Database schema setup
+ *
+ * @see Schema
+ * @see ColumnDef
+ *
+ * @return boolean hook value
+ */
+
+ function onCheckSchema()
+ {
+ $schema = Schema::get();
+
+ // For storing user-submitted flags on profiles
+
+ $schema->ensureTable('group_privacy_settings',
+ array(new ColumnDef('group_id',
+ 'integer',
+ null,
+ false,
+ 'PRI'),
+ new ColumnDef('allow_privacy',
+ 'integer'),
+ new ColumnDef('allow_sender',
+ 'integer'),
+ new ColumnDef('created',
+ 'datetime'),
+ new ColumnDef('modified',
+ 'timestamp')));
+
+ $schema->ensureTable('group_message',
+ array(new ColumnDef('id',
+ 'char',
+ 36,
+ false,
+ 'PRI'),
+ new ColumnDef('uri',
+ 'varchar',
+ 255,
+ false,
+ 'UNI'),
+ new ColumnDef('from_profile',
+ 'integer',
+ null,
+ false,
+ 'MUL'),
+ new ColumnDef('to_group',
+ 'integer',
+ null,
+ false,
+ 'MUL'),
+ new ColumnDef('content',
+ 'text'),
+ new ColumnDef('rendered',
+ 'text'),
+ new ColumnDef('url',
+ 'varchar',
+ 255,
+ false,
+ 'UNI'),
+ new ColumnDef('created',
+ 'datetime'),
+ new ColumnDef('modified',
+ 'timestamp')));
+
+
+ $schema->ensureTable('group_message_copy',
+ array(new ColumnDef('group_message_id',
+ 'char',
+ 36,
+ false,
+ 'PRI'),
+ new ColumnDef('message_uri',
+ 'varchar',
+ 255,
+ false,
+ 'PRI'),
+ new ColumnDef('created',
+ 'datetime'),
+ new ColumnDef('modified',
+ 'timestamp')));
+
+ return true;
+ }
+
+ /**
+ * Load related modules when needed
+ *
+ * @param string $cls Name of the class to be loaded
+ *
+ * @return boolean hook value
+ */
+
+ function onAutoload($cls)
+ {
+ $dir = dirname(__FILE__);
+
+ switch ($cls)
+ {
+ case 'GroupinboxAction':
+ include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
+ return false;
+ case 'Group_privacy_settings':
+ case 'Group_private_inbox':
+ include_once $dir . '/'.$cls.'.php';
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * Map URLs to actions
+ *
+ * @param Net_URL_Mapper $m path-to-action mapper
+ *
+ * @return boolean hook value
+ */
+
+ function onRouterInitialized($m)
+ {
+ $m->connect('group/:nickname/inbox',
+ array('action' => 'groupinbox'),
+ array('nickname' => Nickname::DISPLAY_FMT));
+
+ return true;
+ }
+
+ /**
+ * Add group inbox to the menu
+ *
+ * @param Action $action The current action handler. Use this to
+ * do any output.
+ *
+ * @return boolean hook value; true means continue processing, false means stop.
+ *
+ * @see Action
+ */
+
+ function onEndGroupGroupNav($groupnav)
+ {
+ $action = $groupnav->action;
+ $group = $groupnav->group;
+
+ $action->menuItem(common_local_url('groupinbox',
+ array('nickname' => $group->nickname)),
+ _m('Inbox'),
+ _m('Private messages for this group'),
+ $action->trimmed('action') == 'groupinbox',
+ 'nav_group_inbox');
+ return true;
+ }
+
+ /**
+ * Create default group privacy settings at group create time
+ *
+ * @param $group Group that was just created
+ *
+ * @result boolean hook value
+ */
+
+ function onEndGroupSave($group)
+ {
+ $gps = new Group_privacy_settings();
+
+ $gps->group_id = $group->id;
+ $gps->allow_privacy = Group_privacy_settings::SOMETIMES;
+ $gps->allow_sender = Group_privacy_settings::MEMBER;
+ $gps->created = common_sql_now();
+ $gps->modified = $gps->created;
+
+ // This will throw an exception on error
+
+ $gps->insert();
+
+ return true;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'PrivateGroup',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:PrivateGroup',
+ 'rawdescription' =>
+ _m('Allow posting DMs to a group.'));
+ return true;
+ }
+}
--- /dev/null
+<?php
+/**
+ * Give a warm greeting to our friendly user
+ *
+ * PHP version 5
+ *
+ * @category Sample
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
+ * @link http://status.net/
+ *
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * 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/>.
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Give a warm greeting to our friendly user
+ *
+ * This sample action shows some basic ways of doing output in an action
+ * class.
+ *
+ * Action classes have several output methods that they override from
+ * the parent class.
+ *
+ * @category Sample
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
+ * @link http://status.net/
+ */
+class HelloAction extends Action
+{
+ var $user = null;
+ var $gc = null;
+
+ /**
+ * Take arguments for running
+ *
+ * This method is called first, and it lets the action class get
+ * all its arguments and validate them. It's also the time
+ * to fetch any relevant data from the database.
+ *
+ * Action classes should run parent::prepare($args) as the first
+ * line of this method to make sure the default argument-processing
+ * happens.
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
+ function prepare($args)
+ {
+ parent::prepare($args);
+
+ $this->user = common_current_user();
+
+ if (!empty($this->user)) {
+ $this->gc = User_greeting_count::inc($this->user->id);
+ }
+
+ return true;
+ }
+
+ /**
+ * Handle request
+ *
+ * This is the main method for handling a request. Note that
+ * most preparation should be done in the prepare() method;
+ * by the time handle() is called the action should be
+ * more or less ready to go.
+ *
+ * @param array $args $_REQUEST args; handled in prepare()
+ *
+ * @return void
+ */
+ function handle($args)
+ {
+ parent::handle($args);
+
+ $this->showPage();
+ }
+
+ /**
+ * Title of this page
+ *
+ * Override this method to show a custom title.
+ *
+ * @return string Title of the page
+ */
+ function title()
+ {
+ if (empty($this->user)) {
+ return _m('Hello');
+ } else {
+ return sprintf(_m('Hello, %s!'), $this->user->nickname);
+ }
+ }
+
+ /**
+ * Show content in the content area
+ *
+ * The default StatusNet page has a lot of decorations: menus,
+ * logos, tabs, all that jazz. This method is used to show
+ * content in the content area of the page; it's the main
+ * thing you want to overload.
+ *
+ * This method also demonstrates use of a plural localized string.
+ *
+ * @return void
+ */
+ function showContent()
+ {
+ if (empty($this->user)) {
+ $this->element('p', array('class' => 'greeting'),
+ _m('Hello, stranger!'));
+ } else {
+ $this->element('p', array('class' => 'greeting'),
+ sprintf(_m('Hello, %s'), $this->user->nickname));
+ $this->element('p', array('class' => 'greeting_count'),
+ sprintf(_m('I have greeted you %d time.',
+ 'I have greeted you %d times.',
+ $this->gc->greeting_count),
+ $this->gc->greeting_count));
+ }
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * Some actions only read from the database; others read and write.
+ * The simple database load-balancer built into StatusNet will
+ * direct read-only actions to database mirrors (if they are configured),
+ * and read-write actions to the master database.
+ *
+ * This defaults to false to avoid data integrity issues, but you
+ * should make sure to overload it for performance gains.
+ *
+ * @param array $args other arguments, if RO/RW status depends on them.
+ *
+ * @return boolean is read only action?
+ */
+ function isReadOnly($args)
+ {
+ return false;
+ }
+}