Ejemplo n.º 1
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')));
}
Ejemplo n.º 2
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);
					}
				}')));
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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));
    }
}
Ejemplo n.º 5
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'));
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
 /**
  * Returns the HTML markup for referencing all the stylesheets added so far
  * @method stylesheets
  * @static.
  * @param {string} [$slotName=null] If provided, returns only the stylesheets added while filling this slot.
  * @param {string} [$between=''] Optional text to insert between the &lt;link&gt; tags
  * @return {string} the HTML markup for referencing all the stylesheets added so far
  */
 static function stylesheets($slotName = null, $between = "\n")
 {
     $stylesheets = self::stylesheetsArray($slotName);
     if (empty($stylesheets)) {
         return '';
     }
     $tags = array();
     foreach ($stylesheets as $stylesheet) {
         $rel = 'stylesheet';
         $href = '';
         $media = 'screen, print';
         $type = 'text/css';
         extract($stylesheet, EXTR_IF_EXISTS);
         $attributes = compact('rel', 'type', 'href', 'media');
         $attributes['data-slot'] = $stylesheet['slot'];
         $tags[] = Q_Html::tag('link', $attributes);
     }
     return implode($between, $tags);
 }
Ejemplo n.º 9
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']);
}
Ejemplo n.º 10
0
function Streams_invite_tool($options)
{
    extract($options);
    $form_tool = Q::tool('Q/form', array('fields' => array('displayName' => array('label' => "Display name", 'type' => 'text', 'value' => Streams::displayName(Users::loggedInUser(), array('fullAccess' => true))), 'userId' => array('label' => "User id to invite", 'type' => 'textarea'), 'identifier' => array('label' => 'Mobile Number or Email Address', 'type' => 'textarea'), 'label' => array('label' => 'Group label', 'type' => 'textarea'), 'readLevel' => array('label' => 'Read level', 'type' => 'select', 'value' => Streams::$READ_LEVEL['content'], 'options' => array_flip(Streams::$READ_LEVEL)), 'writeLevel' => array('label' => 'Write level', 'type' => 'select', 'value' => Streams::$WRITE_LEVEL['post'], 'options' => array_flip(Streams::$WRITE_LEVEL)), 'adminLevel' => array('label' => 'Admin level', 'type' => 'select', 'options' => array_flip(Streams::$ADMIN_LEVEL)), 'submit' => array('label' => '', 'type' => 'submit_buttons', 'options' => array('submit' => 'Send Invite'))))) . Q_Html::hidden(array('publisherId' => $stream->publisherId, 'streamName' => $stream->name));
    return Q_Html::tag('h3', array(), 'Invite to stream "' . $options['stream']->name . '"') . Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/invite', 'post', array(), $form_tool);
}
Ejemplo n.º 11
0
/**
 * This tool renders tabs which behave appropriately in many different environments
 * @class Q tabs
 * @constructor
 * @param {array} [$options] options to pass to the tool
 *  @param {array} [$options.tabs] An associative array of name: title pairs.
 *  @param {array} [$options.urls] An associative array of name: url pairs to override the default urls.
 *  @param {string} [$options.field='tab'] Uses this field when urls doesn't contain the tab name.
 *  @param {boolean} [options.checkQueryString=false] Whether the default getCurrentTab should check the querystring when determining the current tab
 *  @param {boolean} [$options.vertical=false] Stack the tabs vertically instead of horizontally
 *  @param {boolean} [$options.compact=false] Display the tabs interface in a compact space with a contextual menu
 *  @param {Object} [$options.overflow]
 *  @param {String} [$options.overflow.content] The html that is displayed when the tabs overflow. You can interpolate {{count}}, {{text}} or {{html}} in the string. 
 *  @param {String} [$options.overflow.glyph] Override the glyph that appears next to the overflow text. You can interpolate {{count}} here
 *  @param {String} [$options.overflow.defaultText] The text to interpolate {{text}} in the content when no tab is selected
 *  @param {String} [$options.overflow.defaultHtml] The text to interpolate {{text}} in the content when no tab is selected
 *  @param {string} [$options.defaultTabName] Here you can specify the name of the tab to show by default
 *  @param {string} [$options.selectors] Array of (slotName => selector) pairs, where the values are CSS style selectors indicating the element to update with javascript, and can be a parent of the tabs. Set to null to reload the page.
 *  @param {string} [$options.slot] The name of the slot to request when changing tabs with javascript.
 *  @param {string} [$options.classes] An associative array of the form name => classes, for adding classes to tabs
 *  @param {string} [$options.titleClasses]  An associative array for adding classes to tab titles
 *  @param {string} [$options.after] Name of an event that will return HTML to place after the generated HTML in the tabs tool element
 *  @param {string} [$options.loader] Name of a function which takes url, slot, callback. It should call the callback and pass it an object with the response info. Can be used to implement caching, etc. instead of the default HTTP request. This function shall be Q.batcher getter
 *  @param {string} [$options.onClick] Event when a tab was clicked, with arguments (name, element). Returning false cancels the tab switching.
 *  @param {string} [$options.beforeSwitch] Event when tab switching begins. Returning false cancels the switching.
 *  @param {string} [$options.beforeScripts] Name of the function to execute after tab is loaded but before its javascript is executed.
 *  @param {string} [$options.onCurrent] Name of the function to execute after a tab is shown to be selected.
 *  @param {string} [$options.onActivate] Name of the function to execute after a tab is activated.
 */
function Q_tabs_tool($options)
{
    $field = 'tab';
    $slot = 'content,title';
    $selectors = array('content' => '#content_slot');
    $urls = array();
    extract($options);
    if (!isset($tabs)) {
        return '';
    }
    if (isset($overflow) and is_string($overflow)) {
        $overflow = array('content' => $overflow);
    }
    /**
     * @var array $tabs
     * @var boolean $vertical
     * @var boolean $compact
     */
    $sel = isset($_REQUEST[$field]) ? $_REQUEST[$field] : null;
    $result = '';
    $i = 0;
    $selectedName = null;
    $uri_string = (string) Q_Dispatcher::uri();
    foreach ($tabs as $name => $title) {
        if ($name === $sel or $name === $uri_string or $urls[$name] === $uri_string or $urls[$name] === Q_Request::url()) {
            $selectedName = $name;
            break;
        }
    }
    foreach ($tabs as $name => $title) {
        if (isset($urls[$name])) {
            $urls[$name] = Q_Uri::url($urls[$name]);
        } else {
            $urls[$name] = Q_Uri::url(Q_Request::url(array($field => $name, "/Q\\.(.*)/" => null)));
        }
        $selected_class = $name === $selectedName ? ' Q_current' : '';
        $classes_string = " Q_tab_" . Q_Utils::normalize($name);
        if (isset($classes[$name])) {
            if (is_string($classes[$name])) {
                $classes_string .= ' ' . $classes[$name];
            } else {
                if (is_array($classes[$name])) {
                    $classes_string .= ' ' . implode(' ', $classes[$name]);
                }
            }
        }
        $titleClasses_string = '';
        if (isset($titleClasses[$name])) {
            if (is_string($titleClasses[$name])) {
                $titleClasses_string = $titleClasses[$name];
            } else {
                if (is_array($titleClasses[$name])) {
                    $titleClasses_string = implode(' ', $titleClasses[$name]);
                }
            }
        }
        $title_container = Q_Html::div(null, "Q_tabs_title {$titleClasses_string}", isset($title) ? $title : $name);
        $result .= Q_Html::tag('li', array('id' => 'tab_' . ++$i, 'class' => "Q_tabs_tab {$classes_string}{$selected_class}", 'data-name' => $name), Q_Html::a($urls[$name], $title_container));
    }
    Q_Response::setToolOptions(compact('selectors', 'slot', 'urls', 'defaultTabName', 'vertical', 'compact', 'overflow', 'field', 'loader', 'beforeSwitch', 'beforeScripts', 'onActivate'));
    Q_Response::addScript('plugins/Q/js/tools/tabs.js');
    Q_Response::addStylesheet('plugins/Q/css/tabs.css');
    $classes = empty($vertical) ? ' Q_tabs_horizontal' : ' Q_tabs_vertical';
    if (!empty($compact)) {
        $classes .= " Q_tabs_compact";
    }
    $after = isset($options['after']) ? Q::event($options['after'], $options) : '';
    return "<ul class='Q_tabs_tabs Q_clearfix{$classes}'>{$result}{$after}</ul>";
}
Ejemplo n.º 12
0
function Streams_stream_tool($options)
{
    extract($options);
    $fields = array();
    $hidden = array();
    $user = Users::loggedInUser();
    if (!$user) {
        throw new Users_Exception_NotLoggedIn();
    }
    // if PK provided check for the stream
    if (isset($publisherId) && isset($name)) {
        $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('content') || !$stream->testWriteLevel('edit')) {
            throw new Users_Exception_NotAuthorized();
        }
    } else {
        $stream = null;
    }
    // publisherId can be taken from request or shall be equal to user id
    $hidden['publisherId'] = $publisherId = isset($stream) ? $stream->publisherId : $user->id;
    // name for existing stream, for new streams name will be generated from type
    if (isset($stream)) {
        $hidden['name'] = $stream->name;
    }
    if (isset($publisherId)) {
        $fields['publisherId'] = array('label' => 'Publisher ID', 'type' => 'static', 'value' => $publisherId);
    }
    if (isset($name)) {
        $fields['name'] = array('label' => 'Stream name', 'type' => 'static', 'value' => $name);
    }
    // type shall be defined for new streams
    if (!isset($stream)) {
        $range = array_keys(Q_Config::expect('Streams', 'types'));
        if (!isset($type)) {
            // selection of available types
            $fields['type'] = array('label' => 'Stream type', 'type' => 'select', 'options' => array_combine($range, $range), 'value' => 'Streams/text');
        } else {
            // check if type is allowed
            if (!in_array($type, $range)) {
                throw new Q_Exception_WrongValue(array('field' => 'stream type', 'range' => join(', ', $range)));
            }
            $hidden['type'] = $type;
        }
    }
    // stream title
    $fields['title'] = array('label' => 'Title', 'type' => 'text', 'value' => $stream ? $stream->title : '');
    // stream content
    $fields['content'] = array('label' => 'Content', 'type' => 'textarea', 'value' => $stream ? $stream->content : '');
    $read_options = array_flip(Streams::$READ_LEVEL);
    if ($stream) {
        foreach ($read_options as $key => $value) {
            if (!$stream->testReadLevel($key)) {
                unset($read_options[$key]);
            }
        }
        $readLevel = min(isset($readLevel) ? $readLevel : 100, $stream->readLevel);
    }
    $fields['readLevel'] = array('label' => 'Read level', 'type' => 'select', 'value' => $readLevel ? $readLevel : Streams::$READ_LEVEL['content'], 'options' => $read_options);
    $write_options = array_flip(Streams::$WRITE_LEVEL);
    if ($stream) {
        foreach ($write_options as $key => $value) {
            if (!$stream->testWriteLevel($key)) {
                unset($write_options[$key]);
            }
        }
        $writeLevel = min(isset($writeLevel) ? $writeLevel : 100, $stream->writeLevel);
    }
    $fields['writeLevel'] = array('label' => 'Write level', 'type' => 'select', 'value' => $writeLevel ? $writeLevel : Streams::$WRITE_LEVEL['post'], 'options' => $write_options);
    $admin_options = array_flip(Streams::$ADMIN_LEVEL);
    if ($stream) {
        foreach ($admin_options as $key => $value) {
            if (!$stream->testAdminLevel($key)) {
                unset($admin_options[$key]);
            }
        }
        $adminLevel = min(isset($adminLevel) ? $adminLevel : 100, $stream->adminLevel);
    }
    array_pop($admin_options);
    $fields['adminLevel'] = array('label' => 'Admin level', 'type' => 'select', 'value' => $adminLevel ? $adminLevel : Streams::$ADMIN_LEVEL['none'], 'options' => $admin_options);
    $fields['submit'] = array('label' => '', 'type' => 'submit_buttons', 'options' => array('submit' => $stream ? 'Update' : 'Create'));
    if (empty($noJoin)) {
        $hidden['join'] = true;
    }
    return Q_Html::tag('h3', array(), !$stream ? 'Create a stream' : 'Update stream') . Q_Html::form(Q_Request::baseUrl() . '/action.php/Streams/stream', $stream ? 'put' : 'post', array(), Q_Html::hidden($hidden) . Q::tool('Q/form', array('fields' => $fields, 'onSuccess' => 'function (data) {
					if (data.errors) alert(data.errors);
					else {
						var stream = Q.getObject(["slots", "form", "fields"], data);
						Q.handle(Q.info.baseUrl+"/plugins/Streams/put?publisherId="+stream.publisherId+"&name="+stream.name);
					}
				}')));
}
Ejemplo n.º 13
0
/**
 * This tool is meant to be wrapped in a <form> tag
 * @param {array} $options An associative array of parameters, containing:
 * @param {array} $options.fields an associative array of fieldname => fieldinfo pairs,
 *   where fieldinfo contains the following:
 *     "type" => the type of the field (@see Q_Html::smartTag())
 *     "attributes" => additional attributes for the field input
 *     "value" => the initial value of the field input
 *     "options" => options for the field input (if type is "select", "checkboxes" or "radios")
 *     "message" => initial message, if any to put in the field's message space
 *     "label" => the label for the field
 *     "extra" => if set, this is html to replace the first cell, displacing the label
 *     "placeholder" => if set, this is the placeholder text for the input
 *     "fillFromRequest" => Defaults to true.
 *       If true, uses $_REQUEST to fill any fields with same name.
 *       Currently doesn't work for names which specify arrays, such as a[b].
 * @param {string} [$options.onSubmit] Optional. Name of the javascript function or url to pass to Q.handle on submit
 * @param {string} [$options.onResponse] Name of the javascript function or url to pass to Q.handle on response
 * @param {string} [$options.onSuccess] Name of javascript function or url to pass to Q.handle on success
 * @param {string} [$options.loader] Optional. Name of a javascript function which takes (action, method, params, slots, callback) as arguments.
 *    It should call the callback and pass it an object with the response info. Can be used to implement caching, etc.
 *    instead of the default HTTP request.
 *    If "loader" is Q.getter and request should be done bypasing cache, assign true to .ignoreCache property of the tool
 * @param {array|string} [$options.slotsToRequest] Optional. A string or array of slot names to request in response. Should include "form".
 * @param {array|string} [$options.contentElements] Optional. Array of $slotName => $cssSelector pairs for child element of the form to fill with HTML returned from the slot.
 */
function Q_form_tool($options)
{
    if (empty($options['fields'])) {
        $options['fields'] = array();
    }
    if (!array_key_exists('fillFromRequest', $options)) {
        $options['fillFromRequest'] = true;
    }
    if (empty($options['contentElements'])) {
        $options['contentElements'] = array();
    }
    $field_defaults = array('type' => 'text', 'attributes' => array(), 'value' => null, 'options' => array(), 'message' => '', 'placeholder' => null);
    $tr_array = array();
    $messages_td = false;
    $colspan = '';
    foreach ($options['fields'] as $name => $field) {
        if (isset($field['message'])) {
            $messages_td = true;
            $colspan = "colspan='2'";
        }
    }
    foreach ($options['fields'] as $name => $field) {
        if (!is_array($field)) {
            $name2 = '"' . addslashes($name) . '"';
            throw new Q_Exception_WrongType(array('field' => "\$options[{$name2}]", 'type' => 'array'));
        }
        $field2 = array_merge($field_defaults, $field);
        $type = $field2['type'];
        if ($type === 'hidden') {
            continue;
        }
        $attributes = array('name' => $name, 'id' => $name);
        $value = $field2['value'];
        $o = $field2['options'];
        $message = $field2['message'];
        if (!empty($options['fillFromRequest']) and !in_array($type, array('button', 'submit'))) {
            if (isset($_REQUEST[$name])) {
                $value = $_REQUEST[$name];
            } else {
                if ($type === 'static' or $type === 'date') {
                    $parts = array($name . '_hour' => 0, $name . '_minute' => 0, $name . '_second' => 0, $name . '_month' => date('m'), $name . '_day' => date('d'), $name . '_year' => date('Y'));
                    $provided = Q::ifset($_REQUEST, array_keys($parts), null);
                    if (isset($provided)) {
                        $mktime = Q::take($_REQUEST, $parts);
                        $value = call_user_func_array('mktime', $mktime);
                    }
                }
            }
        }
        if (isset($field2['placeholder'])) {
            $attributes['placeholder'] = $field2['placeholder'];
        }
        if ($field2['attributes']) {
            $attributes = array_merge($attributes, $field2['attributes']);
        }
        if (ctype_alnum($type)) {
            if (isset($attributes['class'])) {
                if (is_array($attributes['class'])) {
                    foreach ($attributes['class'] as $k => $v) {
                        $attributes['class'][$k] .= " {$type}";
                    }
                } else {
                    $attributes['class'] .= " {$type}";
                }
            } else {
                $attributes['class'] = " {$type}";
            }
        }
        $label = isset($field['label']) ? $field['label'] : Q_Html::text($name);
        $label = Q_Html::tag('label', array('for' => $attributes['id']), $label);
        $name_text = Q_Html::text($name);
        $extra = isset($field['extra']) ? $field['extra'] : null;
        switch ($type) {
            case 'textarea':
                $tr_rest = "<td class='Q_form_fieldinput' data-fieldname=\"{$name_text}\" {$colspan}>" . ($extra ? "<div class='Q_form_label'>{$label}</div>" : '') . Q_Html::smartTag($type, $attributes, $value, $o) . "</td></tr><tr><td class='Q_form_placeholder'>" . "</td><td class='Q_form_undermessage Q_form_textarea_undermessage' {$colspan}>" . "<div class='Q_form_undermessagebubble'>{$message}</div></td>";
                break;
            default:
                $tr_rest = "<td class='Q_form_fieldinput' data-fieldname=\"{$name_text}\">" . ($extra ? "<div class='Q_form_label'>{$label}</div>" : '') . Q_Html::smartTag($type, $attributes, $value, $o) . "</td>" . ($messages_td ? "<td class='Q_form_fieldmessage Q_form_{$type}_message'>{$message}</td>" : '') . "</tr><tr><td class='Q_form_placeholder'>" . "</td><td class='Q_form_undermessage Q_form_{$type}_undermessage' {$colspan}>" . "<div class='Q_form_undermessagebubble'></div></td>";
                break;
        }
        $leftside = $extra ? $extra : $label;
        $tr_array[] = "<tr><td class='Q_form_fieldname'>{$leftside}</td>{$tr_rest}</tr>";
    }
    $result = "<table class='Q_form_tool_table'>\n" . implode("\n\t", $tr_array) . "\n</table>";
    foreach ($options['fields'] as $name => $field) {
        if (isset($field['type']) and $field['type'] === 'hidden') {
            $result .= Q_Html::hidden($field['value'], $name);
        }
    }
    $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;
}