Ejemplo n.º 1
0
function Websites_before_Q_uriFromUrl($params, &$result)
{
    $wp = new Websites_Permalink();
    $wp->url = $params['url'];
    if ($wp->retrieve()) {
        $result = Q_Uri::from($wp->uri);
    }
}
Ejemplo n.º 2
0
function Trump_before_Websites_permalink($params)
{
    $uri = Q_Uri::from($params['permalink']->uri);
    if ($uri->module === 'Trump' and $uri->action === 'article') {
        $streamName = "Websites/article/{$uri->articleId}";
        $params['stream'] = Streams::fetchOne(null, 'Trump', $streamName);
    }
}
Ejemplo n.º 3
0
/**
 * We are going to implement a subset of the OAuth 1.0a functionality for now,
 * and later we can expand it to match the full OAuth specification.
 */
function Users_authorize_response()
{
    if (Q_Response::getErrors()) {
        Q_Dispatcher::showErrors();
    }
    $response_type = 'token';
    $token_type = 'bearer';
    $client_id = $_REQUEST['client_id'];
    $state = $_REQUEST['state'];
    $skip = Q::ifset($_REQUEST, 'skip', false);
    $scope = Users_OAuth::requestedScope(true, $scopes);
    $client = Users_User::fetch($client_id, true);
    if (!$client) {
        throw new Q_Exception_MissingRow(array('table' => 'client user', 'criteria' => "id = '{$client_id}'"), 'client_id');
    }
    if (empty($client->url)) {
        throw new Q_Exception("Client app needs to register url", 'client_id');
    }
    $redirect_uri = Q::ifset($_REQUEST, 'redirect_uri', $client->url);
    $user = Users::loggedInUser();
    $oa = null;
    if (isset(Users::$cache['oAuth'])) {
        $oa = Users::$cache['oAuth'];
    } else {
        if ($user) {
            $oa = new Users_OAuth();
            $oa->client_id = $client_id;
            $oa->userId = $user->id;
            $oa->state = $state;
            $oa = $oa->retrieve();
        }
    }
    $remaining = $scope;
    if ($oa and $oa->wasRetrieved()) {
        // User is logged in and already has a token for this client_id and state
        $paths = Q_Config::get('Users', 'authorize', 'clients', Q::app(), 'redirectPaths', false);
        $path = substr($redirect_uri, strlen($client->url) + 1);
        $p = array('response_type' => $response_type, 'token_type' => $token_type, 'access_token' => $oa->access_token, 'expires_in' => $oa->token_expires_seconds, 'scope' => implode(' ', $scope), 'state' => $oa->state);
        $p = Q_Utils::sign($p, 'Q.Users.oAuth');
        // the redirect uri could be a native app url scheme
        $s = strpos($redirect_uri, '#') === false ? '#' : '&';
        $redirect_uri = Q_Uri::from($redirect_uri . $s . http_build_query($p), false)->toUrl();
        if (!Q::startsWith($redirect_uri, $client->url) or is_array($paths) and !in_array($path, $paths)) {
            throw new Users_Exception_Redirect(array('uri' => $redirect_uri));
        }
        Q_Response::redirect($redirect_uri);
        return false;
    }
    $terms_label = Users::termsLabel('authorize');
    Q_Response::setScriptData('Q.Users.authorize', compact('client_id', 'redirect_uri', 'scope', 'scopes', 'remaining', 'state', 'response_type', 'skip'));
    $content = Q::view('Users/content/authorize.php', compact('client', 'user', 'redirect_uri', 'scope', 'scopes', 'remaining', 'state', 'terms_label', 'response_type', 'skip'));
    Q_Response::setSlot('content', $content);
    Q_Response::setSlot('column0', $content);
    return true;
}
Ejemplo n.º 4
0
function Websites_before_Q_uriFromUrl($params, &$result)
{
    if (!Q::$bootstrapped) {
        return;
        // we probably haven't even loaded the database configuration yet.
    }
    $wp = new Websites_Permalink();
    $wp->url = $params['url'];
    if ($wp->retrieve()) {
        $result = Q_Uri::from($wp->uri);
    }
}
Ejemplo n.º 5
0
/**
 * This is the default handler for the Q/responseExtras event.
 * It should not be invoked during AJAX requests, and especially
 * not during JSONP requests. It will output things like the nonce,
 * which prevents CSRF attacks, but is only supposed to be printed
 * on our webpages and not also given to anyone who does a JSONP request.
 */
function Q_before_Q_responseExtras()
{
    $app = Q_Config::expect('Q', 'app');
    $uri = Q_Dispatcher::uri();
    $url = Q_Request::url(true);
    $base_url = Q_Request::baseUrl();
    $ajax = Q_Request::isAjax();
    if (!$uri) {
        return;
    }
    $info = array('url' => $url, 'uriString' => (string) $uri);
    if ($uri) {
        $info['uri'] = $uri->toArray();
    }
    if (!$ajax) {
        $info = array_merge(array('app' => Q_Config::expect('Q', 'app')), $info, array('proxies' => Q_Config::get('Q', 'proxies', array()), 'baseUrl' => $base_url, 'proxyBaseUrl' => Q_Uri::url($base_url), 'proxyUrl' => Q_Uri::url($url), 'sessionName' => Q_Session::name(), 'nodeUrl' => Q_Utils::nodeUrl(), 'slotNames' => Q_Config::get("Q", "response", "slotNames", array('content', 'dashboard', 'title', 'notices'))));
    }
    foreach ($info as $k => $v) {
        Q_Response::setScriptData("Q.info.{$k}", $v);
    }
    if (!$ajax) {
        $uris = Q_Config::get('Q', 'javascript', 'uris', array());
        $urls = array();
        foreach ($uris as $u) {
            $urls["{$u}"] = Q_Uri::url("{$u}");
        }
        Q_Response::setScriptData('Q.urls', $urls);
    }
    // Export more variables to inline js
    $nonce = isset($_SESSION['Q']['nonce']) ? $_SESSION['Q']['nonce'] : null;
    if ($nonce) {
        Q_Response::setScriptData('Q.nonce', $nonce);
    }
    // Attach stylesheets and scripts
    foreach (Q_Config::get('Q', 'javascript', 'responseExtras', array()) as $src => $b) {
        if (!$b) {
            continue;
        }
        Q_Response::addScript($src);
    }
    foreach (Q_Config::get('Q', 'stylesheets', 'responseExtras', array()) as $src => $media) {
        if (!$media) {
            continue;
        }
        if ($media === true) {
            $media = 'screen,print';
        }
        Q_Response::addStylesheet($src, null, $media);
    }
}
Ejemplo n.º 6
0
function Users_before_Q_responseExtras()
{
    Q_Response::addScript('plugins/Users/js/Users.js');
    $app = Q_Config::expect('Q', 'app');
    $requireLogin = Q_Config::get('Users', 'requireLogin', array());
    $rl_array = array();
    foreach ($requireLogin as $rl => $value) {
        $rl_array[Q_Uri::url($rl)] = $value;
    }
    if (!Q_Request::isAjax()) {
        Q_Response::setScriptData('Q.plugins.Users.requireLogin', $rl_array);
        $successUrl = Q_Config::get('Users', 'uris', "{$app}/successUrl", "{$app}/home");
        $afterActivate = Q_Config::get('Users', 'uris', "{$app}/afterActivate", $successUrl);
        $loginOptions = Q_Config::get('Users', 'login', array("identifierType" => 'email,mobile', "userQueryUri" => 'Users/user', "using" => "native,facebook", "noRegister" => false));
        $loginOptions["afterActivate"] = Q_Uri::url($afterActivate);
        $loginOptions["successUrl"] = Q_Uri::url($successUrl);
        Q_Response::setScriptData('Q.plugins.Users.login.serverOptions', $loginOptions);
        $setIdentifierOptions = Q::take($loginOptions, array('identifierType'));
        Q_Response::setScriptData('Q.plugins.Users.setIdentifier.serverOptions', $setIdentifierOptions);
    }
    $fb_app_info = Q_Config::get('Users', 'facebookApps', $app, array());
    if ($fb_app_info) {
        unset($fb_app_info['secret']);
        Q_Response::setScriptData("Q.plugins.Users.facebookApps.{$app}", $fb_app_info);
    }
    if ($node_server_url = Q_Config::get('Users', 'nodeServer', 'url', null)) {
        Q_Response::setScriptData("Q.plugins.Users.nodeServer", parse_url($node_server_url));
    }
    if (Q_Config::get('Users', 'showLoggedInUser', true)) {
        $user = Q_Session::id() ? Users::loggedInUser() : null;
        if ($user) {
            $u = $user->exportArray();
            $u['sessionCount'] = $user->sessionCount;
            Q_Response::setScriptData("Q.plugins.Users.loggedInUser", $u);
            Q_Response::addScriptLine("Q.plugins.Users.loggedInUser = new Q.plugins.Users.User(Q.plugins.Users.loggedInUser);");
        }
    }
    Q_Response::setScriptData('Q.plugins.Users.communityId', Users::communityId());
    Q_Response::setScriptData('Q.plugins.Users.communityName', Users::communityName());
    Q_Response::setScriptData('Q.plugins.Users.communitySuffix', Users::communitySuffix());
    Q_Response::setScriptData('Q.plugins.Users.hinted', Q::ifset($_SESSION, 'Users', 'hinted', array()));
    if ($sizes = Q_Config::expect('Users', 'icon', 'sizes')) {
        sort($sizes);
        Q_Response::setScriptData('Q.plugins.Users.icon.sizes', $sizes);
    }
    $defaultSize = Q_Config::get('Users', 'icon', 'defaultSize', 40);
    Q_Response::setScriptData('Q.plugins.Users.icon.defaultSize', $defaultSize);
    Q_Response::addStylesheet("plugins/Users/css/Users.css");
}
Ejemplo n.º 7
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.";
}
Ejemplo n.º 8
0
 function beforeSave($modifiedFields)
 {
     $stream = null;
     $uri = Q_Uri::from($this->uri);
     if ($uri->module === 'Streams' and $uri->action === 'stream') {
         $publisherId = Streams::requestedPublisherId(false, $uri);
         $streamName = Streams::requestedName(false, 'original', $uri);
         $stream = Streams::fetchOne(null, $publisherId, $streamName);
     }
     Q::event('Websites/permalink', array('permalink' => $this, 'modifiedFields' => $modifiedFields, 'stream' => &$stream), 'before');
     if ($stream and $stream instanceof Streams_Stream) {
         $stream->setAttribute("Websites/url", $this->url);
         $stream->changed();
     }
     return parent::beforeSave($modifiedFields);
 }
Ejemplo n.º 9
0
/**
 * We are going to implement a subset of the OAuth 1.0a functionality for now,
 * and later we can expand it to match the full OAuth specification.
 */
function Users_authorize_response()
{
    if (Q_Response::getErrors()) {
        Q_Dispatcher::showErrors();
    }
    $client_id = $_REQUEST['client_id'];
    $redirect_url = $_REQUEST['redirect_uri'];
    $state = $_REQUEST['state'];
    $client = Users_User::fetch($client_id);
    if (!$client) {
        throw new Q_Exception_MissingRow(array('table' => 'user', 'criteria' => "id = '{$client_id}'"), 'client_id');
    }
    if (empty($client->url)) {
        throw new Q_Exception("Client app needs to register url", 'client_id');
    }
    if (substr($redirect_url, 0, strlen($client->url)) !== $client->url) {
        throw new Q_Exception_WrongValue(array('field' => 'redirect_uri', 'range' => "a url prefixed by client user's url"));
    }
    $user = Users::loggedInUser();
    $oa = null;
    if (isset(Users::$cache['oAuth'])) {
        $oa = Users::$cache['oAuth'];
    } else {
        if ($user) {
            $oa = new Users_OAuth();
            $oa->client_id = $client_id;
            $oa->userId = $user->id;
            $oa->state = $state;
            $oa->retrieve();
        }
    }
    if ($oa and $oa->wasRetrieved()) {
        // User is logged in and already has a token for this client_id and state
        $separator = strpos($redirect_url, '?') === false ? '?' : '&';
        $url = $redirect_url . $separator . http_build_query(array('access_token' => $oa->access_token, 'token_type' => 'bearer', 'expires_in' => $oa->token_expires_seconds, 'scope' => 'user', 'state' => $oa->state));
        Q_Response::redirect(Q_Uri::from($url, false));
        return false;
    }
    $terms_label = Users::termsLabel('authorize');
    $content = Q::view('Users/content/authorize.php', compact('client', 'redirect_url', 'user', 'state', 'terms_label'));
    Q_Response::setSlot('content', $content);
    Q_Response::setSlot('column0', $content);
    return true;
}
Ejemplo n.º 10
0
/**
 * Renders an import tool
 * @param $options
 *   An associative array of parameters, which can include:
 *   "provider" => Required. The provider from which we are importing.
 * @return {string}
 */
function Users_importContacts_tool($options)
{
    $provider = $options['provider'];
    ob_start();
    try {
        if (!($client = Users::oAuth($provider))) {
            throw new Users_Exception_NotAuthorized();
        }
        Q::event('Users/importContacts/providers/' . $provider, array('client' => $client));
    } catch (Users_Exception_OAuthTokenInvalid $ex) {
        #TODO: Log something to error log?
        Users::oAuthClear($provider);
        Q_Response::redirect(Q_Uri::url(Q_Request::url(true)));
        return false;
    } catch (Zend_Oauth_Exception $ex) {
        #TODO: Show a nicely-formatted message and close the pop-up
        echo 'Could not import contacts: ' . $ex->getMessage();
    }
    $out = ob_get_contents();
    ob_clean();
    Q_Response::output($out, true);
    return true;
}
Ejemplo n.º 11
0
Click here to verify your mobile number:
<?php 
echo Q_Uri::url($link);
Ejemplo n.º 12
0
 /**
  * Returns the canonical url of the stream, if any
  * @return {string|null|false}
  */
 function url()
 {
     $uri = self::getConfigField($this->type, 'uri', null);
     if (!$uri) {
         return null;
     }
     $uriString = Q_Handlebars::renderSource($uri, array('publisherId' => $this->publisherId, 'streamName' => explode('/', $this->name), 'name' => $this->name));
     return Q_Uri::from($uriString)->toUrl();
 }
Ejemplo n.º 13
0
 protected static function handleForwardException($e)
 {
     $slotNames = Q_Request::slotNames(true);
     foreach ($slotNames as $slotName) {
         Q_Response::clearSlot($slotName);
     }
     // Go again, this time with a different URI.
     Q::$toolWasRendered = array();
     self::$uri = Q_Uri::from($e->uri);
     if (is_array($e->skip)) {
         self::$skip = $e->skip;
     } else {
         // Don't process any non-GET methods this time around,
         // Do not collect any analytics
         // And also ignore any accumulated errors
         self::$skip = array('Q/method' => true, 'Q/analytics' => true, 'Q/errors' => true);
     }
     // We'll be handling errors anew
     self::$handling_errors = false;
 }
Ejemplo n.º 14
0
 /**
  * Sets whether the response is buffered from the config, if any
  * @method setResponseBuffered
  * @static
  */
 static function setUrls()
 {
     $url = Q_Config::get('Q', 'response', 'cacheBaseUrl', null);
     if (isset($url)) {
         Q_Uri::cacheBaseUrl($url);
     }
 }
Ejemplo n.º 15
0
 /**
  * Set cache base url, relative to which this particular client may store cached
  * versions of files.
  * @method cacheBaseUrl
  * @static
  * @param {array} [$base_url=null] If no arguments are passed, just returns the current cache base url.
  * @return {array} Returns the cache base url at the time the function was called.
  */
 static function cacheBaseUrl($base_url = null)
 {
     if (!isset($base_url)) {
         return isset(self::$cacheBaseUrl) ? self::$cacheBaseUrl : array();
     }
     $prev_base_url = self::$cacheBaseUrl;
     self::$cacheBaseUrl = $base_url;
     return $prev_base_url;
 }
Ejemplo n.º 16
0
 /**
  * @method uri
  * @static
  * @return {Q_Uri}
  */
 static function uri()
 {
     if (!isset(self::$uri)) {
         self::$uri = Q_Uri::from(self::url());
     }
     return self::$uri;
 }
Ejemplo n.º 17
0
 /**
  * @method init
  * @static
  */
 static function init()
 {
     if (self::$inited) {
         return false;
     }
     ini_set("session.entropy_file", "/dev/urandom");
     ini_set("session.entropy_length", "512");
     ini_set("session.hash_function", "1");
     $base_url = Q_Request::baseUrl();
     $name = Q_Config::get('Q', 'session', 'name', 'sessionId');
     $lifetime = Q_Config::get('Q', 'session', 'durations', Q_Request::formFactor(), 0);
     $parts = parse_url($base_url);
     $path = !empty($parts['path']) ? $parts['path'] : '/';
     $domain = '.' . $parts['host'];
     Q::event('Q/session/init', array('name' => &$name, 'lifetime' => &$lifetime, 'path' => &$path, 'domain' => &$domain), 'before');
     Q_Session::name($name);
     session_set_cookie_params(isset($lifetime) ? $lifetime : 0, $path, $domain, false, false);
     if (Q_Config::get('Q', 'session', 'appendSuffix', false) or isset($_GET[$name])) {
         if (self::id()) {
             $s = "?{$name}=" . self::id();
             $suffix = Q_Uri::suffix();
             $suffix[$base_url] = isset($suffix[$base_url]) ? $suffix[$base_url] . $s : $s;
             Q_Uri::suffix($suffix);
         }
     }
     self::$inited = true;
     return true;
 }
Ejemplo n.º 18
0
/**
 * Default Q/response handler.
 * 1. Gets some slots, depending on what was requested.
 * 2. Renders them in a layout
 *    The layout expects "title", "dashboard" and "contents" slots to be filled.
 */
function Q_response($params)
{
    extract($params);
    /**
     * @var Exception $exception
     * @var array $errors
     */
    if (empty($errors)) {
        $errors = Q_Response::getErrors();
    }
    if (!empty($_GET['Q_ct'])) {
        Q_Response::setCookie('Q_ct', $_GET['Q_ct']);
    }
    // If output is set, use that
    $output = Q_Response::output();
    if (isset($output)) {
        if ($output === true) {
            return;
        }
        if (is_string($output)) {
            echo $output;
        }
        return;
    }
    // Redirect to success page, if requested.
    $isAjax = Q_Request::isAjax();
    if (empty($errors) and empty($exception)) {
        if (!$isAjax and null !== Q_Request::special('onSuccess', null)) {
            $onSuccess = Q_Request::special('onSuccess', null);
            if (Q_Config::get('Q', 'response', 'onSuccessShowFrom', true)) {
                $onSuccess = Q_Uri::url($onSuccess . '?Q.fromSuccess=' . Q_Dispatcher::uri());
            }
            Q_Response::redirect($onSuccess);
            return;
        }
    }
    // Get the requested module
    $uri = Q_Dispatcher::uri();
    if (!isset($module)) {
        $module = $uri->module;
        if (!isset($module)) {
            $module = 'Q';
            Q_Dispatcher::uri()->module = 'Q';
        }
    }
    if (!$isAjax || Q_Request::isLoadExtras()) {
        Q::event('Q/responseExtras', array(), 'before');
    }
    // Get the main module (the app)
    $app = Q_Config::expect('Q', 'app');
    $action = $uri->action;
    if (Q::canHandle("{$module}/{$action}/response")) {
        if (false === Q::event("{$module}/{$action}/response") and !$isAjax) {
            return;
        }
    }
    $slotNames = Q_Request::slotNames(true);
    $idPrefixes = array();
    if ($temp = Q_Request::special('idPrefixes', null)) {
        foreach (explode(',', $temp) as $i => $prefix) {
            if (!isset($slotNames[$i])) {
                throw new Q_Exception("More id prefixes than slot names", "Q.idPrefixes");
            }
            $idPrefixes[$slotNames[$i]] = $prefix;
        }
    }
    // What to do if this is an AJAX request
    if ($isAjax) {
        $to_encode = array();
        if (Q_Response::$redirected) {
            // We already called Q_Response::redirect
            $to_encode['redirect']['url'] = Q_Uri::url(Q_Response::$redirected);
            try {
                $to_encode['redirect']['uri'] = Q_Uri::from(Q_Response::$redirected)->toArray();
            } catch (Exception $e) {
                // couldn't get internal URI
            }
        } else {
            if (is_array($slotNames)) {
                foreach ($slotNames as $slotName) {
                    Q_Response::fillSlot($slotName, 'default', Q::ifset($idPrefixes, $slotName, null));
                }
                // Go through the slots again, because other handlers may have overwritten
                // their contents using Q_Response::setSlot()
                foreach ($slotNames as $sn) {
                    Q_Response::fillSlot($sn, 'default', Q::ifset($idPrefixes, $slotName, null));
                }
                if (Q_Response::$redirected) {
                    // While rendering the slots we called Q_Redirect
                    $to_encode['redirect']['url'] = Q_Uri::url(Q_Response::$redirected);
                    try {
                        $to_encode['redirect']['uri'] = Q_Uri::from(Q_Response::$redirected)->toArray();
                    } catch (Exception $e) {
                        // couldn't get internal URI
                    }
                } else {
                    if (Q_Request::isLoadExtras()) {
                        $to_encode['slots'] = Q_Response::slots(true);
                        // add stylesheets, stylesinline, scripts, scriptlines, scriptdata, templates
                        foreach (array_merge(array(''), $slotNames) as $slotName) {
                            $temp = Q_Response::stylesheetsArray($slotName);
                            if ($temp) {
                                $to_encode['stylesheets'][$slotName] = $temp;
                            }
                            $temp = Q_Response::stylesInline($slotName);
                            if ($temp) {
                                $to_encode['stylesInline'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptsArray($slotName);
                            if ($temp) {
                                $to_encode['scripts'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptLines($slotName, true, "\n", false);
                            if ($temp) {
                                $to_encode['scriptLines'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptData($slotName);
                            if ($temp) {
                                $to_encode['scriptData'][$slotName] = $temp;
                            }
                            $temp = Q_Response::templateData($slotName);
                            if ($temp) {
                                $to_encode['templates'][$slotName] = $temp;
                            }
                        }
                    } else {
                        $to_encode['slots'] = Q_Response::slots(true);
                        // add stylesinline, scriptlines, scriptdata, templates
                        foreach (array_merge(array(''), $slotNames) as $slotName) {
                            $temp = Q_Response::stylesInline($slotName);
                            if ($temp) {
                                $to_encode['stylesInline'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptData($slotName);
                            if ($temp) {
                                $to_encode['scriptData'][$slotName] = $temp;
                            }
                            $temp = Q_Response::scriptLines($slotName, true, "\n", false);
                            if ($temp) {
                                $to_encode['scriptLines'][$slotName] = $temp;
                            }
                        }
                    }
                }
            }
        }
        $to_encode['timestamp'] = microtime(true);
        $echo = Q_Request::contentToEcho();
        if (isset($echo)) {
            $to_encode['echo'] = $echo;
        }
        $json = Q::json_encode(Q::cutoff($to_encode));
        $callback = Q_Request::callback();
        switch (strtolower($isAjax)) {
            case 'iframe':
                if (!Q_Response::$batch) {
                    header("Content-type: text/html");
                }
                echo <<<EOT
<!doctype html><html lang=en>
<head><meta charset=utf-8><title>Q Result</title></head>
<body>
<script type="text/javascript">
window.result = function () { return {$json} };
</script>
</body>
</html>
EOT;
                break;
            case 'json':
            default:
                if (!Q_Response::$batch) {
                    header("Content-type: " . ($callback ? "application/javascript" : "application/json"));
                }
                echo $callback ? "{$callback}({$json})" : $json;
        }
        return;
    }
    // If this is a request for a regular webpage,
    // fill the usual slots and render a layout.
    if (Q_Response::$redirected) {
        return;
        // If already set a redirect header, simply return -- no reason to output all this HTML
    }
    static $added_Q_init = false;
    if (!$added_Q_init) {
        Q_Response::addScriptLine("\n// Now, initialize Q\nQ.init();\n", null, 'Q');
        $added_Q_init = true;
    }
    // Get all the usual slots for a webpage
    $slots = array();
    foreach ($slotNames as $sn) {
        Q_Response::fillSlot($sn, 'default', Q::ifset($idPrefixes, $sn, null));
    }
    // Go through the slots again, because other handlers may have overwritten
    // their contents using Q_Response::setSlot()
    foreach ($slotNames as $sn) {
        Q_Response::fillSlot($sn, 'default', Q::ifset($idPrefixes, $sn, null));
    }
    $output = Q_Response::output();
    if (isset($output)) {
        if ($output === true) {
            return;
        }
        if (is_string($output)) {
            echo $output;
        }
        return;
    }
    if (!$isAjax or Q_Request::isLoadExtras()) {
        Q::event('Q/responseExtras', array(), 'after');
    }
    $slots = Q_Response::slots(false);
    // Render a full HTML layout
    $layout_view = Q_Response::layoutView();
    echo Q::view($layout_view, $slots);
}
Ejemplo n.º 19
0
 /**
  * Gets the url and filename of a themed file
  * @method themedUrlAndFilename
  * @static
  * @param {string} $filePath  Basically the subpath of the file underneath the web or theme directory
  * @param {boolean} [$ignoreEnvironment=false] If true, doesn't apply environment transformations
  * @return {array} A two-element array containing the url and filename
  */
 static function themedUrlAndFilename($filePath, $ignoreEnvironment = false)
 {
     /**
      * @event Q/themedUrlAndFilename {before}
      * @param {string} file_path
      * @return {array}
      */
     $result = Q::event('Q/themedUrlAndFilename', compact('file_path'), 'before');
     if ($result) {
         return $result;
     }
     if (!$ignoreEnvironment and $environment = Q_Config::get('Q', 'environment', false)) {
         if ($info = Q_Config::get('Q', 'environments', $environment, false)) {
             if (!empty($info['files'][$filePath])) {
                 $filePath = $info['files'][$filePath];
             }
         }
     }
     $filename = false;
     if (Q_Valid::url($filePath)) {
         $url = $filePath;
     } else {
         $theme = Q_Uri::url(self::themeUrl());
         $themes = self::$themes;
         $c = count($themes);
         if ($c > 1) {
             // At least two theme URLs have been loaded
             // Do the cascade
             for ($i = $c - 1; $i >= 0; --$i) {
                 try {
                     $filename = Q_Uri::filenameFromUrl($themes[$i] . '/' . $filePath);
                 } catch (Exception $e) {
                     continue;
                 }
                 if ($filename and file_exists($filename)) {
                     $theme = $themes[$i];
                     break;
                 }
             }
         }
         $url = $theme . '/' . $filePath;
     }
     if (empty($filename)) {
         try {
             $filename = Q_Uri::filenameFromUrl($url);
         } catch (Exception $e) {
             $filename = null;
         }
     }
     $url = Q_Uri::cachedUrl($url);
     return array($url, $filename);
 }
Ejemplo n.º 20
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.º 21
0
/**
 * The default implementation.
 */
function Q_errors($params)
{
    extract($params);
    /**
     * @var Exception $exception
     * @var boolean $startedResponse
     */
    if (!empty($exception)) {
        Q_Response::addError($exception);
    }
    $errors = Q_Response::getErrors();
    $errors_array = Q_Exception::toArray($errors);
    // Simply return the errors, if this was an AJAX request
    if ($is_ajax = Q_Request::isAjax()) {
        try {
            $errors_json = @Q::json_encode($errors_array);
        } catch (Exception $e) {
            $errors_array = array_slice($errors_array, 0, 1);
            unset($errors_array[0]['trace']);
            $errors_json = @Q::json_encode($errors_array);
        }
        $json = "{\"errors\": {$errors_json}}";
        $callback = Q_Request::callback();
        switch (strtolower($is_ajax)) {
            case 'iframe':
                if (!Q_Response::$batch) {
                    header("Content-type: text/html");
                }
                echo <<<EOT
<!doctype html><html lang=en>
<head><meta charset=utf-8><title>Q Result</title></head>
<body>
<script type="text/javascript">
window.result = function () { return {$json} };
</script>
</body>
</html>
EOT;
                break;
            case 'json':
            default:
                header("Content-type: " . ($callback ? "application/javascript" : "application/json"));
                echo $callback ? "{$callback}({$json})" : $json;
        }
        return;
    }
    // Forward internally, if it was requested
    if ($onErrors = Q_Request::special('onErrors', null)) {
        $uri1 = Q_Dispatcher::uri();
        $uri2 = Q_Uri::from($onErrors);
        $url2 = $uri2->toUrl();
        if (!isset($uri2)) {
            throw new Q_Exception_WrongValue(array('field' => 'onErrors', 'range' => 'an internal URI reachable from a URL'));
        }
        if ($uri1->toUrl() !== $url2) {
            Q_Dispatcher::forward($uri2);
            return;
            // we don't really need this, but it's here anyway
        }
    }
    $params2 = compact('errors', 'exception', 'errors_array', 'exception_array');
    if (Q::eventStack('Q/response')) {
        // Errors happened while rendering response. Just render errors view.
        return Q::view('Q/errors.php', $params2);
    }
    if (!$startedResponse) {
        try {
            // Try rendering the response, expecting it to
            // display the errors along with the rest.
            $ob = new Q_OutputBuffer();
            Q::event('Q/response', $params2);
            $ob->endFlush();
            return;
        } catch (Exception $e) {
            if (get_class($e) === 'Q_Exception_DispatcherForward') {
                throw $e;
                // if forwarding was requested, do it
                // for all other errors, continue trying other things
            }
            $output = $ob->getClean();
        }
    }
    if ($errors) {
        // Try rendering the app's errors response, if any.
        $app = Q::app();
        if (Q::canHandle("{$app}/errors/response/content")) {
            Q_Dispatcher::forward("{$app}/errors");
        } else {
            echo Q::view("Q/errors.php", compact('errors'));
        }
    }
    if (!empty($e)) {
        return Q::event('Q/exception', array('exception' => $e));
    }
}
Ejemplo n.º 22
0
 /**
  * A convenience method to get the URL of the streams-related action
  * @method register
  * @static
  * @param {string} $publisherId
  *	The name of the publisher
  * @param {string} $streamName
  *	The name of the stream
  * @param {string} $what
  *	Defaults to 'stream'. Can also be 'message', 'relation', etc.
  * @return {string} 
  *	The corresponding URL
  */
 static function actionUrl($publisherId, $streamName, $what = 'stream')
 {
     switch ($what) {
         case 'stream':
         case 'message':
         case 'relation':
             return Q_Uri::url("Streams/{$what}?publisherId=" . urlencode($publisherId) . "&name=" . urlencode($streamName));
     }
     return null;
 }
Ejemplo n.º 23
0
 /**
  * Sets a header to redirect to a given URI or URL.
  * @method redirect
  * @static
  * @param {string} $uri The URL or internal URI to redirect to
  * @param {array} $options An array of options that can include:
  *  "loop" => Defaults to false. If true, sets the redirect header even if the current URL is the same.
  *  "noProxy" => Defaults to false. If true, doesn't use the proxy mapping to determine URL
  *  "permanently" => If true, sets response code as 304 instead of 302
  * @param {boolean} [$noProxy=false]
  * @return {boolean}
  *  Return whether the redirect header was set.
  */
 static function redirect($uri, $options = array())
 {
     extract($options);
     $url = Q_Uri::url($uri, null, !empty($noProxy));
     if ($url === Q_Uri::unreachableUri()) {
         throw new Q_Exception_BadValue(array('internal' => 'uri', 'problem' => 'no url routes to it'));
     }
     $level = ob_get_level();
     for ($i = 0; $i < $level; ++$i) {
         ob_clean();
     }
     /**
      * @event Q/response {before}
      * @param {string} permanently
      * @param {string} uri
      * @param {string} url
      * @param {string} loop
      * @return {boolean}
      */
     $result = Q::event('Q/redirect', compact('uri', 'url', 'loop', 'permanently', 'noProxy', 'level'), 'before');
     if (isset($result)) {
         return $result;
     }
     if (!empty($loop) and Q_Request::url() === $url) {
         return false;
     }
     if (!Q_Request::isAjax()) {
         if (!empty($permanently)) {
             header("HTTP/1.1 301 Moved Permanently");
         }
         header("Location: {$url}");
     }
     self::$redirected = $uri;
     return true;
 }
Ejemplo n.º 24
0
#Read primary arguments
$LOCAL_DIR = $FROM_APP ? APP_DIR : $argv[1];
#Check paths
if (!file_exists($Q_filename = Q_DIR . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . 'Q.inc.php')) {
    #Q Platform
    die("[ERROR] {$Q_filename} not found" . PHP_EOL);
}
if (!is_dir($LOCAL_DIR)) {
    #App dir
    die("[ERROR] {$LOCAL_DIR} doesn't exist or is not a directory" . PHP_EOL);
}
#Define APP_DIR
if (!defined('APP_DIR')) {
    define('APP_DIR', $LOCAL_DIR);
}
#Include Q
try {
    include $Q_filename;
} catch (Exception $e) {
    die('[ERROR] ' . $e->getMessage() . PHP_EOL . $e->getTraceAsString() . PHP_EOL);
}
$app = Q_Config::expect('Q', 'app');
$identifier = $FROM_APP ? $argv[1] : $argv[2];
$communityId = Q::ifset($argv, $FROM_APP ? 2 : 3, Users::communityId());
$labels = array_slice($argv, $FROM_APP ? 3 : 4);
$addLabel = empty($labels) ? "{$app}/admins" : $labels;
$asUserId = $app;
$skipAccess = true;
$appUrl = Q_Uri::url('Communities/onboarding');
Streams::invite($communityId, 'Streams/community/main', compact('identifier'), compact('addLabel', 'asUserId', 'skipAccess', 'appUrl'));
echo "Successfully invited {$identifier}\n";
Ejemplo n.º 25
0
 /**
  * The standard action front controller
  * @method execute
  * @static
  * @throws {Q_Exception_BadUrl}
  * @throws {Q_Exception}
  * @throws {Q_Exception_MissingConfig}
  */
 static function execute($url = null)
 {
     // Fixes for different platforms:
     if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
         // ISAPI 3.0
         $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL'];
     }
     // Set the controller that is being used
     if (!isset(Q::$controller)) {
         Q::$controller = 'Q_ActionController';
     }
     try {
         $slots = Q_Request::slotNames(false);
         $slots = $slots ? ' slots: (' . implode(',', $slots) . ') from' : '';
         $method = Q_Request::method();
         Q::log("{$method}{$slots} url: " . Q_Request::url(true));
         $tail = Q_Request::tail($url);
         if (!isset($tail)) {
             // Bad url was requested somehow
             $url = Q_Request::url(true);
             $base_url = Q_Request::baseUrl(true);
             throw new Q_Exception_BadUrl(compact('base_url', 'url'));
         }
         $parts = explode('/', $tail);
         $parts_len = count($parts);
         if ($parts_len >= 1) {
             $module = $parts[0];
         }
         if ($parts_len >= 2) {
             $action = $parts[1];
         }
         if (empty($module) or empty($action)) {
             throw new Q_Exception("Not implemented");
         }
         // Make sure the 'Q'/'web' config fields are set,
         // otherwise URLs will be formed pointing to the wrong
         // controller script.
         $ar = Q_Config::get('Q', 'web', 'appRootUrl', null);
         if (!isset($ar)) {
             throw new Q_Exception_MissingConfig(array('fieldpath' => 'Q/web/appRootUrl'));
         }
         // Dispatch the request
         $uri = Q_Uri::from(compact('module', 'action'));
         Q_Dispatcher::dispatch($uri);
         $dispatchResult = Q_Dispatcher::result();
         if (!isset($dispatchResult)) {
             $dispatchResult = 'Ran dispatcher';
         }
         if ($module and $action) {
             $slotNames = Q_Request::slotNames();
             $requestedSlots = empty($slotNames) ? '' : implode(',', $slotNames);
             Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " {$dispatchResult} for {$module}/{$action}" . " ({$requestedSlots})");
         } else {
             Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " No route for " . $_SERVER['REQUEST_URI']);
         }
     } catch (Exception $exception) {
         /**
          * @event Q/exception
          * @param {Exception} exception
          */
         Q::event('Q/exception', compact('exception'));
     }
 }
Ejemplo n.º 26
0
/**
 * Access tool
 * @class Streams access
 * @constructor
 * @param {array} $options Options for the tool
 * @param {string} [$options.publisherId] the id of the user who is publishing the stream
 * @param {string} [$options.streamName] the name of the stream for which to edit access levels
 * @param {array} [$options.tabs] array of tab name => title. Defaults to read, write, admin tabs.
 * @param {array} [$options.ranges] associative array with keys "read", "write", "admin" and values as associative arrays of ($min, $max) for the displayed levels.
 * @param {boolean} [$options.controls] optionally set this to true to render only the controls
 */
function Streams_access_tool($options)
{
    $tabs = array('read' => 'visible to', 'write' => 'editable by', 'admin' => 'members');
    extract($options);
    $user = Users::loggedInUser(true);
    /**
     * @var string $streamName
     */
    if (empty($streamName)) {
        $streamName = Streams::requestedName(true);
    }
    if (empty($publisherId)) {
        $publisherId = Streams::requestedPublisherId();
        if (empty($publisherId)) {
            $publisherId = $user->id;
        }
    }
    reset($tabs);
    $tab = Q::ifset($_REQUEST, 'tab', key($tabs));
    $stream = Streams::fetchOne($user->id, $publisherId, $streamName);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'));
    }
    $stream->addPreloaded($user->id);
    if (!$stream->testAdminLevel('own')) {
        throw new Users_Exception_NotAuthorized();
    }
    $access_array = Streams_Access::select('*')->where(array('publisherId' => $stream->publisherId, 'streamName' => $stream->name))->andWhere("{$tab}Level != -1")->fetchDbRows();
    $labelRows = Users_Label::fetch($stream->publisherId, '', true);
    $labels = array();
    $icons = array();
    foreach ($labelRows as $label => $row) {
        $labels[$label] = $row->title;
        $icons[$label] = "labels/{$label}";
    }
    $userId_list = array();
    foreach ($access_array as $a) {
        if ($a->ofUserId) {
            $userId_list[] = $a->ofUserId;
        }
    }
    $avatar_array = empty($userId_list) ? array() : Streams_Avatar::fetch($user->id, $userId_list);
    switch ($tab) {
        case 'read':
            $levels = Q_Config::get('Streams', 'readLevelOptions', array());
            break;
        case 'write':
            $levels = Q_Config::get('Streams', 'writeLevelOptions', array());
            break;
        case 'admin':
            $levels = Q_Config::get('Streams', 'adminLevelOptions', array());
            break;
    }
    if (isset($ranges[$tab])) {
        $range_min = reset($ranges[$tab]);
        $range_max = end($ranges[$tab]);
        foreach ($levels as $k => $v) {
            if ($k < $range_min) {
                unset($levels[$k]);
            }
            if ($k > $range_max) {
                unset($levels[$k]);
            }
        }
    }
    $accessActionUrl = Q_Uri::url("Streams/access?publisherId={$publisherId}&streamName={$streamName}");
    $dir = Q_Config::get('Users', 'paths', 'icons', 'files/Users/icons');
    $accessArray = Db::exportArray($access_array);
    $avatarArray = Db::exportArray($avatar_array);
    if (empty($controls)) {
        Q_Response::addScript("plugins/Streams/js/Streams.js");
        Q_Response::addScript("plugins/Streams/js/tools/access.js");
        Q_Response::setToolOptions(compact('accessArray', 'avatarArray', 'labels', 'icons', 'tab', 'publisherId', 'streamName'));
    } else {
        Q_Response::setSlot('extra', array('stream' => $stream->exportArray(), 'accessArray' => $accessArray, 'avatarArray' => $avatarArray, 'labels' => $labels, 'icons' => $icons));
    }
    return Q::view('Streams/tool/access.php', compact('stream', 'tabs', 'tab', 'labels', 'icons', 'levels', 'dir', 'publisherId', 'streamName', 'accessActionUrl', 'controls'));
}