|
6 | 6 | use Error; |
7 | 7 | use phpweb\Framework\Build\BuildContext; |
8 | 8 | use phpweb\Framework\Build\BuildStep; |
| 9 | +use phpweb\Framework\Build\BuildStepFailureException; |
9 | 10 | use phpweb\Framework\Build\BuildTools; |
10 | 11 | use phpweb\Framework\Build\ReflectionHelpers; |
11 | 12 | use phpweb\Framework\IO\FS; |
12 | 13 | use phpweb\Framework\Routing\Route; |
13 | 14 | use phpweb\ProjectGlobals; |
14 | 15 | use Psr\Container\ContainerInterface; |
15 | 16 | use ReflectionClass; |
| 17 | +use ReflectionException; |
16 | 18 | use Symfony\Component\DependencyInjection\Container; |
17 | 19 | use Symfony\Component\DependencyInjection\ContainerBuilder; |
18 | 20 | use Symfony\Component\DependencyInjection\Definition; |
@@ -49,13 +51,51 @@ public static function build(BuildContext $context): void |
49 | 51 | if ($attr && $attr->factory) { |
50 | 52 | [$factoryClassId, $factoryMethod] = $attr->factory; |
51 | 53 |
|
52 | | - if (!new ReflectionClass($factoryClassId)->getMethod($factoryMethod)->isStatic()) { |
| 54 | + try { |
| 55 | + $factoryClassReflection = new ReflectionClass($factoryClassId); |
| 56 | + } |
| 57 | + /** @phpstan-ignore-next-line - It doesn't know ReflectionClass constructor can throw */ |
| 58 | + catch (ReflectionException) { |
| 59 | + throw new BuildStepFailureException( |
| 60 | + message: "#[Service] specifies factory class '$factoryClassId' that does not exist", |
| 61 | + target: $class, |
| 62 | + ); |
| 63 | + } |
| 64 | + |
| 65 | + try { |
| 66 | + $factoryMethodReflection = $factoryClassReflection->getMethod($factoryMethod); |
| 67 | + } catch (ReflectionException) { |
| 68 | + throw new BuildStepFailureException( |
| 69 | + message: "#[Service] specifies factory class method {$factoryClassId}::{$factoryMethod} that does not exist'", |
| 70 | + target: $class, |
| 71 | + ); |
| 72 | + } |
| 73 | + |
| 74 | + if (!$factoryMethodReflection->isPublic()) { |
| 75 | + throw new BuildStepFailureException( |
| 76 | + message: "#[Service] specifies factory class method {$factoryClassId}::{$factoryMethod} that is not public'", |
| 77 | + target: $class, |
| 78 | + ); |
| 79 | + } |
| 80 | + |
| 81 | + /* non-static methods must be on a class that is by itself a service */ |
| 82 | + if (!$factoryMethodReflection->isStatic()) { |
| 83 | + $targetFactoryClass = new ReflectionClass($factoryClassId); |
| 84 | + if (!ReflectionHelpers::getAttribute($targetFactoryClass, Service::class)) { |
| 85 | + throw new BuildStepFailureException( |
| 86 | + message: "#[Service] specifies factory class '$factoryClassId' that is not registered a service", |
| 87 | + target: $class, |
| 88 | + ); |
| 89 | + } |
| 90 | + |
| 91 | + /* by using a reference we call upon the service */ |
53 | 92 | $factoryClassId = new Reference($factoryClassId); |
54 | 93 | } |
55 | 94 |
|
56 | 95 | $definition->setFactory([$factoryClassId, $factoryMethod]); |
57 | 96 | } |
58 | 97 |
|
| 98 | + $context->logger->debug("Registered {$class->getName()} as a service"); |
59 | 99 | $builder->setDefinition($classId, $definition); |
60 | 100 | } |
61 | 101 |
|
|
0 commit comments