示例#1
0
 /**
  * Subscribe to the stream's messages<br/>
  *	If options are not given check the subscription templates:
  *	1. exact stream name and exact user id
  *	2. generic stream name and exact user id
  *	3. exact stream name and generic user
  *	4. generic stream name and generic user
  *	default is to subscribe to ALL messages.
  *	If options supplied - skip templates and use options<br/><br/>
  * Using subscribe if subscription is already active will modify existing
  * subscription - change type(s) or modify notifications
  * @method subscribe
  * @param $options=array() {array}
  * @param {array} [$options.types] array of message types, if this is empty then subscribes to all types
  * @param {integer} [$options.notifications=0] limit number of notifications, 0 means no limit
  * @param {datetime} [$options.untilTime=null] time limit, if any for subscription
  * @param {datetime} [$options.readyTime] time from which user is ready to receive notifications again
  * @param {string} [$options.userId] the user subscribing to the stream. Defaults to the logged in user.
  * @param {array} [$options.deliver=array('to'=>'default')] under "to" key, named the field under Streams/rules/deliver config, which will contain the names of destinations, which can include "email", "mobile", "email+pending", "mobile+pending"
  * @param {boolean} [$options.skipRules]  if true, do not attempt to create rules
  * @param {boolean} [$options.skipAccess]  if true, skip access check for whether user can subscribe
  * @return {Streams_Subscription|false}
  */
 function subscribe($options = array())
 {
     $stream = $this->fetchAsUser($options, $userId, $user);
     if (empty($options['skipAccess']) and !$stream->testReadLevel('messages')) {
         if (!$stream->testReadLevel('see')) {
             throw new Streams_Exception_NoSuchStream();
         }
         throw new Users_Exception_NotAuthorized();
     }
     // first make user a participant
     $stream->join(array("userId" => $userId, "subscribed" => true, "noVisit" => true, "skipAccess" => Q::ifset($options, 'skipAccess', false)));
     // check for 'messages' level
     $s = new Streams_Subscription();
     $s->publisherId = $stream->publisherId;
     $s->streamName = $stream->name;
     $s->ofUserId = $userId;
     $s->retrieve();
     $type = null;
     if ($template = $stream->getSubscriptionTemplate('Streams_Subscription', $userId, $type)) {
         $filter = json_decode($template->filter, true);
     } else {
         $filter = array('types' => array(), 'notifications' => 0);
     }
     if (isset($options['types'])) {
         $filter['types'] = !empty($options['types']) ? $options['types'] : $filter['types'];
     }
     if (isset($options['notifications'])) {
         $filter['notifications'] = $options['notifications'];
     }
     $s->filter = Q::json_encode($filter);
     if (isset($options['untilTime'])) {
         $s->untilTime = $options['untilTime'];
     } else {
         if ($type > 0 and $template and $template->duration > 0) {
             $s->untilTime = date("c", time() + $template->duration);
         }
     }
     if (!$s->save(true)) {
         return false;
     }
     if (empty($options['skipRules'])) {
         // Now let's handle rules
         $type2 = null;
         $template = $stream->getSubscriptionTemplate('Streams_Rule', $userId, $type2);
         $ruleSuccess = true;
         if ($type2 !== 0) {
             $rule = new Streams_Rule();
             $rule->ofUserId = $userId;
             $rule->publisherId = $stream->publisherId;
             $rule->streamName = $stream->name;
             if (empty($template) and $rule->retrieve()) {
                 $ruleSuccess = false;
             } else {
                 $rule->readyTime = isset($options['readyTime']) ? $options['readyTime'] : new Db_Expression('CURRENT_TIMESTAMP');
                 $rule->filter = !empty($template->filter) ? $template->filter : '{"types":[],"labels":[]}';
                 $rule->relevance = !empty($template->relevance) ? $template->relevance : 1;
                 $rule->deliver = !empty($template->deliver) ? $template->deliver : Q::json_encode(Q::ifset($options, 'deliver', array('to' => 'default')));
                 $ruleSuccess = !!$rule->save();
             }
         }
     }
     // skip error testing for rule save BUT inform node.
     // Node can notify user to check the rules
     Q_Utils::sendToNode(array("Q/method" => "Streams/Stream/subscribe", "subscription" => Q::json_encode($s->toArray()), "stream" => Q::json_encode($stream->toArray()), "success" => Q::json_encode($ruleSuccess)));
     // Post Streams/subscribe message to the stream
     $stream->post($userId, array('type' => 'Streams/subscribe'), true);
     // Now post Streams/subscribed message to Streams/participating
     Streams_Message::post($userId, $userId, 'Streams/participating', array('type' => 'Streams/subscribed', 'instructions' => Q::json_encode(array('publisherId' => $stream->publisherId, 'streamName' => $stream->name))), true);
     return $s;
 }