/** * @param string $adapter * @param bool $new * @return MySQL\Abstracts\MySQLi|MySQL\Abstracts\None */ public static function getInstance($adapter = self::INST_DEFAULT, $new = false) { if ($adapter == self::INST_AUTO) { static $auto = null; if (!is_null($auto)) { return self::getInstance($auto, $new); } if (MySQLi::isAvailable()) { Debugger::addLine("MySQL module: MySQLi"); return self::getInstance($auto = self::INST_MYSQLI, $new); } else { Debugger::addLine("No suitable MySQL module detected"); return self::getInstance($auto = self::INST_NONE, $new); } } if (!$new and isset(self::$adapters[$adapter])) { return self::$adapters[$adapter]; } switch ($adapter) { case self::INST_MYSQLI: $obj = new MySQLi(); break; default: $obj = new None(); } if (!$new) { self::$adapters[$adapter] = $obj; } return $obj; }
/** * Find controller and action for current URI * @throws Exception */ public static function find() { if (self::loadCache()) { Debugger::addLine('Cached controller ' . self::$controllerClass . ' from ' . self::$controllerFile); return; } $uri = trim(Envi::getUri(), '/'); $parts = $uri ? explode('/', $uri) : []; self::getResource($parts); $controllerUriParts = $parts; if (!(self::$controllerFile = self::findController($parts))) { self::saveCache('404'); throw new HttpError(404); } self::$controllerUri = '/' . implode('/', sizeof($parts) ? array_slice($controllerUriParts, 0, -sizeof($parts)) : $controllerUriParts); /** @noinspection PhpIncludeInspection */ include_once self::$controllerFile; if (!class_exists(self::$controllerClass)) { throw new Exception('Error! Controller class ' . self::$controllerClass . ' not found'); } self::findAction($parts); self::$parameters = $parts; self::saveCache('action'); Debugger::addLine('Selected controller ' . self::$controllerClass . ' from ' . self::$controllerFile); }
/** * @param \DOMDocument $xml * @param bool|string $specificInstance * @param bool $dontEcho * @param bool $dontFillXML * @param bool $normalize * @return bool|string * @throws Exception */ public static function render(&$xml, $specificInstance = false, $dontEcho = false, $dontFillXML = false, $normalize = true) { if ($specificInstance) { $instance = $specificInstance; } elseif (self::$instance) { $instance = self::$instance; } else { $instance = 'main'; } Debugger::addLine("Render start (instance '{$instance}')"); if (!($resource = Resourcer::getInstance('xslt')->compile($instance))) { throw new Exception("XSLT resource not found"); } $xslDom = new \DomDocument(); $xslDom->resolveExternals = true; $xslDom->substituteEntities = true; if (!$xslDom->loadXML($resource)) { throw new Exception("XSLT load problem for instance '{$instance}'"); } $xslProcessor = new \XSLTProcessor(); $xslProcessor->importStylesheet($xslDom); if (!$dontFillXML and !HttpError::$error and !Debugger::$shutdown) { View\XML::fillXML($xml, $instance); } // transform template if ($html = $xslProcessor->transformToDoc($xml)) { if ($normalize) { $html = self::normalize($html); } else { $html->formatOutput = true; $html = $html->saveXML(); } if ($dontEcho) { return $html; } echo $html; self::$rendered = true; if (Debugger::isEnabled()) { echo '<!-- Page rendered in ' . Debugger::getTimer() . ' seconds -->'; } if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } } else { $errormsg = libxml_get_errors(); //error_get_last(); throw new Exception($errormsg ? $errormsg['message'] : "Can't render templates"); } return true; }
/** * Run suitable action */ public static final function run() { $controller = self::getInstance(); $controller->chooseAction(); if (!$controller->method) { throw new Exception('Controller failed to choose action method'); } Debugger::addLine('Started action ' . Action::$method); $controller->callAction(); Debugger::addLine('Finished action ' . Action::$method); }
/** * 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); }
/** * Compile resource * @param string $instance * @param bool $withSources * @throws Exception * @return string */ private function realCompile($instance, $withSources = false) { Debugger::addLine("Resource {$this->type}/{$instance} compile started"); $res = false; if ($this->find($instance)) { $this->processDirs($instance); $res = $this->processData($instance, $withSources); } $res = $this->processText($res); Debugger::addLine("Resource {$this->type}/{$instance} compile finished"); return $res; }