Пример #1
0
 /**
  * If the user is participating in (soe of) the streams, sets state of participant row
  * as "left" and posts a "Streams/leave" type message to the streams.
  * Also posts "Streams/left" message on user's "Streams/participating" stream
  * for each stream that was left.
  * @method leave
  * @static
  * @param {string} $asUserId The id of the user that is joining. Pass null here to use the logged-in user's id.
  * @param {string} $publisherId The id of the user publishing all the streams
  * @param {array} $streams An array of Streams_Stream objects or stream names
  * @param {array} [$options=array()] An associative array of options.
  * @param {boolean} [$options.skipAccess] If true, skip access check for whether user can join
  * @return {array} Returns an array of (streamName => Streams_Participant) pairs
  */
 static function leave($asUserId, $publisherId, $streams, $options = array())
 {
     $streams2 = self::_getStreams($asUserId, $publisherId, $streams);
     $streamNames = array();
     foreach ($streams2 as $s) {
         $streamNames[] = $s->name;
     }
     if (empty($options['skipAccess'])) {
         self::_accessExceptions($streams2, $streamNames, 'join');
     }
     $participants = Streams_Participant::select('*')->where(array('publisherId' => $publisherId, 'streamName' => $streamNames, 'userId' => $asUserId))->ignoreCache()->fetchDbRows(null, null, 'streamName');
     $streamNamesUpdate = array();
     $updateCounts = array();
     $state = 'left';
     foreach ($streamNames as $sn) {
         if (!isset($participants[$sn])) {
             $updateCounts[''][] = $sn;
             $streamNamesMissing[] = $sn;
             continue;
         }
         $p =& $participants[$sn];
         if ($p->state === $state) {
             continue;
         }
         if (!isset($participants[$sn])) {
             $streamNamesMissing[] = $sn;
             continue;
         }
         $streamNamesUpdate[] = $sn;
         $updateCounts[$p->state][] = $sn;
         $p->set('prevState', $p->state);
         $p->state = $state;
     }
     if ($streamNamesUpdate) {
         Streams_Participant::update()->set(compact('state'))->where(array('publisherId' => $publisherId, 'streamName' => $streamNamesUpdate, 'userId' => $asUserId))->execute();
     }
     self::_updateCounts($publisherId, $updateCounts, $state);
     if ($streamNamesMissing) {
         $rows = array();
         foreach ($streamNamesMissing as $sn) {
             $stream = $streams2[$sn];
             $participants[$sn] = $rows[$sn] = new Streams_Participant(array('publisherId' => $publisherId, 'streamName' => $sn, 'userId' => $asUserId, 'streamType' => $stream->type, 'state' => 'participating', 'subscribed' => !empty($options['subscribed']) ? 'yes' : 'no', 'posted' => !empty($options['posted']) ? 'yes' : 'no', 'extra' => !empty($options['extra']) ? $options['extra'] : ''));
         }
         Streams_Participant::insertManyAndExecute($rows);
     }
     foreach ($streamNames as $sn) {
         $stream = $streams2[$sn];
         $participant = Q::ifset($participants, $sn, null);
         $prevState = $participant ? $participant->get('prevState', null) : null;
         // Send a message to Node
         Q_Utils::sendToNode(array("Q/method" => "Streams/Stream/leave", "participant" => Q::json_encode($participant->toArray()), "stream" => Q::json_encode($stream->toArray()), "prevState" => $prevState));
         // Stream messages to post
         $messages[$publisherId][$sn] = array('type' => 'Streams/leave', 'instructions' => array('prevState' => $prevState, 'extra' => isset($participant->extra) ? $participant->extra : array()));
         $pMessages[] = array('type' => "Streams/left", 'instructions' => array('publisherId' => $publisherId, 'streamName' => $sn, 'prevState' => $prevState));
     }
     Streams_Message::postMessages($asUserId, $messages, true);
     Streams_Message::postMessages($asUserId, array($asUserId => array('Streams/participating' => $pMessages)), true);
     return $participants;
 }