Пример #1
0
function Q_errors_native($params)
{
    echo Q::view('Q/errors.php', $params);
    $app = Q_Config::expect('Q', 'app');
    Q::log("{$app}: Errors in " . ceil(Q::milliseconds()) . "ms\n");
    Q::log($params);
}
Пример #2
0
 /**
  * Excecute web request
  * @method execute
  * @static
  */
 static function execute()
 {
     // Fixes for different platforms:
     if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
         // ISAPI 3.0
         $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL'];
     }
     // Get the base URL
     $base_url = Q_Request::baseUrl();
     if (Q::$controller === 'Q_ActionController') {
         // we detected action.php in the URL, but
         // a misconfigured web server executed index.php instead
         return Q_ActionController::execute();
     }
     // Set the controller that is being used
     if (!isset(Q::$controller)) {
         Q::$controller = 'Q_WebController';
     }
     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), null, null, array('maxLength' => 10000));
         Q_Dispatcher::dispatch();
         $dispatchResult = Q_Dispatcher::result();
         if (!isset($dispatchResult)) {
             $dispatchResult = 'Ran dispatcher';
         }
         $uri = Q_Request::uri();
         $module = $uri->module;
         $action = $uri->action;
         if ($module and $action) {
             $slotNames = Q_Request::slotNames();
             $returned_slots = empty($slotNames) ? '' : implode(',', $slotNames);
             Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " {$dispatchResult} for {$module}/{$action}" . " ({$returned_slots})", null, null, array('maxLength' => 10000));
         } else {
             Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " {$dispatchResult} No route for " . $_SERVER['REQUEST_URI'], null, null, array('maxLength' => 10000));
         }
     } catch (Exception $exception) {
         /**
          * @event Q/exception
          * @param {Exception} exception
          */
         Q::event('Q/exception', compact('exception'));
     }
 }
Пример #3
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'));
     }
 }
Пример #4
0
<div id='content'>
	<h1>Welcome!</h1>
	To start a new app, you should follow the instructions <a href="https://qbix.com/platform">here</a>.<br>
	Oh, and by the way, this rendered in <?php 
echo ceil(Q::milliseconds());
?>
 ms.
	Refresh the page a few times and see how efficient the Qbix Platform can be.
	In fact, it can execute <a href="fast.php">even faster</a>.
</div>
Пример #5
0
<?php

include "Q.inc.php";
$ms = ceil(Q::milliseconds());
echo <<<EOT


\t<!DOCTYPE html>
\t<html lang="en" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml" class='Q_notTouchscreen Q_notMobile Q_notIE Q_notIE8OrBelow'>
\t<head>
\t\t<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
\t\t<title>Fast loading page</title>
\t\t<link rel="shortcut icon" href="http://gmba.local/First/favicon.ico" type="image/x-icon">
\t</head>
\t<body>

\t\t<h1>Even Faster Loading Page</h1>
\t\t<p>
\t\t\tThis is a naked PHP script that includes the Qbix Platform as a library, like this:
\t\t</p>
\t\t<pre>
\t\t\t&lt;?php include ("Q.inc.php") ?&gt;
\t\t</pre>
\t\t<p>
\t\t\tIn this scenario, the entire Qbix environment is ready to go in <strong>{$ms} milliseconds</strong>!
\t\t</p>
\t\t<p>
\t\t\tTry refreshing this page, and it will probably load even faster.
\t\t</p>
 
\t</body>
Пример #6
0
function Q_exception_native($params)
{
    extract($params);
    /**
     * @var Exception $exception 
     */
    if ($is_ajax = Q_Request::isAjax()) {
        $json = @Q::json_encode(array('errors' => Q_Exception::toArray(array($exception))));
        $callback = Q_Request::callback();
        switch (strtolower($is_ajax)) {
            case 'iframe':
                // Render an HTML layout for ajax
                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':
                // Render a JSON layout for ajax
            // Render a JSON layout for ajax
            default:
                header("Content-type: " . ($callback ? "application/javascript" : "application/json"));
                echo $callback ? "{$callback}({$json})" : $json;
        }
    } else {
        if (Q::textMode()) {
            echo Q_Exception::coloredString($exception);
            exit;
        }
        $message = $exception->getMessage();
        $file = $exception->getFile();
        $line = $exception->getLine();
        if (is_callable(array($exception, 'getTraceAsStringEx'))) {
            $trace_string = $exception->getTraceAsStringEx();
        } else {
            $trace_string = $exception->getTraceAsString();
        }
        if ($exception instanceof Q_Exception_PhpError or !empty($exception->messageIsHtml)) {
            // do not sanitize $message
        } else {
            $message = Q_Html::text($message);
        }
        $content = "<h1 class='exception_message'>{$message}</h1>";
        if (Q_Config::get('Q', 'exception', 'showFileAndLine', true)) {
            $content .= "<h3 class='exception_fileAndLine'>in {$file} ({$line})</h3>";
        }
        if (Q_Config::get('Q', 'exception', 'showTrace', true)) {
            $content .= "<pre class='exception_trace'>{$trace_string}</pre>";
        }
        $content .= str_repeat(' ', 512);
        // because of chrome
        $title = "Exception occurred";
        $dashboard = "";
        echo Q::view('Q/layout/html.php', compact('content', 'dashboard', 'title'));
    }
    $app = Q_Config::get('Q', 'app', null);
    $colored = Q_Exception::coloredString($exception);
    Q::log("{$app}: Exception in " . ceil(Q::milliseconds()) . "ms:\n\n{$colored}\n", null, true, array('maxLength' => 10000));
}
Пример #7
0
 /**
  * Executes a query against the database and returns the result set.
  * @method excecute
  * @param {boolean} [$prepareStatement=false] If true, a PDO statement will be prepared
  * from the query before it is executed. It is also saved for future invocations to use.
  * Do this only if the statement will be executed many times with
  * different parameters. Basically you would use ->bind(...) between
  * invocations of ->execute().
  * @return {Db_Result} The Db_Result object containing the PDO statement that resulted from the query.
  */
 function execute($prepareStatement = false)
 {
     if (class_exists('Q')) {
         /**
          * @event Db/query/execute {before}
          * @param {Db_Query_Mysql} query
          * @return {Db_Result}
          */
         $result = Q::event('Db/query/execute', array('query' => $this), 'before');
     }
     if (isset($result)) {
         return $result;
     }
     $stmts = array();
     // make sure SQL template will be ready for sharding. reallyConnect will add new values
     unset($this->replacements['{$dbname}']);
     unset($this->replacements['{$prefix}']);
     $this->startedTime = Q::milliseconds(true);
     if ($prepareStatement) {
         // Prepare the query into a SQL statement
         // this takes two round-trips to the database
         // Preparing the statement if it wasn't yet set
         if (!isset($this->statement)) {
             if ($q = $this->build()) {
                 $pdo = $this->reallyConnect();
                 $this->statement = $pdo->prepare($q);
                 if ($this->statement === false) {
                     if (!isset($sql)) {
                         $sql = $this->getSQL();
                     }
                     if (class_exists('Q_Exception_DbQuery')) {
                         throw new Exception("query could not be prepared");
                     }
                     throw new Exception("query could not be prepared [query was: {$sql} ]", -1);
                 }
             }
         }
         // Bind the parameters
         foreach ($this->parameters as $key => $value) {
             $this->statement->bindValue($key, $value);
         }
     }
     $sql_template = $this->getSQL(null, true);
     $queries = $this->shard();
     $connection = $this->db->connectionName();
     if (!empty($queries["*"])) {
         $shard_names = Q_Config::get('Db', 'connections', $connection, 'shards', array('' => ''));
         $q = $queries["*"];
         foreach ($shard_names as $k => $v) {
             $queries[$k] = $q;
         }
         unset($queries['*']);
     }
     foreach ($queries as $shard_name => $query) {
         $upcoming = Q_Config::get('Db', 'upcoming', $connection, false);
         if ($query->type !== Db_Query::TYPE_SELECT && $query->type !== Db_Query::TYPE_RAW) {
             if (!empty($upcoming['block']) && $shard_name === $upcoming['shard']) {
                 throw new Db_Exception_Blocked(compact('shard_name', 'connection'));
             }
         }
         $query->startedTime = Q::milliseconds(true);
         $pdo = $query->reallyConnect($shard_name);
         $connInfo = Db::getConnection($connection);
         $dsn = $connInfo['dsn'];
         $nt =& self::$nestedTransactions[$dsn];
         if (!isset($nt)) {
             self::$nestedTransactions[$dsn] = 0;
             $nt =& self::$nestedTransactions[$dsn];
         }
         $sql = $query->getSQL();
         try {
             if (!empty($query->clauses["BEGIN"])) {
                 if (++$nt == 1) {
                     $pdo->beginTransaction();
                 }
             } else {
                 if (!empty($query->clauses["ROLLBACK"])) {
                     $pdo->rollBack();
                     $nt = 0;
                 }
             }
             if ($query->type !== Db_Query::TYPE_ROLLBACK) {
                 if ($prepareStatement) {
                     // Execute the statement
                     try {
                         $query->statement->execute();
                         $stmt = $query->statement;
                     } catch (Exception $e) {
                         if (class_exists('Q_Exception_DbQuery')) {
                             throw $e;
                         }
                         throw new Exception($e->getMessage() . "\n... Query was: {$sql}", -1);
                     }
                 } else {
                     // Obtain the full SQL code ourselves
                     // and send to the database, without preparing it there.
                     if ($sql) {
                         $stmt = $pdo->query($sql);
                     } else {
                         $stmt = true;
                     }
                 }
                 $stmts[] = $stmt;
                 if (!empty($query->clauses["COMMIT"]) && $nt) {
                     // we commit only if no error occurred - warnings are permitted
                     if (!$stmt or $stmt !== true and !in_array(substr($stmt->errorCode(), 0, 2), array('00', '01'))) {
                         $err = $pdo->errorInfo();
                         throw new Exception($err[0], $err[1]);
                     }
                     if (--$nt == 0) {
                         $pdo->commit();
                     }
                 }
             }
         } catch (Exception $exception) {
             if ($nt) {
                 $pdo->rollBack();
                 $nt = 0;
             }
             break;
         }
         $this->nestedTransactionCount = $nt;
         if (class_exists('Q') && isset($sql)) {
             // log query if shard split process is active
             // all activities will be done by node.js
             switch ($this->type) {
                 case Db_Query::TYPE_SELECT:
                     // SELECT queries don't need to be logged
                 // SELECT queries don't need to be logged
                 case Db_Query::TYPE_RAW:
                     // Raw queries are run on shard '' - i.e. main db only
                     // actually, raw query may get here only on initial sharding
                     // when sharding has started raw queries are never run on shard
                     break;
                 default:
                     if (!$upcoming or $shard_name !== $upcoming['shard']) {
                         break;
                     }
                     $table = $this->table;
                     foreach ($this->replacements as $k => $v) {
                         $table = str_replace($k, $v, $table);
                     }
                     if ($table !== $upcoming['dbTable']) {
                         break;
                     }
                     // node will determine new shard(s) names using
                     // new sharding config which is available within split process
                     $timestamp = $pdo->query("SELECT CURRENT_TIMESTAMP")->fetchAll(PDO::FETCH_COLUMN, 0);
                     if ($timestamp === false || !isset($timestamp[0])) {
                         $timestamp = date("Y-m-d H:i:s");
                         // backup solution
                     } else {
                         $timestamp = $timestamp[0];
                     }
                     $sql_template = str_replace('CURRENT_TIMESTAMP', "'{$timestamp}'", $sql_template);
                     $transaction = !empty($this->clauses['COMMIT']) ? 'COMMIT' : (!empty($this->clauses['BEGIN']) ? 'START TRANSACTION' : (!empty($this->clauses['ROLLBACK']) ? 'ROLLBACK' : ''));
                     $upcoming_shards = array_keys($query->shard($upcoming['indexes'][$upcoming['table']]));
                     $logServer = Q_Config::get('Db', 'internal', 'sharding', 'logServer', null);
                     if (!empty($transaction) && $transaction !== 'COMMIT') {
                         Q_Utils::sendToNode(array('Q/method' => 'Db/Shards/log', 'shards' => $upcoming_shards, 'sql' => "{$transaction};"), Q_Config::get('Db', 'internal', 'sharding', 'logServer', null));
                     }
                     Q_Utils::sendToNode(array('Q/method' => 'Db/Shards/log', 'shards' => $upcoming_shards, 'sql' => trim(str_replace("\n", ' ', $sql_template))), Q_Config::get('Db', 'internal', 'sharding', 'logServer', null));
                     if (!empty($transaction) && $transaction === 'COMMIT') {
                         Q_Utils::sendToNode(array('Q/method' => 'Db/Shards/log', 'shards' => $upcoming_shards, 'sql' => "{$transaction};"), $logServer, true);
                     }
             }
             $query->endedTime = Q::milliseconds(true);
         }
     }
     $this->endedTime = Q::milliseconds(true);
     if (!empty($exception)) {
         /**
          * @event Db/query/exception {after}
          * @param {Db_Query_Mysql} query
          * @param {array} queries
          * @param {string} sql
          * @param {Exception} exception
          */
         Q::event('Db/query/exception', compact('query', 'queries', 'sql', 'exception'), 'after');
         if (!class_exists('Q_Exception_DbQuery')) {
             throw $exception;
         }
         throw new Q_Exception_DbQuery(array('sql' => $sql, 'message' => $exception->getMessage() . "[query was: {$sql}]"));
     }
     /**
      * @event Db/query/execute {after}
      * @param {Db_Query_Mysql} query
      * @param {array} queries
      * @param {string} sql
      */
     Q::event('Db/query/execute', compact('query', 'queries', 'sql'), 'after');
     return new Db_Result($stmts, $this);
 }
Пример #8
0
// Include core classes
//
require Q_CLASSES_DIR . DS . 'Q.php';
require Q_CLASSES_DIR . DS . 'Q' . DS . 'Cache.php';
require Q_CLASSES_DIR . DS . 'Q' . DS . 'Bootstrap.php';
require Q_CLASSES_DIR . DS . 'Q' . DS . 'Tree.php';
require Q_CLASSES_DIR . DS . 'Q' . DS . 'Config.php';
require Q_CLASSES_DIR . DS . 'Q' . DS . 'Exception.php';
require Q_CLASSES_DIR . DS . 'Q' . DS . 'Exception' . DS . 'PhpError.php';
require Q_CLASSES_DIR . DS . 'Db.php';
require Q_CLASSES_DIR . DS . 'Db' . DS . 'Expression.php';
require Q_CLASSES_DIR . DS . 'Db' . DS . 'Query.php';
//
// Set things up
//
Q::milliseconds();
Q_Bootstrap::registerShutdownFunction();
Q_Bootstrap::setDefaultTimezone();
Q_Bootstrap::setIncludePath();
Q_Bootstrap::registerAutoload();
Q_Bootstrap::defineFunctions();
Q_Bootstrap::registerExceptionHandler();
Q_Bootstrap::registerErrorHandler();
Q_Bootstrap::revertSlashes();
Q_Bootstrap::configure();
Q_Bootstrap::alertAboutLocalConfiguration();
Q_Bootstrap::setDefaultTimezone();
Q_Bootstrap::setResponseBuffered();
Q_Bootstrap::setUrls();
Q_Response::setIgnoreUserAbort();
if (defined('APP_WEB_DIR')) {
Пример #9
0
/**
 * Front controller for Q
 */
include dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Q.inc.php';
//
// Handle batch request
//
$urls = Q::ifset($_REQUEST['urls'], array());
Q::log("Batch request for " . count($urls) . " urls");
header("Content-type: application/json");
Q_Response::$batch = true;
echo "[";
$original_request = $_REQUEST;
foreach ($urls as $i => $url) {
    $request = parse_url($url);
    parse_str($request['query'], $_REQUEST);
    $request = explode('?', $url);
    echo "[";
    if (!empty($request[0])) {
        Q_ActionController::execute($request[0]);
    }
    echo "]";
    if (isset($urls[$i + 1])) {
        echo ',';
    }
}
$_REQUEST = $original_request;
echo "]";
Q::log("~" . ceil(Q::milliseconds()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " batch complete.");