function infra_download_browser($agent = false) { if (!$agent) { $agent = $_SERVER['HTTP_USER_AGENT']; } $agent = strtolower($agent); $name = Once::exec('infra_imager_browser', function ($agent) { if (preg_match('/msie (\\d)/', $agent, $matches)) { $name = 'ie ie' . $matches[1]; } elseif (preg_match('/opera/', $agent)) { $name = 'opera'; if (preg_match('/opera\\/9/', $agent)) { $name .= ' opera9'; } elseif (preg_match('/opera (\\d)/', $agent, $matches)) { $name .= ' opera' . $mathces[1]; } if (preg_match('/opera\\smini/', $agent)) { $name .= ' opera_mini'; } } elseif (preg_match('/gecko\\//', $agent)) { $name = 'gecko'; if (preg_match('/firefox/', $agent)) { $name .= ' ff'; if (preg_match('/firefox\\/2/', $agent)) { $name .= ' ff2'; } elseif (preg_match('/firefox\\/3/', $agent)) { $name .= ' ff3'; } } } elseif (preg_match('/webkit/', $agent)) { $name = 'webkit'; if (preg_match('/chrome/', $agent)) { $name .= ' chrome'; } else { $name .= ' safari'; } } elseif (preg_match('/konqueror/', $agent)) { $name = 'konqueror'; } elseif (preg_match('/flock/', $agent)) { $name = 'flock'; } else { $name = 'stranger'; } if (!preg_match('/ie/', $name)) { $name .= ' noie'; } if (preg_match('/linux|x11/', $agent)) { $name .= ' linux'; } elseif (preg_match('/macintosh|mac os x/', $agent)) { $name .= ' mac'; } elseif (preg_match('/windows|win32/', $agent)) { $name .= ' win'; } if (preg_match('/stranger/', $name)) { $name = ''; } return $name; }, array($agent)); return $name; }
public static function init() { Once::exec(__FILE__, function () { //Список операций выполняющихся при любом запросе со спецсимволом в адресе [-~!] и при запросах без файлов //или при яном вызове в скрипте Router::init(); //Собирается конфиг .infra.json из корня проекта //Теперь при первом обащении к классу расширения будет собираться его конфиг .infra.json из папки расширения Config::init(); //Анализируется папка vendor Находятся все производители поддерживающие конфигурационные файлы .infra.json //Некий производитель angelcharly попадёт в список поиска, если у него есть библиотека с файлом .infra.json //Эту обработку можно убрать если производители прописаны вручную в config.path.search проекта //Без этой обработке, например, переопределения в кореновм .infra.json для расширения weather //не применятся к Weather::$conf и неinfrajs расширения будет работать со значениями по умолчанию //.infra.json в самих неinfrajs расширениях также не будет прочитан, //но значения конфига по умолчанию и так указаны в переменной класса, вроде Weather::$conf по этому не скажется на работе //В общем заполняем config.path.search путями до установленных расширений Search::init(); //Автоматическая установка расширений //Cоздаются папка cache и для расширения mem создаётся папка cache/mem, если их нет //Наличие этих папок, например, обязательно для Search, который кэширует свою работу //Во время обновления запускаются тесты Update::init(); //По дате авторизации админа выход и если браузер прислал информацию что у него есть кэш //Заголовок Cache-control:no-store в расширении Nostore::on() запретит создавать кэш, если станет ясно, что modfeied не нужен Access::modified(); //Заголовки по умолчанию для Cache-Controll Nostore::init(); //Вспомогательные заголовки с информацией о правах пользователя test debug admin Access::headers(); }); }
public static function exec($conds, $name, $fn, $args = array(), $re = false) { $name = 'Cache::exec' . $name; return Once::exec($name, function ($args, $r, $hash) use($name, $fn, $conds, $re) { $data = Mem::get($name . $hash); if (!$data) { $data = array('time' => 0); } $execute = Access::adminIsTime($data['time'], function ($cache_time) use($conds) { if (!sizeof($conds)) { return false; //Если нет conds кэш навсегда и develop не поможет } $max_time = 1; for ($i = 0, $l = sizeof($conds); $i < $l; $i++) { $mark = $conds[$i]; $mark = Path::theme($mark); if (!$mark) { continue; } $m = filemtime($mark); if ($m > $max_time) { $max_time = $m; } if (!is_dir($mark)) { continue; } foreach (glob($mark . '*.*') as $filename) { $m = filemtime($filename); if ($m > $max_time) { $max_time = $m; } } } return $max_time > $cache_time; }, $re); if ($execute) { $cache = Nostore::check(function () use(&$data, $fn, $args, $re) { $data['result'] = call_user_func_array($fn, array_merge($args, array($re))); }); if ($cache) { $data['time'] = time(); Mem::set($name . $hash, $data); } else { Mem::delete($name . $hash); } } return $data['result']; }, array($args), $re); }
public function testOnce() { $res = Once::exec('test', function ($a, $b) { return $a + $b; }, [4, 5]); $this->assertTrue(9 === $res); $res = Once::exec('test', function ($a, $b) { return $a + $b; }, [10, 5]); $this->assertTrue(9 !== $res); $this->assertTrue(15 === $res); Once::clear('test'); $res = Once::exec('test', function () { $a = 1; $b = 2; return $a + $b; }); $this->assertTrue(3 === $res); $res = Once::exec('test', function () { $a = 3; $b = 2; return $a * $b; }); $this->assertTrue(3 === $res); Once::clear('test'); $res = Once::exec('test', function () { $a = 3; $b = 2; return $a * $b; }); $this->assertTrue(6 === $res); Once::clear('test'); $res = Once::exec('test', function () { return true; }); $this->assertTrue(true === $res); $res = Once::exec('test', function () { $a = 1; $b = 2; return $a + $b; }, array(), true); assert(3 === $res); $res = Once::exec('test', function () { $a = 3; $b = 2; return $a * $b; }, array(), true); assert(6 === $res); }
public static function init() { Once::exec(__FILE__ . 'init', function () { $action = Ans::GET('-update'); Config::init(); $path = Path::$conf; if ($action) { Access::test(true); if (!Update::$is) { Path::fullrmdir($path['cache']); Update::exec(); } } if ($path['fs'] && !Update::$is) { if (!is_dir($path['cache'])) { Access::$conf['test'] = true; Update::exec(); } if (Access::isTest()) { if (is_file($path['data'] . 'update')) { unlink($path['data'] . 'update'); Access::$conf['test'] = true; if (!Update::$is) { Path::fullrmdir($path['cache']); Update::exec(); } } } } if (Update::$is) { if (is_file($path['data'] . 'update')) { unlink($path['data'] . 'update'); } } }); }
private function makeMark($data) { if (!$data) { return ''; } self::rksort($data); $key = md5(serialize($data)); $that = $this; $mark = Once::exec($this->prefix . $key, function () use($data, $that, $key) { $isoutdate = true; $raise = $this->raise; //На сколько символов разрешено увеличивать хэш $note = $this->note; //При увеличении на сколько записывается сообщение в лог $len = $this->len - 1; while ($isoutdate && $len < $this->len + $raise) { $len++; $mark = substr($key, 0, $len); $src = Path::theme('~.marks/' . $that->prefix . $mark . '.json'); if ($src) { $otherdata = file_get_contents($src); $otherdata = Load::json_decode($otherdata, true); } else { $otherdata = false; } //$otherdata=infra_mem_get($that->prefix.$mark); if ($otherdata && is_array($otherdata['data']) && $otherdata['time']) { if ($otherdata['data'] == $data) { $isoutdate = false; //Такая метка уже есть и она правильная } else { //Решается судьба старой метки $isoutdate = time() > $data['time'] + $this->warrantytime; } } else { $isoutdate = false; } } if ($len >= $this->len + $note) { $that->notice = 'Mark adding to hash ' . ($len - $this->len) . ' symbol(s) for save time warranty ' . print_r($data, true); error_log($that->notice); } if ($isoutdate) { //Все метки актуальны... перезаписываем первую $that->error = 'Mark rewrite actual hashmark'; error_log($that->error); $mark = substr($key, 0, $this->len); } $src = Path::theme('~.marks/'); if (!$src) { die('Fatal error no marks dir'); } $src = $src . $this->prefix . $mark . '.json'; $data = Load::json_encode(array('time' => time(), 'data' => $data)); $data = file_put_contents($src, $data); //infra_mem_set($that->prefix.$mark, array( // 'time'=>time(), // 'data'=>$data //)); return $mark; }); return $mark; }
private static function load($path) { $args = array($path); $res = Once::exec('Load::load', function ($path) { //php файлы эмитация веб запроса //всё остальное file_get_content $_r_e_s_ = array(); $_r_e_s_['cache'] = !Nostore::check(function () use($path, &$_r_e_s_) { if (Path::isDir($path)) { $p = explode('?', $path, 2); $p[0] .= 'index.php'; $path = implode('?', $p); } $load_path = Path::theme($path); $fdata = Load::srcinfo($load_path); if ($load_path && $fdata['file']) { $plug = Path::theme($fdata['path']); if ($fdata['ext'] == 'php') { $getstr = Path::toutf($fdata['query']); //get параметры в utf8, с вопросом $getstr = preg_replace("/^\\?/", '', $getstr); parse_str($getstr, $get); if (!$get) { $get = array(); } $GET = $_GET; $_GET = $get; $REQUEST = $_REQUEST; $_REQUEST = array_merge($_GET, $_POST, $_COOKIE); $SERVER_QUERY_STRING = $_SERVER['QUERY_STRING']; $_SERVER['QUERY_STRING'] = $getstr; $from_php_old = Load::isphp(); Load::isphp(true); ob_start(); //headers надо ловить $ans = array(); $rrr = (include $plug); $result = ob_get_contents(); $resecho = $result; ob_end_clean(); Load::isphp($from_php_old); if ($rrr !== 1 && !is_null($rrr)) { //Есть возвращённый результат $result = $rrr; if ($resecho) { //Сообщение об ошибке... далее всё ломаем $result = $resecho . Load::json_encode($result); //Есть вывод в браузер и return } } $_SERVER['QUERY_STRING'] = $SERVER_QUERY_STRING; $_REQUEST =& $REQUEST; $_GET =& $GET; $data = $result; //$data='php file'; } else { $data = file_get_contents($plug); } $_r_e_s_ = array(); //Если в include это имя использовалось. Главное чтобы оно небыло ссылкой & $_r_e_s_['status'] = 200; $_r_e_s_['value'] = $data; } else { $_r_e_s_['status'] = 404; $_r_e_s_['value'] = ''; } }); return $_r_e_s_; }, $args); if (!$res['cache']) { Nostore::on(); } return $res['value']; }
public static function &make($url, $tplempty = 'root') { $args = array($url, $tplempty); $tpls = Once::exec('Infrajs::Template::make', function ($url, $tplempty) { if (is_array($url)) { $template = $url[0]; } else { $template = static::load($url); } $ar = static::prepare($template); static::analysis($ar); $tpls = static::getTpls($ar, $tplempty); if (!$tpls) { $tpls[$tplempty] = array(); } //Пустой шаблон добавляется когда вообще ничего нет //$res=static::parseEmptyTpls($tpls); static::includes($tpls); return $tpls; }, $args); return $tpls; }
//время синхронизации и время записываемых данных, устанавливается в cookie $ans['time'] = $time; $list = Load::json_decode($_POST['list']); Each::exec($list, function &(&$li) use($time) { $li['time'] = $time; //У каждого сета добавляем его момет, что бы он начал попадат в выборку по времени в своём периуде $r = null; return $r; }); if ($session_id) { $session_id = Once::exec('sync_php_checksession', function ($session_id, $session_pass) { $db =& Db::pdo(); $sql = 'select password from ses_sessions where session_id=?'; $stmt = $db->prepare($sql); $stmt->execute(array($session_id)); $real_pass = $stmt->fetchColumn(); if (md5($real_pass) != $session_pass) { $session_id = false; } return $session_id; }, array($session_id, $session_pass), isset($_GET['re'])); } $ans['auth'] = !!$session_id; //Здесь session_id проверенный if ($session_id && $timelast <= $time) { $sql = 'select name, value, unix_timestamp(time) as time from ses_records where session_id=? and time>=from_unixtime(?) order by time, rec_id'; $stmt = $db->prepare($sql); $stmt->execute(array($session_id, $timelast)); $news = $stmt->fetchAll(); if ($list) { $ans['list'] = $list;
public static function req($path) { $args = array($path); Once::exec('Path::req', function ($path) { $rpath = Path::theme($path); if (!$rpath) { echo '<pre>'; throw new \Exception('Path::req - не найден путь ' . $path); } require_once $rpath; //Просто require позволяет загрузить самого себя. А мы текущий скрипт не добавляем в список подключённых }, $args); }
public static function load($src, $name = null) { $src = Path::theme($src); if (!$src) { return; } Once::exec('Config::load::' . $src, function () use($src, $name) { $d = file_get_contents($src); try { $d = Load::json_decode($d); } catch (\Exception $e) { } if (!is_array($d)) { echo '<pre>'; throw new \Exception('Wrong config ' . $src); } if ($name) { Config::accept($name, $d); } else { foreach ($d as $k => &$v) { Config::accept($k, $v); } } }); }
public static function analize() { return Once::exec('URN::getQuery', function () { $uri = $_SERVER['REQUEST_URI']; $p = explode('?', $uri, 2); $uri = urldecode($p[0]); $proj = getcwd() . '/'; $p = explode(':', $proj, 2); if (sizeof($p) != 1) { $proj = $p[1]; } $proj = str_replace('\\', '/', $proj); $proj = explode('/', $proj); $uri = explode('/', $uri); //Удалить пустые элементы $proj = array_diff($proj, array('')); $temp = array_pop($uri); //Последний элемент может быть пустым if (sizeof($uri)) { $uri = array_diff($uri, array('')); } $uri[] = $temp; /* proj Array ( [1] => xampp [2] => htdocs [3] => git [4] => infrajs ) uri Array ( [1] => git [2] => infrajs [3] => vendor [4] => infrajs [5] => tester ) */ $uri = array_reverse($uri); $proj = array_reverse($proj); $try = array(); $r = false; foreach ($uri as $i => $u) { if ($uri[$i] != $proj[0]) { continue; } $try = array_slice($uri, $i); //В try каждый элемент должен входить в proj $r = true; foreach ($try as $ii => $t) { if ($proj[$ii] != $t) { $r = false; break; } } if ($r) { break; } } if (!$r) { $try = array(); } $root = implode('/', array_reverse($try)); if ($root) { $root = '/' . $root; } $root .= '/'; $req = array_slice(array_reverse($uri), sizeof($try)); $req = implode('/', $req); $query = urldecode($_SERVER['QUERY_STRING']); if ($query) { if ($req) { $query = $req . '?' . $query; } else { $query = '?' . $query; } } else { if ($req) { $query = $req; } else { $query = ''; } } return array('root' => $root, 'query' => $query); }); }
public static function getType($src) { return Once::exec(__FILE__ . 'getTpype', function ($src) { $src = Path::tofs($src); $handle = fopen($src, 'r'); $line = fgets($handle, 50); $line2 = fgets($handle, 50); fclose($handle); if (preg_match('/JFIF/', $line)) { return 'jpeg'; } if (preg_match('/PNG/', $line)) { return 'png'; } if (preg_match('/GIF/', $line)) { return 'gif'; } if (preg_match('/Exif/', $line)) { return 'jpeg'; } if (preg_match('/Exif/', $line2)) { return 'jpeg'; } if (preg_match('/BM/', $line)) { return 'wbmp'; } return false; }, array($src)); }
public static function &user_init($email) { $user = Session::getUser($email); $session_id = $user['session_id']; $nowsession_id = Session::getId(); if ($session_id == $nowsession_id) { return Session::get(); } return Once::exec(__FILE__ . 'user_init', function ($session_id) { $sql = 'select name, value, unix_timestamp(time) as time from ses_records where session_id=? order by time,rec_id'; $db = Db::pdo(); $stmt = $db->prepare($sql); $stmt->execute(array($session_id)); $news = $stmt->fetchAll(); if (!$news) { $news = array(); } $obj = array(); Each::forr($news, function &(&$v) use(&$obj) { $r = null; if ($v['value'] == 'null') { $value = null; } else { $value = Load::json_decode($v['value']); } $right = Sequence::right($v['name']); $obj = Sequence::set($obj, $right, $value); return $r; }); return $obj; }, array($session_id)); }
public static function cache($name, $fn, $args = array(), $re = false) { //Запускается один раз для админа, остальные разы возвращает кэш из памяти $name = 'Access::cache ' . $name; return Once::exec($name, function ($args, $name) use($name, $fn, $re) { $path = $name . '_' . Hash::make($args); $data = Mem::get($path); if (!$data) { $data = array('time' => 0); } $execute = self::adminIsTime($data['time'], function () { return true; }, $re); if ($execute) { $cache = !Nostore::check(function () use(&$data, $fn, $args, $re) { $data['result'] = call_user_func_array($fn, array_merge($args, array($re))); }); if ($cache) { $data['time'] = time(); Mem::set($path, $data); } else { Mem::delete($path); } } return $data['result']; }, array($args, $name), $re); }
public static function &memcache() { return Once::exec('Mem::memcache', function () { $conf = Mem::$conf; if ($conf['type'] != 'mem') { return false; } if (!class_exists('Memcache')) { return false; } if (!$conf['memcache']) { return false; } $infra_mem = new \Memcache(); $infra_mem->connect($conf['memcache']['host'], $conf['memcache']['port']) or die('Could not connect'); return $infra_mem; }); }