/** * @param string $method * @param array $Args * @return Bridge * @throws \Exception */ public function __call($method, array $Args = []) { if (!preg_match('/^with(' . Reglib::VAR . ')$/', $method, $Matches)) { throw new \Exception('Call to undefined method "' . get_class($this) . '::' . $method . '()"!'); } return call_user_func_array([$this, 'with'], Arr::unshift($Args, $Matches[1])); }
/** * @param mixed $fragment, ... * @return Path */ public final function prepend($fragment) : Path { foreach (Arr::simplify(func_get_args()) as $fragment) { $this->Fragments = Arr::prepend($this->Fragments, preg_split('/' . preg_quote(DIRECTORY_SEPARATOR, '/') . '/', trim($fragment), -1, PREG_SPLIT_NO_EMPTY)); } return $this; }
/** * Send get request and return result. * @param string $url * @param array $Params * @param array $Headers * @param int $flags * @return string * @throws /Exception */ public static final function get($url, array $Params = [], array $Headers = [], $flags = 0b0) { $Curl = curl_init(); if (preg_match('/^(.*):([0-9]+)$/', $url, $Macth) > 0) { curl_setopt($Curl, CURLOPT_PORT, $Macth[2]); $url = $Macth[1]; } if (count($Params) > 0) { $url .= '?' . http_build_query($Params, '', '&', PHP_QUERY_RFC3986); } if (count($Headers) > 0) { curl_setopt($Curl, CURLOPT_HTTPHEADER, Arr::pack($Headers, ': ')); } curl_setopt($Curl, CURLOPT_URL, $url); curl_setopt($Curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($Curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($Curl, CURLOPT_SSL_VERIFYHOST, 2); if (self::F_RETURN_HEADERS & $flags) { curl_setopt($Curl, CURLOPT_HEADER, true); } if (($Response = curl_exec($Curl)) === false) { $Exception = new \Exception(curl_error($Curl), curl_errno($Curl)); curl_close($Curl); throw $Exception; } curl_close($Curl); return $Response; }
/** * @param string $name * @return AAdapter * @throws \Exception */ protected final function getAdapter(string $name) : AAdapter { if (!array_key_exists($name = strtolower(trim($name)), $this->Adapters)) { /** * If any adapter currently is not cached we need to create it and add to the cache. * Of course it should be configured previously. */ if (!array_key_exists($name, $this->Config)) { throw new \Exception('Undefined adapter "' . $name . '"!'); } /** * All standard adapter are always defined in the \Eggbe\Soauth\ namespace. * * Alternatively you could use any custom adapter from different namespaces * by using the special attribute "class" at the adapter configuration. */ if (!class_exists($class = Arr::get($this->Config, 'class', __NAMESPACE__ . '\\Adapter\\' . ucfirst($name)))) { throw new \Exception('Undefined adapter class "' . $class . '"!'); } /** * All adapters should always extend the base * \Eggbe\Soauth\Abstracts\AAdapter class. */ if (!is_subclass_of($class, AAdapter::class)) { throw new \Exception('Adapter class is not subclass of ' . AAdapter::class . '!'); } $this->Adapters[$name] = new $class($this->Config[$name]); } return $this->Adapters[$name]; }
/** * @param int $type * @param string $value * @return bool * @throws \Exception */ public static final function make($type, $value) { switch ((int) $type) { case self::HASH_TYPE_MD5: return md5(implode(Arr::simplify(array_slice(func_get_args(), 1)))); } throw new \Exception('Unknown validation type "' . $type . '"!'); }
/** * @param string $packed * @param string $rowsep * @param string $valsep * @return array */ public static function unpack($packed, $rowsep = ',', $valsep = '=') { $Values = []; foreach (preg_split('/' . preg_quote($rowsep, '/') . '+/', $packed, -1, PREG_SPLIT_NO_EMPTY) as $row) { if (strpos($row, $valsep) !== false) { $Values[preg_replace('/(?:[^\\w_.!:@+-]).*$/', null, trim(preg_replace('/' . preg_quote($valsep, '/') . '.*$/', null, trim($row))))] = preg_replace('/' . preg_quote($valsep, '/') . '.*$/', null, trim(preg_replace('/^.*?' . preg_quote($valsep, '/') . '/', null, trim($row)))); } } return array_filter(Arr::only($Values, array_filter(array_keys($Values)))); }
/** * @param array $Request * @return string * @throws \Exception */ public function dispatch(array $Request) { $Request = array_change_key_case($Request, CASE_LOWER); foreach ($this->Callbacks as $Rules => $Calbacks) { /** * All positive conditions are parsed here. * * This type of conditions don't need any special character in the beginning * and always checked in the first place. */ $Keys = array_filter($Rules = explode(',', $Rules), function ($key) { return !preg_match('/^[:!]/', $key); }); if (count(array_diff($Keys, array_keys($Request))) < 1) { /** * All negative conditions are parsed here. * * This type of conditions have to start from a special negation character * and always checked in the second place. */ $Keys = array_map(function ($key) { return preg_replace('/^!/', null, $key); }, array_filter($Rules, function ($key) { return preg_match('/^!/', $key); })); if (empty($Keys) || count(array_diff($Keys, array_keys($Request))) == count($Keys)) { /** * All grabbable keys are parsed here. * * This list are always includes all positive conditions and conditions * started by special colon character. */ $Values = Arr::like($Request, array_map(function ($key) { return preg_replace('/^:/', null, $key); }, array_filter($Rules, function ($key) { return !preg_match('/^!/', $key); }))); foreach ($Calbacks as $Callback) { if (!is_null($response = call_user_func_array($Callback, $Values))) { return $response; } } } } } /** * If any non-empty value wasn't obtained from callbacks * then the null value will be returned by default. */ return null; }
/** * @param AWatcher $Watcher * @throws \Exception */ public final function addWatcher(AWatcher $Watcher) { /** * Three keys are always use for system needs so we have to be * sure that nobody will be able to break this logic. */ if (in_array($Watcher->getKey(), ['namespace', 'method', 'params'])) { throw new \Exception('Can\'t use reserved key "' . $Watcher->getKey() . '" for custom needs!'); } /** * To prevent all kind of potential errors, the reassigning * of already existing keys isn't possible. */ if (Arr::has($this->Watchers, $Watcher->getKey())) { throw new \Exception('Watcher for key "' . $Watcher->getKey() . '" is already registered!'); } $this->Watchers[$Watcher->getKey()] = $Watcher; }
/** * @param string $path * @return array */ public static function files($path) { return Arr::simplify(array_map(function ($value) { return $value[strlen($value) - 1] == '/' ? [Fs::files($value)] : $value; }, glob(rtrim($path, '/') . '/*', GLOB_NOSORT | GLOB_MARK))); }
/** * Join all given arguments into one single string. * * @attention Type Casting is provided so this method cant throw an exception * if one or more arguments cannot be represented as a string. * * @param string $separator * @param mixed $source, ... * @return string */ public static final function join($separator, $source) { return implode($separator, array_map(function ($value) { return Str::cast($value); }, array_filter(Arr::simplify(array_slice(func_get_args(), 1))))); }
/** * @param array $Source * @param \Closure $Callback * @param array|string $keys, ... * @return array */ public static final function each(array $Source, \Closure $Callback, $keys = null) { return array_walk($Source, function (&$value, $key, $keys) use($Callback) { $value = count($keys) < 1 || in_array($key, $keys) ? $Callback($key, $value) : $value; }, Arr::simplify(array_slice(func_get_args(), 2))) ? $Source : []; }