function Streams_message_response_messages() { if (isset(Streams::$cache['message'])) { $message = Streams::$cache['message']; return Db::exportArray(array($message->ordinal => $message)); } if (isset(Streams::$cache['messages'])) { return Db::exportArray(Streams::$cache['messages']); } $publisherId = Streams::requestedPublisherId(true); $streamName = Streams::requestedName(true); $type = Streams::requestedMessageType(); $stream = Q::ifset(Streams::$cache, 'stream', Streams::fetchOne(null, $publisherId, $streamName, true)); $maxLimit = Streams_Stream::getConfigField($type, 'getMessagesLimit', 100); $limit = min($maxLimit, Q::ifset($_REQUEST, 'limit', $maxLimit)); if (isset($_REQUEST['ordinal'])) { $min = $_REQUEST['ordinal']; $limit = 1; } if (isset($_REQUEST['min'])) { $min = $_REQUEST['min']; } $max = isset($_REQUEST['max']) ? $_REQUEST['max'] : -1; if (isset($_REQUEST['ascending'])) { $ascending = $_REQUEST['ascending']; } if (!$stream->testReadLevel('messages')) { throw new Users_Exception_NotAuthorized(); } $messages = $stream->getMessages(compact('type', 'min', 'max', 'limit', 'ascending')); return Db::exportArray($messages); }
function Streams_after_Q_responseExtras() { if ($preloaded = Streams_Stream::$preloaded) { $preloaded = Db::exportArray($preloaded); Q_Response::setScriptData('Q.plugins.Streams.Stream.preloaded', $preloaded); } }
function Users_after_Q_responseExtras() { if ($preloaded = Users_User::$preloaded) { Q_Response::setScriptData('Q.plugins.Users.User.preloaded', Db::exportArray($preloaded, array('asAvatar' => true))); } Q_Response::setScriptData('Q.plugins.Users.roles', Users::roles()); }
function Streams_after_Q_objects() { $user = Users::loggedInUser(); if (!$user) { return; } $invite = Streams::$followedInvite; if (!$invite) { return; } $displayName = $user->displayName(); if ($displayName) { return; } $stream = new Streams_Stream(); $stream->publisherId = $invite->publisherId; $stream->name = $invite->streamName; if (!$stream->retrieve()) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName'); } // Prepare the complete invite dialog $invitingUser = Users_User::fetch($invite->invitingUserId); list($relations, $related) = Streams::related($user->id, $stream->publisherId, $stream->name, false); $params = array('displayName' => null, 'action' => 'Streams/basic', 'icon' => $user->iconUrl(), 'token' => $invite->token, 'user' => array('icon' => $invitingUser->iconUrl(), 'displayName' => $invitingUser->displayName(array('fullAccess' => true))), 'stream' => $stream->exportArray(), 'relations' => Db::exportArray($relations), 'related' => Db::exportArray($related)); $config = Streams_Stream::getConfigField($stream->type, 'invite', array()); $defaults = Q::ifset($config, 'dialog', array()); $tree = new Q_Tree($defaults); if ($tree->merge($params)) { $dialogData = $tree->getAll(); if ($dialogData) { Q_Response::setScriptData('Q.plugins.Streams.invite.dialog', $dialogData); Q_Response::addTemplate('Streams/invite/complete'); } } }
function Streams_after_Users_Contact_removeExecute($params) { // Update avatar as viewed by everyone who was in that contacts list $contacts = Streams::$cache['contacts_removed']; foreach ($contacts as $contact) { Streams::updateAvatar($contact->contactUserId, $contact->userId); } Streams_Message::post(null, $contact->userId, 'Streams/contacts', array('type' => 'Streams/contacts/removed', 'instructions' => array('contacts' => Db::exportArray($contacts))), true); }
function Users_after_Q_responseExtras() { if ($preloaded = Users_User::$preloaded) { Q_Response::setScriptData('Q.plugins.Users.User.preloaded', Db::exportArray($preloaded, array('asAvatar' => true))); } Q_Response::setScriptData('Q.plugins.Users.roles', Users::roles()); $user = Users::loggedInUser(); Q_Response::addHtmlCssClass($user ? 'Users_loggedIn' : 'Users_loggedOut'); }
/** * Adds contacts to the system. Fills the "contacts" slot. * @param {array} $_REQUEST * @param {string} $_REQUEST.label The label of the contact * @param {string} $_REQUEST.contactUserId The contactUserId of the contact * @param {string} [$_REQUEST.nickname] The nickname of the contact * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this */ function Users_contact_post($params = array()) { $req = array_merge($_REQUEST, $params); Q_Request::requireFields(array('label', 'contactUserId'), $req, true); $loggedInUserId = Users::loggedInUser(true)->id; $userId = Q::ifset($req, 'userId', $loggedInUserId); $contactUserId = $req['contactUserId']; $nickname = Q::ifset($req, 'nickname', null); $contacts = Users_Contact::addContact($userId, $req['label'], $contactUserId, $nickname); Q_Response::setSlot('contacts', Db::exportArray($contacts)); }
function Users_user_response_users($params = array()) { $req = array_merge($_REQUEST, $params); Q_Valid::requireFields(array('userIds'), $req, true); $userIds = $req['userIds']; if (is_string($userIds)) { $userIds = explode(",", $userIds); } $fields = Q_Config::expect('Users', 'avatarFields'); $users = Users_User::select($fields)->where(array('id' => $userIds))->fetchDbRows(null, null, 'id'); return Q_Response::setSlot('users', Db::exportArray($users, array('asAvatar' => true))); }
function Streams_stream_response_streams() { // happens only during non-GET requests $publisherId = Streams::requestedPublisherId(true); $name = Streams::requestedName(true); $fields = Streams::requestedFields(); $limit = isset($_REQUEST['limit']) ? $_REQUEST['limit'] : null; $user = Users::loggedInUser(); $userId = $user ? $user->id : ""; $streams = Streams::fetch($userId, $publisherId, $name, $fields ? $fields : '*', $limit ? compact('limit') : array()); return Streams::$cache['streams'] = Db::exportArray($streams); }
function Streams_stream_response_streams() { // happens only during non-GET requests $publisherId = Streams::requestedPublisherId(true); $name = Streams::requestedName(true); $fields = Streams::requestedFields(); $limit = isset($_REQUEST['limit']) ? $_REQUEST['limit'] : null; $user = Users::loggedInUser(); $userId = $user ? $user->id : ""; $options = array('withParticipant' => true); if (isset($limit)) { $options['limit'] = $limit; } $streams = Streams::fetch($userId, $publisherId, $name, $fields ? $fields : '*', $options); return Streams::$cache['streams'] = Db::exportArray($streams); }
function Streams_avatar_response() { $prefix = $limit = $userIds = $batch = $public = null; extract($_REQUEST, EXTR_IF_EXISTS); $user = Users::loggedInUser(); $asUserId = $user ? $user->id : ""; if (isset($prefix)) { $avatars = Streams_Avatar::fetchByPrefix($asUserId, $prefix, compact('limit', 'public')); } else { if (isset($batch)) { $batch = json_decode($batch, true); if (!isset($batch)) { throw new Q_Exception_WrongValue(array('field' => 'batch', 'range' => '{userIds: [userId1, userId2, ...]}')); } if (!isset($batch['userIds'])) { throw new Q_Exception_RequiredField(array('field' => 'userIds')); } $userIds = $batch['userIds']; } if (!isset($userIds)) { throw new Q_Exception_RequiredField(array('field' => 'userIds')); } if (is_string($userIds)) { $userIds = explode(",", $userIds); } $avatars = Streams_Avatar::fetch($asUserId, $userIds); } $avatars = Db::exportArray($avatars); if (isset($batch)) { $result = array(); foreach ($userIds as $userId) { $result[] = array('slots' => array('avatar' => isset($avatars[$userId]) ? $avatars[$userId] : null)); } Q_Response::setSlot('batch', $result); } else { Q_Response::setSlot('avatars', $avatars); } return $avatars; }
/** * Adds contacts to the system. Fills the "contacts" slot. * @param {array} $_REQUEST * @param {string} $_REQUEST.label The label of the contact * @param {string} $_REQUEST.contactUserId The contactUserId of the contact * @param {string} [$_REQUEST.nickname] The nickname of the contact * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this */ function Users_contact_post($params = array()) { $req = array_merge($_REQUEST, $params); Q_Request::requireFields(array('label', 'contactUserId'), $req, true); $loggedInUserId = Users::loggedInUser(true)->id; $userId = Q::ifset($req, 'userId', $loggedInUserId); $contactUserId = $req['contactUserId']; $nickname = Q::ifset($req, 'nickname', null); $l = $req['label']; if ($userId !== $loggedInUserId) { Users_User::fetch($userId, true); } Users_User::fetch($contactUserId, true); Users::canManageContacts($loggedInUserId, $userId, $l, true); $label = new Users_Label(); $label->userId = $userId; $label->label = $l; if (!$label->retrieve()) { throw new Q_Exception_MissingRow(array('table' => 'Users_Label', 'criteria' => json_encode($label->fields))); } $contacts = Users_Contact::addContact($userId, $l, $contactUserId, $nickname); Q_Response::setSlot('contacts', Db::exportArray($contacts)); }
function Streams_participant_response_participants() { if (isset(Streams::$cache['participant'])) { $participant = Streams::$cache['participant']; return Db::exportArray(array($participant->userId => $participant)); } $publisherId = Streams::requestedPublisherId(true); $streamName = Streams::requestedName(true); $limit = isset($_REQUEST['limit']) ? $_REQUEST['limit'] : 10; $offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : -1; $state = isset($_REQUEST['state']) ? $_REQUEST['state'] : null; $user = Users::loggedInUser(); $userId = $user ? $user->id : ""; $stream = Streams::fetchOne($userId, $publisherId, $streamName); if (empty($stream)) { throw new Q_Exception_MissingRow(array('table' => 'Stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}")); } if (!$stream->testReadLevel('participants')) { throw new Users_Exception_NotAuthorized(); } $participants = $stream->getParticipants(compact('limit', 'offset', 'state')); Db::exportArray($participants); }
function Users_avatar_response($params) { $userIds = $batch = null; extract($_REQUEST, EXTR_IF_EXISTS); if ($batch) { $batch = json_decode($batch, true); if (!isset($batch)) { throw new Q_Exception_WrongValue(array('field' => 'batch', 'range' => '{userIds: [userId1, userId2, ...]}')); } if (!isset($batch['userIds'])) { throw new Q_Exception_RequiredField(array('field' => 'userIds')); } $userIds = $batch['userIds']; } else { if (!isset($userIds)) { throw new Q_Exception_RequiredField(array('field' => 'userIds'), 'userIds'); } } if (is_string($userIds)) { $userIds = explode(",", $userIds); } $fields = Q_Config::expect('Users', 'avatarFields'); $users = Users_User::select($fields)->where(array('id' => $userIds))->fetchDbRows(null, null, 'id'); $avatars = Db::exportArray($users); if (!isset($batch)) { Q_Response::setSlot('avatars', $avatars); return $avatars; } if ($batch) { $result = array(); foreach ($userIds as $userId) { $result[] = array('slots' => array('avatar' => isset($avatars[$userId]) ? $avatars[$userId] : null)); } Q_Response::setSlot('batch', $result); } return $avatars; }
function Streams_message_response_messages() { if (isset(Streams::$cache['message'])) { $message = Streams::$cache['message']; return Db::exportArray(array($message->ordinal => $message)); } if (isset(Streams::$cache['messages'])) { return Db::exportArray(Streams::$cache['messages']); } $publisherId = Streams::requestedPublisherId(true); $streamName = Streams::requestedName(true); $type = Streams::requestedMessageType(); $maxLimit = Q_Config::get('Streams', 'defaults', 'getMessagesLimit', 100); $limit = min($maxLimit, Q::ifset($_REQUEST, 'limit', $maxLimit)); if (isset($_REQUEST['ordinal'])) { $min = $_REQUEST['ordinal']; $limit = 1; } if (isset($_REQUEST['min'])) { $min = $_REQUEST['min']; } $max = isset($_REQUEST['max']) ? $_REQUEST['max'] : -1; if (isset($_REQUEST['ascending'])) { $ascending = $_REQUEST['ascending']; } $user = Users::loggedInUser(); $userId = $user ? $user->id : ""; $stream = isset(Streams::$cache['stream']) ? Streams::$cache['stream'] : Streams::fetchOne($userId, $publisherId, $streamName); if (!$stream) { throw new Q_Exception_MissingRow(array('table' => 'Stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}")); } if (!$stream->testReadLevel('messages')) { throw new Users_Exception_NotAuthorized(); } $messages = $stream->getMessages(compact('type', 'min', 'max', 'limit', 'ascending')); return Db::exportArray($messages); }
function Streams_form_post($params = array()) { if (empty($_REQUEST['inputs'])) { throw new Q_Exception_RequiredField(array('field' => 'inputs')); } $inputs = Q::json_decode($_REQUEST['inputs'], true); $user = Users::loggedInUser(true); $r = array_merge($_REQUEST, $params); $streams = array(); foreach ($inputs as $name => $info) { $inputName = "input_{$name}"; if (!isset($r[$inputName])) { continue; } if (!is_array($info) or count($info) < 4) { throw new Q_Exception_WrongValue(array('field' => 'inputs', 'range' => 'array of name => (streamExists, publisherId, streamName, fieldName)')); } list($streamExists, $publisherId, $streamName, $fieldName) = $info; $stream = Streams::fetchOne(null, $publisherId, $streamName); if (!$stream) { if ($user->id !== $publisherId or !Q_Config::get('Streams', 'possibleUserStreams', $streamName, false)) { throw new Users_Exception_NotAuthorized(); } $stream = Streams::create(null, $publisherId, null, array('name' => $streamName)); } $attribute = substr($fieldName, 0, 10) === 'attribute:' ? substr($fieldName, 10) : null; if ($attribute) { $stream->setAttribute($attribute, $r[$inputName]); } else { $stream->{$fieldName} = $r[$inputName]; } $stream->save(); $streams[$stream->name] = $stream; } Q_Response::setSlot('streams', Db::exportArray($streams)); }
function Streams_related_response() { if (!Q_Request::slotName('relations') and !Q_Request::slotName('streams')) { return; } $user = Users::loggedInUser(); $asUserId = $user ? $user->id : ''; $publisherId = Streams::requestedPublisherId(true); $streamName = Streams::requestedName(true, 'original'); $isCategory = !empty($_REQUEST['isCategory']); $slotNames = Q_Request::slotNames(); $streams_requested = in_array('relatedStreams', $slotNames); $options = array('relationsOnly' => !$streams_requested, 'orderBy' => !empty($_REQUEST['ascending'])); if (isset($_REQUEST['limit'])) { $options['limit'] = $_REQUEST['limit']; } if (isset($_REQUEST['offset'])) { $options['offset'] = $_REQUEST['offset']; } if (isset($_REQUEST['min'])) { $options['min'] = $_REQUEST['min']; } if (isset($_REQUEST['max'])) { $options['max'] = $_REQUEST['max']; } if (isset($_REQUEST['type'])) { $options['type'] = $_REQUEST['type']; } if (isset($_REQUEST['prefix'])) { $options['prefix'] = $_REQUEST['prefix']; } $result = Streams::related($asUserId, $publisherId, $streamName, $isCategory, $options); if ($streams_requested) { $rel = Db::exportArray($result[0], array('numeric' => true)); } else { $rel = Db::exportArray($result, array('numeric' => true)); } if (!empty($_REQUEST['omitRedundantInfo'])) { if ($isCategory) { foreach ($rel as &$r) { unset($r['toPublisherId']); unset($r['toStreamName']); } } else { foreach ($rel as &$r) { unset($r['fromPublisherId']); unset($r['fromStreamName']); } } } Q_Response::setSlot('relations', $rel); if (!$streams_requested) { return; } $streams = $result[1]; $arr = Db::exportArray($streams, array('numeric' => true)); foreach ($arr as $k => $stream) { if (!$stream) { continue; } $s = $streams[$stream['name']]; $arr[$k]['access'] = array('readLevel' => $s->get('readLevel', $s->readLevel), 'writeLevel' => $s->get('writeLevel', $s->writeLevel), 'adminLevel' => $s->get('adminLevel', $s->adminLevel)); } Q_Response::setSlot('relatedStreams', $arr); $stream = $result[2]; if (is_array($stream)) { Q_Response::setSlot('streams', Db::exportArray($stream)); return; } else { if (is_object($stream)) { Q_Response::setSlot('stream', $stream->exportArray()); } else { Q_Response::setSlot('stream', false); } } if (!empty($_REQUEST['messages'])) { $max = -1; $limit = $_REQUEST['messages']; $messages = false; $type = isset($_REQUEST['messageType']) ? $_REQUEST['messageType'] : null; if ($stream->testReadLevel('messages')) { $messages = Db::exportArray($stream->getMessages(compact('type', 'max', 'limit'))); } Q_Response::setSlot('messages', $messages); } if (!empty($_REQUEST['participants'])) { $limit = $_REQUEST['participants']; $offset = -1; $participants = false; if ($stream->testReadLevel('participants')) { $participants = Db::exportArray($stream->getParticipants(compact('limit', 'offset'))); } Q_Response::setSlot('participants', $participants); } }
/** * Used to get a stream * * @param {array} $_REQUEST * @param {string} $_REQUEST.publisherId Required * @param {string} $_REQUEST.streamName Required streamName or name * @param {integer} [$_REQUEST.messages] optionally pass a number here to fetch latest messages * @param {integer} [$_REQUEST.participants] optionally pass a number here to fetch participants * @return {void} */ function Streams_stream_response() { // this handler is only for GET requests if (Q_Request::method() !== 'GET') { return null; } $publisherId = Streams::requestedPublisherId(true); $name = Streams::requestedName(true); $fields = Streams::requestedFields(); $user = Users::loggedInUser(); $userId = $user ? $user->id : ""; if (isset(Streams::$cache['stream'])) { $stream = Streams::$cache['stream']; } else { $streams = Streams::fetch($userId, $publisherId, $name, $fields ? $fields : '*', array('withParticipant' => true)); if (Q_Request::slotName('streams')) { Q_Response::setSlot('streams', Db::exportArray($streams)); } if (empty($streams)) { if (Q_Request::slotName('stream')) { Q_Response::setSlot('stream', null); Q_Response::setSlot('messages', null); Q_Response::setSlot('participants', null); Q_Response::setSlot('related', null); Q_Response::setSlot('relatedTo', null); } else { if (!Q_Request::slotName('streams')) { $app = Q_Config::expect('Q', 'app'); Q_Dispatcher::forward("{$app}/notFound"); } } return null; } // The rest of the data is joined only on the first stream Streams::$cache['stream'] = $stream = reset($streams); } if (empty($stream)) { if (Q_Request::slotName('stream')) { Q_Response::setSlot('stream', null); } return null; } if ($userId && !empty($_REQUEST['join'])) { $stream->join(); // NOTE: one of the rare times we may change state in a response handler } if (Q_Request::slotName('stream')) { Q_Response::setSlot('stream', $stream->exportArray()); } if (!empty($_REQUEST['messages'])) { $max = -1; $limit = $_REQUEST['messages']; $messages = false; $type = isset($_REQUEST['messageType']) ? $_REQUEST['messageType'] : null; if ($stream->testReadLevel('messages')) { $messages = Db::exportArray($stream->getMessages(compact('type', 'max', 'limit'))); } Q_Response::setSlot('messages', $messages); } if (!empty($_REQUEST['participants'])) { $limit = $_REQUEST['participants']; $participants = false; if ($stream->testReadLevel('participants')) { $participants = Db::exportArray($stream->getParticipants(compact('limit', 'offset'))); } Q_Response::setSlot('participants', $participants); } }
/** * Used by HTTP clients to look up streams published by a certain publisher, based on their title * @class HTTP Streams lookup * @method get * @param {array} [$_REQUEST] Parameters that can come from the request * @param {string} $_REQUEST.publisherId Required. The user id of the publisher of the streams * @param {string|array} $_REQUEST.types Required. The type (or types) of the streams to find * @param {string|array} $_REQUEST.title Required. The string to use with SQL's "LIKE" statement. May be rejected depending on configuration. */ function Streams_lookup_response_results() { Q_Request::requireFields(array('publisherId', 'types', 'title'), true); $streams = Streams::lookup($_REQUEST['publisherId'], $_REQUEST['types'], $_REQUEST['title']); return Db::exportArray($streams); }
/** * Post (potentially) multiple messages to multiple streams. * @method postMessages * @static * @param {string} $asUserId * The user to post the message as * @param {string} $messages * Array indexed as follows: * array($publisherId => array($streamName => $message)) * where $message are either Streams_Message objects, * or arrays containing all the fields of messages that will need to be posted. * @param {booleam} $skipAccess=false * If true, skips the access checks and just posts the message. * @return {array} * Returns an array(array(Streams_Message), array(Streams_Stream)) */ static function postMessages($asUserId, $messages, $skipAccess = false) { if (!isset($asUserId)) { $asUserId = Users::loggedInUser(); if (!$asUserId) { $asUserId = ""; } } if ($asUserId instanceof Users_User) { $asUserId = $asUserId->id; } // Build arrays we will need foreach ($messages as $publisherId => $arr) { if (!is_array($arr)) { throw new Q_Exception_WrongType(array('field' => "messages", 'type' => 'array of publisherId => streamName => message')); } foreach ($arr as $streamName => &$message) { if (!is_array($message)) { if (!$message instanceof Streams_Message) { throw new Q_Exception_WrongType(array('field' => "message under {$publisherId} => {$streamName}", 'type' => 'array or Streams_Message')); } $message = $message->fields; } } } // Check if there are any messages to post $atLeastOne = false; foreach ($messages as $publisherId => $arr) { foreach ($arr as $streamName => $m) { if (!$m) { continue; } $atLeastOne = true; break 2; } } if (!$atLeastOne) { return array(array(), array()); } // Start posting messages, publisher by publisher $eventParams = array(); $posted = array(); $streams = array(); $messages2 = array(); $totals2 = array(); $updates = array(); $clientId = Q_Request::special('clientId', ''); $sendToNode = true; foreach ($messages as $publisherId => $arr) { $streamNames = array_keys($messages[$publisherId]); $streams[$publisherId] = $fetched = Streams::fetch($asUserId, $publisherId, $streamNames, '*', array('refetch' => true, 'begin' => true)); foreach ($arr as $streamName => $m) { // Get the Streams_Stream object if (!isset($fetched[$streamName])) { $p = new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "publisherId {$publisherId} and name {$streamName}")); $updates[$publisherId]['missingRow'][] = $streamName; continue; } $p =& $posted[$publisherId][$streamName]; $p = array(); if (!$m) { $updates[$publisherId]['noMessages'][] = $streamName; continue; } $messages3 = is_array($m) && !Q::isAssociative($m) ? $m : array($m); $count = count($messages3); $updates[$publisherId][$count][] = $streamName; $i = 0; foreach ($messages3 as $message) { ++$i; $type = isset($message['type']) ? $message['type'] : 'text/small'; $content = isset($message['content']) ? $message['content'] : ''; $instructions = isset($message['instructions']) ? $message['instructions'] : ''; $weight = isset($message['weight']) ? $message['weight'] : 1; if (!isset($message['byClientId'])) { $message['byClientId'] = $clientId ? substr($clientId, 0, 255) : ''; } if (is_array($instructions)) { $instructions = Q::json_encode($instructions); } $byClientId = $message['byClientId']; $stream = $fetched[$streamName]; // Make a Streams_Message object $message = new Streams_Message(); $message->publisherId = $publisherId; $message->streamName = $streamName; $message->insertedTime = new Db_Expression("CURRENT_TIMESTAMP"); $message->sentTime = new Db_Expression("CURRENT_TIMESTAMP"); $message->byUserId = $asUserId; $message->byClientId = $byClientId ? substr($byClientId, 0, 31) : ''; $message->type = $type; $message->content = $content; $message->instructions = $instructions; $message->weight = $weight; $message->ordinal = $stream->messageCount + $i; // thanks to transaction // Set up some parameters for the event hooks $params = $eventParams[$publisherId][$streamName][] = array('publisherId' => $publisherId, 'message' => $message, 'skipAccess' => $skipAccess, 'sendToNode' => &$sendToNode, 'stream' => $stream); /** * @event Streams/post/$streamType {before} * @param {string} publisherId * @param {Streams_Stream} stream * @param {string} message * @return {false} To cancel further processing */ if (Q::event("Streams/post/{$stream->type}", $params, 'before') === false) { $results[$stream->name] = false; continue; } /** * @event Streams/message/$messageType {before} * @param {string} publisherId * @param {Streams_Stream} stream * @param {string} message * @return {false} To cancel further processing */ if (Q::event("Streams/message/{$type}", $params, 'before') === false) { $results[$stream->name] = false; continue; } if (!$skipAccess && !$stream->testWriteLevel('post')) { $p[] = new Users_Exception_NotAuthorized(); /** * @event Streams/notAuthorized {before} * @param {string} publisherId * @param {Streams_Stream} stream * @param {string} message */ Q::event("Streams/notAuthorized", $params, 'after'); continue; } // if we are still here, mark the message as "in the database" $message->wasRetrieved(true); $p[] = $message; // build the arrays of rows to insert $messages2[] = $mf = $message->fields; } $totals2[$count][] = array('publisherId' => $mf['publisherId'], 'streamName' => $mf['streamName'], 'messageType' => $mf['type'], 'messageCount' => $count); } } foreach ($totals2 as $count => $rows) { Streams_Total::insertManyAndExecute($rows, array('onDuplicateKeyUpdate' => array('messageCount' => new Db_Expression("messageCount + {$count}")))); } if ($messages2) { Streams_Message::insertManyAndExecute($messages2); } // time to update the stream rows and commit the transaction // on all the shards where the streams were fetched. foreach ($updates as $publisherId => $arr) { foreach ($arr as $count => $streamNames) { $suffix = is_numeric($count) ? " + {$count}" : ''; Streams_Stream::update()->set(array('messageCount' => new Db_Expression('messageCount' . $suffix)))->where(array('publisherId' => $publisherId, 'name' => $streamNames))->commit()->execute(); } } // handle all the events for successfully posting foreach ($posted as $publisherId => $arr) { foreach ($arr as $streamName => $messages3) { $stream = $streams[$publisherId][$streamName]; foreach ($messages3 as $i => $message) { $params = $eventParams[$publisherId][$streamName][$i]; /** * @event Streams/message/$messageType {after} * @param {string} publisherId * @param {Streams_Stream} stream * @param {string} message */ Q::event("Streams/message/{$message->type}", $params, 'after', false); /** * @event Streams/post/$streamType {after} * @param {string} publisherId * @param {Streams_Stream} stream * @param {string} message */ Q::event("Streams/post/{$stream->type}", $params, 'after', false); } } } /** * @event Streams/postMessages {after} * @param {string} publisherId * @param {Streams_Stream} stream * @param {string} posted */ Q::event("Streams/postMessages", array('streams' => $streams, 'messages' => $messages, 'skipAccess' => $skipAccess, 'posted' => $posted), 'after', false); if ($sendToNode) { Q_Utils::sendToNode(array("Q/method" => "Streams/Message/postMessages", "posted" => Q::json_encode($messages2), "streams" => Q::json_encode(Db::exportArray($streams)))); } return array($posted, $streams); }
/** * Access tool * @class Streams access * @constructor * @param {array} $options Options for the tool * @param {string} [$options.publisherId] the id of the user who is publishing the stream * @param {string} [$options.streamName] the name of the stream for which to edit access levels * @param {array} [$options.tabs] array of tab name => title. Defaults to read, write, admin tabs. * @param {array} [$options.ranges] associative array with keys "read", "write", "admin" and values as associative arrays of ($min, $max) for the displayed levels. * @param {boolean} [$options.controls] optionally set this to true to render only the controls */ function Streams_access_tool($options) { $tabs = array('read' => 'visible to', 'write' => 'editable by', 'admin' => 'members'); extract($options); $user = Users::loggedInUser(true); /** * @var string $streamName */ if (empty($streamName)) { $streamName = Streams::requestedName(true); } if (empty($publisherId)) { $publisherId = Streams::requestedPublisherId(); if (empty($publisherId)) { $publisherId = $user->id; } } reset($tabs); $tab = Q::ifset($_REQUEST, 'tab', key($tabs)); $stream = Streams::fetchOne($user->id, $publisherId, $streamName); if (!$stream) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name')); } $stream->addPreloaded($user->id); if (!$stream->testAdminLevel('own')) { throw new Users_Exception_NotAuthorized(); } $access_array = Streams_Access::select('*')->where(array('publisherId' => $stream->publisherId, 'streamName' => $stream->name))->andWhere("{$tab}Level != -1")->fetchDbRows(); $labelRows = Users_Label::fetch($stream->publisherId, '', true); $labels = array(); $icons = array(); foreach ($labelRows as $label => $row) { $labels[$label] = $row->title; $icons[$label] = "labels/{$label}"; } $userId_list = array(); foreach ($access_array as $a) { if ($a->ofUserId) { $userId_list[] = $a->ofUserId; } } $avatar_array = empty($userId_list) ? array() : Streams_Avatar::fetch($user->id, $userId_list); switch ($tab) { case 'read': $levels = Q_Config::get('Streams', 'readLevelOptions', array()); break; case 'write': $levels = Q_Config::get('Streams', 'writeLevelOptions', array()); break; case 'admin': $levels = Q_Config::get('Streams', 'adminLevelOptions', array()); break; } if (isset($ranges[$tab])) { $range_min = reset($ranges[$tab]); $range_max = end($ranges[$tab]); foreach ($levels as $k => $v) { if ($k < $range_min) { unset($levels[$k]); } if ($k > $range_max) { unset($levels[$k]); } } } $accessActionUrl = Q_Uri::url("Streams/access?publisherId={$publisherId}&streamName={$streamName}"); $dir = Q_Config::get('Users', 'paths', 'icons', 'files/Users/icons'); $accessArray = Db::exportArray($access_array); $avatarArray = Db::exportArray($avatar_array); if (empty($controls)) { Q_Response::addScript("plugins/Streams/js/Streams.js"); Q_Response::addScript("plugins/Streams/js/tools/access.js"); Q_Response::setToolOptions(compact('accessArray', 'avatarArray', 'labels', 'icons', 'tab', 'publisherId', 'streamName')); } else { Q_Response::setSlot('extra', array('stream' => $stream->exportArray(), 'accessArray' => $accessArray, 'avatarArray' => $avatarArray, 'labels' => $labels, 'icons' => $icons)); } return Q::view('Streams/tool/access.php', compact('stream', 'tabs', 'tab', 'labels', 'icons', 'levels', 'dir', 'publisherId', 'streamName', 'accessActionUrl', 'controls')); }