From cea0bfbb526e2078242f07fa5b36586d0be198bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rald=20Plusquellec?= Date: Mon, 9 Apr 2018 08:29:51 +0200 Subject: [PATCH] component --- lib/component.php | 160 +++++++++++++++++++ lib/lib.php | 224 +++++++++++++++++++++++++- lib/mvc.php | 38 +++++ lib/parametermemory.php | 343 ++++++++++++++++++++++++++++++++++++++++ tests/EventsTest.php | 1 + tests/SimpleTest.php | 53 +++++++ 6 files changed, 811 insertions(+), 8 deletions(-) create mode 100644 lib/component.php create mode 100644 lib/mvc.php create mode 100644 lib/parametermemory.php diff --git a/lib/component.php b/lib/component.php new file mode 100644 index 0000000..cf3d80e --- /dev/null +++ b/lib/component.php @@ -0,0 +1,160 @@ +__bag = new Parametermemory($data); + } + + /** + * @param string $key + * @param $value + */ + public function __set(string $key, $value) + { + $this->__bag[$key] = $value; + } + + /** + * @param string $key + * @return mixed + */ + public function __get(string $key) + { + return $this->__bag->{$key} ?? null; + } + + /** + * @param $method + * @param $parameters + * @return Component|mixed + * @throws \ReflectionException + */ + public function __call($method, $parameters) + { + if ($callable = $this->__bag->{$method}) { + if (is_callable($callable)) { + if ($callable instanceof \Closure) { + $args = array_merge([$callable], $parameters); + + return gi()->makeClosure(...$args); + } elseif (is_array($callable)) { + $args = array_merge($callable, $parameters); + + return gi()->call(...$args); + } + } else { + return $callable; + } + } + + if (fnmatch('get*', $method) && strlen($method) > 3) { + $key = Inflector::uncamelize(substr($method, 3)); + $default = empty($parameters) ? null : current($parameters); + + return isset($this->{$key}) ? $this->{$key} : $default; + } elseif (fnmatch('set*', $method) && strlen($method) > 3) { + $key = Inflector::uncamelize(substr($method, 3)); + + $this->{$key} = current($parameters); + + return $this; + } elseif (fnmatch('has*', $method) && strlen($method) > 3) { + $key = Inflector::uncamelize(substr($method, 3)); + + return isset($this->{$key}); + } elseif (fnmatch('remove*', $method) && strlen($method) > 6) { + $key = Inflector::uncamelize(substr($method, 6)); + + if (isset($this->{$key})) { + unset($this->{$key}); + + return true; + } + + return false; + } + + if (!empty($parameters) && count($parameters) === 1 && is_callable(current($parameters))) { + $this->__bag->{$method} = current($parameters); + + return $this; + } + + if (in_array($method, get_class_methods($this->__bag))) { + return $this->__bag->{$method}(...$parameters); + } + + return null; + } + + /** + * @param mixed $key + * + * @return bool + */ + public function offsetExists($key) + { + return $this->__bag->has($key); + } + + /** + * @param mixed $key + * + * @return bool + */ + public function __isset($key) + { + return $this->__bag->has($key); + } + + /** + * @param mixed $key + * + * @return mixed + */ + public function offsetGet($key) + { + return $this->__bag->get($key); + } + + /** + * @param mixed $key + * @param mixed $value + */ + public function offsetSet($key, $value) + { + $this->__bag->set($key, $value); + } + + /** + * @param mixed $key + */ + public function offsetUnset($key) + { + $this->__bag->remove($key); + } + + /** + * @param mixed $key + */ + public function __unset($key) + { + $this->__bag->remove($key); + } +} diff --git a/lib/lib.php b/lib/lib.php index 5c51d7d..93df39f 100755 --- a/lib/lib.php +++ b/lib/lib.php @@ -384,7 +384,12 @@ function current_url() return URLSITE . isAke($_SERVER, 'REQUEST_URI', ''); } - function contains($key, $string) + /** + * @param string $key + * @param string $string + * @return bool + */ + function contains(string $key, string $string) { return \fnmatch("*$key*", $string) ? true : false; } @@ -2111,6 +2116,16 @@ function getCallReflector($callback) ; } + /** + * @param string $callback + * @param null|string $default + * @return array + */ + function parseCaller(string $callback, ?string $default = null): array + { + return false !== strpos($callback, '@') ? explode('@', $callback, 2) : [$callback, $default]; + } + /** * @param string|null $str */ @@ -2127,7 +2142,6 @@ function displayCodeLines() { $back = ''; - // $traces = Thin\Input::globals('dbg_stack', []); $traces = debug_backtrace(); array_pop($traces); @@ -2139,12 +2153,10 @@ function displayCodeLines() if (false !== $file && false !== $line && $file != __FILE__) { $start = $line > 5 ? $line - 5 : $line; $code = File::readLines($file, $start, $line + 5); - $lines = explode("\n", $code); - $codeLines = []; - $i = $start; + $i = $start; foreach ($lines as $codeLine) { if ($i == $line) { @@ -3158,7 +3170,9 @@ function lazyFactory(...$args) if ($closure instanceof Closure) { return lazy(function () use ($closure, $args) { - return instanciator()->makeClosure($closure, $args); + $params = array_merge([$closure], $args); + + return instanciator()->makeClosure(...$params); }); } @@ -6611,6 +6625,195 @@ function store(...$args) return null; } + /** + * @param string $key + * @param array ...$args + * + * @return bool|mixed|null + * + * @throws \ReflectionException + */ + function factorer(string $key, ...$args) + { + $value = array_shift($args); + + if (null === $value) { + if ($class = getCore('instances.' . $key)) { + $params = array_merge([$class], $args); + + return gi()->makeClosure(...$params); + } + } else { + if (is_callable($value)) { + setCore('instances.' . $key, $value); + + return true; + } + } + + return null; + } + + /** + * @param string $key + * @param array ...$args + * + * @return bool|mixed|null + * + * @throws \ReflectionException + */ + function factorOnce(string $key, ...$args) + { + $value = array_shift($args); + + if (null === $value) { + if ($singleton = getCore('singletons.' . $key)) { + return $singleton; + } + } else { + if (is_callable($value)) { + $params = array_merge([$value], $args); + $singleton = gi()->makeClosure(...$params); + setCore('singletons.' . $key, $singleton); + + return true; + } + } + + return null; + } + + function coreData(? array $core = null) + { + static $data = []; + + if (null === $core) { + return $data; + } + + $data = $core; + } + + /** + * @param string $key + * @param $value + */ + function setCore(string $key, $value) + { + $data = coreData(); + $k = 'core.' . $key; + $data[$k] = $value; + + coreData($data); + } + + /** + * @param string $key + * @param null $default + * @return mixed + */ + function getCore(string $key, $default = null) + { + $data = coreData(); + $k = 'core.' . $key; + + return isAke($data, $k, $default); + } + + /** + * @param string $key + * @return bool + */ + function hasCore(string $key): bool + { + $data = coreData(); + $k = 'core.' . $key; + + return 'octodummy' !== isAke($data, $k, 'octodummy'); + } + + /** + * @param string $key + * @return bool + */ + function delCore(string $key): bool + { + $status = hasCore($key); + + if (true === $status) { + $data = coreData(); + $k = 'core.' . $key; + unset($data[$k]); + coreData($data); + } + + return $status; + } + + /** + * @param string $key + * @param null $default + * + * @return mixed|null + */ + function pullCore(string $key, $default = null) + { + if (true === hasCore($key)) { + $value = getCore($key); + delCore($key); + + return $value; + } + + return $default; + } + + /** + * @param string $key + * @param int $by + * @return int + */ + function incrCore(string $key, $by = 1): int + { + $old = getCore($key, 0); + $new = $old + $by; + + setCore($key, $new); + + return $new; + } + + /** + * @param string $key + * @param int $by + * @return int + */ + function decrCore(string $key, $by = 1): int + { + $old = getCore($key, 0); + $new = $old - $by; + + setCore($key, $new); + + return $new; + } + + /** + * @param string $key + * @param $cb + * @return mixed + */ + function lazyCore(string $key, $cb = null) + { + $res = getCore($key, 'octodummy'); + + if ('octodummy' === $res) { + setCore($key, $res = is_callable($cb) ? $cb() : $cb); + } + + return $res; + } + /** * @param array ...$args * @return bool|mixed|null @@ -7911,11 +8114,16 @@ function forward($what, $method = 'get', callable $before = null, callable $afte /** * @param null $value + * @param callable|null * @return Nullable */ - function nullable($value = null) + function nullable($value = null, ?callable $callback = null) { - return new Nullable($value); + if (is_null($callback)) { + return new Nullable($value); + } elseif (!is_null($value)) { + return $callback($value); + } } /** diff --git a/lib/mvc.php b/lib/mvc.php new file mode 100644 index 0000000..049316e --- /dev/null +++ b/lib/mvc.php @@ -0,0 +1,38 @@ +call(...$params); + }; + + $return[$method] = $callback; + } + } + + return $return; + } + + /** + * @param Inflector $i + * @param string $a + * @return mixed|null|string|string[] + */ + public function testing(Inflector $i,string $a) + { + return $i::lower($a); + } +} \ No newline at end of file diff --git a/lib/parametermemory.php b/lib/parametermemory.php new file mode 100644 index 0000000..3ede0b7 --- /dev/null +++ b/lib/parametermemory.php @@ -0,0 +1,343 @@ +__instance = !$instance ? sha1(uuid() . uuid()) : $instance; + setCore('pm.parameters.' . $this->__instance, $parameters); + } + + /** + * Returns the parameters. + * + * @return array An array of parameters + */ + public function all() + { + return getCore('pm.parameters.' . $this->__instance, []); + } + + /** + * Returns the parameter keys. + * + * @return array An array of parameter keys + */ + public function keys() + { + return array_keys($this->all()); + } + + /** + * @param array $parameters + * + * @return Parameter + */ + public function replace(array $parameters = []): self + { + $params = $parameters; + setCore('pm.parameters.' . $this->__instance, $params); + + return $this; + } + + /** + * @param array $parameters + * + * @return Parameter + */ + public function add(array $parameters = []): self + { + $params = $this->all(); + $params = array_replace($params, $parameters); + setCore('pm.parameters.' . $this->__instance, $params); + + return $this; + } + + /** + * Returns a parameter by name. + * + * @param string $key The key + * @param mixed $default The default value if the parameter key does not exist + * + * @return mixed + */ + public function get($key, $default = null) + { + $params = $this->all(); + + return array_key_exists($key, $params) ? $params[$key] : $default; + } + + /** + * @param $key + * @return mixed + */ + public function __get($key) + { + if ('parameters' === $key) { + $key = 'pm.parameters.' . $this->__instance; + + return getCore($key, []); + } + + return $this->get($key); + } + + /** + * @param $key + * @param $value + * + * @return $this + */ + public function set($key, $value) + { + $params = $this->all(); + $params[$key] = $value; + setCore('pm.parameters.' . $this->__instance, $params); + + return $this; + } + + /** + * @param $key + * @param $value + */ + public function __set($key, $value) + { + if ('parameters' === $key) { + $key = 'pm.parameters.' . $this->__instance; + + setCore($key, $value); + } else { + $params = $this->all(); + $params[$key] = $value; + setCore('pm.parameters.' . $this->__instance, $params); + } + } + + /** + * Returns true if the parameter is defined. + * + * @param string $key The key + * + * @return bool true if the parameter exists, false otherwise + */ + public function has($key) + { + $params = $this->all(); + + return array_key_exists($key, $params); + } + + /** + * @param $key + * @return bool + */ + public function __isset($key) + { + if ('parameters' === $key) { + $key = 'pm.parameters.' . $this->__instance; + + return hasCore($key); + } + + return array_key_exists($key, $this->parameters); + } + + /** + * @param $key + * + * @return bool + */ + public function remove($key) + { + $params = $this->all(); + + $status = $this->has($key); + + unset($params[$key]); + + setCore('pm.parameters.' . $this->__instance, $params); + + return $status; + } + + /** + * @param $key + */ + public function __unset($key) + { + if ('parameters' === $key) { + $key = 'pm.parameters.' . $this->__instance; + + return delCore($key); + } + + unset($this->parameters[$key]); + } + + /** + * Returns the alphabetic characters of the parameter value. + * + * @param string $key The parameter key + * @param string $default The default value if the parameter key does not exist + * + * @return string The filtered value + */ + public function getAlpha($key, $default = '') + { + return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default)); + } + + /** + * Returns the alphabetic characters and digits of the parameter value. + * + * @param string $key The parameter key + * @param string $default The default value if the parameter key does not exist + * + * @return string The filtered value + */ + public function getAlnum($key, $default = '') + { + return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default)); + } + + /** + * Returns the digits of the parameter value. + * + * @param string $key The parameter key + * @param string $default The default value if the parameter key does not exist + * + * @return string The filtered value + */ + public function getDigits($key, $default = '') + { + return str_replace( + array('-', '+'), + '', + $this->filter( + $key, + $default, + FILTER_SANITIZE_NUMBER_INT + ) + ); + } + + /** + * Returns the parameter value converted to integer. + * + * @param string $key The parameter key + * @param int $default The default value if the parameter key does not exist + * + * @return int The filtered value + */ + public function getInt($key, $default = 0) + { + return (int) $this->get($key, $default); + } + + /** + * Returns the parameter value converted to boolean. + * + * @param string $key The parameter key + * @param mixed $default The default value if the parameter key does not exist + * + * @return bool The filtered value + */ + public function getBoolean($key, $default = false) + { + return $this->filter($key, $default, FILTER_VALIDATE_BOOLEAN); + } + + /** + * Filter key. + * + * @param string $key Key + * @param mixed $default Default = null + * @param int $filter FILTER_* constant + * @param mixed $options Filter options + * + * @see http://php.net/manual/en/function.filter-var.php + * + * @return mixed + */ + public function filter($key, $default = null, $filter = FILTER_DEFAULT, $options = []) + { + $value = $this->get($key, $default); + + if (!is_array($options) && $options) { + $options = array('flags' => $options); + } + + if (is_array($value) && !isset($options['flags'])) { + $options['flags'] = FILTER_REQUIRE_ARRAY; + } + + return filter_var($value, $filter, $options); + } + + /** + * Returns an iterator for parameters. + * + * @return \ArrayIterator An \ArrayIterator instance + */ + public function getIterator() + { + return new \ArrayIterator($this->all()); + } + + /** + * Returns the number of parameters. + * + * @return int The number of parameters + */ + public function count() + { + return count($this->all()); + } + + /** + * @param mixed $offset + * @return bool + */ + public function offsetExists($offset) + { + return $this->has($offset); + } + + /** + * @param mixed $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->get($offset); + } + + /** + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + $this->set($offset, $value); + } + + /** + * @param mixed $offset + */ + public function offsetUnset($offset) + { + $this->remove($offset); + } +} diff --git a/tests/EventsTest.php b/tests/EventsTest.php index eaf2685..48ab183 100644 --- a/tests/EventsTest.php +++ b/tests/EventsTest.php @@ -47,6 +47,7 @@ public function setUp() } /** + * @throws Exception * @throws ReflectionException */ public function testDispatcher() diff --git a/tests/SimpleTest.php b/tests/SimpleTest.php index aa951ae..6cd90de 100644 --- a/tests/SimpleTest.php +++ b/tests/SimpleTest.php @@ -1,7 +1,9 @@ assertSame('bar', $app['foo']); + $this->assertSame('bar', $app->foo); + $this->assertSame('bar', $app->foo()); + + $app->test(function (Inflector $i, $a) { + return $i::upper($a); + }); + + $app['baz'] = function ($x) { + return 10 * $x; + }; + + $this->assertSame('FOO', $app->test('foo')); + $this->assertSame('baz', $app->testing('BAZ')); + $this->assertSame(100, $app->baz(10)); + } + + /** + * @throws Exception + */ public function testLazyLoading() { + $this->factorOnce(Inflector::class, function () { + return new Inflector; + }); + + $this->assertSame($this->factorOnce(Inflector::class), $this->factorOnce(Inflector::class)); + + $this->factorer(Arrays::class, function () { + return new Arrays; + }); + + $this->assertNotSame($this->factorer(Arrays::class), $this->factorer(Arrays::class)); + + $this->lazyCore('foo', 'bar'); + $this->assertSame('bar', $this->lazyCore('foo')); + $this->assertSame('bar', $this->lazyCore('foo', 'baz')); + $this->delCore('foo'); + $this->assertNull($this->lazyCore('foo')); + $this->assertSame(1, $this->incrCore('bar')); + $this->assertSame(10, $this->incrCore('bar', 9)); + $this->assertSame(9, $this->decrCore('bar')); + $this->assertSame(1, $this->decrCore('bar', 8)); + $this->assertTrue($this->hasCore('bar')); + $this->assertTrue($this->appli('foo', 'bar')); $this->assertSame('bar', $this->appli('foo')); @@ -174,6 +225,7 @@ public function testLazyLoading() } /** + * @throws Exception * @throws ReflectionException */ public function testThrottle() @@ -192,6 +244,7 @@ public function testThrottle() } /** + * @throws Exception * @throws ReflectionException */ public function testYour()