/**
  * Render a developer facing error page, showing the stack trace and details
  * of the code where the error occured.
  *
  * @param int $errno
  * @param string $errstr
  * @param string $errfile
  * @param int $errline
  * @param array $errcontext
  * @return string
  */
 protected function output($errno, $errstr, $errfile, $errline, $errcontext)
 {
     $reporter = Debug::create_debug_view();
     // Coupling alert: This relies on knowledge of how the director gets its URL, it could be improved.
     $httpRequest = null;
     if (isset($_SERVER['REQUEST_URI'])) {
         $httpRequest = $_SERVER['REQUEST_URI'];
     } elseif (isset($_REQUEST['url'])) {
         $httpRequest = $_REQUEST['url'];
     }
     if (isset($_SERVER['REQUEST_METHOD'])) {
         $httpRequest = $_SERVER['REQUEST_METHOD'] . ' ' . $httpRequest;
     }
     $output = $reporter->renderHeader();
     $output .= $reporter->renderError($httpRequest, $errno, $errstr, $errfile, $errline);
     if (file_exists($errfile)) {
         $lines = file($errfile);
         // Make the array 1-based
         array_unshift($lines, "");
         unset($lines[0]);
         $offset = $errline - 10;
         $lines = array_slice($lines, $offset, 16, true);
         $output .= $reporter->renderSourceFragment($lines, $errline);
     }
     $output .= $reporter->renderTrace($errcontext);
     $output .= $reporter->renderFooter();
     return $output;
 }
 /**
  * This is the main method to build the master string tables with the original strings.
  * It will search for existent modules that use the i18n feature, parse the _t() calls
  * and write the resultant files in the lang folder of each module.
  *
  * @uses DataObject->collectI18nStatics()
  *
  * @param HTTPRequest $request
  */
 public function run($request)
 {
     increase_time_limit_to();
     $collector = i18nTextCollector::create($request->getVar('locale'));
     $merge = $this->getIsMerge($request);
     // Custom writer
     $writerName = $request->getVar('writer');
     if ($writerName) {
         $writer = Injector::inst()->get($writerName);
         $collector->setWriter($writer);
     }
     // Get restrictions
     $restrictModules = $request->getVar('module') ? explode(',', $request->getVar('module')) : null;
     $collector->run($restrictModules, $merge);
     Debug::message(__CLASS__ . " completed!", false);
 }
 /**
  * Debugging used by Debug::show()
  *
  * @return string HTML data representing this object
  */
 public function debug()
 {
     $val = "<h3>Database record: {$this->class}</h3>\n<ul>\n";
     if ($this->record) {
         foreach ($this->record as $fieldName => $fieldVal) {
             $val .= "\t<li>{$fieldName}: " . Debug::text($fieldVal) . "</li>\n";
         }
     }
     $val .= "</ul>\n";
     return $val;
 }
 /**
  * Allows the display and benchmarking of queries as they are being run
  *
  * @param string $sql Query to run, and single parameter to callback
  * @param callable $callback Callback to execute code
  * @param array $parameters Parameters for any parameterised query
  * @return mixed Result of query
  */
 protected function benchmarkQuery($sql, $callback, $parameters = array())
 {
     if (isset($_REQUEST['showqueries']) && Director::isDev()) {
         $this->queryCount++;
         $starttime = microtime(true);
         $result = $callback($sql);
         $endtime = round(microtime(true) - $starttime, 4);
         // replace parameters as closely as possible to what we'd expect the DB to put in
         if (strtolower($_REQUEST['showqueries']) == 'inline') {
             $sql = DB::inline_parameters($sql, $parameters);
         }
         Debug::message("\n{$sql}\n{$endtime}s\n", false);
         return $result;
     } else {
         return $callback($sql);
     }
 }
 /**
  * Add methods from the {@link ViewableData::$failover} object, as well as wrapping any methods prefixed with an
  * underscore into a {@link ViewableData::cachedCall()}.
  *
  * @throws LogicException
  */
 public function defineMethods()
 {
     if ($this->failover && !is_object($this->failover)) {
         throw new LogicException("ViewableData::\$failover set to a non-object");
     }
     if ($this->failover) {
         $this->addMethodsFrom('failover');
         if (isset($_REQUEST['debugfailover'])) {
             Debug::message("{$this->class} created with a failover class of {$this->failover->class}");
         }
     }
     parent::defineMethods();
 }
 /**
  * Prepare the response (we can receive an assortment of response types (strings/objects/HTTPResponses) and
  * changes the controller response object appropriately
  *
  * @param HTTPResponse|Object $response
  */
 protected function prepareResponse($response)
 {
     if ($response instanceof HTTPResponse) {
         if (isset($_REQUEST['debug_request'])) {
             Debug::message("Request handler returned HTTPResponse object to {$this->class} controller;" . "returning it without modification.");
         }
         $this->setResponse($response);
     } else {
         if ($response instanceof Object && $response->hasMethod('getViewer')) {
             if (isset($_REQUEST['debug_request'])) {
                 Debug::message("Request handler {$response->class} object to {$this->class} controller;" . "rendering with template returned by {$response->class}::getViewer()");
             }
             $response = $response->getViewer($this->getAction())->process($response);
         }
         $this->getResponse()->setBody($response);
     }
     //deal with content if appropriate
     ContentNegotiator::process($this->getResponse());
     //add cache headers
     HTTP::add_cache_headers($this->getResponse());
 }
 /**
  * Show a debugging message
  *
  * @param string $message
  * @param bool $showHeader
  */
 public static function message($message, $showHeader = true)
 {
     if (!Director::isLive()) {
         $caller = Debug::caller();
         $file = basename($caller['file']);
         if (Director::is_cli()) {
             if ($showHeader) {
                 echo "Debug (line {$caller['line']} of {$file}):\n ";
             }
             echo $message . "\n";
         } else {
             echo "<p class=\"message warning\">\n";
             if ($showHeader) {
                 echo "<b>Debug (line {$caller['line']} of {$file}):</b>\n ";
             }
             echo Convert::raw2xml($message) . "</p>\n";
         }
     }
 }
 public function debug()
 {
     $result = "{$this->class} ({$this->name}) <ul>";
     foreach ($this->children as $child) {
         $result .= "<li>" . Debug::text($child) . "&nbsp;</li>";
     }
     $result .= "</ul>";
     return $result;
 }
 /**
  * Handle an HTTP request, defined with a HTTPRequest object.
  *
  * @skipUpgrade
  * @param HTTPRequest $request
  * @param Session $session
  * @param DataModel $model
  * @return HTTPResponse|string
  */
 protected static function handleRequest(HTTPRequest $request, Session $session, DataModel $model)
 {
     $rules = Director::config()->get('rules');
     if (isset($_REQUEST['debug'])) {
         Debug::show($rules);
     }
     foreach ($rules as $pattern => $controllerOptions) {
         if (is_string($controllerOptions)) {
             if (substr($controllerOptions, 0, 2) == '->') {
                 $controllerOptions = array('Redirect' => substr($controllerOptions, 2));
             } else {
                 $controllerOptions = array('Controller' => $controllerOptions);
             }
         }
         if (($arguments = $request->match($pattern, true)) !== false) {
             $request->setRouteParams($controllerOptions);
             // controllerOptions provide some default arguments
             $arguments = array_merge($controllerOptions, $arguments);
             // Pop additional tokens from the tokenizer if necessary
             if (isset($controllerOptions['_PopTokeniser'])) {
                 $request->shift($controllerOptions['_PopTokeniser']);
             }
             // Handle redirection
             if (isset($arguments['Redirect'])) {
                 return "redirect:" . Director::absoluteURL($arguments['Redirect'], true);
             } else {
                 // Find the controller name
                 $controller = $arguments['Controller'];
                 Director::$urlParams = $arguments;
                 $controllerObj = Injector::inst()->create($controller);
                 $controllerObj->setSession($session);
                 try {
                     $result = $controllerObj->handleRequest($request, $model);
                 } catch (HTTPResponse_Exception $responseException) {
                     $result = $responseException->getResponse();
                 }
                 if (!is_object($result) || $result instanceof HTTPResponse) {
                     return $result;
                 }
                 user_error("Bad result from url " . $request->getURL() . " handled by " . get_class($controllerObj) . " controller: " . get_class($result), E_USER_WARNING);
             }
         }
     }
     // No URL rules matched, so return a 404 error.
     return new HTTPResponse('No URL rule was matched', 404);
 }
 /**
  * Return the appropriate error content for the given status code
  *
  * @param int $statusCode
  * @return string Content in an appropriate format for the current request
  */
 public function output($statusCode)
 {
     // TODO: Refactor into a content-type option
     if (Director::is_ajax()) {
         return $this->getTitle();
     }
     $renderer = Debug::create_debug_view();
     $output = $renderer->renderHeader();
     $output .= $renderer->renderInfo("Website Error", $this->getTitle(), $this->getBody());
     if (Email::config()->admin_email) {
         $mailto = Email::obfuscate(Email::config()->admin_email);
         $output .= $renderer->renderParagraph('Contact an administrator: ' . $mailto . '');
     }
     $output .= $renderer->renderFooter();
     return $output;
 }
 public function debug()
 {
     $val = "<h2>" . $this->class . "</h2><ul>";
     foreach ($this->toNestedArray() as $item) {
         $val .= "<li style=\"list-style-type: disc; margin-left: 20px\">" . Debug::text($item) . "</li>";
     }
     $val .= "</ul>";
     return $val;
 }
 /**
  * Determine the best module to be given ownership over this key
  *
  * @param array $entitiesByModule
  * @param string $key
  * @return string Best module, if found
  */
 protected function getBestModuleForKey($entitiesByModule, $key)
 {
     // Check classes
     $class = current(explode('.', $key));
     if (array_key_exists($class, $this->classModuleCache)) {
         return $this->classModuleCache[$class];
     }
     $owner = $this->findModuleForClass($class);
     if ($owner) {
         $this->classModuleCache[$class] = $owner;
         return $owner;
     }
     // @todo - How to determine ownership of templates? Templates can
     // exist in multiple locations with the same name.
     // Display notice if not found
     Debug::message("Duplicate key {$key} detected in no / multiple modules with no obvious owner", false);
     // Fall back to framework then cms modules
     foreach (array('framework', 'cms') as $module) {
         if (isset($entitiesByModule[$module][$key])) {
             $this->classModuleCache[$class] = $module;
             return $module;
         }
     }
     // Do nothing
     $this->classModuleCache[$class] = null;
     return null;
 }
 /**
  * @param HTTPRequest $request
  * @return array
  */
 protected function findAction($request)
 {
     $handlerClass = $this->class ? $this->class : get_class($this);
     // We stop after RequestHandler; in other words, at ViewableData
     while ($handlerClass && $handlerClass != 'SilverStripe\\View\\ViewableData') {
         $urlHandlers = Config::inst()->get($handlerClass, 'url_handlers', Config::UNINHERITED);
         if ($urlHandlers) {
             foreach ($urlHandlers as $rule => $action) {
                 if (isset($_REQUEST['debug_request'])) {
                     Debug::message("Testing '{$rule}' with '" . $request->remaining() . "' on {$this->class}");
                 }
                 if ($request->match($rule, true)) {
                     if (isset($_REQUEST['debug_request'])) {
                         Debug::message("Rule '{$rule}' matched to action '{$action}' on {$this->class}. " . "Latest request params: " . var_export($request->latestParams(), true));
                     }
                     return array('rule' => $rule, 'action' => $action);
                 }
             }
         }
         $handlerClass = get_parent_class($handlerClass);
     }
     return null;
 }