diff --git a/LICENSE b/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/composer.json b/composer.json
index fc9bb299..49c0b60c 100644
--- a/composer.json
+++ b/composer.json
@@ -17,7 +17,6 @@
"Max\\Database\\": "src/database/src",
"Max\\Di\\": "src/di/src",
"Max\\Event\\": "src/event/src",
- "Max\\": "src/framework/src",
"Max\\Http\\Server\\": "src/http-server/src",
"Max\\Http\\Message\\": "src/http-message/src",
"Max\\Routing\\": "src/routing/src",
@@ -45,7 +44,6 @@
"max/di": "*",
"max/aop": "*",
"max/event": "*",
- "max/framework": "*",
"max/http-message": "*",
"max/http-server": "*",
"max/log": "*",
diff --git a/src/aop/LICENSE b/src/aop/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/aop/LICENSE
+++ b/src/aop/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/aop/src/PropertyHandlerVisitor.php b/src/aop/src/PropertyHandlerVisitor.php
index 6a9c9a4f..f0ec42fc 100644
--- a/src/aop/src/PropertyHandlerVisitor.php
+++ b/src/aop/src/PropertyHandlerVisitor.php
@@ -78,9 +78,16 @@ public function leaveNode(Node $node)
foreach ($reflectionConstructor->getParameters() as $key => $reflectionParameter) {
$type = $reflectionParameter->getType();
if (is_null($type)
- || ($type instanceof ReflectionNamedType && $type->isBuiltin())
- || $type instanceof ReflectionUnionType
- || $type->getName() === 'Closure') {
+ || ($type instanceof ReflectionNamedType && ($type->isBuiltin() || $type->getName() === 'Closure'))
+ ) {
+ continue;
+ }
+ if ($type instanceof ReflectionUnionType) {
+ $unionType = [];
+ foreach ($type->getTypes() as $reflectionNamedType) {
+ $unionType[] = ($reflectionNamedType->isBuiltin() ? '' : '\\') . $reflectionNamedType->getName();
+ }
+ $params[$key]->type = new Name(implode('|', $unionType));
continue;
}
$allowsNull = $reflectionParameter->allowsNull() ? '?' : '';
@@ -88,7 +95,7 @@ public function leaveNode(Node $node)
}
}
$c = [];
- if (! $this->metadata->hasConstructor) {
+ if (!$this->metadata->hasConstructor) {
$constructor = new ClassMethod('__construct', [
'params' => $params,
]);
diff --git a/src/aop/src/Scanner.php b/src/aop/src/Scanner.php
index bbe6f424..dc6315d6 100644
--- a/src/aop/src/Scanner.php
+++ b/src/aop/src/Scanner.php
@@ -53,7 +53,7 @@ public static function init(ScannerConfig $config): void
self::$astManager = new AstManager();
self::$classMap = self::findClasses($config->getPaths());
self::$proxyMap = $proxyMap = self::$runtimeDir . 'proxy.php';
- if (!$config->isCache() || !self::$filesystem->exists($proxyMap)) {
+ if (! $config->isCache() || ! self::$filesystem->exists($proxyMap)) {
self::$filesystem->exists($proxyMap) && self::$filesystem->delete($proxyMap);
if (($pid = pcntl_fork()) == -1) {
throw new Exception('Process fork failed.');
@@ -79,25 +79,6 @@ public static function findClasses(array $dirs): array
return $classes;
}
- public static function scanConfig(string $installedJsonDir): array
- {
- $installed = json_decode(file_get_contents($installedJsonDir), true);
- $installed = $installed['packages'] ?? $installed;
- $config = [];
- foreach ($installed as $package) {
- if (isset($package['extra']['max']['config'])) {
- $configProvider = $package['extra']['max']['config'];
- $configProvider = new $configProvider();
- if (method_exists($configProvider, '__invoke')) {
- if (is_array($configItem = $configProvider())) {
- $config = array_merge_recursive($config, $configItem);
- }
- }
- }
- }
- return $config;
- }
-
public static function addClass(string $class, string $path): void
{
self::$classMap[$class] = $path;
@@ -110,7 +91,7 @@ private static function getProxyMap(array $collectors): array
{
if (! self::$filesystem->exists(self::$proxyMap)) {
$proxyDir = self::$runtimeDir . 'proxy/';
- self::$filesystem->makeDirectory($proxyDir, 0755, true, true);
+ self::$filesystem->exists($proxyDir) || self::$filesystem->makeDirectory($proxyDir, 0755, true, true);
self::$filesystem->cleanDirectory($proxyDir);
self::collect($collectors);
$collectedClasses = array_unique(array_merge(AspectCollector::getCollectedClasses(), PropertyAnnotationCollector::getCollectedClasses()));
diff --git a/src/cache/LICENSE b/src/cache/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/cache/LICENSE
+++ b/src/cache/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/cache/publish/cache.php b/src/cache/publish/cache.php
index 9974eab4..9726e710 100644
--- a/src/cache/publish/cache.php
+++ b/src/cache/publish/cache.php
@@ -32,5 +32,9 @@
'port' => 11211, // 端口
],
],
+ 'apcu' => [
+ 'driver' => \Max\Cache\Driver\ApcDriver::class,
+ 'config' => [],
+ ],
],
];
diff --git a/src/cache/src/Driver/ApcDriver.php b/src/cache/src/Driver/ApcDriver.php
index 3ddb7682..3980544c 100644
--- a/src/cache/src/Driver/ApcDriver.php
+++ b/src/cache/src/Driver/ApcDriver.php
@@ -15,37 +15,37 @@ class ApcDriver extends AbstractDriver
{
public function has(string $key): bool
{
- return (bool) apc_exists($key);
+ return (bool) \apc_exists($key);
}
public function get(string $key): mixed
{
- $data = apc_fetch($key, $success);
+ $data = \apc_fetch($key, $success);
return $success === true ? $data : null;
}
public function set(string $key, mixed $value, ?int $ttl = null): bool
{
- return (bool) apc_store($key, $value, (int) $ttl);
+ return (bool) \apc_store($key, $value, (int) $ttl);
}
public function clear(): bool
{
- return apc_clear_cache('user');
+ return \apc_clear_cache('user');
}
public function delete(string $key): bool
{
- return (bool) apc_delete($key);
+ return (bool) \apc_delete($key);
}
public function increment(string $key, int $step = 1): int|bool
{
- return apc_inc($key, $step);
+ return \apc_inc($key, $step);
}
public function decrement(string $key, int $step = 1): int|bool
{
- return apc_dec($key, $step);
+ return \apc_dec($key, $step);
}
}
diff --git a/src/config/LICENSE b/src/config/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/config/LICENSE
+++ b/src/config/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/config/composer.json b/src/config/composer.json
index fcdb7957..9fc66ec7 100644
--- a/src/config/composer.json
+++ b/src/config/composer.json
@@ -20,10 +20,5 @@
"require": {
"php": "^8.0",
"max/utils": "^1.0"
- },
- "extra": {
- "max": {
- "config": "Max\\Config\\ConfigProvider"
- }
}
}
diff --git a/src/config/src/ConfigProvider.php b/src/config/src/ConfigProvider.php
deleted file mode 100644
index 6a81f4c3..00000000
--- a/src/config/src/ConfigProvider.php
+++ /dev/null
@@ -1,24 +0,0 @@
- [
- 'Max\Config\Contract\ConfigInterface' => 'Max\Config\Repository',
- ],
- ];
- }
-}
diff --git a/src/context/LICENSE b/src/context/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/context/LICENSE
+++ b/src/context/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/database/LICENSE b/src/database/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/database/LICENSE
+++ b/src/database/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/di/LICENSE b/src/di/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/di/LICENSE
+++ b/src/di/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/event/LICENSE b/src/event/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/event/LICENSE
+++ b/src/event/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/event/composer.json b/src/event/composer.json
index 1696ebe0..2369ba17 100644
--- a/src/event/composer.json
+++ b/src/event/composer.json
@@ -23,10 +23,5 @@
"require": {
"php": "^8.0",
"psr/event-dispatcher": "^1.0"
- },
- "extra": {
- "max": {
- "config": "Max\\Event\\ConfigProvider"
- }
}
}
diff --git a/src/event/src/ConfigProvider.php b/src/event/src/ConfigProvider.php
deleted file mode 100644
index 1f3a92f3..00000000
--- a/src/event/src/ConfigProvider.php
+++ /dev/null
@@ -1,26 +0,0 @@
- [
- 'Psr\EventDispatcher\ListenerProviderInterface' => 'Max\Event\ListenerProvider',
- 'Psr\EventDispatcher\EventDispatcherInterface' => 'Max\Event\EventDispatcher',
- 'Max\Event\Contract\EventDispatcherInterface' => 'Max\Event\EventDispatcher',
- ],
- ];
- }
-}
diff --git a/src/framework/LICENSE b/src/framework/LICENSE
deleted file mode 100644
index 261eeb9e..00000000
--- a/src/framework/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/src/framework/README.md b/src/framework/README.md
deleted file mode 100644
index e845566c..00000000
--- a/src/framework/README.md
+++ /dev/null
@@ -1 +0,0 @@
-README
diff --git a/src/framework/composer.json b/src/framework/composer.json
deleted file mode 100644
index 25d62eb0..00000000
--- a/src/framework/composer.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "max/framework",
- "license": "Apache-2.0",
- "homepage": "https://github.com/marxphp/framework",
- "autoload": {
- "psr-4": {
- "Max\\": "src/"
- }
- },
- "authors": [
- {
- "name": "chengyao",
- "email": "987861463@qq.com"
- }
- ],
- "require": {
- "max/http-message": "^1.0",
- "symfony/console": "*",
- "filp/whoops": "*"
- },
- "extra": {
- "max": {
- "config": "Max\\ConfigProvider"
- }
- }
-}
diff --git a/src/framework/src/Cache/Aspect/Cacheable.php b/src/framework/src/Cache/Aspect/Cacheable.php
deleted file mode 100644
index 24edc568..00000000
--- a/src/framework/src/Cache/Aspect/Cacheable.php
+++ /dev/null
@@ -1,47 +0,0 @@
-store()->remember($this->getKey($joinPoint), fn () => $next($joinPoint), $this->ttl);
- }
-
- protected function getKey(JoinPoint $joinPoint): string
- {
- $key = $this->key ?? ($joinPoint->class . ':' . $joinPoint->method . ':' . serialize(array_filter($joinPoint->parameters->getArrayCopy(), fn ($item) => ! is_object($item))));
- return $this->prefix ? ($this->prefix . ':' . $key) : $key;
- }
-}
diff --git a/src/framework/src/Config/Annotation/Config.php b/src/framework/src/Config/Annotation/Config.php
deleted file mode 100644
index 338f07b3..00000000
--- a/src/framework/src/Config/Annotation/Config.php
+++ /dev/null
@@ -1,56 +0,0 @@
-setAccessible(true); // 兼容PHP8.0
- $reflectionProperty->setValue($object, $this->getConfigValue());
- } catch (\Throwable $throwable) {
- throw new PropertyHandleException('Property assign failed. ' . $throwable->getMessage());
- }
- }
-
- /**
- * 获取配置值
- *
- * @throws ContainerExceptionInterface
- * @throws ReflectionException
- */
- protected function getConfigValue()
- {
- return make(ConfigInterface::class)->get($this->key, $this->default);
- }
-}
diff --git a/src/framework/src/ConfigProvider.php b/src/framework/src/ConfigProvider.php
deleted file mode 100644
index 6cfbe66b..00000000
--- a/src/framework/src/ConfigProvider.php
+++ /dev/null
@@ -1,29 +0,0 @@
- [
- 'Max\Console\Command\RouteListCommand',
- 'Max\Console\Command\ControllerMakeCommand',
- 'Max\Console\Command\MiddlewareMakeCommand',
- ],
- ];
- }
-}
diff --git a/src/framework/src/Console/Annotation/Command.php b/src/framework/src/Console/Annotation/Command.php
deleted file mode 100644
index b64a1cfa..00000000
--- a/src/framework/src/Console/Annotation/Command.php
+++ /dev/null
@@ -1,22 +0,0 @@
-setName('make:controller')
- ->setDescription('Making controllers.')
- ->setDefinition([
- new InputArgument('controller', InputArgument::REQUIRED, 'A controller name such as `user`.'),
- new InputOption('rest', 'r', InputOption::VALUE_OPTIONAL, 'Make a restful controller.'),
- ]);
- }
-
- /**
- * @throws FileNotFoundException
- * @return int
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $filesystem = new Filesystem();
- $controller = $input->getArgument('controller');
- $stubFile = $this->stubsPath . ($input->hasOption('rest') ? 'controller_rest.stub' : 'controller.stub');
- [$namespace, $controller] = $this->parse($controller);
- $controllerPath = base_path('app/Http/Controller/' . str_replace('\\', '/', $namespace) . '/');
- $controllerFile = $controllerPath . $controller . 'Controller.php';
- if ($filesystem->exists($controllerFile)) {
- $output->writeln('[WARN] 控制器已经存在!');
- return 1;
- }
- $filesystem->exists($controllerPath) || $filesystem->makeDirectory($controllerPath, 0777, true);
- $filesystem->put($controllerFile, str_replace(['{{namespace}}', '{{class}}', '{{path}}'], ['App\\Http\\Controller' . $namespace, $controller . 'Controller', strtolower($controller)], $filesystem->get($stubFile)));
- $output->writeln("[INFO] 控制器App\\Http\\Controller{$namespace}\\{$controller}Controller创建成功!");
-
- return 1;
- }
-
- /**
- * @param $input
- */
- protected function parse($input): array
- {
- $array = explode('/', $input);
- $class = ucfirst(array_pop($array));
- $namespace = implode('\\', array_map(fn ($value) => ucfirst($value), $array));
- if (! empty($namespace)) {
- $namespace = '\\' . $namespace;
- }
- return [$namespace, $class];
- }
-}
diff --git a/src/framework/src/Console/Command/MiddlewareMakeCommand.php b/src/framework/src/Console/Command/MiddlewareMakeCommand.php
deleted file mode 100644
index a1fbeb95..00000000
--- a/src/framework/src/Console/Command/MiddlewareMakeCommand.php
+++ /dev/null
@@ -1,70 +0,0 @@
-setName('make:middleware')
- ->setDescription('Making middleware.')
- ->setDefinition([
- new InputArgument('middleware', InputArgument::REQUIRED, 'A middleware name such as `auth`.'),
- new InputOption('suffix', 's', InputOption::VALUE_OPTIONAL, 'File is suffixed when this option is available.'),
- ]);
- }
-
- /**
- * @throws Exception
- * @return int
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $filesystem = new Filesystem();
- $stubFile = $this->stubsPath . 'middleware.stub';
- [$namespace, $middleware] = $this->parse($input->getArgument('middleware'));
- $middlewarePath = base_path('app/Http/Middleware/' . str_replace('\\', '/', $namespace) . '/');
- $filesystem->exists($middlewarePath) || $filesystem->makeDirectory($middlewarePath, 0755, true);
- $suffix = $input->getOption('suffix') ? 'Middleware' : '';
- $middlewareFile = $middlewarePath . $middleware . $suffix . '.php';
- $filesystem->exists($middlewareFile) && throw new InvalidArgumentException('中间件已经存在!');
- $filesystem->put($middlewareFile, str_replace(['{{namespace}}', '{{class}}'], ['App\\Http\\Middleware' . $namespace, $middleware . $suffix], file_get_contents($stubFile)));
- $output->writeln("[DEBU]中间件App\\Http\\Middleware{$namespace}\\{$middleware}创建成功!");
-
- return 1;
- }
-
- /**
- * @param $input
- */
- protected function parse($input): array
- {
- $array = explode('/', $input);
- $class = ucfirst(array_pop($array));
- $namespace = implode('\\', array_map(fn ($value) => ucfirst($value), $array));
- if (! empty($namespace)) {
- $namespace = '\\' . $namespace;
- }
- return [$namespace, $class];
- }
-}
diff --git a/src/framework/src/Console/Command/RouteListCommand.php b/src/framework/src/Console/Command/RouteListCommand.php
deleted file mode 100644
index 7af082d4..00000000
--- a/src/framework/src/Console/Command/RouteListCommand.php
+++ /dev/null
@@ -1,89 +0,0 @@
-setHeaders(['Methods', 'URI', 'Action', 'Middlewares']);
- foreach ($this->getRoutes() as $route) {
- $table->addRow([
- implode('|', $route->getMethods()),
- $route->getPath(),
- $this->formatRouteAction($route),
- implode(PHP_EOL, $route->getMiddlewares()),
- ]);
- }
- $table->render();
- return 0;
- }
-
- protected function configure()
- {
- $this->setName('route:list')
- ->setDescription('List the routes');
- }
-
- /**
- * @throws ContainerExceptionInterface
- * @throws NotFoundException
- * @throws ReflectionException
- */
- protected function getRoutes(): Collection
- {
- $kernel = make(Kernel::class);
- $routes = [];
- foreach ($kernel->getAllRoutes() as $registeredRoute) {
- foreach ($registeredRoute as $route) {
- if (! in_array($route, $routes)) {
- $routes[] = $route;
- }
- }
- }
- return Collection::make($routes)->unique();
- }
-
- /**
- * 格式化action为string.
- */
- protected function formatRouteAction(Route $route): string
- {
- $action = $route->getAction();
- if ($action instanceof Closure) {
- return 'Closure';
- }
- if (is_array($action)) {
- return implode('@', $action);
- }
- return $action;
- }
-}
diff --git a/src/framework/src/Console/Command/VendorPublishCommand.php b/src/framework/src/Console/Command/VendorPublishCommand.php
deleted file mode 100644
index fc328150..00000000
--- a/src/framework/src/Console/Command/VendorPublishCommand.php
+++ /dev/null
@@ -1,45 +0,0 @@
-setName('vendor:publish')
- ->setDescription('Publish publishable packages');
- }
-
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $path = getcwd();
- $config = Scanner::scanConfig($path . '/vendor/composer/installed.json');
- if (isset($config['publish'])) {
- foreach ($config['publish'] as $publish) {
- $destination = $publish['destination'];
- if (! file_exists($destination)) {
- copy($publish['source'], $publish['destination']);
- $output->writeln('[DEBUG] Package `' . $publish['name'] . '` config file published.');
- }
- }
- }
- $path .= '/runtime/app/';
- file_exists($path) || mkdir($path);
- file_put_contents($path . 'config.php', sprintf("')]
- public function show(ServerRequestInterface $request, $id): ResponseInterface
- {
- }
-
- #[DeleteMapping(path: '/')]
- public function delete(ServerRequestInterface $request, $id): ResponseInterface
- {
- }
-
- #[RequestMapping(path: '/', methods: ['PUT', 'PATCH'])]
- public function update(ServerRequestInterface $request, $id): ResponseInterface
- {
- }
-}
diff --git a/src/framework/src/Console/Command/stubs/middleware.stub b/src/framework/src/Console/Command/stubs/middleware.stub
deleted file mode 100644
index 8f395d8f..00000000
--- a/src/framework/src/Console/Command/stubs/middleware.stub
+++ /dev/null
@@ -1,28 +0,0 @@
-handle($request);
- // after
- return $response;
- }
-}
diff --git a/src/framework/src/Console/CommandCollector.php b/src/framework/src/Console/CommandCollector.php
deleted file mode 100644
index 6f9b4bf9..00000000
--- a/src/framework/src/Console/CommandCollector.php
+++ /dev/null
@@ -1,40 +0,0 @@
-addListener(make($class));
- }
- }
-}
diff --git a/src/framework/src/Exception/Handler/WhoopsExceptionHandler.php b/src/framework/src/Exception/Handler/WhoopsExceptionHandler.php
deleted file mode 100644
index 7733cbb0..00000000
--- a/src/framework/src/Exception/Handler/WhoopsExceptionHandler.php
+++ /dev/null
@@ -1,87 +0,0 @@
- PrettyPageHandler::class,
- 'application/json' => JsonResponseHandler::class,
- 'application/xml' => XmlResponseHandler::class,
- ];
-
- public function handle(Throwable $throwable, ServerRequestInterface $request): ?ResponseInterface
- {
- $whoops = new Run();
- [$handler, $contentType] = $this->negotiateHandler($request);
-
- $whoops->pushHandler($handler);
- $whoops->allowQuit(false);
- ob_start();
- $whoops->{RunInterface::EXCEPTION_HANDLER}($throwable);
- $content = ob_get_clean();
-
- return new Response(StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR, [HeaderInterface::HEADER_CONTENT_TYPE => $contentType], StandardStream::create((string)$content));
- }
-
- protected function negotiateHandler(ServerRequestInterface $request): array
- {
- $accepts = $request->getHeaderLine(HeaderInterface::HEADER_ACCEPT);
- foreach (self::$preference as $contentType => $handler) {
- if (Str::contains($accepts, $contentType)) {
- return [$this->setupHandler(new $handler(), $request), $contentType];
- }
- }
- return [new PlainTextHandler(), 'text/plain'];
- }
-
- protected function setupHandler($handler, ServerRequestInterface $request)
- {
- if ($handler instanceof PrettyPageHandler) {
- $handler->handleUnconditionally(true);
-
- if (defined('BASE_PATH')) {
- $handler->setApplicationRootPath(BASE_PATH);
- }
-
- $handler->addDataTableCallback('GET Data', [$request, 'getQueryParams']);
- $handler->addDataTableCallback('POST Data', [$request, 'getParsedBody']);
- $handler->addDataTableCallback('Server/Request Data', [$request, 'getServerParams']);
- $handler->addDataTableCallback('Cookies', [$request, 'getCookieParams']);
- $handler->addDataTableCallback('Files', [$request, 'getUploadedFiles']);
- $handler->addDataTableCallback('Attribute', [$request, 'getAttributes']);
- try {
- $handler->addDataTableCallback('Session', [$request->session(), 'all']);
- } catch (Throwable) {
- }
- } elseif ($handler instanceof JsonResponseHandler) {
- $handler->addTraceToOutput(true);
- }
-
- return $handler;
- }
-}
diff --git a/src/framework/src/Http/Annotation/JsonResponse.php b/src/framework/src/Http/Annotation/JsonResponse.php
deleted file mode 100644
index 32bde0e2..00000000
--- a/src/framework/src/Http/Annotation/JsonResponse.php
+++ /dev/null
@@ -1,29 +0,0 @@
- 'application/json'], $data);
- }
-}
diff --git a/src/framework/src/Http/Server/RouteCollector.php b/src/framework/src/Http/Server/RouteCollector.php
deleted file mode 100644
index 20defa34..00000000
--- a/src/framework/src/Http/Server/RouteCollector.php
+++ /dev/null
@@ -1,58 +0,0 @@
-make(\Max\Routing\RouteCollector::class);
- $router = new Router($attribute->prefix, $attribute->patterns, middlewares: $attribute->middlewares, routeCollector: $routeCollector);
- self::$router = $router;
- self::$class = $class;
- }
- }
-
- /**
- * @throws NotFoundException
- */
- public static function collectMethod(string $class, string $method, object $attribute): void
- {
- if ($attribute instanceof RequestMapping && self::$class === $class && !is_null(self::$router)) {
- self::$router->request($attribute->path, [$class, $method], $attribute->methods)->middleware(...$attribute->middlewares);
- }
- }
-}
diff --git a/src/http-message/LICENSE b/src/http-message/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/http-message/LICENSE
+++ b/src/http-message/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/http-message/src/UploadedFile.php b/src/http-message/src/UploadedFile.php
index 865792d7..8e582964 100644
--- a/src/http-message/src/UploadedFile.php
+++ b/src/http-message/src/UploadedFile.php
@@ -129,4 +129,9 @@ public function getMimeType(): string
}
return $this->mimeType = (string)mime_content_type($this->tmpFilename);
}
+
+ public function isValid(): bool
+ {
+ return $this->error === UPLOAD_ERR_OK;
+ }
}
diff --git a/src/http-server/LICENSE b/src/http-server/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/http-server/LICENSE
+++ b/src/http-server/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/http-server/src/Middleware/AllowCrossDomain.php b/src/http-server/src/Middleware/AllowCrossDomain.php
index 38606085..86034aa6 100644
--- a/src/http-server/src/Middleware/AllowCrossDomain.php
+++ b/src/http-server/src/Middleware/AllowCrossDomain.php
@@ -40,7 +40,7 @@ class AllowCrossDomain implements MiddlewareInterface
'If-Modified-Since',
'If-None-Match',
'If-Unmodified-Since',
- 'X-CSRF-TOKEN',
+ 'X-Csrf-Token',
HeaderInterface::HEADER_X_REQUESTED_WITH,
];
diff --git a/src/macro/LICENSE b/src/macro/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/macro/LICENSE
+++ b/src/macro/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/redis/LICENSE b/src/redis/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/redis/LICENSE
+++ b/src/redis/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/routing/LICENSE b/src/routing/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/routing/LICENSE
+++ b/src/routing/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/session/LICENSE b/src/session/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/session/LICENSE
+++ b/src/session/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/swoole/LICENSE b/src/swoole/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/swoole/LICENSE
+++ b/src/swoole/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/utils/LICENSE b/src/utils/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/utils/LICENSE
+++ b/src/utils/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/utils/src/Contract/ValidatedData.php b/src/utils/src/Contract/ValidatedData.php
new file mode 100644
index 00000000..c8a833fc
--- /dev/null
+++ b/src/utils/src/Contract/ValidatedData.php
@@ -0,0 +1,10 @@
+
+ * @implements ArrayAccess
+ */
+class Fluent implements Arrayable, ArrayAccess, Jsonable, JsonSerializable
+{
+ /**
+ * All of the attributes set on the fluent instance.
+ *
+ * @var array
+ */
+ protected $attributes = [];
+
+ /**
+ * Create a new fluent instance.
+ *
+ * @param iterable $attributes
+ *
+ * @return void
+ */
+ public function __construct($attributes = [])
+ {
+ foreach ($attributes as $key => $value) {
+ $this->attributes[$key] = $value;
+ }
+ }
+
+ /**
+ * Get an attribute from the fluent instance.
+ *
+ * @template TGetDefault
+ *
+ * @param TKey $key
+ * @param TGetDefault|(\Closure(): TGetDefault) $default
+ *
+ * @return TValue|TGetDefault
+ */
+ public function get($key, $default = null)
+ {
+ if (array_key_exists($key, $this->attributes)) {
+ return $this->attributes[$key];
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Get the attributes from the fluent instance.
+ *
+ * @return array
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the fluent instance to an array.
+ *
+ * @return array
+ */
+ public function toArray(): array
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize(): array
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the fluent instance to JSON.
+ *
+ * @param int $options
+ *
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Determine if the given offset exists.
+ *
+ * @param TKey $offset
+ *
+ * @return bool
+ */
+ public function offsetExists($offset): bool
+ {
+ return isset($this->attributes[$offset]);
+ }
+
+ /**
+ * Get the value for a given offset.
+ *
+ * @param TKey $offset
+ *
+ * @return TValue|null
+ */
+ public function offsetGet($offset): mixed
+ {
+ return $this->get($offset);
+ }
+
+ /**
+ * Set the value at the given offset.
+ *
+ * @param TKey $offset
+ * @param TValue $value
+ *
+ * @return void
+ */
+ public function offsetSet($offset, $value): void
+ {
+ $this->attributes[$offset] = $value;
+ }
+
+ /**
+ * Unset the value at the given offset.
+ *
+ * @param TKey $offset
+ *
+ * @return void
+ */
+ public function offsetUnset($offset): void
+ {
+ unset($this->attributes[$offset]);
+ }
+
+ /**
+ * Handle dynamic calls to the fluent instance to set attributes.
+ *
+ * @param TKey $method
+ * @param array{0: ?TValue} $parameters
+ *
+ * @return $this
+ */
+ public function __call($method, $parameters)
+ {
+ $this->attributes[$method] = count($parameters) > 0 ? $parameters[0] : true;
+
+ return $this;
+ }
+
+ /**
+ * Dynamically retrieve the value of an attribute.
+ *
+ * @param TKey $key
+ *
+ * @return TValue|null
+ */
+ public function __get($key)
+ {
+ return $this->get($key);
+ }
+
+ /**
+ * Dynamically set the value of an attribute.
+ *
+ * @param TKey $key
+ * @param TValue $value
+ *
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->offsetSet($key, $value);
+ }
+
+ /**
+ * Dynamically check if an attribute is set.
+ *
+ * @param TKey $key
+ *
+ * @return bool
+ */
+ public function __isset($key)
+ {
+ return $this->offsetExists($key);
+ }
+
+ /**
+ * Dynamically unset an attribute.
+ *
+ * @param TKey $key
+ *
+ * @return void
+ */
+ public function __unset($key)
+ {
+ $this->offsetUnset($key);
+ }
+
+ public function __toString(): string
+ {
+ return $this->toJson();
+ }
+}
diff --git a/src/utils/src/MessageBag.php b/src/utils/src/MessageBag.php
new file mode 100644
index 00000000..918f68c9
--- /dev/null
+++ b/src/utils/src/MessageBag.php
@@ -0,0 +1,428 @@
+ $value) {
+ $value = $value instanceof Arrayable ? $value->toArray() : (array)$value;
+
+ $this->messages[$key] = array_unique($value);
+ }
+ }
+
+ /**
+ * Get the keys present in the message bag.
+ *
+ * @return array
+ */
+ public function keys(): array
+ {
+ return array_keys($this->messages);
+ }
+
+ /**
+ * Add a message to the message bag.
+ *
+ * @param string $key
+ * @param string $message
+ *
+ * @return $this
+ */
+ public function add($key, $message): MessageBag
+ {
+ if ($this->isUnique($key, $message)) {
+ $this->messages[$key][] = $message;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a message to the message bag if the given conditional is "true".
+ *
+ * @param bool $boolean
+ * @param string $key
+ * @param string $message
+ *
+ * @return $this
+ */
+ public function addIf($boolean, $key, $message)
+ {
+ return $boolean ? $this->add($key, $message) : $this;
+ }
+
+ /**
+ * Determine if a key and message combination already exists.
+ *
+ * @param string $key
+ * @param string $message
+ *
+ * @return bool
+ */
+ protected function isUnique($key, $message)
+ {
+ $messages = (array)$this->messages;
+
+ return !isset($messages[$key]) || !in_array($message, $messages[$key]);
+ }
+
+ /**
+ * Merge a new array of messages into the message bag.
+ *
+ * @param \Illuminate\Contracts\Support\MessageProvider|array $messages
+ *
+ * @return $this
+ */
+ public function merge($messages)
+ {
+ if ($messages instanceof MessageProvider) {
+ $messages = $messages->getMessageBag()->getMessages();
+ }
+
+ $this->messages = array_merge_recursive($this->messages, $messages);
+
+ return $this;
+ }
+
+ /**
+ * Determine if messages exist for all of the given keys.
+ *
+ * @param array|string|null $key
+ *
+ * @return bool
+ */
+ public function has($key): bool
+ {
+ if ($this->isEmpty()) {
+ return false;
+ }
+
+ if (is_null($key)) {
+ return $this->any();
+ }
+
+ $keys = is_array($key) ? $key : func_get_args();
+
+ foreach ($keys as $key) {
+ if ($this->first($key) === '') {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Determine if messages exist for any of the given keys.
+ *
+ * @param array|string $keys
+ *
+ * @return bool
+ */
+ public function hasAny($keys = [])
+ {
+ if ($this->isEmpty()) {
+ return false;
+ }
+
+ $keys = is_array($keys) ? $keys : func_get_args();
+
+ foreach ($keys as $key) {
+ if ($this->has($key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the first message from the message bag for a given key.
+ *
+ * @param string|null $key
+ * @param string|null $format
+ *
+ * @return string
+ */
+ public function first($key = null, $format = null): string
+ {
+ $messages = is_null($key) ? $this->all($format) : $this->get($key, $format);
+
+ $firstMessage = Arr::first($messages, null, '');
+
+ return is_array($firstMessage) ? Arr::first($firstMessage) : $firstMessage;
+ }
+
+ /**
+ * Get all of the messages from the message bag for a given key.
+ *
+ * @param string $key
+ * @param string|null $format
+ *
+ * @return array
+ */
+ public function get($key, $format = null): array
+ {
+ // If the message exists in the message bag, we will transform it and return
+ // the message. Otherwise, we will check if the key is implicit & collect
+ // all the messages that match the given key and output it as an array.
+ if (array_key_exists($key, $this->messages)) {
+ return $this->transform(
+ $this->messages[$key], $this->checkFormat($format), $key
+ );
+ }
+
+ if (Str::contains($key, '*')) {
+ return $this->getMessagesForWildcardKey($key, $format);
+ }
+
+ return [];
+ }
+
+ /**
+ * Get the messages for a wildcard key.
+ *
+ * @param string $key
+ * @param string|null $format
+ *
+ * @return array
+ */
+ protected function getMessagesForWildcardKey($key, $format)
+ {
+ return collect($this->messages)
+ ->filter(function($messages, $messageKey) use ($key) {
+ return Str::is($key, $messageKey);
+ })
+ ->map(function($messages, $messageKey) use ($format) {
+ return $this->transform(
+ $messages, $this->checkFormat($format), $messageKey
+ );
+ })->all();
+ }
+
+ /**
+ * Get all of the messages for every key in the message bag.
+ *
+ * @param string|null $format
+ *
+ * @return array
+ */
+ public function all($format = null): array
+ {
+ $format = $this->checkFormat($format);
+
+ $all = [];
+
+ foreach ($this->messages as $key => $messages) {
+ $all = array_merge($all, $this->transform($messages, $format, $key));
+ }
+
+ return $all;
+ }
+
+ /**
+ * Get all of the unique messages for every key in the message bag.
+ *
+ * @param string|null $format
+ *
+ * @return array
+ */
+ public function unique($format = null)
+ {
+ return array_unique($this->all($format));
+ }
+
+ /**
+ * Format an array of messages.
+ *
+ * @param array $messages
+ * @param string $format
+ * @param string $messageKey
+ *
+ * @return array
+ */
+ protected function transform($messages, $format, $messageKey)
+ {
+ return collect((array)$messages)
+ ->map(function($message) use ($format, $messageKey) {
+ // We will simply spin through the given messages and transform each one
+ // replacing the :message place holder with the real message allowing
+ // the messages to be easily formatted to each developer's desires.
+ return str_replace([':message', ':key'], [$message, $messageKey], $format);
+ })->all();
+ }
+
+ /**
+ * Get the appropriate format based on the given format.
+ *
+ * @param string $format
+ *
+ * @return string
+ */
+ protected function checkFormat($format)
+ {
+ return $format ?: $this->format;
+ }
+
+ /**
+ * Get the raw messages in the message bag.
+ *
+ * @return array
+ */
+ public function messages()
+ {
+ return $this->messages;
+ }
+
+ /**
+ * Get the raw messages in the message bag.
+ *
+ * @return array
+ */
+ public function getMessages(): array
+ {
+ return $this->messages();
+ }
+
+ /**
+ * Get the messages for the instance.
+ */
+ public function getMessageBag(): MessageBag
+ {
+ return $this;
+ }
+
+ /**
+ * Get the default message format.
+ *
+ * @return string
+ */
+ public function getFormat(): string
+ {
+ return $this->format;
+ }
+
+ /**
+ * Set the default message format.
+ *
+ * @param string $format
+ */
+ public function setFormat($format = ':message')
+ {
+ $this->format = $format;
+
+ return $this;
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function isEmpty(): bool
+ {
+ return !$this->any();
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function isNotEmpty(): bool
+ {
+ return $this->any();
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function any()
+ {
+ return $this->count() > 0;
+ }
+
+ /**
+ * Get the number of messages in the message bag.
+ *
+ * @return int
+ */
+ public function count(): int
+ {
+ return count($this->messages, COUNT_RECURSIVE) - count($this->messages);
+ }
+
+ /**
+ * Get the instance as an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->getMessages();
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize(): array
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the object to its JSON representation.
+ *
+ * @param int $options
+ *
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Convert the message bag to its string representation.
+ *
+ * @return string
+ */
+ public function __toString(): string
+ {
+ return $this->toJson();
+ }
+}
diff --git a/src/utils/src/NamespacedItemResolver.php b/src/utils/src/NamespacedItemResolver.php
new file mode 100644
index 00000000..4cdc45f8
--- /dev/null
+++ b/src/utils/src/NamespacedItemResolver.php
@@ -0,0 +1,112 @@
+parsed[$key])) {
+ return $this->parsed[$key];
+ }
+
+ // If the key does not contain a double colon, it means the key is not in a
+ // namespace, and is just a regular configuration item. Namespaces are a
+ // tool for organizing configuration items for things such as modules.
+ if (! str_contains($key, '::')) {
+ $segments = explode('.', $key);
+
+ $parsed = $this->parseBasicSegments($segments);
+ } else {
+ $parsed = $this->parseNamespacedSegments($key);
+ }
+
+ // Once we have the parsed array of this key's elements, such as its groups
+ // and namespace, we will cache each array inside a simple list that has
+ // the key and the parsed array for quick look-ups for later requests.
+ return $this->parsed[$key] = $parsed;
+ }
+
+ /**
+ * Parse an array of basic segments.
+ *
+ * @param array $segments
+ * @return array
+ */
+ protected function parseBasicSegments(array $segments)
+ {
+ // The first segment in a basic array will always be the group, so we can go
+ // ahead and grab that segment. If there is only one total segment we are
+ // just pulling an entire group out of the array and not a single item.
+ $group = $segments[0];
+
+ // If there is more than one segment in this group, it means we are pulling
+ // a specific item out of a group and will need to return this item name
+ // as well as the group so we know which item to pull from the arrays.
+ $item = count($segments) === 1
+ ? null
+ : implode('.', array_slice($segments, 1));
+
+ return [null, $group, $item];
+ }
+
+ /**
+ * Parse an array of namespaced segments.
+ *
+ * @param string $key
+ * @return array
+ */
+ protected function parseNamespacedSegments($key)
+ {
+ [$namespace, $item] = explode('::', $key);
+
+ // First we'll just explode the first segment to get the namespace and group
+ // since the item should be in the remaining segments. Once we have these
+ // two pieces of data we can proceed with parsing out the item's value.
+ $itemSegments = explode('.', $item);
+
+ $groupAndItem = array_slice(
+ $this->parseBasicSegments($itemSegments), 1
+ );
+
+ return array_merge([$namespace], $groupAndItem);
+ }
+
+ /**
+ * Set the parsed value of a key.
+ *
+ * @param string $key
+ * @param array $parsed
+ * @return void
+ */
+ public function setParsedKey($key, $parsed)
+ {
+ $this->parsed[$key] = $parsed;
+ }
+
+ /**
+ * Flush the cache of parsed keys.
+ *
+ * @return void
+ */
+ public function flushParsedKeys()
+ {
+ $this->parsed = [];
+ }
+}
diff --git a/src/utils/src/Str.php b/src/utils/src/Str.php
index 6a6a5392..48e76fc1 100644
--- a/src/utils/src/Str.php
+++ b/src/utils/src/Str.php
@@ -235,7 +235,7 @@ public static function contains($haystack, $needles, $ignoreCase = false)
}
foreach ((array) $needles as $needle) {
- if ($needle !== '' && str_contains($haystack, $needle)) {
+ if ($needle !== '' && str_contains((string) $haystack, (string) $needle)) {
return true;
}
}
diff --git a/src/utils/src/ValidatedInput.php b/src/utils/src/ValidatedInput.php
new file mode 100644
index 00000000..286df0a6
--- /dev/null
+++ b/src/utils/src/ValidatedInput.php
@@ -0,0 +1,226 @@
+input = $input;
+ }
+
+ /**
+ * Get a subset containing the provided keys with values from the input data.
+ *
+ * @param array|mixed $keys
+ *
+ * @return array
+ */
+ public function only($keys)
+ {
+ $results = [];
+
+ $input = $this->input;
+
+ $placeholder = new stdClass;
+
+ foreach (is_array($keys) ? $keys : func_get_args() as $key) {
+ $value = data_get($input, $key, $placeholder);
+
+ if ($value !== $placeholder) {
+ Arr::set($results, $key, $value);
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Get all of the input except for a specified array of items.
+ *
+ * @param array|mixed $keys
+ *
+ * @return array
+ */
+ public function except($keys)
+ {
+ $keys = is_array($keys) ? $keys : func_get_args();
+
+ $results = $this->input;
+
+ Arr::forget($results, $keys);
+
+ return $results;
+ }
+
+ /**
+ * Merge the validated input with the given array of additional data.
+ *
+ * @param array $items
+ *
+ * @return static
+ */
+ public function merge(array $items)
+ {
+ return new static(array_merge($this->input, $items));
+ }
+
+ /**
+ * Get the input as a collection.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ public function collect()
+ {
+ return new Collection($this->input);
+ }
+
+ /**
+ * Get the raw, underlying input array.
+ *
+ * @return array
+ */
+ public function all()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Get the instance as an array.
+ *
+ * @return array
+ */
+ public function toArray(): array
+ {
+ return $this->all();
+ }
+
+ /**
+ * Dynamically access input data.
+ *
+ * @param string $name
+ *
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ return $this->input[$name];
+ }
+
+ /**
+ * Dynamically set input data.
+ *
+ * @param string $name
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function __set($name, $value)
+ {
+ $this->input[$name] = $value;
+ }
+
+ /**
+ * Determine if an input key is set.
+ *
+ * @return bool
+ */
+ public function __isset($name)
+ {
+ return isset($this->input[$name]);
+ }
+
+ /**
+ * Remove an input key.
+ *
+ * @param string $name
+ *
+ * @return void
+ */
+ public function __unset($name)
+ {
+ unset($this->input[$name]);
+ }
+
+ /**
+ * Determine if an item exists at an offset.
+ *
+ * @param mixed $key
+ *
+ * @return bool
+ */
+ public function offsetExists($key): bool
+ {
+ return isset($this->input[$key]);
+ }
+
+ /**
+ * Get an item at a given offset.
+ *
+ * @param mixed $key
+ *
+ * @return mixed
+ */
+ public function offsetGet($key): mixed
+ {
+ return $this->input[$key];
+ }
+
+ /**
+ * Set the item at a given offset.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function offsetSet($key, $value): void
+ {
+ if (is_null($key)) {
+ $this->input[] = $value;
+ } else {
+ $this->input[$key] = $value;
+ }
+ }
+
+ /**
+ * Unset the item at a given offset.
+ *
+ * @param string $key
+ *
+ * @return void
+ */
+ public function offsetUnset($key): void
+ {
+ unset($this->input[$key]);
+ }
+
+ /**
+ * Get an iterator for the input.
+ *
+ * @return \ArrayIterator
+ */
+ public function getIterator(): Traversable
+ {
+ return new ArrayIterator($this->input);
+ }
+}
diff --git a/src/validator/LICENSE b/src/validator/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/validator/LICENSE
+++ b/src/validator/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/var-dumper/LICENSE b/src/var-dumper/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/var-dumper/LICENSE
+++ b/src/var-dumper/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/src/view/LICENSE b/src/view/LICENSE
index 261eeb9e..b9728b5c 100644
--- a/src/view/LICENSE
+++ b/src/view/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [2022] [ChengYao <987861463@qq.com>]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.