slash = strpos(__DIR__, '/') === null ? '\\' : '/'; $this->inputs = $inputs; } public function nulls($nulls = null){ return is_bool($nulls) ? $nulls : $this->settings("nulls", null, false, false); } public function default_value($default = null, $nulls = null){ return $default !== null || $this->nulls($nulls) ? $default : $this->settings("default_value", null, null, true); } public static function is_dictionary($value){ return is_array($value) && array_values($value) != $value; } public function settings($keys, $inputs = null, $default = null, $nulls = null){ $keys = array_filter(array_unique(array_map(fn($key) => is_string($key) && ($key = trim($key)) ? $key : null, $keys)), fn($key) => $key); if(count($keys)){ $nulls = $this->nulls($nulls); foreach(array_merge( is_array($inputs) ? (self::is_dictionary($inputs) ? [$inputs] : $inputs) : [], [$this->inputs, $this->custom_settings, self::$default_settings] ) as $subinputs) if(self::is_dictionary($subinputs)) foreach($keys as $key) if(isset($subinputs[$key]) && ($nulls || $subinputs[$key] !== null)) return $subinputs[$key]; }; return $this->default_value($default, $nulls); } public static function string_variables($string, $variables = null, $default = null){ $variables = array_filter(is_array($variables) ? (self::is_dictionary($variables) ? [$variables] : $variables) : [], fn($item) => self::is_dictionary($item)); return preg_replace_callback('/\{([^\{\}]+)\}/', function($values) use($variables){ foreach($variables as $subset) if(isset($subset[$values[1]])) return $subset[$values[1]]; return $default ?? $values[0]; }, $string); } public static function check($conditions, $shift = 0){ $error = 0; $k = 0; $i = -1; if(is_array($conditions) && !self::is_dictionary($conditions)) foreach($conditions as $condition){ $ignore = false; $i ++; if(is_array($condition)){ if(($l = count($condition)) == 2) list($condition, $ignore) = $condition; else list($suberror, $sub_k) = self::check($condition); }; if(is_callable($condition) ? $condition() : (is_bool($condition) ? $condition : false)){ $ignore || ($error |= 1 << ($shift + $k + $i)); break; }; }; return [$error, $k + $shift + $i]; } public function fix_path($path){ $error = self::check([ fn() => $path === null, fn() => !is_string($path), [fn() => !$path, true] ], 1)[0]; $results = null; $error || ($results = preg_replace('/[\/\\\\]+/', $this->slash, self::string_variables($path, [ "project_path" => self::root_project_path ]))); return [$results, $error]; } public function get_absolute_path($path){ $error = self::check([ fn() => $path === null, fn() => !is_string($path), [fn() => !$path, true] ], 1)[0]; $absolute_path = null; if(!$error){ foreach($this->root_paths as $root) if(file_exists($full_path = $this->fix_path($root . '/' . $path)[0])){ $absolute_path = $full_path; break; }; $absolute_path === null && ($error |= 1 << 4); }; return [$absolute_path, $error]; } public function load_file($path){ list($path, $error) = $this->absolute_path($path); $data = null; if(!$error) try{ $data = file_get_contents($path); }catch(\Exception $exception){ $error |= 1 << 0; }; return [$data, $error]; } };