function Websites_before_Streams_Stream_save_Websites_seo($params)
{
    $stream = $params['stream'];
    if (!$stream->wasModified('attributes')) {
        return;
    }
    $uri = $stream->getAttribute('uri', null);
    if (!$uri) {
        return;
    }
    $url = $stream->getAttribute('url', null);
    if (preg_match('/\\s/', $url)) {
        throw new Q_Exception_WrongValue(array('field' => 'url', 'range' => "no spaces"));
    }
    $wp = new Websites_Permalink();
    $wp->uri = $uri;
    $wp->retrieve('*', array('ignoreCache' => true));
    if ($url = $stream->getAttribute('url', null)) {
        $url = Q_Html::themedUrl($url);
        if (!isset($wp->url) or $wp->url !== $url) {
            $wp->url = $url;
            $wp->save();
        }
    } else {
        $wp->remove();
    }
}
Example #2
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'));
}
Example #3
0
function Streams_stream_response_Q_inplace()
{
    $stream = isset(Streams::$cache['stream']) ? Streams::$cache['stream'] : null;
    if (!$stream) {
        throw new Exception("No stream");
    }
    if (isset($_REQUEST['title'])) {
        $result = $stream->title;
    } else {
        if (isset($_REQUEST['attributes'])) {
            if (is_array($_REQUEST['attributes'])) {
                reset($_REQUEST['attributes']);
                $result = $stream->getAttribute(key($_REQUEST['attributes']));
            } else {
                $result = $stream->attributes;
            }
        } else {
            $fieldNames = array_diff(Streams::getExtendFieldNames($stream->type), array('insertedTime', 'updatedTime'));
            $field = 'content';
            foreach ($fieldNames as $f) {
                if (isset($_REQUEST[$f])) {
                    $field = $f;
                    break;
                }
            }
            $result = $stream->{$field};
        }
    }
    $convert = Q::ifset($_REQUEST, 'convert', '["\\n"]');
    return Q_Html::text($result, json_decode($convert, true));
}
Example #4
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);
    }
}
Example #5
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;
}
Example #6
0
function Q_before_Q_tool_render($params, &$result)
{
    $info = $params['info'];
    $extra = $params['extra'];
    if (is_string($extra) or is_numeric($extra)) {
        $extra_id = $extra;
        $extra = array();
    } else {
        $extra_id = isset($extra['id']) ? $extra['id'] : '';
    }
    $cur_prefix = isset($extra['prefix']) ? $extra['prefix'] : Q_Html::getIdPrefix();
    $tool_ids = array();
    $tool_prefixes = array();
    foreach ($info as $name => $options) {
        $tool_id = Q_Html::id($name . ($extra_id === '' ? '' : "-{$extra_id}"), $cur_prefix);
        $tool_ids[$name] = $tool_id;
        $tool_prefix = $tool_id . '_';
        if (isset(Q::$toolWasRendered[$tool_prefix])) {
            trigger_error("A tool with prefix \"{$tool_prefix}\" was already rendered.", E_USER_NOTICE);
        }
        Q::$toolWasRendered[$tool_prefix] = true;
        $tool_prefixes[$name] = $tool_prefix;
    }
    $prev_prefix = Q_Html::pushIdPrefix($tool_prefixes, $tool_ids);
}
Example #7
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>" : '';
}
Example #8
0
function Q_before_Q_tool_render($params, &$result)
{
    $info = $params['info'];
    $extra = $params['extra'];
    if (is_string($extra)) {
        $extra_id = $extra;
        $extra = array();
    } else {
        $extra_id = isset($extra['id']) ? $extra['id'] : '';
    }
    $cur_prefix = isset($extra['prefix']) ? $extra['prefix'] : Q_Html::getIdPrefix();
    $tool_ids = array();
    $tool_prefixes = array();
    foreach ($info as $name => $options) {
        $tool_id = implode('_', explode('/', $name));
        if (!empty($extra_id)) {
            $tool_id .= '-' . $extra_id;
        }
        $tool_id = $cur_prefix . $tool_id;
        $tool_ids[$name] = $tool_id;
        $tool_prefix = $tool_id . '_';
        if (isset(Q::$toolWasRendered[$tool_prefix])) {
            trigger_error("A tool with prefix \"{$tool_prefix}\" was already rendered.", E_USER_NOTICE);
        }
        Q::$toolWasRendered[$tool_prefix] = true;
        $tool_prefixes[$name] = $tool_prefix;
    }
    $prev_prefix = Q_Html::pushIdPrefix($tool_prefixes, $tool_ids);
}
Example #9
0
/**
 * This tool renders a user avatar
 *
 * @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.
 *   Can be '' for a blank-looking avatar.
 * @param {boolean} [options.short]
 *   Optional. Renders the short version of the display name.
 * @param {boolean|integer} [options.icon=false]
 *   Optional. Pass the size in pixels of the (square) icon to render
 *   before the username. Or pass true to render the default size.
 * @param {array} [options.iconAttributes]
 *   Optional. Array of attributes to render for the icon.
 * @param {boolean|array} [options.editable=false]
 *   Optional. Whether to provide an interface for editing the user's info. Can be array containing one or more of "icon", "name".
 * @param {boolean} [$options.show] The parts of the name to show. Can have the letters "f", "l", "u" in any order.
 * @param {boolean} [options.cacheBust=null]
 *   Number of milliseconds to use for Q_Uri::cacheBust for combating unintended caching on some environments.
 * @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, 'short' => false, 'cacheBust' => null, 'editable' => false);
    $options = array_merge($defaults, $options);
    Q_Response::addStylesheet('plugins/Users/css/Users.css');
    $loggedInUser = Users::loggedInUser();
    $loggedInUserId = $loggedInUser ? $loggedInUser->id : "";
    if (empty($options['userId'])) {
        $options['userId'] = $loggedInUserId;
    }
    unset($options['iconAttributes']);
    if (empty($options['editable'])) {
        $options['editable'] = array();
    } else {
        if (is_string($options['editable'])) {
            $options['editable'] = array($options['editable']);
        } else {
            if ($options['editable'] === true) {
                $options['editable'] = array('icon', 'name');
            }
        }
    }
    Q_Response::setToolOptions($options);
    if (!empty($options['renderOnClient'])) {
        return '';
    }
    $avatar = Streams_Avatar::fetch($loggedInUserId, $options['userId']);
    if (!$avatar) {
        return '';
    }
    $result = '';
    if ($icon = $options['icon']) {
        if ($icon === true) {
            $icon = Q_Config::get('Users', 'icon', 'defaultSize', 40);
        }
        $attributes = isset($options['iconAttributes']) ? $options['iconAttributes'] : array();
        $class = "Users_avatar_icon Users_avatar_icon_{$icon}";
        $attributes['class'] = isset($attributes['class']) ? $attributes['class'] . ' ' . $class : $class;
        if (isset($options['cacheBust'])) {
            $attributes['cacheBust'] = $options['cacheBust'];
        }
        $result .= Q_Html::img(Users::iconUrl($avatar->icon, "{$icon}.png"), 'user icon', $attributes);
    }
    $o = $options['short'] ? array('short' => true) : array();
    $o['html'] = true;
    if (in_array('name', $options['editable'])) {
        $o['show'] = 'fl';
        $streams = Streams::fetch(null, $options['userId'], array('Streams/user/firstName', 'Streams/user/lastName', 'Streams/user/username'));
        foreach ($streams as $s) {
            $s->addPreloaded();
        }
    }
    if (!empty($options['show'])) {
        $o['show'] = $options['show'];
    }
    $displayName = $avatar->displayName($o, 'Someone');
    $result .= "<span class='Users_avatar_name'>{$displayName}</span>";
    return $result;
}
Example #10
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);
}
Example #11
0
function Streams_publish_Broadcast_tool($options)
{
    extract($options);
    $publisherId = $stream->publisherId;
    $streamName = $stream->name;
    $type = 'Broadcast';
    $input = Q_Html::input('content', '');
    $button = Q_Html::tag('button', array(), 'Post');
    return Q_Html::form('Streams/stream', 'post', array(), Q_Html::formInfo(true) . Q_Html::hidden(compact('publisherId', 'streamName', 'type')) . Q::tool('Q/form', array('fields' => array('message' => array('type' => 'text', 'message' => 'this message will appear as if the user typed it before posting'), 'link' => array('type' => 'text', 'message' => 'the address of the webpage to share'), 'picture' => array('type' => 'text', 'message' => 'if you enter a picture url here, it will override the picture that is posted'), 'description' => array('type' => 'textarea', 'message' => 'if you enter something here, it will override the description that facebook would have automatically grabbed from that page'), '' => array('type' => 'button', 'value' => 'Post')), 'onSuccess' => 'Q.plugins.Broadcast.onBroadcastSuccess')));
}
Example #12
0
/**
 * This tool contains functionality to show things in columns
 * @class Q columns
 * @constructor
 * @param {array}   [options] Provide options for this tool
 *  @param {array}  [options.animation] For customizing animated transitions
 *  @param {integer}  [options.animation.duration] The duration of the transition in milliseconds, defaults to 500
 *  @param {array}  [options.animation.hide] The css properties in "hide" state of animation
 *  @param {array}  [options.animation.show] The css properties in "show" state of animation
 *  @param {array}  [options.back] For customizing the back button on mobile
 *  @param {string}  [options.back.src] The src of the image to use for the back button
 *  @param {boolean} [options.back.triggerFromTitle] Whether the whole title would be a trigger for the back button. Defaults to true.
 *  @param {boolean} [options.back.hide] Whether to hide the back button. Defaults to false, but you can pass true on android, for example.
 *  @param {array}  [options.close] For customizing the back button on desktop and tablet
 *  @param {string}  [options.close.src] The src of the image to use for the close button
 *  @param {string}  [options.title] You can put a default title for all columns here (which is shown as they are loading)
 *  @param {string}  [options.column] You can put a default content for all columns here (which is shown as they are loading)
 *  @param {array}  [options.clickable] If not null, enables the Q/clickable tool with options from here. Defaults to null.
 *  @param {array}  [options.scrollbarsAutoHide] If not null, enables Q/scrollbarsAutoHide functionality with options from here. Enabled by default.
 *  @param {boolean} [options.fullscreen] Whether to use fullscreen mode on mobile phones, using document to scroll instead of relying on possibly buggy "overflow" CSS implementation. Defaults to true on Android, false everywhere else.
 *  @param {array}   [options.columns] In PHP only, an array of $name => $column pairs, where $column is in the form array('title' => $html, 'content' => $html, 'close' => true)
 * @return {string}
 */
function Q_columns_tool($options)
{
    $jsOptions = array('animation', 'back', 'close', 'title', 'scrollbarsAutoHide', 'fullscreen');
    Q_Response::setToolOptions(Q::take($options, $jsOptions));
    if (!isset($options['columns'])) {
        return '';
    }
    Q_Response::addScript('plugins/Q/js/tools/columns.js');
    Q_Response::addStylesheet('plugins/Q/css/columns.css');
    $result = '<div class="Q_columns_container Q_clearfix">';
    $columns = array();
    $i = 0;
    $closeSrc = Q::ifset($options, 'close', 'src', 'plugins/Q/img/x.png');
    $backSrc = Q::ifset($options, 'back', 'src', 'plugins/Q/img/back-v.png');
    foreach ($options['columns'] as $name => $column) {
        $close = Q::ifset($column, 'close', $i > 0);
        $Q_close = Q_Request::isMobile() ? 'Q_close' : 'Q_close Q_back';
        $closeHtml = !$close ? '' : (Q_Request::isMobile() ? '<div class="Q_close Q_back">' . Q_Html::img($backSrc, 'Back') . '</div>' : '<div class="Q_close">' . Q_Html::img($closeSrc, 'Close') . '</div>');
        $n = Q_Html::text($name);
        $columnClass = 'Q_column_' . Q_Utils::normalize($name) . ' Q_column_' . $i;
        if (isset($column['html'])) {
            $html = $column['html'];
            $columns[] = <<<EOT
\t<div class="Q_columns_column {$columnClass}" data-index="{$i}" data-name="{$n}">
\t\t{$html}
\t</div>
EOT;
        } else {
            $titleHtml = Q::ifset($column, 'title', '[title]');
            $columnHtml = Q::ifset($column, 'column', '[column]');
            $classes = $columnClass . ' ' . Q::ifset($column, 'class', '');
            $attrs = '';
            if (isset($column['data'])) {
                $json = Q::json_encode($column['data']);
                $attrs = 'data-more="' . Q_Html::text($json) . '"';
                foreach ($column['data'] as $k => $v) {
                    $attrs .= 'data-' . Q_Html::text($k) . '="' . Q_Html::text($v) . '" ';
                }
            }
            $data = Q::ifset($column, 'data', '');
            $columns[] = <<<EOT
\t<div class="Q_columns_column {$classes}" data-index="{$i}" data-name="{$n}" {$attrs}>
\t\t<div class="Q_columns_title">
\t\t\t{$closeHtml}
\t\t\t<h2 class="Q_title_slot">{$titleHtml}</h2>
\t\t</div>
\t\t<div class="Q_column_slot">{$columnHtml}</div>
\t</div>
EOT;
        }
        ++$i;
    }
    $result .= "\n" . implode("\n", $columns) . "\n</div>";
    return $result;
}
Example #13
0
/**
 * Implements an input that filters an associated list (like an autocomplete)
 * @class Q filter
 * @constructor
 * @param {array} [$options] Override various options for this tool
 *  @param {String} [$options.name=filter] The name of the text input
 *  @param {String} [$options.value=''] The initial value of the text input
 *  @param {String} [$options.placeholder] Any placeholder text
 *  @param {array} [$options.placeholders={}] Options for Q/placeholders, or null to omit it
 *  @param {String} [$options.results=''] HTML to display in the results initially. If setting them later, remember to call stateChanged('results')
 *  @param {Q.Event} [$options.onFilter] Name of a JS event handler that is meant to fetch and update results by editing the contents of the element pointed to by the second argument. The first argument is the content of the text input.
 * @return {string}
 */
function Q_filter_tool($options)
{
    Q_Response::setToolOptions($options);
    $name = Q::ifset($options, 'name', 'filter');
    $value = Q::ifset($options, 'value', '');
    $placeholder = Q::ifset($options, 'placeholder', 'filter');
    $class = 'Q_filter_input';
    Q_Response::addScript('plugins/Q/js/tools/filter.js');
    Q_Response::addStylesheet('plugins/Q/css/filter.css');
    return Q_Html::input($name, $value, compact('placeholder', 'class')) . '<div class="Q_filter_results"></div>';
}
Example #14
0
/**
 * userChooser tool
 * @param array $options
 *  "maxResults" => the maximum number of results to show, defaults to 3
 *  "onSuccess" => the name of the function for what to do
 *  "placeholder" => override the default placeholder text,
 *  "exclude" => associative array of userId => true, where userId are the ids of the users
 *    to exclude from the results. Defaults to id of logged-in user, if logged in.
 */
function Streams_userChooser_tool($options)
{
    $maxResults = Q_Config::get('Streams', 'userChooser', 'maxResults', 3);
    $placeholder = "Start typing...";
    extract($options);
    if (!isset($exclude) and $user = Users::loggedInUser()) {
        $exclude = array($user->id => true);
    }
    Q_Response::addScript('plugins/Streams/js/Streams.js');
    Q_Response::setToolOptions(compact('onSuccess', 'maxResults', 'exclude'));
    return Q_Html::input('query', '', array('class' => 'text', 'placeholder' => $placeholder, 'autocomplete' => 'off'));
}
Example #15
0
/**
 * Creates an area that behaves like position: fixed in most modern browsers,
 * including ones on touchscreens. Often used for fixed areas that wind up
 * covered by content as it scrolls over the areas.
 * @class Q drawers
 * @constructor
 * @param {array}   [$options] Provide options for this tool
 *  @param {array}   [$options.drawers] Array of strings holding html for drawers
 *  @param {string} [$options.container=null] Optional jQuery selector for handling scrolling
 *  @param {array}   [$options.initial] Information for the initial animation
 *  @param {integer}   [$options.initial.index=1] The index of the drawer to show, either 0 or 1
 *  @param {integer}   [$options.initial.delay=0] Delay before starting initial animation
 *  @param {integer}   [$options.initial.duration=300] The duration of the initial animation
 *  @param {Function} [$options.initial.ease=Q.Animation.linear] The easing function of the initial animation
 *  @param {array}   [$options.transition] Information for the transition animation
 *  @param {integer}   [$options.transition.duration=300] The duration of the transition animation
 *  @param {Function}   [$options.transition.ease=Q.Animation.linear] The easing function of the transition animation
 *  @param {Function}   [$options.width] Override the function that computes the width of the drawers
 *  @param {Function}   [$options.height] Override the function that computes the height drawers tool
 *  @param {array}   [$options.heights=[100,100]] Array of [height0, height1] for drawers that are pinned
 *  @param {array}   [$options.placeholders=['','']] Array of [html0, html1] for drawers that are pinned
 *  @param {array}   [$options.behind=[true,false]] Array of [boolean0, boolean1] to indicate which drawer is behind the others
 *  @param {array}   [$options.bottom=[false,false]] Array of [boolean0, boolean1] to indicate whether to scroll to the bottom of a drawer after switching to it
 *  @param {array}   [$options.triggers=['plugins/Q/img/drawers/up.png', 'plugins/Q/img/drawers/down.png']] Array of [src0, src1] for img elements that act as triggers to swap drawers. Set array elements to false to avoid rendering a trigger.
 *  @param {array}   [$options.trigger]] Options for the trigger elements
 *  @param {integer}   [$options.trigger.rightMargin=10]] How many pixels from the right side of the drawers
 *  @param {integer}   [$options.transition=300]] Number of milliseconds for fading in the trigger images
 *  @param {boolean}   [$options.fullscreen=Q.info.isAndroidStock && Q.info.isAndroid(1000)]] Whether the drawers should take up the whole screen
 *  @param {integer}   [$options.foregroundZIndex=50] The z-index of the drawer in the foreground
 *  @param {integer}   [$options.beforeSwap=new Q.Event()] Occurs right before drawer swap
 *  @param {integer}   [$options.onSwap=new Q.Event()] Occurs right after drawer swap
 */
function Q_drawers_tool($options)
{
    $result = '';
    foreach ($options['drawers'] as $i => $html) {
        $result .= Q_Html::div("drawer_{$i}", "Q_drawers_drawer Q_drawers_drawer_{$i}", $html);
    }
    unset($options['drawers']);
    Q_Response::addScript('plugins/Q/js/tools/drawers.js');
    Q_Response::addStylesheet('plugins/Q/css/drawers.css');
    Q_Response::setToolOptions($options);
    return $result;
}
Example #16
0
function Streams_message_tool($options)
{
    extract($options);
    $user = Users::loggedInUser();
    if (!$user) {
        throw new Users_Exception_NotLoggedIn();
    }
    if (empty($publisherId)) {
        $publisherId = Streams::requestedPublisherId();
    }
    if (empty($publisherId)) {
        $publisherId = $_REQUEST['publisherId'] = $user->id;
    }
    if (empty($name)) {
        $name = Streams::requestedName(true);
    }
    $stream = Streams::fetch($user->id, $publisherId, $name);
    $stream = !empty($stream) ? reset($stream) : null;
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName');
    }
    if (!$stream->testReadLevel('messages') || !$stream->testWriteLevel('post')) {
        throw new Users_Exception_NotAuthorized();
    }
    $hidden = array('publisherId' => $publisherId, 'streamName' => $name);
    $fields = array('stream' => array('label' => 'Stream', 'type' => 'static', 'value' => $stream->title));
    $type = Streams::requestedType();
    // check if stream has messages
    $types = Q_Config::get('Streams', 'messages', $stream->type, array());
    if (count($types) === 0) {
        throw new Q_Exception("Stream of type '{$stream->type}' does not support messages");
    }
    if (!empty($type) && !in_array($type, $types)) {
        throw new Q_Exception("Requested message type '{$type}' is not alowed for streams of type '{$stream->type}'");
    }
    if (!empty($type)) {
        $hidden['type'] = $type;
        $fields['type'] = array('label' => 'Message type', 'type' => 'static', 'value' => $type);
    } else {
        $fields['type'] = array('label' => 'Message type', 'type' => 'select', 'options' => array_merge(array('' => 'Select type'), array_combine($types, $types)), 'value' => '');
    }
    $fields['content'] = array('label' => 'Content', 'type' => 'textarea');
    $fields['submit'] = array('label' => '', 'type' => 'submit_buttons', 'options' => array('submit' => 'Post'));
    return Q_Html::tag('h3', array(), 'Post a message') . Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/message', 'post', array(), Q_Html::hidden($hidden) . Q::tool('Q/form', array('fields' => $fields, 'onSuccess' => 'function (data) {
					if (data.errors) alert(data.errors);
					else {
						alert("Message posted");
						var message = Q.getObject(["slots", "form", "fields"], data);
						Q.handle(Q.info.baseUrl+"/plugins/Streams/message?publisherId="+message.publisherId+"&name="+message.streamName);
					}
				}')));
}
Example #17
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 #18
0
function Streams_player_tool($options)
{
    extract($options);
    if (!isset($stream)) {
        throw new Q_Exception_MissingObject(array('name' => 'stream'));
    }
    if (!$stream->testReadLevel('content')) {
        $streamName_html = Q_Html::text($stream->name);
        return "<a href='#{$streamName_html}'>hidden</a>";
    }
    $options['streamName'] = $stream->name;
    $parts = explode('/', $stream->type);
    switch ($parts[0]) {
        case 'Streams/text/small':
        case 'Streams/text/medium':
        case 'Streams/text':
            return $stream->content;
        case 'Streams/date':
            // TODO: localize
            if (isset($parts[1]) and $parts[1] === 'birthday') {
                return date('M j', strtotime($stream->content));
            }
            return date('M j, Y', strtotime($stream->content));
        case 'Streams/number':
            if (isset($parts[1]) and $parts[1] === 'age') {
                if (!empty($streams['Streams/user/birthday']->content)) {
                    return Db::ageFromDateTime($streams['Streams/user/birthday']->content);
                }
                return null;
            }
            return $strem->content;
        case 'Streams/category':
            // TODO: implement
        // TODO: implement
        case 'Streams/chat':
            // TODO: implement
        // TODO: implement
        case 'Streams/community':
            // TODO: implement
        // TODO: implement
        default:
            $event = $stream->type . "/tool";
            if (Q::canHandle($event)) {
                return Q::tool($stream->type, $options);
            }
            return Q_Html::tag('div', array('class' => 'Streams_player_stream_content'), Q_Html::text($stream->content));
    }
}
Example #19
0
function Q_scripts_combine()
{
    $environment = Q_Config::get('Q', 'environment', false);
    if (!$environment) {
        return "Config field 'Q'/'environment' is empty";
    }
    $files = Q_Config::get('Q', 'environments', $environment, 'files', Q_Config::get('Q', 'environments', '*', 'files', false));
    if (empty($files)) {
        return "Config field 'Q'/'environments'/'{$environment}'/files is empty";
    }
    $filters = Q_Config::get('Q', 'environments', $environment, 'filters', Q_Config::get('Q', 'environments', '*', 'filters', false));
    if (empty($filters)) {
        return "Config field 'Q'/'environments'/'{$environment}'/filters is empty";
    }
    $combined = array();
    foreach ($files as $src => $dest) {
        $f = Q_Uri::filenameFromUrl(Q_Html::themedUrl($src, true));
        if (!file_exists($f)) {
            return "Aborting: File corresponding to {$src} doesn't exist";
        }
        $content = file_get_contents($f);
        $combined[$dest][$src] = $content;
    }
    foreach ($combined as $dest => $parts) {
        $df = Q_Uri::filenameFromUrl(Q_Html::themedUrl($dest));
        $ext = pathinfo($df, PATHINFO_EXTENSION);
        echo "Writing {$df}\n";
        if (!empty($filters)) {
            foreach ($filters as $e => $filter) {
                if ($ext !== $e) {
                    continue;
                }
                $p = !empty($filter['params']) ? Q::json_encode($filter['params']) : '';
                echo "\t" . $filter['handler'] . "{$p}\n";
                foreach ($parts as $src => $part) {
                    echo "\t\t{$src}\n";
                }
                $params = compact('dest', 'parts');
                if (!empty($filter['params'])) {
                    $params = array_merge($params, $filter['params']);
                }
                $content = Q::event($filter['handler'], $params);
            }
        }
        file_put_contents($df, $content);
    }
    echo "Success.";
}
Example #20
0
function Users_identifier_tool($options)
{
    $defaults = array('uri' => 'Users/identifier', 'omit' => array(), 'fields' => array(), 'title' => "Contact Info", 'collapsed' => false, 'toggle' => false, 'editing' => true, 'complete' => true, 'inProcess' => false, 'prompt' => "In order for things to work, we must be able to reach you.", 'button_content' => 'OK');
    extract(array_merge($defaults, $options));
    $default_fields = array('emailAddress' => array('type' => 'text', 'label' => 'Email'));
    $fields = array_merge($default_fields, $fields);
    $user = Users::loggedInUser(true);
    $email = null;
    if (isset($user->emailAddress)) {
        $fields['emailAddress']['value'] = $user->emailAddress;
    } else {
        if ($user->emailAddressPending) {
            $link = Q_Html::a('#resend', array('class' => 'Users_idenfitier_tool_resend'), "You can re-send the activation email");
            $email = new Users_Email();
            $email->address = $user->emailAddressPending;
            if ($email->retrieve()) {
                switch ($email->state) {
                    case 'active':
                        if ($email->userId == $user->id) {
                            $message = "Please confirm this email address.<br>{$link}";
                        } else {
                            $message = "This email seems to belong to another user";
                        }
                        break;
                    case 'suspended':
                        $message = "This address has been suspended.";
                        break;
                    case 'unsubscribed':
                        $message = "The owner of this address has unsubscribed";
                        break;
                    case 'unverified':
                    default:
                        $message = "Not verified yet.<br>{$link}";
                        break;
                }
                $fields['emailAddress']['value'] = $email->address;
                $fields['emailAddress']['message'] = $message;
            } else {
                // something went wrong, so we'll try to correct it
                $user->emailAddressPending = "";
                $user->save();
            }
        }
    }
    $onSuccess = Q_Request::special('onSuccess', Q_Request::url());
    $form = $static = compact('fields');
    return Q::tool('Q/panel', compact('uri', 'onSuccess', 'form', 'static', 'title', 'collapsed', 'toggle', 'complete', 'editing', 'inProcess', 'setSlots'));
}
Example #21
0
function Q_after_Q_tool_render($params, &$result)
{
    $info = $params['info'];
    $extra = $params['extra'];
    if (!is_array($extra)) {
        $extra = array();
    }
    $id_prefix = Q_Html::getIdPrefix();
    $tool_ids = Q_Html::getToolIds();
    $tag = Q::ifset($extra, 'tag', 'div');
    if (empty($tag)) {
        Q_Html::popIdPrefix();
        return;
    }
    $classes = '';
    $data_options = '';
    $count = count($info);
    foreach ($info as $name => $opt) {
        $classes = ($classes ? "{$classes} " : $classes) . implode('_', explode('/', $name)) . '_tool';
        $options = Q_Response::getToolOptions($name);
        if (isset($options)) {
            $friendly_options = str_replace(array('&quot;', '\\/'), array('"', '/'), Q_Html::text(Q::json_encode($options)));
        } else {
            $friendly_options = '';
        }
        $normalized = Q_Utils::normalize($name, '-');
        if (isset($options) or $count > 1) {
            $id = $tool_ids[$name];
            $id_string = $count > 1 ? "{$id} " : '';
            $data_options .= " data-{$normalized}='{$id_string}{$friendly_options}'";
        }
        $names[] = $name;
    }
    if (isset($extra['classes'])) {
        $classes .= ' ' . $extra['classes'];
    }
    $attributes = isset($extra['attributes']) ? ' ' . Q_Html::attributes($extra['attributes']) : '';
    $data_retain = !empty($extra['retain']) || Q_Response::shouldRetainTool($id_prefix) ? " data-Q-retain=''" : '';
    $data_replace = !empty($extra['replace']) || Q_Response::shouldReplaceWithTool($id_prefix) ? " data-Q-replace=''" : '';
    $names = $count === 1 ? ' ' . key($info) : 's ' . implode(" ", $names);
    $ajax = Q_Request::isAjax();
    $result = "<{$tag} id='{$id_prefix}tool' " . "class='Q_tool {$classes}'{$data_options}{$data_retain}{$data_replace}{$attributes}>" . "{$result}</{$tag}>";
    if (!Q_Request::isAjax()) {
        $result = "<!--\nbegin tool{$names}\n-->{$result}<!--\nend tool{$names} \n-->";
    }
    Q_Html::popIdPrefix();
}
Example #22
0
/**
 * Inplace text editor tool to edit the content or attribute of a stream
 * @class Places location
 * @constructor
 * @param {array} [$options] used to pass options
 * @param {array} [$options.miles] array of { miles: title } pairs, by default is generated from Places/nearby/miles config
 * @param {array} [$options.defaultMiles] override the key in the miles array to select by default. Defaults to "Places/nearby/defaultMiles" config
 * @param {array} [$options.map] options for the map
 * @param {integer} [$options.map.delay=300] how many milliseconds to delay showing the map, e.g. because the container is animating
 * @param {string} [$options.map.prompt="img/map.png"] The src of the map graphical prompt when no location has been selected yet
 * @param {String} [$options.updateButton="Update my location"] the title of the update button
 * @param {string} [$options.onUpdate] name an event handler for when the location is updated
 * @param {string} [$options.onUnset] name an event handler for when the location is unset
 */
function Places_location_tool($options)
{
    if (empty($options['miles'])) {
        $options['miles'] = array();
        foreach (Q_Config::expect('Places', 'nearby', 'miles') as $m) {
            $options['miles'][$m] = $m === 1 ? "{$m} mile" : "{$m} miles";
        }
    }
    if (empty($options['map']['prompt'])) {
        $options['map']['prompt'] = Q_Html::themedUrl('plugins/Places/img/map.png');
    }
    if (!isset($options['defaultMiles'])) {
        $options['defaultMiles'] = Q_Config::expect('Places', 'nearby', 'defaultMiles');
    }
    Q_Response::setToolOptions($options);
    return '';
}
Example #23
0
function Broadcast_stream_response_content()
{
    $publisherId = Streams::requestedPublisherId(true);
    $name = Streams::requestedName(true);
    $fields = Streams::requestedFields();
    $user = Users::loggedInUser();
    $userId = $user ? $user->id : 0;
    if (isset(Streams::$cache['stream'])) {
        $stream = Streams::$cache['stream'];
    } else {
        $streams = Streams::fetch($userId, $publisherId, $name, $fields, array('limit' => 30));
        if (empty($streams)) {
            throw new Q_Exception("No such stream", 'name');
        }
        $stream = reset($streams);
    }
    if ($publisherId != $userId and !$stream->testReadLevel('content')) {
        return "This belongs to someone else.";
    }
    if ($publisherId != $userId and !$stream->testReadLevel('content')) {
        throw new Users_Exception_NotAuthorized();
    }
    $userIds = array();
    $agreements = Broadcast_Agreement::select('userId')->where(array('publisherId' => $publisherId, 'streamName' => $name, 'platform' => 'facebook'))->fetchDbRows();
    foreach ($agreements as $a) {
        $userIds[] = $a->userId;
    }
    if ($userIds) {
        $agreed_users = Users_User::select('*')->where(array('id' => $userIds))->fetchDbRows();
    } else {
        $agreed_users = array();
    }
    $src = 'Broadcast/widget?';
    $q = array('publisherId' => $publisherId, 'streamName' => $name);
    foreach (array('css', 'button', 'checkmark', 'explanation') as $field) {
        if (isset($_REQUEST[$field])) {
            $q[$field] = $_REQUEST[$field];
        }
    }
    $src .= http_build_query($q, null, '&');
    $style = 'border: 0px;';
    $code = Q_Html::tag('iframe', compact('src', 'style'), '');
    Q_Response::addScript('plugins/Broadcast/js/Broadcast.js');
    return Q::view('Broadcast/content/stream.php', compact('publisherId', 'name', 'fields', 'user', 'stream', 'agreed_users', 'code'));
}
Example #24
0
/**
 * This tool renders ways to get in touch
 *
 * @param array [$options] An associative array of options, containing:
 *   @param {string|Users_User} [$options.user] Required. The user object or id of the user exposing their primary identifiers for getting in touch.
 *   @param {boolean|string} [$options.email] Pass true here to use the primary verified email address, if any. Or pass the string label for this button.
 *   @param {string} [$options.emailSubject] Fill this if you want the email subject to be automatically filled in
 *   @param {string} [$options.emailBody] Fill this if you want the email body to be automatically filled in
 *   @param {boolean|string} [$options.sms] Pass true here to allow texting the primary verified mobile number, if any. Or pass the string label for this button.
 *   @param {boolean|string} [$options.call] Pass true here to allow calling the primary verified mobile number, if any. Or pass the string label for this button.
 *   @param {string} [$options.tag] The type of tag to use, defaults to "button"
 *   @param {string} [$options.class] Any classes to add to the tags
 *   @param {string} [$options.between] Any HTML to put between the elements
 */
function Users_getintouch_tool($options)
{
    $tag = 'button';
    $class = null;
    $between = '';
    $user = null;
    $emailSubject = '';
    $emailBody = '';
    extract($options, EXTR_IF_EXISTS);
    if (!$user) {
        throw new Q_Exception_RequiredField(array('field' => 'user'));
    }
    if (is_string($user)) {
        $userId = $user;
        $user = Users_User::fetch($userId);
        if (!$user) {
            throw new Q_Exception_MissingRow(array('table' => 'user', 'criteria' => "id={$userId}"));
        }
    }
    $ways = array();
    $email = $sms = $call = false;
    if (!empty($options['email']) and $user->emailAddress) {
        $email = is_string($options['email']) ? $options['email'] : "Email me";
        $email = Q_Html::img("plugins/Users/img/email.png") . $email;
        $ways['email'] = Q_Html::tag($tag, array('id' => 'email', 'class' => $class), $email);
        Q_Response::setToolOptions(array('emailAddress' => Q_Utils::obfuscate($user->emailAddress), 'emailSubject' => Q_Utils::obfuscate($emailSubject), 'emailBody' => Q_Utils::obfuscate($emailBody)));
    }
    if (Q_Request::isMobile()) {
        $obfuscated_mobileNumber = Q_Utils::obfuscate($user->mobileNumber);
        if (!empty($options['sms']) and $user->mobileNumber) {
            $sms = is_string($options['sms']) ? $options['sms'] : "Text me";
            $sms = Q_Html::img("plugins/Users/img/sms.png") . $sms;
            $ways['sms'] = Q_Html::tag($tag, array('id' => 'sms', 'class' => $class), $sms);
            Q_Response::setToolOptions(array('mobileNumber' => $obfuscated_mobileNumber));
        }
        if (!empty($options['call']) and $user->mobileNumber) {
            $call = is_string($options['call']) ? $options['call'] : "Call me";
            $call = Q_Html::img("plugins/Users/img/call.png") . $call;
            $ways['call'] = Q_Html::tag($tag, array('id' => 'call', 'class' => $class), $call);
            Q_Response::setToolOptions(array('mobileNumber' => $obfuscated_mobileNumber));
        }
    }
    return implode($between, $ways);
}
Example #25
0
/**
 * This tool generates an inline editor, along with a form tag.
 * @class Q inplace
 * @constructor
 * @param {array} [$options] An associative array of parameters, containing:
 *   @param {string} $options.fieldInput  Required. HTML representing a text input, textarea, or select.
 *   @param {string} $options.staticHtml  Required. The static HTML to display when the input isn't showing.
 *   @param {string} [$options.type='textarea']  The type of the input. Can be "textarea", "text" or "select"
 *   @param {string} [$options.action=""]  The uri or url to submit to
 *   @param {string} [$options.method="put"]  The method to use for submitting the form.
 *   @param {boolean} [$options.editing]  If true, then renders the inplace tool in editing mode.
 *   @param {boolean} [$options.editOnClick=true]  If true, then edit mode starts only if "Edit" button is clicked.
 *   @param {boolean} [$options.selectOnEdit=true] If true, selects all the text when entering edit mode.
 *   @param {string} [$options.placeholder] Text to show in the staticHtml or input field when the editor is empty
 *   @param {array} [$options.hidden] An associative array of additional hidden fields to submit in the form
 *   @param {integer} [$options.maxWidth] The maximum width for the Q/autogrow
 *   @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.
 */
function Q_inplace_tool($options)
{
    $action = '';
    $method = 'put';
    $fieldInput = '';
    $staticHtml = '';
    $type = 'textarea';
    $editOnClick = true;
    $selectOnEdit = true;
    extract($options);
    if (isset($inplace)) {
        extract($inplace);
    }
    if (!isset($fieldInput)) {
        throw new Q_Exception_RequiredField(array('field' => 'fieldInput'));
    }
    $staticClass = $type === 'textarea' ? 'Q_inplace_tool_blockstatic' : 'Q_inplace_tool_static';
    Q_Response::addScript('plugins/Q/js/tools/inplace.js');
    Q_Response::addStylesheet('plugins/Q/css/inplace.css');
    $formTag = Q_Html::form("{$action}", $method, array('class' => 'Q_inplace_tool_form'));
    $hiddenInputs = $options['hidden'] ? Q_Html::hidden($options['hidden']) : '';
    $classes = !empty($editing) ? 'Q_editing Q_nocancel' : '';
    $options = compact('editOnClick', 'selectOnEdit', 'showEditButtons', 'maxWidth', 'beforeSave', 'onSave', 'placeholder', 'type');
    Q_Response::setToolOptions($options);
    $sh = $staticHtml ? $staticHtml : '<span class="Q_placeholder">' . Q_Html::text($placeholder) . '</span>';
    return <<<EOT
<div class='Q_inplace_tool_container {$classes} Q_inplace_{$type}' style="position: relative;">
\t<div class='Q_inplace_tool_editbuttons'>
\t\t<button class='Q_inplace_tool_edit basic16 basic16_edit'>Edit</button>
\t</div>
\t<div class='{$staticClass}'>{$sh}</div>
\t{$formTag}
\t\t{$fieldInput}
\t\t{$hiddenInputs}
\t\t<div class='Q_inplace_tool_buttons'>
\t\t\t<button class='Q_inplace_tool_cancel basic16 basic16_cancel'>Cancel</button>
\t\t\t<button class='Q_inplace_tool_save basic16 basic16_save'>Save</button>
\t\t</div>
\t</form>
</div>

EOT;
}
Example #26
0
function Websites_0_8_Streams_mysql()
{
    $userId = Q_Config::get("Websites", "user", "id", null);
    if (!$userId) {
        throw new Q_Exception('Websites: Please fill in the config field "Websites"/"user"/"id"');
    }
    // $now = Streams::db()->toDateTime(Streams::db()->getCurrentTimestamp());
    $ofUserId = '';
    $ofContactLabel = 'Websites/admins';
    $grantedByUserId = null;
    $streams = array("Streams/images/" => array('type' => "Streams/template", "title" => "Images", "icon" => "default", "content" => "", "deletable" => true), "Streams/image/" => array('type' => "Streams/template", "title" => "Untitled Image", "icon" => "Streams/image", "content" => "", "deletable" => true), "Streams/file/" => array('type' => "Streams/template", "title" => "Untitled File", "icon" => "files/_blank", "content" => "", "deletable" => true), "Websites/article/" => array('type' => "Streams/template", "title" => "Untitled Article", "icon" => "default", "content" => "", "deletable" => true), "Websites/seo/" => array('type' => "Streams/template", "title" => "Website SEO", "icon" => Q_Html::themedUrl("plugins/Websites/img/seo"), "content" => "", "deletable" => true), "Websites/header" => array('type' => "Streams/image/icon", "title" => "Header image", "icon" => Q_Html::themedUrl("plugins/Websites/img/header"), "content" => ""), "Websites/slogan" => array('type' => "Streams/text/small", "title" => "Website slogan", "icon" => "default", "content" => "The coolest website"), "Websites/title" => array('type' => "Streams/text/small", "title" => "Website title", "icon" => "default", "content" => "Website Title"), "Websites/menu" => array('type' => "Streams/category", "title" => "Website Menu", "icon" => "default", "content" => ""), "Websites/articles" => array('type' => "Streams/category", "title" => "Articles", "icon" => "default", "content" => "Articles"), "Websites/images" => array('type' => "Streams/category", "title" => "Images", "icon" => "default", "content" => "Articles"));
    $readLevel = Streams::$READ_LEVEL['messages'];
    $writeLevel = Streams::$WRITE_LEVEL['edit'];
    $adminLevel = Streams::$ADMIN_LEVEL['own'];
    $rows = array();
    foreach ($streams as $streamName => $stream) {
        $publisherId = substr($streamName, -1) == '/' ? '' : $userId;
        $writeLevel = !empty($stream['deletable']) ? 40 : 30;
        $rows[] = compact('publisherId', 'streamName', 'ofUserId', 'ofContactLabel', 'grantedByUserId', 'readLevel', 'writeLevel', 'adminLevel');
    }
    Streams_Access::insertManyAndExecute($rows);
    $attributes = null;
    $closedTime = null;
    $readLevel = Streams::$READ_LEVEL['messages'];
    $writeLevel = Streams::$WRITE_LEVEL['join'];
    $adminLevel = Streams::$ADMIN_LEVEL['invite'];
    $inheritAccess = null;
    $rows = array();
    foreach ($streams as $name => $s) {
        extract($s);
        if (substr($name, 0, 9) != 'Websites/') {
            continue;
            // this tempate was already added by Streams install script
        }
        $publisherId = substr($name, -1) == '/' ? '' : $userId;
        $rows[] = compact('publisherId', 'name', 'type', 'title', 'icon', 'content', 'attributes', 'readLevel', 'writeLevel', 'adminLevel', 'inheritAccess');
    }
    Streams_Stream::insertManyAndExecute($rows);
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Streams/images/', 'type' => 'images', 'fromPublisherId' => '', 'fromStreamName' => 'Streams/image/'))->execute();
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Streams/category/', 'type' => 'articles', 'fromPublisherId' => '', 'fromStreamName' => 'Websites/article/'))->execute();
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Streams/category/', 'type' => 'announcements', 'fromPublisherId' => '', 'fromStreamName' => 'Websites/article/'))->execute();
}
Example #27
0
function Broadcast_stream_response_form($params)
{
    extract($params);
    if (empty($publisherId)) {
        $publisherId = Streams::requestedPublisherId(true);
    }
    if (empty($name)) {
        $name = Streams::requestedName(true);
    }
    $name = is_array($name) ? implode('/', $name) : $name;
    $src = 'Broadcast/widget?';
    $q = array('publisherId' => $publisherId, 'streamName' => $name);
    foreach (array('css', 'button', 'checkbox', 'explanation') as $field) {
        if (isset($_REQUEST[$field])) {
            $q[$field] = $_REQUEST[$field];
        }
    }
    $src .= http_build_query($q, null, '&');
    $style = 'border: 0px;';
    $code = Q_Html::tag('iframe', compact('src', 'style'), '');
    return $code;
}
Example #28
0
function Users_after_Q_image_save($params, &$return)
{
    extract($params);
    /**
     * @var string $path
     * @var string $subpath
     * @var Users_User $user
     */
    $user = Users::loggedInUser(true);
    $fullpath = $path . ($subpath ? DS . $subpath : '');
    $prefix = "uploads/Users/{$user->id}/icon";
    if (substr($fullpath, 0, strlen($prefix)) === $prefix) {
        if ($user->icon != $subpath) {
            $user->icon = Q_Html::themedUrl("{$path}/{$subpath}");
            $user->save();
            // triggers any registered hooks
            Users::$cache['iconUrlWasChanged'] = true;
        } else {
            Users::$cache['iconUrlWasChanged'] = false;
        }
    }
}
Example #29
0
function Trump_welcome_response_content($params)
{
    Q_Response::addStylesheet('http://fonts.googleapis.com/css?family=Lobster');
    $options = array('transition' => array('duration' => 2000), 'interval' => array('duration' => 9000));
    $styles = array(null, array('color' => '#5a3127', 'text-shadow' => 'white 4px -2px'), array('color' => '#ee2244'), array('color' => '#ffffff', 'left' => '20px', 'margin' => '0px', 'top' => '20px'), array('color' => '#ffffff', 'left' => '20px', 'margin' => '0px', 'top' => '20px'), array('color' => '#000000'), array('color' => '#ffffff'), array('color' => '#5a3127', 'text-shadow' => 'white 2px -1px'), array('color' => '#ffffff', 'text-shadow' => 'black 4px -2px'), array('color' => '#5577ff', 'left' => '20px', 'margin' => '0px', 'top' => '20px'), array('color' => '#ff33cc'), array('color' => '#cc33ff', 'text-shadow' => 'black 4px -2px'), array('color' => '#000000'), array('color' => '#ff3355'), array('color' => '#5a3127', 'text-shadow' => 'white 4px -2px'));
    $captions = array(null, 'Trump Village Estates', 'Relaxing oasis', 'A short walk from the beach', null, 'Beautiful sunsets', 'Great neighborhood', 'Convenient parking lots', 'Awesome amenities', 'Near Q and F trains', null, 'Parks between buildings', 'Near Coney Island', 'Enjoy your summer!', 'Trump Village Estates');
    for ($i = 1; $i <= 14; ++$i) {
        $image = array('src' => Q_Html::themedUrl("img/welcome/{$i}.jpg"), 'caption' => $captions[$i], 'style' => $styles[$i]);
        $options['images'][] = $image;
    }
    for ($i = 5; $i <= count($options['images']) - 2; $i += 2) {
        $options['images'][$i]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0, 'top' => 0.02, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0.15, 'top' => 0.01, 'width' => 0.5, 'height' => 0.5));
        $options['images'][$i + 1]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0.3, 'top' => 0.1, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0, 'top' => 0, 'width' => 1, 'height' => 1), 'ease' => 'smooth');
    }
    $options['images'][0]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0.4, 'top' => 0.5, 'width' => 0.4, 'height' => 0.25), 'to' => array('left' => 0.0, 'top' => 0, 'width' => 0.8, 'height' => 0.5));
    $options['images'][1]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0.5, 'top' => 0, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0.3, 'top' => 0.3, 'width' => 0.5, 'height' => 0.5));
    $options['images'][2]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0.1, 'top' => 0.0, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0, 'top' => 0, 'width' => 0.9, 'height' => 0.9));
    $options['images'][3]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0, 'top' => 0.01, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0.15, 'top' => 0.01, 'width' => 0.5, 'height' => 0.5));
    $options['images'][4]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0.3, 'top' => 0.1, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0, 'top' => 0, 'width' => 1, 'height' => 1), 'ease' => 'smooth');
    $options['images'][9]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0, 'top' => 0.2, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0.3, 'top' => 0.2, 'width' => 0.7, 'height' => 0.7), 'ease' => 'smooth');
    $options['images'][13]['interval'] = array('type' => 'kenburns', 'from' => array('left' => 0.3, 'top' => 0.1, 'width' => 0.5, 'height' => 0.5), 'to' => array('left' => 0, 'top' => 0, 'width' => 1, 'height' => 1), 'ease' => 'smooth');
    return Q::view('Trump/content/welcome.php', compact('options'));
}
Example #30
0
 function authToken($customerId = null)
 {
     if (!isset($customerId)) {
         $customerId = $this->customerId();
     }
     $options = $this->options;
     // Common Set Up for API Credentials
     $merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
     $merchantAuthentication->setName($options['authname']);
     $merchantAuthentication->setTransactionKey($options['authkey']);
     $refId = 'ref' . time();
     $setting = new AnetAPI\SettingType();
     // 2do: fix domain name and path for iframe popup
     $setting->setSettingName("hostedProfileIFrameCommunicatorUrl");
     $setting->setSettingValue(Q_Html::themedUrl('plugins/Assets/authnet_iframe_communicator.html'));
     $setting->setSettingName("hostedProfilePageBorderVisible");
     $setting->setSettingValue("false");
     $frequest = new AnetAPI\GetHostedProfilePageRequest();
     $frequest->setMerchantAuthentication($merchantAuthentication);
     $frequest->setCustomerProfileId($customerId);
     $frequest->addToHostedProfileSettings($setting);
     $controller = new AnetController\GetHostedProfilePageController($frequest);
     $fresponse = $controller->executeWithApiResponse($options['server']);
     if (!isset($fresponse) or $fresponse->getMessages()->getResultCode() != "Ok") {
         $messages = $fresponse->getMessages()->getMessage();
         $message = reset($messages);
         throw new Assets_Exception_InvalidResponse(array('response' => $message->getCode() . ' ' . $message->getText()));
     }
     return $fresponse->getToken();
 }