2021-08-27 06:46:27 -04:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Contracts\Service ;
use Psr\Container\ContainerInterface ;
2023-02-24 06:26:40 -05:00
use Symfony\Contracts\Service\Attribute\Required ;
2022-03-14 16:22:30 -04:00
use Symfony\Contracts\Service\Attribute\SubscribedService ;
2021-08-27 06:46:27 -04:00
/**
* Implementation of ServiceSubscriberInterface that determines subscribed services from
2022-03-14 16:22:30 -04:00
* method return types . Service ids are available as " ClassName::methodName " .
2021-08-27 06:46:27 -04:00
*
* @ author Kevin Bond < kevinbond @ gmail . com >
*/
trait ServiceSubscriberTrait
{
/** @var ContainerInterface */
protected $container ;
public static function getSubscribedServices () : array
{
2023-02-24 06:26:40 -05:00
$services = method_exists ( get_parent_class ( self :: class ) ? : '' , __FUNCTION__ ) ? parent :: getSubscribedServices () : [];
2021-08-27 06:46:27 -04:00
foreach (( new \ReflectionClass ( self :: class )) -> getMethods () as $method ) {
2022-03-14 16:22:30 -04:00
if ( self :: class !== $method -> getDeclaringClass () -> name ) {
continue ;
}
if ( ! $attribute = $method -> getAttributes ( SubscribedService :: class )[ 0 ] ? ? null ) {
2021-08-27 06:46:27 -04:00
continue ;
}
2022-03-14 16:22:30 -04:00
if ( $method -> isStatic () || $method -> isAbstract () || $method -> isGenerator () || $method -> isInternal () || $method -> getNumberOfRequiredParameters ()) {
throw new \LogicException ( sprintf ( 'Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).' , SubscribedService :: class , self :: class , $method -> name ));
2021-08-27 06:46:27 -04:00
}
2022-03-14 16:22:30 -04:00
if ( ! $returnType = $method -> getReturnType ()) {
throw new \LogicException ( sprintf ( 'Cannot use "%s" on methods without a return type in "%s::%s()".' , SubscribedService :: class , $method -> name , self :: class ));
}
2023-02-24 06:26:40 -05:00
/* @var SubscribedService $attribute */
$attribute = $attribute -> newInstance ();
$attribute -> key ? ? = self :: class . '::' . $method -> name ;
$attribute -> type ? ? = $returnType instanceof \ReflectionNamedType ? $returnType -> getName () : ( string ) $returnType ;
$attribute -> nullable = $returnType -> allowsNull ();
2022-03-14 16:22:30 -04:00
2023-02-24 06:26:40 -05:00
if ( $attribute -> attributes ) {
$services [] = $attribute ;
} else {
$services [ $attribute -> key ] = ( $attribute -> nullable ? '?' : '' ) . $attribute -> type ;
2022-03-14 16:22:30 -04:00
}
2021-08-27 06:46:27 -04:00
}
return $services ;
}
2023-02-24 06:26:40 -05:00
#[Required]
2022-03-14 16:22:30 -04:00
public function setContainer ( ContainerInterface $container ) : ? ContainerInterface
2021-08-27 06:46:27 -04:00
{
$this -> container = $container ;
2023-02-24 06:26:40 -05:00
if ( method_exists ( get_parent_class ( self :: class ) ? : '' , __FUNCTION__ )) {
2021-08-27 06:46:27 -04:00
return parent :: setContainer ( $container );
}
return null ;
}
}