Example #1
0
function Streams_after_Q_image_save($params)
{
    $user = Users::loggedInUser(true);
    $path = $subpath = $data = $save = null;
    extract($params, EXTR_OVERWRITE);
    if (isset(Users::$cache['iconUrlWasChanged']) and Users::$cache['iconUrlWasChanged'] === false) {
        // the logged-in user's icon was changed without the url changing
        $stream = Streams::fetchOne($user->id, $user->id, "Streams/user/icon");
    } else {
        if (!empty(Streams::$cache['canWriteToStream'])) {
            // some stream's icon was being changed
            $stream = Streams::$cache['canWriteToStream'];
        }
    }
    if (empty($stream)) {
        return;
    }
    $url = $data[''];
    $stream->icon = Q_Valid::url($url) ? $url : Q_Request::baseUrl() . '/' . $url;
    $sizes = array();
    foreach ($save as $k => $v) {
        $sizes[] = "{$k}";
    }
    sort($sizes);
    $stream->setAttribute('sizes', $sizes);
    if (empty(Streams::$beingSavedQuery)) {
        $stream->changed($user->id);
    } else {
        $stream->save();
    }
}
Example #2
0
/**
 * Tool for admins to edit the url, title, keywords, description of the current page
 * @class Websites seo
 * @constructor
 * @param {Object} [$options] Options for the tool
 * @param {String} [$options.skipIfNotAuthorized=true] Whether to skip rendering the contents of the tool if the logged-in user is not authorized to edit the SEO information for this page.
 */
function Websites_seo_tool($options)
{
    $skipIfNotAuthorized = Q::ifset($options, 'skipIfNotAuthorized', true);
    if ($skipIfNotAuthorized) {
        $websitesUserId = Users::communityId();
        $sha1 = sha1(Q_Dispatcher::uri());
        $seoStreamName = "Websites/seo/{$sha1}";
        $stream = Streams::fetchOne(null, $websitesUserId, $seoStreamName);
        $user = Users::loggedInUser();
        if (!$user or $stream and !$stream->testWriteLevel('suggest')) {
            $options['skip'] = true;
        }
        if (!$stream and !Streams::isAuthorizedToCreate($user->id, $websitesUserId, 'Websites/seo')) {
            $options['skip'] = true;
        }
    }
    unset($options['skipIfNotAuthorized']);
    Q_Response::addStylesheet('plugins/Websites/css/Websites.css');
    Q_Response::addScript("plugins/Websites/js/Websites.js");
    Q_Response::setToolOptions($options);
    $user = Users::loggedInUser(false, false);
    $userId = $user ? $user->id : "";
    $communityId = Users::communityId();
    $sha1 = sha1(Q_Dispatcher::uri());
    $seoStreamName = "Websites/seo/{$sha1}";
    $streams = Streams::fetch($userId, $communityId, array("Websites/header", "Websites/title", "Websites/slogan", $seoStreamName));
    foreach ($streams as $name => $s) {
        if ($s) {
            $s->addPreloaded($userId);
        }
    }
}
Example #3
0
/**
 * This tool generates an HTML article viewer that lets authorized users edit the article.
 * @class Websites article
 * @constructor
 * @param {Object} [$options] parameters for the tool
 *   @param {String} $options.publisherId The article publisher's user id
 *   @param {String} $options.streamName The article's stream name
 *   @param {String} $options.stream The article's stream, if it is already fetched
 *   @param {String} [$options.html=array()] Any additional for the Streams/html editor
 *   @param {String} [$options.getintouch=array()] Additional options for the Users/getintouch tool, in case it's rendered
 */
function Websites_article_tool($options)
{
    $publisherId = $options['publisherId'];
    $streamName = $options['streamName'];
    $article = Q::ifset($options, 'stream', Streams::fetchOne(null, $publisherId, $streamName));
    if (!$article) {
        throw new Q_Exception_MissingRow(array('table' => 'article', 'criteria' => $streamName));
    }
    $getintouch = array_merge(array('user' => $article->userId, 'email' => true, 'sms' => true, 'call' => true, 'between' => "", 'emailSubject' => 'Reaching out from your website', 'class' => 'Q_button Q_clickable'), Q::ifset($options, 'getintouch', array()));
    $canView = $article->testReadLevel('content');
    $canEdit = $article->testWriteLevel('edit');
    if ($article->getintouch) {
        if (is_array($git = json_decode($article->getintouch, true))) {
            $getintouch = array_merge($getintouch, $git);
        }
    }
    $getintouch['class'] = 'Q_button';
    if (!$canView) {
        throw new Users_Exception_NotAuthorized();
    }
    $html = Q::ifset($options, 'html', array());
    $article->addPreloaded();
    Q_Response::addStylesheet('plugins/Websites/css/Websites.css');
    Q_Response::addScript("plugins/Websites/js/Websites.js");
    Q_Response::setToolOptions($options);
    return Q::view("Websites/tool/article.php", compact('article', 'getintouch', 'canEdit', 'canView', 'html'));
}
Example #4
0
/**
 * Displays an HTML document that can be printed, ideally with line breaks.
 * Uses a particular view for the layout.
 * @param {array} $_REQUEST
 * @param {string} $_REQUEST.invitingUserId Required. The id of the user that generated the invitations with a call to Streams::invite.
 * @param {string} $_REQUEST.batch Required. The name of the batch under which invitations were saved during a call to Streams::invite.
 * @param {string} [$_REQUEST.limit=100] The maximum number of invitations to show on the page
 * @param {string} [$_REQUEST.offset=0] Used for paging
 * @param {string} [$_REQUEST.title='Invitations'] Override the title of the document
 * @param {string} [$_REQUEST.layout='default'] The name of the layout to use for the HTML document
 * @see Users::addLink()
 */
function Streams_invitations_response()
{
    Q_Request::requireFields(array('batch', 'invitingUserId'), true);
    $invitingUserId = $_REQUEST['invitingUserId'];
    $batch = $_REQUEST['batch'];
    $user = Users::loggedInUser(true);
    $stream = Streams::fetchOne(null, $invitingUserId, 'Streams/invitations', true);
    if (!$stream->testReadLevel('content')) {
        throw new Users_Exception_NotAuthorized();
    }
    $title = Q::ifset($_REQUEST, 'layout', 'title');
    $layoutKey = Q::ifset($_REQUEST, 'layout', 'default');
    $limit = min(1000, Q::ifset($_REQUEST, 'limit', 100));
    $offset = Q::ifset($_REQUEST, 'offset', 0);
    $layout = Q_Config::expect('Streams', 'invites', 'layout', $layoutKey);
    $pattern = Streams::invitationsPath($invitingUserId) . DS . $batch . DS . "*.html";
    $filenames = glob($pattern);
    $parts = array();
    foreach ($filenames as $f) {
        if (--$offset > 0) {
            continue;
        }
        $parts[] = file_get_contents($f);
        if (--$limit == 0) {
            break;
        }
    }
    $content = implode("\n\n<div class='Q_pagebreak Streams_invitations_separator'></div>\n\n", $parts);
    echo Q::view($layout, compact('title', 'content', 'parts'));
    return false;
}
Example #5
0
function Shipping_scheduled_response_content($params)
{
    // redirect to home page if not logged in
    if (!Users::loggedInUser()) {
        header("Location: " . Q_Request::baseUrl());
        exit;
    }
    // get "Shipping/shipments" stream
    $publisherId = Users::communityId();
    $streamName = 'Shipping/shipment/' . Q_Request::uri()->shipmentStreamName;
    $stream = Streams::fetchOne($publisherId, $publisherId, $streamName);
    //$xml = simplexml_load_file(APP_DIR.'/classes/dhl/response.xml');
    //$xml = simplexml_load_string(str_replace('req:', '', file_get_contents(APP_DIR.'/classes/dhl/response.xml')));
    //print_r($xml); exit;
    // test pickup
    //$carrier = new Shipping_Carrier_DHL();
    //$carrier->createAWBBarCode($stream, 'iVBORw0KGgoAAAANSUhEUgAAAYwAAABeAQMAAAAKdrGZAAAABlBMVEX///8AAABVwtN+AAAAaklEQVR42mNkYGBIyL8wZcutG2wTzVMZfG99eep7y1tp5oIokaMMOtabG6PuTflrnnHqVfI013vzlRYwMDAxkAxGtYxqGdUyqmVUy6iWUS2jWka1jGoZ1TKqZVTLqJZRLaNaRrWMaiEVAABqDRe8DYfcJgAAAABJRU5ErkJggg==', "AWBBarCode");
    // -----------
    //echo Shipping::getShipmentRelation($stream, true);
    //unlink("/tmp/dhl-api-autoload.php");
    if (!$stream || !$stream->testReadLevel('see')) {
        throw new Users_Exception_NotAuthorized();
    }
    return Q::view('Shipping/content/scheduled.php', compact('streamName'));
}
Example #6
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.
 * @return {void}
 */
function Streams_interest_delete()
{
    $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) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => Q::json_encode(compact('publisherId', 'name'))));
    }
    $miPublisherId = $user->id;
    $miName = 'Streams/user/interests';
    $myInterests = Streams::fetchOne($user->id, $miPublisherId, $miName);
    if (!$myInterests) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => Q::json_encode(array('publisherId' => $miPublisherId, 'name' => $miName))));
    }
    $stream->leave();
    Streams::unrelate($user->id, $user->id, 'Streams/user/interests', 'Streams/interest', $publisherId, $name, array('adjustWeights' => true));
    Q_Response::setSlot('publisherId', $publisherId);
    Q_Response::setSlot('streamName', $name);
    /**
     * Occurs when the logged-in user has successfully removed an interest via HTTP
     * @event Streams/interest/delete {after}
     * @param {string} publisherId The publisher of the interest stream
     * @param {string} title The title of the interest
     * @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/remove", compact('publisherId', 'title', 'subscribe', 'user', 'stream', 'myInterests'), 'after');
}
function Websites_before_Streams_Stream_save_Websites_article($params)
{
    $stream = $params['stream'];
    $modifiedFields = $params['modifiedFields'];
    if ($stream->wasRetrieved()) {
        return;
    }
    $user = new Users_User();
    if (empty($stream->userId) and empty($modifiedFields['userId'])) {
        if ($liu = Users::loggedInUser()) {
            $stream->userId = $liu->id;
        } else {
            throw new Q_Exception_RequiredField(array('field' => 'userId'));
        }
    }
    $user->id = $stream->userId;
    if (!$user->retrieve()) {
        throw new Users_Exception_NoSuchUser();
    }
    $title = Streams::displayName($user, array('fullAccess' => true));
    if (isset($title)) {
        $stream->title = $title;
    }
    $stream->icon = $user->iconUrl();
    $s = Streams::fetchOne($user->id, $user->id, "Streams/user/icon");
    if (!$s or !($sizes = $s->getAttribute('sizes', null))) {
        $sizes = Q_Config::expect('Users', 'icon', 'sizes');
        sort($sizes);
    }
    $stream->setAttribute('sizes', $sizes);
}
Example #8
0
/**
 * Renders chat tool.
 * @class Streams chat
 * @constructor
 * @param {array} $options Options for the tool
 * @param {string} $options.publisherId Publisher id of the stream to get messsages from.
 * @param {string} $options.streamName Required. Name of the stream to get messsages from.
 * @param {string} [$options.loadMore] May have one these values: 'scroll', 'click' or 'pull' which indicates what kind of algorithm will be used for loading new messages. 'scroll' means that new messages will be loaded when scrollbar of the chat cointainer reaches the top (for desktop) or whole document scrollbar reaches the top (for android). 'click' will show label with 'Click to see earlier messages' and when user clicks it, new messages will be loaded. Finally, 'pull' implements 'pull-to-refresh' behavior used in many modern applications today when new messages loaded by rubber-scrolling the container by more amount than it actually begins. Defaults to 'scroll' for desktop and Android devices and 'pull' for iOS devices.
*/
function Streams_chat_tool($options)
{
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : '';
    /*
    $defaults = array(
    	'loadMore'         => (Q_Request::isTouchscreen() && Q_Request::platform() != 'android') ? 'click' : 'scroll',
    	'messagesToLoad'   => 5,
    	'messageMaxHeight' => 200
    );
    $options = array_merge($defaults, $options);
    */
    extract($options);
    if (!isset($publisherId)) {
        $publisherId = Streams::requestedPublisherId(true);
    }
    if (!isset($streamName)) {
        $streamName = Streams::requestedName();
    }
    $stream = Streams::fetchOne($userId, $publisherId, $streamName);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => compact('publisherId', 'streamName')));
    }
    $options['userId'] = $userId;
    if (!isset($options['notLoggedIn'])) {
        $options['notLoggedIn'] = 'You are not logged in';
    }
    if (!isset($options['notAuthorized'])) {
        $options['notAuthorized'] = 'You are not authorized';
    }
    Q_Response::setToolOptions($options);
}
Example #9
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);
}
function Trump_before_Websites_permalink($params)
{
    $uri = Q_Uri::from($params['permalink']->uri);
    if ($uri->module === 'Trump' and $uri->action === 'article') {
        $streamName = "Websites/article/{$uri->articleId}";
        $params['stream'] = Streams::fetchOne(null, 'Trump', $streamName);
    }
}
Example #11
0
/**
 * This tool generates an inline editor to edit the content or attribute of a stream.
 * @class Streams inplace
 * @constructor
 * @param {array} $options Options for the tool
 *  An associative array of parameters, containing:
 * @param {string} [$options.inplaceType='textarea'] The type of the fieldInput. Can be "textarea" or "text"
 * @param {array} [$options.convert] The characters to convert to HTML. Pass an array containing zero or more of "\n", " "
 * @param {Streams_Stream} $options.stream A Streams_Stream object
 * @param {string} [$options.field] Optional, name of an field to change instead of the content of the stream
 * @param {string} [$options.attribute] Optional, name of an attribute to change instead of any field.
 * @param {string} [$options.beforeSave] Reference to a callback to call after a successful save. This callback can cancel the save by returning false.
 * @param {string} [$options.onSave] Reference to a callback or event to run after a successful save.
 * @param {string} [$options.onCancel] Reference to a callback or event to run after cancel.
 * @param {array} [$options.inplace=array()] Additional fields to pass to the child Q/inplace tool, if any
 * @uses Q inplace
 */
function Streams_inplace_tool($options)
{
    if (empty($options['stream'])) {
        if (empty($options['publisherId']) or empty($options['streamName'])) {
            throw new Q_Exception_RequiredField(array('field' => 'stream'));
        }
        $publisherId = $options['publisherId'];
        $streamName = $options['streamName'];
        $stream = Streams::fetchOne(null, $publisherId, $streamName);
        if (!$stream) {
            throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "publisherId={$publisherId}, name={$streamName}"));
        }
    } else {
        $stream = $options['stream'];
    }
    $inplaceType = Q::ifset($options, 'inplaceType', 'textarea');
    $inplace = array('action' => $stream->actionUrl(), 'method' => 'PUT', 'type' => $inplaceType);
    if (isset($options['inplace'])) {
        $inplace = array_merge($options['inplace'], $inplace);
    }
    $convert = Q::ifset($options, 'convert', array("\n"));
    $inplace['hidden']['convert'] = json_encode($convert);
    if (!empty($options['attribute'])) {
        $field = 'attributes[' . urlencode($options['attribute']) . ']';
        $content = $stream->get($options['attribute'], '');
        $maxlength = $stream->maxSize_attributes - strlen($stream->maxSize_attributes) - 10;
    } else {
        $field = !empty($options['field']) ? $options['field'] : 'content';
        $content = $stream->{$field};
        $maxlength = $stream->maxSizeExtended($field);
    }
    switch ($inplaceType) {
        case 'text':
            $inplace['fieldInput'] = Q_Html::input($field, $content, array('placeholder' => Q::ifset($input, 'placeholder', null), 'maxlength' => $maxlength));
            $inplace['staticHtml'] = Q_Html::text($content);
            break;
        case 'textarea':
            $inplace['fieldInput'] = Q_Html::textarea($field, 5, 80, array('placeholder' => Q::ifset($inplace, 'placeholder', null), 'maxlength' => $maxlength), $content);
            $inplace['staticHtml'] = Q_Html::text($content, $convert);
            break;
        default:
            return "inplaceType must be 'textarea' or 'text'";
    }
    if (!$stream->testWriteLevel('suggest')) {
        if (!isset($options['classes'])) {
            $options['classes'] = '';
        }
        Q_Response::setToolOptions(array('publisherId' => $stream->publisherId, 'streamName' => $stream->name));
        $staticClass = $options['inplaceType'] === 'textarea' ? 'Q_inplace_tool_blockstatic' : 'Q_inplace_tool_static';
        return "<span class='Q_inplace_tool_container {$options['classes']}' style='position: relative;'>" . "<div class='{$staticClass}'>{$inplace['staticHtml']}</div></span>";
    }
    $toolOptions = array('publisherId' => $stream->publisherId, 'streamName' => $stream->name, 'inplaceType' => $options['inplaceType']);
    Q::take($options, array('attribute', 'field', 'convert'), $toolOptions);
    $toolOptions['inplace'] = $inplace;
    Q_Response::setToolOptions($toolOptions);
    return Q::tool("Q/inplace", $inplace);
}
function Streams_before_Q_Utils_canWriteToPath($params, &$result)
{
    extract($params);
    /**
     * @var $path
     * @var $throwIfNotWritable
     * @var $mkdirIfMissing
     */
    // Assume that Users/before/Q/Utils/canWriteToPath already executed
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : "";
    $app = Q_Config::expect('Q', 'app');
    $len = strlen(APP_DIR);
    if (substr($path, 0, $len) === APP_DIR) {
        $sp = str_replace(DS, '/', substr($path, $len + 1));
        if (substr($sp, -1) === '/') {
            $sp = substr($sp, 0, strlen($sp) - 1);
        }
        $prefix = "files/{$app}/uploads/Streams/";
        $len = strlen($prefix);
        if (substr($sp, 0, $len) === $prefix) {
            $splitId = Q_Utils::splitId($userId);
            $prefix2 = "files/{$app}/uploads/Streams/invitations/{$splitId}/";
            if ($userId and substr($sp, 0, strlen($prefix2)) === $prefix2) {
                $result = true;
                // user can write any invitations here
                return;
            }
            $parts = explode('/', substr($sp, $len));
            $c = count($parts);
            if ($c >= 3) {
                $result = false;
                for ($j = 0; $j < $c - 3; ++$j) {
                    $publisherId = implode('', array_slice($parts, 0, $j + 1));
                    $l = $j;
                    for ($i = $c - 1; $i > $j; --$i) {
                        $l = $i;
                        if (in_array($parts[$i], array('icon', 'file'))) {
                            break;
                        }
                    }
                    $name = implode('/', array_slice($parts, $j + 1, $l - $j - 1));
                    if ($name and $stream = Streams::fetchOne($userId, $publisherId, $name)) {
                        $result = $stream->testWriteLevel('edit');
                        Streams::$cache['canWriteToStream'] = $stream;
                        break;
                    }
                }
            }
        }
    }
    if (!$result and $throwIfNotWritable) {
        throw new Q_Exception_CantWriteToPath();
    }
}
Example #13
0
function Streams_access_response_data()
{
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId(true);
    $streamName = Streams::requestedName(true);
    $stream = Streams::fetchOne($user->id, $publisherId, $streamName);
    if (!$stream->testAdminLevel('own')) {
        throw new Users_Exception_NotAuthorized();
    }
    return array('access' => Q::ifset(Streams::$cache, 'access', null));
}
Example #14
0
/**
 * Used by HTTP clients to start a subscription
 * @class HTTP Assets subscription
 * @method post
 * @param {array} $_REQUEST
 * @param {string} $_REQUEST.payments Required. Should be either "authnet" or "stripe"
 *  @param {String} $_REQUEST.planStreamName the name of the subscription plan's stream
 *  @param {String} [$_REQUEST.planPublisherId=Users::communityId()] the publisher of the subscription plan's stream
 *  @param {String} [$_REQUEST.token=null] if using stripe, pass the token here
 */
function Assets_subscription_post($params = array())
{
    $req = array_merge($_REQUEST, $params);
    Q_Valid::requireFields(array('payments'), $req, true);
    // to be safe, we only start subscriptions from existing plans
    $planPublisherId = Q::ifset($req, 'planPublisherId', Users::communityId());
    $plan = Streams::fetchOne($planPublisherId, $planPublisherId, $req['planStreamName'], true);
    // the currency will always be assumed to be "USD" for now
    // and the amount will always be assumed to be in dollars, for now
    $token = Q::ifset($req, 'token', null);
    $subscription = Assets::startSubscription($plan, $req['payments'], compact('token'));
    Q_Response::setSlot('subscription', $subscription);
}
function Streams_after_Users_setLoggedInUser($params)
{
    // if this the first time the user has ever logged in...
    $user = $params['user'];
    if ($user->sessionCount != 1) {
        return;
    }
    // subscribe to main community announcements
    $communityId = Users::communityId();
    $stream = Streams::fetchOne($user->id, $communityId, 'Streams/community/main');
    if ($stream and !$stream->subscription($user->id)) {
        $stream->subscribe();
    }
}
Example #16
0
function Streams_stream_response_stream()
{
    // happens only during non-GET requests
    if (isset(Streams::$cache['stream'])) {
        return Streams::$cache['stream']->exportArray();
    }
    $publisherId = Streams::requestedPublisherId(true);
    $name = Streams::requestedName(true);
    $fields = Streams::requestedFields();
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : "";
    Streams::$cache['stream'] = $stream = Streams::fetchOne($userId, $publisherId, $name, $fields, array('withParticipant' => true));
    return $stream ? $stream->exportArray() : null;
}
Example #17
0
/**
 * This tool generates a category selector.
 *
 * @param {array} $options An associative array of parameters, containing:
 * @param {string} [$options.publisherId=Streams::requestedPublisherId()] The publisherId of the stream to present. If "stream" parameter is empty
 * @param {string} [$options.streamName=Streams::requestedName()] The streamName of the stream to present. If "stream" parameter is empty
 * @param {string} [options.relationType=null] Filter the relation type.
 */
function Streams_category_tool($options)
{
    extract($options);
    if (!$publisherId) {
        $options['publisherId'] = $publisherId = Streams::requestedPublisherId(true);
    }
    if (!$streamName) {
        $options['streamName'] = $streamName = Streams::requestedName(true);
    }
    Q_Response::setToolOptions($options);
    $stream = Streams::fetchOne(null, $publisherId, $streamName, true);
    $userId = Users::loggedInUser(true)->id;
    return Q::tool('Streams/related', $options);
}
function Streams_after_Users_setLoggedInUser($params)
{
    // if this the first time the user has ever logged in...
    $user = $params['user'];
    if ($user->sessionCount != 1) {
        return;
    }
    // subscribe to app announcements
    $app = Q_Config::expect('Q', 'app');
    $stream = Streams::fetchOne($user->id, $app, 'Streams/community/main');
    if ($stream and !$stream->subscription($user->id)) {
        $stream->subscribe();
    }
}
Example #19
0
/**
 * Generates a form with inputs that modify various streams
 * @class Streams form
 * @constructor
 * @param {array} $options
 *  An associative array of parameters, containing:
 * @param {array} [$options.fields] an associative array of $id => $fieldinfo pairs,
 *   where $id is the id to append to the tool's id, to generate the input's id,
 *   and fieldinfo is either an associative array with the following fields,
 *   or a regular array consisting of fields in the following order:
 *     "publisherId" => Required. The id of the user publishing the stream
 *     "streamName" => Required. The name of the stream
 *     "field" => The stream field to edit, or "attribute:$attributeName" for an attribute.
 *     "input" => The type of the input (@see Q_Html::smartTag())
 *     "attributes" => Additional attributes for the input
 *     "options" => options for the input (if type is "select", "checkboxes" or "radios")
 *     "params" => array of extra parameters to Q_Html::smartTag
 */
function Streams_form_tool($options)
{
    $fields = Q::ifset($options, 'fields', array());
    $defaults = array('publisherId' => null, 'streamName' => null, 'field' => null, 'type' => 'text', 'attributes' => array(), 'value' => array(), 'options' => array(), 'params' => array());
    $sections = array();
    $hidden = array();
    $contents = '';
    foreach ($fields as $id => $field) {
        if (Q::isAssociative($field)) {
            $r = Q::take($field, $defaults);
        } else {
            $c = count($field);
            if ($c < 4) {
                throw new Q_Exception("Streams/form tool: field needs at least 4 values");
            }
            $r = array('publisherId' => $field[0], 'streamName' => $field[1], 'field' => $field[2], 'type' => $field[3], 'attributes' => isset($field[4]) ? $field[4] : array(), 'value' => isset($field[5]) ? $field[5] : '', 'options' => isset($field[6]) ? $field[6] : null, 'params' => isset($field[7]) ? $field[7] : null);
        }
        $r['attributes']['name'] = "input_{$id}";
        if (!isset($r['type'])) {
            var_dump($r['type']);
            exit;
        }
        $stream = Streams::fetchOne(null, $r['publisherId'], $r['streamName']);
        if ($stream) {
            if (substr($r['field'], 0, 10) === 'attribute:') {
                $attribute = trim(substr($r['field'], 10));
                $value = $stream->get($attribute, $r['value']);
            } else {
                $field = $r['field'];
                $value = $stream->{$field};
            }
        } else {
            $value = $r['value'];
        }
        $tag = Q_Html::smartTag($r['type'], $r['attributes'], $value, $r['options'], $r['params']);
        $class1 = 'publisherId_' . Q_Utils::normalize($r['publisherId']);
        $class2 = 'streamName_' . Q_Utils::normalize($r['streamName']);
        $contents .= "<span class='Q_before {$class1} {$class2}'></span>" . Q_Html::tag('span', array('data-publisherId' => $r['publisherId'], 'data-streamName' => $r['streamName'], 'data-field' => $r['field'], 'data-type' => $r['type'], 'class' => "{$class1} {$class2}"), $tag);
        $hidden[$id] = array(!!$stream, $r['publisherId'], $r['streamName'], $r['field']);
    }
    $contents .= Q_Html::hidden(array('inputs' => Q::json_encode($hidden)));
    return Q_Html::form('Streams/form', 'post', array(), $contents);
    //
    // $fields = array('onSubmit', 'onResponse', 'onSuccess', 'slotsToRequest', 'loader', 'contentElements');
    // Q_Response::setToolOptions(Q::take($options, $fields));
    // Q_Response::addScript('plugins/Q/js/tools/form.js');
    // Q_Response::addStylesheet('plugins/Q/css/form.css');
    // return $result;
}
Example #20
0
 function beforeSave($modifiedFields)
 {
     $stream = null;
     $uri = Q_Uri::from($this->uri);
     if ($uri->module === 'Streams' and $uri->action === 'stream') {
         $publisherId = Streams::requestedPublisherId(false, $uri);
         $streamName = Streams::requestedName(false, 'original', $uri);
         $stream = Streams::fetchOne(null, $publisherId, $streamName);
     }
     Q::event('Websites/permalink', array('permalink' => $this, 'modifiedFields' => $modifiedFields, 'stream' => &$stream), 'before');
     if ($stream and $stream instanceof Streams_Stream) {
         $stream->setAttribute("Websites/url", $this->url);
         $stream->changed();
     }
     return parent::beforeSave($modifiedFields);
 }
Example #21
0
function Websites_article_put()
{
    // only a logged-in user can do this
    $user = Users::loggedInUser(true);
    $publisherId = Streams::requestedPublisherId();
    if (empty($publisherId)) {
        $publisherId = $_REQUEST['publisherId'] = $user->id;
    }
    $name = Streams::requestedName(true);
    $article = Streams::fetchOne($user->id, $publisherId, $name);
    if (!$article) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$name}'}"));
    }
    $article->getintouch = isset($_REQUEST['getintouch']) ? $_REQUEST['getintouch'] : '';
    $article->save();
    Q_Response::setSlot('form', '');
}
Example #22
0
function Streams_access_put($params)
{
    $user = Users::loggedInUser(true);
    Q_Valid::nonce(true);
    $publisherId = Streams::requestedPublisherId(true);
    $streamName = Streams::requestedName(true);
    $stream = Streams::fetchOne($user->id, $publisherId, $streamName);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'));
    }
    if (!$stream->testAdminLevel('own')) {
        throw new Users_Exception_NotAuthorized();
    }
    $p = array_merge($_REQUEST, $params);
    $access = new Streams_Access();
    $access->publisherId = $stream->publisherId;
    $access->streamName = $stream->name;
    $access->ofUserId = Q::ifset($_REQUEST, 'ofUserId', '');
    $access->ofContactLabel = Q::ifset($_REQUEST, 'ofContactLabel', '');
    if (empty($access->ofUserId) and empty($access->ofContactLabel)) {
        $fields = array('grantedByUserId', 'filter', 'readLevel', 'writeLevel', 'adminLevel', 'permissions');
        foreach ($fields as $field) {
            if (isset($p[$field])) {
                $stream->{$field} = $p[$field];
            }
        }
        $stream->save();
        return;
    }
    $access->retrieve();
    $fields = array('grantedByUserId', 'filter', 'readLevel', 'writeLevel', 'adminLevel', 'permissions');
    foreach ($fields as $field) {
        if (isset($p[$field])) {
            $access->{$field} = $p[$field];
        }
    }
    $defaults = array('grantedByUserId' => $user->id, 'readLevel' => -1, 'writeLevel' => -1, 'adminLevel' => -1);
    foreach ($defaults as $k => $v) {
        if (!isset($access->{$k})) {
            $access->{$k} = $v;
        }
    }
    $access->save();
    Streams::$cache['access'] = $access;
}
Example #23
0
 /**
  * Get the logged-in user's credits stream
  * @method userStream
  * @param {string} [$userId=null]
  *   The id of the user for which the stream is obtained. Defaults to logged-in user.
  * @param {string} [$asUserId=null]
  *   The id of the user who is trying to obtain it. Defaults to logged-in user.
  * @param {boolean} [$throwIfNotLoggedIn=false]
  *   Whether to throw a Users_Exception_NotLoggedIn if no user is logged in.
  * @return {Streams_Stream|null}
  * @throws {Users_Exception_NotLoggedIn} If user is not logged in and
  *   $throwIfNotLoggedIn is true
  */
 static function userStream($userId = null, $asUserId = null, $throwIfNotLoggedIn = false)
 {
     if (!isset($userId)) {
         $user = Users::loggedInUser($throwIfNotLoggedIn);
         if (!$user) {
             return null;
         }
     } else {
         $user = Users_User::fetch($userId, true);
     }
     $userId = $user->id;
     $streamName = 'Awards/user/credits';
     $stream = Streams::fetchOne($asUserId, $userId, $streamName);
     if (!$stream) {
         $amount = Q_Config::get('Awards', 'credits', 'amounts', 'Users/insertUser', self::DEFAULT_AMOUNT);
         $stream = Streams::create($userId, $userId, 'Awards/credits', array('name' => 'Awards/user/credits', 'title' => "Credits", 'icon' => 'plugins/Awards/img/credits.png', 'content' => '', 'attributes' => Q::json_encode(compact('amount'))));
     }
     return $stream;
 }
function Websites_before_Q_responseExtras()
{
    $user = Users::loggedInUser(false, false);
    $userId = $user ? $user->id : "";
    $websitesUserId = Users::communityId();
    $sha1 = sha1(Q_Dispatcher::uri());
    $seoStreamName = "Websites/seo/{$sha1}";
    $stream = Streams::fetchOne($userId, $websitesUserId, $seoStreamName);
    if ($stream) {
        $fields = Q::take($stream->getAllAttributes(), array('keywords', 'description'));
        foreach ($fields as $k => $v) {
            Q_Response::setMeta($k, $v);
        }
        Q_Response::setSlot('title', $stream->getAttribute('title'));
    }
    Q_Response::setScriptData('Q.plugins.Websites.seoStreamName', $seoStreamName);
    Q_Response::setScriptData('Q.plugins.Websites.userId', Users::communityId());
    Q_Response::setScriptData('Q.plugins.Websites.seoReload', Q_Config::expect('Websites', 'seoReload'));
}
Example #25
0
function Shipping_tracking_post()
{
    if (empty($_REQUEST["streamName"])) {
        throw new Q_Exception_WrongValue(array('field' => 'streamName', 'range' => "not empty"));
    }
    $env = Shipping::getVars();
    $publisherId = $env->communityId;
    $stream = Streams::fetchOne($publisherId, $publisherId, "Shipping/shipment/" . $_REQUEST["streamName"]);
    // trying to send request
    $carrier = new Shipping_Carrier_TNT();
    //Q_Response::setSlot('tracking', $carrier->track($stream));
    echo $carrier->track($stream);
    exit;
    // set shipment scheduled
    //Shipping::updateShipment($shipmentStream, 'scheduled');
    //Q_Request::requireFields(array('streamName'), $_REQUEST, true);
    //$params = Q::take($_REQUEST, array("streamName"));
    //$stream = Streams::fetchOne($userId, $userId, $params["streamName"]);
    //Shipping::updateShipment($stream, "scheduled");
}
function Streams_before_Users_canManageContacts($params, &$result)
{
    $asUserId = $params['asUserId'];
    $userId = $params['userId'];
    $label = $params['label'];
    $throwIfNotAuthorized = $params['throwIfNotAuthorized'];
    if ($asUserId === $userId and substr($label, 0, 6) === 'Users/') {
        $result = true;
    }
    $stream = Streams::fetchOne($asUserId, $userId, 'Streams/contacts');
    if ($stream and $stream->testWriteLevel('edit')) {
        if ($prefixes = $stream->getAttribute('prefixes', null)) {
            foreach ($prefixes as $prefix) {
                if (substr($label, 0, strlen($prefix)) === $prefix) {
                    $result = true;
                    return;
                }
            }
        }
    }
}
Example #27
0
/**
 * Tool for admins to edit the url, title, keywords, description of the current page
 * @class Websites seo
 * @constructor
 * @param {Object} [$options] Options for the tool
 * @param {String} [$options.skipIfNotAuthorized=true] Whether to skip rendering the contents of the tool if the logged-in user is not authorized to edit the SEO information for this page.
 */
function Websites_seo_tool($options)
{
    $skipIfNotAuthorized = Q::ifset($options, 'skipIfNotAuthorized', true);
    if ($skipIfNotAuthorized) {
        $websitesUserId = Q_Config::expect("Websites", "user", "id");
        $sha1 = sha1(Q_Dispatcher::uri());
        $seoStreamName = "Websites/seo/{$sha1}";
        $stream = Streams::fetchOne(null, $websitesUserId, $seoStreamName);
        $user = Users::loggedInUser();
        if (!$user or $stream and !$stream->testWriteLevel('suggest')) {
            $options['skip'] = true;
        }
        if (!$stream and !Streams::isAuthorizedToCreate($user->id, $websitesUserId, 'Websites/seo')) {
            $options['skip'] = true;
        }
    }
    unset($options['skipIfNotAuthorized']);
    Q_Response::addStylesheet('plugins/Websites/css/Websites.css');
    Q_Response::addScript("plugins/Websites/js/Websites.js");
    Q_Response::setToolOptions($options);
}
function Streams_after_Streams_message_Streams_relatedTo($params)
{
    $message = $params['message'];
    $type = $message->getInstruction('type', null);
    $stream = $params['stream'];
    $rtypes = Q_Config::get('Streams', 'categorize', 'relationTypes', array());
    $stypes = Q_Config::get('Streams', 'categorize', 'streamTypes', array());
    if (!in_array($type, $rtypes) or !in_array($stream->type, $stypes)) {
        return;
    }
    $c = new Streams_Category();
    $c->publisherId = $stream->publisherId;
    $c->streamName = $stream->name;
    $fromPublisherId = $message->getInstruction('fromPublisherId', null);
    $fromStreamName = $message->getInstruction('fromStreamName', null);
    if (!isset($fromPublisherId) or !isset($fromStreamName)) {
        return;
    }
    // Begin database transaction
    $relatedTo = $c->retrieve(null, array('ignoreCache' => true, 'begin' => true)) ? json_decode($c->relatedTo, true) : array();
    $weight = (double) $message->getInstruction('weight', null);
    if (!isset($weight)) {
        $rt = new Streams_RelatedTo();
        $rt->toPublisherId = $stream->publisherId;
        $rt->toStreamName = $stream->name;
        $rt->type = $type;
        $rt->fromPublisherId = $fromPublisherId;
        $rt->fromStreamName = $fromStreamName;
        $rt->retrieve(null, null, array('ignoreCache' => true));
        $weight = $rt->weight;
    }
    $fs = Streams::fetchOne($message->byUserId, $fromPublisherId, $fromStreamName);
    $weight = floor($weight);
    $relatedTo[$type][$weight] = array($fromPublisherId, $fromStreamName, $fs->title, $fs->icon);
    $c->relatedTo = Q::json_encode($relatedTo);
    $c->save(false, true);
    // End database transaction
}
Example #29
0
function Streams_participant_response_participants()
{
    if (isset(Streams::$cache['participant'])) {
        $participant = Streams::$cache['participant'];
        return Db::exportArray(array($participant->userId => $participant));
    }
    $publisherId = Streams::requestedPublisherId(true);
    $streamName = Streams::requestedName(true);
    $limit = isset($_REQUEST['limit']) ? $_REQUEST['limit'] : 10;
    $offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : -1;
    $state = isset($_REQUEST['state']) ? $_REQUEST['state'] : null;
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : "";
    $stream = Streams::fetchOne($userId, $publisherId, $streamName);
    if (empty($stream)) {
        throw new Q_Exception_MissingRow(array('table' => 'Stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}"));
    }
    if (!$stream->testReadLevel('participants')) {
        throw new Users_Exception_NotAuthorized();
    }
    $participants = $stream->getParticipants(compact('limit', 'offset', 'state'));
    Db::exportArray($participants);
}
Example #30
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();
    $maxLimit = Q_Config::get('Streams', 'defaults', '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'];
    }
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : "";
    $stream = isset(Streams::$cache['stream']) ? Streams::$cache['stream'] : Streams::fetchOne($userId, $publisherId, $streamName);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'Stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}"));
    }
    if (!$stream->testReadLevel('messages')) {
        throw new Users_Exception_NotAuthorized();
    }
    $messages = $stream->getMessages(compact('type', 'min', 'max', 'limit', 'ascending'));
    return Db::exportArray($messages);
}