public static function render($e)
 {
     $xml = new DOMDocument('1.0', 'utf-8');
     $xml->formatOutput = true;
     $root = $xml->createElement('data');
     $xml->appendChild($root);
     $details = $xml->createElement('details', $e->getMessage());
     $details->setAttribute('type', General::sanitize($e instanceof ErrorException ? GenericErrorHandler::$errorTypeStrings[$e->getSeverity()] : 'Fatal Error'));
     $details->setAttribute('file', General::sanitize($e->getFile()));
     $details->setAttribute('line', $e->getLine());
     $root->appendChild($details);
     $nearby_lines = self::__nearByLines($e->getLine(), $e->getFile());
     $lines = $xml->createElement('nearby-lines');
     $markdown = "\t" . $e->getMessage() . "\n";
     $markdown .= "\t" . $e->getFile() . " line " . $e->getLine() . "\n\n";
     foreach ($nearby_lines as $line_number => $string) {
         $markdown .= "\t{$string}";
         $string = trim(str_replace("\t", '    ', General::sanitize($string)));
         $item = $xml->createElement('item', strlen($string) == 0 ? ' ' : $string);
         $item->setAttribute('number', $line_number + 1);
         $lines->appendChild($item);
     }
     $root->appendChild($lines);
     $element = $xml->createElement('markdown');
     //, General::sanitize($markdown)));
     $element->appendChild($xml->createCDATASection($markdown));
     $root->appendChild($element);
     $trace = $xml->createElement('backtrace');
     foreach ($e->getTrace() as $t) {
         $item = $xml->createElement('item');
         if (isset($t['file'])) {
             $item->setAttribute('file', General::sanitize($t['file']));
         }
         if (isset($t['line'])) {
             $item->setAttribute('line', $t['line']);
         }
         if (isset($t['class'])) {
             $item->setAttribute('class', General::sanitize($t['class']));
         }
         if (isset($t['type'])) {
             $item->setAttribute('type', $t['type']);
         }
         $item->setAttribute('function', General::sanitize($t['function']));
         $trace->appendChild($item);
     }
     $root->appendChild($trace);
     if (Frontend instanceof Symphony && Frontend::Parameters() instanceof Register) {
         $params = Frontend::Parameters();
         $parameters = $xml->createElement('parameters');
         foreach ($params as $key => $parameter) {
             $p = $xml->createElement('param');
             $p->setAttribute('key', $key);
             $p->setAttribute('value', (string) $parameter);
             if (is_array($parameter->value) && count($parameter->value) > 1) {
                 foreach ($parameter->value as $v) {
                     $p->appendChild($xml->createElement('item', (string) $v));
                 }
             }
             $parameters->appendChild($p);
         }
         $root->appendChild($parameters);
     }
     /*
     if(is_object(Symphony::Database())){
     
     	TODO: Implement Error Handling
     	$debug = Symphony::Database()->debug();
     
     	if(count($debug['query']) > 0){
     
     		$queries = $xml->createElement('query-log');
     
     		foreach($debug['query'] as $query){
     			$item = $xml->createElement('item', General::sanitize($query['query']));
     			if(isset($query['time'])) $item->setAttribute('time', $query['time']);
     			$queries->appendChild($item);
     		}
     
     		$root->appendChild($queries);
     	}
     
     }
     */
     return self::__transform($xml);
 }
 public static function resolveParameter($param, Register $DataSourceParameterOutput = null)
 {
     //	TODO: Allow resolveParamter to check the stack, ie: $ds-blog-tag:$ds-blog-id
     $param = trim($param, '$');
     if (isset(Frontend::Parameters()->{$param})) {
         return Frontend::Parameters()->{$param}->value;
     }
     if (isset($DataSourceParameterOutput->{$param})) {
         return $DataSourceParameterOutput->{$param}->value;
     }
     return null;
 }
 public function display($url = NULL)
 {
     self::$Parameters = new Register();
     // Default headers. Can be overwritten later
     //self::$Headers->append('HTTP/1.0 200 OK');
     self::$Headers->append('Content-Type', 'text/html;charset=utf-8');
     self::$Headers->append('Expires', 'Mon, 12 Dec 1982 06:14:00 GMT');
     self::$Headers->append('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
     self::$Headers->append('Cache-Control', 'no-cache, must-revalidate, max-age=0');
     self::$Headers->append('Pragma', 'no-cache');
     ####
     # Delegate: FrontendPreInitialise
     # Description: TODO
     # Global: Yes
     Extension::notify('FrontendPreInitialise', '/frontend/', array('view' => &self::$view, 'url' => &$url));
     if (!self::$view instanceof View) {
         $this->resolve($url);
     }
     ####
     # Delegate: FrontendPostInitialise
     Extension::notify('FrontendPostInitialise', '/frontend/', array('view' => &self::$view));
     // SETTING UP PARAMETERS --------------------------
     $root_page = array_shift(explode('/', self::$view->parent()->path));
     $current_path = explode(dirname($_SERVER['SCRIPT_NAME']), $_SERVER['REQUEST_URI'], 2);
     $current_path = '/' . ltrim(end($current_path), '/');
     self::$Parameters->register(array('today' => DateTimeObj::get('Y-m-d'), 'current-time' => DateTimeObj::get('H:i'), 'this-year' => DateTimeObj::get('Y'), 'this-month' => DateTimeObj::get('m'), 'this-day' => DateTimeObj::get('d'), 'timezone' => date_default_timezone_get(), 'website-name' => Symphony::Configuration()->core()->symphony->sitename, 'symphony-version' => Symphony::Configuration()->core()->symphony->version, 'upload-limit' => min(ini_size_to_bytes(ini_get('upload_max_filesize')), Symphony::Configuration()->core()->symphony->{'maximum-upload-size'}), 'root' => URL, 'workspace' => URL . '/workspace', 'page-title' => self::$view->title, 'root-page' => !is_null($root_page) ? $root_page : self::$view->handle, 'current-page' => self::$view->handle, 'current-path' => $current_path, 'parent-path' => '/' . self::$view->path, 'current-url' => URL . $current_path));
     if (isset(self::$view->{'url-parameters'}) && is_array(self::$view->{'url-parameters'})) {
         foreach (self::$view->{'url-parameters'} as $p) {
             self::$Parameters->{$p} = NULL;
         }
         foreach (self::$view->parameters() as $p => $v) {
             self::$Parameters->{$p} = str_replace(' ', '+', $v);
         }
     }
     if (is_array($_GET) && !empty($_GET)) {
         foreach ($_GET as $key => $val) {
             if (in_array($key, array('symphony-page', 'debug', 'profile'))) {
                 continue;
             }
             // self::$Parameters->{"url-{$key}"} = $val; "url" is not prepended by $_GET params
             self::$Parameters->{$key} = $val;
         }
     }
     if (is_array($_COOKIE[__SYM_COOKIE_PREFIX__]) && !empty($_COOKIE[__SYM_COOKIE_PREFIX__])) {
         foreach ($_COOKIE[__SYM_COOKIE_PREFIX__] as $key => $val) {
             self::$Parameters->{"cookie-{$key}"} = $val;
         }
     }
     // RENDER THE VIEW --------------------------
     // Can ask the view to operate on an existing
     // Document. Useful if we pass it around beyond
     // the scope of View::render()
     ####
     # Delegate: FrontendPreRender
     # Description: TODO
     # Global: Yes
     Extension::notify('FrontendPreRender', '/frontend/', array('view' => &self::$view, 'parameters' => &self::$Parameters, 'document' => &self::$Document, 'headers' => &self::$Headers));
     $output = self::$view->render(self::$Parameters, self::$Document, self::$Headers);
     ####
     # Delegate: FrontendPostRender
     # Description: TODO
     # Global: Yes
     Extension::notify('FrontendPostRender', '/frontend/', array('output' => &$output, 'headers' => &self::$Headers));
     self::Headers()->render();
     return $output;
 }