mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-23 03:02:33 +01:00
109 lines
3.6 KiB
PHP
109 lines
3.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Rector\SymfonyPhpConfig;
|
|
|
|
use Rector\Core\Exception\ShouldNotHappenException;
|
|
use Rector\SymfonyPhpConfig\Reflection\ArgumentAndParameterFactory;
|
|
use ReflectionClass;
|
|
use function Symfony\Component\DependencyInjection\Loader\Configurator\inline;
|
|
use function Symfony\Component\DependencyInjection\Loader\Configurator\inline_service;
|
|
use Symfony\Component\DependencyInjection\Loader\Configurator\InlineServiceConfigurator;
|
|
use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator;
|
|
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
|
|
use Symfony\Component\DependencyInjection\Loader\Configurator\ServicesConfigurator;
|
|
|
|
function inline_single_object(object $object, ServicesConfigurator $servicesConfigurator): ReferenceConfigurator
|
|
{
|
|
$reflectionClass = new ReflectionClass($object);
|
|
|
|
$className = $reflectionClass->getName();
|
|
$propertyValues = resolve_property_values($reflectionClass, $object);
|
|
$argumentValues = resolve_argument_values($reflectionClass, $object);
|
|
|
|
// create fake factory with private accessor, as properties are different
|
|
// @see https://symfony.com/doc/current/service_container/factories.html#passing-arguments-to-the-factory-method
|
|
$servicesConfigurator->set(ArgumentAndParameterFactory::class);
|
|
|
|
$servicesConfigurator->set($className)
|
|
->factory([service(ArgumentAndParameterFactory::class), 'create'])
|
|
->args([$className, $argumentValues, $propertyValues]);
|
|
|
|
return service($className);
|
|
}
|
|
|
|
function inline_value_object(object $object): InlineServiceConfigurator
|
|
{
|
|
$reflectionClass = new ReflectionClass($object);
|
|
|
|
$className = $reflectionClass->getName();
|
|
$argumentValues = resolve_argument_values($reflectionClass, $object);
|
|
|
|
// Symfony 5.1+
|
|
if (function_exists('Symfony\Component\DependencyInjection\Loader\Configurator\inline_service')) {
|
|
return inline_service($className)->args($argumentValues);
|
|
}
|
|
|
|
// Symfony 5.0-
|
|
return inline($className)->args($argumentValues);
|
|
}
|
|
|
|
/**
|
|
* @param object[] $objects
|
|
* @return InlineServiceConfigurator[]
|
|
*/
|
|
function inline_value_objects(array $objects): array
|
|
{
|
|
$inlineServices = [];
|
|
foreach ($objects as $object) {
|
|
$inlineServices[] = inline_value_object($object);
|
|
}
|
|
|
|
return $inlineServices;
|
|
}
|
|
|
|
/**
|
|
* @return mixed[]
|
|
*/
|
|
function resolve_argument_values(ReflectionClass $reflectionClass, object $object): array
|
|
{
|
|
$argumentValues = [];
|
|
|
|
$constructorMethodReflection = $reflectionClass->getConstructor();
|
|
if ($constructorMethodReflection === null) {
|
|
$message = sprintf(
|
|
'Constructor for "%s" was not found. Be sure to use only value objects',
|
|
$reflectionClass->getName()
|
|
);
|
|
throw new ShouldNotHappenException($message);
|
|
}
|
|
|
|
foreach ($constructorMethodReflection->getParameters() as $constructorParameter) {
|
|
$parameterName = $constructorParameter->getName();
|
|
$propertyReflection = $reflectionClass->getProperty($parameterName);
|
|
$propertyReflection->setAccessible(true);
|
|
|
|
$argumentValues[] = $propertyReflection->getValue($object);
|
|
}
|
|
|
|
return $argumentValues;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
function resolve_property_values(ReflectionClass $reflectionClass, object $object): array
|
|
{
|
|
$propertyValues = [];
|
|
|
|
foreach ($reflectionClass->getProperties() as $reflectionProperty) {
|
|
$parameterName = $reflectionProperty->getName();
|
|
$reflectionProperty->setAccessible(true);
|
|
|
|
$propertyValues[$parameterName] = $reflectionProperty->getValue($object);
|
|
}
|
|
|
|
return $propertyValues;
|
|
}
|