| Conditions | 34 |
| Paths | 3585 |
| Total Lines | 105 |
| Code Lines | 67 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 35 | protected function processValue(mixed $value, bool $isRoot = false): mixed |
||
| 36 | { |
||
| 37 | if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) { |
||
| 38 | return parent::processValue($value, $isRoot); |
||
| 39 | } |
||
| 40 | |||
| 41 | $serviceMap = []; |
||
| 42 | $autowire = $value->isAutowired(); |
||
| 43 | |||
| 44 | foreach ($value->getTag('container.service_subscriber') as $attributes) { |
||
| 45 | if (!$attributes) { |
||
| 46 | $autowire = true; |
||
| 47 | continue; |
||
| 48 | } |
||
| 49 | ksort($attributes); |
||
| 50 | if ([] !== array_diff(array_keys($attributes), ['id', 'key'])) { |
||
| 51 | throw new InvalidArgumentException(\sprintf('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "%s" given for service "%s".', implode('", "', array_keys($attributes)), $this->currentId)); |
||
| 52 | } |
||
| 53 | if (!\array_key_exists('id', $attributes)) { |
||
| 54 | throw new InvalidArgumentException(\sprintf('Missing "id" attribute on "container.service_subscriber" tag with key="%s" for service "%s".', $attributes['key'], $this->currentId)); |
||
| 55 | } |
||
| 56 | if (!\array_key_exists('key', $attributes)) { |
||
| 57 | $attributes['key'] = $attributes['id']; |
||
| 58 | } |
||
| 59 | if (isset($serviceMap[$attributes['key']])) { |
||
| 60 | continue; |
||
| 61 | } |
||
| 62 | $serviceMap[$attributes['key']] = new Reference($attributes['id']); |
||
| 63 | } |
||
| 64 | $class = $value->getClass(); |
||
| 65 | |||
| 66 | if (!$r = $this->container->getReflectionClass($class)) { |
||
|
|
|||
| 67 | throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId)); |
||
| 68 | } |
||
| 69 | if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) { |
||
| 70 | throw new InvalidArgumentException(\sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class)); |
||
| 71 | } |
||
| 72 | $class = $r->name; |
||
| 73 | $subscriberMap = []; |
||
| 74 | |||
| 75 | foreach ($class::getSubscribedServices() as $key => $type) { |
||
| 76 | $attributes = []; |
||
| 77 | |||
| 78 | if (!isset($serviceMap[$key]) && $type instanceof Autowire) { |
||
| 79 | $subscriberMap[$key] = $type; |
||
| 80 | continue; |
||
| 81 | } |
||
| 82 | |||
| 83 | if ($type instanceof SubscribedService) { |
||
| 84 | $key = $type->key ?? $key; |
||
| 85 | $attributes = $type->attributes; |
||
| 86 | $type = ($type->nullable ? '?' : '').($type->type ?? throw new InvalidArgumentException(\sprintf('When "%s::getSubscribedServices()" returns "%s", a type must be set.', $class, SubscribedService::class))); |
||
| 87 | } |
||
| 88 | |||
| 89 | if (!\is_string($type) || !preg_match('/(?(DEFINE)(?<cn>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+))(?(DEFINE)(?<fqcn>(?&cn)(?:\\\\(?&cn))*+))^\??(?&fqcn)(?:(?:\|(?&fqcn))*+|(?:&(?&fqcn))*+)$/', $type)) { |
||
| 90 | throw new InvalidArgumentException(\sprintf('"%s::getSubscribedServices()" must return valid PHP types for service "%s" key "%s", "%s" returned.', $class, $this->currentId, $key, \is_string($type) ? $type : get_debug_type($type))); |
||
| 91 | } |
||
| 92 | $optionalBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; |
||
| 93 | if ('?' === $type[0]) { |
||
| 94 | $type = substr($type, 1); |
||
| 95 | $optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; |
||
| 96 | } |
||
| 97 | if (\is_int($name = $key)) { |
||
| 98 | $key = $type; |
||
| 99 | $name = null; |
||
| 100 | } |
||
| 101 | if (!isset($serviceMap[$key])) { |
||
| 102 | if (!$autowire) { |
||
| 103 | throw new InvalidArgumentException(\sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class)); |
||
| 104 | } |
||
| 105 | $serviceMap[$key] = new Reference($type); |
||
| 106 | } |
||
| 107 | |||
| 108 | if ($name) { |
||
| 109 | if (false !== $i = strpos($name, '::get')) { |
||
| 110 | $name = lcfirst(substr($name, 5 + $i)); |
||
| 111 | } elseif (str_contains($name, '::')) { |
||
| 112 | $name = null; |
||
| 113 | } |
||
| 114 | } |
||
| 115 | |||
| 116 | if (null !== $name && !$this->container->has($name) && !$this->container->has($type.' $'.$name)) { |
||
| 117 | $camelCaseName = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $name)))); |
||
| 118 | $name = $this->container->has($type.' $'.$camelCaseName) ? $camelCaseName : $name; |
||
| 119 | } |
||
| 120 | |||
| 121 | $subscriberMap[$key] = new TypedReference((string) $serviceMap[$key], $type, $optionalBehavior, $name, $attributes); |
||
| 122 | unset($serviceMap[$key]); |
||
| 123 | } |
||
| 124 | |||
| 125 | if ($serviceMap = array_keys($serviceMap)) { |
||
| 126 | $message = \sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap))); |
||
| 127 | throw new InvalidArgumentException(\sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId)); |
||
| 128 | } |
||
| 129 | |||
| 130 | $locatorRef = ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId); |
||
| 131 | |||
| 132 | $value->addTag('container.service_subscriber.locator', ['id' => (string) $locatorRef]); |
||
| 133 | |||
| 134 | $value->setBindings([ |
||
| 135 | PsrContainerInterface::class => new BoundArgument($locatorRef, false), |
||
| 136 | ServiceProviderInterface::class => new BoundArgument($locatorRef, false), |
||
| 137 | ] + $value->getBindings()); |
||
| 138 | |||
| 139 | return parent::processValue($value); |
||
| 140 | } |
||
| 142 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.