/** * Choose view depending on request type */ public static final function start() { $controller = Controller::getInstance(); if (Controller::hasUnusedParameters()) { $controller->putExpires(true); throw new HttpError(404); } elseif (!is_null(self::$output)) { $controller->putExpires(); header('Content-Type: ' . self::$outputType . '; charset="utf-8"'); echo self::$output; View::$rendered = true; } elseif (Debugger::isEnabled() and isset($_GET['xml']) and $_GET['xml']) { if ($_GET['xml'] == '2') { View\XML::fillXML(); } header('Content-Type: text/xml; charset="utf-8"'); $controller->xml->formatOutput = true; $controller->xml->encoding = 'utf-8'; echo rawurldecode($controller->xml->saveXML()); View::$rendered = true; } elseif (!View::$rendered and Request::isAjax()) { $controller->putExpires(); // should be application/json, but opera doesn't understand it and offers to save file to disk header('Content-type: text/plain'); echo Ajaxer::getResponse(); View::$rendered = true; } elseif (!View::$rendered) { $controller->putExpires(); try { View::render($controller->xml); } catch (HttpError $ex) { if (!Debugger::isConsoleEnabled()) { throw new HttpError(500); } else { echo Debugger::debugHTML(true); die; } } } }
/** * Process parameters and run action */ private function callAction() { $method = $this->method; $actionMethod = Action::${$method}; $actionReflection = new \ReflectionMethod($this, $actionMethod); $actionParameters = $actionReflection->getParameters(); // action has no parameters? just call it. if (empty($actionParameters)) { call_user_func([$this, $actionMethod]); return; } // get named REQUEST_URI parameters list $namedParameters = []; foreach ($actionParameters as $parameter) { $class = $parameter->getClass() ? $parameter->getClass()->name : 'Difra\\Param\\NamedString'; if (call_user_func(["{$class}", "getSource"]) == 'query' and call_user_func(["{$class}", "isNamed"])) { $namedParameters[] = $parameter->getName(); } } // get parameter values $callParameters = []; foreach ($actionParameters as $parameter) { $name = $parameter->getName(); $class = $parameter->getClass() ? $parameter->getClass()->name : 'Difra\\Param\\NamedString'; switch (call_user_func(["{$class}", "getSource"])) { // query parameters case 'query': if (call_user_func(["{$class}", "isNamed"])) { // named parameter if (sizeof(self::$parameters) >= 2 and self::$parameters[0] == $name) { array_shift(self::$parameters); if (!call_user_func(["{$class}", 'verify'], self::$parameters[0])) { throw new View\HttpError(404); } $callParameters[$parameter->getName()] = new $class(array_shift(self::$parameters)); } elseif (call_user_func(["{$class}", 'isAuto'])) { $callParameters[$name] = new $class(); } elseif (!$parameter->isOptional()) { throw new View\HttpError(404); } else { $callParameters[$parameter->getName()] = null; } array_shift($namedParameters); } else { // unnamed parameter if (!empty(self::$parameters) and (!$parameter->isOptional() or empty($namedParameters) or self::$parameters[0] != $namedParameters[0])) { if (!call_user_func(["{$class}", 'verify'], self::$parameters[0])) { throw new View\HttpError(404); } $callParameters[$name] = new $class(array_shift(self::$parameters)); } elseif (!$parameter->isOptional()) { throw new View\HttpError(404); } else { $callParameters[$parameter->getName()] = null; } } break; // ajax parameters // ajax parameters case 'ajax': $value = Request::getParam($name); if (!is_null($value) and $value !== '') { if (!call_user_func(["{$class}", "verify"], $value)) { Ajaxer::invalid($name); continue; } $callParameters[$name] = new $class($value); } elseif (call_user_func(["{$class}", 'isAuto'])) { $callParameters[$name] = new $class(); } elseif (!$parameter->isOptional()) { Ajaxer::required($name); } else { $callParameters[$name] = null; } } } if (!Ajaxer::hasProblem()) { call_user_func_array([$this, $actionMethod], $callParameters); } }
/** * Fill output XML with some common data * @param \DOMDocument|null $xml * @param null $instance */ public static function fillXML(&$xml = null, $instance = null) { $controller = Controller::getInstance(); if (is_null($xml)) { $xml = $controller->xml; $node = $controller->realRoot; } else { $node = $xml->documentElement; } Debugger::addLine('Filling XML data for render: Started'); // TODO: sync this with Envi::getState() $node->setAttribute('lang', Envi\Setup::getLocale()); $node->setAttribute('site', Envi::getSubsite()); $node->setAttribute('host', $host = Envi::getHost()); $node->setAttribute('mainhost', $mainhost = Envi::getHost(true)); $node->setAttribute('protocol', Envi::getProtocol()); $node->setAttribute('fullhost', Envi::getURLPrefix()); $node->setAttribute('instance', $instance ? $instance : View::$instance); $node->setAttribute('uri', Envi::getUri()); $node->setAttribute('controllerUri', Action::getControllerUri()); if ($host != $mainhost) { $node->setAttribute('urlprefix', Envi::getURLPrefix(true)); } // get user agent Envi\UserAgent::getUserAgentXML($node); // ajax flag $node->setAttribute('ajax', (Request::isAjax() or isset($_SERVER['HTTP_X_REQUESTED_WITH']) and $_SERVER['HTTP_X_REQUESTED_WITH'] == 'SwitchPage') ? '1' : '0'); $node->setAttribute('switcher', (!$controller->cache and isset($_SERVER['HTTP_X_REQUESTED_WITH']) and $_SERVER['HTTP_X_REQUESTED_WITH'] == 'SwitchPage') ? '1' : '0'); // build and version number $node->setAttribute('build', Version::getBuild()); $node->setAttribute('framework', Version::getFrameworkVersion(false)); $node->setAttribute('frameworkLong', Version::getFrameworkVersion(true)); // date /** @var $dateNode \DOMElement */ $dateNode = $node->appendChild($xml->createElement('date')); $dateKeys = ['d', 'e', 'A', 'a', 'm', 'B', 'b', 'Y', 'y', 'c', 'x', 'H', 'M', 'S']; $dateValues = explode('|', strftime('%' . implode('|%', $dateKeys))); $dateCombined = array_combine($dateKeys, $dateValues); $dateNode->setAttribute('ts', time()); foreach ($dateCombined as $k => $v) { $dateNode->setAttribute($k, $v); } // debug flag $node->setAttribute('debug', Debugger::isEnabled() ? '1' : '0'); // config values (for js variable) $configNode = $node->appendChild($xml->createElement('config')); Envi::getStateXML($configNode); // menu if ($menuResource = Resourcer::getInstance('menu')->compile(View::$instance)) { $menuXML = new \DOMDocument(); $menuXML->loadXML($menuResource); $node->appendChild($xml->importNode($menuXML->documentElement, true)); } // auth Auth::getInstance()->getAuthXML($node); // locale Locales::getInstance()->getLocaleXML($node); // Add config js object $config = Envi::getState(); $confJS = ''; foreach ($config as $k => $v) { $confJS .= "config.{$k}='" . addslashes($v) . "';"; } $node->setAttribute('jsConfig', $confJS); Debugger::addLine('Filling XML data for render: Done'); Debugger::debugXML($node); }
/** * Callback for fatal errors */ public static function captureShutdown() { if (View::$rendered) { return; } // was there an error? if (!($error = error_get_last()) and !self::$handledByException) { return; } if ($error) { // add error to console log if (self::$handledByNormal != $error['message']) { $error['error'] = Libs\Debug\ErrorConstants::getInstance()->getVerbalError($error['type']); $error['class'] = 'errors'; $error['traceback'] = debug_backtrace(); array_shift($error['traceback']); self::addLineAsArray($error); } } self::$shutdown = true; // view was not rendered yet, render console standalone page if (!View::$rendered) { if (!Request::isAjax()) { echo self::debugHTML(true); } else { echo Ajaxer::getResponse(); } View::$rendered = true; } }