Esempio n. 1
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>" : '';
}
Esempio n. 2
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;
}
Esempio n. 3
0
function Q_response_errors()
{
    $errors = Q_Response::getErrors();
    if (empty($errors)) {
        return '';
    }
    $result = "<ul class='Q_errors'>";
    foreach ($errors as $e) {
        $result .= "<li>" . $e->getMessage() . "</li>";
    }
    $result .= "</ul>";
    return $result;
}
Esempio n. 4
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;
}
Esempio n. 5
0
function Streams_basic_validate()
{
    Q_Valid::nonce(true);
    if (Q_Request::method() !== 'POST') {
        return;
    }
    $fields = array('firstName' => 'First name', 'lastName' => 'Last name', 'gender' => 'Gender', 'birthday_month' => 'Month', 'birthday_day' => 'Day', 'birthday_year' => 'Year');
    if (isset($_REQUEST['fullName'])) {
        $length_min = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMin', 5);
        $length_max = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMax', 30);
        if (strlen($_REQUEST['fullName']) < $length_min) {
            Q_Response::addError(new Q_Exception("Your full name can't be that short.", 'fullName'));
        }
        if (strlen($_REQUEST['fullName']) > $length_max) {
            Q_Response::addError(new Q_Exception("Your full name can't be that long.", 'fullName'));
        }
    }
    if (Q_Response::getErrors()) {
        return;
    }
    if (!empty($_REQUEST['birthday_month']) or !empty($_REQUEST['birthday_day']) or !empty($_REQUEST['birthday_year'])) {
        foreach (array('birthday_month', 'birthday_day', 'birthday_year') as $field) {
            if (empty($_REQUEST[$field]) or !trim($_REQUEST[$field])) {
                throw new Q_Exception_RequiredField(compact('field'), $field);
            }
        }
        if (!checkdate($_REQUEST['birthday_month'], $_REQUEST['birthday_day'], $_REQUEST['birthday_year'])) {
            Q_Response::addError(new Q_Exception("Not a valid date", "birthday_day"));
        }
        if ($_REQUEST['birthday_year'] > date('Y') - 13) {
            // compliance with COPPA
            Q_Response::addError(new Q_Exception("You're still a kid.", "birthday_year"));
        }
        if ($_REQUEST['birthday_year'] < date('Y') - 100) {
            Q_Response::addError(new Q_Exception("A world record? Really?", "birthday_year"));
        }
    }
    if (!empty($_REQUEST['gender'])) {
        if (!in_array($_REQUEST['gender'], array('male', 'female'))) {
            Q_Response::addError(new Q_Exception("Please enter male or female", "gender"));
        }
    }
}
Esempio n. 6
0
 /**
  * @method errors
  * @static
  * @protected
  * @param {Exception} $exception
  * @param {string} $module
  * @param {string} [$partial_response=null]
  */
 protected static function errors($exception, $module, $partial_response = null)
 {
     self::$errors_occurred = true;
     $response_started = self::$response_started;
     $errors = Q_Response::getErrors();
     Q::$toolWasRendered = array();
     try {
         if (self::$handling_errors) {
             // We need to handle errors, but we
             // have already tried to do it.
             // Just show the errors view.
             Q::event('Q/errors/native', compact('errors', 'exception', 'partial_response', 'response_started'));
             return;
         }
         self::$handling_errors = true;
         if (Q::canHandle("{$module}/errors")) {
             /**
              * @event $module/errors
              * @param {Exception} exception
              * @param {string} module
              * @param {string} partial_response
              */
             Q::event("{$module}/errors", compact('errors', 'exception', 'partial_response', 'response_started'));
         } else {
             /**
              * @event Q/errors
              * @param {Exception} exception
              * @param {string} module
              * @param {string} partial_response
              */
             Q::event("Q/errors", compact('errors', 'exception', 'partial_response', 'response_started'));
         }
     } catch (Exception $e) {
         Q_Exception::rethrow($e, '');
         // may be for forwarding
         /**
          * @event Q/exception
          * @param {Exception} exception
          */
         Q::event('Q/exception', compact('exception'));
         // the original exception
     }
 }
Esempio n. 7
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));
    }
}
Esempio n. 8
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);
}