public function testCreateViewDifferentAttributesClosure() { $attr1 = function () { }; $attr2 = function () { }; $list = $this->getMock('Symfony\\Component\\Form\\ChoiceList\\ChoiceListInterface'); $view1 = new \stdClass(); $view2 = new \stdClass(); $this->decoratedFactory->expects($this->at(0))->method('createView')->with($list, null, null, null, null, $attr1)->will($this->returnValue($view1)); $this->decoratedFactory->expects($this->at(1))->method('createView')->with($list, null, null, null, null, $attr2)->will($this->returnValue($view2)); $this->assertSame($view1, $this->factory->createView($list, null, null, null, null, $attr1)); $this->assertSame($view2, $this->factory->createView($list, null, null, null, null, $attr2)); }
/** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $choiceListFactory = $this->choiceListFactory; $choiceLoaders =& $this->choiceLoaders; $type = $this; $choiceLoader = function (Options $options, $value) use($choiceListFactory, &$choiceLoaders, $type) { if (null === $options['choices'] && $options['select2']['enabled']) { $hash = null; $qbParts = null; // If there is no QueryBuilder we can safely cache DoctrineChoiceLoader, // also if concrete Type can return important QueryBuilder parts to generate // hash key we go for it as well if (!$options['query_builder'] || false !== ($qbParts = $type->getQueryBuilderPartsForCachingHash($options['query_builder']))) { $hash = CachingFactoryDecorator::generateHash(array($options['em'], $options['class'], $qbParts, $options['select2']['ajax'])); if (isset($choiceLoaders[$hash])) { return $choiceLoaders[$hash]; } } if (null !== $options['query_builder']) { $entityLoader = $type->getLoader($options['em'], $options['query_builder'], $options['class']); } else { $queryBuilder = $options['em']->getRepository($options['class'])->createQueryBuilder('e'); $entityLoader = $type->getLoader($options['em'], $queryBuilder, $options['class']); } if ($options['select2']['ajax']) { $doctrineChoiceLoader = new AjaxDoctrineChoiceLoader($entityLoader, $options['id_reader'], null === $options['choice_label_name'] && is_string($options['choice_label']) ? $options['choice_label'] : $options['choice_label_name'], $choiceListFactory); } else { $doctrineChoiceLoader = new DynamicDoctrineChoiceLoader($entityLoader, $options['id_reader'], null === $options['choice_label_name'] && is_string($options['choice_label']) ? $options['choice_label'] : $options['choice_label_name'], $choiceListFactory); } if ($hash !== null) { $choiceLoaders[$hash] = $doctrineChoiceLoader; } return $doctrineChoiceLoader; } return $value; }; $choiceName = function (Options $options, $value) { return isset($options['id_reader']) ? array($options['id_reader'], 'getIdValue') : $value; }; $newTagConverter = function (Options $options) { return new NewTagConverter($options['class'], $options['choice_label']); }; $resolver->setDefaults(array('choice_loader' => $choiceLoader, 'choice_name' => $choiceName, 'choice_label_name' => null, 'new_tag_converter' => $newTagConverter)); $resolver->setAllowedTypes('choice_label_name', array('null', 'string')); }
public function configureOptions(OptionsResolver $resolver) { parent::configureOptions($resolver); /** * Здесь требуется внедрить опцию 'menu' в Loader. * Код скопирован из DoctrineType::configureOptions() * * @param Options $options * * @return DoctrineChoiceLoader */ $choiceLoader = function (Options $options) { // Unless the choices are given explicitly, load them on demand if (null === $options['choices']) { $hash = null; $qbParts = null; // If there is no QueryBuilder we can safely cache DoctrineChoiceLoader, // also if concrete Type can return important QueryBuilder parts to generate // hash key we go for it as well if (!$options['query_builder'] || false !== ($qbParts = $this->getQueryBuilderPartsForCachingHash($options['query_builder']))) { $hash = CachingFactoryDecorator::generateHash(array($options['em'], $options['class'], $qbParts)); if (isset($this->choiceLoaders[$hash])) { return $this->choiceLoaders[$hash]; } } if (null !== $options['query_builder']) { $entityLoader = $this->getLoader($options['em'], $options['query_builder'], $options['class']); } else { $queryBuilder = $options['em']->getRepository($options['class'])->createQueryBuilder('e'); $entityLoader = $this->getLoader($options['em'], $queryBuilder, $options['class']); } // !!! Вот здесь инжектится опция. $entityLoader->setMenu($options['menu']); $doctrineChoiceLoader = new DoctrineChoiceLoader($options['em'], $options['class'], $options['id_reader'], $entityLoader); if ($hash !== null) { $this->choiceLoaders[$hash] = $doctrineChoiceLoader; } return $doctrineChoiceLoader; } }; $resolver->setDefaults(['choice_label' => 'form_title', 'class' => 'MenuModule:Item', 'choice_loader' => $choiceLoader, 'menu' => null, 'required' => false]); }
public function configureOptions(OptionsResolver $resolver) { parent::configureOptions($resolver); $choiceLoader = function (Options $options) { // Unless the choices are given explicitly, load them on demand if (null === $options['choices']) { $hash = null; $qbParts = null; // If there is no QueryBuilder we can safely cache DoctrineChoiceLoader, // also if concrete Type can return important QueryBuilder parts to generate // hash key we go for it as well if (!$options['query_builder'] || false !== ($qbParts = $this->getQueryBuilderPartsForCachingHash($options['query_builder']))) { $hash = CachingFactoryDecorator::generateHash(array($options['em'], $options['class'], $qbParts)); if (isset($this->choiceLoaders[$hash])) { return $this->choiceLoaders[$hash]; } } if (null !== $options['query_builder']) { $entityLoader = $this->getLoader($options['em'], $options['query_builder'], $options['class']); } else { $queryBuilder = $options['em']->getRepository($options['class'])->createQueryBuilder('e'); $entityLoader = $this->getLoader($options['em'], $queryBuilder, $options['class']); } // Inject option 'unicat_structure' $entityLoader->setStructure($options['unicat_structure']); $doctrineChoiceLoader = new DoctrineChoiceLoader($options['em'], $options['class'], $options['id_reader'], $entityLoader); if ($hash !== null) { $this->choiceLoaders[$hash] = $doctrineChoiceLoader; } return $doctrineChoiceLoader; } }; $resolver->setDefaults(['choice_label' => 'form_title', 'class' => function (Options $options) { return $options['unicat_structure']->getConfiguration()->getTaxonClass(); }, 'choice_loader' => $choiceLoader, 'required' => false, 'unicat_structure' => null]); }
public function configureOptions(OptionsResolver $resolver) { $registry = $this->registry; $choiceListFactory = $this->choiceListFactory; $idReaders =& $this->idReaders; $choiceLoaders =& $this->choiceLoaders; $type = $this; $choiceLoader = function (Options $options) use($choiceListFactory, &$choiceLoaders, $type) { // Unless the choices are given explicitly, load them on demand if (null === $options['choices']) { $hash = null; $qbParts = null; // If there is no QueryBuilder we can safely cache DoctrineChoiceLoader, // also if concrete Type can return important QueryBuilder parts to generate // hash key we go for it as well if (!$options['query_builder'] || false !== ($qbParts = $type->getQueryBuilderPartsForCachingHash($options['query_builder']))) { $hash = CachingFactoryDecorator::generateHash(array($options['em'], $options['class'], $qbParts, $options['loader'])); if (isset($choiceLoaders[$hash])) { return $choiceLoaders[$hash]; } } if ($options['loader']) { $entityLoader = $options['loader']; } elseif (null !== $options['query_builder']) { $entityLoader = $type->getLoader($options['em'], $options['query_builder'], $options['class']); } else { $queryBuilder = $options['em']->getRepository($options['class'])->createQueryBuilder('e'); $entityLoader = $type->getLoader($options['em'], $queryBuilder, $options['class']); } $doctrineChoiceLoader = new DoctrineChoiceLoader($choiceListFactory, $options['em'], $options['class'], $options['id_reader'], $entityLoader); if ($hash !== null) { $choiceLoaders[$hash] = $doctrineChoiceLoader; } return $doctrineChoiceLoader; } }; $choiceLabel = function (Options $options) { // BC with the "property" option if ($options['property']) { return $options['property']; } // BC: use __toString() by default return array(__CLASS__, 'createChoiceLabel'); }; $choiceName = function (Options $options) { /** @var IdReader $idReader */ $idReader = $options['id_reader']; // If the object has a single-column, numeric ID, use that ID as // field name. We can only use numeric IDs as names, as we cannot // guarantee that a non-numeric ID contains a valid form name if ($idReader->isIntId()) { return array(__CLASS__, 'createChoiceName'); } // Otherwise, an incrementing integer is used as name automatically }; // The choices are always indexed by ID (see "choices" normalizer // and DoctrineChoiceLoader), unless the ID is composite. Then they // are indexed by an incrementing integer. // Use the ID/incrementing integer as choice value. $choiceValue = function (Options $options) { /** @var IdReader $idReader */ $idReader = $options['id_reader']; // If the entity has a single-column ID, use that ID as value if ($idReader->isSingleId()) { return array($idReader, 'getIdValue'); } // Otherwise, an incrementing integer is used as value automatically }; $emNormalizer = function (Options $options, $em) use($registry) { /* @var ManagerRegistry $registry */ if (null !== $em) { if ($em instanceof ObjectManager) { return $em; } return $registry->getManager($em); } $em = $registry->getManagerForClass($options['class']); if (null === $em) { throw new RuntimeException(sprintf('Class "%s" seems not to be a managed Doctrine entity. ' . 'Did you forget to map it?', $options['class'])); } return $em; }; // deprecation note $propertyNormalizer = function (Options $options, $propertyName) { if ($propertyName) { @trigger_error('The "property" option is deprecated since version 2.7 and will be removed in 3.0. Use "choice_label" instead.', E_USER_DEPRECATED); } return $propertyName; }; // Invoke the query builder closure so that we can cache choice lists // for equal query builders $queryBuilderNormalizer = function (Options $options, $queryBuilder) { if (is_callable($queryBuilder)) { $queryBuilder = call_user_func($queryBuilder, $options['em']->getRepository($options['class'])); } return $queryBuilder; }; // deprecation note $loaderNormalizer = function (Options $options, $loader) { if ($loader) { @trigger_error('The "loader" option is deprecated since version 2.7 and will be removed in 3.0. Override getLoader() instead.', E_USER_DEPRECATED); } return $loader; }; // Set the "id_reader" option via the normalizer. This option is not // supposed to be set by the user. $idReaderNormalizer = function (Options $options) use(&$idReaders) { $hash = CachingFactoryDecorator::generateHash(array($options['em'], $options['class'])); // The ID reader is a utility that is needed to read the object IDs // when generating the field values. The callback generating the // field values has no access to the object manager or the class // of the field, so we store that information in the reader. // The reader is cached so that two choice lists for the same class // (and hence with the same reader) can successfully be cached. if (!isset($idReaders[$hash])) { $classMetadata = $options['em']->getClassMetadata($options['class']); $idReaders[$hash] = new IdReader($options['em'], $classMetadata); } return $idReaders[$hash]; }; $resolver->setDefaults(array('em' => null, 'property' => null, 'query_builder' => null, 'loader' => null, 'choices' => null, 'choices_as_values' => true, 'choice_loader' => $choiceLoader, 'choice_label' => $choiceLabel, 'choice_name' => $choiceName, 'choice_value' => $choiceValue, 'id_reader' => null, 'choice_translation_domain' => false)); $resolver->setRequired(array('class')); $resolver->setNormalizer('em', $emNormalizer); $resolver->setNormalizer('property', $propertyNormalizer); $resolver->setNormalizer('query_builder', $queryBuilderNormalizer); $resolver->setNormalizer('loader', $loaderNormalizer); $resolver->setNormalizer('id_reader', $idReaderNormalizer); $resolver->setAllowedTypes('em', array('null', 'string', 'Doctrine\\Common\\Persistence\\ObjectManager')); $resolver->setAllowedTypes('loader', array('null', 'Symfony\\Bridge\\Doctrine\\Form\\ChoiceList\\EntityLoaderInterface')); }
/** * {@inheritdoc} * * @throws AccessException * @throws UndefinedOptionsException */ public function configureOptions(OptionsResolver $resolver) { parent::configureOptions($resolver); $choiceNormalizer = function (OptionsResolver $options, $value) { return $value === null && $options['autocomplete'] ? [] : $value; }; $emNormalizer = function (Options $options, $em) { //support for sonata model type if (null === $em && !empty($options['model_manager']) && !empty($options['class'])) { $em = $options['model_manager']->getEntityManager($options['class']); } return $em; }; $queryBuilderNormalizer = function (Options $options, $queryBuilder) { if (is_callable($queryBuilder) && !empty($options['em'])) { $queryBuilder = call_user_func($queryBuilder, $options['em']->getRepository($options['class'])); } return $queryBuilder; }; // Set the "id_reader" option via the normalizer. This option is not // supposed to be set by the user. $idReaderNormalizer = function (Options $options, $idReader) { if (empty($options['em']) || $idReader instanceof IdReader) { return $idReader; } $hash = CachingFactoryDecorator::generateHash(array($options['em'], $options['class'])); if (!isset($this->idReaders[$hash])) { $classMetadata = $options['em']->getClassMetadata($options['class']); $this->idReaders[$hash] = new IdReader($options['em'], $classMetadata); } return $this->idReaders[$hash]; }; //this option is used internally to know when the autocomplete //has been initialized in the pre-submit data $resolver->setDefault('_autocomplete_submitted', false); $resolver->setDefault('em', null); $resolver->setDefault('id_reader', null); // internal $resolver->setAllowedTypes('em', ['null', 'Doctrine\\ORM\\EntityManager']); $resolver->setNormalizer('em', $emNormalizer); $resolver->setNormalizer('query_builder', $queryBuilderNormalizer); $resolver->setNormalizer('id_reader', $idReaderNormalizer); $resolver->setNormalizer('choices', $choiceNormalizer); }