--- /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 GroupPrivateMessagePlugin 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')));
+
+ $schema->ensureTable('group_message_profile',
+ array(new ColumnDef('to_profile',
+ 'integer',
+ null,
+ false,
+ 'PRI'),
+ new ColumnDef('group_message_id',
+ 'char',
+ 36,
+ false,
+ 'PRI'),
+ new ColumnDef('created',
+ 'datetime')));
+
+ 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':
+ case 'ShowgroupmessageAction':
+ case 'NewgroupmessageAction':
+ include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
+ return false;
+ case 'Group_privacy_settings':
+ case 'Group_message':
+ case 'Group_message_profile':
+ include_once $dir . '/'.$cls.'.php';
+ return false;
+ case 'GroupMessageCommand':
+ case 'GroupMessageList':
+ case 'GroupMessageListItem':
+ case 'GroupMessageForm':
+ include_once $dir . '/'.strtolower($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));
+
+ $m->connect('group/message/:id',
+ array('action' => 'showgroupmessage'),
+ array('id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'));
+
+ $m->connect('group/:nickname/message/new',
+ array('action' => 'newgroupmessage'),
+ 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 User_group $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;
+ }
+
+ /**
+ * Show group privacy controls on group edit form
+ *
+ * @param GroupEditForm $form form being shown
+ */
+
+ function onEndGroupEditFormData($form)
+ {
+ $gps = null;
+
+ if (!empty($form->group)) {
+ $gps = Group_privacy_settings::staticGet('group_id', $form->group->id);
+ }
+
+ $form->out->elementStart('li');
+ $form->out->dropdown('allow_privacy',
+ _('Private messages'),
+ array(Group_privacy_settings::SOMETIMES => _('Sometimes'),
+ Group_privacy_settings::ALWAYS => _('Always'),
+ Group_privacy_settings::NEVER => _('Never')),
+ _('Whether to allow private messages to this group'),
+ false,
+ (empty($gps)) ? Group_privacy_settings::SOMETIMES : $gps->allow_privacy);
+ $form->out->elementEnd('li');
+ $form->out->elementStart('li');
+ $form->out->dropdown('allow_sender',
+ _('Private sender'),
+ array(Group_privacy_settings::EVERYONE => _('Everyone'),
+ Group_privacy_settings::MEMBER => _('Member'),
+ Group_privacy_settings::ADMIN => _('Admin')),
+ _('Who can send private messages to the group'),
+ false,
+ (empty($gps)) ? Group_privacy_settings::MEMBER : $gps->allow_sender);
+ $form->out->elementEnd('li');
+ return true;
+ }
+
+ function onEndGroupSaveForm($action)
+ {
+ $gps = null;
+
+ if (!empty($action->group)) {
+ $gps = Group_privacy_settings::staticGet('group_id', $action->group->id);
+ }
+
+ $orig = null;
+
+ if (empty($gps)) {
+ $gps = new Group_privacy_settings();
+ $gps->group_id = $action->group->id;
+ } else {
+ $orig = clone($gps);
+ }
+
+ $gps->allow_privacy = $action->trimmed('allow_privacy');
+ $gps->allow_sender = $action->trimmed('allow_sender');
+
+ if (empty($orig)) {
+ $gps->created = common_sql_now();
+ $gps->insert();
+ } else {
+ $gps->update($orig);
+ }
+
+ return true;
+ }
+
+ /**
+ * Overload 'd' command to send private messages to groups.
+ *
+ * 'd !group word word word' will send the private message
+ * 'word word word' to the group 'group'.
+ *
+ * @param string $cmd Command being run
+ * @param string $arg Rest of the message (including address)
+ * @param User $user User sending the message
+ * @param Command &$result The resulting command object to be run.
+ *
+ * @return boolean hook value
+ */
+ function onStartIntepretCommand($cmd, $arg, $user, &$result)
+ {
+ if ($cmd == 'd' || $cmd == 'dm') {
+
+ $this->debug('Got a d command');
+
+ // Break off the first word as the address
+
+ $pieces = explode(' ', $arg, 2);
+
+ if (count($pieces) == 1) {
+ $pieces[] = null;
+ }
+
+ list($addr, $msg) = $pieces;
+
+ if (!empty($addr) && $addr[0] == '!') {
+ $result = new GroupMessageCommand($user, substr($addr, 1), $msg);
+ Event::handle('EndInterpretCommand', array($cmd, $arg, $user, $result));
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * To add a "Message" button to the group profile page
+ *
+ * @param Action $action The showgroup action being shown
+ * @param User_group $group The current group
+ *
+ * @return boolean hook value
+ */
+ function onEndGroupActionsList($action, $group)
+ {
+ $cur = common_current_user();
+
+ if (empty($cur)) {
+ return true;
+ }
+
+ try {
+ Group_privacy_settings::ensurePost($cur, $group);
+ } catch (Exception $e) {
+ return true;
+ }
+
+ $action->elementStart('li', 'entity_send-a-message');
+ $action->element('a', array('href' => common_local_url('newgroupmessage', array('nickname' => $group->nickname)),
+ 'title' => _('Send a direct message to this group')),
+ _('Message'));
+ // $form = new GroupMessageForm($action, $group);
+ // $form->hidden = true;
+ // $form->show();
+ $action->elementEnd('li');
+ return true;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'GroupPrivateMessage',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:GroupPrivateMessage',
+ 'rawdescription' =>
+ _m('Allow posting DMs to a group.'));
+ return true;
+ }
+}
--- /dev/null
+<?php
+/**
+ * Data class for group direct messages
+ *
+ * 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 group direct messages
+ *
+ * @category PrivateGroup
+ * @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 = 'group_message'; // table name
+ public $id; // char(36) primary_key not_null
+ public $uri; // varchar(255)
+ public $from_profile; // int
+ public $to_group; // int
+ public $content;
+ public $rendered;
+ public $url;
+ public $created;
+
+ /**
+ * 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('id' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
+ 'uri' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
+ 'from_profile' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+ 'to_group' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+ 'content' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
+ 'rendered' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
+ 'url' => DB_DATAOBJECT_STR,
+ 'created' => 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('id' => 'K', 'uri' => 'U');
+ }
+
+ static function send($user, $group, $text)
+ {
+ if (!$user->hasRight(Right::NEWMESSAGE)) {
+ // XXX: maybe break this out into a separate right
+ throw new Exception(sprintf(_('User %s not allowed to send private messages.'),
+ $user->nickname));
+ }
+
+ Group_privacy_settings::ensurePost($user, $group);
+
+ $text = $user->shortenLinks($text);
+
+ // We use the same limits as for 'regular' private messages.
+
+ if (Message::contentTooLong($text)) {
+ throw new Exception(sprintf(_m('That\'s too long. Maximum message size is %d character.',
+ 'That\'s too long. Maximum message size is %d characters.',
+ Message::maxContent()),
+ Message::maxContent()));
+ }
+
+ // Valid! Let's do this thing!
+
+ $gm = new Group_message();
+
+ $gm->id = UUID::gen();
+ $gm->uri = common_local_url('showgroupmessage', array('id' => $gm->id));
+ $gm->from_profile = $user->id;
+ $gm->to_group = $group->id;
+ $gm->content = $text; // XXX: is this cool?!
+ $gm->rendered = common_render_text($text);
+ $gm->url = $gm->uri;
+ $gm->created = common_sql_now();
+
+ // This throws a conniption if there's a problem
+
+ $gm->insert();
+
+ $gm->distribute();
+
+ return $gm;
+ }
+
+ function distribute()
+ {
+ $group = User_group::staticGet('id', $this->to_group);
+
+ $member = $group->getMembers();
+
+ while ($member->fetch()) {
+ Group_message_profile::send($this, $member);
+ }
+ }
+
+ function getGroup()
+ {
+ $group = User_group::staticGet('id', $this->to_group);
+ if (empty($group)) {
+ throw new ServerException(_('No group for group message'));
+ }
+ return $group;
+ }
+
+ function getSender()
+ {
+ $sender = Profile::staticGet('id', $this->from_profile);
+ if (empty($sender)) {
+ throw new ServerException(_('No sender for group message'));
+ }
+ return $sender;
+ }
+
+ static function forGroup($group, $offset, $limit)
+ {
+ // XXX: cache
+ $gm = new Group_message();
+
+ $gm->to_group = $group->id;
+ $gm->orderBy('created DESC');
+ $gm->limit($offset, $limit);
+
+ $gm->find();
+
+ return $gm;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Who received a group message
+ *
+ * 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) 2010, 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 group direct messages for users
+ *
+ * @category PrivateGroup
+ * @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_profile extends Memcached_DataObject
+{
+ public $__table = 'group_message_profile'; // table name
+ public $to_profile; // int
+ public $group_message_id; // char(36) primary_key not_null
+ public $created;
+
+ /**
+ * 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_profile', $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('to_profile' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+ 'group_message_id' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
+ 'created' => 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('to_profile' => 'K', 'group_message_id' => 'K');
+ }
+
+ /**
+ * No sequence keys in this table.
+ */
+ function sequenceKey()
+ {
+ return array(false, false, false);
+ }
+
+ function send($gm, $profile)
+ {
+ $gmp = new Group_message_profile();
+
+ $gmp->group_message_id = $gm->id;
+ $gmp->to_profile = $profile->id;
+ $gmp->created = common_sql_now();
+
+ $gmp->insert();
+
+ $gmp->notify();
+
+ return $gmp;
+ }
+
+ function notify()
+ {
+ // XXX: add more here
+ $this->notifyByMail();
+ }
+
+ function notifyByMail()
+ {
+ $to = User::staticGet('id', $this->to_profile);
+
+ if (empty($to) || is_null($to->email) || !$to->emailnotifymsg) {
+ return true;
+ }
+
+ $gm = Group_message::staticGet('id', $this->group_message_id);
+
+ $from_profile = Profile::staticGet('id', $gm->from_profile);
+
+ $group = $gm->getGroup();
+
+ common_switch_locale($to->language);
+
+ // TRANS: Subject for direct-message notification email.
+ // TRANS: %s is the sending user's nickname.
+ $subject = sprintf(_('New private message from %s to group %s'), $from->nickname, $group->nickname);
+
+ $from_profile = $from->getProfile();
+
+ // TRANS: Body for direct-message notification email.
+ // TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname,
+ // TRANS: %3$s is the message content, %4$s a URL to the message,
+ // TRANS: %5$s is the StatusNet sitename.
+ $body = sprintf(_("%1\$s (%2\$s) sent a private message to group %3\$s:\n\n".
+ "------------------------------------------------------\n".
+ "%4\$s\n".
+ "------------------------------------------------------\n\n".
+ "You can reply to their message here:\n\n".
+ "%5\$s\n\n".
+ "Don't reply to this email; it won't get to them.\n\n".
+ "With kind regards,\n".
+ "%6\$s\n"),
+ $from_profile->getBestName(),
+ $from->nickname,
+ $group->nickname,
+ $this->content,
+ common_local_url('newmessage', array('to' => $from->id)),
+ common_config('site', 'name'));
+
+ $headers = _mail_prepare_headers('message', $to->nickname, $from->nickname);
+
+ common_switch_locale();
+
+ return mail_to_user($to, $subject, $body, $headers);
+ }
+}
--- /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);
+ }
+
+ function ensurePost($user, $group)
+ {
+ $gps = Group_privacy_settings::staticGet('group_id', $group->id);
+
+ if (empty($gps)) {
+ // make a fake one with defaults
+ $gps = new Group_privacy_settings();
+ $gps->allow_privacy = Group_privacy_settings::SOMETIMES;
+ $gps->allow_sender = Group_privacy_settings::MEMBER;
+ }
+
+ if ($gps->allow_privacy == Group_privacy_settings::NEVER) {
+ throw new Exception(sprintf(_('Group %s does not allow private messages.'),
+ $group->nickname));
+ }
+
+ switch ($gps->allow_sender) {
+ case Group_privacy_settings::EVERYONE:
+ $profile = $user->getProfile();
+ if (Group_block::isBlocked($group, $profile)) {
+ throw new Exception(sprintf(_('User %s is blocked from group %s.'),
+ $user->nickname,
+ $group->nickname));
+ }
+ break;
+ case Group_privacy_settings::MEMBER:
+ if (!$user->isMember($group)) {
+ throw new Exception(sprintf(_('User %s is not a member of group %s.'),
+ $user->nickname,
+ $group->nickname));
+ }
+ break;
+ case Group_privacy_settings::ADMIN:
+ if (!$user->isAdmin($group)) {
+ throw new Exception(sprintf(_('User %s is not an administrator of group %s.'),
+ $user->nickname,
+ $group->nickname));
+ }
+ break;
+ default:
+ throw new Exception(sprintf(_('Unknown privacy settings for group %s.'),
+ $group->nickname));
+ }
+
+ return true;
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * List of private messages to this group
+ *
+ * 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 PrivateGroup
+ * @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);
+}
+
+/**
+ * Show a list of private messages to this group
+ *
+ * @category PrivateGroup
+ * @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 GroupinboxAction extends GroupDesignAction
+{
+ var $gm;
+
+ /**
+ * For initializing members of the class.
+ *
+ * @param array $argarray misc. arguments
+ *
+ * @return boolean true
+ */
+ function prepare($argarray)
+ {
+ parent::prepare($argarray);
+
+ $cur = common_current_user();
+
+ if (empty($cur)) {
+ throw new ClientException(_('Only for logged-in users'), 403);
+ }
+
+ $nicknameArg = $this->trimmed('nickname');
+
+ $nickname = common_canonical_nickname($nicknameArg);
+
+ if ($nickname != $nicknameArg) {
+ $url = common_local_url('groupinbox', array('nickname' => $nickname));
+ common_redirect($url);
+ return false;
+ }
+
+ $localGroup = Local_group::staticGet('nickname', $nickname);
+
+ if (empty($localGroup)) {
+ throw new ClientException(_('No such group'), 404);
+ }
+
+ $this->group = User_group::staticGet('id', $localGroup->group_id);
+
+ if (empty($this->group)) {
+ throw new ClientException(_('No such group'), 404);
+ }
+
+ if (!$cur->isMember($this->group)) {
+ throw new ClientException(_('Only for members'), 403);
+ }
+
+ $this->page = $this->trimmed('page');
+
+ if (!$this->page) {
+ $this->page = 1;
+ }
+
+ $this->gm = Group_message::forGroup($this->group,
+ ($this->page - 1) * MESSAGES_PER_PAGE,
+ MESSAGES_PER_PAGE + 1);
+ return true;
+ }
+
+ function showLocalNav()
+ {
+ $nav = new GroupNav($this, $this->group);
+ $nav->show();
+ }
+
+ function showNoticeForm()
+ {
+ $form = new GroupMessageForm($this, $this->group);
+ $form->show();
+ }
+
+ function showContent()
+ {
+ $gml = new GroupMessageList($this, $this->gm);
+ $gml->show();
+ }
+
+ /**
+ * Handler method
+ *
+ * @param array $argarray is ignored since it's now passed in in prepare()
+ *
+ * @return void
+ */
+ function handle($argarray=null)
+ {
+ $this->showPage();
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * MAY override
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean is read only action?
+ */
+ function isReadOnly($args)
+ {
+ return true;
+ }
+
+ /**
+ * Title of the page
+ *
+ * @return string page title, with page number
+ */
+ function title()
+ {
+ $base = $this->group->getFancyName();
+
+ if ($this->page == 1) {
+ return sprintf(_('%s group inbox'), $base);
+ } else {
+ // TRANS: Page title for any but first group page.
+ // TRANS: %1$s is a group name, $2$s is a page number.
+ return sprintf(_('%1$s group inbox, page %2$d'),
+ $base,
+ $this->page);
+ }
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Command object for messages to groups
+ *
+ * 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 Command
+ * @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);
+}
+
+/**
+ * Command object for messages to groups
+ *
+ * @category General
+ * @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 GroupMessageCommand extends Command
+{
+ /** User sending the message. */
+ var $user;
+ /** Nickname of the group they're sending to. */
+ var $nickname;
+ /** Text of the message. */
+ var $text;
+
+ /**
+ * Constructor
+ *
+ * @param User $user User sending the message
+ * @param string $nickname Nickname of the group
+ * @param string $text Text of message
+ */
+
+ function __construct($user, $nickname, $text)
+ {
+ $this->user = $user;
+ $this->nickname = $nickname;
+ $this->text = $text;
+ }
+
+ function handle($channel)
+ {
+ // Throws a command exception if group not found
+ $group = $this->getGroup($this->nickname);
+
+ $gm = Group_message::send($this->user, $group, $this->text);
+
+ $channel->output($this->user,
+ sprintf(_('Direct message to group %s sent.'),
+ $group->nickname));
+
+ return true;
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2011, StatusNet, Inc.
+ *
+ * Form for posting a group message
+ *
+ * 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 PrivateGroup
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2011 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);
+}
+
+/**
+ * Form for posting a group message
+ *
+ * @category PrivateGroup
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class GroupMessageForm extends Form
+{
+ var $group;
+ var $content;
+
+ /**
+ * Constructor
+ *
+ * @param HTMLOutputter $out Output context
+ * @param User_group $group Group to post to
+ *
+ * @todo add a drop-down list to post to any group
+ */
+
+ function __construct($out, $group, $content=null)
+ {
+ parent::__construct($out);
+
+ $this->group = $group;
+ $this->content = $content;
+ }
+
+ /**
+ * Action for the form
+ */
+ function action()
+ {
+ return common_local_url('newgroupmessage',
+ array('nickname' => $this->group->nickname));
+ }
+
+ /**
+ * Legend for the form
+ *
+ * @param
+ *
+ * @return
+ */
+ function formLegend()
+ {
+ $this->out->element('legend',
+ null,
+ sprintf(_('Message to %s'), $this->group->nickname));
+ }
+
+ /**
+ * id for the form
+ *
+ * @param
+ *
+ * @return
+ */
+
+ function id()
+ {
+ return 'form_notice-group-message';
+ }
+
+ /**
+ * class for the form
+ *
+ * @param
+ *
+ * @return
+ */
+
+ function formClass()
+ {
+ return 'form_notice';
+ }
+
+ /**
+ * Entry data
+ *
+ * @param
+ *
+ * @return
+ */
+
+ function formData()
+ {
+ $this->out->element('label', array('for' => 'notice_data-text',
+ 'id' => 'notice_data-text-label'),
+ sprintf(_('Direct message to %s'), $this->group->nickname));
+
+ $this->out->element('textarea', array('id' => 'notice_data-text',
+ 'cols' => 35,
+ 'rows' => 4,
+ 'name' => 'content'),
+ ($this->content) ? $this->content : '');
+
+ $contentLimit = Message::maxContent();
+
+ if ($contentLimit > 0) {
+ $this->out->elementStart('dl', 'form_note');
+ $this->out->element('dt', null, _('Available characters'));
+ $this->out->element('dd', array('id' => 'notice_text-count'),
+ $contentLimit);
+ $this->out->elementEnd('dl');
+ }
+ }
+
+ /**
+ * Legend for the form
+ *
+ * @param
+ *
+ * @return
+ */
+
+ function formActions()
+ {
+ $this->out->element('input', array('id' => 'notice_action-submit',
+ 'class' => 'submit',
+ 'name' => 'message_send',
+ 'type' => 'submit',
+ 'value' => _m('Send button for sending notice', 'Send')));
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Widget for showing list of group messages
+ *
+ * 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 PrivateGroup
+ * @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);
+}
+
+/**
+ * Widget for showing list of group messages
+ *
+ * @category PrivateGroup
+ * @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 GroupMessageList extends Widget
+{
+ var $gm;
+
+ /**
+ * Constructor
+ *
+ * @param HTMLOutputter $out output context
+ * @param Group_message $gm Group message stream
+ */
+ function __construct($out, $gm)
+ {
+ parent::__construct($out);
+ $this->gm = $gm;
+ }
+
+ /**
+ * Show the list
+ *
+ * @return void
+ */
+ function show()
+ {
+ $this->out->elementStart('ul', 'notices messages group-messages');
+ while ($this->gm->fetch()) {
+ $gmli = new GroupMessageListItem($this->out, $this->gm);
+ $gmli->show();
+ }
+ $this->out->elementEnd('ul');
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Widget for showing an individual group message
+ *
+ * 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 PrivateGroup
+ * @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);
+}
+
+/**
+ * Widget for showing a single group message
+ *
+ * @category PrivateGroup
+ * @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 GroupMessageListItem extends Widget
+{
+ var $gm;
+
+ /**
+ * Constructor
+ *
+ * @param HTMLOutputter $out output context
+ * @param Group_message $gm Group message
+ */
+ function __construct($out, $gm)
+ {
+ parent::__construct($out);
+ $this->gm = $gm;
+ }
+
+ /**
+ * Show the item
+ *
+ * @return void
+ */
+ function show()
+ {
+ $group = $this->gm->getGroup();
+ $sender = $this->gm->getSender();
+
+ $this->out->elementStart('li', array('class' => 'hentry notice message group-message',
+ 'id' => 'message-' . $this->gm->id));
+
+ $this->out->elementStart('div', 'entry-title');
+ $this->out->elementStart('span', 'vcard author');
+ $this->out->elementStart('a',
+ array('href' => $sender->profileurl,
+ 'class' => 'url'));
+ $avatar = $sender->getAvatar(AVATAR_STREAM_SIZE);
+ $this->out->element('img', array('src' => ($avatar) ?
+ $avatar->displayUrl() :
+ Avatar::defaultImage(AVATAR_STREAM_SIZE),
+ 'width' => AVATAR_STREAM_SIZE,
+ 'height' => AVATAR_STREAM_SIZE,
+ 'class' => 'photo avatar',
+ 'alt' => $sender->getBestName()));
+ $this->out->element('span',
+ array('class' => 'nickname fn'),
+ $sender->nickname);
+ $this->out->elementEnd('a');
+ $this->out->elementEnd('span');
+
+ $this->out->elementStart('p', array('class' => 'entry-content message-content'));
+ $this->out->raw($this->gm->rendered);
+ $this->out->elementEnd('p');
+ $this->out->elementEnd('div');
+
+ $this->out->elementStart('div', 'entry-content');
+ $this->out->elementStart('a', array('rel' => 'bookmark',
+ 'class' => 'timestamp',
+ 'href' => $this->gm->url));
+ $dt = common_date_iso8601($this->gm->created);
+ $this->out->element('abbr', array('class' => 'published',
+ 'title' => $dt),
+ common_date_string($this->gm->created));
+ $this->out->elementEnd('a');
+ $this->out->elementEnd('div');
+
+ $this->out->elementEnd('li');
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Action for adding a new group message
+ *
+ * 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 Cache
+ * @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);
+}
+
+/**
+ * Action for adding a new group message
+ *
+ * @category Action
+ * @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 NewgroupmessageAction extends Action
+{
+ var $group;
+ var $user;
+ var $text;
+
+ /**
+ * For initializing members of the class.
+ *
+ * @param array $argarray misc. arguments
+ *
+ * @return boolean true
+ */
+
+ function prepare($argarray)
+ {
+ parent::prepare($argarray);
+
+ $this->user = common_current_user();
+
+ if (empty($this->user)) {
+ throw new ClientException(_('Must be logged in.'), 403);
+ }
+
+ if (!$this->user->hasRight(Right::NEWMESSAGE)) {
+ throw new Exception(sprintf(_('User %s not allowed to send private messages.'),
+ $this->user->nickname));
+ }
+
+ $nicknameArg = $this->trimmed('nickname');
+
+ $nickname = common_canonical_nickname($nicknameArg);
+
+ if ($nickname != $nicknameArg) {
+ $url = common_local_url('newgroupmessage', array('nickname' => $nickname));
+ common_redirect($url, 301);
+ return false;
+ }
+
+ $localGroup = Local_group::staticGet('nickname', $nickname);
+
+ if (empty($localGroup)) {
+ throw new ClientException(_('No such group'), 404);
+ }
+
+ $this->group = User_group::staticGet('id', $localGroup->group_id);
+
+ if (empty($this->group)) {
+ throw new ClientException(_('No such group'), 404);
+ }
+
+ // This throws an exception on error
+
+ Group_privacy_settings::ensurePost($this->user, $this->group);
+
+ // If we're posted to, check session token and get text
+
+ if ($this->isPost()) {
+ $this->checkSessionToken();
+ $this->text = $this->trimmed('content');
+ }
+
+ return true;
+ }
+
+ /**
+ * Handler method
+ *
+ * @param array $argarray is ignored since it's now passed in in prepare()
+ *
+ * @return void
+ */
+
+ function handle($argarray=null)
+ {
+ if ($this->isPost()) {
+ $this->sendNewMessage();
+ } else {
+ $this->showPage();
+ }
+ }
+
+ function showNoticeForm()
+ {
+ $form = new GroupMessageForm($this, $this->group);
+ $form->show();
+ }
+
+ function sendNewMessage()
+ {
+ $gm = Group_message::send($this->user, $this->group, $this->text);
+
+ if ($this->boolean('ajax')) {
+ $this->startHTML('text/xml;charset=utf-8');
+ $this->elementStart('head');
+ $this->element('title', null, _('Message sent'));
+ $this->elementEnd('head');
+ $this->elementStart('body');
+ $this->element('p',
+ array('id' => 'command_result'),
+ sprintf(_('Direct message to %s sent.'),
+ $this->group->nickname));
+ $this->elementEnd('body');
+ $this->elementEnd('html');
+ } else {
+ common_redirect($gm->url, 303);
+ }
+ }
+
+ function title()
+ {
+ return sprintf(_('New message to group %s'), $this->group->nickname);
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Show a single group message
+ *
+ * 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 PrivateGroup
+ * @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);
+}
+
+/**
+ * Show a single private group message
+ *
+ * @category PrivateGroup
+ * @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 ShowgroupmessageAction extends Action
+{
+ var $gm;
+ var $group;
+ var $sender;
+ var $user;
+
+ /**
+ * For initializing members of the class.
+ *
+ * @param array $argarray misc. arguments
+ *
+ * @return boolean true
+ */
+
+ function prepare($argarray)
+ {
+ parent::prepare($argarray);
+
+ $this->user = common_current_user();
+
+ if (empty($this->user)) {
+ throw new ClientException(_('Only logged-in users can view private messages.'),
+ 403);
+ }
+
+ $id = $this->trimmed('id');
+
+ $this->gm = Group_message::staticGet('id', $id);
+
+ if (empty($this->gm)) {
+ throw new ClientException(_('No such message'), 404);
+ }
+
+ $this->group = User_group::staticGet('id', $this->gm->to_group);
+
+ if (empty($this->group)) {
+ throw new ServerException(_('Group not found.'));
+ }
+
+ if (!$this->user->isMember($this->group)) {
+ throw new ClientException(_('Cannot read message.'), 403);
+ }
+
+ $this->sender = Profile::staticGet('id', $this->gm->from_profile);
+
+ if (empty($this->sender)) {
+ throw new ServerException(_('No sender found.'));
+ }
+
+ return true;
+ }
+
+ /**
+ * Handler method
+ *
+ * @param array $argarray is ignored since it's now passed in in prepare()
+ *
+ * @return void
+ */
+
+ function handle($argarray=null)
+ {
+ $this->showPage();
+ }
+
+ /**
+ * Title of the page
+ */
+
+ function title()
+ {
+ return sprintf(_('Message from %1$s to group %2$s on %3$s'),
+ $this->sender->nickname,
+ $this->group->nickname,
+ common_exact_date($this->gm->created));
+ }
+
+ /**
+ * Show the content area.
+ */
+
+ function showContent()
+ {
+ $this->elementStart('ul', 'notices messages');
+ $gmli = new GroupMessageListItem($this, $this->gm);
+ $gmli->show();
+ $this->elementEnd('ul');
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * MAY override
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean is read only action?
+ */
+
+ function isReadOnly($args)
+ {
+ return true;
+ }
+
+ /**
+ * Return last modified, if applicable.
+ *
+ * MAY override
+ *
+ * @return string last modified http header
+ */
+ function lastModified()
+ {
+ return max(strtotime($this->group->modified),
+ strtotime($this->sender->modified),
+ strtotime($this->gm->modified));
+ }
+
+ /**
+ * Return etag, if applicable.
+ *
+ * MAY override
+ *
+ * @return string etag http header
+ */
+ function etag()
+ {
+ $avatar = $this->sender->getAvatar(AVATAR_STREAM_SIZE);
+
+ $avtime = ($avatar) ? strtotime($avatar->modified) : 0;
+
+ return 'W/"' . implode(':', array($this->arg('action'),
+ common_user_cache_hash(),
+ common_language(),
+ $this->gm->id,
+ strtotime($this->sender->modified),
+ strtotime($this->group->modified),
+ $avtime)) . '"';
+ }
+}
+++ /dev/null
-<?php
-/**
- * Data class for group direct messages
- *
- * 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 group direct messages
- *
- * @category PrivateGroup
- * @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 = 'group_message'; // table name
- public $id; // char(36) primary_key not_null
- public $uri; // varchar(255)
- public $from_profile; // int
- public $to_group; // int
- public $content;
- public $rendered;
- public $url;
- public $created;
-
- /**
- * 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('id' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
- 'uri' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
- 'from_profile' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
- 'to_group' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
- 'content' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
- 'rendered' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
- 'url' => DB_DATAOBJECT_STR,
- 'created' => 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('id' => 'K', 'uri' => 'U');
- }
-
- static function send($user, $group, $text)
- {
- if (!$user->hasRight(Right::NEWMESSAGE)) {
- // XXX: maybe break this out into a separate right
- throw new Exception(sprintf(_('User %s not allowed to send private messages.'),
- $user->nickname));
- }
-
- Group_privacy_settings::ensurePost($user, $group);
-
- $text = $user->shortenLinks($text);
-
- // We use the same limits as for 'regular' private messages.
-
- if (Message::contentTooLong($text)) {
- throw new Exception(sprintf(_m('That\'s too long. Maximum message size is %d character.',
- 'That\'s too long. Maximum message size is %d characters.',
- Message::maxContent()),
- Message::maxContent()));
- }
-
- // Valid! Let's do this thing!
-
- $gm = new Group_message();
-
- $gm->id = UUID::gen();
- $gm->uri = common_local_url('showgroupmessage', array('id' => $gm->id));
- $gm->from_profile = $user->id;
- $gm->to_group = $group->id;
- $gm->content = $text; // XXX: is this cool?!
- $gm->rendered = common_render_text($text);
- $gm->url = $gm->uri;
- $gm->created = common_sql_now();
-
- // This throws a conniption if there's a problem
-
- $gm->insert();
-
- $gm->distribute();
-
- return $gm;
- }
-
- function distribute()
- {
- $group = User_group::staticGet('id', $this->to_group);
-
- $member = $group->getMembers();
-
- while ($member->fetch()) {
- Group_message_profile::send($this, $member);
- }
- }
-
- function getGroup()
- {
- $group = User_group::staticGet('id', $this->to_group);
- if (empty($group)) {
- throw new ServerException(_('No group for group message'));
- }
- return $group;
- }
-
- function getSender()
- {
- $sender = Profile::staticGet('id', $this->from_profile);
- if (empty($sender)) {
- throw new ServerException(_('No sender for group message'));
- }
- return $sender;
- }
-
- static function forGroup($group, $offset, $limit)
- {
- // XXX: cache
- $gm = new Group_message();
-
- $gm->to_group = $group->id;
- $gm->orderBy('created DESC');
- $gm->limit($offset, $limit);
-
- $gm->find();
-
- return $gm;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Who received a group message
- *
- * 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) 2010, 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 group direct messages for users
- *
- * @category PrivateGroup
- * @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_profile extends Memcached_DataObject
-{
- public $__table = 'group_message_profile'; // table name
- public $to_profile; // int
- public $group_message_id; // char(36) primary_key not_null
- public $created;
-
- /**
- * 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_profile', $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('to_profile' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
- 'group_message_id' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
- 'created' => 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('to_profile' => 'K', 'group_message_id' => 'K');
- }
-
- /**
- * No sequence keys in this table.
- */
- function sequenceKey()
- {
- return array(false, false, false);
- }
-
- function send($gm, $profile)
- {
- $gmp = new Group_message_profile();
-
- $gmp->group_message_id = $gm->id;
- $gmp->to_profile = $profile->id;
- $gmp->created = common_sql_now();
-
- $gmp->insert();
-
- $gmp->notify();
-
- return $gmp;
- }
-
- function notify()
- {
- // XXX: add more here
- $this->notifyByMail();
- }
-
- function notifyByMail()
- {
- $to = User::staticGet('id', $this->to_profile);
-
- if (empty($to) || is_null($to->email) || !$to->emailnotifymsg) {
- return true;
- }
-
- $gm = Group_message::staticGet('id', $this->group_message_id);
-
- $from_profile = Profile::staticGet('id', $gm->from_profile);
-
- $group = $gm->getGroup();
-
- common_switch_locale($to->language);
-
- // TRANS: Subject for direct-message notification email.
- // TRANS: %s is the sending user's nickname.
- $subject = sprintf(_('New private message from %s to group %s'), $from->nickname, $group->nickname);
-
- $from_profile = $from->getProfile();
-
- // TRANS: Body for direct-message notification email.
- // TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname,
- // TRANS: %3$s is the message content, %4$s a URL to the message,
- // TRANS: %5$s is the StatusNet sitename.
- $body = sprintf(_("%1\$s (%2\$s) sent a private message to group %3\$s:\n\n".
- "------------------------------------------------------\n".
- "%4\$s\n".
- "------------------------------------------------------\n\n".
- "You can reply to their message here:\n\n".
- "%5\$s\n\n".
- "Don't reply to this email; it won't get to them.\n\n".
- "With kind regards,\n".
- "%6\$s\n"),
- $from_profile->getBestName(),
- $from->nickname,
- $group->nickname,
- $this->content,
- common_local_url('newmessage', array('to' => $from->id)),
- common_config('site', 'name'));
-
- $headers = _mail_prepare_headers('message', $to->nickname, $from->nickname);
-
- common_switch_locale();
-
- return mail_to_user($to, $subject, $body, $headers);
- }
-}
+++ /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);
- }
-
- function ensurePost($user, $group)
- {
- $gps = Group_privacy_settings::staticGet('group_id', $group->id);
-
- if (empty($gps)) {
- // make a fake one with defaults
- $gps = new Group_privacy_settings();
- $gps->allow_privacy = Group_privacy_settings::SOMETIMES;
- $gps->allow_sender = Group_privacy_settings::MEMBER;
- }
-
- if ($gps->allow_privacy == Group_privacy_settings::NEVER) {
- throw new Exception(sprintf(_('Group %s does not allow private messages.'),
- $group->nickname));
- }
-
- switch ($gps->allow_sender) {
- case Group_privacy_settings::EVERYONE:
- $profile = $user->getProfile();
- if (Group_block::isBlocked($group, $profile)) {
- throw new Exception(sprintf(_('User %s is blocked from group %s.'),
- $user->nickname,
- $group->nickname));
- }
- break;
- case Group_privacy_settings::MEMBER:
- if (!$user->isMember($group)) {
- throw new Exception(sprintf(_('User %s is not a member of group %s.'),
- $user->nickname,
- $group->nickname));
- }
- break;
- case Group_privacy_settings::ADMIN:
- if (!$user->isAdmin($group)) {
- throw new Exception(sprintf(_('User %s is not an administrator of group %s.'),
- $user->nickname,
- $group->nickname));
- }
- break;
- default:
- throw new Exception(sprintf(_('Unknown privacy settings for group %s.'),
- $group->nickname));
- }
-
- return true;
- }
-}
+++ /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')));
-
- $schema->ensureTable('group_message_profile',
- array(new ColumnDef('to_profile',
- 'integer',
- null,
- false,
- 'PRI'),
- new ColumnDef('group_message_id',
- 'char',
- 36,
- false,
- 'PRI'),
- new ColumnDef('created',
- 'datetime')));
-
- 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':
- case 'ShowgroupmessageAction':
- case 'NewgroupmessageAction':
- include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
- return false;
- case 'Group_privacy_settings':
- case 'Group_message':
- case 'Group_message_profile':
- include_once $dir . '/'.$cls.'.php';
- return false;
- case 'GroupMessageCommand':
- case 'GroupMessageList':
- case 'GroupMessageListItem':
- case 'GroupMessageForm':
- include_once $dir . '/'.strtolower($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));
-
- $m->connect('group/message/:id',
- array('action' => 'showgroupmessage'),
- array('id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'));
-
- $m->connect('group/:nickname/message/new',
- array('action' => 'newgroupmessage'),
- 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 User_group $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;
- }
-
- /**
- * Show group privacy controls on group edit form
- *
- * @param GroupEditForm $form form being shown
- */
-
- function onEndGroupEditFormData($form)
- {
- $gps = null;
-
- if (!empty($form->group)) {
- $gps = Group_privacy_settings::staticGet('group_id', $form->group->id);
- }
-
- $form->out->elementStart('li');
- $form->out->dropdown('allow_privacy',
- _('Private messages'),
- array(Group_privacy_settings::SOMETIMES => _('Sometimes'),
- Group_privacy_settings::ALWAYS => _('Always'),
- Group_privacy_settings::NEVER => _('Never')),
- _('Whether to allow private messages to this group'),
- false,
- (empty($gps)) ? Group_privacy_settings::SOMETIMES : $gps->allow_privacy);
- $form->out->elementEnd('li');
- $form->out->elementStart('li');
- $form->out->dropdown('allow_sender',
- _('Private sender'),
- array(Group_privacy_settings::EVERYONE => _('Everyone'),
- Group_privacy_settings::MEMBER => _('Member'),
- Group_privacy_settings::ADMIN => _('Admin')),
- _('Who can send private messages to the group'),
- false,
- (empty($gps)) ? Group_privacy_settings::MEMBER : $gps->allow_sender);
- $form->out->elementEnd('li');
- return true;
- }
-
- function onEndGroupSaveForm($action)
- {
- $gps = null;
-
- if (!empty($action->group)) {
- $gps = Group_privacy_settings::staticGet('group_id', $action->group->id);
- }
-
- $orig = null;
-
- if (empty($gps)) {
- $gps = new Group_privacy_settings();
- $gps->group_id = $action->group->id;
- } else {
- $orig = clone($gps);
- }
-
- $gps->allow_privacy = $action->trimmed('allow_privacy');
- $gps->allow_sender = $action->trimmed('allow_sender');
-
- if (empty($orig)) {
- $gps->created = common_sql_now();
- $gps->insert();
- } else {
- $gps->update($orig);
- }
-
- return true;
- }
-
- /**
- * Overload 'd' command to send private messages to groups.
- *
- * 'd !group word word word' will send the private message
- * 'word word word' to the group 'group'.
- *
- * @param string $cmd Command being run
- * @param string $arg Rest of the message (including address)
- * @param User $user User sending the message
- * @param Command &$result The resulting command object to be run.
- *
- * @return boolean hook value
- */
- function onStartIntepretCommand($cmd, $arg, $user, &$result)
- {
- if ($cmd == 'd' || $cmd == 'dm') {
-
- $this->debug('Got a d command');
-
- // Break off the first word as the address
-
- $pieces = explode(' ', $arg, 2);
-
- if (count($pieces) == 1) {
- $pieces[] = null;
- }
-
- list($addr, $msg) = $pieces;
-
- if (!empty($addr) && $addr[0] == '!') {
- $result = new GroupMessageCommand($user, substr($addr, 1), $msg);
- Event::handle('EndInterpretCommand', array($cmd, $arg, $user, $result));
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * To add a "Message" button to the group profile page
- *
- * @param Action $action The showgroup action being shown
- * @param User_group $group The current group
- *
- * @return boolean hook value
- */
- function onEndGroupActionsList($action, $group)
- {
- $cur = common_current_user();
-
- if (empty($cur)) {
- return true;
- }
-
- try {
- Group_privacy_settings::ensurePost($cur, $group);
- } catch (Exception $e) {
- return true;
- }
-
- $action->elementStart('li', 'entity_send-a-message');
- $action->element('a', array('href' => common_local_url('newgroupmessage', array('nickname' => $group->nickname)),
- 'title' => _('Send a direct message to this group')),
- _('Message'));
- // $form = new GroupMessageForm($action, $group);
- // $form->hidden = true;
- // $form->show();
- $action->elementEnd('li');
- 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
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, Inc.
- *
- * List of private messages to this group
- *
- * 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 PrivateGroup
- * @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);
-}
-
-/**
- * Show a list of private messages to this group
- *
- * @category PrivateGroup
- * @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 GroupinboxAction extends GroupDesignAction
-{
- var $gm;
-
- /**
- * For initializing members of the class.
- *
- * @param array $argarray misc. arguments
- *
- * @return boolean true
- */
- function prepare($argarray)
- {
- parent::prepare($argarray);
-
- $cur = common_current_user();
-
- if (empty($cur)) {
- throw new ClientException(_('Only for logged-in users'), 403);
- }
-
- $nicknameArg = $this->trimmed('nickname');
-
- $nickname = common_canonical_nickname($nicknameArg);
-
- if ($nickname != $nicknameArg) {
- $url = common_local_url('groupinbox', array('nickname' => $nickname));
- common_redirect($url);
- return false;
- }
-
- $localGroup = Local_group::staticGet('nickname', $nickname);
-
- if (empty($localGroup)) {
- throw new ClientException(_('No such group'), 404);
- }
-
- $this->group = User_group::staticGet('id', $localGroup->group_id);
-
- if (empty($this->group)) {
- throw new ClientException(_('No such group'), 404);
- }
-
- if (!$cur->isMember($this->group)) {
- throw new ClientException(_('Only for members'), 403);
- }
-
- $this->page = $this->trimmed('page');
-
- if (!$this->page) {
- $this->page = 1;
- }
-
- $this->gm = Group_message::forGroup($this->group,
- ($this->page - 1) * MESSAGES_PER_PAGE,
- MESSAGES_PER_PAGE + 1);
- return true;
- }
-
- function showLocalNav()
- {
- $nav = new GroupNav($this, $this->group);
- $nav->show();
- }
-
- function showNoticeForm()
- {
- $form = new GroupMessageForm($this, $this->group);
- $form->show();
- }
-
- function showContent()
- {
- $gml = new GroupMessageList($this, $this->gm);
- $gml->show();
- }
-
- /**
- * Handler method
- *
- * @param array $argarray is ignored since it's now passed in in prepare()
- *
- * @return void
- */
- function handle($argarray=null)
- {
- $this->showPage();
- }
-
- /**
- * Return true if read only.
- *
- * MAY override
- *
- * @param array $args other arguments
- *
- * @return boolean is read only action?
- */
- function isReadOnly($args)
- {
- return true;
- }
-
- /**
- * Title of the page
- *
- * @return string page title, with page number
- */
- function title()
- {
- $base = $this->group->getFancyName();
-
- if ($this->page == 1) {
- return sprintf(_('%s group inbox'), $base);
- } else {
- // TRANS: Page title for any but first group page.
- // TRANS: %1$s is a group name, $2$s is a page number.
- return sprintf(_('%1$s group inbox, page %2$d'),
- $base,
- $this->page);
- }
- }
-}
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, Inc.
- *
- * Command object for messages to groups
- *
- * 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 Command
- * @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);
-}
-
-/**
- * Command object for messages to groups
- *
- * @category General
- * @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 GroupMessageCommand extends Command
-{
- /** User sending the message. */
- var $user;
- /** Nickname of the group they're sending to. */
- var $nickname;
- /** Text of the message. */
- var $text;
-
- /**
- * Constructor
- *
- * @param User $user User sending the message
- * @param string $nickname Nickname of the group
- * @param string $text Text of message
- */
-
- function __construct($user, $nickname, $text)
- {
- $this->user = $user;
- $this->nickname = $nickname;
- $this->text = $text;
- }
-
- function handle($channel)
- {
- // Throws a command exception if group not found
- $group = $this->getGroup($this->nickname);
-
- $gm = Group_message::send($this->user, $group, $this->text);
-
- $channel->output($this->user,
- sprintf(_('Direct message to group %s sent.'),
- $group->nickname));
-
- return true;
- }
-}
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2011, StatusNet, Inc.
- *
- * Form for posting a group message
- *
- * 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 PrivateGroup
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2011 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);
-}
-
-/**
- * Form for posting a group message
- *
- * @category PrivateGroup
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2011 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link http://status.net/
- */
-
-class GroupMessageForm extends Form
-{
- var $group;
- var $content;
-
- /**
- * Constructor
- *
- * @param HTMLOutputter $out Output context
- * @param User_group $group Group to post to
- *
- * @todo add a drop-down list to post to any group
- */
-
- function __construct($out, $group, $content=null)
- {
- parent::__construct($out);
-
- $this->group = $group;
- $this->content = $content;
- }
-
- /**
- * Action for the form
- */
- function action()
- {
- return common_local_url('newgroupmessage',
- array('nickname' => $this->group->nickname));
- }
-
- /**
- * Legend for the form
- *
- * @param
- *
- * @return
- */
- function formLegend()
- {
- $this->out->element('legend',
- null,
- sprintf(_('Message to %s'), $this->group->nickname));
- }
-
- /**
- * id for the form
- *
- * @param
- *
- * @return
- */
-
- function id()
- {
- return 'form_notice-group-message';
- }
-
- /**
- * class for the form
- *
- * @param
- *
- * @return
- */
-
- function formClass()
- {
- return 'form_notice';
- }
-
- /**
- * Entry data
- *
- * @param
- *
- * @return
- */
-
- function formData()
- {
- $this->out->element('label', array('for' => 'notice_data-text',
- 'id' => 'notice_data-text-label'),
- sprintf(_('Direct message to %s'), $this->group->nickname));
-
- $this->out->element('textarea', array('id' => 'notice_data-text',
- 'cols' => 35,
- 'rows' => 4,
- 'name' => 'content'),
- ($this->content) ? $this->content : '');
-
- $contentLimit = Message::maxContent();
-
- if ($contentLimit > 0) {
- $this->out->elementStart('dl', 'form_note');
- $this->out->element('dt', null, _('Available characters'));
- $this->out->element('dd', array('id' => 'notice_text-count'),
- $contentLimit);
- $this->out->elementEnd('dl');
- }
- }
-
- /**
- * Legend for the form
- *
- * @param
- *
- * @return
- */
-
- function formActions()
- {
- $this->out->element('input', array('id' => 'notice_action-submit',
- 'class' => 'submit',
- 'name' => 'message_send',
- 'type' => 'submit',
- 'value' => _m('Send button for sending notice', 'Send')));
- }
-}
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, Inc.
- *
- * Widget for showing list of group messages
- *
- * 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 PrivateGroup
- * @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);
-}
-
-/**
- * Widget for showing list of group messages
- *
- * @category PrivateGroup
- * @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 GroupMessageList extends Widget
-{
- var $gm;
-
- /**
- * Constructor
- *
- * @param HTMLOutputter $out output context
- * @param Group_message $gm Group message stream
- */
- function __construct($out, $gm)
- {
- parent::__construct($out);
- $this->gm = $gm;
- }
-
- /**
- * Show the list
- *
- * @return void
- */
- function show()
- {
- $this->out->elementStart('ul', 'notices messages group-messages');
- while ($this->gm->fetch()) {
- $gmli = new GroupMessageListItem($this->out, $this->gm);
- $gmli->show();
- }
- $this->out->elementEnd('ul');
- }
-}
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, Inc.
- *
- * Widget for showing an individual group message
- *
- * 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 PrivateGroup
- * @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);
-}
-
-/**
- * Widget for showing a single group message
- *
- * @category PrivateGroup
- * @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 GroupMessageListItem extends Widget
-{
- var $gm;
-
- /**
- * Constructor
- *
- * @param HTMLOutputter $out output context
- * @param Group_message $gm Group message
- */
- function __construct($out, $gm)
- {
- parent::__construct($out);
- $this->gm = $gm;
- }
-
- /**
- * Show the item
- *
- * @return void
- */
- function show()
- {
- $group = $this->gm->getGroup();
- $sender = $this->gm->getSender();
-
- $this->out->elementStart('li', array('class' => 'hentry notice message group-message',
- 'id' => 'message-' . $this->gm->id));
-
- $this->out->elementStart('div', 'entry-title');
- $this->out->elementStart('span', 'vcard author');
- $this->out->elementStart('a',
- array('href' => $sender->profileurl,
- 'class' => 'url'));
- $avatar = $sender->getAvatar(AVATAR_STREAM_SIZE);
- $this->out->element('img', array('src' => ($avatar) ?
- $avatar->displayUrl() :
- Avatar::defaultImage(AVATAR_STREAM_SIZE),
- 'width' => AVATAR_STREAM_SIZE,
- 'height' => AVATAR_STREAM_SIZE,
- 'class' => 'photo avatar',
- 'alt' => $sender->getBestName()));
- $this->out->element('span',
- array('class' => 'nickname fn'),
- $sender->nickname);
- $this->out->elementEnd('a');
- $this->out->elementEnd('span');
-
- $this->out->elementStart('p', array('class' => 'entry-content message-content'));
- $this->out->raw($this->gm->rendered);
- $this->out->elementEnd('p');
- $this->out->elementEnd('div');
-
- $this->out->elementStart('div', 'entry-content');
- $this->out->elementStart('a', array('rel' => 'bookmark',
- 'class' => 'timestamp',
- 'href' => $this->gm->url));
- $dt = common_date_iso8601($this->gm->created);
- $this->out->element('abbr', array('class' => 'published',
- 'title' => $dt),
- common_date_string($this->gm->created));
- $this->out->elementEnd('a');
- $this->out->elementEnd('div');
-
- $this->out->elementEnd('li');
- }
-}
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, Inc.
- *
- * Action for adding a new group message
- *
- * 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 Cache
- * @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);
-}
-
-/**
- * Action for adding a new group message
- *
- * @category Action
- * @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 NewgroupmessageAction extends Action
-{
- var $group;
- var $user;
- var $text;
-
- /**
- * For initializing members of the class.
- *
- * @param array $argarray misc. arguments
- *
- * @return boolean true
- */
-
- function prepare($argarray)
- {
- parent::prepare($argarray);
-
- $this->user = common_current_user();
-
- if (empty($this->user)) {
- throw new ClientException(_('Must be logged in.'), 403);
- }
-
- if (!$this->user->hasRight(Right::NEWMESSAGE)) {
- throw new Exception(sprintf(_('User %s not allowed to send private messages.'),
- $this->user->nickname));
- }
-
- $nicknameArg = $this->trimmed('nickname');
-
- $nickname = common_canonical_nickname($nicknameArg);
-
- if ($nickname != $nicknameArg) {
- $url = common_local_url('newgroupmessage', array('nickname' => $nickname));
- common_redirect($url, 301);
- return false;
- }
-
- $localGroup = Local_group::staticGet('nickname', $nickname);
-
- if (empty($localGroup)) {
- throw new ClientException(_('No such group'), 404);
- }
-
- $this->group = User_group::staticGet('id', $localGroup->group_id);
-
- if (empty($this->group)) {
- throw new ClientException(_('No such group'), 404);
- }
-
- // This throws an exception on error
-
- Group_privacy_settings::ensurePost($this->user, $this->group);
-
- // If we're posted to, check session token and get text
-
- if ($this->isPost()) {
- $this->checkSessionToken();
- $this->text = $this->trimmed('content');
- }
-
- return true;
- }
-
- /**
- * Handler method
- *
- * @param array $argarray is ignored since it's now passed in in prepare()
- *
- * @return void
- */
-
- function handle($argarray=null)
- {
- if ($this->isPost()) {
- $this->sendNewMessage();
- } else {
- $this->showPage();
- }
- }
-
- function showNoticeForm()
- {
- $form = new GroupMessageForm($this, $this->group);
- $form->show();
- }
-
- function sendNewMessage()
- {
- $gm = Group_message::send($this->user, $this->group, $this->text);
-
- if ($this->boolean('ajax')) {
- $this->startHTML('text/xml;charset=utf-8');
- $this->elementStart('head');
- $this->element('title', null, _('Message sent'));
- $this->elementEnd('head');
- $this->elementStart('body');
- $this->element('p',
- array('id' => 'command_result'),
- sprintf(_('Direct message to %s sent.'),
- $this->group->nickname));
- $this->elementEnd('body');
- $this->elementEnd('html');
- } else {
- common_redirect($gm->url, 303);
- }
- }
-
- function title()
- {
- return sprintf(_('New message to group %s'), $this->group->nickname);
- }
-}
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, Inc.
- *
- * Show a single group message
- *
- * 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 PrivateGroup
- * @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);
-}
-
-/**
- * Show a single private group message
- *
- * @category PrivateGroup
- * @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 ShowgroupmessageAction extends Action
-{
- var $gm;
- var $group;
- var $sender;
- var $user;
-
- /**
- * For initializing members of the class.
- *
- * @param array $argarray misc. arguments
- *
- * @return boolean true
- */
-
- function prepare($argarray)
- {
- parent::prepare($argarray);
-
- $this->user = common_current_user();
-
- if (empty($this->user)) {
- throw new ClientException(_('Only logged-in users can view private messages.'),
- 403);
- }
-
- $id = $this->trimmed('id');
-
- $this->gm = Group_message::staticGet('id', $id);
-
- if (empty($this->gm)) {
- throw new ClientException(_('No such message'), 404);
- }
-
- $this->group = User_group::staticGet('id', $this->gm->to_group);
-
- if (empty($this->group)) {
- throw new ServerException(_('Group not found.'));
- }
-
- if (!$this->user->isMember($this->group)) {
- throw new ClientException(_('Cannot read message.'), 403);
- }
-
- $this->sender = Profile::staticGet('id', $this->gm->from_profile);
-
- if (empty($this->sender)) {
- throw new ServerException(_('No sender found.'));
- }
-
- return true;
- }
-
- /**
- * Handler method
- *
- * @param array $argarray is ignored since it's now passed in in prepare()
- *
- * @return void
- */
-
- function handle($argarray=null)
- {
- $this->showPage();
- }
-
- /**
- * Title of the page
- */
-
- function title()
- {
- return sprintf(_('Message from %1$s to group %2$s on %3$s'),
- $this->sender->nickname,
- $this->group->nickname,
- common_exact_date($this->gm->created));
- }
-
- /**
- * Show the content area.
- */
-
- function showContent()
- {
- $this->elementStart('ul', 'notices messages');
- $gmli = new GroupMessageListItem($this, $this->gm);
- $gmli->show();
- $this->elementEnd('ul');
- }
-
- /**
- * Return true if read only.
- *
- * MAY override
- *
- * @param array $args other arguments
- *
- * @return boolean is read only action?
- */
-
- function isReadOnly($args)
- {
- return true;
- }
-
- /**
- * Return last modified, if applicable.
- *
- * MAY override
- *
- * @return string last modified http header
- */
- function lastModified()
- {
- return max(strtotime($this->group->modified),
- strtotime($this->sender->modified),
- strtotime($this->gm->modified));
- }
-
- /**
- * Return etag, if applicable.
- *
- * MAY override
- *
- * @return string etag http header
- */
- function etag()
- {
- $avatar = $this->sender->getAvatar(AVATAR_STREAM_SIZE);
-
- $avtime = ($avatar) ? strtotime($avatar->modified) : 0;
-
- return 'W/"' . implode(':', array($this->arg('action'),
- common_user_cache_hash(),
- common_language(),
- $this->gm->id,
- strtotime($this->sender->modified),
- strtotime($this->group->modified),
- $avtime)) . '"';
- }
-}