/** * Запуск подчиненных контроллеров * @param Request $request Входящие данные и команды для обработки контроллерами * @param bool $all Признак, запускать все контроллеры (true), или пока не возвратится результат хотябы от одного из запущенных (false) * @param array $result Значения-заглушки для подчиненных контроллеров. Если в массиве есть ключ с именем контроллера, то этот контроллер не исполняется, а испольщуется указанное в элементе значение. * @return array Результаты исполнения контроллеров. Ключи массива - названия контроллеров. */ function startChildren($request, $all = true, $result = []) { $list = $this->getCihildrenControllers([], $request); $config = Config::read('collections'); if (isset($config[$this->uri() . '.startChildren'])) { $children = array_reverse($config[$this->uri() . '.startChildren']); foreach ($children as $item) { array_unshift($list, Data::read($item)); } } foreach ($list as $child) { $child = $child->linked(); if ($child instanceof controller) { $key = $child->name(); if (!isset($result[$key])) { $out = $child->start($request); if ($out !== false) { if (!$all) { return $out; } $request->mix(['previous' => true]); $result[$key] = $out; } } } } return $result; }
function work(Request $request) { // Объект по URI запроса $obj = Data::read('/contents' . $request['REQUEST']['path']); $request->mix(['REQUEST' => ['object' => $obj]]); return parent::work($request); }
/** * Генерация события * * @param string $event Имя события * @param array|mixed $params Параметры события * @param bool $all * @return mixed Объект события с результатами его обработки */ static function trigger($event, $params = [], $all = true) { $result = []; if (isset(self::$handlers[$event])) { foreach (self::$handlers[$event] as $key => $handler) { if (isset($handler[0]) && (empty($handler[0]) || mb_strpos($handler[0], '/') !== false)) { $out = call_user_func_array([\boolive\core\data\Data::read($handler[0]), $handler[1]], $params); } else { $out = call_user_func_array($handler, $params); } if ($out === false) { if (!$all) { return $out; } } else { $result[$key] = $out; } } } if (count($result) == 0 && !$all) { return null; } return $result; }
/** @const string Директория временных файлов на сервере. Слеш в конце обязателен! */ define('DIR_TEMP', DIR . 'temp/'); /** @const string Директория конфигураций. Слеш в конце обязателен! */ define('DIR_CONFIG', DIR . 'config/'); // Адрес сайта, например: boolive.ru. Значение по умолчанию для CLI режима define('HTTP_HOST', empty($_SERVER['HTTP_HOST']) ? 'boolive.ru' : $_SERVER['HTTP_HOST']); /* Признак, выводить всю трассировку?*/ define('GLOBAL_TRACE', false); /* Признак, профилировать запросы к модулю даных?*/ define('PROFILE_DATA', false); // Get composer loader $loader = (include DIR . 'vendor/autoload.php'); // Activate Boolive Core::activate($loader); // Start project (read and call root object) echo Data::read('/interfaces')->start(new Request()); //$u = \boolive\core\auth\Auth::get_user(); //trace($u); //trace($u->password); //trace(Data::find([ // 'from' => '/access/users', // 'select' => 'children', // //'struct' => 'tree', // 'key'=>'name', // 'depth' => 10 //])); //$bench_cnt = 100; // //$test = 3; // ////$dir = 'C:/Server/Sites/usurt/';
function read($uri) { if (!($entity = Buffer::get_entity($uri))) { // Экземпляра объекта в буфере нет, проверяем массив его атрибутов в буфере $info = Buffer::get_info($uri); if (empty($info)) { try { if ($uri === '') { $file = DIR . 'project.info'; $dir = DIR; } else { $file = DIR . trim($uri, '/') . '/' . File::fileName($uri) . '.info'; $dir = DIR . trim($uri, '/'); } if (is_file($file)) { // Чтение информации об объекте $info = file_get_contents($file); $info = json_decode($info, true); $error = json_last_error(); if ($error != JSON_ERROR_NONE) { $info = []; } $info['uri'] = $uri; if (!empty($info['file'])) { $info['is_default_file'] = false; // $info['is_file'] = true; // $info['value'] = $info['file']; } if (!empty($info['logic'])) { $info['is_default_logic'] = false; } if (!isset($info['is_default_logic'])) { $info['is_default_logic'] = true; } $info['is_exists'] = true; // Инфо о свойствах в буфер $info = Buffer::set_info($info); } // else // if (is_dir($dir)){ // $info = [ // 'uri' => $uri, // 'is_exists' => true // ]; // $info = Buffer::set_info($info); // } } catch (\Exception $e) { return false; } } if (empty($info) && $uri) { // Поиск объекта в свойствах объекта list($parent_uri, $name) = F::splitRight('/', $uri); if ($parent = Data::read($parent_uri)) { $props = Buffer::get_props($parent_uri); $entity = $parent->child($name, isset($props[$name])); } else { $entity = false; } } else { // Создать экземпляр без свойств $entity = Data::entity($info); } } return $entity; }
/** * Создание идентификатора для указанного URI. * Если объект с указанным URI существует, то будет возвращен его идентификатор * @param string $uri URI для которого нужно получить идентификатор * @param bool $create Создать идентификатор, если отсутствует? * @param bool $is_new Возвращаемый прзнак, был ли создан новый идентификатор? * @return int|null */ function localId($uri, $create = true, &$is_new = false) { $is_new = false; if (!is_string($uri)) { return 0; } // Из кэша if (!isset($this->_local_ids)) { // if ($local_ids = Cache::get('mysqlstore/localids')){ // $this->_local_ids = json_decode($local_ids, true); // }else{ $this->_local_ids = array(); // } } if (isset($this->_local_ids[$uri])) { return $this->_local_ids[$uri]; } // Поиск идентифкатора URI $q = $this->db->prepare('SELECT id FROM {ids} WHERE `uri`=? LIMIT 0,1 FOR UPDATE'); $q->execute(array($uri)); if ($row = $q->fetch(DB::FETCH_ASSOC)) { $id = $row['id']; $is_new = false; $this->_local_ids[$uri] = $id; $this->_global_ids[$id] = $uri; // Отношение с родителями $q = $this->db->prepare('SELECT * FROM {parents1} WHERE `id`=? LIMIT 0,1'); $q->execute(array($id)); if ($row = $q->fetch(DB::FETCH_ASSOC)) { $this->_parents_ids[$id] = F::array_clear($row); } // Отношение с прототипами $q = $this->db->prepare('SELECT * FROM {protos1} WHERE `id`=? LIMIT 0,1'); $q->execute(array($id)); if ($row = $q->fetch(DB::FETCH_ASSOC)) { $this->_protos_ids[$id] = F::array_clear($row); } } else { if ($create) { // Создание идентификатора для URI $q = $this->db->prepare('INSERT INTO {ids} (`id`, `uri`) VALUES (null, ?)'); $q->execute([$uri]); $id = $this->db->lastInsertId('id'); $is_new = true; $obj = Data::read($uri); // Отношения с родителями $this->makeParents($id, $this->localId($obj->parent())); // Отношения с прототипами $this->makeProtos($id, $this->localId($obj->proto())); } else { return 0; } } unset($q); return intval($id); }
static function entity($info) { $key = isset($info['uri']) ? $info['uri'] : null; if (!isset($key) || !($entity = Buffer::get_entity($key))) { try { $name = basename($info['uri']); if (isset($info['uri'])) { if (!empty($info['is_default_logic'])) { if (isset($info['proto'])) { // Класс от прототипа $class = get_class(self::read($info['proto'])); } else { // Класс наследуется, но нет прототипа $class = '\\boolive\\core\\data\\Entity'; } } else { if (empty($info['uri']) || preg_match('#^[a-zA-Z_0-9\\/]+$#ui', $info['uri'])) { $namespace = str_replace('/', '\\', rtrim($info['uri'], '/')); // Свой класс if (empty($namespace)) { $class = '\\project'; } else { if (substr($namespace, 0, 7) === '\\vendor') { $class = substr($namespace, 7) . '\\' . $name; } else { $class = $namespace . '\\' . $name; } } } else { $class = '\\boolive\\core\\data\\Entity'; } } } else { $class = '\\boolive\\core\\data\\Entity'; } if (isset($info['value']) && !isset($info['is_default_value'])) { $info['is_default_value'] = false; } if (!isset($info['is_default_value'])) { $info['is_default_value'] = true; } if (!isset($info['value']) && !empty($info['is_default_value']) && !empty($info['proto'])) { $info['value'] = Data::read($info['proto'])->value(); } // if (!isset($info['is_mandatory']) && isset($info['proto'])){ // $proto = self::read($info['proto']); // $info['is_mandatory'] = $proto->is_mandatory(); // } $entity = new $class($info); } catch (\ErrorException $e) { $entity = new Entity($info); } if (isset($key)) { Buffer::set_entity($entity); } } return $entity; }
static function fromArray($array) { if (isset($array['_attributes']['uri'])) { $obj = Data::read($array['_attributes']['uri']); } else { if (!isset($array['class'])) { $array['class'] = '\\boolive\\core\\data\\Entity'; } $obj = new $array['class'](); } if (!empty($array['_errors'])) { $obj->_errors = Error::createFromArray($array['_errors']); } if (isset($array['_children'])) { foreach ($array['_children'] as $key => $child) { $obj->_children[$key] = self::fromArray($child); $obj->_children[$key]->_parent = $obj; if ($obj->_children[$key]->_errors) { $obj->errors()->_children->add($obj->_children[$key]->_errors); } } } $obj->_attributes = $array['_attributes']; $obj->_changes = $array['_changes']; $obj->_checked = $array['_checked']; $obj->_auto_naming = $array['_auto_naming']; $obj->_is_inner = $array['_is_inner']; return $obj; }
/** * Проверка значения на соответствие объекту класса \boolive\core\data\Entity * Если значение строка, то значение будет воспринято как uri объекта данных, и будет попытка выбора объекта из бд. * @param mixed $value Значение для проверки * @param null|Error &$error Возвращаемый объект исключения, если значение не соответсвует типу * @param array $args Аргументы фильтра * @return \boolive\core\data\Entity|null */ static function entity($value, &$error, $args) { $cond = isset($args[0]) ? $args[0] : false; if (!is_object($value)) { if (is_string($value) && substr($value, 0, 1) == '{') { $value = json_decode($value, true); } if (is_string($value)) { // Пробуем получить объект по uri $value = Data::read($value); } else { if (is_array($value)) { // if (isset($value['id'])){ // $value = Data::read($value['id']); // }else if (isset($value['uri'])) { $value = Data::read($value['uri']); } // else // if (isset($value['proto'])){ // $value = Data::read($value['proto'])->birth(); // if (isset($value['parent']) && $parent = Data::read($value['parent'])){ // $parent->__set(null, $value); // } // } // unset($value['uri'], $value['proto'], $value['value']); } } } if (!$value instanceof Entity) { $error = new Error('Не является объектом данных "\\boolive\\core\\data\\Entity"', 'entity'); } else { if (!empty($cond) && !$value->verify($cond)) { $error = new Error('Объект не соответсвует заданному условию', 'entity'); } else { // if (!$value->is_exists()){ // $error = new Error('Объект не существует', 'entity'); // }else if (!$value->is_accessible()) { $error = new Error('Объект недоступен для чтения', 'entity'); } else { return $value; } } } return null; }
function work(Request $request) { $uri = ''; // $s = C::read(); // C::writeln(mb_detect_encoding($s,['utf-8','cp866'])); do { try { C::write(C::style($uri, [C::COLOR_GRAY_DARK]) . '> '); $commands = preg_split('/\\s/ui', trim(C::read())); $cmd_count = count($commands); if ($commands[0] == 'show') { $new_uri = !empty($commands[1]) ? $uri . '/' . trim($commands[1], ' \\/') : $uri; $obj = Data::read($new_uri); C::writeln(C::style(Trace::format($obj, false))); } else { if (mb_strlen($commands[0]) > 1 && ($commands[0][0] == '/' || mb_substr($commands[0], 0, 2) == '..')) { $new_uri = !empty($commands[0]) ? $uri . '/' . trim($commands[0], ' \\/') : $uri; $obj = Data::read($new_uri, false, true); if ($obj && $obj->is_exists()) { $uri = $obj->uri(); } else { C::writeln(C::style('Object does not exist', C::COLOR_RED)); } } else { if ($commands[0] == 'ls' || $commands[0] == 'children') { $list = Data::find(['from' => $uri, 'select' => empty($commands[1]) || $commands[1] != '-p' ? 'children' : 'properties', 'struct' => 'list', 'limit' => [0, 50]]); foreach ($list as $obj) { C::writeln(C::style($obj->name(), C::COLOR_BLUE)); } } else { if (preg_match('/^\\s*select(\\(|=)/ui', $commands[0])) { $cond = Data::normalizeCond($commands[0], false); if (!isset($cond['from'])) { $cond['from'] = $uri; } $result = Data::find($cond); C::writeln(C::style(Trace::format($result, false))); } else { if ($commands[0] == 'color') { if (!empty($commands[1])) { C::use_style($commands[1] == 'off' ? false : null); } else { C::use_style(true); } } else { if ($cmd_count > 1 && $commands[0] == 'attr') { $obj = Data::read($uri); $attr = $commands[1]; if ($obj instanceof Entity && $obj->is_exists() && $obj->is_attr($attr)) { if ($cmd_count > 2) { if ($commands[2] === "null") { $commands[2] = null; } else { if ($commands[2] === "false") { $commands[2] = false; } else { $commands[2] = trim(trim($commands[2], '"')); } } $obj->{$attr}($commands[2]); Data::write($obj); C::writeln(Trace::format($obj, false)); } else { C::writeln(C::style($obj->attr($attr)), C::COLOR_PURPLE); } } } else { if ($cmd_count > 2 && $commands[0] == 'new') { $new_uri = !empty($commands[1]) ? $uri . '/' . trim($commands[1], ' \\/') : $uri; list($parent, $name) = F::splitRight('/', $new_uri); if (!$parent) { $parent = ''; } $proto = $commands[2]; $obj = Data::create($proto, $parent, ['name' => $name]); $signs = array_flip($commands); if (isset($signs['-m'])) { $obj->is_mandatory(true); } if (isset($signs['-p'])) { $obj->is_property(true); } if (isset($signs['-d'])) { $obj->is_draft(true); } if (isset($signs['-h'])) { $obj->is_hidden(true); } if (isset($signs['-l'])) { $obj->is_link(true); } if (isset($signs['-r'])) { $obj->is_relative(true); } $obj->complete(); Data::write($obj); C::writeln(Trace::format($obj, false)); } else { if ($commands[0] == 'complete') { $obj = Data::read($uri); $signs = array_flip($commands); $only_mandatory = !isset($signs['-all']) && !isset($signs['-not-mandatory']); $only_property = !isset($signs['-all']) && !isset($signs['-not-property']); $obj->complete($only_mandatory, $only_property); Data::write($obj); C::writeln(Trace::format($obj, false)); } else { C::writeln(C::style('Unknown command', C::COLOR_RED)); } } } } } } } } } catch (Error $e) { C::writeln(C::style($e->getMessage(), C::COLOR_RED)); } catch (\Exception $e) { C::writeln(C::style((string) $e, C::COLOR_RED)); } Buffer::clear(); } while ($commands[0] !== 'exit'); C::writeln("\nby!"); // if (!empty($request['ARG'][2])) { // if ($request['ARG'][2] == 'read') { // $uri = empty($request['ARG'][3]) ? '' : '/' . trim($request['ARG'][3], '/'); // $obj = Data::read($uri); // C::writeln(C::style(Trace::style($obj, false))); // } else // if ($request['ARG'][2] == 'find') { // $cond = empty($request['ARG'][3]) ? '' : trim($request['ARG'][3], '/'); // $result = Data::find($cond); // C::write(C::style(Trace::style($result, false))); // } else // if ($request['ARG'][2] == 'edit') { // $object = Data::read(empty($request['ARG'][3]) ? '' : '/'.trim($request['ARG'][3], '/')); // $attr = empty($request['ARG'][4]) ? null : $request['ARG'][4]; // $value = empty($request['ARG'][5]) ? null : $request['ARG'][5]; // if ($object instanceof Entity && $object->is_exists() && $attr){ // $object->{$attr}($value); // Data::write($object); // C::write(C::style(Trace::style($object, false))); // } // }else // { //// phpinfo(); //// C::writeln(Trace::style($_ENV, false)); //// C::writeln(getenv('ANSICON')); // C::writeln( // C::style(json_encode($request['ARG']), [C::STYLE_BOLD, C::STYLE_UNDERLINE, C::COLOR_BLUE])); // //$a = C::read(); // //C::writeln($a); // //// fwrite(STDOUT, $colors->getColoredString("Testing Colors class, this is purple string on yellow background.", "purple", "yellow") . "\n"); //// $line = fgets(STDIN); //// if(trim($line) != 'yes'){ //// echo "ABORTING!\n"; //// exit; //// } //// echo "\n"; //// echo "Thank you, continuing...\n"; //// return true; // } // } }