Example #1
0
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);
}
Example #2
0
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');
        }
    }
}
Example #3
0
function Streams_after_Q_file_save($params)
{
    $path = $subpath = $name = $writePath = $data = $tailUrl = $size = $audio = null;
    extract($params, EXTR_OVERWRITE);
    if (!empty(Streams::$cache['canWriteToStream'])) {
        // some stream's associated file was being changed
        $stream = Streams::$cache['canWriteToStream'];
    }
    if (empty($stream)) {
        return;
    }
    $url = Q_Valid::url($tailUrl) ? $tailUrl : '{{baseUrl}}/' . $tailUrl;
    $stream->setAttribute('Q.file.url', $url);
    $stream->setAttribute('Q.file.size', $size);
    if ($audio) {
        include_once Q_CLASSES_DIR . DS . 'Audio' . DS . 'getid3' . DS . 'getid3.php';
        $getID3 = new getID3();
        $meta = $getID3->analyze($writePath . $name);
        $bitrate = $meta['audio']['bitrate'];
        $bits = $size * 8;
        $duration = $bits / $bitrate;
        $stream->setAttribute('Q.audio.bitrate', $bitrate);
        $stream->setAttribute('Q.audio.duration', $duration);
    }
    if (Streams_Stream::getConfigField($stream->type, 'updateTitle', false)) {
        // set the title every time a new file is uploaded
        $stream->title = $name;
    }
    if (Streams_Stream::getConfigField($stream->type, 'updateIcon', false)) {
        // set the icon every time a new file is uploaded
        $parts = explode('.', $name);
        $urlPrefix = Q_Request::baseUrl() . '/plugins/Streams/img/icons/files';
        $dirname = STREAMS_PLUGIN_FILES_DIR . DS . 'Streams' . DS . 'icons' . DS . 'files';
        $extension = end($parts);
        $stream->icon = file_exists($dirname . DS . $extension) ? "{$urlPrefix}/{$extension}" : "{$urlPrefix}/_blank";
    }
    if (empty(Streams::$beingSavedQuery)) {
        $stream->changed();
    } else {
        $stream->save();
    }
}
Example #4
0
 /**
  * Subscribe to one or more streams, to start receiving notifications.
  * Posts "Streams/subscribe" message to the streams.
  * Also posts "Streams/subscribed" messages to user's "Streams/participating" stream.
  *	If options are not given check the subscription templates:
  *	1. generic publisher id and generic user
  *	2. exact publisher id and generic user
  *	3. generic publisher id and exact user
  *	default is to subscribe to ALL messages.
  *	If options are supplied - skip templates and use options.
  * Using subscribe if subscription is already active will modify existing
  * subscription - change type(s) or modify notifications
  * @method subscribe
  * @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()]
  * @param {array} [$options.filter] optional array with two keys
  * @param {array} [$options.filter.types] array of message types, if this is empty then subscribes to all types
  * @param {array} [$options.filter.notifications=0] limit number of notifications, 0 means no limit
  * @param {datetime} [$options.untilTime=null] time limit, if any for subscription
  * @param {array} [$options.rule=array()] optionally override the rule for new subscriptions
  * @param {array} [$options.rule.deliver=array('to'=>'default')] under "to" key,
  *   named the field under Streams/rules/deliver config, which will contain the names of destinations,
  *   which can include "email", "mobile", "email+pending", "mobile+pending"
  * @param {datetime} [$options.rule.readyTime] time from which user is ready to receive notifications again
  * @param {array} [$options.rule.filter] optionally set a filter for the rules to add
  * @param {boolean} [$options.skipRules] if true, do not attempt to create rules for new subscriptions
  * @param {boolean} [$options.skipAccess] if true, skip access check for whether user can join and subscribe
  * @return {array} An array of Streams_Participant rows from the database.
  */
 static function subscribe($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::join($asUserId, $publisherId, $streams2, array('subscribed' => true, 'noVisit' => true, 'skipAccess' => Q::ifset($options, 'skipAccess', false)));
     $shouldUpdate = false;
     if (isset($options['filter'])) {
         $filter = Q::json_encode($options['filter']);
         $shouldUpdate = true;
     }
     $db = Streams_Subscription::db();
     if (isset($options['untilTime'])) {
         $untilTime = $db->toDateTime($options['untilTime']);
         $shouldUpdate = true;
     }
     $subscriptions = array();
     $rows = Streams_Subscription::select('*')->where(array('publisherId' => $publisherId, 'streamName' => $streamNames, 'ofUserId' => $asUserId))->fetchAll(PDO::FETCH_ASSOC);
     foreach ($rows as $row) {
         $sn = $row['streamName'];
         $subscriptions[$sn] = $row;
     }
     $messages = array();
     $pMessages = array();
     $streamNamesMissing = array();
     $streamNamesUpdate = array();
     foreach ($streamNames as $sn) {
         $messages[$publisherId][$sn] = array('type' => 'Streams/subscribe');
         $pMessages[] = array('type' => 'Streams/subscribed', 'instructions' => array('publisherId' => $publisherId, 'streamName' => $sn));
         if (empty($subscriptions[$sn])) {
             $streamNamesMissing[] = $sn;
             continue;
         }
         if ($shouldUpdate) {
             $streamNamesUpdate[] = $sn;
         }
     }
     if ($streamNamesUpdate) {
         Streams_Subscription::update()->set(compact('filter', 'untilTime'))->where(array('publisherId' => $publisherId, 'streamName' => $streamNamesUpdate, 'ofUserId' => $asUserId))->execute();
     }
     $rules = array();
     if ($streamNamesMissing) {
         $types = array();
         foreach ($streamNamesMissing as $sn) {
             $stream = $streams2[$sn];
             $types[$stream->type][] = $sn;
         }
         $subscriptionRows = array();
         $ruleRows = array();
         foreach ($types as $type => $sns) {
             // insert subscriptions
             if (!isset($filter) or !isset($untilTime)) {
                 $templates = Streams_Subscription::select('*')->where(array('publisherId' => array('', $publisherId), 'streamName' => $type . '/', 'ofUserId' => array('', $asUserId)))->fetchAll(PDO::FETCH_ASSOC);
                 $template = null;
                 foreach ($templates as $t) {
                     if (!$template or $template['publisherId'] == '' and $t['publisherId'] !== '' or $template['userId'] == '' and $t['userId'] !== '') {
                         $template = $t;
                     }
                 }
             }
             if (!isset($filter)) {
                 $filter = Q::json_encode($template ? Q::json_decode($template['filter']) : Streams_Stream::getConfigField($type, array('subscriptions', 'filter'), array("types" => array("^(?!(Users/)|(Streams/)).*/", "Streams/relatedTo", "Streams/chat/message"), "notifications" => 0)));
             }
             if (!isset($untilTime)) {
                 $untilTime = ($template and $template['duration'] > 0) ? new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$template['duration']} SECOND") : null;
             }
             foreach ($sns as $sn) {
                 $subscriptions[$sn] = $subscriptionRows[] = new Streams_Subscription(array('publisherId' => $publisherId, 'streamName' => $sn, 'ofUserId' => $asUserId, 'untilTime' => $untilTime, 'filter' => $filter));
             }
             if (!empty($options['skipRules'])) {
                 continue;
             }
             // insert up to one rule per subscription
             $rule = null;
             if (isset($options['rule'])) {
                 $rule = $options['rule'];
                 if (isset($rule['readyTime'])) {
                     $rule['readyTime'] = $db->toDateTime($rule['readyTime']);
                 }
                 if (isset($rule['filter']) and is_array($rule['filter'])) {
                     $rule['filter'] = Q::json_encode($rule['filter']);
                 }
                 if (isset($rule['deliver']) and is_array($rule['deliver'])) {
                     $rule['deliver'] = Q::json_encode($rule['deliver']);
                 }
             }
             if (!isset($rule)) {
                 $templates = Streams_Rule::select('*')->where(array('ofUserId' => array('', $asUserId), 'publisherId' => array('', $publisherId), 'streamName' => $type . '/', 'ordinal' => 1))->fetchAll(PDO::FETCH_ASSOC);
                 foreach ($templates as $t) {
                     if (!$rule or $rule['userId'] == '' and $t['userId'] !== '' or $rule['publisherId'] == '' and $t['publisherId'] !== '') {
                         $rule = $t;
                     }
                 }
             }
             if (!isset($rule)) {
                 $rule = array('deliver' => '{"to": "default"}', 'filter' => '{"types": [], "labels": []}');
             }
             if ($rule) {
                 $rule['ofUserId'] = $asUserId;
                 $rule['publisherId'] = $publisherId;
                 if (empty($rule['readyTime'])) {
                     $rule['readyTime'] = new Db_Expression("CURRENT_TIMESTAMP");
                 }
                 foreach ($sns as $sn) {
                     $row = $rule;
                     $row['streamName'] = $sn;
                     $row['ordinal'] = 1;
                     $row['filter'] = '';
                     $rules[$sn] = $ruleRows[] = $row;
                     $messages[$publisherId][$sn]['instructions'] = Q::json_encode(array('rule' => $row));
                 }
             }
         }
         Streams_Subscription::insertManyAndExecute($subscriptionRows);
         Streams_Rule::insertManyAndExecute($ruleRows);
     }
     foreach ($streamNames as $sn) {
         $subscription = $subscriptions[$sn];
         $stream = $streams2[$sn];
         // skip error testing for rule save BUT inform node.
         // Node can notify user to check the rules
         Q_Utils::sendToNode(array("Q/method" => "Streams/Stream/subscribe", "subscription" => Q::json_encode($subscription), "stream" => Q::json_encode($stream->toArray()), "rule" => isset($rules[$sn]) ? Q::json_encode($rules[$sn]) : null));
     }
     Streams_Message::postMessages($asUserId, $messages, true);
     Streams_Message::postMessages($asUserId, array($asUserId => array('Streams/participating' => $pMessages)), true);
     return $participants;
 }
Example #5
0
/**
 * Used to update an existing stream
 *
 * @param string $params Must include "publisherId" as well as "name" or "streamName".
 *    Can also include 'type', 'title', 'icon', 'content', 'attributes', 'readLevel',
 *    'writeLevel', 'adminLevel', as well as any fields named in the
 *    'Streams'/'types'/$type/'fields' config field for this $type of stream.
 * @param {string} [$params.publisherId] The id of the user publishing the stream
 * @param {string} [$params.name] The name of the stream
 * @param {string} [$params.streamName] Alternatively, the name of the stream
 * @param {array} [$params.attributes] Array of attributeName => value to set in stream.
 * @param {array} [$params.icon] Optional array of icon data (see Q_Image::save params)
 * @return {}
 */
function Streams_stream_put($params)
{
    // only logged in user can edit stream
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId();
    if (empty($publisherId)) {
        $publisherId = $_REQUEST['publisherId'] = $user->id;
    }
    $name = Streams::requestedName(true);
    $req = array_merge($_REQUEST, $params);
    if (array_key_exists('closedTime', $req)) {
        $closedTime = $req['closedTime'];
        if (in_array($closedTime, array(false, 'false', 'null'))) {
            $req['closedTime'] = null;
        }
    }
    // do not set stream name
    $stream = Streams::fetchOne($user->id, $publisherId, $name);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$name}'}"));
    }
    // valid stream types should be defined in config by 'Streams/type' array
    $range = Q_Config::expect('Streams', 'types');
    if (!array_key_exists($stream->type, $range)) {
        throw new Q_Exception("This app doesn't support streams of type " . $stream->type);
    }
    // check if editing directly from client is allowed
    $edit = Streams_Stream::getConfigField($stream->type, 'edit', false);
    if (!$edit) {
        throw new Q_Exception("This app doesn't let clients directly edit streams of type '{$stream->type}'");
    }
    $suggest = false;
    if ($stream->publisherId != $user->id) {
        $stream->calculateAccess($user->id);
        if (!$stream->testWriteLevel('edit')) {
            if ($stream->testWriteLevel('suggest')) {
                $suggest = true;
            } else {
                throw new Users_Exception_NotAuthorized();
            }
        }
    }
    $restricted = array('readLevel', 'writeLevel', 'adminLevel', 'permissions', 'inheritAccess', 'closedTime');
    $owned = $stream->testAdminLevel('own');
    // owners can reopen streams
    foreach ($restricted as $r) {
        if (isset($req[$r]) and !$owned) {
            throw new Users_Exception_NotAuthorized();
        }
    }
    // handle setting of attributes
    if (isset($req['attributes']) and is_array($req['attributes'])) {
        foreach ($req['attributes'] as $k => $v) {
            $stream->setAttribute($k, $v);
        }
        unset($req['attributes']);
    }
    // Get all the extended field names for this stream type
    $fieldNames = Streams::getExtendFieldNames($stream->type);
    // Prevent editing restricted fields
    if (is_array($edit)) {
        $restrictedFields = array_diff($fieldNames, $edit);
        foreach ($restrictedFields as $fieldName) {
            if (in_array($fieldName, array('publisherId', 'name', 'streamName'))) {
                continue;
            }
            if (isset($req[$fieldName])) {
                throw new Users_Exception_NotAuthorized();
            }
        }
    }
    // Process any icon that was posted
    $icon = Q::ifset($fieldNames, 'icon', null);
    if (is_array($icon)) {
        unset($fieldNames['icon']);
        Q_Response::setSlot('icon', Q::event("Q/image/post", $icon));
    }
    // Process any file that was posted
    $file = Q::ifset($fieldNames, 'file', null);
    if (is_array($file)) {
        unset($fieldNames['file']);
        $data = Q::event("Q/file/post", $file);
        Q_Response::setSlot('file', $data);
    }
    if (!empty($fieldNames)) {
        foreach ($fieldNames as $f) {
            if (array_key_exists($f, $req)) {
                $stream->{$f} = $req[$f];
            }
        }
        $stream->changed($user->id, $suggest ? 'Streams/suggest' : 'Streams/changed');
    }
    if (!empty($req['join'])) {
        $stream->join();
    }
    Streams::$cache['stream'] = $stream;
}
Example #6
0
/**
 * Used by HTTP clients to create a new stream in the system.
 * @class HTTP Streams stream
 * @method post
 * @param {array} [$params] Parameters that can come from the request
 *   @param {string} $params.publisherId  Required. The id of the user to publish the stream.
 *   @param {string} $params.type Required. The type of the stream.
 *   @param {string} [$params.Q_Streams_related_publisherId] Optionally indicate the publisher of the stream to relate the newly created to. Used together with the related.streamName option.
 *   @param {string} [$params.Q_Streams_related_streamName] Optionally indicate the name of a stream to relate the newly crated stream to. This is often necessary in order to obtain permissions to create the stream.
 *   @param {bool} [$params.dontSubscribe=false] Pass 1 or true here in order to skip auto-subscribing to the newly created stream.
 *   @param {array} [$params.icon] This is used to upload a custom icon for the stream which will then be saved in different sizes. See fields for Q/image/post method
 *     @param {string} [$params.icon.data]  Required if $_FILES is empty. Base64-encoded  data URI - see RFC 2397
 *     @param {string} [$params.icon.path="uploads"] parent path under web dir (see subpath)
 *     @param {string} [$params.icon.subpath=""] subpath that should follow the path, to save the image under
 *     @param {string} [$params.icon.merge=""] path under web dir for an optional image to use as a background
 *     @param {string} [$params.icon.crop] array with keys "x", "y", "w", "h" to crop the original image
 *     @param {string} [$params.icon.save=array("x" => "")] array of $size => $basename pairs
 *      where the size is of the format "WxH", and either W or H can be empty.
 *   @param {array} [$params.file] This is used to upload a custom icon for the stream which will then be saved in different sizes. See fields for Q/image/post method
 *     @param {string} [$params.file.data]  Required if $_FILES is empty. Base64-encoded  data URI - see RFC 2397
 *     @param {string} [$params.file.path="uploads"] parent path under web dir (see subpath)
 *     @param {string} [$params.file.subpath=""] subpath that should follow the path, to save the file under
 *     @param {string} [$params.file.name] override name of the file, after the subpath
 */
function Streams_stream_post($params = array())
{
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId();
    if (empty($publisherId)) {
        $publisherId = $_REQUEST['publisherId'] = $user->id;
    }
    $req = array_merge($_REQUEST, $params);
    $type = Streams::requestedType(true);
    $types = Q_Config::expect('Streams', 'types');
    if (!array_key_exists($type, $types)) {
        throw new Q_Exception("This app doesn't support streams of type {$type}", 'type');
    }
    $create = Streams_Stream::getConfigField($type, 'create', false);
    if (!$create) {
        throw new Q_Exception("This app doesn't let clients directly create streams of type {$type}", 'type');
    }
    // Should this stream be related to another stream?
    $relate = array();
    $relate['streamName'] = Q_Request::special("Streams.related.streamName", null, $req);
    if (isset($relate['streamName'])) {
        $relate['publisherId'] = Q_Request::special("Streams.related.publisherId", $publisherId, $req);
        $relate['type'] = Q_Request::special("Streams.related.type", "", $req);
        $relate['weight'] = "+1";
        // TODO: introduce ways to have "1" and "+1" for some admins etc.
    }
    // Split the id for saving files in the filesystem
    $splitId = Q_Utils::splitId($publisherId);
    // Hold on to any icon that was posted
    $icon = null;
    if (!empty($req['icon']) and is_array($req['icon'])) {
        $icon = $req['icon'];
        unset($req['icon']);
    }
    // Hold on to any file that was posted
    $file = null;
    if (!empty($req['file']) and is_array($req['file'])) {
        $file = $req['file'];
        unset($req['file']);
    }
    // Check if the user owns the stream
    if ($user->id === $publisherId) {
        $asOwner = true;
    } else {
        $streamTemplate = Streams_Stream::getStreamTemplate($publisherId, $type, 'Streams_Stream');
        $asOwner = $streamTemplate ? $streamTemplate->testAdminLevel('own') : false;
    }
    // Check if client can set the name of this stream
    if (isset($req['name'])) {
        $possible = Q_Config::get('Streams', 'possibleUserStreams', $req['name'], false);
        if (!$asOwner or !$possible) {
            throw new Users_Exception_NotAuthorized();
        }
    }
    // Get allowed fields
    $allowedFields = array_merge(array('publisherId', 'name', 'type', 'icon', 'file'), Streams::getExtendFieldNames($type, $asOwner));
    $fields = Q::take($req, $allowedFields);
    // Prevent setting restricted fields
    if (is_array($create)) {
        $restrictedFields = array_diff($allowedFields, $create);
        foreach ($restrictedFields as $fieldName) {
            if (in_array($fieldName, array('publisherId', 'type'))) {
                continue;
            }
            if (isset($req[$fieldName])) {
                throw new Users_Exception_NotAuthorized();
            }
        }
    }
    // Create the stream
    $stream = Streams::create($user->id, $publisherId, $type, $fields, $relate, $result);
    $messageTo = false;
    if (isset($result['messagesTo'])) {
        $messageTo = reset($result['messagesTo']);
        $messageTo = reset($messageTo);
        if (is_array($messageTo)) {
            $messageTo = reset($messageTo);
        }
        $messageTo = $messageTo->exportArray();
    }
    Q_Response::setSlot('messageTo', $messageTo);
    // Process any icon that was posted
    if ($icon === true) {
        $icon = array();
    }
    if (is_array($icon)) {
        if (empty($icon['path'])) {
            $icon['path'] = 'uploads/Streams';
        }
        if (empty($icon['subpath'])) {
            $icon['subpath'] = "{$splitId}/{$stream->name}/icon/" . time();
        }
        Q_Response::setSlot('icon', Q::event("Q/image/post", $icon));
        // the Streams/after/Q_image_save hook saves some attributes
    }
    // Process any file that was posted
    if ($file === true) {
        $file = array();
    }
    if (is_array($file)) {
        if (empty($file['path'])) {
            $file['path'] = 'uploads/Streams';
        }
        if (empty($file['subpath'])) {
            $file['subpath'] = "{$splitId}/{$stream->name}/file/" . time();
        }
        Q_Response::setSlot('file', Q::event("Q/file/post", $file));
        // the Streams/after/Q_file_save hook saves some attributes
    }
    // Re-fetch the stream object from the Streams::fetch cache,
    // since it might have been retrieved and modified to be different
    // from what is currently in $stream.
    // This also calculates the access levels on the stream.
    $stream = Streams::fetchOne($user->id, $publisherId, $stream->name);
    if (empty($req['dontSubscribe'])) {
        // autosubscribe to streams you yourself create, using templates
        $stream->subscribe();
    }
    Streams::$cache['stream'] = $stream;
}
Example #7
0
 /**
  * Find out whether a certain field is restricted from being
  * edited by clients via the regular Streams REST API.
  * @method restrictedFromClient
  * @static
  * @param {string} $streamType
  * @param {string} $fieldName
  * @param {string} [$whenCreating=false]
  * @return {boolean}
  */
 static function restrictedFromClient($streamType, $fieldName, $whenCreating = false)
 {
     $during = $whenCreating ? 'create' : 'edit';
     $info = Streams_Stream::getConfigField($streamType, $during, false);
     if (!$info) {
         return true;
     }
     if (is_array($info) and !in_array($fieldName, $info)) {
         return true;
     }
     return false;
 }
Example #8
0
 /**
  * Creates a new stream in the system
  * @method create
  * @static
  * @param {string} $asUserId The user who is attempting to create the stream.
  * @param {string} $publisherId The id of the user to publish the stream.
  * @param {string} $type The type of the stream to create.
  * @param {array} $fields Use this to set additional fields for the stream:
  * @param {string} [$fields.title=null] You can set the stream's title
  * @param {string} [$fields.icon=null] You can set the stream's icon
  * @param {string} [$fields.title=null] You can set the stream's content
  * @param {string} [$fields.attributes=null] You can set the stream's attributes directly as a JSON string
  * @param {string|integer} [$fields.readLevel=null] You can set the stream's read access level, see Streams::$READ_LEVEL
  * @param {string|integer} [$fields.writeLevel=null] You can set the stream's write access level, see Streams::$WRITE_LEVEL
  * @param {string|integer} [$fields.adminLevel=null] You can set the stream's admin access level, see Streams::$ADMIN_LEVEL
  * @param {string} [$fields.name=null] Here you can specify an exact name for the stream to be created. Otherwise a unique one is generated automatically.
  * @param {boolean} [$fields.skipAccess=false] Skip all access checks when creating and relating the stream.
  * @param {array} [$relate=array()]
  *  The user would also be authorized if the stream would be related to
  *  an existing category stream, in which the user has a writeLevel of at least "relate",
  *  and the user that would be publishing this new stream has a template for this stream type
  *  that is related to either the category stream or a template matching the category stream.
  *  To test for this, pass an array with the following keys:
  * @param {string} $relate.publisherId The id of the user publishing that stream, defaults to $publisherId
  * @param {string} $relate.streamName The name of the stream to which the new stream would be related
  * @param {string} [$relate.type] The type of relation, defaults to ""
  * @param {string} [$relate.weight] To set the weight for the relation
  * @return {Streams_Stream|boolean} Returns the stream that was created.
  * @throws {Users_Exception_NotAuthorized}
  */
 static function create($asUserId, $publisherId, $type, $fields = array(), $relate = null, &$result = null)
 {
     $skipAccess = Q::ifset($fields, 'skipAccess', false);
     if (!isset($asUserId)) {
         $asUserId = Users::loggedInUser();
         if (!$asUserId) {
             $asUserId = "";
         }
     }
     if ($asUserId instanceof Users_User) {
         $asUserId = $asUserId->id;
     }
     if ($publisherId instanceof Users_User) {
         $publisherId = $publisherId->id;
     }
     $authorized = self::isAuthorizedToCreate($asUserId, $publisherId, $type, $relate);
     if (!$authorized and !$skipAccess) {
         throw new Users_Exception_NotAuthorized();
     }
     // OK we are good to go!
     $stream = new Streams_Stream();
     $stream->publisherId = $publisherId;
     if (!empty($fields['name'])) {
         $p = new Q_Tree();
         $p->load(STREAMS_PLUGIN_CONFIG_DIR . DS . 'streams.json');
         $p->load(APP_CONFIG_DIR . DS . 'streams.json');
         if ($info = $p->get($fields['name'], array())) {
             foreach (Base_Streams_Stream::fieldNames() as $f) {
                 if (isset($info[$f])) {
                     $stream->{$f} = $info[$f];
                 }
             }
         }
     }
     if (!isset($stream->type)) {
         $stream->type = $type;
     }
     // prepare attributes field
     if (isset($fields['attributes']) and is_array($fields['attributes'])) {
         $fields['attributes'] = json_encode($fields['attributes']);
     }
     // extend with any config defaults for this stream type
     $fieldNames = Streams::getExtendFieldNames($type);
     $fieldNames[] = 'name';
     $defaults = Streams_Stream::getConfigField($stream->type, 'defaults', Streams_Stream::$DEFAULTS);
     foreach ($fieldNames as $f) {
         if (isset($fields[$f])) {
             $stream->{$f} = $fields[$f];
         } else {
             if (array_key_exists($f, $defaults)) {
                 $stream->{$f} = $defaults[$f];
             }
         }
     }
     // ready to persist this stream to the database
     if (!empty($relate['streamName'])) {
         $rs = Streams::fetchOne($asUserId, $relate['publisherId'], $relate['streamName']);
         if ($rs and $rs->inheritAccess) {
             // inherit from the same stream $rs does
             $inheritAccess = $rs->inheritAccess;
         } else {
             // inherit from $rs
             $inheritAccess = Q::json_encode(array(array($relate['publisherId'], $relate['streamName'])));
         }
         $stream->inheritAccess = $inheritAccess;
     }
     $stream->save();
     $stream->post($asUserId, array('type' => 'Streams/created', 'content' => '', 'instructions' => Q::json_encode($stream->toArray())), true);
     // relate the stream to category stream, if any
     if ($relate['streamName']) {
         $result = Streams::relate($asUserId, $relate['publisherId'], $relate['streamName'], $relate['type'], $stream->publisherId, $stream->name, array('weight' => isset($relate['weight']) ? $relate['weight'] : null, 'skipAccess' => $skipAccess));
     }
     self::$fetch[$asUserId][$publisherId][$stream->name] = array('*' => $stream);
     return $stream;
 }