2012-07-12 18:17:14 +01: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\Component\Form ;
2013-01-05 17:31:34 +00:00
use Symfony\Component\Form\Exception\ExceptionInterface ;
2012-07-12 18:17:14 +01:00
use Symfony\Component\Form\Exception\UnexpectedTypeException ;
2013-04-15 21:11:02 +01:00
use Symfony\Component\Form\Exception\InvalidArgumentException ;
2012-07-12 18:17:14 +01:00
/**
* The central registry of the Form component .
*
* @ author Bernhard Schussek < bschussek @ gmail . com >
*/
class FormRegistry implements FormRegistryInterface
{
/**
2014-12-21 17:00:50 +00:00
* Extensions .
2012-11-01 15:08:59 +00:00
*
* @ var FormExtensionInterface [] An array of FormExtensionInterface
2012-07-12 18:17:14 +01:00
*/
private $extensions = array ();
/**
2014-07-09 11:03:33 +01:00
* @ var FormTypeInterface []
2012-07-12 18:17:14 +01:00
*/
private $types = array ();
2015-06-23 17:42:21 +01:00
/**
* @ var string []
*/
private $legacyNames = array ();
2012-07-12 18:17:14 +01:00
/**
2012-11-08 18:49:46 +00:00
* @ var FormTypeGuesserInterface | false | null
2012-07-12 18:17:14 +01:00
*/
2012-11-08 18:49:46 +00:00
private $guesser = false ;
2012-07-12 18:17:14 +01:00
2012-07-29 18:10:47 +01:00
/**
* @ var ResolvedFormTypeFactoryInterface
*/
private $resolvedTypeFactory ;
2012-07-12 18:17:14 +01:00
/**
* Constructor .
*
2012-11-01 15:08:59 +00:00
* @ param FormExtensionInterface [] $extensions An array of FormExtensionInterface
2012-07-29 18:10:47 +01:00
* @ param ResolvedFormTypeFactoryInterface $resolvedTypeFactory The factory for resolved form types .
2012-07-12 18:17:14 +01:00
*
* @ throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
*/
2012-07-29 18:10:47 +01:00
public function __construct ( array $extensions , ResolvedFormTypeFactoryInterface $resolvedTypeFactory )
2012-07-12 18:17:14 +01:00
{
foreach ( $extensions as $extension ) {
if ( ! $extension instanceof FormExtensionInterface ) {
throw new UnexpectedTypeException ( $extension , 'Symfony\Component\Form\FormExtensionInterface' );
}
}
$this -> extensions = $extensions ;
2012-07-29 18:10:47 +01:00
$this -> resolvedTypeFactory = $resolvedTypeFactory ;
2012-07-12 18:17:14 +01:00
}
/**
* { @ inheritdoc }
*/
public function getType ( $name )
{
if ( ! is_string ( $name )) {
throw new UnexpectedTypeException ( $name , 'string' );
}
if ( ! isset ( $this -> types [ $name ])) {
$type = null ;
foreach ( $this -> extensions as $extension ) {
if ( $extension -> hasType ( $name )) {
$type = $extension -> getType ( $name );
break ;
}
}
if ( ! $type ) {
2015-06-23 17:42:21 +01:00
// Support fully-qualified class names
if ( class_exists ( $name ) && in_array ( 'Symfony\Component\Form\FormTypeInterface' , class_implements ( $name ))) {
$type = new $name ();
} else {
throw new InvalidArgumentException ( sprintf ( 'Could not load type "%s"' , $name ));
}
2012-07-12 18:17:14 +01:00
}
2012-08-22 15:00:43 +01:00
$this -> resolveAndAddType ( $type );
}
2012-07-29 18:10:47 +01:00
2015-06-23 17:42:21 +01:00
if ( isset ( $this -> legacyNames [ $name ])) {
2015-08-24 07:21:47 +01:00
@ trigger_error ( sprintf ( 'Accessing type "%s" by its string name is deprecated since version 2.8 and will be removed in 3.0. Use the fully-qualified type class name "%s" instead.' , $name , get_class ( $this -> types [ $name ] -> getInnerType ())), E_USER_DEPRECATED );
2015-06-23 17:42:21 +01:00
}
2012-08-22 15:00:43 +01:00
return $this -> types [ $name ];
}
/**
* Wraps a type into a ResolvedFormTypeInterface implementation and connects
* it with its parent type .
*
* @ param FormTypeInterface $type The type to resolve .
*
* @ return ResolvedFormTypeInterface The resolved type .
*/
private function resolveAndAddType ( FormTypeInterface $type )
{
2015-06-23 17:42:21 +01:00
$typeExtensions = array ();
2012-08-22 15:00:43 +01:00
$parentType = $type -> getParent ();
2015-06-23 17:42:21 +01:00
$fqcn = get_class ( $type );
$name = $type -> getName ();
$hasCustomName = $name !== $fqcn ;
2012-07-29 18:10:47 +01:00
2012-08-22 15:00:43 +01:00
if ( $parentType instanceof FormTypeInterface ) {
2015-06-23 17:42:21 +01:00
@ trigger_error ( 'Returning a FormTypeInterface from FormTypeInterface::getParent() is deprecated since version 2.8 and will be removed in 3.0.' , E_USER_DEPRECATED );
2012-08-22 15:00:43 +01:00
$this -> resolveAndAddType ( $parentType );
$parentType = $parentType -> getName ();
}
2015-06-23 17:42:21 +01:00
if ( $hasCustomName ) {
foreach ( $this -> extensions as $extension ) {
$typeExtensions = array_merge (
$typeExtensions ,
$extension -> getTypeExtensions ( $name )
);
}
if ( $typeExtensions ) {
@ trigger_error ( 'Returning a type name from FormTypeExtensionInterface::getExtendedType() is deprecated since version 2.8 and will be removed in 3.0. Return the fully-qualified type class name instead.' , E_USER_DEPRECATED );
}
}
2012-08-22 15:00:43 +01:00
foreach ( $this -> extensions as $extension ) {
$typeExtensions = array_merge (
2012-07-29 18:10:47 +01:00
$typeExtensions ,
2015-06-23 17:42:21 +01:00
$extension -> getTypeExtensions ( $fqcn )
2012-08-22 15:00:43 +01:00
);
2012-07-12 18:17:14 +01:00
}
2015-06-23 17:42:21 +01:00
$resolvedType = $this -> resolvedTypeFactory -> createResolvedType (
2012-08-22 15:00:43 +01:00
$type ,
$typeExtensions ,
$parentType ? $this -> getType ( $parentType ) : null
2013-03-01 09:41:59 +00:00
);
2015-06-23 17:42:21 +01:00
$this -> types [ $fqcn ] = $resolvedType ;
if ( $hasCustomName ) {
// Enable access by the explicit type name until Symfony 3.0
$this -> types [ $name ] = $resolvedType ;
$this -> legacyNames [ $name ] = true ;
}
2012-07-12 18:17:14 +01:00
}
/**
* { @ inheritdoc }
*/
public function hasType ( $name )
{
2015-06-23 17:42:21 +01:00
if ( isset ( $this -> legacyNames [ $name ])) {
2015-08-24 07:21:47 +01:00
@ trigger_error ( sprintf ( 'Accessing type "%s" by its string name is deprecated since version 2.8 and will be removed in 3.0. Use the fully-qualified type class name "%s" instead.' , $name , get_class ( $this -> types [ $name ] -> getInnerType ())), E_USER_DEPRECATED );
2015-06-23 17:42:21 +01:00
}
2012-07-12 18:17:14 +01:00
if ( isset ( $this -> types [ $name ])) {
return true ;
}
try {
$this -> getType ( $name );
2013-01-05 17:31:34 +00:00
} catch ( ExceptionInterface $e ) {
2012-07-12 18:17:14 +01:00
return false ;
}
return true ;
}
/**
* { @ inheritdoc }
*/
public function getTypeGuesser ()
{
2012-11-08 18:49:46 +00:00
if ( false === $this -> guesser ) {
2012-07-12 18:17:14 +01:00
$guessers = array ();
foreach ( $this -> extensions as $extension ) {
$guesser = $extension -> getTypeGuesser ();
if ( $guesser ) {
$guessers [] = $guesser ;
}
}
2012-11-08 18:49:46 +00:00
$this -> guesser = ! empty ( $guessers ) ? new FormTypeGuesserChain ( $guessers ) : null ;
2012-07-12 18:17:14 +01:00
}
return $this -> guesser ;
}
/**
* { @ inheritdoc }
*/
public function getExtensions ()
{
return $this -> extensions ;
}
}