function Streams_batch_response_batch() { if (empty($_REQUEST['batch'])) { throw new Q_Exception_RequiredField(array('field' => 'batch')); } try { $batch = json_decode($_REQUEST['batch'], true); } catch (Exception $e) { } if (empty($batch)) { throw new Q_Exception_WrongValue(array('field' => 'batch', 'range' => 'valid JSON')); } if (empty($batch['args'])) { throw new Q_Exception_RequiredField(array('field' => 'args')); } // Gather the publisher ids and stream names to fetch $to_fetch = array(); foreach ($batch['args'] as $args) { if (count($args) < 4) { continue; } list($action, $slots, $publisherId, $name) = $args; if (empty($to_fetch[$publisherId])) { $to_fetch[$publisherId] = array(); } $to_fetch[$publisherId][] = $name; } $user = Users::loggedInUser(); $userId = $user ? $user->id : ""; // Fetch the actual streams $streams = array(); foreach ($to_fetch as $publisherId => $names) { if (empty($streams[$publisherId])) { $streams[$publisherId] = array(); } $streams[$publisherId] = array_merge($streams[$publisherId], Streams::fetch($userId, $publisherId, $names, '*')); } // Now, build the result $result = array(); foreach ($batch['args'] as $args) { try { $action = $args[0]; $prev_request = $_REQUEST; $extra = !empty($args[4]) ? $args[4] : null; if (is_array($extra)) { foreach ($extra as $k => $v) { $_REQUEST[$k] = $v; } } switch ($action) { case 'stream': break; case 'message': if (!is_array($extra)) { $_REQUEST['ordinal'] = $extra; } break; case 'participant': if (!is_array($extra)) { $_REQUEST['userId'] = $extra; } break; default: throw new Q_Exception_WrongValue(array('field' => 'action', 'range' => "'stream', 'message' or 'participant'")); } Q_Request::$slotNames_override = is_array($args[1]) ? $args[1] : explode(',', $args[1]); Q_Request::$method_override = 'GET'; if (count($args) >= 4) { Streams::$requestedPublisherId_override = $publisherId = $args[2]; Streams::$requestedName_override = $name = $args[3]; if (empty($streams[$publisherId][$name])) { throw new Q_Exception_MissingRow(array('table' => 'Stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$name}'}")); } Streams::$cache['stream'] = $streams[$publisherId][$name]; } Q::event("Streams/{$action}/response", compact('streams', 'publisherId', 'name', 'extra', 'user', 'userId')); $slots = Q_Response::slots(true); unset($slots['batch']); $result[] = compact('slots'); } catch (Exception $e) { $result[] = array('errors' => Q_Exception::toArray(array($e))); } $prev_request = $_REQUEST; Q_Request::$slotNames_override = null; Q_Request::$method_override = null; Streams::$requestedPublisherId_override = null; Streams::$requestedName_override = null; } return $result; }
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)); }
/** * 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)); } }