Ejemplo n.º 1
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);
}
Ejemplo n.º 2
0
/**
 * Used to create a new stream
 *
 * @param {array} $_REQUEST 
 * @param {String} [$_REQUEST.title] Required. The title of the interest.
 * @param {String} [$_REQUEST.publisherId] Optional. Defaults to the app name.
 * @param {String} [$_REQUEST.subscribe] Optional. Defauls to false. Whether to subscribe rather than just join the interest stream.
 * @return {void}
 */
function Streams_interest_post()
{
    $user = Users::loggedInUser(true);
    $title = Q::ifset($_REQUEST, 'title', null);
    if (!isset($title)) {
        throw new Q_Exception_RequiredField(array('field' => 'title'));
    }
    $app = Q_Config::expect('Q', 'app');
    $publisherId = Q::ifset($_REQUEST, 'publisherId', $app);
    $name = 'Streams/interest/' . Q_Utils::normalize($title);
    $stream = Streams::fetchOne(null, $publisherId, $name);
    if (!$stream) {
        $stream = Streams::create($publisherId, $publisherId, 'Streams/interest', array('name' => $name, 'title' => $title));
        $parts = explode(': ', $title, 2);
        $keywords = implode(' ', $parts);
        try {
            $data = Q_Image::pixabay($keywords, array('orientation' => 'horizontal', 'min_width' => '500', 'safesearch' => 'true', 'image_type' => 'photo'), true);
        } catch (Exception $e) {
            Q::log("Exception during Streams/interest post: " . $e->getMessage());
            $data = null;
        }
        if (!empty($data)) {
            $sizes = Q_Config::expect('Streams', 'icons', 'sizes');
            ksort($sizes);
            $params = array('data' => $data, 'path' => "plugins/Streams/img/icons", 'subpath' => $name, 'save' => $sizes, 'skipAccess' => true);
            Q_Image::save($params);
            $stream->icon = $name;
        }
        $stream->save();
    }
    $subscribe = !!Q::ifset($_REQUEST, 'subscribe', false);
    if ($subscribe) {
        if (!$stream->subscription($user->id)) {
            $stream->subscribe();
        }
    } else {
        $stream->join();
    }
    $myInterestsName = 'Streams/user/interests';
    $myInterests = Streams::fetchOne($user->id, $user->id, $myInterestsName);
    if (!$myInterests) {
        $myInterests = new Streams_Stream();
        $myInterests->publisherId = $user->id;
        $myInterests->name = $myInterestsName;
        $myInterests->type = 'Streams/category';
        $myInterests->title = 'My Interests';
        $myInterests->save();
    }
    Streams::relate($user->id, $user->id, 'Streams/user/interests', 'Streams/interest', $publisherId, $name, array('weight' => '+1'));
    Q_Response::setSlot('publisherId', $publisherId);
    Q_Response::setSlot('streamName', $name);
    /**
     * Occurs when the logged-in user has successfully added an interest via HTTP
     * @event Streams/interest/post {after}
     * @param {string} publisherId The publisher of the interest stream
     * @param {string} title The title of the interest
     * @param {boolean} subscribe Whether the user subscribed to the interest stream
     * @param {Users_User} user The logged-in user
     * @param {Streams_Stream} stream The interest stream
     * @param {Streams_Stream} myInterests The user's "Streams/user/interests" stream
     */
    Q::event("Streams/interest/add", compact('publisherId', 'title', 'subscribe', 'user', 'stream', 'myInterests'), 'after');
}
Ejemplo n.º 3
0
 /**
  * Relate another stream, published by the same publisher, to this stream
  * @param {Streams_Stream} $fromStream The stream to relate to this stream
  * @param {string} $type The type of relation
  * @param {string} [$asUserId=null] Override the user id to perform this action as
  * @param {array} [$options=array()] Any options to pass to Streams::relate
  * @return {array|boolean}
  *  Returns false if the operation was canceled by a hook
  *  Returns true if relation was already there
  *  Otherwise returns array with keys "messageFrom" and "messageTo" and values of type Streams_Message
  */
 function relateFrom($fromStream, $type, $asUserId = null, $options = array())
 {
     return Streams::relate($asUserId, $this->publisherId, $this->name, $type, $fromStream->publisherId, $fromStream->name, $options);
 }
Ejemplo n.º 4
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)
 {
     $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 = Q_Config::get('Streams', 'types', $type, 'defaults', array());
     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 ($relate['streamName']) {
         $rs = Streams::fetchOne($asUserId, $relate['publisherId'], $relate['streamName']);
         if ($rs and $rs->inheritAccess) {
             // inherit from the same stream $rs does
             $inherit = $rs->inheritAccess;
         } else {
             // inherit from $rs
             $json = Q::json_encode(array(array($relate['publisherId'], $relate['streamName'])));
         }
         $stream->inheritAccess = $json;
     }
     $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));
         Q_Response::setSlot('messageTo', $result['messageTo']->exportArray());
     }
     self::$fetch[$asUserId][$publisherId][$stream->name] = array('*' => $stream);
     return $stream;
 }
Ejemplo n.º 5
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;
 }