2023-04-16 16:40:44 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Kiri\Di;
|
|
|
|
|
|
2023-12-12 10:56:43 +08:00
|
|
|
use Kiri\Di\Inject\Container;
|
2023-04-16 16:40:44 +08:00
|
|
|
use Kiri\Abstracts\Component;
|
2023-04-24 22:31:08 +08:00
|
|
|
use Kiri\Di\Inject\Skip;
|
2023-12-12 10:56:43 +08:00
|
|
|
use Psr\Container\ContainerInterface;
|
2023-08-03 14:08:16 +08:00
|
|
|
use ReflectionMethod;
|
2023-04-16 16:40:44 +08:00
|
|
|
|
|
|
|
|
class Scanner extends Component
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
2023-05-25 16:59:17 +08:00
|
|
|
/**
|
2023-12-12 10:56:43 +08:00
|
|
|
* @var ContainerInterface
|
2023-05-25 16:59:17 +08:00
|
|
|
*/
|
2023-12-12 10:56:43 +08:00
|
|
|
#[Container(ContainerInterface::class)]
|
|
|
|
|
public ContainerInterface $container;
|
2023-05-25 16:59:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2023-12-12 10:56:43 +08:00
|
|
|
* @param string $path
|
2023-05-25 16:59:17 +08:00
|
|
|
* @return void
|
2023-12-12 15:35:35 +08:00
|
|
|
* @throws
|
2023-05-25 16:59:17 +08:00
|
|
|
*/
|
2023-12-12 10:56:43 +08:00
|
|
|
public function load_directory(string $path): void
|
2023-05-25 16:59:17 +08:00
|
|
|
{
|
2023-12-12 10:56:43 +08:00
|
|
|
$dir = new \DirectoryIterator($path);
|
|
|
|
|
$skip = \config('scanner.skip', []);
|
|
|
|
|
foreach ($dir as $value) {
|
|
|
|
|
if ($value->isDot() || str_starts_with($value->getFilename(), '.')) {
|
2023-08-17 16:15:07 +08:00
|
|
|
continue;
|
|
|
|
|
}
|
2023-12-12 10:56:43 +08:00
|
|
|
if ($value->isDir()) {
|
|
|
|
|
if (in_array($value->getRealPath() . '/', $skip)) {
|
2023-05-25 16:59:17 +08:00
|
|
|
continue;
|
|
|
|
|
}
|
2023-12-12 10:56:43 +08:00
|
|
|
$this->load_directory($value->getRealPath());
|
|
|
|
|
} else if ($value->getExtension() == 'php') {
|
|
|
|
|
$this->load_file($value->getRealPath());
|
2023-05-25 16:59:17 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $file
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function rename(string $file): string
|
|
|
|
|
{
|
|
|
|
|
$filter = array_filter(explode('/', $file), function ($value) {
|
|
|
|
|
if (empty($value)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return ucfirst($value);
|
|
|
|
|
});
|
|
|
|
|
return ucfirst(implode('\\', $filter));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $path
|
|
|
|
|
* @return void
|
2023-12-12 15:35:35 +08:00
|
|
|
* @throws
|
2023-05-25 16:59:17 +08:00
|
|
|
*/
|
|
|
|
|
private function load_file(string $path): void
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
require_once "$path";
|
|
|
|
|
$path = str_replace($_SERVER['PWD'], '', $path);
|
|
|
|
|
$path = str_replace('.php', '', $path);
|
2023-12-12 10:56:43 +08:00
|
|
|
$this->parseFile($path);
|
2023-05-25 16:59:17 +08:00
|
|
|
} catch (\Throwable $throwable) {
|
|
|
|
|
error($throwable);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-16 16:40:44 +08:00
|
|
|
|
|
|
|
|
|
2023-12-12 10:56:43 +08:00
|
|
|
/**
|
|
|
|
|
* @param $file
|
|
|
|
|
* @return void
|
2023-12-12 15:35:35 +08:00
|
|
|
* @throws
|
2023-12-12 10:56:43 +08:00
|
|
|
*/
|
|
|
|
|
protected function parseFile($file): void
|
|
|
|
|
{
|
|
|
|
|
$class = $this->rename($file);
|
|
|
|
|
if (class_exists($class)) {
|
|
|
|
|
$reflect = $this->container->getReflectionClass($class);
|
|
|
|
|
if ($reflect->isInstantiable()) {
|
|
|
|
|
$data = $reflect->getAttributes(Skip::class);
|
|
|
|
|
if (count($data) > 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-12-18 16:20:38 +08:00
|
|
|
$data = $reflect->getAttributes(\Attribute::class);
|
|
|
|
|
if (count($data) > 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-12-12 10:56:43 +08:00
|
|
|
$object = $this->container->parse($class);
|
|
|
|
|
$methods = $this->container->getReflectionClass($class);
|
|
|
|
|
foreach ($methods->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
|
|
|
|
|
if ($method->isStatic() || $method->getDeclaringClass()->getName() != $class) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$attributes = $method->getAttributes();
|
|
|
|
|
foreach ($attributes as $attribute) {
|
|
|
|
|
if (!class_exists($attribute->getName())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$attribute->newInstance()->dispatch($object, $method->getName());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-16 16:40:44 +08:00
|
|
|
}
|