Пример #1
0
 /**
  * @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;
 }
Пример #2
0
 /**
  * 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);
 }
Пример #3
0
 public function dispatch()
 {
     if (!\Difra\Debugger::isEnabled()) {
         throw new \Difra\View\HttpError(404);
     }
     \Difra\View::$instance = 'adm';
 }
Пример #4
0
 /**
  * Convert LESS to CSS
  * @param string $string
  * @return string
  */
 public static function compile($string)
 {
     self::init();
     $parser = new \Less_Parser();
     $parser->SetOptions(['compress' => !Debugger::isEnabled()]);
     $parser->parse($string);
     return $parser->getCss();
 }
Пример #5
0
 /**
  * Choose most suitable file
  * @param $file
  * @return mixed|string
  */
 private function getFile($file)
 {
     $debuggerEnabled = Debugger::isEnabled();
     if (!$debuggerEnabled and !empty($file['min'])) {
         return file_get_contents($file['min']);
     } elseif (!$debuggerEnabled and !empty($file['raw'])) {
         return Minify::getInstance($this->type)->minify(file_get_contents($file['raw']));
     } elseif ($debuggerEnabled and !empty($file['raw'])) {
         return file_get_contents($file['raw']);
     } elseif ($debuggerEnabled and !empty($file['min'])) {
         return file_get_contents($file['min']);
     }
     return '';
 }
Пример #6
0
 /**
  * @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;
 }
Пример #7
0
 /**
  * @backupGlobals enabled
  */
 public function test_actions()
 {
     \Difra\Debugger::disable();
     \Difra\Ajaxer::clean();
     $actions = [];
     \Difra\Ajaxer::notify('notification message');
     $actions[] = ['action' => 'notify', 'message' => 'notification message', 'lang' => ['close' => \Difra\Locales::get('notifications/close')]];
     \Difra\Ajaxer::display('<span>test</span>');
     $actions[] = ['action' => 'display', 'html' => '<span>test</span>'];
     \Difra\Ajaxer::error('error message <span>test</span>');
     $actions[] = ['action' => 'error', 'message' => 'error message &lt;span&gt;test&lt;/span&gt;', 'lang' => ['close' => \Difra\Locales::get('notifications/close')]];
     \Difra\Ajaxer::required('element');
     $actions[] = ['action' => 'require', 'name' => 'element'];
     \Difra\Ajaxer::invalid('inv1');
     $actions[] = ['action' => 'invalid', 'name' => 'inv1'];
     \Difra\Ajaxer::invalid('inv2');
     $actions[] = ['action' => 'invalid', 'name' => 'inv2'];
     \Difra\Ajaxer::status('field1', 'bad value', 'problem');
     $actions[] = ['action' => 'status', 'name' => 'field1', 'message' => 'bad value', 'classname' => 'problem'];
     \Difra\Ajaxer::redirect('/some/page');
     $actions[] = ['action' => 'redirect', 'url' => '/some/page'];
     $_SERVER['HTTP_REFERER'] = '/current/page';
     \Difra\Ajaxer::refresh();
     $actions[] = ['action' => 'redirect', 'url' => '/current/page'];
     \Difra\Ajaxer::reload();
     $actions[] = ['action' => 'reload'];
     \Difra\Ajaxer::load('someid', 'some <b>content</b>');
     $actions[] = ['action' => 'load', 'target' => 'someid', 'html' => 'some <b>content</b>'];
     \Difra\Ajaxer::close();
     $actions[] = ['action' => 'close'];
     \Difra\Ajaxer::reset();
     $actions[] = ['action' => 'reset'];
     \Difra\Envi::setUri('/current/page');
     \Difra\Ajaxer::confirm('Are you sure?');
     $actions[] = ['action' => 'display', 'html' => '<form action="/current/page" class="ajaxer"><input type="hidden" name="confirm" value="1"/>' . '<div>Are you sure?</div>' . '<input type="submit" value="' . \Difra\Locales::get('ajaxer/confirm-yes') . '"/>' . '<input type="button" value="' . \Difra\Locales::get('ajaxer/confirm-no') . '" onclick="ajaxer.close(this)"/>' . '</form>'];
     $this->assertEquals(\Difra\Ajaxer::getResponse(), json_encode(['actions' => $actions], \Difra\Ajaxer::getJsonFlags()));
     \Difra\Ajaxer::clean();
     $this->assertEquals(\Difra\Ajaxer::getResponse(), '[]');
     $this->assertFalse(\Difra\Ajaxer::hasProblem());
     \Difra\Ajaxer::reload();
     \Difra\Ajaxer::clean(true);
     $this->assertEquals(\Difra\Ajaxer::getResponse(), '[]');
     $this->assertTrue(\Difra\Ajaxer::hasProblem());
 }
Пример #8
0
 /**
  * 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;
             }
         }
     }
 }
Пример #9
0
 /**
  * @param \SimpleXMLElement $node
  * @param string $href
  * @param string $prefix
  * @param string $instance
  * @internal param string $url
  */
 private function recursiveProcessor($node, $href, $prefix, $instance)
 {
     /** @var \SimpleXMLElement $subNode */
     foreach ($node as $subname => $subNode) {
         /** @noinspection PhpUndefinedFieldInspection */
         if ($subNode->attributes()->sup and $subNode->attributes()->sup == '1') {
             if (!Debugger::isEnabled()) {
                 $subNode->addAttribute('hidden', 1);
             }
         }
         $newHref = "{$href}/{$subname}";
         $newPrefix = "{$prefix}_{$subname}";
         $subNode->addAttribute('id', $newPrefix);
         /** @noinspection PhpUndefinedFieldInspection */
         if (!isset($subNode->attributes()->href)) {
             $subNode->addAttribute('href', $newHref);
         }
         $subNode->addAttribute('pseudoHref', $newHref);
         $subNode->addAttribute('xpath', 'locale/menu/' . $instance . '/' . $newPrefix);
         $this->recursiveProcessor($subNode, $newHref, $newPrefix, $instance);
     }
 }
Пример #10
0
 /**
  * Set X-Accel-Expires header for web server-side caching
  * @param bool|int $ttl
  */
 public function putExpires($ttl = null)
 {
     if (Debugger::isEnabled()) {
         return;
     }
     if (is_null($ttl)) {
         $ttl = $this->cache;
     }
     if ($ttl === true) {
         $ttl = self::DEFAULT_CACHE;
     }
     if (!$ttl or !is_numeric($ttl) or $ttl < 0) {
         return;
     }
     View::addExpires($ttl);
 }
Пример #11
0
 /**
  * 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);
 }
Пример #12
0
 /**
  * Выбирает рабочий cdn хост
  */
 public function selectHost()
 {
     $this->_getSettings();
     $db = \Difra\MySQL::getInstance();
     $res = null;
     $stage = null;
     // stage 1 — select from 'ok' hosts with softer load of new cdn hosts
     try {
         $queryWrk = "SELECT `id`, `host`, `port` FROM `cdn_hosts_work`\n\t\t\t\tWHERE (`status`='ok'\n\t\t\t\tOR `failed`<DATE_SUB(NOW(),INTERVAL " . intval($this->settings['failtime']) . " MINUTE))\n\t\t\t\tAND `created`<DATE_SUB(NOW(),INTERVAL " . intval(rand(0, 24)) . " HOUR)\n\t\t\t\tORDER BY `selected`\n\t\t\t\tLIMIT 1";
         $res = $db->fetchRow($queryWrk);
         if (!$res) {
             $db->query('REPLACE INTO `cdn_hosts_work` SELECT * FROM `cdn_hosts`');
             $res = $db->fetchRow($queryWrk);
         }
         $stage = 1;
     } catch (\Difra\Exception $ex) {
     }
     // stage 2 — select from 'ok' hosts without softer load of new cdn hosts
     if (!$res) {
         try {
             $query = "SELECT `id`, `host`, `port` FROM `cdn_hosts_work`\n\t\t\t\tWHERE `status`='ok'\n\t\t\t\tAND `failed`<DATE_SUB(NOW(),INTERVAL " . intval($this->settings['failtime']) . " MINUTE)\n\t\t\t\tORDER BY `selected`\n\t\t\t\tLIMIT 1";
             $res = $db->fetchRow($query);
             $stage = 2;
         } catch (\Difra\Exception $ex) {
         }
     }
     // stage 3 — select from busy hosts
     if (!$res) {
         try {
             $query = "SELECT `id`, `host`, `port` FROM `cdn_hosts_work`\n\t\t\t\tWHERE `status`='busy'\n\t\t\t\tORDER BY `selected` DESC\n\t\t\t\tLIMIT 1";
             $res = $db->fetchRow($query);
             $stage = 3;
         } catch (\Difra\Exception $ex) {
         }
     }
     // stage 4 - select from hosts that haven't been checked for a long time
     if (!$res) {
         try {
             $query = "SELECT `id`, `host`, `port` FROM `cdn_hosts`\n\t\t\t\tWHERE `failed`<DATE_SUB(NOW(),INTERVAL " . intval($this->settings['failtime']) . " MINUTE)\n\t\t\t\tORDER BY `selected`\n\t\t\t\tLIMIT 1";
             $res = $db->fetchRow($query);
             $stage = 4;
         } catch (\Difra\Exception $ex) {
         }
     }
     if (!empty($res)) {
         $rootNode = \Difra\Action::getInstance()->controller->root;
         $rootNode->setAttribute('cdn_host', $res['host'] . ':' . $res['port']);
         $rootNode->setAttribute('cdn_host_id', $res['id']);
         $this->_updateSelected($res['id'], $res['host'] . ':' . $res['port']);
         if (\Difra\Debugger::getInstance()->isEnabled()) {
             $rootNode->setAttribute('cdn_stage', $stage);
         }
         return;
     }
 }
Пример #13
0
 /**
  * Fetch data from database
  * @param string $query
  * @param bool $replica Allow reading data from db replica
  * @return array
  */
 public function fetch($query, $replica = false)
 {
     $this->connect();
     Debugger::prepareDBLine();
     $result = $this->realFetch($query, $replica);
     Debugger::addDBLine('MySQL', $query);
     $this->queries++;
     return $result;
 }
Пример #14
0
 /**
  * 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;
 }
Пример #15
0
 /**
  * Commit transaction
  * @return bool
  */
 public function commit()
 {
     $this->transaction = false;
     $result = $this->pdo->commit();
     if (Debugger::isEnabled()) {
         Debugger::addDBLine('DB', 'Transaction commited in ' . number_format((microtime(true) - $this->transaction) * 1000, 1) . ' ms');
     }
     return $result;
 }
Пример #16
0
 /**
  * Is debugging enabled?
  * @return bool
  */
 protected static function isDebug()
 {
     return \Difra\Debugger::isEnabled();
 }