/** * 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|array} [$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()] * Fill this out in order to relate the newly created stream to a category stream, * and also inheritAccess from it. When using this option, a user may be authorized * to create a stream they would otherwise not be authorized to create. * This happens when the asUserId user has a writeLevel of at least "relate" in the * existing category stream, and the publisherId user has a template for this stream * type that is related to either the category stream, or a template for the * category stream's type. * @param {string} [$relate.publisherId] The id of the user publishing the category stream, defaults to $publisherId * @param {string} [$relate.streamName] The name of the category stream * @param {string} [$relate.type] The type of relation, defaults to "" * @param {string} [$relate.weight] To set the weight for the relation. You can pass a numeric value here, or something like "max+1" to make the weight 1 greater than the current MAX(weight) * @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(true)->id; } else { 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'])) { if (is_array($fields['attributes'])) { $fields['attributes'] = Q::json_encode($fields['attributes']); } else { if (is_string($fields['attributes'])) { Q::json_decode($fields['attributes']); // may throw an exception } } } // 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->set('createdAsUserId', $asUserId); $stream->save(); $stream->post($asUserId, array('type' => 'Streams/created', 'content' => '', 'instructions' => $stream->toArray()), true); // relate the stream to category stream, if any if (!empty($relate['streamName'])) { $relationType = isset($relate['type']) ? $relate['type'] : ''; $result = Streams::relate($asUserId, $relate['publisherId'], $relate['streamName'], $relationType, $stream->publisherId, $stream->name, array('weight' => isset($relate['weight']) ? $relate['weight'] : null, 'skipAccess' => $skipAccess)); } self::$fetch[$asUserId][$publisherId][$stream->name] = array('*' => $stream); return $stream; }