Пример #1
0
function Streams_invite_response_data()
{
    if (isset(Streams::$cache['invited'])) {
        return Streams::$cache['invited'];
    }
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId();
    $streamType = Streams::requestedType();
    $invitingUserId = Streams::requestedField('invitingUserId');
    $limit = Q::ifset($_REQUEST, 'limit', Q_Config::get('Streams', 'invites', 'limit', 100));
    $invited = Streams_Invited::select('*')->where(array('userId' => $user->id, 'state' => 'pending', 'expireTime <' => new Db_Expression('CURRENT_TIMESTAMP')))->limit($limit)->fetchDbRows(null, null, 'token');
    $query = Streams_Invite::select('*')->where(array('token' => array_keys($invited)));
    if (isset($publisherId)) {
        $query = $query->where(array('publisherId' => $publisherId));
    }
    if (isset($streamType)) {
        $query = $query->where(array('streamName' => new Db_Range($streamType . '/', true, false, true)));
    }
    if (isset($invitingUserId)) {
        $query = $query->where(array('invitingUserId' => $invitingUserId));
    }
    $invites = $query->fetchDbRows();
    $streams = array();
    foreach ($invites as $invite) {
        $stream = new Streams_Stream();
        $stream->publisherId = $invite->publisherId;
        $stream->name = $invite->streamName;
        if ($stream->retrieve()) {
            $streams[$invite->token] = $stream->exportArray();
            $streams[$invite->token]['displayName'] = $invite->displayName;
        }
    }
    return compact('streams', 'invites');
}
Пример #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');
        }
    }
}
Пример #3
0
function Streams_before_Streams_Participant_save($params)
{
    $row = $params['row'];
    if (substr($row->streamName, 0, 18) === 'Streams/community/' and !$row->wasRetrieved()) {
        $communityId = $row->publisherId;
        $stream = new Streams_Stream();
        $stream->publisherId = $row->userId;
        $stream->name = "Streams/greeting/{$communityId}";
        if ($stream->retrieve()) {
            $row->setExtra('Streams/greeting', $stream->content);
        }
    }
}
Пример #4
0
 /**
  * Get a Places/location stream published by a publisher for a given placeId.
  * This is used to cache information from the Google Places API.
  * @method stream
  * @static
  * @param {string} $publisherId
  * @param {string} $placeId The id of the place in Google Places
  * @param {boolean} $throwIfBadValue
  *  Whether to throw Q_Exception if the result contains a bad value
  * @return {Streams_Stream|null}
  * @throws {Q_Exception} if a bad value is encountered and $throwIfBadValue is true
  */
 static function stream($publisherId, $placeId, $throwIfBadValue = false)
 {
     if (empty($placeId)) {
         if ($throwIfBadValue) {
             throw new Q_Exception_RequiredField(array('field' => 'id'));
         }
         return null;
     }
     // sanitize the ID
     $characters = '/[^A-Za-z0-9]+/';
     $result = preg_replace($characters, '_', $placeId);
     // see if it's already in the system
     $location = new Streams_Stream();
     $location->publisherId = $publisherId;
     $location->name = "Places/location/{$placeId}";
     if ($location->retrieve()) {
         $ut = $location->updatedTime;
         if (isset($ut)) {
             $db = $location->db();
             $ut = $db->fromDateTime($ut);
             $ct = $db->getCurrentTimestamp();
             $cd = Q_Config::get('Places', 'cache', 'duration', 60 * 60 * 24 * 30);
             if ($ct - $ut < $cd) {
                 // there is a cached location stream that is still viable
                 return $location;
             }
         }
     }
     $key = Q_Config::expect('Places', 'google', 'keys', 'server');
     $query = http_build_query(array('key' => $key, 'placeid' => $placeId));
     $url = "https://maps.googleapis.com/maps/api/place/details/json?{$query}";
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_URL, $url);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     $json = curl_exec($ch);
     curl_close($ch);
     $response = json_decode($json, true);
     if (empty($response['result'])) {
         throw new Q_Exception("Places_Location::stream: Couldn't obtain place information for {$placeId}");
     }
     if (!empty($response['error_message'])) {
         throw new Q_Exception("Places_Location::stream: " . $response['error_message']);
     }
     $result = $response['result'];
     $attributes = array('title' => $result['name'], 'latitude' => $result['geometry']['location']['lat'], 'longitude' => $result['geometry']['location']['lng'], 'viewport' => $result['geometry']['viewport'], 'phoneNumber' => Q::ifset($result, 'international_phone_number', null), 'phoneFormatted' => Q::ifset($result, 'formatted_phone_number', null), 'rating' => Q::ifset($result, 'rating', null), 'address' => Q::ifset($result, 'formatted_address', null));
     $location->title = $result['name'];
     $location->setAttribute($attributes);
     $location->type = 'Places/location';
     $location->save();
     return $location;
 }
Пример #5
0
function Broadcast_main_response_content()
{
    Q_Response::addScript('plugins/Broadcast/js/Broadcast.js');
    $user = Users::loggedInUser(true);
    $stream = new Streams_Stream();
    $stream->publisherId = $user->id;
    $stream->name = 'Broadcast/main';
    if (!$stream->retrieve()) {
        $stream->type = 'Broadcast';
        $stream->title = "Main broadcast stream";
        $stream->content = "Whatever you post to this stream will be syndicated by everyone who has opted in.";
        $stream->save();
    }
    Q_Response::redirect('Broadcast/stream publisherId=' . $stream->publisherId . ' name=Broadcast/main');
}
Пример #6
0
function Streams_invite_response_content()
{
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId();
    if (empty($publisherId)) {
        $publisherId = $user->id;
    }
    $streamName = Streams::requestedName(true);
    $stream = new Streams_Stream();
    $stream->publisherId = $publisherId;
    $stream->name = $streamName;
    if (!$stream->retrieve()) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}"));
    }
    return Q::tool('Streams/invite', compact('stream'));
}
Пример #7
0
function Streams_access_response_content($options)
{
    $ajax = true;
    $user = Users::loggedInUser(true);
    $streamName = Streams::requestedName(true);
    $publisherId = Streams::requestedPublisherId();
    if (empty($publisherId)) {
        $publisherId = $user->id;
    }
    $stream = new Streams_Stream();
    $stream->publisherId = $publisherId;
    $stream->name = $streamName;
    if (!$stream->retrieve()) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'name');
    }
    $controls = !empty($options['controls']);
    Q_Response::setSlot('title', "Access to: " . $stream->title);
    return Q::tool('Streams/access', compact('publisherId', 'streamName', 'ajax', 'controls'), $controls ? array('tag' => null) : array());
}
Пример #8
0
 /**
  * Check if user "owns" a stream template for a publisher
  * @method isOwner
  * @static
  * @param {string} $publisherId
  * @param {string} $type
  * @param {string|Users_User} [$user=null]
  * @return {boolean}
  */
 static function isOwner($publisherId, $type, $user = null)
 {
     if (!isset($user)) {
         $user = Users::loggedInUser();
     } else {
         if (is_string($user)) {
             $user = Users_User::fetch($user);
         }
     }
     if (!isset($user)) {
         return false;
     }
     // check if user is owner of stream template
     $stream = new Streams_Stream();
     $stream->publisherId = $publisherId;
     $stream->name = $type . '/';
     if (!$stream->retrieve()) {
         return false;
     }
     $stream->calculateAccess($user->id);
     return $stream->testAdminLevel('own');
 }
Пример #9
0
 /**
  * Closes a stream, which prevents anyone from posting messages to it
  * unless they have WRITE_LEVEL >= "close", as well as attempting to remove
  * all relations to other streams. A "cron job" can later go and delete
  * closed streams. The reason you should avoid deleting streams right away
  * is that other subscribers may still want to receive the last messages
  * posted to the stream.
  * @method close
  * @param {string} $asUserId The id of the user who would be closing the stream
  * @param {string} $publisherId The id of the user publishing the stream
  * @param {string} $streamName The name of the stream
  * @param {array} [$options=array()] Can include "skipAccess"
  * @static
  */
 static function close($asUserId, $publisherId, $streamName, $options = array())
 {
     $stream = new Streams_Stream();
     $stream->publisherId = $publisherId;
     $stream->name = $streamName;
     if (!$stream->retrieve()) {
         throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}"));
     }
     // Authorization check
     if (empty($options['skipAccess'])) {
         if ($asUserId !== $publisherId) {
             $stream->calculateAccess($asUserId);
             if (!$stream->testWriteLevel('close')) {
                 throw new Users_Exception_NotAuthorized();
             }
         }
     }
     // Clean up relations from other streams to this category
     list($relations, $related) = Streams::related($asUserId, $stream->publisherId, $stream->name, true);
     foreach ($relations as $r) {
         try {
             Streams::unrelate($asUserId, $r->fromPublisherId, $r->fromStreamName, $r->type, $stream->publisherId, $stream->name);
         } catch (Exception $e) {
         }
     }
     // Clean up relations from this stream to categories
     list($relations, $related) = Streams::related($asUserId, $stream->publisherId, $stream->name, false);
     foreach ($relations as $r) {
         try {
             Streams::unrelate($asUserId, $r->toPublisherId, $r->toStreamName, $r->type, $stream->publisherId, $stream->name);
         } catch (Exception $e) {
         }
     }
     $result = false;
     try {
         $db = $stream->db();
         $stream->closedTime = $closedTime = $db->toDateTime($db->getCurrentTimestamp());
         if ($stream->save()) {
             $stream->post($asUserId, array('type' => 'Streams/closed', 'content' => '', 'instructions' => compact('closedTime')), true);
             $result = true;
         }
     } catch (Exception $e) {
         throw $e;
     }
     return $result;
 }
Пример #10
0
 /**
  * Send credits, as the logged-in user, to another user
  * @method send
  * @static
  * @param {integer} $amount The amount of credits to send.
  * @param {string} $toUserId The id of the user to whom you will send the credits
  * @param {array} $more An array supplying more info, including
  *  "reason" => Identifies the reason for sending, if any
  */
 static function send($amount, $toUserId, $more = array())
 {
     if (!is_int($amount) or $amount <= 0) {
         throw new Q_Exception_WrongType(array('field' => 'amount', 'type' => 'integer'));
     }
     $user = Users::loggedInUser(true);
     $from_stream = new Streams_Stream();
     $from_stream->publisherId = $user->id;
     $from_stream->name = 'Awards/credits';
     if (!$from_stream->retrieve()) {
         $from_stream = self::createStream($user);
     }
     $existing_amount = $from_stream->getAttribute('amount');
     if ($existing_amount < $amount) {
         throw new Awards_Exception_NotEnoughCredits(array('missing' => $amount - $existing_amount));
     }
     $to_user = Users_User::fetch($toUserId, true);
     $to_stream = new Streams_Stream();
     $to_stream->publisherId = $toUserId;
     $to_stream->name = 'Awards/credits';
     if (!$to_stream->retrieve()) {
         $to_stream = self::createStream($to_user);
     }
     $to_stream->setAttribute('amount', $to_stream->getAttribute('amount') - $amount);
     $to_stream->save();
     // NOTE: we are not doing transactions here mainly because of sharding.
     // If if we reached this point without exceptions, that means everything worked.
     // But if the following statement fails, then someone will get free credits.
     $from_stream->setAttribute('amount', $from_stream->getAttribute('amount') - $amount);
     $from_stream->save();
     $instructions_json = Q::json_encode(array_merge(array('app' => Q_Config::expect('Q', 'app')), $more));
     Streams_Message::post($user->id, $userId, array('type' => 'Awards/credits/sent', 'content' => $amount, 'instructions' => $instructions_json));
     Streams_Message::post($user->id, $toUserId, array('type' => 'Awards/credits/received', 'content' => $amount, 'instructions' => $instructions_json));
 }