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']; } // Define a constant if (!defined('PIE_CONTROLLER')) { define('PIE_CONTROLLER', 'Pie_ActionController'); } try { $parts = explode('/', Pie_Request::tail()); $parts_len = count($parts); if ($parts_len >= 1) { $module = $parts[0]; } if ($parts_len >= 2) { $action = $parts[1]; } // Make sure the 'pie'/'web' config fields are set, // otherwise URLs will be formed pointing to the wrong // controller script. $ar = Pie_Config::get('pie', 'web', 'appRootUrl', null); if (!isset($ar)) { throw new Pie_Exception_MissingConfig(array('fieldpath' => 'pie/web/appRootUrl')); } $cs = Pie_Config::get('pie', 'web', 'controllerSuffix', null); if (!isset($cs)) { throw new Pie_Exception_MissingConfig(array('fieldpath' => 'pie/web/controllerSuffix')); } // Dispatch the request $uri = Pie_Uri::from(compact('module', 'action')); Pie_Dispatcher::dispatch($uri); $dispatch_result = Pie_Dispatcher::result(); if (!isset($dispatch_result)) { $dispatch_result = 'Ran dispatcher'; } $uri = Pie_Dispatcher::uri(); $module = $uri->module; $action = $uri->action; if ($module and $action) { $slot_names = Pie_Request::slotNames(); $requested_slots = empty($slot_names) ? '' : implode(',', array_keys($slot_names)); Pie::log("~" . ceil(Pie::microtime()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " {$dispatch_result} for {$module}/{$action}" . " ({$requested_slots})"); } else { Pie::log("~" . ceil(Pie::microtime()) . 'ms+' . ceil(memory_get_peak_usage() / 1000) . 'kb.' . " No route for " . $_SERVER['REQUEST_URI']); } } catch (Exception $exception) { Pie::event('pie/exception', compact('exception')); } }
/** * The default implementation. */ function pie_errors($params) { extract($params); /** * @var Exception $exception */ if (!empty($exception)) { Pie_Response::addError($exception); $errors = Pie_Response::getErrors(); } $errors_array = Pie_Exception::toArray($errors); $exception_array = Pie_Exception::toArray($exception); // Simply return the errors, if this was an AJAX request if ($is_ajax = Pie_Request::isAjax()) { switch (strtolower($is_ajax)) { case 'json': default: $json = json_encode(array('errors' => $errors_array, 'exception' => $exception_array)); $callback = Pie_Request::callback(); echo $callback ? "{$callback}({$json})" : $json; } return; } // Forward internally, if it was requested if (isset($_REQUEST['_pie']['onErrors'])) { $uri = Pie_Dispatcher::uri(); $uri2 = Pie_Uri::from($_REQUEST['_pie']['onErrors']); if ($uri !== $uri2) { Pie_Dispatcher::forward($uri2); return; // we don't really need this, but it's here anyway } } if (Pie::eventStack('pie/response')) { // Errors happened while rendering response. Just render errors view. return Pie::view('pie/errors.php', $params); } try { // Try rendering the response, expecting it to // display the errors along with the rest. $ob = new Pie_OutputBuffer(); Pie::event('pie/response', compact('errors', 'exception', 'errors_array', 'exception_array')); $ob->endFlush(); } catch (Exception $exception) { $output = $ob->getClean(); return Pie::event('pie/exception', compact('exception')); } }
static function uri() { if (!isset(self::$uri)) { self::$uri = Pie_Uri::from(self::url()); } return self::$uri; }
/** * Dispatches a URI for internal processing. * Usually called by a front controller. * @param mixed $uri * Optional. You can pass a custom URI to dispatch. Otherwise, PIE will attempt * to route the requested URL, if any. * @param array $check * Optional. Pass array() to skip checking whether the URI can be obtained * as a result of routing some URL. * @return boolean */ static function dispatch($uri = null, $check = array('accessible')) { if (!is_array($check)) { $check = array('accessible'); } if (isset($uri)) { if (in_array('accessible', $check)) { if (!Pie_Uri::url($uri)) { // We shouldn't dispatch to this URI $uri = Pie_Uri::from(array()); } } self::$uri = Pie_Uri::from($uri); } else { self::$uri = Pie_Request::uri(); } // if file or dir is requested, try to serve it $served = false; $skip = Pie_Config::get('pie', 'dispatcherSkipFilename', false); $filename = $skip ? false : Pie_Request::filename(); if ($filename) { if (is_dir($filename)) { $served = Pie::event("pie/dir", compact('filename', 'routed_uri')); $dir_was_served = true; } else { $served = Pie::event("pie/file", compact('filename', 'routed_uri')); $dir_was_served = false; } } // if response was served, then return if ($served) { self::result($dir_was_served ? "Dir served" : "File served"); return true; } // This loop is for forwarding $max_forwards = Pie_Config::get('pie', 'maxForwards', 10); for ($try = 0; $try < $max_forwards; ++$try) { // Make an array from the routed URI $routed_uri_array = array(); if (self::$uri instanceof Pie_Uri) { $routed_uri_array = self::$uri->toArray(); } // If no module was found, then respond with noModule and return if (!isset(self::$uri->module)) { Pie::event("pie/noModule", $routed_uri_array); // should echo things self::result("No module"); return false; } $module = self::$uri->module; // Implement restricting of modules we are allowed to access $routed_modules = Pie_Config::get('pie', 'routedModules', null); if (isset($routed_modules)) { if (!in_array($module, $routed_modules)) { Pie::event('pie/notFound', $routed_uri_array); // should echo things self::result("Unknown module"); return false; } } else { if (!Pie::realPath("handlers/{$module}")) { Pie::event('pie/notFound', $routed_uri_array); // should echo things self::result("Unknown module"); return false; } } try { // Fire a pure event, for aggregation etc if (!in_array('pie/prepare', self::$skip)) { Pie::event('pie/prepare', $routed_uri_array, true); } // Perform validation if (!in_array('pie/validate', self::$skip)) { Pie::event('pie/validate', $routed_uri_array); // Check if any errors accumulated if (Pie_Response::getErrors()) { // There were validation errors -- render a response self::errors(null, $module, null); self::result('Validation errors'); return false; } } // Time to instantiate some app objects from the request if (!in_array('pie/objects', self::$skip)) { Pie::event('pie/objects', $routed_uri_array, true); } // We might want to reroute the request if (!in_array('pie/reroute', self::$skip)) { $stop_dispatch = Pie::event('pie/reroute', $routed_uri_array, true); if ($stop_dispatch) { self::result("Stopped dispatch"); return false; } } if (Pie_Request::isPost()) { if (!in_array('pie/post', self::$skip)) { // Make some changes to server state, possibly Pie::event('pie/post', $routed_uri_array); } } // Time to instantiate some app objects from the request if (!in_array('pie/analytics', self::$skip)) { Pie::event('pie/analytics', $routed_uri_array, true); } // Start buffering the response, unless otherwise requested if ($handler = Pie_Response::isBuffered()) { $ob = new Pie_OutputBuffer($handler); } // Generate and render a response Pie::event("pie/response", $routed_uri_array); if (!empty($ob)) { $ob->endFlush(); } self::result("Served response"); return true; } catch (Pie_Exception_DispatcherForward $e) { // Go again, this time with a different URI. self::$uri = Pie_Uri::from($e->uri); if (is_array($e->skip)) { self::$skip = $e->skip; } else { // Don't process the POST fields this time around self::$skip = array('pie/post'); } // We'll be handling errors anew self::$handling_errors = false; } catch (Pie_Exception_DispatcherErrors $e) { if (!empty($ob)) { $partial_response = $ob->getClean(); } else { $partial_response = null; } self::errors(null, $module, $partial_response); self::result("Rendered errors"); return true; } catch (Exception $exception) { if (!empty($ob)) { $partial_response = $ob->getClean(); } else { $partial_response = null; } self::errors($exception, $module, $partial_response); self::result("Exception occurred"); return false; } } // If we are here, we have done forwarding too much throw new Pie_Exception_Recursion(array('function_name' => 'Dispatcher::forward()')); }