Example #1
0
function Streams_participant_response_participant()
{
    if (isset(Streams::$cache['participant'])) {
        return Streams::$cache['participant'];
    }
    $publisherId = Streams::requestedPublisherId(true);
    $streamName = Streams::requestedName(true);
    if (empty($_REQUEST['userId'])) {
        throw new Q_Exception_RequiredField(array('field' => 'userId'));
    }
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : "";
    $stream = Streams::fetch($userId, $publisherId, $streamName);
    if (empty($stream)) {
        throw new Q_Exception_MissingRow(array('table' => 'Stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}"));
    }
    $stream = reset($stream);
    if (!$stream->testReadLevel('participants')) {
        throw new Users_Exception_NotAuthorized();
    }
    $p = new Streams_Participant();
    $p->publisherId = $publisherId;
    $p->streamName = $streamName;
    $p->userId = $_REQUEST['userId'];
    if ($p->retrieve()) {
        return $p->exportArray();
    }
    return null;
}
Example #2
0
/**
 * Provide player content to view the members of category listing
 * Uses Streams/$type/category.php view (Streams/$streamType/category/get.php can be used for viewing the category
 * stream itself if type of category is $streamType/category)
 * and Streams::related to retrieve streams data
 *
 **/
function Streams_category_response_player()
{
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : 0;
    // These are PK of the category!
    $publisherId = Streams::requestedPublisherId(true);
    $name = Streams::requestedName(true);
    // need to know publisher and type of the streams to list
    $streamType = Streams::requestedType();
    if ($streamType) {
        $prefix = "{$streamType}/";
    }
    $stream_publisherId = Q::expect('Streams', $streamType, 'publisher');
    if (substr($name, -1) === '/') {
        throw new Q_Exception("Player cannot show listing for multiple categories", compact('publisherId', 'name'));
    }
    /*
     * Get shall return only streams which user is authorized to see.
     */
    $categories = Streams::fetch($userId, $publisherId, $name);
    if (empty($categories)) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => compact('publisherId', 'name')));
    }
    $category = reset($categories);
    // Are you authorized to see category content?
    if (!$category->testReadLevel('content')) {
        throw new Users_Exception_NotAuthorized();
    }
    // get all the streams which are members of this category
    // as Streams::get verifies access rights, it's safe to show all streams' content
    list($relations, $streams) = Streams::related($userId, $publisherId, $name, true, array('prefix' => $prefix, 'skipAccess' => true));
    Q::view("Stream/{$type}/category.php", compact('relations', 'streams', 'userId'));
}
Example #3
0
/**
 * Tool for admins to edit the url, title, keywords, description of the current page
 * @class Websites seo
 * @constructor
 * @param {Object} [$options] Options for the tool
 * @param {String} [$options.skipIfNotAuthorized=true] Whether to skip rendering the contents of the tool if the logged-in user is not authorized to edit the SEO information for this page.
 */
function Websites_seo_tool($options)
{
    $skipIfNotAuthorized = Q::ifset($options, 'skipIfNotAuthorized', true);
    if ($skipIfNotAuthorized) {
        $websitesUserId = Users::communityId();
        $sha1 = sha1(Q_Dispatcher::uri());
        $seoStreamName = "Websites/seo/{$sha1}";
        $stream = Streams::fetchOne(null, $websitesUserId, $seoStreamName);
        $user = Users::loggedInUser();
        if (!$user or $stream and !$stream->testWriteLevel('suggest')) {
            $options['skip'] = true;
        }
        if (!$stream and !Streams::isAuthorizedToCreate($user->id, $websitesUserId, 'Websites/seo')) {
            $options['skip'] = true;
        }
    }
    unset($options['skipIfNotAuthorized']);
    Q_Response::addStylesheet('plugins/Websites/css/Websites.css');
    Q_Response::addScript("plugins/Websites/js/Websites.js");
    Q_Response::setToolOptions($options);
    $user = Users::loggedInUser(false, false);
    $userId = $user ? $user->id : "";
    $communityId = Users::communityId();
    $sha1 = sha1(Q_Dispatcher::uri());
    $seoStreamName = "Websites/seo/{$sha1}";
    $streams = Streams::fetch($userId, $communityId, array("Websites/header", "Websites/title", "Websites/slogan", $seoStreamName));
    foreach ($streams as $name => $s) {
        if ($s) {
            $s->addPreloaded($userId);
        }
    }
}
Example #4
0
/**
 * Used to create a new relation
 *
 * @param array $_REQUEST 
 *   toPublisherId, toStreamName, type
 *   fromPublisherId, fromStreamName, weight
 * @return {void}
 */
function Streams_related_post($params)
{
    $user = Users::loggedInUser(true);
    $asUserId = $user->id;
    $toPublisherId = $_REQUEST['toPublisherId'];
    $toStreamName = $_REQUEST['toStreamName'];
    $type = $_REQUEST['type'];
    $fromPublisherId = $_REQUEST['fromPublisherId'];
    $fromStreamName = $_REQUEST['fromStreamName'];
    // TODO: When we start supporting multiple hosts, this will have to be rewritten
    // to make servers communicate with one another when establishing relations between streams
    if (!($stream = Streams::fetch($asUserId, $toPublisherId, $toStreamName))) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with those fields'), array('publisherId', 'name'));
    }
    if (!($stream = Streams::fetch($asUserId, $fromPublisherId, $fromStreamName))) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with those fields'), array('fromPublisherId', 'from_name'));
    }
    $weight = "+1";
    if (isset($_REQUEST['weight'])) {
        if (!$stream->testWriteLevel('relations')) {
            throw new Users_Exception_NotAuthorized();
        }
        $weight = $_REQUEST['weight'];
    }
    $result = Streams::relate($asUserId, $toPublisherId, $toStreamName, $type, $fromPublisherId, $fromStreamName, compact('weight'));
    Q_Response::setSlot('result', $result);
}
Example #5
0
/**
 * Used to post messages to EXISTING stream
 * $_REQUEST shall contain the content of the message. Also may include 'streamNames' 
 * field which is an array of additional names of the streams to post message to.
 *
 * @param string $params 
 *   publisher id and stream name of existing stream shall be supplied
 * @return {void}
 */
function Streams_message_post()
{
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId(true);
    $streamName = Streams::requestedName(true);
    // check if type is allowed
    $streams = Streams::fetch($user->id, $publisherId, $streamName);
    if (empty($streams)) {
        throw new Streams_Exception_NoSuchStream();
    }
    $stream = reset($streams);
    if (empty($_REQUEST['type'])) {
        throw new Q_Exception_RequiredField(array('field' => 'type'), 'type');
    }
    $type = $_REQUEST['type'];
    if (!Q_Config::get("Streams", "types", $stream->type, "messages", $type, 'post', false)) {
        throw new Q_Exception("This app doesn't support directly posting messages of type '{$type}' for streams of type '{$stream->type}'");
    }
    $result = Streams_Message::post($user->id, $publisherId, $streamName, $_REQUEST);
    if (is_array($result)) {
        Streams::$cache['messages'] = $result;
    } else {
        Streams::$cache['message'] = $result;
    }
}
Example #6
0
function Streams_stream_response_data()
{
    // happens only during non-GET requests
    if (isset(Streams::$cache['removed_count'])) {
        return array('removed_count' => Streams::$cache['removed_count']);
    }
    if (isset(Streams::$cache['result'])) {
        return Streams::$cache['result'];
    }
    if (isset(Streams::$cache['stream'])) {
        $user = Users::loggedInUser();
        $userId = $user ? $user->id : "";
        return Streams::$cache['stream']->exportArray(array('asUserId' => $userId));
    }
    $publisherId = Streams::requestedPublisherId(true);
    $name = Streams::requestedName(true);
    $fields = Streams::requestedFields();
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : 0;
    $streams = array();
    foreach (Streams::fetch($userId, $publisherId, $name, $fields) as $key => $stream) {
        $streams[$key] = $stream->exportArray(array('asUserId' => $userId));
        if ($userId && !empty($_REQUEST['join'])) {
            $stream->join();
            // NOTE: one of the rare times we may change state in a response handler
        }
    }
    return Streams::$cache['result'] = array('stream' => empty($streams) ? null : reset($streams));
}
Example #7
0
/**
 * This tool renders a user avatar
 *
 * @param {array} $options An associative array of parameters, containing:
 * @param {string} [$options.userId]
 *   The user's id. Defaults to id of the logged-in user, if any.
 *   Can be '' for a blank-looking avatar.
 * @param {boolean} [options.short]
 *   Optional. Renders the short version of the display name.
 * @param {boolean|integer} [options.icon=false]
 *   Optional. Pass the size in pixels of the (square) icon to render
 *   before the username. Or pass true to render the default size.
 * @param {array} [options.iconAttributes]
 *   Optional. Array of attributes to render for the icon.
 * @param {boolean|array} [options.editable=false]
 *   Optional. Whether to provide an interface for editing the user's info. Can be array containing one or more of "icon", "name".
 * @param {boolean} [$options.show] The parts of the name to show. Can have the letters "f", "l", "u" in any order.
 * @param {boolean} [options.cacheBust=null]
 *   Number of milliseconds to use for Q_Uri::cacheBust for combating unintended caching on some environments.
 * @param {boolean} [options.renderOnClient]
 *   If true, only the html container is rendered, so the client will do the rest.
 */
function Users_avatar_tool($options)
{
    $defaults = array('icon' => false, 'short' => false, 'cacheBust' => null, 'editable' => false);
    $options = array_merge($defaults, $options);
    Q_Response::addStylesheet('plugins/Users/css/Users.css');
    $loggedInUser = Users::loggedInUser();
    $loggedInUserId = $loggedInUser ? $loggedInUser->id : "";
    if (empty($options['userId'])) {
        $options['userId'] = $loggedInUserId;
    }
    unset($options['iconAttributes']);
    if (empty($options['editable'])) {
        $options['editable'] = array();
    } else {
        if (is_string($options['editable'])) {
            $options['editable'] = array($options['editable']);
        } else {
            if ($options['editable'] === true) {
                $options['editable'] = array('icon', 'name');
            }
        }
    }
    Q_Response::setToolOptions($options);
    if (!empty($options['renderOnClient'])) {
        return '';
    }
    $avatar = Streams_Avatar::fetch($loggedInUserId, $options['userId']);
    if (!$avatar) {
        return '';
    }
    $result = '';
    if ($icon = $options['icon']) {
        if ($icon === true) {
            $icon = Q_Config::get('Users', 'icon', 'defaultSize', 40);
        }
        $attributes = isset($options['iconAttributes']) ? $options['iconAttributes'] : array();
        $class = "Users_avatar_icon Users_avatar_icon_{$icon}";
        $attributes['class'] = isset($attributes['class']) ? $attributes['class'] . ' ' . $class : $class;
        if (isset($options['cacheBust'])) {
            $attributes['cacheBust'] = $options['cacheBust'];
        }
        $result .= Q_Html::img(Users::iconUrl($avatar->icon, "{$icon}.png"), 'user icon', $attributes);
    }
    $o = $options['short'] ? array('short' => true) : array();
    $o['html'] = true;
    if (in_array('name', $options['editable'])) {
        $o['show'] = 'fl';
        $streams = Streams::fetch(null, $options['userId'], array('Streams/user/firstName', 'Streams/user/lastName', 'Streams/user/username'));
        foreach ($streams as $s) {
            $s->addPreloaded();
        }
    }
    if (!empty($options['show'])) {
        $o['show'] = $options['show'];
    }
    $displayName = $avatar->displayName($o, 'Someone');
    $result .= "<span class='Users_avatar_name'>{$displayName}</span>";
    return $result;
}
Example #8
0
function Streams_participating_response()
{
    if (!Q_Request::isAjax()) {
        return;
    }
    $max_limit = Q_Config::expect('Streams', 'db', 'limits', 'participating');
    $user = Users::loggedInUser(true);
    $type = Streams::requestedType();
    $limit = Streams::requestedField('limit', false, $max_limit);
    if ($limit > $max_limit) {
        throw new Q_Exception("limit is too large, must be <= {$max_limit}");
    }
    $offset = Streams::requestedField('offset', false, 0);
    $order = Streams::requestedField('order', false, true);
    $participating = array();
    $q = Streams_Participating::select('*')->where(array('userId' => $user->id));
    if ($type) {
        $q = $q->where(array('streamName' => new Db_Range($type . '/', true, false, true)));
    }
    if ($limit) {
        $q = $q->limit($limit, $offset);
    }
    if ($order) {
        $q = $q->orderBy('updatedTime', false);
    }
    $res_participating = $q->fetchDbRows();
    foreach ($res_participating as $part) {
        $part_safe = $part->exportArray();
        if (isset($part_safe)) {
            $participating[] = $part_safe;
        }
    }
    Q_Response::setSlot('participating', $participating);
    if (!Q_Request::slotName('streams')) {
        return;
    }
    $res_streams = array();
    $streamNames = array();
    foreach ($res_participating as $p) {
        $streamNames[$p->publisherId][] = $p->streamName;
    }
    foreach ($streamNames as $p_id => $names) {
        $res_streams[$p_id] = Streams::fetch($user->id, $p_id, $names);
    }
    $streams = array();
    $o = array('asUserId' => $user->id);
    foreach ($res_streams as $publisherId => $streams_array) {
        if (!empty($streams_array)) {
            $streams[$publisherId] = array();
            foreach ($streams_array as $streamName => $stream) {
                $streams[$publisherId][$streamName] = $stream->exportArray($o);
            }
        }
    }
    Q_Response::setSlot('streams', $streams);
}
Example #9
0
/**
 * Post one or more fields here to change the corresponding basic streams for the logged-in user. Fields can include:
 * "firstName": specify the first name directly
 * "lastName": specify the last name directly
 * "fullName": the user's full name, which if provided will be split into first and last name and override them
 * "gender": the user's gender
 * "birthday_year": the year the user was born
 * "birthday_month": the month the user was born
 * "birthday_day": the day the user was born
 */
function Streams_basic_post()
{
    Q_Valid::nonce(true);
    $user = Users::loggedInUser(true);
    $request = $_REQUEST;
    $fields = array();
    if (!empty($request['birthday_year']) && !empty($request['birthday_month']) && !empty($request['birthday_day'])) {
        $request['birthday'] = sprintf("%04d-%02d-%02d", $_REQUEST['birthday_year'], $_REQUEST['birthday_month'], $_REQUEST['birthday_day']);
    }
    //	$request['icon'] = $user->icon;
    if (isset($request['fullName'])) {
        $name = Streams::splitFullName($request['fullName']);
        $request['firstName'] = $name['first'];
        $request['lastName'] = $name['last'];
    }
    foreach (array('firstName', 'lastName', 'birthday', 'gender') as $field) {
        if (isset($request[$field])) {
            $fields[] = $field;
        }
    }
    $p = new Q_Tree();
    $p->load(STREAMS_PLUGIN_CONFIG_DIR . DS . 'streams.json');
    $p->load(APP_CONFIG_DIR . DS . 'streams.json');
    $names = array();
    foreach ($fields as $field) {
        $names[] = "Streams/user/{$field}";
    }
    $streams = Streams::fetch($user, $user->id, $names);
    foreach ($fields as $field) {
        $name = "Streams/user/{$field}";
        $type = $p->get($name, "type", null);
        if (!$type) {
            throw new Q_Exception("Missing {$name} type", $field);
        }
        $title = $p->get($name, "title", null);
        if (!$title) {
            throw new Q_Exception("Missing {$name} title", $field);
        }
        $stream = $streams[$name];
        if (isset($stream) and $stream->content === (string) $request[$field]) {
            continue;
        }
        if (!isset($stream)) {
            $stream = new Streams_Stream();
            $stream->publisherId = $user->id;
            $stream->name = $name;
        }
        $messageType = $stream->wasRetrieved() ? 'Streams/changed' : 'Streams/created';
        $stream->content = (string) $request[$field];
        $stream->type = $type;
        $stream->title = $title;
        $stream->changed($user->id, $messageType);
    }
}
Example #10
0
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);
}
Example #11
0
function Streams_message_tool($options)
{
    extract($options);
    $user = Users::loggedInUser();
    if (!$user) {
        throw new Users_Exception_NotLoggedIn();
    }
    if (empty($publisherId)) {
        $publisherId = Streams::requestedPublisherId();
    }
    if (empty($publisherId)) {
        $publisherId = $_REQUEST['publisherId'] = $user->id;
    }
    if (empty($name)) {
        $name = Streams::requestedName(true);
    }
    $stream = Streams::fetch($user->id, $publisherId, $name);
    $stream = !empty($stream) ? reset($stream) : null;
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName');
    }
    if (!$stream->testReadLevel('messages') || !$stream->testWriteLevel('post')) {
        throw new Users_Exception_NotAuthorized();
    }
    $hidden = array('publisherId' => $publisherId, 'streamName' => $name);
    $fields = array('stream' => array('label' => 'Stream', 'type' => 'static', 'value' => $stream->title));
    $type = Streams::requestedType();
    // check if stream has messages
    $types = Q_Config::get('Streams', 'messages', $stream->type, array());
    if (count($types) === 0) {
        throw new Q_Exception("Stream of type '{$stream->type}' does not support messages");
    }
    if (!empty($type) && !in_array($type, $types)) {
        throw new Q_Exception("Requested message type '{$type}' is not alowed for streams of type '{$stream->type}'");
    }
    if (!empty($type)) {
        $hidden['type'] = $type;
        $fields['type'] = array('label' => 'Message type', 'type' => 'static', 'value' => $type);
    } else {
        $fields['type'] = array('label' => 'Message type', 'type' => 'select', 'options' => array_merge(array('' => 'Select type'), array_combine($types, $types)), 'value' => '');
    }
    $fields['content'] = array('label' => 'Content', 'type' => 'textarea');
    $fields['submit'] = array('label' => '', 'type' => 'submit_buttons', 'options' => array('submit' => 'Post'));
    return Q_Html::tag('h3', array(), 'Post a message') . Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/message', 'post', array(), Q_Html::hidden($hidden) . Q::tool('Q/form', array('fields' => $fields, 'onSuccess' => 'function (data) {
					if (data.errors) alert(data.errors);
					else {
						alert("Message posted");
						var message = Q.getObject(["slots", "form", "fields"], data);
						Q.handle(Q.info.baseUrl+"/plugins/Streams/message?publisherId="+message.publisherId+"&name="+message.streamName);
					}
				}')));
}
Example #12
0
function Streams_leave_post()
{
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId();
    $streamName = Streams::requestedName(true);
    $streams = Streams::fetch($user->id, $publisherId, $streamName);
    if (empty($streams)) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}"));
    }
    $stream = reset($streams);
    $stream->leave(array(), $participant);
    Q_Response::setSlot('participant', $participant->exportArray());
}
Example #13
0
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);
}
Example #14
0
function Streams_join_post()
{
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId();
    $streamName = Streams::requestedName(true);
    $streams = Streams::fetch($user->id, $publisherId, $streamName);
    if (empty($streams)) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}"));
    }
    $stream = reset($streams);
    $options = array();
    if (isset($_REQUEST['extra'])) {
        $options['extra'] = json_decode($_REQUEST['extra'], true);
    }
    $stream->join($options, $participant);
    Q_Response::setSlot('participant', $participant->exportArray());
}
Example #15
0
function Broadcast_stream_response_content()
{
    $publisherId = Streams::requestedPublisherId(true);
    $name = Streams::requestedName(true);
    $fields = Streams::requestedFields();
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : 0;
    if (isset(Streams::$cache['stream'])) {
        $stream = Streams::$cache['stream'];
    } else {
        $streams = Streams::fetch($userId, $publisherId, $name, $fields, array('limit' => 30));
        if (empty($streams)) {
            throw new Q_Exception("No such stream", 'name');
        }
        $stream = reset($streams);
    }
    if ($publisherId != $userId and !$stream->testReadLevel('content')) {
        return "This belongs to someone else.";
    }
    if ($publisherId != $userId and !$stream->testReadLevel('content')) {
        throw new Users_Exception_NotAuthorized();
    }
    $userIds = array();
    $agreements = Broadcast_Agreement::select('userId')->where(array('publisherId' => $publisherId, 'streamName' => $name, 'platform' => 'facebook'))->fetchDbRows();
    foreach ($agreements as $a) {
        $userIds[] = $a->userId;
    }
    if ($userIds) {
        $agreed_users = Users_User::select('*')->where(array('id' => $userIds))->fetchDbRows();
    } else {
        $agreed_users = array();
    }
    $src = 'Broadcast/widget?';
    $q = array('publisherId' => $publisherId, 'streamName' => $name);
    foreach (array('css', 'button', 'checkmark', 'explanation') as $field) {
        if (isset($_REQUEST[$field])) {
            $q[$field] = $_REQUEST[$field];
        }
    }
    $src .= http_build_query($q, null, '&');
    $style = 'border: 0px;';
    $code = Q_Html::tag('iframe', compact('src', 'style'), '');
    Q_Response::addScript('plugins/Broadcast/js/Broadcast.js');
    return Q::view('Broadcast/content/stream.php', compact('publisherId', 'name', 'fields', 'user', 'stream', 'agreed_users', 'code'));
}
Example #16
0
function Streams_related_delete($params)
{
    $user = Users::loggedInUser(true);
    $asUserId = $user->id;
    $toPublisherId = $_REQUEST['toPublisherId'];
    $toStreamName = $_REQUEST['toStreamName'];
    $type = $_REQUEST['type'];
    $fromPublisherId = $_REQUEST['fromPublisherId'];
    $fromStreamName = $_REQUEST['fromStreamName'];
    // TODO: When we start supporting multiple hosts, this will have to be rewritten
    // to make servers communicate with one another when establishing relations between streams
    if (!($stream = Streams::fetch($asUserId, $toPublisherId, $toStreamName))) {
        Q_Response::setSlot('result', false);
    }
    if (!($stream = Streams::fetch($asUserId, $fromPublisherId, $fromStreamName))) {
        Q_Response::setSlot('result', false);
    }
    Streams::unrelate($asUserId, $toPublisherId, $toStreamName, $type, $fromPublisherId, $fromStreamName);
    Q_Response::setSlot('result', true);
}
Example #17
0
function Websites_before_Q_responseExtras()
{
    $user = Users::loggedInUser(false, false);
    $userId = $user ? $user->id : "";
    $websitesUserId = Q_Config::expect("Websites", "user", "id");
    $sha1 = sha1(Q_Dispatcher::uri());
    $seoStreamName = "Websites/seo/{$sha1}";
    $streams = Streams::fetch($userId, $websitesUserId, array("Websites/header", "Websites/title", "Websites/slogan", $seoStreamName));
    if (!empty($streams[$seoStreamName])) {
        $fields = Q::take($streams[$seoStreamName]->getAllAttributes(), array('keywords', 'description'));
        foreach ($fields as $k => $v) {
            Q_Response::setMeta($k, $v);
        }
        Q_Response::setSlot('title', $streams[$seoStreamName]->getAttribute('title'));
    }
    foreach ($streams as $name => $s) {
        if ($s) {
            $s->addPreloaded($userId);
        }
    }
    Q_Response::setScriptData('Q.plugins.Websites.seoStreamName', $seoStreamName);
    Q_Response::setScriptData('Q.plugins.Websites.userId', Q_Config::expect('Websites', 'user', 'id'));
    Q_Response::setScriptData('Q.plugins.Websites.seoReload', Q_Config::expect('Websites', 'seoReload'));
}
Example #18
0
/**
 * 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);
    }
}
Example #19
0
 private static function _getStreams(&$asUserId, $publisherId, $streams)
 {
     if (!isset($asUserId)) {
         $asUserId = Users::loggedInUser(true)->id;
     } else {
         if ($asUserId instanceof Users_User) {
             $asUserId = $asUserId->id;
         }
     }
     Users::fetch($asUserId, true);
     $names = array();
     $streams2 = array();
     foreach ($streams as $s) {
         if (is_string($s)) {
             $names[] = $s;
         } else {
             if ($s instanceof Streams_Stream) {
                 $streams2[$s->name] = $s;
             } else {
                 if (isset($s)) {
                     throw new Q_Exception_WrongType(array('field' => 'stream', 'type' => 'Streams_Stream or string'));
                 }
             }
         }
     }
     $rows = Streams::fetch($asUserId, $publisherId, $names, array('refetch' => true));
     $result = array_merge($streams2, $rows);
     foreach ($result as $k => $v) {
         if (!isset($v)) {
             unset($result[$k]);
         }
     }
     return $result;
 }
Example #20
0
 /**
  * Call this function to relate a stream to category streams for things happening
  * around the given location.
  * @method relateTo
  * @static
  * @param {string} $publisherId The publisherId of the category streams
  * @param {double} $latitude The latitude of the coordinates near which to relate
  * @param {double} $longitude The longitude of the coordinates near which to relate
  * @param {string} $fromPublisherId The publisherId of the stream to relate
  * @param {string} $fromStreamName The name of the stream to relate
  * @param {string} $relationType The type of the relation to add
  * @param {array} $options The options to pass to the Streams::relate and Streams::create functions. Also can contain the following options:
  * @param {array} [$options.miles] Override the default set of distances found in the config under Places/nearby/miles
  * @param {callable} [$options.create] If set, this callback will be used to create streams when they don't already exist. It receives the $options array and should return a Streams_Stream object. Otherwise the category stream is skipped.
  * @param {callable} [$options.transform="array_keys"] Can be used to override the function which takes the output of Places_Nearby::forPublishers, and this $options array, and returns the array of ($originalName => $newCategoryName) pairs.
  * @return {array|boolean} Returns the array of category streams
  */
 static function relateTo($publisherId, $latitude, $longitude, $fromPublisherId, $fromStreamName, $relationType, $options = array())
 {
     $miles = Q::ifset($options, 'miles', null);
     $nearby = Places_Nearby::forPublishers($latitude, $longitude, $miles);
     if (!isset($fromPublisherId)) {
         $fromPublisherId = Q_Config::expect('Q', 'app');
     }
     if ($transform = Q::ifset($options, 'transform', null)) {
         $create = Q::ifset($options, 'create', null);
         $transformed = call_user_func($transform, $nearby, $options);
     } else {
         $transformed = array_keys($nearby);
         $create = Q::ifset($options, 'create', array('Places_Nearby', '_create'));
     }
     $streams = Streams::fetch(null, $publisherId, $transformed);
     foreach ($nearby as $k => $info) {
         $name = isset($transformed[$k]) ? $transformed[$k] : $k;
         if (empty($streams[$name])) {
             if (empty($create)) {
                 continue;
             }
             $params = compact('publisherId', 'latitude', 'longitude', 'fromPublisherId', 'fromStreamName', 'relationType', 'transformed', 'miles', 'nearby', 'name', 'info', 'streams');
             $streams[$name] = call_user_func($create, $params, $options);
         }
         $stream = $streams[$name];
         Streams::relate(null, $stream->publisherId, $stream->name, $relationType, $fromPublisherId, $fromStreamName, $options);
     }
     return $streams;
 }
Example #21
0
 /**
  * Method is used to verify access rights and fetch stream specific data
  * @method get
  * @static
  *
  * @param {string} $asUserId
  *  The user who is attempting to fetch streams
  * @param {string|array} $publisherId
  *  Optional. The publisher of the stream to fetch
  * @param {string|array} $streamName
  *  Optional. The name of the stream to fetch. May be generic name if last char is '/'
  *   if array is provided fetches streams for each array member
  * @param {array} $options=array()
  *   Array of parameters including:<br/>
  *	"search" => Experimental, Optional. A search term to look in 'title' and 'content'.
  *	  If provided, $streamName shall be not empty and contain generic name (type) of the
  *	  streams to search. Streams/search/$type 'before' and 'after' hooks are called to
  *	  adjust search result<br/>
  *
  *   Following options work only if $publisherId and $streamName are strings and 'Stream' table is not
  *	 sharded:<br/>
  *
  *	"limit" => Optional. The number of streams to fetch<br/>
  *	"offset" => Optional. The offset to start from<br/>
  *	"orderBy" => Optional. The name(s) of the field(s) to order result<br/>
  * @param {boolean} $single=false
  * @return {array}
  *  Array of resulting stream indexed by name
  */
 static function get($asUserId, $publisherId, $streamName, $options = array(), $single = false)
 {
     $publishers = is_array($publisherId) ? $publisherId : array($publisherId);
     $names = is_array($streamName) ? $streamName : array($streamName);
     // set up extra query options
     $modifiers = array();
     // use of these options is useless if fetching in many tries
     if (is_string($publisherId) && is_string($streamName)) {
         foreach (array('limit', 'offset', 'orderBy') as $option) {
             if (isset($options[$option])) {
                 $modifiers[$option] = $options[$option];
             }
         }
     }
     $streams = array();
     if (!isset($options['search'])) {
         // simply fetch requested streams
         foreach ($publishers as $publisherId) {
             foreach ($names as $name) {
                 $bulk = Streams::fetch($asUserId, $publisherId, $name, '*', $modifiers);
                 foreach ($bulk as $key => $s) {
                     if (!$s->testReadLevel('see')) {
                         unset($bulk[$key]);
                     } else {
                         if (!$s->testReadLevel('content')) {
                             foreach (array_diff(array_keys($s->fields), array('publisherId', 'insertedTime', 'updatedTime', 'name', 'type', 'title', 'icon', 'messageCount', 'participantCount')) as $field) {
                                 unset($s->{$field});
                             }
                         }
                     }
                 }
                 $streams = array_merge($streams, $bulk);
             }
         }
     } else {
         // try to search according to search term
         $search = $options['search'];
         // WARNING: we should use a separate solution for searches!!
         $modifiers['orWhere'] = "title LIKE %{$search}% OR content LIKE %{$search}%";
         foreach ($publishers as $publisherId) {
             foreach ($names as $name) {
                 // we skip silently before/after hooks if $name is not generic
                 if (substr($name, -1) === '/') {
                     $type = substr($name, 0, -1);
                     /**
                      * @event Streams/search/$streamType {before}
                      * @param {string} publisherId
                      * @param {string} name
                      * @return {false} To cancel further processing
                      */
                     if (Q::event("Streams/search/{$type}", compact('publisherId', 'name'), 'before', false, $modifiers) === false) {
                         continue;
                     }
                     $result = Streams::fetch($asUserId, $publisherId, $name, '*', $modifiers);
                     /**
                      * @event Streams/search/$streamType {after}
                      * @param {string} publisherId
                      * @param {string} name
                      */
                     Q::event("Streams/search/{$type}", compact('publisherId', 'name', 'modifiers'), 'after', false, $result);
                     array_merge($streams, $result);
                 }
             }
         }
     }
     return $single ? reset($streams) : $streams;
 }
Example #22
0
 /**
  * Post (potentially) multiple messages to multiple streams.
  * With one call to this function you can post at most one message per stream.
  * @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;
             }
         }
     }
     // Start posting messages, publisher by publisher
     $eventParams = array();
     $posted = array();
     $streams = array();
     $messages2 = array();
     $totals2 = 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 => $message) {
             $p =& $posted[$publisherId][$streamName];
             $p = false;
             $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'];
             // Get the Streams_Stream object
             if (!isset($fetched[$streamName])) {
                 $p = new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "publisherId {$publisherId} and name {$streamName}"));
                 continue;
             }
             $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 + 1;
             // thanks to transaction
             // Set up some parameters for the event hooks
             $eventParams[$publisherId][$streamName] = array('publisherId' => $publisherId, 'message' => $message, 'skipAccess' => $skipAccess, 'sendToNode' => &$sendToNode, 'stream' => $stream);
             $params = $eventParams[$publisherId][$streamName];
             /**
              * @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);
             $posted[$publisherId][$streamName] = $message;
             // build the arrays of rows to insert
             $messages2[] = $mf = $message->fields;
             $totals2[] = array('publisherId' => $mf['publisherId'], 'streamName' => $mf['streamName'], 'messageType' => $mf['type'], 'messageCount' => 1);
         }
     }
     if ($totals2) {
         Streams_Total::insertManyAndExecute($totals2, array('onDuplicateKeyUpdate' => array('messageCount' => new Db_Expression('messageCount + 1'))));
     }
     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.
     Streams_Stream::update()->set(array('messageCount' => new Db_Expression("messageCount+1")))->where(array('publisherId' => $publisherId, 'name' => $streamNames))->commit()->execute();
     // handle all the events for successfully posting
     foreach ($posted as $publisherId => $arr) {
         foreach ($arr as $streamName => $m) {
             $message = $posted[$publisherId][$streamName];
             $params =& $eventParams[$publisherId][$streamName];
             /**
              * @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($streams)));
     }
     return array($posted, $streams);
 }
Example #23
0
function Streams_batch_response_batch()
{
    if (empty($_REQUEST['batch'])) {
        throw new Q_Exception_RequiredField(array('field' => 'batch'));
    }
    try {
        $batch = json_decode($_REQUEST['batch'], true);
    } catch (Exception $e) {
    }
    if (empty($batch)) {
        throw new Q_Exception_WrongValue(array('field' => 'batch', 'range' => 'valid JSON'));
    }
    if (empty($batch['args'])) {
        throw new Q_Exception_RequiredField(array('field' => 'args'));
    }
    // Gather the publisher ids and stream names to fetch
    $to_fetch = array();
    foreach ($batch['args'] as $args) {
        if (count($args) < 4) {
            continue;
        }
        list($action, $slots, $publisherId, $name) = $args;
        if (empty($to_fetch[$publisherId])) {
            $to_fetch[$publisherId] = array();
        }
        $to_fetch[$publisherId][] = $name;
    }
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : "";
    // Fetch the actual streams
    $streams = array();
    foreach ($to_fetch as $publisherId => $names) {
        if (empty($streams[$publisherId])) {
            $streams[$publisherId] = array();
        }
        $streams[$publisherId] = array_merge($streams[$publisherId], Streams::fetch($userId, $publisherId, $names, '*'));
    }
    // Now, build the result
    $result = array();
    foreach ($batch['args'] as $args) {
        try {
            $action = $args[0];
            $prev_request = $_REQUEST;
            $extra = !empty($args[4]) ? $args[4] : null;
            if (is_array($extra)) {
                foreach ($extra as $k => $v) {
                    $_REQUEST[$k] = $v;
                }
            }
            switch ($action) {
                case 'stream':
                    break;
                case 'message':
                    if (!is_array($extra)) {
                        $_REQUEST['ordinal'] = $extra;
                    }
                    break;
                case 'participant':
                    if (!is_array($extra)) {
                        $_REQUEST['userId'] = $extra;
                    }
                    break;
                default:
                    throw new Q_Exception_WrongValue(array('field' => 'action', 'range' => "'stream', 'message' or 'participant'"));
            }
            Q_Request::$slotNames_override = is_array($args[1]) ? $args[1] : explode(',', $args[1]);
            Q_Request::$method_override = 'GET';
            if (count($args) >= 4) {
                Streams::$requestedPublisherId_override = $publisherId = $args[2];
                Streams::$requestedName_override = $name = $args[3];
                if (empty($streams[$publisherId][$name])) {
                    throw new Q_Exception_MissingRow(array('table' => 'Stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$name}'}"));
                }
                Streams::$cache['stream'] = $streams[$publisherId][$name];
            }
            Q::event("Streams/{$action}/response", compact('streams', 'publisherId', 'name', 'extra', 'user', 'userId'));
            $slots = Q_Response::slots(true);
            unset($slots['batch']);
            $result[] = compact('slots');
        } catch (Exception $e) {
            $result[] = array('errors' => Q_Exception::toArray(array($e)));
        }
        $prev_request = $_REQUEST;
        Q_Request::$slotNames_override = null;
        Q_Request::$method_override = null;
        Streams::$requestedPublisherId_override = null;
        Streams::$requestedName_override = null;
    }
    return $result;
}
Example #24
0
 /**
  * Fetch (and create, if necessary) "Places/nearby" streams
  * corresponding ot the given parameters.
  * @method streams
  * @static
  * @param {string} $publisherId The publisherId of the category streams
  * @param {double} $latitude The latitude of the coordinates near which to relate
  * @param {double} $longitude The longitude of the coordinates near which to relate
  * @param {array} $options The options to pass to the Streams::relate and Streams::create functions. Also can contain the following options:
  * @param {boolean} [$options.forSubscribers] Set to true to return the streams that are relevant to subscribers instead of publishers, i.e. users who want to know when something relevant happens, rather than users who want to relate the streams they publish to categories.
  * @param {array|double} [$options.miles] Override the default array of distances found in the config under Places/nearby/miles. If options.forSubscribers is true, however, this should be one of the entries from the array in Places/nearby/miles config.
  * @param {callable} [$options.create] If set, this callback will be used to create streams when they don't already exist. It receives the $options array and should return a Streams_Stream object. If this option is set to null, new streams won't be created.
  * @param {callable} [$options.transform="array_keys"] Can be used to override the function which takes the output of Places_Nearby::forPublishers, and this $options array, and returns the array of ($originalStreamName => $newStreamName) pairs.
  * @param {array} [$streamNames=null] Optional reference to fill with the stream names
  * @return {array|boolean} Returns the array of category streams
  */
 static function streams($publisherId, $latitude, $longitude, $options = array(), &$streamNames = null)
 {
     $miles = Q::ifset($options, 'miles', null);
     $nearby = empty($options['forSubscribers']) ? Places_Nearby::forPublishers($latitude, $longitude, $miles) : Places_Nearby::forSubscribers($latitude, $longitude, $miles);
     if (!isset($fromPublisherId)) {
         $fromPublisherId = Users::communityId();
     }
     if ($transform = Q::ifset($options, 'transform', null)) {
         $create = Q::ifset($options, 'create', null);
         $transformed = call_user_func($transform, $nearby, $options);
     } else {
         $transformed = array_keys($nearby);
         $create = Q::ifset($options, 'create', array('Places_Nearby', '_create'));
     }
     $streams = Streams::fetch(null, $publisherId, $transformed);
     if (!isset($streamNames)) {
         $streamNames = array();
     }
     foreach ($nearby as $k => $info) {
         $name = isset($transformed[$k]) ? $transformed[$k] : $k;
         if (empty($streams[$name])) {
             if (empty($create)) {
                 continue;
             }
             $params = compact('publisherId', 'latitude', 'longitude', 'fromPublisherId', 'fromStreamName', 'transformed', 'miles', 'nearby', 'name', 'info', 'streams');
             $streams[$name] = call_user_func($create, $params, $options);
         }
         if (!in_array($name, $streamNames)) {
             $streamNames[] = $name;
         }
     }
     return $streams;
 }
Example #25
0
function Streams_stream_tool($options)
{
    extract($options);
    $fields = array();
    $hidden = array();
    $user = Users::loggedInUser();
    if (!$user) {
        throw new Users_Exception_NotLoggedIn();
    }
    // if PK provided check for the stream
    if (isset($publisherId) && isset($name)) {
        $stream = Streams::fetch($user->id, $publisherId, $name);
        $stream = !empty($stream) ? reset($stream) : null;
        if (!$stream) {
            throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName');
        }
        if (!$stream->testReadLevel('content') || !$stream->testWriteLevel('edit')) {
            throw new Users_Exception_NotAuthorized();
        }
    } else {
        $stream = null;
    }
    // publisherId can be taken from request or shall be equal to user id
    $hidden['publisherId'] = $publisherId = isset($stream) ? $stream->publisherId : $user->id;
    // name for existing stream, for new streams name will be generated from type
    if (isset($stream)) {
        $hidden['name'] = $stream->name;
    }
    if (isset($publisherId)) {
        $fields['publisherId'] = array('label' => 'Publisher ID', 'type' => 'static', 'value' => $publisherId);
    }
    if (isset($name)) {
        $fields['name'] = array('label' => 'Stream name', 'type' => 'static', 'value' => $name);
    }
    // type shall be defined for new streams
    if (!isset($stream)) {
        $range = array_keys(Q_Config::expect('Streams', 'types'));
        if (!isset($type)) {
            // selection of available types
            $fields['type'] = array('label' => 'Stream type', 'type' => 'select', 'options' => array_combine($range, $range), 'value' => 'Streams/text');
        } else {
            // check if type is allowed
            if (!in_array($type, $range)) {
                throw new Q_Exception_WrongValue(array('field' => 'stream type', 'range' => join(', ', $range)));
            }
            $hidden['type'] = $type;
        }
    }
    // stream title
    $fields['title'] = array('label' => 'Title', 'type' => 'text', 'value' => $stream ? $stream->title : '');
    // stream content
    $fields['content'] = array('label' => 'Content', 'type' => 'textarea', 'value' => $stream ? $stream->content : '');
    $read_options = array_flip(Streams::$READ_LEVEL);
    if ($stream) {
        foreach ($read_options as $key => $value) {
            if (!$stream->testReadLevel($key)) {
                unset($read_options[$key]);
            }
        }
        $readLevel = min(isset($readLevel) ? $readLevel : 100, $stream->readLevel);
    }
    $fields['readLevel'] = array('label' => 'Read level', 'type' => 'select', 'value' => $readLevel ? $readLevel : Streams::$READ_LEVEL['content'], 'options' => $read_options);
    $write_options = array_flip(Streams::$WRITE_LEVEL);
    if ($stream) {
        foreach ($write_options as $key => $value) {
            if (!$stream->testWriteLevel($key)) {
                unset($write_options[$key]);
            }
        }
        $writeLevel = min(isset($writeLevel) ? $writeLevel : 100, $stream->writeLevel);
    }
    $fields['writeLevel'] = array('label' => 'Write level', 'type' => 'select', 'value' => $writeLevel ? $writeLevel : Streams::$WRITE_LEVEL['post'], 'options' => $write_options);
    $admin_options = array_flip(Streams::$ADMIN_LEVEL);
    if ($stream) {
        foreach ($admin_options as $key => $value) {
            if (!$stream->testAdminLevel($key)) {
                unset($admin_options[$key]);
            }
        }
        $adminLevel = min(isset($adminLevel) ? $adminLevel : 100, $stream->adminLevel);
    }
    array_pop($admin_options);
    $fields['adminLevel'] = array('label' => 'Admin level', 'type' => 'select', 'value' => $adminLevel ? $adminLevel : Streams::$ADMIN_LEVEL['none'], 'options' => $admin_options);
    $fields['submit'] = array('label' => '', 'type' => 'submit_buttons', 'options' => array('submit' => $stream ? 'Update' : 'Create'));
    if (empty($noJoin)) {
        $hidden['join'] = true;
    }
    return Q_Html::tag('h3', array(), !$stream ? 'Create a stream' : 'Update stream') . Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/stream', $stream ? 'put' : 'post', array(), Q_Html::hidden($hidden) . Q::tool('Q/form', array('fields' => $fields, 'onSuccess' => 'function (data) {
					if (data.errors) alert(data.errors);
					else {
						var stream = Q.getObject(["slots", "form", "fields"], data);
						Q.handle(Q.info.baseUrl+"/plugins/Streams/put?publisherId="+stream.publisherId+"&name="+stream.name);
					}
				}')));
}
Example #26
0
 /**
  * Retrieve the user's stream needed to post invite messages
  * If stream does not exists - create it. May return null if save failed.
  * @method getInvitedStream
  * @static
  * @param $asUserId {string}
  *	The user id of inviting user
  * @param $forUserId {string}
  *	User id for which stream is created
  * @return {Streams_Stream|null}
  */
 static function getInvitedStream($asUserId, $forUserId)
 {
     $invited = Streams::fetch($asUserId, $forUserId, 'Streams/invited');
     if (!empty($invited)) {
         return $invited['Streams/invited'];
     }
     $invited = new Streams_Stream();
     $invited->publisherId = $forUserId;
     $invited->name = 'Streams/invited';
     $invited->type = 'Streams/invited';
     $invited->title = 'Streams/invited';
     $invited->content = 'Post message here when user is invited to some stream';
     $invited->readLevel = Streams::$READ_LEVEL['none'];
     $invited->writeLevel = Streams::$WRITE_LEVEL['post'];
     // anyone can post messages
     $invited->adminLevel = Streams::$ADMIN_LEVEL['none'];
     $result = $invited->save(true);
     //Streams::calculateAccess($asUserId, $forUserId, array('Streams/invited' => $invited), false);
     return $result ? $invited : null;
 }