Exemplo 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);
}
Exemplo n.º 2
0
/**
 * This tool renders all user sessions opened.
 *
 * @param {array} $options An associative array of parameters, containing:
 * @param {string} [$options.userId]
 *   The user's id. Defaults to id of the logged-in user, if any.
 * @param {bool} [$options.editable=true]
 *   Whether user can delete sessions
 * @param {bool} [$options.devices=true]
 *   Whether to show devices info
 */
function Users_sessions_tool($options)
{
    $options = array_merge(array('editable' => true, 'devices' => true), $options);
    if (empty($options['userId'])) {
        $options['userId'] = Users::loggedInUser(true)->id;
    }
    Q_Response::addStylesheet('plugins/Users/css/tools/sessions.css');
    Q_Response::setToolOptions($options);
    $sessions = Users_Session::select("us.*, ud.deviceId, ud.platform, ud.version, ud.formFactor", "us")->join(Users_Device::table() . ' ud', array('us.userId' => 'ud.userId', 'us.id' => 'ud.sessionId'), "LEFT")->where(array('us.userId' => $options['userId']))->fetchDbRows();
    $noDevicesClass = $options['devices'] ? '' : "Users_sessions_noDevices";
    $html = "<table class='Users_sessions_container {$noDevicesClass}'><tr><th>Session Id</th><th class='Users_sessions_devicesData'>Platform</th><th class='Users_sessions_devicesData'>Version</th><th>Last Updated</th>";
    if ($options["editable"]) {
        $html .= '<th class="Users_sessions_actions"></th>';
    }
    $html .= '</tr>';
    foreach ($sessions as $session) {
        $updatedTime = date("M j, Y g:i A", strtotime($session->updatedTime));
        $html .= "<tr><td class='Users_sessions_sessionId'>{$session->id}</td>" . "<td class='Users_sessions_devicesData'>{$session->platform}</td>" . "<td class='Users_sessions_devicesData'>{$session->version}</td>" . "<td>{$updatedTime}</td>";
        if ($options["editable"]) {
            $html .= "<td class='Users_sessions_actions'><button name='delete'>Delete</button></td>";
        }
        $html .= '</tr>';
    }
    $html .= "</table>";
    return $html;
}
Exemplo n.º 3
0
/**
 * This tool renders a user avatar
 *
 * @param {array} $options An associative array of parameters, containing:
 * @param {boolean} [$options.userId]
 *   "userId" => The user's id. Defaults to id of the logged-in user, if any.
 * @param {boolean} [$options.icon]
 *   "icon" => Optional. Render icon before the username.
 * @param {boolean} [$options.iconAttributes]
 *   "iconAttributes" => Optional. Array of attributes to render for the icon.
 * @param {boolean} [$options.editable]
 *   "editable" => Optional. Whether to provide an interface for editing the user's info. Can be array containing "icon", "name".
 * @param {array} [$options.inplaces] Additional fields to pass to the child Streams/inplace tools, if any
 * @param {boolean} [$options.renderOnClient]
 *    If true, only the html container is rendered, so the client will do the rest.
 */
function Users_avatar_tool($options)
{
    $defaults = array('icon' => false, 'editable' => false);
    $options = array_merge($defaults, $options);
    if (empty($options['userId'])) {
        $user = Users::loggedInUser();
        $options['userId'] = $user->id;
    } else {
        $user = Users_User::fetch($options['userId']);
    }
    Q_Response::addStylesheet('plugins/Q/css/Q.css');
    Q_Response::setToolOptions($options);
    if (!empty($options['renderOnClient'])) {
        return '';
    }
    if (!$user) {
        return '';
    }
    $user->addPreloaded();
    $p = $options;
    $p['userId'] = $user->id;
    Q_Response::setToolOptions($p);
    $result = '';
    $icon = $options['icon'];
    if ($icon) {
        if ($icon === true) {
            $icon = Q_Config::get('Users', 'icon', 'defaultSize', 40);
        }
        $attributes = isset($options['iconAttributes']) ? $options['iconAttributes'] : array();
        $attributes['class'] = isset($attributes['class']) ? $attributes['class'] . ' Users_avatar_icon' : 'Users_avatar_icon';
        $result .= Q_Html::img($user->iconUrl($icon), 'user icon', $attributes);
    }
    $result .= '<span class="Users_avatar_name">' . $user->username . '</span>';
    return $result;
}
Exemplo n.º 4
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'));
}
Exemplo n.º 5
0
function Broadcast_control_response_content($params)
{
    $user = Users::loggedInUser(true);
    $organizations = Broadcast_Agreement::select('a.userId, a.publisherId, u.organization_title, u.organization_domain', 'a')->join(Broadcast_User::table() . ' u', array('a.publisherId' => 'u.userId'))->where(array('a.userId' => $user->id))->fetchAll(PDO::FETCH_ASSOC);
    foreach ($organizations as $k => $org) {
        $messages = Streams_Message::select('content')->where(array('publisherId' => $org['publisherId'], 'streamName' => 'Broadcast/main'))->orderBy('sentTime')->fetchAll(PDO::FETCH_ASSOC);
        $organizations[$k]['messages'] = array();
        foreach ($messages as $msg) {
            $content = json_decode($msg['content'], true);
            if (isset($content['link'])) {
                $ch = curl_init();
                $timeout = 5;
                curl_setopt($ch, CURLOPT_URL, $content['link']);
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
                curl_setopt($ch, CURLOPT_HEADER, 0);
                curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; U; Linux i686; cs-CZ; rv:1.7.12) Gecko/20050929");
                $page_contents = curl_exec($ch);
                curl_close($ch);
                preg_match('/<title>([^<]+)<\\/title>/', $page_contents, $matches);
                if (isset($matches[1])) {
                    $content['link_title'] = $matches[1];
                }
            }
            $organizations[$k]['messages'][] = $content;
        }
    }
    Q_Config::set('Q', 'response', 'Broadcast', 'layout_html', 'Broadcast/layout/canvas.php');
    Q_Response::addStylesheet('css/canvas.css');
    Q_Response::addScript('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js');
    Q_Response::addScript('js/canvas.js');
    return Q::view('Broadcast/content/control.php', compact('organizations'));
}
Exemplo n.º 6
0
function Streams_after_Q_responseExtras()
{
    if ($preloaded = Streams_Stream::$preloaded) {
        $preloaded = Db::exportArray($preloaded);
        Q_Response::setScriptData('Q.plugins.Streams.Stream.preloaded', $preloaded);
    }
}
Exemplo n.º 7
0
function Streams_related_validate()
{
    switch (Q_Request::method()) {
        case 'POST':
            $required = array('toPublisherId', 'toStreamName', 'type', 'fromPublisherId', 'fromStreamName');
            break;
        case 'DELETE':
            $required = array('toPublisherId', 'toStreamName', 'type', 'fromPublisherId', 'fromStreamName');
            break;
        case 'PUT':
            $required = array('toPublisherId', 'toStreamName', 'type', 'fromPublisherId', 'fromStreamName', 'weight');
            if (isset($_REQUEST['adjustWeights'])) {
                if (!is_numeric($_REQUEST['adjustWeights'])) {
                    Q_Response::addError(new Q_Exception_WrongValue(array('field' => 'adjustWeights', 'range' => 'a numeric value'), 'adjustWeights'));
                }
            }
            break;
        case 'GET':
            $required = array();
            break;
    }
    foreach ($required as $r) {
        if (!isset($_REQUEST[$r])) {
            Q_Response::addError(new Q_Exception_RequiredField(array('field' => $r)));
        }
    }
}
Exemplo n.º 8
0
function Users_after_Q_reroute($params, &$stop_dispatch)
{
    $uri = Q_Dispatcher::uri();
    $app = Q_Config::expect('Q', 'app');
    $ma = $uri->module . '/' . $uri->action;
    $requireLogin = Q_Config::get('Users', 'requireLogin', array());
    if (!isset($requireLogin[$ma])) {
        return;
        // We don't have to require login here
    }
    $user = Users::loggedInUser();
    if ($requireLogin[$ma] === true and !$user) {
        // require login
    } else {
        if ($requireLogin[$ma] === 'facebook' and !Users::facebook($app)) {
            // require facebook
        } else {
            return;
            // We don't have to require login here
        }
    }
    $redirect_action = Q_Config::get('Users', 'uris', "{$app}/login", "{$app}/welcome");
    if ($redirect and $ma != $redirect_action) {
        Q_Response::redirect($redirect_action);
        $stop_dispatch = true;
        return;
    }
}
Exemplo n.º 9
0
function Streams_before_Q_responseExtras()
{
    Q_Response::addScript('plugins/Streams/js/Streams.js');
    $host = Q_Config::get('Streams', 'node', 'host', Q_Config::get('Q', 'node', 'host', null));
    $port = Q_Config::get('Streams', 'node', 'port', Q_Config::get('Q', 'node', 'port', null));
    $user = Users::loggedInUser();
    if ($user) {
        Q_Response::setScriptData('Q.plugins.Users.loggedInUser.displayName', Streams::displayName($user));
    }
    if (!Q_Request::isAjax()) {
        $invite_url = Q_Config::get('Streams', 'invite', 'url', "http://invites.to");
        Q_Response::setScriptData('Q.plugins.Streams.invite.url', $invite_url);
        if (isset($host) && isset($port)) {
            Q_Response::setScriptData('Q.plugins.Streams.node', array("http://{$host}:{$port}"));
        }
        if ($sizes = Q_Config::expect('Streams', 'types', 'Streams/image', 'sizes')) {
            sort($sizes);
            Q_Response::setScriptData('Q.plugins.Streams.image.sizes', $sizes);
        }
        $defaults = array('readLevel' => Streams::$READ_LEVEL['messages'], 'writeLevel' => Streams::$WRITE_LEVEL['join'], 'adminLevel' => Streams::$ADMIN_LEVEL['invite']);
        Q_Response::setScriptData('Q.plugins.Streams.defaults', $defaults);
        if ($froalaKey = Q_Config::get('Streams', 'froala', 'key', null)) {
            Q_Response::setScriptData('Q.plugins.Streams.froala.key', $froalaKey);
        }
    }
    Q_Response::addStylesheet("plugins/Streams/css/Streams.css");
}
Exemplo n.º 10
0
function Users_activate_response()
{
    $content = Q::event('Users/activate/response/content');
    Q_Response::setSlot('content', $content);
    Q_Response::setSlot('column0', $content);
    // for SmartApp
}
Exemplo n.º 11
0
function Shipping_shipment_response_content($params)
{
    $user = Users::loggedInUser(true);
    // copy from shipment
    $useTemplate = Q_Request::uri()->template ? "Shipping/shipment/" . Q_Request::uri()->template : false;
    // Check if stream "Shipping/shipments" exists for current user. If no -> create one.
    Shipping::shipments();
    // Check if stream "Shipping/templates" exists for current user. If no -> create one.
    Shipping::createTemplatesStream();
    // Collect streams for shipments. Relations: "describing", "scheduled", "confirmed", "shipping", "canceled", "returned"
    $shipment = Shipping::shipment();
    //$shipment->addPreloaded($userId);
    // test for UPS pickup
    //$stream = Streams::fetchOne("Shipping", "Shipping", "Shipping/shipment/Qdqpcspny");
    //$carrier = new Shipping_Carrier_UPS();
    //$carrier->pickupCreate($stream);
    //-------------------------------
    // add main style
    Q_Response::addStylesheet('css/Shipment.css');
    // set communityId
    Q_Response::setScriptData("Q.info.communityId", Users::communityId());
    Q_Response::setScriptData("Q.info.useTemplate", $useTemplate);
    Q_Response::addScript('js/shipment.js');
    Q_Response::addScript('js/date.js');
    // add jquery UI
    //Q_Response::addStylesheet('//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css');
    //Q_Response::addScript('//code.jquery.com/ui/1.11.4/jquery-ui.js');
    // add pickadate as date picker
    Q_Response::addStylesheet('js/pickadate/compressed/themes/default.css');
    Q_Response::addStylesheet('js/pickadate/compressed/themes/default.date.css');
    Q_Response::addScript('js/pickadate/compressed/picker.js');
    Q_Response::addScript('js/pickadate/compressed/picker.date.js');
    return Q::view('Shipping/content/shipment.php', compact('user', 'shipment', 'useTemplate'));
}
Exemplo n.º 12
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');
        }
    }
}
Exemplo n.º 13
0
function Q_response_notices()
{
    $result = "";
    $notices = Q_Response::getNotices();
    // Get any notices that we should know about
    if (!empty($notices)) {
        $result .= "<ul class='Q_notices'>";
        foreach ($notices as $k => $n) {
            $key = Q_Html::text($k);
            $result .= "<li data-key='{$key}'>{$n}</li>\n";
        }
        $result .= "</ul>";
    }
    // Get any errors that we should display
    $errors = Q_Response::getErrors();
    if (!empty($errors)) {
        $result .= "<ul class='Q_errors'>";
        foreach ($errors as $e) {
            $field = '';
            if ($e instanceof Q_Exception and $fields = $e->inputFields()) {
                $field .= '<div class="Q_field_name">' . Q_Html::text(reset($fields)) . '</div>';
            }
            $result .= "<li>" . $e->getMessage() . "{$field}</li>";
        }
        $result .= "</ul>";
    }
    return $result ? "<div id='notices'>{$result}</div>" : '';
}
Exemplo n.º 14
0
/**
 * Edits a label in the system. Fills the "label" (and possibly "icon") slot.
 * @param {array} $_REQUEST
 * @param {string} $_REQUEST.label The label
 * @param {string} [$_REQUEST.title] The title of the label
 * @param {string} [$_REQUEST.icon] Optional path to an icon
 * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this
 */
function Users_label_put($params = array())
{
    $req = array_merge($_REQUEST, $params);
    Q_Request::requireFields(array('label'), $req, true);
    $loggedInUserId = Users::loggedInUser(true)->id;
    $userId = Q::ifset($req, 'userId', $loggedInUserId);
    $l = $req['label'];
    $icon = Q::ifset($req, 'icon', null);
    $title = Q::ifset($req, 'title', null);
    Users::canManageLabels($loggedInUserId, $userId, $l, true);
    $label = new Users_Label();
    $label->userId = $userId;
    $label->label = $l;
    if (!$label->retrieve()) {
        throw new Q_Exception_MissingRow(array('table' => 'Label', 'criteria' => json_encode($label->fields)));
    }
    if (isset($title)) {
        $label->title = $title;
    }
    if (is_array($icon)) {
        // Process any icon data
        $icon['path'] = 'uploads/Users';
        $icon['subpath'] = "{$userId}/label/{$label}/icon";
        $data = Q::event("Q/image/post", $icon);
        Q_Response::setSlot('icon', $data);
        $label->icon = Q_Request::baseUrl() . '/' . $data[''];
    }
    $label->save();
    Q_Response::setSlot('label', $label->exportArray());
}
Exemplo n.º 15
0
/**
 * Ticker that scrolls its contents with various speeds and pauses
 * @class Q ticker
 * @constructor
 * @param {array} $options
 *  An associative array of fields, possibly including:
 *
 * "content" => string
 *  The content of the ticker. The first top-level element
 *  should contain sub-elements, and their sizes determine where
 *  the ticker would pause between automatically scrolling.
 *  The ticker animates by scrolling its inner contents.
 *
 * "vertical" => bool
 *  Defaults to true. If false, the ticker scrolls horizontally.
 *
 * "speed" => integer
 *  The scrolling speed.
 *  This is the number of items that would scroll by in 1 second,
 *  if there were no pauses.
 *  When the speed is positive, vertical tickers scroll down, and
 *  horizontal tickers scroll to the right. New content seems to come in
 *  from the bottom (for vertical tickers) or right (for horizontal tickers)
 *  as the ticker scrolls. The element inside the ticker will start out
 *  aligned with the top side of the ticker (for vertical tickers),
 *  or the left side of the ticker (for horizontal tickers).
 *  When the speed is negative, all this faces the other way.
 *
 * "pause_ms" => int
 *  Defaults to 2000. This is the number of milliseconds to wait
 *  after each second-level element of $content is automatically
 *  scrolled completely into view.
 *
 * "pause_ms_min" => int
 *  If set, then the number of milliseconds to pause is a random
 *  integer between $pause_ms_min and $pause_ms.
 *
 * "scrollbars" => bool
 *  Defaults to true. If true, shows scrollbars, otherwise doesn't.
 *  (Note: this will let the user know how much content is left,
 *   and be able to see it before it would automatically scroll into view.)
 *
 * "scrollbars_pause_ms" => int
 *  Defaults to 500. The ticker pauses its automatic scrolling when the user
 *  starts using the scrollbars. This is the number of milliseconds to wait
 *  until resuming the automatic scrolling.
 *
 * "anim_ms" => int
 *  Defaults to 100. This is the number of milliseconds between calls to
 *  autoScroll.
 *
 * "initial_scroll_mode" => string
 *  Defaults to 'auto'. This is the mode that scrolling starts out in.
 *  Possible values are 'auto' and 'paused'.
 *
 * "ease" => string
 *  Optional. If set, specifies the name of the ease function
 */
function Q_ticker_tool($options = array())
{
    $defaults = array('vertical' => true, 'speed' => 1, 'pause_ms' => 2000, 'scrollbars' => true, 'scrollbars_pause_ms' => 500, 'anim_ms' => 100);
    $fields2 = array_merge($defaults, $options);
    if (!isset($fields2['pause_ms_min'])) {
        $fields2['pause_ms_min'] = $fields2['pause_ms'];
    }
    if (!isset($fields2['content'])) {
        $li_array = array();
        for ($i = 0; $i < 100; ++$i) {
            $li_array[] = '<li><div style="background-color:#' . dechex(rand(0, 16)) . dechex(rand(0, 16)) . dechex(rand(0, 16)) . dechex(rand(0, 16)) . dechex(rand(0, 16)) . dechex(rand(0, 16)) . '">Missing $content parameter. This is just example #' . $i . '</div></li>';
        }
        $default_content = implode("\n", $li_array);
        if ($fields2['vertical']) {
            $fields2['content'] = "<ul class='error'>{$default_content}</ul>";
        } else {
            $fields2['content'] = "<ul class='error'>{$default_content}</ul>";
        }
    }
    Q_Response::addStylesheet('plugins/Q/css/ticker.css');
    Q_Response::addScript('plugins/Q/js/tools/ticker.js');
    Q_Response::setToolOptions($fields2);
    $direction_class = $fields2['vertical'] ? 'vertical' : 'horizontal';
    $scrollbars_class = $fields2['scrollbars'] ? 'scrollbars' : '';
    return Q_Html::tag('div', array('class' => "Q_ticker {$direction_class} {$scrollbars_class}"), $fields2['content']);
}
Exemplo n.º 16
0
function Q_notice_delete()
{
    if (!isset($_REQUEST['key'])) {
        throw new Q_Exception_RequiredField(array('field' => 'key'), 'key');
    }
    Q::$cache['notice_deleted'] = Q_Response::removeNotice($_REQUEST['key']);
}
Exemplo n.º 17
0
function Users_after_Q_responseExtras()
{
    if ($preloaded = Users_User::$preloaded) {
        Q_Response::setScriptData('Q.plugins.Users.User.preloaded', Db::exportArray($preloaded, array('asAvatar' => true)));
    }
    Q_Response::setScriptData('Q.plugins.Users.roles', Users::roles());
}
Exemplo n.º 18
0
function Users_account_validate()
{
    Q_Valid::nonce(true);
    $birthday_year = $birthday_month = $birthday_day = null;
    extract($_REQUEST);
    $field_names = array('firstName' => 'First name', 'lastName' => 'Last name', 'username' => 'Username', 'gender' => 'Your gender', 'desired_gender' => 'Gender preference', 'orientation' => 'Orientation', 'relationship_status' => 'Status', 'zipcode' => 'Zipcode');
    foreach ($field_names as $name => $label) {
        if (isset($_POST[$name]) and !$_POST[$name]) {
            Q_Response::addError(new Q_Exception_RequiredField(array('field' => $label), $name));
        }
    }
    if (isset($birthday_year)) {
        if (!checkdate($birthday_month, $birthday_day, $birthday_year)) {
            $field = 'Birthday';
            $range = 'a valid date';
            Q_Response::addError(new Q_Exception_WrongValue(compact('field', 'range'), 'birthday'));
        }
    }
    global $Q_installing;
    if (isset($username) and isset($Q_installing)) {
        try {
            Q::event('Users/validate/username', compact('username'));
        } catch (Exception $e) {
            Q_Response::addError($e);
        }
    }
}
Exemplo n.º 19
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');
}
Exemplo n.º 20
0
/**
 * Renders a photo selector tool
 * @param $options
 *   An associative array of parameters, which can include:
 * @param {Object} [$options] this object contains function parameters
 *   @param {Q.Event} $options.onSelect Required string naming the callback to be called when the user selects a photo.
 *   @param {Q.Event} [$options.beforePhotos] Triggered when photos are about to be rendered.
 *   @param {Q.Event} [$options.onPhotos] Triggered when photos have been rendered.
 *   @param {String} [$options.uid='me'] Optional. The uid of the user on the provider whose photos should be shown. Facebook only allows 'me' or a page id as a value.
 *   @param {String} [$options.fetchBy='album'] The tool supports different algoriths for fetching photos. Can be either by 'album' or 'tags'. Maybe more will be added later.
 *   @param {String} [$options.preprocessAlbums] Optional function to process the albums array before presenting it in the select. Receives a reference to the albums array as the first parameter, and a callback to call when it's done as the second.
 *   @param {String} [$options.preprocessPhotos] Optional function to process the photos array before presenting it in the select. Receives a reference to the albums array as the first parameter, and a callback to call when it's done as the second.
 *   @param {Q.Event} [$options.onLoad] Q.Event, callback or callback string name which is called when bunch of photos has been loaded.
 *   @param {Q.Event} [$options.onError] Q.Event, callback or callback string which will be called for each image that is unable to load. Image DOM element will be passed as first argument.
 *   @param {String} [$options.provider='facebook'] Has to be "facebook" for now.
 *   @param {String} [$options.prompt=false]
 *   Specifies type of prompt if user is not logged in or didn't give required permission for the tool.
 *   Can be either 'button', 'dialog' or null|false. 
 *   In first case just shows simple button which opens facebook login popup.
 *   In second case shows Users.facebookDialog prompting user to login.
 *   In third case will not show any prompt and will just hide the tool.
 *   @param {String} [$options.promptTitle]  Used only when 'prompt' equals 'dialog' - will be title of the dialog.
 *   @param {String} [$options.promptText]  Used either for button caption when 'prompt' equals 'button' or dialog text when 'prompt' equals 'dialog'.
 *   @param {Boolean} [$options.oneLine]  If true, all the images are shown in a large horizontally scrolling line.
 * @return {void}
 */
function Streams_photoSelector_tool($options)
{
    Q_Response::addScript('plugins/Streams/js/Streams.js');
    Q_Response::addStylesheet('plugins/Streams/css/Streams.css');
    Q_Response::setToolOptions($options);
    return '';
}
Exemplo n.º 21
0
/**
 * Adds a label to the system. Fills the "label" (and possibly "icon") slot.
 * @param {array} $_REQUEST
 * @param {string} $_REQUEST.title The title of the label
 * @param {string} [$_REQUEST.label] You can override the label to use
 * @param {string} [$_REQUEST.icon] Optional path to an icon
 * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this
 */
function Users_label_post($params = array())
{
    $req = array_merge($_REQUEST, $params);
    Q_Request::requireFields(array('title'), $req, true);
    $loggedInUserId = Users::loggedInUser(true)->id;
    $userId = Q::ifset($req, 'userId', $loggedInUserId);
    $icon = Q::ifset($req, 'icon', null);
    $title = $req['title'];
    $l = Q::ifset($req, 'label', 'Users/' . Q_Utils::normalize($title));
    Users::canManageLabels($loggedInUserId, $userId, $l, true);
    $label = new Users_Label();
    $label->userId = $userId;
    $label->label = $l;
    if ($label->retrieve()) {
        throw new Users_Exception_LabelExists();
    }
    $label->title = $title;
    if (is_array($icon)) {
        // Process any icon that was posted
        $icon['path'] = 'uploads/Users';
        $icon['subpath'] = "{$userId}/label/{$label}/icon";
        $data = Q::event("Q/image/post", $icon);
        Q_Response::setSlot('icon', $data);
        $label->icon = Q_Request::baseUrl() . '/' . $data[''];
    } else {
        $label->icon = 'default';
    }
    $label->save();
    Q_Response::setSlot('label', $label->exportArray());
}
Exemplo n.º 22
0
/**
 * This tool implements expandable containers that work on most modern browsers,
 * including ones on touchscreens.
 * @class Q expandable
 * @constructor
 * @param {array} $options Options for the tool
 * @param {string} $options.title Required. The title for the expandable.
 * @param {string} $options.content The content. Required unless you pass "items" instead.
 * @param {array} [$options.items] An array of strings to wrap in <span> elements and render in the content
 * @param {string} [$options.class] If you use "items", optionally specify the class of the container elements for each item
 * @param {integer} [$options.title] A number, if any, to display when collapsed
 * @param {boolean} [$options.autoCollapseSiblings]  Whether, when expanding an expandable, its siblings should be automatically collapsed.
 */
function Q_expandable_tool($options)
{
    if (isset($options['items'])) {
        $classString = isset($options['class']) ? "class='{$options['class']}'" : '';
        $lines = array();
        foreach ($options['items'] as $key => $value) {
            $lines[] = "<span {$classString}>{$key}</span>";
        }
        $between = Q::ifset($options, 'between', '');
        $options['content'] = implode($between, $lines);
    }
    foreach (array('title', 'content') as $field) {
        if (!isset($options[$field])) {
            throw new Q_Exception_RequiredField(compact('field'));
        }
    }
    Q_Response::addScript('plugins/Q/js/tools/expandable.js');
    Q_Response::addStylesheet('plugins/Q/css/expandable.css');
    $count = Q::ifset($options, 'count', '');
    $style = empty($options['expanded']) ? '' : 'style="display:block"';
    $h2 = "<h2>\n\t<span class='Q_expandable_count'>{$count}</span>\n\t{$options['title']}\n</h2>";
    $div = "<div class='Q_expandable_container' {$style}><div class='Q_expandable_content'>\n\t{$options['content']}\n</div></div>";
    Q_Response::setToolOptions($options);
    return $h2 . $div;
}
Exemplo n.º 23
0
function Overlay_before_Q_responseExtras()
{
    $app = Q_Config::expect('Q', 'app');
    Q_Response::addStylesheet('plugins/Q/css/Q.css');
    Q_Response::addStylesheet('css/Overlay.css', '@end');
    Q_Response::addStylesheet('http://fonts.googleapis.com/css?family=Open+Sans:400italic,400,300,700');
    if (Q_Config::get('Q', 'firebug', false)) {
        Q_Response::addScript("https://getfirebug.com/firebug-lite-debug.js");
    }
    Q_Response::addScript('js/Overlay.js');
    Q_Response::setMeta("title", "Customize My Pic!");
    Q_Response::setMeta("description", "Make a statement on Facebook by customizing your profile picture, even from your smartphone.");
    Q_Response::setMeta("image", Q_Html::themedUrl('img/icon/icon.png'));
    if (Q_Request::isIE()) {
        header("X-UA-Compatible", "IE=edge");
    }
    header('Vary: User-Agent');
    // running an event for loading action-specific extras (if there are any)
    $uri = Q_Dispatcher::uri();
    $module = $uri->module;
    $action = $uri->action;
    $event = "{$module}/{$action}/response/responseExtras";
    if (Q::canHandle($event)) {
        Q::event($event);
    }
}
Exemplo n.º 24
0
/**
 * Used by HTTP clients to upload a new file to the server
 * @class Q/file
 * @method post
 * @param {array} [$params] Parameters that can come from the request
 *   @param {string} [$params.data]  Required if $_FILES is empty. Base64-encoded image data URI - see RFC 2397
 *   @param {string} [$params.path="uploads"] parent path under web dir (see subpath)
 *   @param {string} [$params.subpath=""] subpath that should follow the path, to save the image under
 *   @param {string} [$params.name] override the name of the file, after the subpath
 */
function Q_file_post($params = null)
{
    $p = $params ? $params : Q::take($_REQUEST, array('data', 'path', 'subpath'));
    if (!empty($_FILES)) {
        $file = reset($_FILES);
        if ($tmp = $file['tmp_name']) {
            if (empty($p['data'])) {
                $p['data'] = file_get_contents($tmp);
                $p['name'] = $file['name'];
            }
            unlink($tmp);
        }
    } else {
        if (empty($p['data'])) {
            throw new Q_Exception_RequiredField(array('field' => 'data'), 'data');
        }
        $p['data'] = base64_decode(chunk_split(substr($p['data'], strpos($p['data'], ',') + 1)));
    }
    $timeLimit = Q_Config::get('Q', 'uploads', 'limits', 'file', 'time', 5 * 60 * 60);
    set_time_limit($timeLimit);
    // default is 5 min
    $data = Q_File::save($p);
    if (empty($params)) {
        Q_Response::setSlot('data', $data);
    }
    return $data;
}
Exemplo n.º 25
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);
}
Exemplo n.º 26
0
function Websites_seo_post()
{
    if (empty($_REQUEST['streamName'])) {
        throw new Q_Exception_RequiredField(array('field' => 'streamName'));
    }
    $prefix = "Websites/seo/";
    if (substr($_REQUEST['streamName'], 0, strlen($prefix)) !== $prefix) {
        throw new Q_Exception_WrongValue(array('field' => 'streamName', 'range' => "string beginning with {$prefix}"));
    }
    $user = Users::loggedInUser(true);
    $publisherId = Users::communityId();
    $type = "Websites/seo";
    if (!Streams::isAuthorizedToCreate($user->id, $publisherId, $type)) {
        throw new Users_Exception_NotAuthorized();
    }
    $stream = new Streams_Stream($publisherId);
    $stream->publisherId = $publisherId;
    $stream->name = $_REQUEST['streamName'];
    $stream->type = $type;
    if (isset($_REQUEST['uri'])) {
        $stream->setAttribute('uri', $_REQUEST['uri']);
    }
    $stream->save();
    $stream->post($user->id, array('type' => 'Streams/created', 'content' => '', 'instructions' => Q::json_encode($stream->toArray())), true);
    $stream->subscribe();
    // autosubscribe to streams you yourself create, using templates
    Q_Response::setSlot('stream', $stream->exportArray());
}
Exemplo n.º 27
0
/**
 * Standard tool for starting or managing subscriptions.
 * @class Assets subscription
 * @constructor
 * @param {array} $options Override various options for this tool
 *  @param {string} $options.payments can be "authnet" or "stripe"
 *  @param {string} $options.planStreamName the name of the subscription plan's stream
 *  @param {string} [$options.publisherId=Q.Users.communityId] the publisher of the subscription plan's stream
 *  @param {string} [$options.subscribeButton] Can override the title of the subscribe button
 *  @param {array} [$options=array()] Any additional options
 *  @param {string} [$options.token=null] required unless the user is an existing customer
 */
function Assets_subscription_tool($options)
{
    if (empty($options['payments'])) {
        throw new Q_Exception_RequiredField(array('field' => 'payments'), 'payments');
    }
    $payments = ucfirst($options['payments']);
    $lcpayments = strtolower($payments);
    $currency = strtolower(Q::ifset($options, 'currency', 'usd'));
    if ($payments === 'Authnet' and $currency !== 'usd') {
        throw new Q_Exception("Authnet doesn't support currencies other than USD", 'currency');
    }
    $className = "Assets_Payments_{$payments}";
    switch ($payments) {
        case 'Authnet':
            $adapter = new $className($options);
            $token = $options['token'] = $adapter->authToken();
            $testing = $options['testing'] = Q_Config::expect('Assets', 'payments', $lcpayments, 'testing');
            $action = $options['action'] = $testing ? "https://test.authorize.net/profile/manage" : "https://secure.authorize.net/profile/manage";
            break;
        case 'Stripe':
            $publishableKey = Q_Config::expect('Assets', 'payments', 'stripe', 'publishableKey');
            break;
    }
    $titles = array('Authnet' => 'Authorize.net', 'Stripe' => 'Stripe');
    $subscribeButton = Q::ifset($options, 'subscribeButton', "Subscribe with " . $titles[$payments]);
    Q_Response::setToolOptions($options);
    return Q::view("Assets/tool/subscription/{$payments}.php", compact('token', 'publishableKey', 'action', 'paymentButton', 'subscribeButton', 'planStreamName'));
}
Exemplo n.º 28
0
/**
 * Standard tool for making payments.
 * @class Assets payment
 * @constructor
 * @param {array} $options Override various options for this tool
 *  @param {string} $options.payments can be "authnet" or "stripe"
 *  @param {string} $options.amount the amount to pay.
 *  @param {double} [$options.currency="usd"] the currency to pay in. (authnet supports only "usd")
 *  @param {string} [$options.payButton] Can override the title of the pay button
 *  @param {String} [$options.publisherId=Users::communityId()] The publisherId of the Assets/product or Assets/service stream
 *  @param {String} [$options.streamName] The name of the Assets/product or Assets/service stream
 *  @param {string} [$options.name=Users::communityName()] The name of the organization the user will be paying
 *  @param {string} [$options.image] The url pointing to a square image of your brand or product. The recommended minimum size is 128x128px.
 *  @param {string} [$options.description=null] A short name or description of the product or service being purchased.
 *  @param {string} [$options.panelLabel] The label of the payment button in the Stripe Checkout form (e.g. "Pay {{amount}}", etc.). If you include {{amount}}, it will be replaced by the provided amount. Otherwise, the amount will be appended to the end of your label.
 *  @param {string} [$options.zipCode] Specify whether Stripe Checkout should validate the billing ZIP code (true or false). The default is false.
 *  @param {boolean} [$options.billingAddress] Specify whether Stripe Checkout should collect the user's billing address (true or false). The default is false.
 *  @param {boolean} [$options.shippingAddress] Specify whether Checkout should collect the user's shipping address (true or false). The default is false.
 *  @param {string} [$options.email=Users::loggedInUser(true)->emailAddress] You can use this to override the email address, if any, provided to Stripe Checkout to be pre-filled.
 *  @param {boolean} [$options.allowRememberMe=true] Specify whether to include the option to "Remember Me" for future purchases (true or false).
 *  @param {boolean} [$options.bitcoin=false] Specify whether to accept Bitcoin (true or false). 
 *  @param {boolean} [$options.alipay=false] Specify whether to accept Alipay ('auto', true, or false). 
 *  @param {boolean} [$options.alipayReusable=false] Specify if you need reusable access to the customer's Alipay account (true or false).
 */
function Assets_payment_tool($options)
{
    Q_Valid::requireFields(array('payments', 'amount'), $options, true);
    if (empty($options['name'])) {
        $options['name'] = Users::communityName();
    }
    if (!empty($options['image'])) {
        $options['image'] = Q_Html::themedUrl($options['image']);
    }
    $options['payments'] = strtolower($options['payments']);
    if (empty($options['email'])) {
        $options['email'] = Users::loggedInUser(true)->emailAddress;
    }
    $payments = ucfirst($options['payments']);
    $currency = strtolower(Q::ifset($options, 'currency', 'usd'));
    if ($payments === 'Authnet' and $currency !== 'usd') {
        throw new Q_Exception("Authnet doesn't support currencies other than USD", 'currency');
    }
    $className = "Assets_Payments_{$payments}";
    switch ($payments) {
        case 'Authnet':
            $adapter = new $className($options);
            $token = $options['token'] = $adapter->authToken();
            $testing = $options['testing'] = Q_Config::expect('Assets', 'payments', $lcpayments, 'testing');
            $action = $options['action'] = $testing ? "https://test.authorize.net/profile/manage" : "https://secure.authorize.net/profile/manage";
            break;
        case 'Stripe':
            $publishableKey = Q_Config::expect('Assets', 'payments', 'stripe', 'publishableKey');
            break;
    }
    $titles = array('Authnet' => 'Authorize.net', 'Stripe' => 'Stripe');
    Q_Response::setToolOptions($options);
    $payButton = Q::ifset($options, 'payButton', "Pay with " . $titles[$payments]);
    return Q::view("Assets/tool/payment/{$payments}.php", compact('token', 'publishableKey', 'action', 'payButton'));
}
Exemplo n.º 29
0
/**
 * Renders a Websites/presentation stream,
 * including an interface to edit the presentation
 * for users who have the permissions to do so.
 * @param {array} $options
 * @param {string} $options.publisherId
 * @param {string} $options.streamName
 */
function Websites_presentation_tool($options)
{
    Q_Response::addStylesheet('plugins/Websites/css/Websites.css');
    Q_Response::addScript('plugins/Websites/js/Websites.js');
    Q_Response::setToolOptions($options);
    return '';
}
Exemplo n.º 30
0
function Streams_invite_validate()
{
    if (Q_Request::method() === 'PUT') {
        return;
    }
    if (Q_Request::method() !== 'GET') {
        Q_Valid::nonce(true);
    }
    $fields = array('publisherId', 'streamName');
    if (Q_Request::method() === 'POST') {
        if (Q_Valid::requireFields($fields)) {
            return;
        }
        foreach ($fields as $f) {
            if (strlen(trim($_REQUEST[$f])) === 0) {
                Q_Response::addError(new Q_Exception("{$f} can't be empty", $f));
            }
        }
    }
    if (isset($_REQUEST['fullName'])) {
        $length_min = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMin', 5);
        $length_max = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMax', 30);
        if (strlen($_REQUEST['fullName']) < $length_min) {
            throw new Q_Exception("A user's full name can't be that short.", 'fullName');
        }
        if (strlen($_REQUEST['fullName']) > $length_max) {
            throw new Q_Exception("A user's full name can't be that long.", 'fullName');
        }
    }
}