]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Send a private group message with a d command
authorEvan Prodromou <evan@status.net>
Fri, 4 Feb 2011 20:51:59 +0000 (15:51 -0500)
committerEvan Prodromou <evan@status.net>
Fri, 4 Feb 2011 20:51:59 +0000 (15:51 -0500)
plugins/PrivateGroup/Group_message.php
plugins/PrivateGroup/Group_message_profile.php
plugins/PrivateGroup/PrivateGroupPlugin.php
plugins/PrivateGroup/groupmessagecommand.php [new file with mode: 0644]

index 27f4cff0ed60dbe821d77fa1403633f782a54941..b3d34cf28725709228f556614ae7b5a80cc6d535 100644 (file)
@@ -118,4 +118,98 @@ class Group_message extends Memcached_DataObject
     {
         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));
+        }
+
+        $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));
+        }
+        
+        $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);
+        }
+    }
 }
index b32341ca773c53d337ea12deb3bb41cb9ed7e4ae..fc1ff1bcebcca4c21dec151984fa0a2066d44833 100644 (file)
@@ -108,4 +108,79 @@ class Group_message_profile extends Memcached_DataObject
     {
         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);
+
+        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'), $from->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 you a private message:\n\n".
+                          "------------------------------------------------------\n".
+                          "%3\$s\n".
+                          "------------------------------------------------------\n\n".
+                          "You can reply to their message here:\n\n".
+                          "%4\$s\n\n".
+                          "Don't reply to this email; it won't get to them.\n\n".
+                          "With kind regards,\n".
+                          "%5\$s\n"),
+                        $from_profile->getBestName(),
+                        $from->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);
+    }
 }
index 67e1cfb65ee737c6afd0ac0af685324c96e28fbf..4d8f2b370bb4e1680d8002b693f69834a6f588aa 100644 (file)
@@ -144,6 +144,7 @@ class PrivateGroupPlugin extends Plugin
         switch ($cls)
         {
         case 'GroupinboxAction':
+        case 'ShowgroupmessageAction':
             include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
             return false;
         case 'Group_privacy_settings':
@@ -151,6 +152,9 @@ class PrivateGroupPlugin extends Plugin
         case 'Group_message_profile':
             include_once $dir . '/'.$cls.'.php';
             return false;
+        case 'GroupMessageCommand':
+            include_once $dir . '/'.strtolower($cls).'.php';
+            return false;
         default:
             return true;
         }
@@ -170,6 +174,10 @@ class PrivateGroupPlugin extends Plugin
                     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}'));
+
         return true;
     }
 
@@ -289,7 +297,46 @@ class PrivateGroupPlugin extends Plugin
         
         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;
+    }
+
     function onPluginVersion(&$versions)
     {
         $versions[] = array('name' => 'PrivateGroup',
diff --git a/plugins/PrivateGroup/groupmessagecommand.php b/plugins/PrivateGroup/groupmessagecommand.php
new file mode 100644 (file)
index 0000000..19136f1
--- /dev/null
@@ -0,0 +1,85 @@
+<?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;
+    }
+}