diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/README.md b/README.md new file mode 100644 index 000000000..5e1f190b9 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Hyperf + +A coroutine framework that focuses on hyperspeed and flexibility, specifically used for build microservices or middlewares. + +- [中文文档](zh/README.md) +- [English](en/README.md) + diff --git a/composer.json b/composer.json deleted file mode 100644 index 9c027a3d9..000000000 --- a/composer.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "name": "hyperflex/hyperflex", - "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices or middlewares.", - "license": "Apache-2.0", - "keywords": [ - "php", - "swoole", - "hyperflex" - ], - "support": { - }, - "require": { - "php": ">=7.1", - "psr/http-server-middleware": "^1.0", - "psr/container": "^1.0", - "psr/log": "^1.0", - "psr/http-message": "^1.0.1", - "psr/http-server-middleware": "^1.0", - "fig/http-message-util": "^1.1.2", - "nikic/fast-route": "^1.3", - "nikic/php-parser": "^4.1", - "doctrine/annotations": "^1.6", - "doctrine/instantiator": "^1.0", - "php-di/phpdoc-reader": "^2.0.1", - "google/protobuf": "^3.6.1", - "grpc/grpc": "^1.15", - "symfony/finder": "^4.1", - "symfony/console": "^4.2", - "swoft/http-message": "^1.0" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0", - "php-di/php-di": "^6.0", - "doctrine/common": "@stable" - }, - "replace": { - "hyperflex/config": "self.version", - "hyperflex/di": "self.version", - "hyperflex/dispatcher": "self.version", - "hyperflex/grpc-server": "self.version", - "hyperflex/http-server": "self.version", - "hyperflex/framework": "self.version", - "hyperflex/memory": "self.version", - "hyperflex/utils": "self.version" - }, - "suggest": { - }, - "autoload": { - "files": [ - "src/utils/src/Functions.php" - ], - "psr-4": { - "Hyperflex\\Config\\": "src/config/src/", - "Hyperflex\\Di\\": "src/di/src/", - "Hyperflex\\Dispatcher\\": "src/dispatcher/src/", - "Hyperflex\\GrpcServer\\": "src/grpc-server/src/", - "Hyperflex\\HttpServer\\": "src/http-server/src/", - "Hyperflex\\Framework\\": "src/framework/src/", - "Hyperflex\\Memory\\": "src/memory/src/", - "Hyperflex\\Utils\\": "src/utils/src/" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": [ - "Hyperflex\\Config\\ConfigProvider", - "Hyperflex\\Di\\ConfigProvider", - "Hyperflex\\Dispatcher\\ConfigProvider", - "Hyperflex\\Framework\\ConfigProvider", - "Hyperflex\\GrpcServer\\ConfigProvider", - "Hyperflex\\HttpServer\\ConfigProvider", - "Hyperflex\\Memory\\ConfigProvider", - "Hyperflex\\Utils\\ConfigProvider" - ] - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - }, - "minimum-stability": "dev" -} diff --git a/en/README.md b/en/README.md new file mode 100644 index 000000000..93aea096a --- /dev/null +++ b/en/README.md @@ -0,0 +1,4 @@ +# Introduction + +[components](https://github.com/hyperf-cloud/hyperf) + diff --git a/en/amqp.md b/en/amqp.md new file mode 100644 index 000000000..1079d91b4 --- /dev/null +++ b/en/amqp.md @@ -0,0 +1,125 @@ +# AMQP + +[https://github.com/hyperf-cloud/amqp](https://github.com/hyperf-cloud/amqp) + +## Default Config +~~~php + [ + 'host' => 'localhost', + 'port' => 5672, + 'user' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + ], + 'params' => [ + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'connection_timeout' => 3.0, + 'read_write_timeout' => 3.0, + 'context' => null, + 'keepalive' => false, + 'heartbeat' => 0, + ], + ], +]; +~~~ + +## Deliver Message + +Use generator command to create a producer. +~~~ +php bin/hyperf.php gen:amqp-producer DemoProducer +~~~ + +We can modify the Producer annotation to replace exchange and routingKey. +Payloload is the data that is finally delivered to the message queue, so we can rewrite the _construct method easyly,just make sure payload is assigned. + +~~~php +first(); + $this->payload = [ + 'id' => $id, + 'data' => $user->toArray() + ]; + } +} + +~~~ + +Get the Producer instance through container, and you can deliver the message. It is not reasonable for the following examples to use Application Context directly to get the Producer. For the specific use of container, see the di module. + +~~~php +get(Producer::class); +$result = $producer->produce($message); + +~~~ + +## Consume Message + +Use generator command to create a consumer. +~~~ +php bin/hyperf.php gen:amqp-consumer DemoConsumer +~~~ + +we can modify the Consumer annotation to replace exchange, routingKey and queue. +And $data is parsed metadata. + +~~~php + [ + 'driver' => Hyperf\Cache\Driver\RedisDriver::class, + 'packer' => Hyperf\Cache\Packer\PhpSerializer::class, + ], +]; +~~~ + +## How to use + +Components provide Cacheable annotation to configure cache prefix, expiration times, listeners, and cache groups. +For example, UserService provides a user method to query user information. When the Cacheable annotation is added, the Redis cache is automatically generated with the key value of `user:id` and the timeout time of 9000 seconds. When querying for the first time, it will be fetched from DB, and when querying later, it will be fetched from Cache. + +~~~php +where('id',$id)->first(); + + if($user){ + return $user->toArray(); + } + + return null; + } +} +~~~ + +## Clear Cache + +Of course, if the data changes, how to delete the cache? Here we need to use the listener. Next, a new Service provides a way to help us deal with it. + +~~~php +dispatcher->dispatch(new DeleteListenerEvent('user-update', [$userId])); + + return true; + } +} +~~~ \ No newline at end of file diff --git a/en/core/README.md b/en/core/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/en/microservice/README.md b/en/microservice/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/en/model/README.md b/en/model/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/en/quick_start/README.md b/en/quick_start/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/en/quick_start/summary.md b/en/quick_start/summary.md new file mode 100644 index 000000000..e69de29bb diff --git a/index.html b/index.html new file mode 100644 index 000000000..64f88fd67 --- /dev/null +++ b/index.html @@ -0,0 +1,41 @@ + + + + + + Document + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/src/config/composer.json b/src/config/composer.json deleted file mode 100644 index 39c76eacf..000000000 --- a/src/config/composer.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "hyperflex/config", - "description": "An independent component that provide configuration container.", - "license": "Apache-2.0", - "keywords": [ - "php", - "swoole", - "hyperflex", - "config", - "configuration" - ], - "support": { - }, - "require": { - "php": ">=7.1", - "hyperflex/framework": "dev-master", - "hyperflex/utils": "dev-master" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0" - }, - "suggest": { - }, - "autoload": { - "files": [ - ], - "psr-4": { - "Hyperflex\\Config\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": "Hyperflex\\Config\\ConfigProvider" - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - } -} diff --git a/src/config/src/Config.php b/src/config/src/Config.php deleted file mode 100644 index 89ff15acc..000000000 --- a/src/config/src/Config.php +++ /dev/null @@ -1,62 +0,0 @@ -configs = $configs; - } - - /** - * Finds an entry of the container by its identifier and returns it. - * - * @param string $key Identifier of the entry to look for. - * @param mixed $default Default value of the entry when does not found. - * @return mixed Entry. - */ - public function get(string $key, $default = null) - { - return Arr::get($this->configs, $key, $default); - } - - /** - * Returns true if the container can return an entry for the given identifier. - * Returns false otherwise. - * - * @param string $key Identifier of the entry to look for. - * @return bool - */ - public function has(string $key) - { - return Arr::has($this->configs, $key); - } - - /** - * Set a value to the container by its identifier. - * - * @param string $key Identifier of the entry to set. - * @param mixed $value The value that save to container. - * @return void - */ - public function set(string $key, $value) - { - Arr::set($this->configs, $key, $value); - } -} \ No newline at end of file diff --git a/src/config/src/ConfigFactory.php b/src/config/src/ConfigFactory.php deleted file mode 100644 index e1fe85561..000000000 --- a/src/config/src/ConfigFactory.php +++ /dev/null @@ -1,45 +0,0 @@ -readConfig($configPath . 'config.php'); - $serverConfig = $this->readConfig($configPath . 'server.php'); - $autoloadConfig = $this->readPaths([BASE_PATH . '/config/autoload']); - $merged = array_replace_recursive(ProviderConfig::load(), $serverConfig, $config, ...$autoloadConfig); - return new Config($merged); - } - - private function readConfig(string $configPath): array - { - $config = []; - if (file_exists($configPath) && is_readable($configPath)) { - $config = require $configPath; - } - return is_array($config) ? $config : []; - } - - private function readPaths(array $paths) - { - $configs = []; - $finder = new Finder(); - $finder->files()->in($paths)->name('*.php'); - foreach ($finder as $file) { - $configs[] = [ - $file->getBasename('.php') => require $file->getRealPath(), - ]; - } - return $configs; - } - -} \ No newline at end of file diff --git a/src/config/src/ConfigProvider.php b/src/config/src/ConfigProvider.php deleted file mode 100644 index 56aab636a..000000000 --- a/src/config/src/ConfigProvider.php +++ /dev/null @@ -1,25 +0,0 @@ - [ - ConfigInterface::class => ConfigFactory::class, - ], - 'scan' => [ - 'paths' => [ - 'vendor/hyperflex/config/src' - ] - ], - ]; - } - -} \ No newline at end of file diff --git a/src/config/src/ProviderConfig.php b/src/config/src/ProviderConfig.php deleted file mode 100644 index cafb5965a..000000000 --- a/src/config/src/ProviderConfig.php +++ /dev/null @@ -1,51 +0,0 @@ -=7.1", - "hyperflex/framework": "dev-master", - "nikic/php-parser": "^4.1", - "doctrine/annotations": "^1.6", - "symfony/finder": "^4.1", - "php-di/phpdoc-reader": "^2.0.1", - "doctrine/instantiator": "^1.0" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0" - }, - "suggest": { - }, - "autoload": { - "files": [ - ], - "psr-4": { - "Hyperflex\\Di\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": "Hyperflex\\Di\\ConfigProvider" - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - } -} diff --git a/src/di/src/Annotation/AbstractAnnotation.php b/src/di/src/Annotation/AbstractAnnotation.php deleted file mode 100644 index bb2dfb059..000000000 --- a/src/di/src/Annotation/AbstractAnnotation.php +++ /dev/null @@ -1,26 +0,0 @@ -value = $value; - } - - public function collect(string $className, ?string $target): void - { - if (isset($this->value)) { - AnnotationCollector::collectClass($className, static::class, $this->value); - } - } - -} \ No newline at end of file diff --git a/src/di/src/Annotation/AnnotationCollector.php b/src/di/src/Annotation/AnnotationCollector.php deleted file mode 100644 index 78c113071..000000000 --- a/src/di/src/Annotation/AnnotationCollector.php +++ /dev/null @@ -1,26 +0,0 @@ -instantiate($className); - switch ($instance) { - case $instance instanceof ArroundInterface: - AspectCollector::setArround($className, $instance->classes, $instance->annotations); - break; - } - } - } - -} \ No newline at end of file diff --git a/src/di/src/Annotation/AspectCollector.php b/src/di/src/Annotation/AspectCollector.php deleted file mode 100644 index d431c1d30..000000000 --- a/src/di/src/Annotation/AspectCollector.php +++ /dev/null @@ -1,31 +0,0 @@ -docReader = new PhpDocReader(); - } - - public function collect(string $className, ?string $target): void - { - if (! $this->value) { - $this->value = $this->docReader->getPropertyClass(ReflectionManager::reflectClass($className)->getProperty($target)); - } - if (isset($this->value)) { - AnnotationCollector::collectProperty($className, $target, static::class, $this->value); - } - } - - -} \ No newline at end of file diff --git a/src/di/src/Annotation/MetadataHolder.php b/src/di/src/Annotation/MetadataHolder.php deleted file mode 100644 index 40ba66581..000000000 --- a/src/di/src/Annotation/MetadataHolder.php +++ /dev/null @@ -1,47 +0,0 @@ -container[$key] ?? $default; - } - - /** - * Set the metadata to holder. - */ - public function set(string $key, $value): void - { - $this->container[$key] = $value; - } - - /** - * Serialize the all metadata to a string. - */ - public function serialize(): string - { - return serialize($this->container); - } - - /** - * Deserialize the serialized metadata and set the metadata to holder. - */ - public function deserialize(string $metadata): bool - { - $data = unserialize($metadata); - $this->container = $data; - return true; - } -} \ No newline at end of file diff --git a/src/di/src/Annotation/MetadataHolderInterface.php b/src/di/src/Annotation/MetadataHolderInterface.php deleted file mode 100644 index f500d4d89..000000000 --- a/src/di/src/Annotation/MetadataHolderInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -parser = new Ast(); - $this->ignoreAnnotations = $ignoreAnnotations; - - // TODO: this method is deprecated and will be removed in doctrine/annotations 2.0 - AnnotationRegistry::registerLoader('class_exists'); - } - - public function scan(array $paths) - { - $finder = new Finder(); - $finder->files()->in($paths)->name('*.php'); - - array_walk($this->ignoreAnnotations, function ($value) { - AnnotationReader::addGlobalIgnoredName($value); - }); - $reader = new AnnotationReader(); - $classColletion = []; - foreach ($finder as $file) { - try { - $stmts = $this->parser->parse($file->getContents()); - $className = $this->parser->parseClassByStmts($stmts); - if (! $className) { - continue; - } - AstCollector::set($className, $stmts); - $classColletion[] = $className; - } catch (\RuntimeException $e) { - continue; - } - } - // Because the annotation class should loaded before use it, so load file via $finder previous, and then parse annotation here. - foreach ($classColletion as $className) { - $reflectionClass = ReflectionManager::reflectClass($className); - $annotations = $reader->getClassAnnotations($reflectionClass); - foreach ($annotations as $annotation) { - if ($annotation instanceof AbstractAnnotation) { - $annotation->collect($className, null); - } - } - - $properties = $reflectionClass->getProperties(); - foreach ($properties as $property) { - $propertyAnnotations = $reader->getPropertyAnnotations($property); - if (! empty($propertyAnnotations)) { - foreach ($propertyAnnotations as $propertyAnnotation) { - $propertyAnnotation instanceof AnnotationInterface && $propertyAnnotation->collect($className, $property->getName()); - } - } - } - unset($classColletion); - } - } -} \ No newline at end of file diff --git a/src/di/src/Aop/ArroundInterface.php b/src/di/src/Aop/ArroundInterface.php deleted file mode 100644 index f6dcfc0d2..000000000 --- a/src/di/src/Aop/ArroundInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -astParser = $parserFactory->create(ParserFactory::ONLY_PHP7); - $this->printer = new Standard(); - } - - public function parse(string $code): ?array - { - return $this->astParser->parse($code); - } - - public function proxy(string $className, string $proxyClassName) - { - $stmts = AstCollector::get($className, value(function () use ($className) { - $code = $this->getCodeByClassName($className); - return $stmts = $this->astParser->parse($code); - })); - $traverser = new NodeTraverser(); - // @TODO Allow user modify or replace node vistor. - $traverser->addVisitor(new ProxyClassNameVistor($proxyClassName)); - $traverser->addVisitor(new ProxyCallVistor()); - $modifiedStmts = $traverser->traverse($stmts); - $code = $this->printer->prettyPrintFile($modifiedStmts); - return $code; - } - - public function parseClassByStmts(array $stmts): string - { - $namespace = $className = ''; - foreach ($stmts as $stmt) { - if ($stmt instanceof Namespace_) { - $namespace = $stmt->name->toString(); - foreach ($stmt->stmts as $node) { - if ($node instanceof Class_) { - $className = $node->name->toString(); - break; - } - } - } - } - return ($namespace && $className) ? $namespace . '\\' . $className : ''; - } - - private function getCodeByClassName(string $className) - { - $file = Composer::getLoader()->findFile($className); - if (! $file) { - return ''; - } - return file_get_contents($file); - } - - -} \ No newline at end of file diff --git a/src/di/src/Aop/AstCollector.php b/src/di/src/Aop/AstCollector.php deleted file mode 100644 index 27b960c1e..000000000 --- a/src/di/src/Aop/AstCollector.php +++ /dev/null @@ -1,16 +0,0 @@ -create(ParserFactory::ONLY_PHP7); - } - -} \ No newline at end of file diff --git a/src/di/src/Aop/Pipeline.php b/src/di/src/Aop/Pipeline.php deleted file mode 100644 index a5d99766d..000000000 --- a/src/di/src/Aop/Pipeline.php +++ /dev/null @@ -1,28 +0,0 @@ -container->get($pipe); - } - if (! $passable instanceof ProceedingJoinPoint) { - throw new InvalidDefinitionException('$passable must is a ProceedingJoinPoint object.'); - } - $passable->pipe = $stack; - return method_exists($pipe, $this->method) ? $pipe->{$this->method}($passable) : $pipe($passable); - }; - }; - } - - -} \ No newline at end of file diff --git a/src/di/src/Aop/ProceedingJoinPoint.php b/src/di/src/Aop/ProceedingJoinPoint.php deleted file mode 100644 index 17c102281..000000000 --- a/src/di/src/Aop/ProceedingJoinPoint.php +++ /dev/null @@ -1,73 +0,0 @@ -originalMethod = $originalMethod; - $this->className = $className; - $this->method = $method; - $this->arguments = $arguments; - } - - public function process() - { - $closure = $this->pipe; - return $closure($this); - } - - public function processOriginalMethod() - { - $this->pipe = null; - $closure = $this->originalMethod; - if (count($this->arguments['keys']) > 1) { - $arguments = value(function () { - $result = []; - foreach ($this->arguments['order'] as $order) { - $result[] = $this->arguments['keys'][$order]; - } - return $result; - }); - } else { - $arguments = array_values($this->arguments['keys']); - } - return $closure(...$arguments); - } - -} \ No newline at end of file diff --git a/src/di/src/Aop/ProxyCallVistor.php b/src/di/src/Aop/ProxyCallVistor.php deleted file mode 100644 index fdf7743c5..000000000 --- a/src/di/src/Aop/ProxyCallVistor.php +++ /dev/null @@ -1,216 +0,0 @@ -name->toCodeString(), - ]; - foreach ($namespace->stmts as $class) { - switch ($class) { - case $class instanceof Use_: - // Collect the namespace which the current class imported. - foreach ($class->uses as $classUse) { - $usedNamespace[] = $classUse->name->toCodeString(); - } - break; - case $class instanceof Class_: - $this->class = $class->name; - if ($class->extends) { - $this->extends = $class->extends; - } - // Determine if the current class has used the proxy trait. - foreach ($class->stmts as $subNode) { - if ($subNode instanceof TraitUse) { - /** @var Name $trait */ - foreach ($subNode->traits as $trait) { - if ($this->isMatchUseTrait($usedNamespace, $trait->toCodeString())) { - $this->useProxyTrait = true; - } - } - } - } - break; - } - } - } - } - - public function leaveNode(Node $node) - { - switch ($node) { - case $node instanceof ClassMethod: - if ($node->name->toString() === '__construct') { - return $node; - } - // Rewrite the method to proxy call method. - return $this->rewriteMethod($node); - break; - case $node instanceof Class_: - // Add use proxy traits. - $stmts = $node->stmts; - array_unshift($stmts, $this->buildProxyCallTraitUseStatement()); - $node->stmts = $stmts; - unset($stmts); - return $node; - break; - case $node instanceof StaticPropertyFetch && $this->extends: - // Rewrite parent::$staticProperty to ParentClass::$staticProperty. - if ($node->class->toString() === 'parent') { - $node->class = new Name($this->extends->toCodeString()); - return $node; - } - break; - } - } - - /** - * @param array $namespaces The namespaces that the current class imported. - * @param string $trait The full namespace of trait or the trait name. - */ - private function isMatchUseTrait(array $namespaces, string $trait): bool - { - // @TODO use $this->proxyTraits. - $proxyTrait = ProxyTrait::class; - $trait = ltrim($trait, '\\'); - if ($trait === $proxyTrait) { - return true; - } - foreach ($namespaces as $namespace) { - if (ltrim($namespace, '\\') . '\\' . $trait === $proxyTrait) { - return true; - } - } - return false; - } - - /** - * Build `use ProxyTrait;` - */ - private function buildProxyCallTraitUseStatement(): TraitUse - { - $traits = []; - foreach ($this->proxyTraits as $proxyTrait) { - if (! is_string($proxyTrait) || ! trait_exists($proxyTrait)) { - continue; - } - // Add backslash prefix if the proxy trait does not start with backslash. - $proxyTrait[0] !== '\\' && $proxyTrait = '\\' . $proxyTrait; - $traits[] = new Name($proxyTrait); - } - return new TraitUse($traits); - } - - /** - * Rewrite a normal class method to a proxy call method, - * include normal class method and static method. - */ - private function rewriteMethod(ClassMethod $node): ClassMethod - { - // Build the static proxy call method base on the original method. - $class = $this->class->toString(); - $node->stmts = [ - new Return_(new StaticCall(new Name('self'), '__proxyCall', [ - // OriginalClass::class - new ClassConstFetch(new Name($class), new Identifier('class')), - // __FUNCTION__ - new MagicConstFunction(), - // self::getParamMap(OriginalClass::class, __FUNCTION, func_get_args()) - new StaticCall(new Name('self'), 'getParamsMap', [ - new ClassConstFetch(new Name($class), new Identifier('class')), - new MagicConstFunction(), - new FuncCall(new Name('func_get_args')) - ]), - // A closure that wrapped original method code. - new Closure([ - 'uses' => $this->getParametersWithoutTypehint($node), - 'stmts' => $node->stmts, - ]), - ])) - ]; - return $node; - } - - /** - * Get the parameters of method, without parameter typehint. - */ - private function getParametersWithoutTypehint(ClassMethod $node): array - { - $parametersWithoutTypehint = value(function () use ($node) { - // Remove the parameter typehint, otherwise will cause syntax error. - $params = []; - foreach ($node->getParams() as $param) { - /** @var \PhpParser\Node\Param $param */ - // Should create a new param node, modify the original node will change the original status. - $newParam = clone $param; - $newParam->type = null; - $params[] = $newParam; - } - return $params; - }); - return $parametersWithoutTypehint; - } - -} \ No newline at end of file diff --git a/src/di/src/Aop/ProxyClassNameVistor.php b/src/di/src/Aop/ProxyClassNameVistor.php deleted file mode 100644 index f4c92eae5..000000000 --- a/src/di/src/Aop/ProxyClassNameVistor.php +++ /dev/null @@ -1,35 +0,0 @@ -proxyClassName = $proxyClassName; - } - - public function leaveNode(Node $node) - { - // Rewirte the class name and extends the original class. - if ($node instanceof Node\Stmt\Class_) { - $node->extends = $node->name; - $node->name = new Node\Identifier($this->proxyClassName); - return $node; - } - } - -} \ No newline at end of file diff --git a/src/di/src/Aop/ProxyTrait.php b/src/di/src/Aop/ProxyTrait.php deleted file mode 100644 index 7a190fe35..000000000 --- a/src/di/src/Aop/ProxyTrait.php +++ /dev/null @@ -1,84 +0,0 @@ - [], - 'order' => [], - ]; - $reflectMethod = ReflectionManager::reflectMethod($className, $method); - $reflectParameters = $reflectMethod->getParameters(); - foreach ($reflectParameters as $key => $reflectionParameter) { - $map['keys'][$reflectionParameter->getName()] = $args[$key]; - $map['order'][] = $reflectionParameter->getName(); - } - return $map; - } - - private static function handleArround(ProceedingJoinPoint $proceedingJoinPoint) - { - $arround = AspectCollector::get('arround'); - if ($aspects = self::isMatchClassName($arround['classes'] ?? [], $proceedingJoinPoint->className, $proceedingJoinPoint->method)) { - $pipeline = new Pipeline(Hyperflex::getContainer()); - return $pipeline->via('process')->through($aspects)->send($proceedingJoinPoint)->then(function (ProceedingJoinPoint $proceedingJoinPoint) { - return $proceedingJoinPoint->processOriginalMethod(); - }); - } else { - return $proceedingJoinPoint->processOriginalMethod(); - } - } - - private static function isMatchClassName(array $aspects, string $className, string $method) - { - // @TODO Handle wildcard character - $matchAspect = []; - foreach ($aspects as $aspect => $item) { - foreach ($item as $class) { - if (strpos($class, '::') !== false) { - [$expectedClass, $expectedMethod] = explode('::', $class); - if ($expectedClass === $className && $expectedMethod === $method) { - $matchAspect[] = $aspect; - break; - } - } else { - if ($class === $className) { - $matchAspect[] = $aspect; - break; - } - } - } - } - return $matchAspect; - } - -} \ No newline at end of file diff --git a/src/di/src/ConfigProvider.php b/src/di/src/ConfigProvider.php deleted file mode 100644 index 3a418e229..000000000 --- a/src/di/src/ConfigProvider.php +++ /dev/null @@ -1,29 +0,0 @@ - [ - Parser::class => AstParserFactory::class, - PrettyPrinterAbstract::class => Standard::class, - ], - 'scan' => [ - 'paths' => [ - "vendor/hyperflex/di/src" - ], - ], - ]; - } - -} \ No newline at end of file diff --git a/src/di/src/Container.php b/src/di/src/Container.php deleted file mode 100644 index 328a60377..000000000 --- a/src/di/src/Container.php +++ /dev/null @@ -1,192 +0,0 @@ -definitionSource = $definitionSource; - $this->definitionResolver = new ResolverDispatcher($this); - $this->proxyFactory = new ProxyFactory($this); - // Auto-register the container. - $this->resolvedEntries = [ - self::class => $this, - ContainerInterface::class => $this, - FactoryInterface::class => $this, - InvokerInterface::class => $this, - ]; - } - - - /** - * Build an entry of the container by its name. - * This method behave like get() except resolves the entry again every time. - * For example if the entry is a class then a new instance will be created each time. - * This method makes the container behave like a factory. - * - * @param string $name Entry name or a class name. - * @param array $parameters Optional parameters to use to build the entry. Use this to force specific parameters - * to specific values. Parameters not defined in this array will be resolved using - * the container. - * @throws InvalidArgumentException The name parameter must be of type string. - * @throws DependencyException Error while resolving the entry. - * @throws NotFoundException No entry found for the given name. - * @return mixed - */ - public function make(string $name, array $parameters = []) - { - // If the entry is already resolved we return it - if (isset($this->resolvedEntries[$name]) || array_key_exists($name, $this->resolvedEntries)) { - return $this->resolvedEntries[$name]; - } - - $definition = $this->getDefinition($name); - - if (! $definition) { - throw new NotFoundException("No entry or class found for '$name'"); - } - - return $this->resolveDefinition($name, $definition, $parameters); - } - - /** - * Finds an entry of the container by its identifier and returns it. - * - * @param string $name Identifier of the entry to look for. - * @throws NotFoundExceptionInterface No entry was found for **this** identifier. - * @throws ContainerExceptionInterface Error while retrieving the entry. - * @throws DependencyException Error while resolving the entry. - * @return mixed Entry. - */ - public function get($name) - { - $this->resolvedEntries[$name] = $value = $this->make($name); - return $value; - } - - /** - * Returns true if the container can return an entry for the given identifier. - * Returns false otherwise. - * `has($name)` returning true does not mean that `get($name)` will not throw an exception. - * It does however mean that `get($name)` will not throw a `NotFoundExceptionInterface`. - * - * @param string $name Identifier of the entry to look for. - * @return bool - */ - public function has($name) - { - if (! is_string($name)) { - throw new InvalidArgumentException(sprintf('The name parameter must be of type string, %s given', is_object($name) ? get_class($name) : gettype($name))); - } - - if (array_key_exists($name, $this->resolvedEntries)) { - return true; - } - - $definition = $this->getDefinition($name); - if ($definition === null) { - return false; - } - - return true; - } - - private function getDefinition(string $name) - { - // Local cache that avoids fetching the same definition twice - if (! array_key_exists($name, $this->fetchedDefinitions)) { - $this->fetchedDefinitions[$name] = $this->definitionSource->getDefinition($name); - } - - return $this->fetchedDefinitions[$name]; - } - - /** - * Resolves a definition. - * Checks for circular dependencies while resolving the definition. - * - * @throws DependencyException Error while resolving the entry. - * @return mixed - */ - private function resolveDefinition(string $entryName, DefinitionInterface $definition, array $parameters = []) - { - return $this->definitionResolver->resolve($definition, $parameters); - } - - protected function setDefinition(string $name, DefinitionInterface $definition) - { - // Clear existing entry if it exists - if (array_key_exists($name, $this->resolvedEntries)) { - unset($this->resolvedEntries[$name]); - } - $this->fetchedDefinitions = []; // Completely clear this local cache - - $this->definitionSource->addDefinition($definition); - } - - public function getProxyFactory(): ProxyFactory - { - return $this->proxyFactory; - } - - /** - * Init defined dependencies, not include dynamic definition. - * - * @throws DependencyException Error while resolving the entry. - */ - public function initDependencies(): void - { - $definitions = $this->definitionSource->getDefinitions(); - foreach ($definitions as $key => $definition) { - $this->get($key); - } - } -} \ No newline at end of file diff --git a/src/di/src/Definition/DefinitionInterface.php b/src/di/src/Definition/DefinitionInterface.php deleted file mode 100644 index 740a1fece..000000000 --- a/src/di/src/Definition/DefinitionInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -scanner = $scanner; - // Scan the specified paths and collect the ast and annotations. - $this->scan($scanDir); - $this->source = $this->normalizeSource($source); - } - - /** - * Returns the DI definition for the entry name. - * - * @return DefinitionInterface|null - */ - public function getDefinition(string $name): ?DefinitionInterface - { - if (! isset($this->source[$name])) { - $this->source[$name] = $this->autowire($name); - } - return $this->source[$name]; - } - - /** - * @return array Definitions indexed by their name. - */ - public function getDefinitions(): array - { - return $this->source; - } - - public function addDefinition(string $name, array $definition): self - { - $this->source[$name] = $definition; - return $this; - } - - public function clearDefinitions(): void - { - $this->source = []; - } - - /** - * Read the type-hinting from the parameters of the function. - */ - private function getParametersDefinition(ReflectionFunctionAbstract $constructor): array - { - $parameters = []; - - foreach ($constructor->getParameters() as $index => $parameter) { - // Skip optional parameters - if ($parameter->isOptional()) { - continue; - } - - $parameterClass = $parameter->getClass(); - - if ($parameterClass) { - $parameters[$index] = new Reference($parameterClass->getName()); - } - } - - return $parameters; - } - - /** - * Normaliaze the user definition source to a standard definition souce. - */ - private function normalizeSource(array $source): array - { - $definitions = []; - foreach ($source as $identifier => $definition) { - if (is_string($definition) && class_exists($definition)) { - if (method_exists($definition, '__invoke')) { - $definitions[$identifier] = new FactoryDefinition($identifier, $definition, []); - } else { - $definitions[$identifier] = $this->autowire($identifier, new ObjectDefinition($identifier, $definition)); - } - } elseif (is_array($definition) && is_callable($definition)) { - $definitions[$identifier] = new FactoryDefinition($identifier, $definition, []); - } - } - return $definitions; - } - - private function autowire(string $name, ObjectDefinition $definition = null): ObjectDefinition - { - $className = $definition ? $definition->getClassName() : $name; - if (! class_exists($className) && ! interface_exists($className)) { - return $definition; - } - - $definition = $definition ? : new ObjectDefinition($name); - - // Constructor - $class = ReflectionManager::reflectClass($className); - $constructor = $class->getConstructor(); - if ($constructor && $constructor->isPublic()) { - $constructorInjection = new MethodInjection('__construct', $this->getParametersDefinition($constructor)); - $definition->completeConstructorInjection($constructorInjection); - } - - // Properties - $propertiesMetadata = AnnotationCollector::get($className); - if (isset($propertiesMetadata['_p'])) { - foreach ($propertiesMetadata['_p'] as $propertyName => $value) { - if (! isset($value[Inject::class])) { - continue; - } - $propertyInjection = new PropertyInjection($propertyName, new Reference($value[Inject::class])); - $definition->addPropertyInjection($propertyInjection); - } - } - - if ($className === IndexController::class) { - $definition->setNeedProxy(true); - } - - return $definition; - - } - - private function scan(array $paths): bool - { - $pathsHash = md5(implode(',', $paths)); - if ($this->hasAvailableCache($paths, $pathsHash, $this->cachePath)) { - $this->printLn('Detected an available cache, skip the scan process.'); - list(, $annotationMetadata, $aspectMetadata) = explode(PHP_EOL, file_get_contents($this->cachePath)); - // Deserialize metadata when the cache is valid - AnnotationCollector::deserialize($annotationMetadata); - AspectCollector::deserialize($aspectMetadata); - return false; - } - $this->printLn('Scanning ...'); - $this->scanner->scan($paths); - if (! file_exists($this->cachePath)) { - $exploded = explode('/', $this->cachePath); - unset($exploded[count($exploded) - 1]); - $dirPath = implode('/', $exploded); - if (! is_dir($dirPath)) { - mkdir($dirPath, 0755, true); - } - } - $data = implode(PHP_EOL, [$pathsHash, AnnotationCollector::serialize(), AspectCollector::serialize()]); - file_put_contents($this->cachePath, $data); - $this->printLn('Scan completed.'); - return true; - } - - private function hasAvailableCache(array $paths, string $pathsHash, string $filename): bool - { - if (! file_exists($filename) || ! is_readable($filename)) { - return false; - } - $handler = fopen($filename, 'r'); - while (! feof($handler)) { - $line = fgets($handler); - if (trim($line) !== $pathsHash) { - return false; - } - break; - } - fclose($handler); - $cacheLastModified = filemtime($filename) ?? 0; - $finder = new Finder(); - $finder->files()->in($paths)->name('*.php'); - foreach ($finder as $file) { - if ($file->getMTime() > $cacheLastModified) { - return false; - } - } - return true; - } - - private function printLn(string $message): void - { - print_r($message . PHP_EOL); - } - -} \ No newline at end of file diff --git a/src/di/src/Definition/DefinitionSourceInterface.php b/src/di/src/Definition/DefinitionSourceInterface.php deleted file mode 100644 index 812217379..000000000 --- a/src/di/src/Definition/DefinitionSourceInterface.php +++ /dev/null @@ -1,31 +0,0 @@ -name = $name; - $this->factory = $factory; - $this->parameters = $parameters; - } - - public function getName(): string - { - return $this->name; - } - - public function setName(string $name): self - { - $this->name = $name; - return $this; - } - - /** - * @return callable|string - */ - public function getFactory() - { - return $this->factory; - } - - /** - * @return mixed[] - */ - public function getParameters(): array - { - return $this->parameters; - } - - public function getAst(): array - { - if (null === $this->ast) { - $this->ast = AstCollector::get($this->getFactory(), []); - } - return $this->ast; - } - - public function __toString(): string - { - return 'Factory'; - } - - /** - * Determine if the definition need to transfer to a proxy class. - */ - public function isNeedProxy(): bool - { - return $this->needProxy; - } - - public function setNeedProxy($needProxy): self - { - $this->needProxy = $needProxy; - return $this; - } -} \ No newline at end of file diff --git a/src/di/src/Definition/MethodInjection.php b/src/di/src/Definition/MethodInjection.php deleted file mode 100644 index f3be2e231..000000000 --- a/src/di/src/Definition/MethodInjection.php +++ /dev/null @@ -1,75 +0,0 @@ -parameters = $parameters; - $this->methodName = $methodName; - } - - public function getName(): string - { - return ''; - } - - public function setName(string $name) - { - // The name does not matter for method injections, so do nothing. - } - - /** - * @return mixed[] - */ - public function getParameters() : array - { - return $this->parameters; - } - - public function merge(self $definition) - { - // In case of conflicts, the current definition prevails. - $this->parameters = $this->parameters + $definition->parameters; - } - - public function __toString(): string - { - return sprintf('method(%s)', $this->methodName); - } - - /** - * Reset the target should be resolved. - * If it is the FactoryDefinition, then the target means $factory property, - * If it is the ObjectDefinition, then the target means $className property. - * - * @param mixed $value - */ - public function setTarget($value) - { - $this->methodName = $value; - } - - /** - * Determine if the definition need to transfer to a proxy class. - */ - public function isNeedProxy(): bool - { - // Method injection does not has proxy. - return false; - } -} \ No newline at end of file diff --git a/src/di/src/Definition/ObjectDefinition.php b/src/di/src/Definition/ObjectDefinition.php deleted file mode 100644 index 00d72a1a2..000000000 --- a/src/di/src/Definition/ObjectDefinition.php +++ /dev/null @@ -1,176 +0,0 @@ -name = $name; - $this->setClassName($className ?? $name); - } - - public function getName(): string - { - return $this->name; - } - - public function setName(string $name): self - { - $this->name = $name; - return $this; - } - - public function setClassName(string $className = null) - { - $this->className = $className; - - $this->updateCache(); - } - - public function getClassName(): string - { - if ($this->className !== null) { - return $this->className; - } - - return $this->name; - } - - public function isClassExists(): bool - { - return $this->classExists; - } - - public function isInstantiable(): bool - { - return $this->instantiable; - } - - /** - * @return \Hyperflex\Di\Definition\MethodInjection|null - */ - public function getConstructorInjection() - { - return $this->constructorInjection; - } - - public function setConstructorInjection(MethodInjection $injection) - { - $this->constructorInjection = $injection; - } - - public function completeConstructorInjection(MethodInjection $injection) - { - if ($this->constructorInjection !== null) { - // Merge - $this->constructorInjection->merge($injection); - } else { - // Set - $this->constructorInjection = $injection; - } - } - - /** - * @return PropertyInjection[] - */ - public function getPropertyInjections(): array - { - return $this->propertyInjections; - } - - public function addPropertyInjection(PropertyInjection $propertyInjection) - { - $this->propertyInjections[$propertyInjection->getPropertyName()] = $propertyInjection; - } - - public function getProxyClassName(): string - { - return $this->proxyClassName; - } - - public function setProxyClassName($proxyClassName): self - { - $this->proxyClassName = $proxyClassName; - return $this; - } - - private function updateCache() - { - $className = $this->getClassName(); - - $this->classExists = class_exists($className) || interface_exists($className); - - if (! $this->classExists) { - $this->instantiable = false; - return; - } - - $this->instantiable = ReflectionManager::reflectClass($className)->isInstantiable(); - } - - /** - * Determine if the definition need to transfer to a proxy class. - */ - public function isNeedProxy(): bool - { - return $this->needProxy; - } - - public function setNeedProxy($needProxy): self - { - $this->needProxy = $needProxy; - return $this; - } - - public function __toString(): string - { - return sprintf('Object[%s]' . $this->getClassName()); - } - -} \ No newline at end of file diff --git a/src/di/src/Definition/PropertyDefinition.php b/src/di/src/Definition/PropertyDefinition.php deleted file mode 100644 index 6a9c44ce4..000000000 --- a/src/di/src/Definition/PropertyDefinition.php +++ /dev/null @@ -1,93 +0,0 @@ -propertyName = $propertyName; - $this->value = $value; - $this->className = $className; - } - - - /** - * Returns the name of the entry in the container. - */ - public function getName(): string - { - return $this->propertyName; - } - - /** - * Set the name of the entry in the container. - */ - public function setName(string $name) - { - $this->propertyName = $name; - } - - /** - * @return mixed - */ - public function getValue() - { - return $this->value; - } - - /** - * @return string|null - */ - public function getClassName(): ?string - { - return $this->className; - } - - /** - * Determine if the definition need to transfer to a proxy class. - */ - public function isNeedProxy(): bool - { - return false; - } - - /** - * Definitions can be cast to string for debugging information. - */ - public function __toString(): string - { - return 'Property'; - } -} \ No newline at end of file diff --git a/src/di/src/Definition/PropertyInjection.php b/src/di/src/Definition/PropertyInjection.php deleted file mode 100644 index 2a5efd34d..000000000 --- a/src/di/src/Definition/PropertyInjection.php +++ /dev/null @@ -1,45 +0,0 @@ -propertyName = $propertyName; - $this->value = $value; - } - - public function getPropertyName() : string - { - return $this->propertyName; - } - - /** - * @return mixed Value that should be injected in the property - */ - public function getValue() - { - return $this->value; - } - -} diff --git a/src/di/src/Definition/Reference.php b/src/di/src/Definition/Reference.php deleted file mode 100644 index e228841ab..000000000 --- a/src/di/src/Definition/Reference.php +++ /dev/null @@ -1,87 +0,0 @@ -targetEntryName = $targetEntryName; - } - - /** - * Returns the name of the entry in the container. - */ - public function getName(): string - { - return $this->name; - } - - /** - * Set the name of the entry in the container. - */ - public function setName(string $name) - { - $this->name = $name; - } - - public function getTargetEntryName(): string - { - return $this->targetEntryName; - } - - public function resolve(ContainerInterface $container) - { - return $container->get($this->getTargetEntryName()); - } - - public function isResolvable(ContainerInterface $container): bool - { - return $container->has($this->getTargetEntryName()); - } - - /** - * Definitions can be cast to string for debugging information. - */ - public function __toString(): string - { - return sprintf('get(%s)', $this->targetEntryName); - } - - /** - * Determine if the definition need to transfer to a proxy class. - */ - public function isNeedProxy(): bool - { - return $this->needProxy; - } - - public function setNeedProxy($needProxy): self - { - $this->needProxy = $needProxy; - return $this; - } -} \ No newline at end of file diff --git a/src/di/src/Definition/SelfResolvingDefinitionInterface.php b/src/di/src/Definition/SelfResolvingDefinitionInterface.php deleted file mode 100644 index ea6cafe7e..000000000 --- a/src/di/src/Definition/SelfResolvingDefinitionInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -getParameters(); - $definitions = []; - foreach ($parameters as $parameter) { - $type = $parameter->getType()->getName(); - switch ($type) { - case 'int': - case 'float': - case 'string': - $definitions[] = [ - 'type' => $type, - 'name' => $parameter->getName(), - 'ref' => '', - 'allowsNull' => $parameter->allowsNull(), - ]; - break; - case 'bool': - $definitions[] = [ - 'type' => $type, - 'name' => $parameter->getName(), - 'ref' => '', - 'allowsNull' => $parameter->allowsNull(), - ]; - break; - default: - // Object - $definitions[] = [ - 'type' => 'object', - 'name' => $parameter->getName(), - 'ref' => $parameter->getClass()->getName() ?? null, - 'allowsNull' => $parameter->allowsNull(), - ]; - break; - } - } - static::set($key, $definitions); - return $definitions; - } - -} \ No newline at end of file diff --git a/src/di/src/ProxyFactory.php b/src/di/src/ProxyFactory.php deleted file mode 100644 index 2c891e91f..000000000 --- a/src/di/src/ProxyFactory.php +++ /dev/null @@ -1,77 +0,0 @@ -create(ParserFactory::ONLY_PHP7); - $this->ast = new Ast($astParser, new Standard()); - } - - public function createProxyDefinition(ObjectDefinition $definition): ObjectDefinition - { - $identifier = $definition->getName(); - if (isset(static::$map[$identifier])) { - return static::$map[$identifier]; - } - $proxyIdentifier = null; - if ($definition instanceof FactoryDefinition) { - $proxyIdentifier = $definition->getFactory() . '_' . md5($definition->getFactory()); - $proxyIdentifier && $definition->setTarget($proxyIdentifier); - $this->loadProxy($definition->getName(), $definition->getFactory()); - } elseif ($definition instanceof ObjectDefinition) { - $proxyIdentifier = $definition->getClassName() . '_' . md5($definition->getClassName()); - $definition->setProxyClassName($proxyIdentifier); - $this->loadProxy($definition->getClassName(), $definition->getProxyClassName()); - } - static::$map[$identifier] = $definition; - return static::$map[$identifier]; - } - - private function loadProxy(string $className, string $proxyClassName) - { - $dir = BASE_PATH . '/runtime/container/proxy/'; - if (! file_exists($dir)) { - mkdir($dir, 0755, true); - } - $proxyFileName = str_replace('\\', '_', $proxyClassName); - $path = $dir . $proxyFileName . '.proxy.php'; - - $key = md5($path); - if (CoroutineLocker::lock($key)) { - // @TODO handle unlink mechanism. - @unlink($path); - if (! file_exists($path)) { - $this->createProxyFile($path, $className, $proxyClassName); - } - include_once $path; - CoroutineLocker::unlock($key); - } - } - - private function createProxyFile(string $path, string $className, string $proxyClassName) - { - $code = $this->ast->proxy($className, $proxyClassName); - file_put_contents($path, $code); - } -} \ No newline at end of file diff --git a/src/di/src/ReflectionManager.php b/src/di/src/ReflectionManager.php deleted file mode 100644 index de2a1f5dd..000000000 --- a/src/di/src/ReflectionManager.php +++ /dev/null @@ -1,60 +0,0 @@ -getMethod($method); - } - return static::$container['method'][$key]; - } - - public static function reflectProperty(string $className, string $property): ReflectionProperty - { - $key = $className . '::' . $property; - if (! isset(static::$container['property'][$key])) { - if (! class_exists($className)) { - throw new InvalidArgumentException("Class $className not exist"); - } - static::$container['property'][$key] = static::reflectClass($className)->getProperty($property); - } - return static::$container['property'][$key]; - } - - public static function clear() - { - static::$container = []; - } - -} \ No newline at end of file diff --git a/src/di/src/Resolver/FactoryResolver.php b/src/di/src/Resolver/FactoryResolver.php deleted file mode 100644 index bac697b42..000000000 --- a/src/di/src/Resolver/FactoryResolver.php +++ /dev/null @@ -1,88 +0,0 @@ -container = $container; - $this->resolver = $resolver; - } - - /** - * Resolve a factory definition to a value. - * - * @param FactoryDefinition $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * @throws InvalidDefinitionException If the definition cannot be resolved. - * @return mixed Value obtained from the definition. - */ - public function resolve(DefinitionInterface $definition, array $parameters = []) - { - $callable = null; - try { - $callable = $definition->getFactory(); - if (! method_exists($callable, '__invoke')) { - throw new NotCallableException(); - } - if (is_string($callable)) { - $callable = $this->container->get($callable); - $object = $callable($this->container); - } else { - $object = call($callable, [$this->container]); - } - - return $object; - } catch (NotCallableException $e) { - // Custom error message to help debugging - if (is_string($callable) && class_exists($callable) && method_exists($callable, '__invoke')) { - throw new InvalidDefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s. Invokable classes cannot be automatically resolved if autowiring is disabled on the container, you need to enable autowiring or define the entry manually.', $definition->getName(), $e->getMessage())); - } - - throw new InvalidDefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s', $definition->getName(), $e->getMessage())); - } - } - - /** - * Check if a definition can be resolved. - * - * @param DefinitionInterface $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * @return bool - */ - public function isResolvable(DefinitionInterface $definition, array $parameters = []): bool - { - return true; - } -} \ No newline at end of file diff --git a/src/di/src/Resolver/ObjectResolver.php b/src/di/src/Resolver/ObjectResolver.php deleted file mode 100644 index 0506cc18f..000000000 --- a/src/di/src/Resolver/ObjectResolver.php +++ /dev/null @@ -1,138 +0,0 @@ -container = $container; - $this->definitionResolver = $definitionResolver; - $this->proxyFactory = $container->getProxyFactory(); - $this->parameterResolver = new ParameterResolver($definitionResolver); - } - - - /** - * Resolve a definition to a value. - * - * @param DefinitionInterface $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * @return mixed Value obtained from the definition. - * @throws DependencyException - * @throws InvalidDefinitionException - */ - public function resolve(DefinitionInterface $definition, array $parameters = []) - { - return $this->createInstance($definition, $parameters); - } - - /** - * Check if a definition can be resolved. - * - * @param ObjectDefinition $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * @return bool - */ - public function isResolvable(DefinitionInterface $definition, array $parameters = []): bool - { - return $definition->isInstantiable(); - } - - private function createInstance(ObjectDefinition $definition, array $parameters) - { - // Check that the class is instantiable - if (! $definition->isInstantiable()) { - // Check that the class exists - if (! $definition->isClassExists()) { - throw InvalidDefinitionException::create($definition, sprintf('Entry "%s" cannot be resolved: the class doesn\'t exist', $definition->getName())); - } - - throw InvalidDefinitionException::create($definition, sprintf('Entry "%s" cannot be resolved: the class is not instantiable', $definition->getName())); - } - - $classReflection = null; - try { - $className = $definition->getClassName(); - if ($definition->isNeedProxy()) { - $definition = $this->proxyFactory->createProxyDefinition($definition); - $className = $definition->getProxyClassName(); - } - $classReflection = ReflectionManager::reflectClass($className); - $constructorInjection = $definition->getConstructorInjection(); - - $args = $this->parameterResolver->resolveParameters($constructorInjection, $classReflection->getConstructor(), $parameters); - $object = new $className(...$args); - $this->injectMethodsAndProperties($object, $definition); - } catch (NotFoundExceptionInterface $e) { - throw new DependencyException(sprintf('Error while injecting dependencies into %s: %s', $classReflection ? $classReflection->getName() : '', $e->getMessage()), 0, $e); - } catch (InvalidDefinitionException $e) { - throw InvalidDefinitionException::create($definition, sprintf('Entry "%s" cannot be resolved: %s', $definition->getName(), $e->getMessage())); - } - return $object; - } - - protected function injectMethodsAndProperties($object, ObjectDefinition $objectDefinition) - { - // Property injections - foreach ($objectDefinition->getPropertyInjections() as $propertyInjection) { - $this->injectProperty($object, $propertyInjection); - } - } - - private function injectProperty($object, PropertyInjection $propertyInjection) - { - $property = ReflectionManager::reflectProperty(get_class($object), $propertyInjection->getPropertyName()); - if ($property->isStatic()) { - return; - } - if (! $property->isPublic()) { - $property->setAccessible(true); - } - if (! $propertyInjection->getValue() instanceof Reference) { - return; - } - /** @var Reference $reference */ - $reference = $propertyInjection->getValue(); - $property->setValue($object, $this->container->get($reference->getTargetEntryName())); - } - -} \ No newline at end of file diff --git a/src/di/src/Resolver/ParameterResolver.php b/src/di/src/Resolver/ParameterResolver.php deleted file mode 100644 index 18ca27e63..000000000 --- a/src/di/src/Resolver/ParameterResolver.php +++ /dev/null @@ -1,88 +0,0 @@ -definitionResolver = $definitionResolver; - } - - public function resolveParameters( - MethodInjection $definition = null, - ReflectionMethod $method = null, - array $parameters = [] - ) { - $args = []; - if (! $method) { - return $args; - } - - $definitionParameters = $definition ? $definition->getParameters() : []; - foreach ($method->getParameters() as $index => $parameter) { - if (array_key_exists($parameter->getName(), $parameters)) { - $value = &$parameters[$parameter->getName()]; - } elseif (array_key_exists($index, $definitionParameters)) { - $value = &$definitionParameters[$index]; - } else { - if ($parameter->isDefaultValueAvailable() || $parameter->isOptional()) { - $args[] = $this->getParameterDefaultValue($parameter, $method); - continue; - } - throw new InvalidDefinitionException(sprintf( - 'Parameter $%s of %s has no value defined or guessable', - $parameter->getName(), - $this->getFunctionName($method) - )); - } - - // Nested definitions - if ($value instanceof DefinitionInterface) { - // If the container cannot produce the entry, we can use the default parameter value - if ($parameter->isOptional() && ! $this->definitionResolver->isResolvable($value)) { - $value = $this->getParameterDefaultValue($parameter, $method); - } else { - $value = $this->definitionResolver->resolve($value); - } - } - - $args[] = &$value; - } - - return $args; - } - - private function getParameterDefaultValue(ReflectionParameter $parameter, ReflectionMethod $function) - { - try { - return $parameter->getDefaultValue(); - } catch (\ReflectionException $e) { - throw new InvalidDefinitionException(sprintf( - 'The parameter "%s" of %s has no type defined or guessable. It has a default value, ' - . 'but the default value can\'t be read through Reflection because it is a PHP internal class.', - $parameter->getName(), - $this->getFunctionName($function) - )); - } - } - - private function getFunctionName(ReflectionMethod $method) : string - { - return $method->getName() . '()'; - } - -} \ No newline at end of file diff --git a/src/di/src/Resolver/ResolverDispatcher.php b/src/di/src/Resolver/ResolverDispatcher.php deleted file mode 100644 index 5c03c9fd2..000000000 --- a/src/di/src/Resolver/ResolverDispatcher.php +++ /dev/null @@ -1,95 +0,0 @@ -container = $container; - } - - /** - * Resolve a definition to a value. - * - * @param DefinitionInterface $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * @throws InvalidDefinition If the definition cannot be resolved. - * @return mixed Value obtained from the definition. - */ - public function resolve(DefinitionInterface $definition, array $parameters = []) - { - if ($definition instanceof SelfResolvingDefinitionInterface) { - return $definition->resolve($this->container); - } - - $resolver = $this->getDefinitionResolver($definition); - return $resolver->resolve($definition, $parameters); - } - - /** - * Check if a definition can be resolved. - * - * @param DefinitionInterface $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * @return bool - */ - public function isResolvable(DefinitionInterface $definition, array $parameters = []): bool - { - if ($definition instanceof SelfResolvingDefinitionInterface) { - return $definition->isResolvable($this->container); - } - - $resolver = $this->getDefinitionResolver($definition); - return $resolver->isResolvable($definition, $parameters); - } - - /** - * Returns a resolver capable of handling the given definition. - * - * @throws RuntimeException No definition resolver was found for this type of definition. - */ - private function getDefinitionResolver(DefinitionInterface $definition): ResolverInterface - { - switch (true) { - case $definition instanceof ObjectDefinition: - if (! $this->objectResolver) { - $this->objectResolver = new ObjectResolver($this->container, $this); - } - return $this->objectResolver; - case $definition instanceof FactoryDefinition: - if (! $this->factoryResolver) { - $this->factoryResolver = new FactoryResolver($this->container, $this); - } - return $this->factoryResolver; - default: - throw new RuntimeException('No definition resolver was configured for definition of type ' . get_class($definition)); - } - } - -} \ No newline at end of file diff --git a/src/di/src/Resolver/ResolverInterface.php b/src/di/src/Resolver/ResolverInterface.php deleted file mode 100644 index 165e573fe..000000000 --- a/src/di/src/Resolver/ResolverInterface.php +++ /dev/null @@ -1,31 +0,0 @@ -=7.1", - "psr/http-server-middleware": "^1.0", - "psr/container": "^1.0" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0" - }, - "suggest": { - }, - "autoload": { - "files": [ - ], - "psr-4": { - "Hyperflex\\Dispatcher\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "HyperflexTest\\Dispatcher\\": "test" - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": "Hyperflex\\Dispatcher\\ConfigProvider" - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - }, - "repositories": { - "packagist": { - "type": "composer", - "url": "https://packagist.laravel-china.org" - } - } -} diff --git a/src/dispatcher/composer.lock b/src/dispatcher/composer.lock deleted file mode 100644 index fac5f87db..000000000 --- a/src/dispatcher/composer.lock +++ /dev/null @@ -1,3173 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "c363d1a328b47d9ac65951b35b1fb49c", - "packages": [ - { - "name": "psr/container", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "time": "2017-02-14T16:28:37+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/http-server-handler", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-server-handler.git", - "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7", - "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.0", - "psr/http-message": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP server-side request handler", - "keywords": [ - "handler", - "http", - "http-interop", - "psr", - "psr-15", - "psr-7", - "request", - "response", - "server" - ], - "time": "2018-10-30T16:46:14+00:00" - }, - { - "name": "psr/http-server-middleware", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-server-middleware.git", - "reference": "ea17eb1fb2c8df6db919cc578451a8013c6a0ae5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/ea17eb1fb2c8df6db919cc578451a8013c6a0ae5", - "reference": "ea17eb1fb2c8df6db919cc578451a8013c6a0ae5", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.0", - "psr/http-message": "^1.0", - "psr/http-server-handler": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP server-side middleware", - "keywords": [ - "http", - "http-interop", - "middleware", - "psr", - "psr-15", - "psr-7", - "request", - "response" - ], - "time": "2018-01-22T17:08:31+00:00" - } - ], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2017-07-22T11:58:36+00:00" - }, - { - "name": "hamcrest/hamcrest-php", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", - "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^5.3|^7.0" - }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" - }, - "require-dev": { - "phpunit/php-file-iterator": "1.3.3", - "phpunit/phpunit": "~4.0", - "satooshi/php-coveralls": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "hamcrest" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD" - ], - "description": "This is the PHP port of Hamcrest Matchers", - "keywords": [ - "test" - ], - "time": "2016-01-20T08:20:44+00:00" - }, - { - "name": "hyperflex/coding-standard", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/hyperflex-cloud/coding-standard.git", - "reference": "69bedc347670cd2f06c9fb296bcc3dececb7c73d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hyperflex-cloud/coding-standard/zipball/69bedc347670cd2f06c9fb296bcc3dececb7c73d", - "reference": "69bedc347670cd2f06c9fb296bcc3dececb7c73d", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "squizlabs/php_codesniffer": "^2.7" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "Hyperflex coding standard", - "keywords": [ - "Coding Standard", - "hyperflex" - ], - "time": "2018-10-23T14:56:29+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "1.2", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", - "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ocramius/package-versions": "^1.2.0", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A wrapper for ocramius/package-versions to get pretty versions strings", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "time": "2018-06-13T13:22:40+00:00" - }, - { - "name": "malukenho/docheader", - "version": "0.1.7", - "source": { - "type": "git", - "url": "https://github.com/malukenho/docheader.git", - "reference": "3eb59f0621125c0dc40775f1bcc3206c37993703" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/malukenho/docheader/zipball/3eb59f0621125c0dc40775f1bcc3206c37993703", - "reference": "3eb59f0621125c0dc40775f1bcc3206c37993703", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "~5.5|^7.0", - "symfony/console": "~2.0 || ^3.0 || ^4.0", - "symfony/finder": "~2.0 || ^3.0 || ^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.7", - "squizlabs/php_codesniffer": "^2.8" - }, - "bin": [ - "bin/docheader" - ], - "type": "library", - "autoload": { - "psr-4": { - "DocHeader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jefersson Nathan", - "email": "malukenho@phpse.net" - } - ], - "description": "A small library to check header docs", - "homepage": "https://github.com/malukenho/docheader", - "keywords": [ - "Code style", - "code standard", - "license" - ], - "time": "2017-12-18T09:16:11+00:00" - }, - { - "name": "mockery/mockery", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/mockery/mockery.git", - "reference": "100633629bf76d57430b86b7098cd6beb996a35a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/100633629bf76d57430b86b7098cd6beb996a35a", - "reference": "100633629bf76d57430b86b7098cd6beb996a35a", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "hamcrest/hamcrest-php": "~2.0", - "lib-pcre": ">=7.0", - "php": ">=5.6.0" - }, - "require-dev": { - "phpunit/phpunit": "~5.7.10|~6.5|~7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Mockery": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "http://davedevelopment.co.uk" - } - ], - "description": "Mockery is a simple yet flexible PHP mock object framework", - "homepage": "https://github.com/mockery/mockery", - "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], - "time": "2018-10-02T21:52:37+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.8.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "time": "2018-06-11T23:09:50+00:00" - }, - { - "name": "nette/bootstrap", - "version": "v2.4.6", - "source": { - "type": "git", - "url": "https://github.com/nette/bootstrap.git", - "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", - "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "nette/di": "~2.4.7", - "nette/utils": "~2.4", - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" - }, - "require-dev": { - "latte/latte": "~2.2", - "nette/application": "~2.3", - "nette/caching": "~2.3", - "nette/database": "~2.3", - "nette/forms": "~2.3", - "nette/http": "~2.4.0", - "nette/mail": "~2.3", - "nette/robot-loader": "^2.4.2 || ^3.0", - "nette/safe-stream": "~2.2", - "nette/security": "~2.3", - "nette/tester": "~2.0", - "tracy/tracy": "^2.4.1" - }, - "suggest": { - "nette/robot-loader": "to use Configurator::createRobotLoader()", - "tracy/tracy": "to use Configurator::enableTracy()" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", - "homepage": "https://nette.org", - "keywords": [ - "bootstrapping", - "configurator", - "nette" - ], - "time": "2018-05-17T12:52:20+00:00" - }, - { - "name": "nette/di", - "version": "v2.4.14", - "source": { - "type": "git", - "url": "https://github.com/nette/di.git", - "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/di/zipball/923da3e2c0aa53162ef455472c0ac7787b096c5a", - "reference": "923da3e2c0aa53162ef455472c0ac7787b096c5a", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-tokenizer": "*", - "nette/neon": "^2.3.3 || ~3.0.0", - "nette/php-generator": "^2.6.1 || ~3.0.0", - "nette/utils": "^2.4.3 || ~3.0.0", - "php": ">=5.6.0" - }, - "conflict": { - "nette/bootstrap": "<2.4", - "nette/nette": "<2.2" - }, - "require-dev": { - "nette/tester": "^2.0", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", - "homepage": "https://nette.org", - "keywords": [ - "compiled", - "di", - "dic", - "factory", - "ioc", - "nette", - "static" - ], - "time": "2018-09-17T15:47:40+00:00" - }, - { - "name": "nette/finder", - "version": "v2.4.2", - "source": { - "type": "git", - "url": "https://github.com/nette/finder.git", - "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0", - "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "nette/utils": "~2.4", - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" - }, - "require-dev": { - "nette/tester": "~2.0", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🔍 Nette Finder: find files and directories with an intuitive API.", - "homepage": "https://nette.org", - "keywords": [ - "filesystem", - "glob", - "iterator", - "nette" - ], - "time": "2018-06-28T11:49:23+00:00" - }, - { - "name": "nette/neon", - "version": "v2.4.3", - "source": { - "type": "git", - "url": "https://github.com/nette/neon.git", - "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/neon/zipball/5e72b1dd3e2d34f0863c5561139a19df6a1ef398", - "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-iconv": "*", - "ext-json": "*", - "php": ">=5.6.0" - }, - "require-dev": { - "nette/tester": "~2.0", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🍸 Nette NEON: encodes and decodes NEON file format.", - "homepage": "http://ne-on.org", - "keywords": [ - "export", - "import", - "neon", - "nette", - "yaml" - ], - "time": "2018-03-21T12:12:21+00:00" - }, - { - "name": "nette/php-generator", - "version": "v3.0.5", - "source": { - "type": "git", - "url": "https://github.com/nette/php-generator.git", - "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/ea90209c2e8a7cd087b2742ca553c047a8df5eff", - "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "nette/utils": "^2.4.2 || ~3.0.0", - "php": ">=7.0" - }, - "conflict": { - "nette/nette": "<2.2" - }, - "require-dev": { - "nette/tester": "^2.0", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.", - "homepage": "https://nette.org", - "keywords": [ - "code", - "nette", - "php", - "scaffolding" - ], - "time": "2018-08-09T14:32:27+00:00" - }, - { - "name": "nette/robot-loader", - "version": "v3.1.0", - "source": { - "type": "git", - "url": "https://github.com/nette/robot-loader.git", - "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/robot-loader/zipball/fc76c70e740b10f091e502b2e393d0be912f38d4", - "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-tokenizer": "*", - "nette/finder": "^2.3 || ^3.0", - "nette/utils": "^2.4 || ^3.0", - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" - }, - "require-dev": { - "nette/tester": "^2.0", - "tracy/tracy": "^2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", - "homepage": "https://nette.org", - "keywords": [ - "autoload", - "class", - "interface", - "nette", - "trait" - ], - "time": "2018-08-13T14:19:06+00:00" - }, - { - "name": "nette/utils", - "version": "v2.5.3", - "source": { - "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/17b9f76f2abd0c943adfb556e56f2165460b15ce", - "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.6.0" - }, - "conflict": { - "nette/nette": "<2.2" - }, - "require-dev": { - "nette/tester": "~2.0", - "tracy/tracy": "^2.3" - }, - "suggest": { - "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize() and toAscii()", - "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", - "ext-json": "to use Nette\\Utils\\Json", - "ext-mbstring": "to use Strings::lower() etc...", - "ext-xml": "to use Strings::length() etc. when mbstring is not available" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ], - "files": [ - "src/loader.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", - "homepage": "https://nette.org", - "keywords": [ - "array", - "core", - "datetime", - "images", - "json", - "nette", - "paginator", - "password", - "slugify", - "string", - "unicode", - "utf-8", - "utility", - "validation" - ], - "time": "2018-09-18T10:22:16+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v3.1.5", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", - "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "time": "2018-02-28T20:30:58+00:00" - }, - { - "name": "ocramius/package-versions", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "composer-plugin-api": "^1.0.0", - "php": "^7.1.0" - }, - "require-dev": { - "composer/composer": "^1.6.3", - "ext-zip": "*", - "infection/infection": "^0.7.1", - "phpunit/phpunit": "^7.0.0" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "time": "2018-02-05T13:05:30+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2018-07-08T19:23:20+00:00" - }, - { - "name": "phar-io/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2018-07-08T19:19:57+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2017-09-11T18:02:19+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "time": "2017-07-14T14:27:02+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.8.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2018-08-05T17:53:17+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "0.2", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "02f909f134fe06f0cd4790d8627ee24efbe84d6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/02f909f134fe06f0cd4790d8627ee24efbe84d6a", - "reference": "02f909f134fe06f0cd4790d8627ee24efbe84d6a", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "~7.0" - }, - "require-dev": { - "consistence/coding-standard": "^2.0.0", - "jakub-onderka/php-parallel-lint": "^0.9.2", - "phing/phing": "^2.16.0", - "phpstan/phpstan": "^0.9", - "phpunit/phpunit": "^6.3", - "slevomat/coding-standard": "^3.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.1-dev" - } - }, - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "time": "2018-01-13T18:19:41+00:00" - }, - { - "name": "phpstan/phpstan", - "version": "0.9.2", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "e59541bcc7cac9b35ca54db6365bf377baf4a488" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e59541bcc7cac9b35ca54db6365bf377baf4a488", - "reference": "e59541bcc7cac9b35ca54db6365bf377baf4a488", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "jean85/pretty-package-versions": "^1.0.3", - "nette/bootstrap": "^2.4 || ^3.0", - "nette/di": "^2.4.7 || ^3.0", - "nette/robot-loader": "^3.0.1", - "nette/utils": "^2.4.5 || ^3.0", - "nikic/php-parser": "^3.1", - "php": "~7.0", - "phpstan/phpdoc-parser": "^0.2", - "symfony/console": "~3.2 || ~4.0", - "symfony/finder": "~3.2 || ~4.0" - }, - "require-dev": { - "consistence/coding-standard": "2.2.1", - "ext-gd": "*", - "ext-intl": "*", - "ext-mysqli": "*", - "jakub-onderka/php-parallel-lint": "^0.9.2", - "phing/phing": "^2.16.0", - "phpstan/phpstan-php-parser": "^0.9", - "phpstan/phpstan-phpunit": "^0.9.3", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^6.5.4", - "slevomat/coding-standard": "4.0.0" - }, - "bin": [ - "bin/phpstan" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9-dev" - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": [ - "src/", - "build/PHPStan" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "time": "2018-01-28T13:22:19+00:00" - }, - { - "name": "phpstan/phpstan-strict-rules", - "version": "0.9", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "15be9090622c6b85c079922308f831018d8d9e23" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/15be9090622c6b85c079922308f831018d8d9e23", - "reference": "15be9090622c6b85c079922308f831018d8d9e23", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "~7.0", - "phpstan/phpstan": "^0.9" - }, - "require-dev": { - "consistence/coding-standard": "^2.0.0", - "jakub-onderka/php-parallel-lint": "^0.9.2", - "phing/phing": "^2.16.0", - "phpstan/phpstan-phpunit": "^0.9", - "phpunit/phpunit": "^6.4", - "slevomat/coding-standard": "^3.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9-dev" - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Extra strict and opinionated rules for PHPStan", - "time": "2017-11-26T20:12:30+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "6.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1 || ^4.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "suggest": { - "ext-xdebug": "^2.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2018-10-31T16:06:48+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2018-09-13T20:33:42+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2018-02-01T13:07:23+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", - "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2018-10-30T05:52:18+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "7.4.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b1be2c8530c4c29c3519a052c9fb6cee55053bbd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b1be2c8530c4c29c3519a052c9fb6cee55053bbd", - "reference": "b1be2c8530c4c29c3519a052c9fb6cee55053bbd", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "doctrine/instantiator": "^1.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.2", - "phar-io/version": "^2.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.0", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^3.1 || ^4.0", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2018-11-14T16:52:02+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" - }, - { - "name": "sebastian/comparator", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2018-07-12T15:12:46+00:00" - }, - { - "name": "sebastian/diff", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "366541b989927187c4ca70490a35615d3fef2dce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", - "reference": "366541b989927187c4ca70490a35615d3fef2dce", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0", - "symfony/process": "^2 || ^3.3 || ^4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "time": "2018-06-10T07:54:39+00:00" - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2017-07-01T08:51:00+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2017-04-03T13:19:02+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "2.9.2", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "bin": [ - "scripts/phpcs", - "scripts/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Fixer.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2018-11-07T22:31:41+00:00" - }, - { - "name": "symfony/console", - "version": "v4.1.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1.3", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/process": "<3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0" - }, - "suggest": { - "psr/log-implementation": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2018-10-31T09:30:44+00:00" - }, - { - "name": "symfony/finder", - "version": "v4.1.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/1f17195b44543017a9c9b2d437c670627e96ad06", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.1.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com", - "time": "2018-10-03T08:47:56+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.10.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2018-09-21T13:07:52+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a", - "shasum": "", - "mirrors": [ - { - "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2018-01-29T19:49:41+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=7.1" - }, - "platform-dev": [] -} diff --git a/src/dispatcher/phpunit.xml b/src/dispatcher/phpunit.xml deleted file mode 100644 index ea39ed69e..000000000 --- a/src/dispatcher/phpunit.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - ./test - - - - - ./src - - - diff --git a/src/dispatcher/src/AbstractDispatcher.php b/src/dispatcher/src/AbstractDispatcher.php deleted file mode 100644 index 0189eb17d..000000000 --- a/src/dispatcher/src/AbstractDispatcher.php +++ /dev/null @@ -1,18 +0,0 @@ -handle(...$params); - } - -} \ No newline at end of file diff --git a/src/dispatcher/src/ConfigProvider.php b/src/dispatcher/src/ConfigProvider.php deleted file mode 100644 index d3f3aa1f9..000000000 --- a/src/dispatcher/src/ConfigProvider.php +++ /dev/null @@ -1,23 +0,0 @@ - [ - - ], - 'scan' => [ - 'paths' => [ - "vendor/hyperflex/dispatcher/src" - ], - ], - ]; - } - -} \ No newline at end of file diff --git a/src/dispatcher/src/DispatcherInterface.php b/src/dispatcher/src/DispatcherInterface.php deleted file mode 100644 index 474fb0743..000000000 --- a/src/dispatcher/src/DispatcherInterface.php +++ /dev/null @@ -1,11 +0,0 @@ -container = $container; - } - - /** - * @inheritdoc - */ - public function dispatch(...$params): ResponseInterface - { - /** - * @var RequestInterface $request - * @var array $middlewares - * @var string $coreHandler - */ - [$request, $middlewares, $coreHandler] = $params; - $requestHandler = new HttpRequestHandler($middlewares, $coreHandler, $this->container); - $response = $requestHandler->handle($request); - return $response; - } -} \ No newline at end of file diff --git a/src/dispatcher/src/HttpRequestHandler.php b/src/dispatcher/src/HttpRequestHandler.php deleted file mode 100644 index f11fad00e..000000000 --- a/src/dispatcher/src/HttpRequestHandler.php +++ /dev/null @@ -1,61 +0,0 @@ -middlewares = array_unique($middlewares); - $this->coreHandler = $coreHandler; - $this->container = $container; - } - - /** - * Handles a request and produces a response. - * May call other collaborating code to generate the response. - */ - public function handle(ServerRequestInterface $request): ResponseInterface - { - if (! isset($this->middlewares[$this->offset]) && ! empty($this->coreHandler)) { - $handler = $this->container->get($this->coreHandler); - } else { - $handler = $this->middlewares[$this->offset]; - is_string($handler) && $handler = $this->container->get($handler); - } - if (! method_exists($handler, 'process')) { - throw new InvalidArgumentException(sprintf('Invalid middleware, it have to provide a process() method.')); - } - return $handler->process($request, $this->next()); - } - - private function next() - { - $this->offset++; - return $this; - } -} \ No newline at end of file diff --git a/src/dispatcher/test/HttpDispatcherTest.php b/src/dispatcher/test/HttpDispatcherTest.php deleted file mode 100644 index e8ca4fa3e..000000000 --- a/src/dispatcher/test/HttpDispatcherTest.php +++ /dev/null @@ -1,48 +0,0 @@ -container = $this->prophesize(ContainerInterface::class); - $this->request = $this->prophesize(ServerRequestInterface::class)->reveal(); - $this->response = $this->prophesize(ResponseInterface::class)->reveal(); - Context::set(ServerRequestInterface::class, $this->request); - Context::set(ResponseInterface::class, $this->response); - } - - public function testA() - { - $this->container->get(TestMiddleware::class)->willReturn(new TestMiddleware()); - $this->container->get(CoreMiddleware::class)->willReturn(new CoreMiddleware()); - $middlewares = [ - TestMiddleware::class, - ]; - $coreHandler = CoreMiddleware::class; - $dispatcher = new HttpDispatcher($middlewares, $coreHandler, $this->container->reveal()); - $this->assertInstanceOf(HttpDispatcher::class, $dispatcher); - $response = $dispatcher->dispatch($this->request, $this->response); - $this->assertInstanceOf(ResponseInterface::class, $response); - } - -} \ No newline at end of file diff --git a/src/dispatcher/test/Middlewares/CoreMiddleware.php b/src/dispatcher/test/Middlewares/CoreMiddleware.php deleted file mode 100644 index 43c712490..000000000 --- a/src/dispatcher/test/Middlewares/CoreMiddleware.php +++ /dev/null @@ -1,26 +0,0 @@ -withAddedHeader('Server', 'Hyperflex'); - return $response; - } -} \ No newline at end of file diff --git a/src/framework/.DS_Store b/src/framework/.DS_Store deleted file mode 100644 index 29a9bb624..000000000 Binary files a/src/framework/.DS_Store and /dev/null differ diff --git a/src/framework/composer.json b/src/framework/composer.json deleted file mode 100644 index 4728b7cea..000000000 --- a/src/framework/composer.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "hyperflex/framework", - "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.", - "license": "Apache-2.0", - "keywords": [ - "php", - "swoole", - "framework", - "hyperflex", - "microservice", - "middleware" - ], - "support": { - }, - "require": { - "php": ">=7.1", - "ext-swoole": ">=4.2", - "fig/http-message-util": "^1.1.2", - "psr/container": "^1.0", - "psr/http-message": "^1.0.1", - "psr/http-server-middleware": "^1.0", - "psr/log": "^1.0", - "symfony/console": "^4.2", - "symfony/routing": "^4.2", - "symfony/http-foundation": "^4.2", - "hyperflex/utils": "dev-master" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0", - "symfony/console": "^4.1", - "php-di/php-di": "^6.0", - "doctrine/common": "@stable" - }, - "suggest": { - }, - "autoload": { - "files": [ - ], - "psr-4": { - "Hyperflex\\Framework\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": "Hyperflex\\Framework\\ConfigProvider" - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - } -} diff --git a/src/framework/src/ApplicationFactory.php b/src/framework/src/ApplicationFactory.php deleted file mode 100644 index 0e9b282c5..000000000 --- a/src/framework/src/ApplicationFactory.php +++ /dev/null @@ -1,31 +0,0 @@ -get(ConfigInterface::class); - $commands = $config->get('commands', []); - $commands = array_replace($this->defaultCommands, $commands); - $application = new Application(); - foreach ($commands as $command) { - $application->add($container->get($command)); - } - return $application; - } - -} \ No newline at end of file diff --git a/src/framework/src/ApplicationInterface.php b/src/framework/src/ApplicationInterface.php deleted file mode 100644 index 6a42bf409..000000000 --- a/src/framework/src/ApplicationInterface.php +++ /dev/null @@ -1,10 +0,0 @@ -container = $container; - $this->server = $server; - } - - public function onStart(SwooleServer $server) - { - Memory\LockManager::initialize(SwooleEvent::ON_WORKER_START, SWOOLE_RWLOCK); - Memory\AtomicManager::initialize(SwooleEvent::ON_WORKER_START); - } - -} \ No newline at end of file diff --git a/src/framework/src/Bootstrap/WorkerStartCallback.php b/src/framework/src/Bootstrap/WorkerStartCallback.php deleted file mode 100644 index af5f43e8b..000000000 --- a/src/framework/src/Bootstrap/WorkerStartCallback.php +++ /dev/null @@ -1,61 +0,0 @@ -container = $container; - $this->logger = $logger; - } - - /** - * Handle Swoole onWorkerStart event. - */ - public function onWorkerStart(SwooleServer $server, int $workerId) - { - // Atomic and Lock have to initializes before worker start. - $atomic = AtomicManager::get(SwooleEvent::ON_WORKER_START); - $lock = LockManager::get(SwooleEvent::ON_WORKER_START); - $isScan = false; - $lockedWorkerId = null; - if ($lock->trylock()) { - $lockedWorkerId = $workerId; - // Only running in one worker. - $this->logger->debug("Worker $lockedWorkerId got the lock."); - // @TODO Do something that you want only one worker do. - $lock->unlock(); - $atomic->wakeup($server->setting['worker_num'] - 1); - } else { - $this->logger->debug("Worker $workerId wating ..."); - $atomic->wait(); - } - if (! $isScan || $workerId !== $lockedWorkerId) { - // @TODO Do something that the workers who does not got the lock should do. - } - $this->logger->info("Worker $workerId started."); - LockManager::clear(SwooleEvent::ON_WORKER_START); - AtomicManager::clear(SwooleEvent::ON_WORKER_START); - } - -} \ No newline at end of file diff --git a/src/framework/src/ConfigProvider.php b/src/framework/src/ConfigProvider.php deleted file mode 100644 index cb608e490..000000000 --- a/src/framework/src/ConfigProvider.php +++ /dev/null @@ -1,29 +0,0 @@ - [ - ApplicationInterface::class => ApplicationFactory::class, - StdoutLoggerInterface::class => StdoutLogger::class, - ], - 'scan'=>[ - 'paths'=>[ - 'vendor/hyperflex/framework/src' - ] - ] - ]; - } - -} \ No newline at end of file diff --git a/src/framework/src/Constants/SwooleEvent.php b/src/framework/src/Constants/SwooleEvent.php deleted file mode 100644 index 2c44b07df..000000000 --- a/src/framework/src/Constants/SwooleEvent.php +++ /dev/null @@ -1,11 +0,0 @@ - $definition) { - if (is_string($definition) && class_exists($definition)) { - if (method_exists($definition, '__invoke')) { - $definitions[$identifier] = factory($definition); - } else { - $definitions[$identifier] = autowire($definition); - } - } elseif (is_array($definition) && is_callable($definition)) { - $definitions[$identifier] = factory($definition); - } - } - return $definitions; - } - -} \ No newline at end of file diff --git a/src/framework/src/ExceptionHandler.php b/src/framework/src/ExceptionHandler.php deleted file mode 100644 index 191c83335..000000000 --- a/src/framework/src/ExceptionHandler.php +++ /dev/null @@ -1,51 +0,0 @@ -propagationStopped = true; - return $this->propagationStopped; - } - - /** - * Is propagation stopped ? - * This will typically only be used by the handler to determine if the - * provious handler halted propagation. - */ - public function isPropagationStopped(): bool - { - return $this->propagationStopped; - } - -} \ No newline at end of file diff --git a/src/framework/src/ExceptionHandlerDispatcher.php b/src/framework/src/ExceptionHandlerDispatcher.php deleted file mode 100644 index dc00992a5..000000000 --- a/src/framework/src/ExceptionHandlerDispatcher.php +++ /dev/null @@ -1,59 +0,0 @@ -container = $container; - } - - /** - * @inheritdoc - */ - public function dispatch(...$params): ResponseInterface - { - return parent::dispatch(...$params); - } - - /** - * @inheritdoc - */ - public function handle(...$params) - { - /** - * @var Throwable $throwable - * @var string[] $handlers - */ - [$throwable, $handlers] = $params; - $response = Context::get(ResponseInterface::class); - foreach ($handlers as $handler) { - if (! $this->container->has($handler)) { - throw new \InvalidArgumentException(sprintf('Invalid exception handler %s.', $handler)); - } - $handlerInstance = $this->container->get($handler); - if (! $handlerInstance instanceof ExceptionHandler || ! $handlerInstance->isValid($throwable)) { - continue; - } - $response = $handlerInstance->handle($throwable, $response); - if ($handlerInstance->isPropagationStopped()) { - break; - } - } - return $response; - } -} \ No newline at end of file diff --git a/src/framework/src/Hyperflex.php b/src/framework/src/Hyperflex.php deleted file mode 100644 index 9afeb3f05..000000000 --- a/src/framework/src/Hyperflex.php +++ /dev/null @@ -1,27 +0,0 @@ -config = $config; - } - - /** - * {@inheritDoc} - */ - public function emergency($message, array $context = []) - { - $this->log(LogLevel::EMERGENCY, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function alert($message, array $context = []) - { - $this->log(LogLevel::ALERT, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function critical($message, array $context = []) - { - $this->log(LogLevel::CRITICAL, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function error($message, array $context = []) - { - $this->log(LogLevel::ERROR, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function warning($message, array $context = []) - { - $this->log(LogLevel::WARNING, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function notice($message, array $context = []) - { - $this->log(LogLevel::NOTICE, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function info($message, array $context = []) - { - $this->log(LogLevel::INFO, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function debug($message, array $context = []) - { - $this->log(LogLevel::DEBUG, $message, $context); - } - - /** - * {@inheritDoc} - */ - public function log($level, $message, array $context = []) - { - $config = $this->config->get(StdoutLoggerInterface::class, ['log_level' => []]); - if (! in_array($level, $config['log_level'])) { - return; - } - foreach ($context as $key => $value) { - $search = sprintf('{%s}', $key); - $message = str_replace($search, $value, $message); - } - printf('%s%s', $message, PHP_EOL); - } - -} \ No newline at end of file diff --git a/src/framework/src/Server.php b/src/framework/src/Server.php deleted file mode 100644 index 0fa7906b9..000000000 --- a/src/framework/src/Server.php +++ /dev/null @@ -1,90 +0,0 @@ -container = $container; - } - - public function initConfigs(array $serverConfigs): self - { - foreach ($serverConfigs as $serverConfig) { - $server = $serverConfig['server']; - $constructor = $serverConfig['constructor']; - $callbacks = $serverConfig['callbacks']; - $settings = $serverConfig['settings'] ?? []; - if (! class_exists($server)) { - throw new \InvalidArgumentException('Server not exist.'); - } - if (! $this->server) { - $this->server = new $server(...$constructor); - $callbacks = array_replace($this->defaultCallbacks(), $callbacks); - $this->registerSwooleEvents($this->server, $callbacks); - $this->server->set($settings); - } else { - $slaveServer = $this->server->addlistener(...$constructor); - $this->registerSwooleEvents($slaveServer, $callbacks); - } - } - return $this; - } - - /** - * @param SwooleServer|Port $server - * @param array $events - */ - protected function registerSwooleEvents($server, array $events): void - { - foreach ($events as $event => $callback) { - if (is_array($callback)) { - $callback = [$this->container->get($callback[0]), $callback[1]]; - } - $server->on($event, $callback); - } - } - - public function run() - { - $this->server->start(); - } - - private function defaultCallbacks() - { - return [ - SwooleEvent::ON_WORKER_START => function (SwooleServer $server, int $workerId) { - printf('Worker %d started.' . PHP_EOL, $workerId); - }, - ]; - } - -} \ No newline at end of file diff --git a/src/framework/src/ServerRunner.php b/src/framework/src/ServerRunner.php deleted file mode 100644 index 687dd550a..000000000 --- a/src/framework/src/ServerRunner.php +++ /dev/null @@ -1,11 +0,0 @@ -=7.1", - "nikic/fast-route": "^1.3", - "hyperflex/framework": "dev-master", - "hyperflex/utils": "dev-master", - "hyperflex/http-server": "dev-master", - "google/protobuf": "^3.6.1", - "grpc/grpc": "^1.15" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0" - }, - "suggest": { - "ext-grpc": "grpc/grpc require grpc extension.", - "ext-protobuf": "For better performance, install the protobuf C extension." - }, - "autoload": { - "files": [ - ], - "psr-4": { - "Hyperflex\\GrpcServer\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": "Hyperflex\\GrpcServer\\ConfigProvider" - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - } -} diff --git a/src/grpc-server/src/ConfigProvider.php b/src/grpc-server/src/ConfigProvider.php deleted file mode 100644 index 6899377bc..000000000 --- a/src/grpc-server/src/ConfigProvider.php +++ /dev/null @@ -1,24 +0,0 @@ - [ - Server::class => ServerFactory::class, - Dispatcher::class => DispatcherFactory::class, - ], - 'scan' => [ - 'paths' => [ - "vendor/hyperflex/grpc-server/src" - ], - ], - ]; - } -} diff --git a/src/grpc-server/src/CoreMiddleware.php b/src/grpc-server/src/CoreMiddleware.php deleted file mode 100644 index e74228909..000000000 --- a/src/grpc-server/src/CoreMiddleware.php +++ /dev/null @@ -1,181 +0,0 @@ -container = $container; - $this->dispatcher = $container->get(GrpcDispatcher::class); - } - - /** - * Process an incoming server request and return a response, optionally delegating - * response creation to a handler. - */ - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface - { - /** @var ResponseInterface $response */ - $uri = $request->getUri(); - - /** - * @var array $routes - * Returns array with one of the following formats: - * [self::NOT_FOUND] - * [self::METHOD_NOT_ALLOWED, ['GET', 'OTHER_ALLOWED_METHODS']] - * [self::FOUND, $handler, ['varName' => 'value', ...]] - */ - $routes = $this->dispatcher->dispatch($request->getMethod(), $uri->getPath()); - switch ($routes[0]) { - case Dispatcher::FOUND: - [$controller, $action] = $this->prepareHandler($routes[1]); - $controllerInstance = $this->container->get($controller); - if (!method_exists($controller, $action)) { - $grpcMessage = sprintf('%s:%s is not implemented!', $controller, $action); - return $this->handleResponse(null, 500, '500', $grpcMessage); - } - $parameters = $this->parseParameters($controller, $action, $routes[2]); - $result = $controllerInstance->$action(...$parameters); - if (!$result instanceof Message) { - $grpcMessage = 'The result is not a valid message!'; - return $this->handleResponse(null, 500, '500', $grpcMessage); - } - - return $this->handleResponse($result, 200); - - case Dispatcher::NOT_FOUND: - case Dispatcher::METHOD_NOT_ALLOWED: - default: - return $this->handleResponse(null, 404, '404', 'Route Not Find!'); - } - } - - /** - * Transfer the non-standard response content to a standard response object. - * - * @param string|array $response - */ - protected function transferToResponse($response): ResponseInterface - { - if ($response instanceof Message) { - $body = Parser::serializeMessage($response); - $response = $this->response() - ->withAddedHeader('Content-Type', 'application/grpc') - ->withAddedHeader('trailer', 'grpc-status, grpc-message') - ->withBody(new SwooleStream($body)); - - $response->getSwooleResponse()->trailer('grpc-status', '0'); - $response->getSwooleResponse()->trailer('grpc-message', ''); - - return $response; - } - - if (is_string($response)) { - return $this->response()->withBody(new SwooleStream($response)); - } - - if (is_array($response)) { - return $this->response() - ->withAddedHeader('Content-Type', 'application/json') - ->withBody(new SwooleStream(json_encode($response))); - } - - return $this->response()->withBody(new SwooleStream((string)$response)); - } - - protected function parseParameters(string $controller, string $action, array $arguments): array - { - $injections = []; - $definitions = MethodDefinitionCollector::getOrParse($controller, $action); - - - foreach ($definitions ?? [] as $definition) { - if (!is_array($definition)) { - throw new \RuntimeException('Invalid method definition.'); - } - if (!isset($definition['type']) || !isset($definition['name'])) { - $injections[] = null; - continue; - } - $injections[] = value(function () use ($definition, $arguments) { - switch ($definition['type']) { - case 'object': - $ref = $definition['ref']; - $class = ReflectionManager::reflectClass($ref); - $parentClass = $class->getParentClass(); - if ($parentClass->getName() === ProtobufMessage::class) { - $request = $this->request(); - return Parser::deserializeMessage([$class->getName(), null], $request->getBody()); - } - - if (!$this->container->has($definition['ref']) && !$definition['allowsNull']) { - throw new \RuntimeException(sprintf('Argument %s invalid, object %s not found.', $definition['name'], $definition['ref'])); - } - - return $this->container->get($definition['ref']); - default: - throw new \RuntimeException('Invalid method definition detected.'); - } - }); - } - - return $injections; - } - - /** - * @return RequestInterface - */ - protected function request() - { - return Context::get(ServerRequestInterface::class); - } - - /** - * Handle GRPC Response - * @param ProtobufMessage|null $message - * @param int $httpStatus - * @param string $grpcStatus - * @param string $grpcMessage - * @return ResponseInterface - */ - protected function handleResponse(?Message $message, $httpStatus = 200, string $grpcStatus = '0', string $grpcMessage = ''): ResponseInterface - { - $response = $this->response()->withStatus($httpStatus) - ->withBody(new SwooleStream(Parser::serializeMessage($message))) - ->withAddedHeader('Server', 'Hyperflex') - ->withAddedHeader('Content-Type', 'application/grpc') - ->withAddedHeader('trailer', 'grpc-status, grpc-message'); - - $response->getSwooleResponse()->trailer('grpc-status', $grpcStatus); - $response->getSwooleResponse()->trailer('grpc-message', $grpcMessage); - - return $response; - } -} diff --git a/src/grpc-server/src/Router/Dispatcher.php b/src/grpc-server/src/Router/Dispatcher.php deleted file mode 100644 index b88201f95..000000000 --- a/src/grpc-server/src/Router/Dispatcher.php +++ /dev/null @@ -1,7 +0,0 @@ -encode(); - } elseif (method_exists($data, 'serializeToString')) { - $data = $data->serializeToString(); - } else { - /** @noinspection PhpUndefinedMethodInspection */ - $data = $data->serialize(); - } - return self::pack($data); - } - - public static function deserializeMessage($deserialize, string $value) - { - if (empty($value)) { - return null; - } else { - $value = self::unpack($value); - } - if (is_array($deserialize)) { - list($className, $deserializeFunc) = $deserialize; - /** @var $obj \Google\Protobuf\Internal\Message */ - $obj = new $className(); - if ($deserializeFunc && method_exists($obj, $deserializeFunc)) { - $obj->$deserializeFunc($value); - } else { - /** @noinspection PhpUndefinedMethodInspection */ - $obj->mergeFromString($value); - } - return $obj; - } - return call_user_func($deserialize, $value); - } - - /** - * @param \swoole_http2_response|null $response - * @param $deserialize - * @return Message[]|\Grpc\StringifyAble[]|\swoole_http2_response[] - */ - public static function parseToResultArray($response, $deserialize): array - { - if (!$response) { - return ['No response', GRPC_ERROR_NO_RESPONSE, $response]; - } elseif ($response->statusCode !== 200) { - return ['Http status Error', $response->errCode ?: $response->statusCode, $response]; - } else { - $grpc_status = (int)($response->headers['grpc-status'] ?? 0); - if ($grpc_status !== 0) { - return [$response->headers['grpc-message'] ?? 'Unknown error', $grpc_status, $response]; - } - $data = $response->data; - $reply = self::deserializeMessage($deserialize, $data); - $status = (int)($response->headers['grpc-status'] ?? 0 ?: 0); - return [$reply, $status, $response]; - } - } -} diff --git a/src/http-server/composer.json b/src/http-server/composer.json deleted file mode 100644 index f50af35e7..000000000 --- a/src/http-server/composer.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "hyperflex/http-server", - "description": "A HTTP Server for Hyperflex.", - "license": "Apache-2.0", - "keywords": [ - "php", - "swoole", - "hyperflex", - "http", - "http-server" - ], - "support": { - }, - "require": { - "php": ">=7.1", - "nikic/fast-route": "^1.3", - "hyperflex/framework": "dev-master", - "hyperflex/utils": "dev-master", - "swoft/http-message": "^1.0" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0" - }, - "suggest": { - }, - "autoload": { - "files": [ - ], - "psr-4": { - "Hyperflex\\HttpServer\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": "Hyperflex\\HttpServer\\ConfigProvider" - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - } -} diff --git a/src/http-server/src/Command/StartServer.php b/src/http-server/src/Command/StartServer.php deleted file mode 100644 index 4014b02b5..000000000 --- a/src/http-server/src/Command/StartServer.php +++ /dev/null @@ -1,64 +0,0 @@ -container = $container; - $this->scanner = $scanner; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->checkEnv($output); - $this->initServer(); - $this->server->run(); - } - - private function initServer() - { - $config = $this->container->get(ConfigInterface::class); - $serverConfigs = $config->get('servers', []); - if (! $serverConfigs) { - throw new \InvalidArgumentException('No available server.'); - } - $this->server = $this->container->get(Server::class)->initConfigs($serverConfigs); - } - - private function checkEnv(OutputInterface $output) - { - if (ini_get_all('swoole')['swoole.use_shortname']['local_value'] !== 'Off') { - $output->writeln('ERROR Swoole short name have to disable before start server, please set swoole.use_shortname = \'Off\' into your php.ini.'); - exit(0); - } - } - -} \ No newline at end of file diff --git a/src/http-server/src/Command/StartServerFactory.php b/src/http-server/src/Command/StartServerFactory.php deleted file mode 100644 index 9dd384fa8..000000000 --- a/src/http-server/src/Command/StartServerFactory.php +++ /dev/null @@ -1,17 +0,0 @@ -get(Scanner::class)); - } - -} \ No newline at end of file diff --git a/src/http-server/src/ConfigProvider.php b/src/http-server/src/ConfigProvider.php deleted file mode 100644 index 882265ec9..000000000 --- a/src/http-server/src/ConfigProvider.php +++ /dev/null @@ -1,33 +0,0 @@ - [ - Server::class => ServerFactory::class, - StartServer::class => StartServerFactory::class, - Dispatcher::class => DispatcherFactory::class, - ], - 'commands' => [ - StartServer::class, - ], - 'scan' => [ - 'paths' => [ - "vendor/hyperflex/http-server/src" - ], - ], - ]; - } -} \ No newline at end of file diff --git a/src/http-server/src/Contract/RouterInterface.php b/src/http-server/src/Contract/RouterInterface.php deleted file mode 100644 index c1dc26c14..000000000 --- a/src/http-server/src/Contract/RouterInterface.php +++ /dev/null @@ -1,11 +0,0 @@ -container = $container; - $this->dispatcher = $container->get(Dispatcher::class); - } - - /** - * Process an incoming server request and return a response, optionally delegating - * response creation to a handler. - */ - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface - { - /** @var ResponseInterface $response */ - $uri = $request->getUri(); - /** - * @var array $routes - * Returns array with one of the following formats: - * [self::NOT_FOUND] - * [self::METHOD_NOT_ALLOWED, ['GET', 'OTHER_ALLOWED_METHODS']] - * [self::FOUND, $handler, ['varName' => 'value', ...]] - */ - $routes = $this->dispatcher->dispatch($request->getMethod(), $uri->getPath()); - switch ($routes[0]) { - case Dispatcher::NOT_FOUND: - $response = $this->response()->withStatus(404); - break; - case Dispatcher::METHOD_NOT_ALLOWED: - $response = $this->response()->withStatus(405)->withAddedHeader('Allow', implode(', ', $routes[1])); - break; - case Dispatcher::FOUND: - [$controller, $action] = $this->prepareHandler($routes[1]); - $controllerInstance = $this->container->get($controller); - if (! method_exists($controller, $action)) { - $response = $this->response()->withStatus(500)->withBody(new SwooleStream('Action not exist.')); - break; - } - $parameters = $this->parseParameters($controller, $action, $routes[2]); - $response = $controllerInstance->$action(...$parameters); - if (! $response instanceof ResponseInterface) { - $response = $this->transferToResponse($response); - } - break; - } - return $response->withAddedHeader('Server', 'Hyperflex'); - } - - /** - * @param string|array $handler - * @return array - */ - protected function prepareHandler($handler): array - { - if (is_string($handler)) { - return explode('@', $handler); - } - if (is_array($handler) && isset($handler[0], $handler[1])) { - return $handler; - } - throw new \RuntimeException('Handler not exist.'); - } - - /** - * Transfer the non-standard response content to a standard response object. - * - * @param string|array $response - */ - protected function transferToResponse($response): ResponseInterface - { - if (is_string($response)) { - return $this->response()->withBody(new SwooleStream($response)); - } - - if (is_array($response)) { - return $this->response() - ->withAddedHeader('Content-Type', 'application/json') - ->withBody(new SwooleStream(json_encode($response))); - } - - return $this->response()->withBody(new SwooleStream((string)$response)); - } - - /** - * Get response instance from context. - */ - protected function response(): ResponseInterface - { - return Context::get(ResponseInterface::class); - } - - /** - * Parse the parameters of method definitions, and then bind the specified arguments or - * get the value from DI container, combine to a argument array that should be injected - * and return the array. - */ - protected function parseParameters(string $controller, string $action, array $arguments): array - { - $injections = []; - $definitions = MethodDefinitionCollector::getOrParse($controller, $action); - foreach ($definitions ?? [] as $definition) { - if (! is_array($definition)) { - throw new \RuntimeException('Invalid method definition.'); - } - if (! isset($definition['type']) || ! isset($definition['name'])) { - $injections[] = null; - continue; - } - $injections[] = value(function () use ($definition, $arguments) { - switch ($definition['type']) { - case 'int': - return (int)$arguments[$definition['name']] ?? null; - break; - case 'float': - return (float)$arguments[$definition['name']] ?? null; - break; - case 'bool': - return (bool)$arguments[$definition['name']] ?? null; - break; - case 'string': - return (string)$arguments[$definition['name']] ?? null; - break; - case 'object': - if (! $this->container->has($definition['ref']) && ! $definition['allowsNull']) { - throw new \RuntimeException(sprintf('Argument %s invalid, object %s not found.', $definition['name'], $definition['ref'])); - } - return $this->container->get($definition['ref']); - break; - default: - throw new \RuntimeException('Invalid method definition detected.'); - } - }); - } - - return $injections; - } - -} \ No newline at end of file diff --git a/src/http-server/src/Exception/Handler/HttpExceptionHandler.php b/src/http-server/src/Exception/Handler/HttpExceptionHandler.php deleted file mode 100644 index 330e5b0a7..000000000 --- a/src/http-server/src/Exception/Handler/HttpExceptionHandler.php +++ /dev/null @@ -1,34 +0,0 @@ -withStatus($throwable->getCode())->withBody(new SwooleStream($throwable->getMessage())); - } - - /** - * Determine if the current exception handler should handle the exception, - * - * @return bool - * If return true, then this exception handler will handle the exception, - * If return false, then delegate to next handler. - */ - public function isValid(Throwable $throwable): bool - { - return $throwable instanceof HttpException; - } -} \ No newline at end of file diff --git a/src/http-server/src/Exception/Http/NotFoundException.php b/src/http-server/src/Exception/Http/NotFoundException.php deleted file mode 100644 index 22bc138a2..000000000 --- a/src/http-server/src/Exception/Http/NotFoundException.php +++ /dev/null @@ -1,11 +0,0 @@ -routes as $route) { - require_once $route; - } - - return new GroupCountBased($router->getData()); - } -} \ No newline at end of file diff --git a/src/http-server/src/Router/Router.php b/src/http-server/src/Router/Router.php deleted file mode 100644 index 1b20261e5..000000000 --- a/src/http-server/src/Router/Router.php +++ /dev/null @@ -1,32 +0,0 @@ -$name(...$arguments); - } -} \ No newline at end of file diff --git a/src/http-server/src/Server.php b/src/http-server/src/Server.php deleted file mode 100644 index c78f005e6..000000000 --- a/src/http-server/src/Server.php +++ /dev/null @@ -1,76 +0,0 @@ -middlewares = $middlewares; - $this->coreHandler = $coreHandler; - $this->exceptionHandlers = $exceptionHandlers; - $this->container = $container; - } - - public function onRequest(SwooleRequest $request, SwooleResponse $response): void - { - try { - // Initialize PSR-7 Request and Response objects. - $psr7Request = \Swoft\Http\Message\Server\Request::loadFromSwooleRequest($request); - $psr7Response = new \Swoft\Http\Message\Server\Response($response); - Context::set(ServerRequestInterface::class, $psr7Request); - Context::set(ResponseInterface::class, $psr7Response); - $dispatcher = $this->container->get(HttpDispatcher::class); - $psr7Response = $dispatcher->dispatch($psr7Request, $this->middlewares, $this->coreHandler); - } catch (\Throwable $throwable) { - if (! $throwable instanceof HttpException) { - $logger = $this->container->get(StdoutLoggerInterface::class); - $logger->error($throwable->getMessage()); - } - // Delegate the exception to exception handler. - $exceptionHandlerDispatcher = $this->container->get(ExceptionHandlerDispatcher::class); - $psr7Response = $exceptionHandlerDispatcher->dispatch($throwable, $this->exceptionHandlers); - } finally { - // Response and Recycle resources. - $psr7Response->send(); - Context::destroy(); - } - } - -} \ No newline at end of file diff --git a/src/http-server/src/ServerFactory.php b/src/http-server/src/ServerFactory.php deleted file mode 100644 index 5f9fc2803..000000000 --- a/src/http-server/src/ServerFactory.php +++ /dev/null @@ -1,23 +0,0 @@ -get(ConfigInterface::class); - $middlewares = $config->get('middlewares.http', []); - $exceptionHandlers = $config->get('exceptions.handler.http', [ - HttpExceptionHandler::class, - ]); - return new Server($middlewares, $this->coreMiddleware, $exceptionHandlers, $container); - } -} \ No newline at end of file diff --git a/src/http-server/src/SwooleStream.php b/src/http-server/src/SwooleStream.php deleted file mode 100644 index 7a84b1bab..000000000 --- a/src/http-server/src/SwooleStream.php +++ /dev/null @@ -1,228 +0,0 @@ -request = $request; - } - - /** - * {@inheritdoc} - */ - public function getContents() - { - // If we're at the end of the string, return an empty string. - if ($this->eof()) { - return ''; - } - $size = $this->getSize(); - // If we have not content, return an empty string - if ($size === 0) { - return ''; - } - // Memoize index so we can use it to get a substring later, - // if required. - $index = $this->index; - // Set the internal index to the end of the string - $this->index = $size - 1; - if ($index) { - // Per PSR-7 spec, if we have seeked or read to a given position in - // the string, we should only return the contents from that position - // forward. - return substr($this->body, $index); - } - // If we're at the start of the content, return all of it. - return $this->body; - } - - /** - * {@inheritdoc} - */ - public function __toString() - { - $this->body !== null || $this->initRawContent(); - return $this->body; - } - - /** - * {@inheritdoc} - */ - public function getSize() - { - if (null === $this->bodySize) { - $this->body !== null || $this->initRawContent(); - $this->bodySize = strlen($this->body); - } - return $this->bodySize; - } - - /** - * {@inheritdoc} - */ - public function tell() - { - return $this->index; - } - - /** - * {@inheritdoc} - */ - public function eof() - { - return $this->index >= $this->getSize() - 1; - } - - /** - * {@inheritdoc} - */ - public function isReadable() - { - return true; - } - - /** - * {@inheritdoc} - */ - public function read($length) - { - $this->body !== null || $this->initRawContent(); - $result = substr($this->body, $this->index, $length); - // Reset index based on legnth; should not be > EOF position. - $size = $this->getSize(); - $this->index = $this->index + $length >= $size ? $size - 1 : $this->index + $length; - return $result; - } - - /** - * {@inheritdoc} - */ - public function isSeekable() - { - return true; - } - - /** - * {@inheritdoc} - */ - public function seek($offset, $whence = SEEK_SET) - { - $size = $this->getSize(); - switch ($whence) { - case SEEK_SET: - if ($offset >= $size) { - throw new RuntimeException('Offset cannot be longer than content size'); - } - $this->index = $offset; - break; - case SEEK_CUR: - if ($offset + $this->index >= $size) { - throw new RuntimeException('Offset + current position cannot be longer than content size when using SEEK_CUR'); - } - $this->index += $offset; - break; - case SEEK_END: - if ($offset + $size >= $size) { - throw new RuntimeException('Offset must be a negative number to be under the content size when using SEEK_END'); - } - $this->index = ($size - 1) + $offset; - break; - default: - throw new InvalidArgumentException('Invalid $whence argument provided; must be one of SEEK_CUR,' . 'SEEK_END, or SEEK_SET'); - } - } - - /** - * {@inheritdoc} - */ - public function rewind() - { - $this->index = 0; - } - - /** - * {@inheritdoc} - */ - public function isWritable() - { - return false; - } - - /** - * {@inheritdoc} - */ - public function write($string) - { - throw new RuntimeException('Stream is not writable'); - } - - /** - * {@inheritdoc} - */ - public function getMetadata($key = null) - { - return $key ? null : []; - } - - /** - * {@inheritdoc} - */ - public function detach() - { - return $this->request; - } - - /** - * {@inheritdoc} - */ - public function close() - { - } - - /** - * Memoize the request raw content in the $body property, if not already done. - */ - private function initRawContent(): void - { - if ($this->body) { - return; - } - $this->body = $this->request->rawContent(); - } -} \ No newline at end of file diff --git a/src/memory/composer.json b/src/memory/composer.json deleted file mode 100644 index f6aa9cd3d..000000000 --- a/src/memory/composer.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "hyperflex/memory", - "description": "An independent component that use to operate and manage memory.", - "license": "Apache-2.0", - "keywords": [ - "php", - "swoole", - "hyperflex", - "memory" - ], - "support": { - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0" - }, - "suggest": { - }, - "autoload": { - "files": [ - ], - "psr-4": { - "Hyperflex\\Memory\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - }, - "hyperflex": { - "config": "Hyperflex\\Memory\\ConfigProvider" - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - } -} diff --git a/src/memory/src/AtomicManager.php b/src/memory/src/AtomicManager.php deleted file mode 100644 index 8c898db84..000000000 --- a/src/memory/src/AtomicManager.php +++ /dev/null @@ -1,49 +0,0 @@ - [ - ], - 'scan' => [ - 'paths' => [ - 'vendor/hyperflex/memory/src' - ], - ] - ]; - } - -} \ No newline at end of file diff --git a/src/memory/src/LockManager.php b/src/memory/src/LockManager.php deleted file mode 100644 index 2f72b293a..000000000 --- a/src/memory/src/LockManager.php +++ /dev/null @@ -1,49 +0,0 @@ -=7.1" - }, - "require-dev": { - "malukenho/docheader": "^0.1.6", - "mockery/mockery": "^1.0", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^7.0.0", - "hyperflex/coding-standard": "~1.0.0" - }, - "suggest": { - "symfony/var-dumper": "Required to use the dd function (^4.1)." - }, - "autoload": { - "files": [ - "src/Functions.php" - ], - "psr-4": { - "Hyperflex\\Utils\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - } - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - } - }, - "bin": [ - ], - "scripts": { - "check": [ - "@license-check", - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "phpstan": "phpstan analyze -l max -c phpstan.neon ./src", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "license-check": "docheader check src/ test/" - } -} diff --git a/src/utils/src/Arr.php b/src/utils/src/Arr.php deleted file mode 100644 index 3f038149a..000000000 --- a/src/utils/src/Arr.php +++ /dev/null @@ -1,510 +0,0 @@ -all(); - } elseif (! is_array($values)) { - continue; - } - $results = array_merge($results, $values); - } - return $results; - } - - /** - * Cross join the given arrays, returning all possible permutations. - * - * @param array ...$arrays - */ - public static function crossJoin(...$arrays): array - { - $results = [[]]; - foreach ($arrays as $index => $array) { - $append = []; - foreach ($results as $product) { - foreach ($array as $item) { - $product[$index] = $item; - $append[] = $product; - } - } - $results = $append; - } - return $results; - } - - /** - * Divide an array into two arrays. One with keys and the other with values. - * - * @param array $array - * @return array - */ - public static function divide($array) - { - return [array_keys($array), array_values($array)]; - } - - /** - * Flatten a multi-dimensional associative array with dots. - */ - public static function dot(array $array, string $prepend = ''): array - { - $results = []; - foreach ($array as $key => $value) { - if (is_array($value) && ! empty($value)) { - $results = array_merge($results, static::dot($value, $prepend . $key . '.')); - } else { - $results[$prepend . $key] = $value; - } - } - return $results; - } - - /** - * Get all of the given array except for a specified array of keys. - * - * @param array|string $keys - */ - public static function except(array $array, $keys): array - { - static::forget($array, $keys); - return $array; - } - - /** - * Determine if the given key exists in the provided array. - * - * @param \ArrayAccess|array $array - * @param string|int $key - */ - public static function exists($array, $key): bool - { - if ($array instanceof ArrayAccess) { - return $array->offsetExists($key); - } - return array_key_exists($key, $array); - } - - /** - * Return the first element in an array passing a given truth test. - * - * @return mixed - */ - public static function first(array $array, callable $callback = null, $default = null) - { - if (is_null($callback)) { - if (empty($array)) { - return value($default); - } - foreach ($array as $item) { - return $item; - } - } - foreach ($array as $key => $value) { - if (call_user_func($callback, $value, $key)) { - return $value; - } - } - return value($default); - } - - /** - * Return the last element in an array passing a given truth test. - * - * @return mixed - */ - public static function last(array $array, callable $callback = null, $default = null) - { - if (is_null($callback)) { - return empty($array) ? value($default) : end($array); - } - return static::first(array_reverse($array, true), $callback, $default); - } - - /** - * Flatten a multi-dimensional array into a single level. - */ - public static function flatten(array $array, int $depth = INF): array - { - $result = []; - foreach ($array as $item) { - $item = $item instanceof Collection ? $item->all() : $item; - if (! is_array($item)) { - $result[] = $item; - } elseif ($depth === 1) { - $result = array_merge($result, array_values($item)); - } else { - $result = array_merge($result, static::flatten($item, $depth - 1)); - } - } - return $result; - } - - /** - * Remove one or many array items from a given array using "dot" notation. - * - * @param array|string $keys - */ - public static function forget(array &$array, $keys): void - { - $original = &$array; - $keys = (array)$keys; - if (count($keys) === 0) { - return; - } - foreach ($keys as $key) { - // if the exact key exists in the top-level, remove it - if (static::exists($array, $key)) { - unset($array[$key]); - continue; - } - $parts = explode('.', $key); - // clean up before each pass - $array = &$original; - while (count($parts) > 1) { - $part = array_shift($parts); - if (isset($array[$part]) && is_array($array[$part])) { - $array = &$array[$part]; - } else { - continue 2; - } - } - unset($array[array_shift($parts)]); - } - } - - /** - * Get an item from an array using "dot" notation. - * - * @param \ArrayAccess|array $array - * @return mixed - */ - public static function get($array, string $key, $default = null) - { - if (! static::accessible($array)) { - return value($default); - } - if (is_null($key)) { - return $array; - } - if (static::exists($array, $key)) { - return $array[$key]; - } - if (strpos($key, '.') === false) { - return $array[$key] ?? value($default); - } - foreach (explode('.', $key) as $segment) { - if (static::accessible($array) && static::exists($array, $segment)) { - $array = $array[$segment]; - } else { - return value($default); - } - } - return $array; - } - - /** - * Check if an item or items exist in an array using "dot" notation. - * - * @param \ArrayAccess|array $array - * @param string|array $keys - */ - public static function has($array, $keys): bool - { - if (is_null($keys)) { - return false; - } - $keys = (array)$keys; - if (! $array) { - return false; - } - if ($keys === []) { - return false; - } - foreach ($keys as $key) { - $subKeyArray = $array; - if (static::exists($array, $key)) { - continue; - } - foreach (explode('.', $key) as $segment) { - if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) { - $subKeyArray = $subKeyArray[$segment]; - } else { - return false; - } - } - } - return true; - } - - /** - * Determines if an array is associative. - * An array is "associative" if it doesn't have sequential numerical keys beginning with zero. - */ - public static function isAssoc(array $array): bool - { - $keys = array_keys($array); - return array_keys($keys) !== $keys; - } - - /** - * Get a subset of the items from the given array. - * - * @param array|string $keys - */ - public static function only(array $array, $keys): array - { - return array_intersect_key($array, array_flip((array)$keys)); - } - - /** - * Pluck an array of values from an array. - * - * @param string|array $value - * @param string|array|null $key - */ - public static function pluck(array $array, $value, $key = null): array - { - $results = []; - [$value, $key] = static::explodePluckParameters($value, $key); - foreach ($array as $item) { - $itemValue = data_get($item, $value); - // If the key is "null", we will just append the value to the array and keep - // looping. Otherwise we will key the array using the value of the key we - // received from the developer. Then we'll return the final array form. - if (is_null($key)) { - $results[] = $itemValue; - } else { - $itemKey = data_get($item, $key); - if (is_object($itemKey) && method_exists($itemKey, '__toString')) { - $itemKey = (string)$itemKey; - } - $results[$itemKey] = $itemValue; - } - } - return $results; - } - - /** - * Explode the "value" and "key" arguments passed to "pluck". - * - * @param string|array $value - * @param string|array|null $key - */ - protected static function explodePluckParameters($value, $key): array - { - $value = is_string($value) ? explode('.', $value) : $value; - $key = is_null($key) || is_array($key) ? $key : explode('.', $key); - return [$value, $key]; - } - - /** - * Push an item onto the beginning of an array. - * - * @param mixed $value - * @param mixed $key - */ - public static function prepend(array $array, $value, $key = null): array - { - if (is_null($key)) { - array_unshift($array, $value); - } else { - $array = [$key => $value] + $array; - } - return $array; - } - - /** - * Get a value from the array, and remove it. - * - * @return mixed - */ - public static function pull(array &$array, string $key, $default = null) - { - $value = static::get($array, $key, $default); - static::forget($array, $key); - return $value; - } - - /** - * Get one or a specified number of random values from an array. - * - * @return mixed - * @throws \InvalidArgumentException - */ - public static function random(array $array, int $number = null) - { - $requested = is_null($number) ? 1 : $number; - $count = count($array); - if ($requested > $count) { - throw new InvalidArgumentException("You requested {$requested} items, but there are only {$count} items available."); - } - if (is_null($number)) { - return $array[array_rand($array)]; - } - if ((int)$number === 0) { - return []; - } - $keys = array_rand($array, $number); - $results = []; - foreach ((array)$keys as $key) { - $results[] = $array[$key]; - } - return $results; - } - - /** - * Set an array item to a given value using "dot" notation. - * If no key is given to the method, the entire array will be replaced. - */ - public static function set(array &$array, string $key, $value): array - { - if (is_null($key)) { - return $array = $value; - } - $keys = explode('.', $key); - while (count($keys) > 1) { - $key = array_shift($keys); - // If the key doesn't exist at this depth, we will just create an empty array - // to hold the next value, allowing us to create the arrays to hold final - // values at the correct depth. Then we'll keep digging into the array. - if (! isset($array[$key]) || ! is_array($array[$key])) { - $array[$key] = []; - } - $array = &$array[$key]; - } - $array[array_shift($keys)] = $value; - return $array; - } - - /** - * Shuffle the given array and return the result. - */ - public static function shuffle(array $array, int $seed = null): array - { - if (is_null($seed)) { - shuffle($array); - } else { - srand($seed); - usort($array, function () { - return rand(-1, 1); - }); - } - return $array; - } - - /** - * Sort the array using the given callback or "dot" notation. - * - * @param callable|string|null $callback - */ - public static function sort(array $array, $callback = null): array - { - return Collection::make($array)->sortBy($callback)->all(); - } - - /** - * Recursively sort an array by keys and values. - */ - public static function sortRecursive(array $array): array - { - foreach ($array as &$value) { - if (is_array($value)) { - $value = static::sortRecursive($value); - } - } - if (static::isAssoc($array)) { - ksort($array); - } else { - sort($array); - } - return $array; - } - - /** - * Convert the array into a query string. - */ - public static function query(array $array): string - { - return http_build_query($array, null, '&', PHP_QUERY_RFC3986); - } - - /** - * Filter the array using the given callback. - */ - public static function where(array $array, callable $callback): array - { - return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH); - } - - /** - * If the given value is not an array and not null, wrap it in one. - * - * @param mixed $value - */ - public static function wrap($value): array - { - if (is_null($value)) { - return []; - } - return ! is_array($value) ? [$value] : $value; - } - - /** - * Make array elements unique - */ - public static function unique(array $array): array - { - $result = []; - foreach ($array ?? [] as $key => $item) { - if (is_array($item)) { - $result[$key] = self::unique($item); - } else { - $result[$key] = $item; - } - } - - if (!self::isAssoc($result)) { - return array_unique($result); - } - - return $result; - } -} \ No newline at end of file diff --git a/src/utils/src/Collection.php b/src/utils/src/Collection.php deleted file mode 100644 index 67d9921cd..000000000 --- a/src/utils/src/Collection.php +++ /dev/null @@ -1,1517 +0,0 @@ -items = $this->getArrayableItems($items); - } - - /** - * Create a new collection instance if the value isn't one already. - * - * @param mixed $items - */ - public static function make($items = []): self - { - return new static($items); - } - - /** - * Wrap the given value in a collection if applicable. - * - * @param mixed $value - */ - public static function wrap($value): self - { - return $value instanceof self ? new static($value) : new static(Arr::wrap($value)); - } - - /** - * Get the underlying items from the given collection if applicable. - * - * @param array|static $value - */ - public static function unwrap($value): array - { - return $value instanceof self ? $value->all() : $value; - } - - /** - * Create a new collection by invoking the callback a given amount of times. - */ - public static function times(int $number, callable $callback = null): self - { - if ($number < 1) { - return new static; - } - if (is_null($callback)) { - return new static(range(1, $number)); - } - return (new static(range(1, $number)))->map($callback); - } - - /** - * Get all of the items in the collection. - */ - public function all(): array - { - return $this->items; - } - - /** - * Get the average value of a given key. - * - * @param callable|string|null $callback - * @return mixed - */ - public function avg($callback = null) - { - $callback = $this->valueRetriever($callback); - $items = $this->map(function ($value) use ($callback) { - return $callback($value); - })->filter(function ($value) { - return ! is_null($value); - }); - if ($count = $items->count()) { - return $items->sum() / $count; - } - } - - /** - * Alias for the "avg" method. - * - * @param callable|string|null $callback - * @return mixed - */ - public function average($callback = null) - { - return $this->avg($callback); - } - - /** - * Get the median of a given key. - * - * @return mixed - */ - public function median($key = null) - { - $values = (isset($key) ? $this->pluck($key) : $this)->filter(function ($item) { - return ! is_null($item); - })->sort()->values(); - $count = $values->count(); - if ($count == 0) { - return; - } - $middle = (int)($count / 2); - if ($count % 2) { - return $values->get($middle); - } - return (new static([ - $values->get($middle - 1), - $values->get($middle), - ]))->average(); - } - - /** - * Get the mode of a given key. - * - * @return array|null - */ - public function mode($key = null) - { - if ($this->count() == 0) { - return; - } - $collection = isset($key) ? $this->pluck($key) : $this; - $counts = new self; - $collection->each(function ($value) use ($counts) { - $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1; - }); - $sorted = $counts->sort(); - $highestValue = $sorted->last(); - return $sorted->filter(function ($value) use ($highestValue) { - return $value == $highestValue; - })->sort()->keys()->all(); - } - - /** - * Collapse the collection of items into a single array. - */ - public function collapse(): self - { - return new static(Arr::collapse($this->items)); - } - - /** - * Determine if an item exists in the collection. - */ - public function contains($key, $operator = null, $value = null): bool - { - if (func_num_args() === 1) { - if ($this->useAsCallable($key)) { - $placeholder = new stdClass; - return $this->first($key, $placeholder) !== $placeholder; - } - return in_array($key, $this->items); - } - return $this->contains($this->operatorForWhere(...func_get_args())); - } - - /** - * Determine if an item exists in the collection using strict comparison. - */ - public function containsStrict($key, $value = null): bool - { - if (func_num_args() === 2) { - return $this->contains(function ($item) use ($key, $value) { - return data_get($item, $key) === $value; - }); - } - if ($this->useAsCallable($key)) { - return ! is_null($this->first($key)); - } - return in_array($key, $this->items, true); - } - - /** - * Cross join with the given lists, returning all possible permutations. - */ - public function crossJoin(...$lists): self - { - return new static(Arr::crossJoin($this->items, ...array_map([$this, 'getArrayableItems'], $lists))); - } - - /** - * Dump the collection and end the script. - */ - public function dd(...$args): void - { - call_user_func_array([$this, 'dump'], $args); - die(1); - } - - /** - * Dump the collection. - */ - public function dump(): self - { - (new static(func_get_args()))->push($this)->each(function ($item) { - if (! class_exists(VarDumper::class)) { - throw new \RuntimeException('symfony/var-dumper package required, please require the package via "composer require symfony/var-dumper"'); - } - VarDumper::dump($item); - }); - return $this; - } - - /** - * Get the items in the collection that are not present in the given items. - */ - public function diff($items): self - { - return new static(array_diff($this->items, $this->getArrayableItems($items))); - } - - /** - * Get the items in the collection that are not present in the given items. - */ - public function diffUsing($items, callable $callback): self - { - return new static(array_udiff($this->items, $this->getArrayableItems($items), $callback)); - } - - /** - * Get the items in the collection whose keys and values are not present in the given items. - */ - public function diffAssoc($items): self - { - return new static(array_diff_assoc($this->items, $this->getArrayableItems($items))); - } - - /** - * Get the items in the collection whose keys and values are not present in the given items. - */ - public function diffAssocUsing($items, callable $callback): self - { - return new static(array_diff_uassoc($this->items, $this->getArrayableItems($items), $callback)); - } - - /** - * Get the items in the collection whose keys are not present in the given items. - */ - public function diffKeys($items): self - { - return new static(array_diff_key($this->items, $this->getArrayableItems($items))); - } - - /** - * Get the items in the collection whose keys are not present in the given items. - */ - public function diffKeysUsing($items, callable $callback): self - { - return new static(array_diff_ukey($this->items, $this->getArrayableItems($items), $callback)); - } - - /** - * Execute a callback over each item. - */ - public function each(callable $callback): self - { - foreach ($this->items as $key => $item) { - if ($callback($item, $key) === false) { - break; - } - } - return $this; - } - - /** - * Execute a callback over each nested chunk of items. - */ - public function eachSpread(callable $callback): self - { - return $this->each(function ($chunk, $key) use ($callback) { - $chunk[] = $key; - return $callback(...$chunk); - }); - } - - /** - * Determine if all items in the collection pass the given test. - * - * @param string|callable $key - */ - public function every($key, $operator = null, $value = null): bool - { - if (func_num_args() === 1) { - $callback = $this->valueRetriever($key); - foreach ($this->items as $k => $v) { - if (! $callback($v, $k)) { - return false; - } - } - return true; - } - return $this->every($this->operatorForWhere(...func_get_args())); - } - - /** - * Get all items except for those with the specified keys. - * - * @param Collection|mixed $keys - */ - public function except($keys): self - { - if ($keys instanceof self) { - $keys = $keys->all(); - } elseif (! is_array($keys)) { - $keys = func_get_args(); - } - return new static(Arr::except($this->items, $keys)); - } - - /** - * Run a filter over each of the items. - * - * @param callable|null $callback - */ - public function filter(callable $callback = null): self - { - if ($callback) { - return new static(Arr::where($this->items, $callback)); - } - return new static(array_filter($this->items)); - } - - /** - * Apply the callback if the value is truthy. - */ - public function when(bool $value, callable $callback, callable $default = null): self - { - if ($value) { - return $callback($this, $value); - } elseif ($default) { - return $default($this, $value); - } - return $this; - } - - /** - * Apply the callback if the value is falsy. - */ - public function unless(bool $value, callable $callback, callable $default = null): self - { - return $this->when(! $value, $callback, $default); - } - - /** - * Filter items by the given key value pair. - */ - public function where(string $key, $operator = null, $value = null): self - { - return $this->filter($this->operatorForWhere(...func_get_args())); - } - - /** - * Get an operator checker callback. - */ - protected function operatorForWhere(string $key, string $operator = null, $value = null): \Closure - { - if (func_num_args() === 1) { - $value = true; - $operator = '='; - } - if (func_num_args() === 2) { - $value = $operator; - $operator = '='; - } - return function ($item) use ($key, $operator, $value) { - $retrieved = data_get($item, $key); - $strings = array_filter([$retrieved, $value], function ($value) { - return is_string($value) || (is_object($value) && method_exists($value, '__toString')); - }); - if (count($strings) < 2 && count(array_filter([$retrieved, $value], 'is_object')) == 1) { - return in_array($operator, ['!=', '<>', '!==']); - } - switch ($operator) { - default: - case '=': - case '==': - return $retrieved == $value; - case '!=': - case '<>': - return $retrieved != $value; - case '<': - return $retrieved < $value; - case '>': - return $retrieved > $value; - case '<=': - return $retrieved <= $value; - case '>=': - return $retrieved >= $value; - case '===': - return $retrieved === $value; - case '!==': - return $retrieved !== $value; - } - }; - } - - /** - * Filter items by the given key value pair using strict comparison. - */ - public function whereStrict(string $key, $value): self - { - return $this->where($key, '===', $value); - } - - /** - * Filter items by the given key value pair. - */ - public function whereIn(string $key, $values, bool $strict = false): self - { - $values = $this->getArrayableItems($values); - return $this->filter(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); - } - - /** - * Filter items by the given key value pair using strict comparison. - */ - public function whereInStrict(string $key, $values): self - { - return $this->whereIn($key, $values, true); - } - - /** - * Filter items by the given key value pair. - */ - public function whereNotIn(string $key, $values, bool $strict = false): self - { - $values = $this->getArrayableItems($values); - return $this->reject(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); - } - - /** - * Filter items by the given key value pair using strict comparison. - */ - public function whereNotInStrict(string $key, $values): self - { - return $this->whereNotIn($key, $values, true); - } - - /** - * Filter the items, removing any items that don't match the given type. - */ - public function whereInstanceOf(string $type): self - { - return $this->filter(function ($value) use ($type) { - return $value instanceof $type; - }); - } - - /** - * Get the first item from the collection. - * - * @param callable|null $callback - * @return mixed - */ - public function first(callable $callback = null, $default = null) - { - return Arr::first($this->items, $callback, $default); - } - - /** - * Get the first item by the given key value pair. - * - * @return mixed - */ - public function firstWhere(string $key, $operator, $value = null) - { - return $this->first($this->operatorForWhere(...func_get_args())); - } - - /** - * Get a flattened array of the items in the collection. - */ - public function flatten(int $depth = INF): self - { - return new static(Arr::flatten($this->items, $depth)); - } - - /** - * Flip the items in the collection. - */ - public function flip(): self - { - return new static(array_flip($this->items)); - } - - /** - * Remove an item from the collection by key. - * - * @param string|array $keys - */ - public function forget($keys): self - { - foreach ((array)$keys as $key) { - $this->offsetUnset($key); - } - return $this; - } - - /** - * Get an item from the collection by key. - */ - public function get($key, $default = null) - { - if ($this->offsetExists($key)) { - return $this->items[$key]; - } - return value($default); - } - - /** - * Group an associative array by a field or using a callback. - * - * @param callable|string $groupBy - */ - public function groupBy($groupBy, bool $preserveKeys = false): self - { - if (is_array($groupBy)) { - $nextGroups = $groupBy; - $groupBy = array_shift($nextGroups); - } - $groupBy = $this->valueRetriever($groupBy); - $results = []; - foreach ($this->items as $key => $value) { - $groupKeys = $groupBy($value, $key); - if (! is_array($groupKeys)) { - $groupKeys = [$groupKeys]; - } - foreach ($groupKeys as $groupKey) { - $groupKey = is_bool($groupKey) ? (int)$groupKey : $groupKey; - if (! array_key_exists($groupKey, $results)) { - $results[$groupKey] = new static; - } - $results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value); - } - } - $result = new static($results); - if (! empty($nextGroups)) { - return $result->map->groupBy($nextGroups, $preserveKeys); - } - return $result; - } - - /** - * Key an associative array by a field or using a callback. - * - * @param callable|string $keyBy - */ - public function keyBy($keyBy): self - { - $keyBy = $this->valueRetriever($keyBy); - $results = []; - foreach ($this->items as $key => $item) { - $resolvedKey = $keyBy($item, $key); - if (is_object($resolvedKey)) { - $resolvedKey = (string)$resolvedKey; - } - $results[$resolvedKey] = $item; - } - return new static($results); - } - - /** - * Determine if an item exists in the collection by key. - */ - public function has($key): bool - { - $keys = is_array($key) ? $key : func_get_args(); - foreach ($keys as $value) { - if (! $this->offsetExists($value)) { - return false; - } - } - return true; - } - - /** - * Concatenate values of a given key as a string. - */ - public function implode(string $value, string $glue = null): string - { - $first = $this->first(); - if (is_array($first) || is_object($first)) { - return implode($glue, $this->pluck($value)->all()); - } - return implode($value, $this->items); - } - - /** - * Intersect the collection with the given items. - */ - public function intersect($items): self - { - return new static(array_intersect($this->items, $this->getArrayableItems($items))); - } - - /** - * Intersect the collection with the given items by key. - */ - public function intersectByKeys($items): self - { - return new static(array_intersect_key($this->items, $this->getArrayableItems($items))); - } - - /** - * Determine if the collection is empty or not. - */ - public function isEmpty(): bool - { - return empty($this->items); - } - - /** - * Determine if the collection is not empty. - */ - public function isNotEmpty(): bool - { - return ! $this->isEmpty(); - } - - /** - * Determine if the given value is callable, but not a string. - */ - protected function useAsCallable($value): bool - { - return ! is_string($value) && is_callable($value); - } - - /** - * Get the keys of the collection items. - */ - public function keys(): self - { - return new static(array_keys($this->items)); - } - - /** - * Get the last item from the collection. - * - * @return mixed - */ - public function last(callable $callback = null, $default = null) - { - return Arr::last($this->items, $callback, $default); - } - - /** - * Get the values of a given key. - * - * @param string|array $value - */ - public function pluck($value, string $key = null): self - { - return new static(Arr::pluck($this->items, $value, $key)); - } - - /** - * Run a map over each of the items. - */ - public function map(callable $callback): self - { - $keys = array_keys($this->items); - $items = array_map($callback, $this->items, $keys); - return new static(array_combine($keys, $items)); - } - - /** - * Run a map over each nested chunk of items. - */ - public function mapSpread(callable $callback): self - { - return $this->map(function ($chunk, $key) use ($callback) { - $chunk[] = $key; - return $callback(...$chunk); - }); - } - - /** - * Run a dictionary map over the items. - * The callback should return an associative array with a single key/value pair. - */ - public function mapToDictionary(callable $callback): self - { - $dictionary = []; - foreach ($this->items as $key => $item) { - $pair = $callback($item, $key); - $key = key($pair); - $value = reset($pair); - if (! isset($dictionary[$key])) { - $dictionary[$key] = []; - } - $dictionary[$key][] = $value; - } - return new static($dictionary); - } - - /** - * Run a grouping map over the items. - * The callback should return an associative array with a single key/value pair. - */ - public function mapToGroups(callable $callback): self - { - $groups = $this->mapToDictionary($callback); - return $groups->map([$this, 'make']); - } - - /** - * Run an associative map over each of the items. - * The callback should return an associative array with a single key/value pair. - */ - public function mapWithKeys(callable $callback): self - { - $result = []; - foreach ($this->items as $key => $value) { - $assoc = $callback($value, $key); - foreach ($assoc as $mapKey => $mapValue) { - $result[$mapKey] = $mapValue; - } - } - return new static($result); - } - - /** - * Map a collection and flatten the result by a single level. - */ - public function flatMap(callable $callback): self - { - return $this->map($callback)->collapse(); - } - - /** - * Map the values into a new class. - */ - public function mapInto(string $class): self - { - return $this->map(function ($value, $key) use ($class) { - return new $class($value, $key); - }); - } - - /** - * Get the max value of a given key. - * - * @param callable|string|null $callback - * @return mixed - */ - public function max($callback = null) - { - $callback = $this->valueRetriever($callback); - return $this->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $item) use ($callback) { - $value = $callback($item); - return is_null($result) || $value > $result ? $value : $result; - }); - } - - /** - * Merge the collection with the given items. - */ - public function merge($items): self - { - return new static(array_merge($this->items, $this->getArrayableItems($items))); - } - - /** - * Create a collection by using this collection for keys and another for its values. - */ - public function combine($values): self - { - return new static(array_combine($this->all(), $this->getArrayableItems($values))); - } - - /** - * Union the collection with the given items. - */ - public function union($items): self - { - return new static($this->items + $this->getArrayableItems($items)); - } - - /** - * Get the min value of a given key. - * - * @param callable|string|null $callback - * @return mixed - */ - public function min($callback = null) - { - $callback = $this->valueRetriever($callback); - return $this->map(function ($value) use ($callback) { - return $callback($value); - })->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $value) { - return is_null($result) || $value < $result ? $value : $result; - }); - } - - /** - * Create a new collection consisting of every n-th element. - */ - public function nth(int $step, int $offset = 0): self - { - $new = []; - $position = 0; - foreach ($this->items as $item) { - if ($position % $step === $offset) { - $new[] = $item; - } - $position++; - } - return new static($new); - } - - /** - * Get the items with the specified keys. - */ - public function only($keys): self - { - if (is_null($keys)) { - return new static($this->items); - } - if ($keys instanceof self) { - $keys = $keys->all(); - } - $keys = is_array($keys) ? $keys : func_get_args(); - return new static(Arr::only($this->items, $keys)); - } - - /** - * "Paginate" the collection by slicing it into a smaller collection. - */ - public function forPage(int $page, int $perPage): self - { - $offset = max(0, ($page - 1) * $perPage); - return $this->slice($offset, $perPage); - } - - /** - * Partition the collection into two arrays using the given callback or key. - * - * @param callable|string $key - */ - public function partition($key, $operator = null, $value = null): self - { - $partitions = [new static, new static]; - $callback = func_num_args() === 1 ? $this->valueRetriever($key) : $this->operatorForWhere(...func_get_args()); - foreach ($this->items as $key => $item) { - $partitions[(int)! $callback($item, $key)][$key] = $item; - } - return new static($partitions); - } - - /** - * Pass the collection to the given callback and return the result. - * - * @return mixed - */ - public function pipe(callable $callback) - { - return $callback($this); - } - - /** - * Get and remove the last item from the collection. - * - * @return mixed - */ - public function pop() - { - return array_pop($this->items); - } - - /** - * Push an item onto the beginning of the collection. - */ - public function prepend($value, $key = null): self - { - $this->items = Arr::prepend($this->items, $value, $key); - return $this; - } - - /** - * Push an item onto the end of the collection. - */ - public function push($value): self - { - $this->offsetSet(null, $value); - return $this; - } - - /** - * Push all of the given items onto the collection. - * - * @param \Traversable|array $source - */ - public function concat($source): self - { - $result = new static($this); - foreach ($source as $item) { - $result->push($item); - } - return $result; - } - - /** - * Get and remove an item from the collection. - * - * @return mixed - */ - public function pull($key, $default = null) - { - return Arr::pull($this->items, $key, $default); - } - - /** - * Put an item in the collection by key. - */ - public function put($key, $value): self - { - $this->offsetSet($key, $value); - return $this; - } - - /** - * Get one or a specified number of items randomly from the collection. - * - * @throws \InvalidArgumentException - */ - public function random(int $number = null): self - { - if (is_null($number)) { - return Arr::random($this->items); - } - return new static(Arr::random($this->items, $number)); - } - - /** - * Reduce the collection to a single value. - * - * @param mixed $initial - * @return mixed - */ - public function reduce(callable $callback, $initial = null) - { - return array_reduce($this->items, $callback, $initial); - } - - /** - * Create a collection of all elements that do not pass a given truth test. - * - * @param callable|mixed $callback - */ - public function reject($callback): self - { - if ($this->useAsCallable($callback)) { - return $this->filter(function ($value, $key) use ($callback) { - return ! $callback($value, $key); - }); - } - return $this->filter(function ($item) use ($callback) { - return $item != $callback; - }); - } - - /** - * Reverse items order. - */ - public function reverse(): self - { - return new static(array_reverse($this->items, true)); - } - - /** - * Search the collection for a given value and return the corresponding key if successful. - * - * @param mixed $value - * @return mixed - */ - public function search($value, bool $strict = false) - { - if (! $this->useAsCallable($value)) { - return array_search($value, $this->items, $strict); - } - foreach ($this->items as $key => $item) { - if (call_user_func($value, $item, $key)) { - return $key; - } - } - return false; - } - - /** - * Get and remove the first item from the collection. - * - * @return mixed - */ - public function shift() - { - return array_shift($this->items); - } - - /** - * Shuffle the items in the collection. - */ - public function shuffle(int $seed = null): self - { - return new static(Arr::shuffle($this->items, $seed)); - } - - /** - * Slice the underlying collection array. - */ - public function slice(int $offset, int $length = null): self - { - return new static(array_slice($this->items, $offset, $length, true)); - } - - /** - * Split a collection into a certain number of groups. - */ - public function split(int $numberOfGroups): self - { - if ($this->isEmpty()) { - return new static; - } - $groups = new static; - $groupSize = floor($this->count() / $numberOfGroups); - $remain = $this->count() % $numberOfGroups; - $start = 0; - for ($i = 0; $i < $numberOfGroups; $i++) { - $size = $groupSize; - if ($i < $remain) { - $size++; - } - if ($size) { - $groups->push(new static(array_slice($this->items, $start, $size))); - $start += $size; - } - } - return $groups; - } - - /** - * Chunk the underlying collection array. - */ - public function chunk(int $size): self - { - if ($size <= 0) { - return new static; - } - $chunks = []; - foreach (array_chunk($this->items, $size, true) as $chunk) { - $chunks[] = new static($chunk); - } - return new static($chunks); - } - - /** - * Sort through each item with a callback. - * - * @param callable|null $callback - */ - public function sort(callable $callback = null): self - { - $items = $this->items; - $callback ? uasort($items, $callback) : asort($items); - return new static($items); - } - - /** - * Sort the collection using the given callback. - * - * @param callable|string $callback - */ - public function sortBy($callback, int $options = SORT_REGULAR, bool $descending = false): self - { - $results = []; - $callback = $this->valueRetriever($callback); - // First we will loop through the items and get the comparator from a callback - // function which we were given. Then, we will sort the returned values and - // and grab the corresponding values for the sorted keys from this array. - foreach ($this->items as $key => $value) { - $results[$key] = $callback($value, $key); - } - $descending ? arsort($results, $options) : asort($results, $options); - // Once we have sorted all of the keys in the array, we will loop through them - // and grab the corresponding model so we can set the underlying items list - // to the sorted version. Then we'll just return the collection instance. - foreach (array_keys($results) as $key) { - $results[$key] = $this->items[$key]; - } - return new static($results); - } - - /** - * Sort the collection in descending order using the given callback. - * - * @param callable|string $callback - */ - public function sortByDesc($callback, int $options = SORT_REGULAR): self - { - return $this->sortBy($callback, $options, true); - } - - /** - * Sort the collection keys. - */ - public function sortKeys(int $options = SORT_REGULAR, bool $descending = false): self - { - $items = $this->items; - $descending ? krsort($items, $options) : ksort($items, $options); - return new static($items); - } - - /** - * Sort the collection keys in descending order. - */ - public function sortKeysDesc(int $options = SORT_REGULAR): self - { - return $this->sortKeys($options, true); - } - - /** - * Splice a portion of the underlying collection array. - * - * @param mixed $replacement - */ - public function splice(int $offset, int $length = null, $replacement = []): self - { - if (func_num_args() === 1) { - return new static(array_splice($this->items, $offset)); - } - return new static(array_splice($this->items, $offset, $length, $replacement)); - } - - /** - * Get the sum of the given values. - * - * @param callable|string|null $callback - * @return mixed - */ - public function sum($callback = null) - { - if (is_null($callback)) { - return array_sum($this->items); - } - $callback = $this->valueRetriever($callback); - return $this->reduce(function ($result, $item) use ($callback) { - return $result + $callback($item); - }, 0); - } - - /** - * Take the first or last {$limit} items. - */ - public function take(int $limit): self - { - if ($limit < 0) { - return $this->slice($limit, abs($limit)); - } - return $this->slice(0, $limit); - } - - /** - * Pass the collection to the given callback and then return it. - */ - public function tap(callable $callback): self - { - $callback(new static($this->items)); - return $this; - } - - /** - * Transform each item in the collection using a callback. - */ - public function transform(callable $callback): self - { - $this->items = $this->map($callback)->all(); - return $this; - } - - /** - * Return only unique items from the collection array. - * - * @param string|callable|null $key - */ - public function unique($key = null, bool $strict = false): self - { - $callback = $this->valueRetriever($key); - $exists = []; - return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) { - if (in_array($id = $callback($item, $key), $exists, $strict)) { - return true; - } - $exists[] = $id; - }); - } - - /** - * Return only unique items from the collection array using strict comparison. - * - * @param string|callable|null $key - */ - public function uniqueStrict($key = null): self - { - return $this->unique($key, true); - } - - /** - * Reset the keys on the underlying array. - */ - public function values(): self - { - return new static(array_values($this->items)); - } - - /** - * Get a value retrieving callback. - */ - protected function valueRetriever(string $value): callable - { - if ($this->useAsCallable($value)) { - return $value; - } - return function ($item) use ($value) { - return data_get($item, $value); - }; - } - - /** - * Zip the collection together with one or more arrays. - * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); - * => [[1, 4], [2, 5], [3, 6]] - * - * @param mixed ...$items - */ - public function zip($items): self - { - $arrayableItems = array_map(function ($items) { - return $this->getArrayableItems($items); - }, func_get_args()); - $params = array_merge([ - function () { - return new static(func_get_args()); - }, - $this->items - ], $arrayableItems); - return new static(call_user_func_array('array_map', $params)); - } - - /** - * Pad collection to the specified length with a value. - * - * @param mixed $value - */ - public function pad(int $size, $value): self - { - return new static(array_pad($this->items, $size, $value)); - } - - /** - * Get the collection of items as a plain array. - */ - public function toArray(): array - { - return array_map(function ($value) { - return $value instanceof Arrayable ? $value->toArray() : $value; - }, $this->items); - } - - /** - * Convert the object into something JSON serializable. - */ - public function jsonSerialize(): array - { - return array_map(function ($value) { - if ($value instanceof JsonSerializable) { - return $value->jsonSerialize(); - } elseif ($value instanceof Jsonable) { - return json_decode($value->toJson(), true); - } elseif ($value instanceof Arrayable) { - return $value->toArray(); - } - return $value; - }, $this->items); - } - - /** - * Get the collection of items as JSON. - */ - public function toJson(int $options = 0): string - { - return json_encode($this->jsonSerialize(), $options); - } - - /** - * Get an iterator for the items. - */ - public function getIterator(): ArrayIterator - { - return new ArrayIterator($this->items); - } - - /** - * Get a CachingIterator instance. - */ - public function getCachingIterator(int $flags = CachingIterator::CALL_TOSTRING): CachingIterator - { - return new CachingIterator($this->getIterator(), $flags); - } - - /** - * Count the number of items in the collection. - */ - public function count(): int - { - return count($this->items); - } - - /** - * Get a base Support collection instance from this collection. - */ - public function toBase() - { - return new self($this); - } - - /** - * Determine if an item exists at an offset. - * - * @param mixed $key - * @return bool - */ - public function offsetExists($key) - { - return array_key_exists($key, $this->items); - } - - /** - * Get an item at a given offset. - * - * @param mixed $key - * @return mixed - */ - public function offsetGet($key) - { - return $this->items[$key]; - } - - /** - * Set the item at a given offset. - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function offsetSet($key, $value) - { - if (is_null($key)) { - $this->items[] = $value; - } else { - $this->items[$key] = $value; - } - } - - /** - * Unset the item at a given offset. - * - * @param string $key - * @return void - */ - public function offsetUnset($key) - { - unset($this->items[$key]); - } - - /** - * Convert the collection to its string representation. - */ - public function __toString(): string - { - return $this->toJson(); - } - - /** - * Results array of items from Collection or Arrayable. - */ - protected function getArrayableItems($items): array - { - if (is_array($items)) { - return $items; - } elseif ($items instanceof self) { - return $items->all(); - } elseif ($items instanceof Arrayable) { - return $items->toArray(); - } elseif ($items instanceof Jsonable) { - return json_decode($items->toJson(), true); - } elseif ($items instanceof JsonSerializable) { - return $items->jsonSerialize(); - } elseif ($items instanceof Traversable) { - return iterator_to_array($items); - } - return (array)$items; - } - - /** - * Add a method to the list of proxied methods. - */ - public static function proxy(string $method): void - { - static::$proxies[] = $method; - } - - /** - * Dynamically access collection proxies. - * - * @return mixed - * @throws \Exception - */ - public function __get(string $key) - { - if (! in_array($key, static::$proxies)) { - throw new Exception("Property [{$key}] does not exist on this collection instance."); - } - return new HigherOrderCollectionProxy($this, $key); - } - -} \ No newline at end of file diff --git a/src/utils/src/Composer.php b/src/utils/src/Composer.php deleted file mode 100644 index 9bef5a7a8..000000000 --- a/src/utils/src/Composer.php +++ /dev/null @@ -1,120 +0,0 @@ -offsetGet('packages') ?? [] as $package) { - $packageName = ''; - foreach ($package ?? [] as $key => $value) { - if ($key === 'name') { - $packageName = $value; - continue; - } - switch ($key) { - case 'extra': - $packageName && self::$extra[$packageName] = $value; - break; - case 'scripts': - $packageName && self::$scripts[$packageName] = $value; - break; - case 'version': - $packageName && self::$versions[$packageName] = $value; - break; - } - } - } - } - return self::$content; - } - - public static function discoverLockFile(): string - { - $path = ''; - if (file_exists(BASE_PATH . '/composer.lock') && is_readable(BASE_PATH . '/composer.lock')) { - $path = BASE_PATH . '/composer.lock'; - } - return $path; - } - - public static function getMergedExtra(string $key = null) - { - if (! self::$extra) { - self::getLockContent(); - } - if (null === $key) { - return self::$extra; - } - $extra = []; - foreach (self::$extra ?? [] as $project => $config) { - foreach ($config ?? [] as $configKey => $item) { - if ($key === $configKey && $item) { - foreach ($item ?? [] as $k => $v) { - if (is_array($v)) { - $extra[$k] = array_merge($extra[$k] ?? [], $v); - } else { - $extra[$k][] = $v; - } - } - } - } - } - return $extra; - } - - public static function getLoader(): ClassLoader - { - return self::findLoader(); - } - - private static function findLoader(): ClassLoader - { - $composerClass = ''; - foreach (get_declared_classes() as $declaredClass) { - if (strpos($declaredClass, 'ComposerAutoloaderInit') === 0 && method_exists($declaredClass, 'getLoader')) { - $composerClass = $declaredClass; - break; - } - } - if (! $composerClass) { - throw new \RuntimeException('Composer loader not found.'); - } - return $composerClass::getLoader(); - } - -} \ No newline at end of file diff --git a/src/utils/src/Context.php b/src/utils/src/Context.php deleted file mode 100644 index 7151ee1c6..000000000 --- a/src/utils/src/Context.php +++ /dev/null @@ -1,54 +0,0 @@ - 0) { - SwooleCoroutine::resume($id); - } - } - self::clear($key); - } - } -} \ No newline at end of file diff --git a/src/utils/src/Functions.php b/src/utils/src/Functions.php deleted file mode 100644 index cce27334f..000000000 --- a/src/utils/src/Functions.php +++ /dev/null @@ -1,578 +0,0 @@ - 1 && $value[0] === '"' && $value[$valueLength - 1] === '"') { - return substr($value, 1, -1); - } - return $value; - } -} -if (! function_exists('retry')) { - /** - * Retry an operation a given number of times. - * - * @param int $times - * @param callable $callback - * @param int $sleep - * @return mixed - * @throws \Exception - */ - function retry($times, callable $callback, $sleep = 0) - { - $times--; - beginning: - try { - return $callback(); - } catch (\Exception $e) { - if (! $times) { - throw $e; - } - $times--; - if ($sleep) { - usleep($sleep * 1000); - } - goto beginning; - } - } -} -if (! function_exists('with')) { - /** - * Return the given value, optionally passed through the given callback. - * - * @param mixed $value - * @param callable|null $callback - * @return mixed - */ - function with($value, callable $callback = null) - { - return is_null($callback) ? $value : $callback($value); - } -} - -/** - * Array helpers - */ -if (! function_exists('array_add')) { - /** - * Add an element to an array using "dot" notation if it doesn't exist. - * - * @param array $array - * @param string $key - * @param mixed $value - * @return array - */ - function array_add($array, $key, $value) - { - return Arr::add($array, $key, $value); - } -} -if (! function_exists('array_collapse')) { - /** - * Collapse an array of arrays into a single array. - * - * @param array $array - * @return array - */ - function array_collapse($array) - { - return Arr::collapse($array); - } -} -if (! function_exists('array_divide')) { - /** - * Divide an array into two arrays. One with keys and the other with values. - * - * @param array $array - * @return array - */ - function array_divide($array) - { - return Arr::divide($array); - } -} -if (! function_exists('array_dot')) { - /** - * Flatten a multi-dimensional associative array with dots. - * - * @param array $array - * @param string $prepend - * @return array - */ - function array_dot($array, $prepend = '') - { - return Arr::dot($array, $prepend); - } -} -if (! function_exists('array_except')) { - /** - * Get all of the given array except for a specified array of keys. - * - * @param array $array - * @param array|string $keys - * @return array - */ - function array_except($array, $keys) - { - return Arr::except($array, $keys); - } -} -if (! function_exists('array_first')) { - /** - * Return the first element in an array passing a given truth test. - * - * @param array $array - * @param callable|null $callback - * @param mixed $default - * @return mixed - */ - function array_first($array, callable $callback = null, $default = null) - { - return Arr::first($array, $callback, $default); - } -} -if (! function_exists('array_flatten')) { - /** - * Flatten a multi-dimensional array into a single level. - * - * @param array $array - * @param int $depth - * @return array - */ - function array_flatten($array, $depth = INF) - { - return Arr::flatten($array, $depth); - } -} -if (! function_exists('array_forget')) { - /** - * Remove one or many array items from a given array using "dot" notation. - * - * @param array $array - * @param array|string $keys - * @return void - */ - function array_forget(&$array, $keys) - { - return Arr::forget($array, $keys); - } -} -if (! function_exists('array_get')) { - /** - * Get an item from an array using "dot" notation. - * - * @param \ArrayAccess|array $array - * @param string $key - * @param mixed $default - * @return mixed - */ - function array_get($array, $key, $default = null) - { - return Arr::get($array, $key, $default); - } -} -if (! function_exists('array_has')) { - /** - * Check if an item or items exist in an array using "dot" notation. - * - * @param \ArrayAccess|array $array - * @param string|array $keys - * @return bool - */ - function array_has($array, $keys) - { - return Arr::has($array, $keys); - } -} -if (! function_exists('array_last')) { - /** - * Return the last element in an array passing a given truth test. - * - * @param array $array - * @param callable|null $callback - * @param mixed $default - * @return mixed - */ - function array_last($array, callable $callback = null, $default = null) - { - return Arr::last($array, $callback, $default); - } -} -if (! function_exists('array_only')) { - /** - * Get a subset of the items from the given array. - * - * @param array $array - * @param array|string $keys - * @return array - */ - function array_only($array, $keys) - { - return Arr::only($array, $keys); - } -} -if (! function_exists('array_pluck')) { - /** - * Pluck an array of values from an array. - * - * @param array $array - * @param string|array $value - * @param string|array|null $key - * @return array - */ - function array_pluck($array, $value, $key = null) - { - return Arr::pluck($array, $value, $key); - } -} -if (! function_exists('array_prepend')) { - /** - * Push an item onto the beginning of an array. - * - * @param array $array - * @param mixed $value - * @param mixed $key - * @return array - */ - function array_prepend($array, $value, $key = null) - { - return Arr::prepend($array, $value, $key); - } -} -if (! function_exists('array_pull')) { - /** - * Get a value from the array, and remove it. - * - * @param array $array - * @param string $key - * @param mixed $default - * @return mixed - */ - function array_pull(&$array, $key, $default = null) - { - return Arr::pull($array, $key, $default); - } -} -if (! function_exists('array_random')) { - /** - * Get a random value from an array. - * - * @param array $array - * @param int|null $num - * @return mixed - */ - function array_random($array, $num = null) - { - return Arr::random($array, $num); - } -} -if (! function_exists('array_set')) { - /** - * Set an array item to a given value using "dot" notation. - * If no key is given to the method, the entire array will be replaced. - * - * @param array $array - * @param string $key - * @param mixed $value - * @return array - */ - function array_set(&$array, $key, $value) - { - return Arr::set($array, $key, $value); - } -} -if (! function_exists('array_sort')) { - /** - * Sort the array by the given callback or attribute name. - * - * @param array $array - * @param callable|string|null $callback - * @return array - */ - function array_sort($array, $callback = null) - { - return Arr::sort($array, $callback); - } -} -if (! function_exists('array_sort_recursive')) { - /** - * Recursively sort an array by keys and values. - * - * @param array $array - * @return array - */ - function array_sort_recursive($array) - { - return Arr::sortRecursive($array); - } -} -if (! function_exists('array_where')) { - /** - * Filter the array using the given callback. - * - * @param array $array - * @param callable $callback - * @return array - */ - function array_where($array, callable $callback) - { - return Arr::where($array, $callback); - } -} -if (! function_exists('array_wrap')) { - /** - * If the given value is not an array, wrap it in one. - * - * @param mixed $value - * @return array - */ - function array_wrap($value) - { - return Arr::wrap($value); - } -} -if (! function_exists('collect')) { - /** - * Create a collection from the given value. - * - * @param mixed $value - * @return Collection - */ - function collect($value = null) - { - return new Collection($value); - } -} -if (! function_exists('data_fill')) { - /** - * Fill in data where it's missing. - * - * @param mixed $target - * @param string|array $key - * @param mixed $value - * @return mixed - */ - function data_fill(&$target, $key, $value) - { - return data_set($target, $key, $value, false); - } -} -if (! function_exists('data_get')) { - /** - * Get an item from an array or object using "dot" notation. - * - * @param mixed $target - * @param string|array $key - * @param mixed $default - * @return mixed - */ - function data_get($target, $key, $default = null) - { - if (is_null($key)) { - return $target; - } - $key = is_array($key) ? $key : explode('.', $key); - while (! is_null($segment = array_shift($key))) { - if ($segment === '*') { - if ($target instanceof Collection) { - $target = $target->all(); - } elseif (! is_array($target)) { - return value($default); - } - $result = []; - foreach ($target as $item) { - $result[] = data_get($item, $key); - } - return in_array('*', $key) ? Arr::collapse($result) : $result; - } - if (Arr::accessible($target) && Arr::exists($target, $segment)) { - $target = $target[$segment]; - } elseif (is_object($target) && isset($target->{$segment})) { - $target = $target->{$segment}; - } else { - return value($default); - } - } - return $target; - } -} -if (! function_exists('data_set')) { - /** - * Set an item on an array or object using dot notation. - * - * @param mixed $target - * @param string|array $key - * @param mixed $value - * @param bool $overwrite - * @return mixed - */ - function data_set(&$target, $key, $value, $overwrite = true) - { - $segments = is_array($key) ? $key : explode('.', $key); - if (($segment = array_shift($segments)) === '*') { - if (! Arr::accessible($target)) { - $target = []; - } - if ($segments) { - foreach ($target as &$inner) { - data_set($inner, $segments, $value, $overwrite); - } - } elseif ($overwrite) { - foreach ($target as &$inner) { - $inner = $value; - } - } - } elseif (Arr::accessible($target)) { - if ($segments) { - if (! Arr::exists($target, $segment)) { - $target[$segment] = []; - } - data_set($target[$segment], $segments, $value, $overwrite); - } elseif ($overwrite || ! Arr::exists($target, $segment)) { - $target[$segment] = $value; - } - } elseif (is_object($target)) { - if ($segments) { - if (! isset($target->{$segment})) { - $target->{$segment} = []; - } - data_set($target->{$segment}, $segments, $value, $overwrite); - } elseif ($overwrite || ! isset($target->{$segment})) { - $target->{$segment} = $value; - } - } else { - $target = []; - if ($segments) { - data_set($target[$segment], $segments, $value, $overwrite); - } elseif ($overwrite) { - $target[$segment] = $value; - } - } - return $target; - } -} -if (! function_exists('head')) { - /** - * Get the first element of an array. Useful for method chaining. - * - * @param array $array - * @return mixed - */ - function head($array) - { - return reset($array); - } -} -if (! function_exists('last')) { - /** - * Get the last element from an array. - * - * @param array $array - * @return mixed - */ - function last($array) - { - return end($array); - } -} -if (! function_exists('tap')) { - /** - * Call the given Closure with the given value then return the value. - * - * @param mixed $value - * @param callable|null $callback - * @return mixed - */ - function tap($value, $callback = null) - { - if (is_null($callback)) { - return new HigherOrderTapProxy($value); - } - $callback($value); - return $value; - } -} - -if (! function_exists('call')) { - /** - * Call a callback with the arguments. - * - * @param mixed $callback - * @param array $args - * @return mixed|null - */ - function call($callback, array $args = []) - { - $result = null; - if (is_object($callback) || (is_string($callback) && function_exists($callback))) { - $result = $callback(...$args); - } elseif (is_array($callback)) { - [$object, $method] = $callback; - $result = is_object($object) ? $object->$method(...$args) : $object::$method(...$args); - } else { - $result = call_user_func_array($callback, $args); - } - return $result; - } -} - -if (! function_exists('go')) { - /** - * @param callable $callback - */ - function go($callback) - { - \Hyperflex\Utils\Coroutine::create($callback); - } -} - -if (! function_exists('defer')) { - /** - * @param callable $callback - */ - function defer($callback): void - { - \Hyperflex\Utils\Coroutine::defer($callback); - } -} \ No newline at end of file diff --git a/src/utils/src/HigherOrderCollectionProxy.php b/src/utils/src/HigherOrderCollectionProxy.php deleted file mode 100644 index b42253d85..000000000 --- a/src/utils/src/HigherOrderCollectionProxy.php +++ /dev/null @@ -1,60 +0,0 @@ -method = $method; - $this->collection = $collection; - } - - /** - * Proxy accessing an attribute onto the collection items. - * - * @return mixed - */ - public function __get(string $key) - { - return $this->collection->{$this->method}(function ($value) use ($key) { - return is_array($value) ? $value[$key] : $value->{$key}; - }); - } - - /** - * Proxy a method call onto the collection items. - * - * @return mixed - */ - public function __call(string $method, array $parameters) - { - return $this->collection->{$this->method}(function ($value) use ($method, $parameters) { - return $value->{$method}(...$parameters); - }); - } - -} \ No newline at end of file diff --git a/src/utils/src/Pipeline.php b/src/utils/src/Pipeline.php deleted file mode 100644 index de637283e..000000000 --- a/src/utils/src/Pipeline.php +++ /dev/null @@ -1,150 +0,0 @@ -container = $container; - } - - /** - * Set the object being sent through the pipeline. - * - * @param mixed $passable - */ - public function send($passable): self - { - $this->passable = $passable; - - return $this; - } - - /** - * Set the array of pipes. - * - * @param array|mixed $pipes - */ - public function through($pipes): self - { - $this->pipes = is_array($pipes) ? $pipes : func_get_args(); - return $this; - } - - /** - * Set the method to call on the pipes. - */ - public function via(string $method): self - { - $this->method = $method; - - return $this; - } - - /** - * Run the pipeline with a final destination callback. - */ - public function then(Closure $destination) - { - $pipeline = array_reduce(array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)); - - return $pipeline($this->passable); - } - - /** - * Get the final piece of the Closure onion. - */ - protected function prepareDestination(Closure $destination): Closure - { - return function ($passable) use ($destination) { - return $destination($passable); - }; - } - - /** - * Get a Closure that represents a slice of the application onion. - */ - protected function carry(): Closure - { - return function ($stack, $pipe) { - return function ($passable) use ($stack, $pipe) { - if (is_callable($pipe)) { - // If the pipe is an instance of a Closure, we will just call it directly but - // otherwise we'll resolve the pipes out of the container and call it with - // the appropriate method and arguments, returning the results back out. - return $pipe($passable, $stack); - } elseif (! is_object($pipe)) { - [$name, $parameters] = $this->parsePipeString($pipe); - - // If the pipe is a string we will parse the string and resolve the class out - // of the dependency injection container. We can then build a callable and - // execute the pipe function giving in the parameters that are required. - $pipe = $this->container->get($name); - - $parameters = array_merge([$passable, $stack], $parameters); - } else { - // If the pipe is already an object we'll just make a callable and pass it to - // the pipe as-is. There is no need to do any extra parsing and formatting - // since the object we're given was already a fully instantiated object. - $parameters = [$passable, $stack]; - } - - return method_exists($pipe, $this->method) ? $pipe->{$this->method}(...$parameters) : $pipe(...$parameters); - }; - }; - } - - /** - * Parse full pipe string to get name and parameters. - * - * @param string $pipe - * @return array - */ - protected function parsePipeString($pipe) - { - [$name, $parameters] = array_pad(explode(':', $pipe, 2), 2, []); - - if (is_string($parameters)) { - $parameters = explode(',', $parameters); - } - - return [$name, $parameters]; - } - -} \ No newline at end of file diff --git a/src/utils/src/Traits/Container.php b/src/utils/src/Traits/Container.php deleted file mode 100644 index 3037a1c32..000000000 --- a/src/utils/src/Traits/Container.php +++ /dev/null @@ -1,38 +0,0 @@ - [ + 'host' => 'localhost', + 'port' => 5672, + 'user' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + ], + 'params' => [ + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'connection_timeout' => 3.0, + 'read_write_timeout' => 3.0, + 'context' => null, + 'keepalive' => false, + 'heartbeat' => 0, + ], + ], +]; +~~~ + +## 投递消息 + +使用generator工具新建一个producer +~~~ +php bin/hyperf.php gen:amqp-producer DemoProducer +~~~ + +在DemoProducer文件中,我们可以修改Producer注解对应的字段来替换对应的exchange和routingKey。 +其中payload就是最终投递到消息队列中的数据,所以我们可以随意改写__construct方法,只要最后赋值payload即可。 +示例如下。 + +~~~php +first(); + $this->payload = [ + 'id' => $id, + 'data' => $user->toArray() + ]; + } +} + +~~~ + +通过container获取Producer实例,即可投递消息。以下实例直接使用ApplicationContext获取Producer其实并不合理,container具体使用请到di模块中查看。 + +~~~php +get(Producer::class); +$result = $producer->produce($message); + +~~~ + +## 消费消息 + +使用generator工具新建一个consumer +~~~ +php bin/hyperf.php gen:amqp-consumer DemoConsumer +~~~ + +在DemoConsumer文件中,我们可以修改Consumer注解对应的字段来替换对应的exchange、routingKey和queue。 +其中$data就是解析后的元数据。 +示例如下。 + +~~~php + [ + 'driver' => Hyperf\Cache\Driver\RedisDriver::class, + 'packer' => Hyperf\Cache\Packer\PhpSerializer::class, + ], +]; +~~~ + +## 使用 + +组件提供Cacheable注解,作用于类方法,可以配置对应的缓存前缀、失效时间、监听器和缓存组。 +例如,UserService提供一个user方法,可以查询对应id的用户信息。当加上Cacheable注解后,会自动生成对应的Redis缓存,key值为`user:id`,超时时间为9000秒。首次查询时,会从DB中查,后面查询时,会从Cache中查。 + +~~~php +where('id',$id)->first(); + + if($user){ + return $user->toArray(); + } + + return null; + } +} +~~~ + +## 清理缓存 + +当然,如果我们DB中的数据改变了,如果删除缓存呢?这里就需要用到后面的监听器。下面新建一个Service提供一方法,来帮我们处理缓存。 + +~~~php +dispatcher->dispatch(new DeleteListenerEvent('user-update', [$userId])); + + return true; + } +} +~~~ \ No newline at end of file diff --git a/zh/core/README.md b/zh/core/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/zh/microservice/README.md b/zh/microservice/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/zh/model/README.md b/zh/model/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/zh/quick_start/install.md b/zh/quick_start/install.md new file mode 100644 index 000000000..b5f657d6f --- /dev/null +++ b/zh/quick_start/install.md @@ -0,0 +1 @@ +# 安装 \ No newline at end of file diff --git a/zh/quick_start/overview.md b/zh/quick_start/overview.md new file mode 100644 index 000000000..161d89dba --- /dev/null +++ b/zh/quick_start/overview.md @@ -0,0 +1,2 @@ +# 概要 + diff --git a/zh/quick_start/summary.md b/zh/quick_start/summary.md new file mode 100644 index 000000000..232afa37a --- /dev/null +++ b/zh/quick_start/summary.md @@ -0,0 +1,2 @@ +- [概要](zh/quick_start/overview.md) +- [安装](zh/quick_start/install.md) \ No newline at end of file