/** * Fetch all the streams which are related to, or from, a given stream. * @method related * @static * @param {string} $asUserId * The user who is fetching * @param {string} $publisherId * The publisher of the stream * @param {string|array|Db_Range} $streamName * The name of the stream which is presumably related to/from other streams * @param {mixed} $isCategory=true * If false, returns the categories that this stream is related to. * If true, returns all the streams this related to this category. * If a string, returns all the streams related to this category with names prefixed by this string. * @param {array} $options=array() * @param {boolean} [$options.orderBy=false] Defaults to false, which means order by decreasing weight. True means order by increasing weight. * @param {integer} [$options.limit] number of records to fetch * @param {integer} [$options.offset] offset to start from * @param {double} [$options.min] the minimum orderBy value (inclusive) to filter by, if any * @param {double} [$options.max] the maximum orderBy value (inclusive) to filter by, if any * @param {string|array|Db_Range} [$options.type] if specified, this filters the type of the relation. Can be useful for implementing custom indexes using relations and varying the value of "type". * @param {string} [$options.prefix] if specified, this filters by the prefix of the related streams * @param {array} [$options.where] you can also specify any extra conditions here * @param {array} [$options.extra] An array of any extra info to pass to Streams::fetch when fetching streams * @param {array} [$options.relationsOnly] If true, returns only the relations to/from stream, doesn't fetch the other data. Useful if publisher id of relation objects is not the same as provided by publisherId. * @param {array} [$options.streamsOnly] If true, returns only the streams related to/from stream, doesn't return the other data. * @param {array} [$options.streamFields] If specified, fetches only the fields listed here for any streams. * @param {array} [$options.skipFields] Optional array of field names. If specified, skips these fields when fetching streams * @param {array} [$options.includeTemplates] Defaults to false. Pass true here to include template streams (whose name ends in a slash) among the related streams. * @return {array} * Returns array($relations, $relatedStreams, $stream). * However, if $streamName wasn't a string or ended in "/" * then these third parameter is an array of streams. */ static function related($asUserId, $publisherId, $streamName, $isCategory = true, $options = array()) { if (is_string($streamName) and substr($streamName, -1) === '/') { $streamName = new Db_Range($streamName, false, false, true); } $returnMultiple = !is_string($streamName); if (is_array($isCategory)) { $options = $isCategory; $isCategory = true; } // Check access to stream $rows = Streams::fetch($asUserId, $publisherId, $streamName); $streams = array(); foreach ($rows as $n => $row) { if (!$row) { continue; } if (!$row->testReadLevel('see')) { throw new Users_Exception_NotAuthorized(); } $streams[$n] = $row; } if (!$streams) { if (!empty($options['relationsOnly']) || !empty($options['streamsOnly'])) { return array(); } return array(array(), array(), $returnMultiple ? array() : null); } $stream = reset($streams); if ($isCategory) { $query = Streams_RelatedTo::select('*')->where(array('toPublisherId' => $publisherId, 'toStreamName' => $streamName)); } else { $query = Streams_RelatedFrom::select('*')->where(array('fromPublisherId' => $publisherId, 'fromStreamName' => $streamName)); } if ($isCategory) { if (empty($options['orderBy'])) { $query = $query->orderBy('weight', false); } else { if ($options['orderBy'] === true) { $query = $query->orderBy('weight', true); } } } if (isset($options['prefix'])) { if (substr($options['prefix'], -1) !== '/') { throw new Q_Exception("prefix has to end in a slash", 'prefix'); } $other_field = $isCategory ? 'fromStreamName' : 'toStreamName'; $query = $query->where(array($other_field => new Db_Range($options['prefix'], true, false, true))); } $offset = !empty($options['offset']) ? $options['offset'] : 0; $max_limit = Q_Config::expect('Streams', 'db', 'limits', 'stream'); $limit = !empty($options['limit']) ? $options['limit'] : $max_limit; if ($limit > $max_limit) { throw new Q_Exception("Streams::related limit is too large, must be <= {$max_limit}"); } $min = isset($options['min']) ? $options['min'] : null; $max = isset($options['max']) ? $options['max'] : null; if (isset($min) or isset($max)) { $range = new Db_Range($min, true, true, $max); $query = $query->where(array('weight' => $range)); } if (isset($limit)) { $query = $query->limit($limit, $offset); } if (isset($options['type'])) { $query = $query->where(array('type' => $options['type'])); } if (isset($options['where'])) { $query = $query->where($options['where']); } $FT = $isCategory ? 'from' : 'to'; if (empty($options['includeTemplates'])) { $col = $FT . 'StreamName'; $query = $query->where(new Db_Expression("SUBSTRING({$col}, -1, 1) != '/'")); } $relations = $query->fetchDbRows(null, '', $FT . 'StreamName'); if (empty($options['includeTemplates'])) { foreach ($relations as $k => $v) { if (substr($k, -1) === '/') { unset($relations[$k]); } } } if (!empty($options['relationsOnly'])) { return $relations; } if (empty($relations)) { return empty($options['streamsOnly']) ? array($relations, array(), $returnMultiple ? $streams : $stream) : array(); } $fields = '*'; if (isset($options['skipFields'])) { $skip_fields = is_array($options['skipFields']) ? $options['skipFields'] : explode(',', $options['skipFields']); $fields = implode(',', array_diff(Streams_Stream::fieldNames(), $skip_fields)); } else { if (isset($options['streamFields'])) { $fields = is_string($options['streamFields']) ? $options['streamFields'] : implode(',', $options['streamFields']); } } $extra = isset($options['extra']) ? $options['extra'] : null; $names = array(); $FTP = $FT . 'PublisherId'; foreach ($relations as $name => $r) { if ($r->{$FTP} === $publisherId) { $names[] = $name; } } $relatedStreams = Streams::fetch($asUserId, $publisherId, $names, $fields, $extra); foreach ($relatedStreams as $name => $s) { if (!$s) { continue; } $s->weight = isset($relations[$name]->weight) ? $relations[$name]->weight : null; } if (!empty($options['streamsOnly'])) { return $relatedStreams; } return array($relations, $relatedStreams, $returnMultiple ? $streams : $stream); }
/** * Get current relation of shipment stream to Shipping/shipments category stream * @method getShipmentRelation * @static * @param object $stream shipment stream object * @param boolean $returnTitle flag which define what to return, if true - return relation title from config, else - return value from DB * @return string */ static function getShipmentRelation($stream, $returnTitle = false) { $env = self::getVars(); $type = Streams_RelatedTo::select(array("type"))->where(array('toPublisherId' => $env->communityId, 'toStreamName' => $env->shipmentsStreamName, 'fromPublisherId' => $stream->publisherId, 'fromStreamName' => $stream->name))->execute()->fetchAll(PDO::FETCH_ASSOC)[0]["type"]; if (!$returnTitle) { return $type; } $states = Q_Config::expect('Shipping', 'states'); foreach ($states as $state) { if ($state["type"] == $type) { return $state["title"]; } } }