diff --git a/.travis.yml b/.travis.yml index f31ff7da..4235edcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,13 +22,32 @@ matrix: - php: 5.5 env: - EXECUTE_CS_CHECK=true + - php: 5.5 + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" - php: 5.6 env: - EXECUTE_TEST_COVERALLS=true + - php: 5.6 + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" + - php: 7 - php: 7 + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" + - php: hhvm - php: hhvm + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" allow_failures: - - php: 7 - php: hhvm notifications: @@ -39,9 +58,17 @@ before_install: - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi - composer self-update - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then composer require --dev --no-update satooshi/php-coveralls ; fi + - if [[ $EVENT_MANAGER_VERSION != '' ]]; then composer require --dev --no-update "zendframework/zend-eventmanager:$EVENT_MANAGER_VERSION" ; fi + - if [[ $EVENT_MANAGER_VERSION == '' ]]; then composer require --dev --no-update "zendframework/zend-eventmanager:^3.0" ; fi + - if [[ $HYDRATOR_VERSION != '' ]]; then composer require --no-update "zendframework/zend-stdlib:^2.7" ; fi + - if [[ $HYDRATOR_VERSION != '' ]]; then composer require --no-update "zendframework/zend-hydrator:$HYDRATOR_VERSION" ; fi + - if [[ $SERVICE_MANAGER_VERSION != '' ]]; then composer require --dev --no-update "zendframework/zend-servicemanager:$SERVICE_MANAGER_VERSION" ; fi + - if [[ $SERVICE_MANAGER_VERSION = '' ]]; then composer require --dev --no-update "zendframework/zend-servicemanager:^3.0.3" ; fi + - if [[ $SERVICE_MANAGER_VERSION = '' ]]; then composer remove --dev --no-update zendframework/zend-captcha zendframework/zend-session ; fi install: - travis_retry composer install --no-interaction --ignore-platform-reqs + - composer info -i script: - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit --coverage-clover clover.xml ; fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6f44f7..0144bcc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 2.7.0 - TBD +## 2.7.0 - 2016-02-22 ### Added @@ -18,7 +18,13 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- [#40](https://github.com/zendframework/zend-form/pull/40) and + [#43](https://github.com/zendframework/zend-form/pull/43) prepare the + component to be forwards compatible with each of the following: + - zend-eventmanager v3 + - zend-hydrator v2.1 + - zend-servicemanager v3 + - zend-stdlib v3 ## 2.6.1 - TBD diff --git a/book/zend.form.advanced-use-of-forms.md b/book/zend.form.advanced-use-of-forms.md index 642b7a3c..78989962 100644 --- a/book/zend.form.advanced-use-of-forms.md +++ b/book/zend.form.advanced-use-of-forms.md @@ -57,10 +57,10 @@ class Phone extends Element implements InputProviderInterface protected $validator; /** - * Get a validator if none has been set. - * - * @return ValidatorInterface - */ + * Get a validator if none has been set. + * + * @return ValidatorInterface + */ public function getValidator() { if (null === $this->validator) { @@ -160,17 +160,22 @@ First, add the custom element to the plugin manager, in your `Module.php` class: ```php namespace Application; +use Application\Form\Element\Phone; +use Zend\Form\ElementFactory; use Zend\ModuleManager\Feature\FormElementProviderInterface; class Module implements FormElementProviderInterface { public function getFormElementConfig() { - return array( - 'invokables' => array( - 'phone' => 'Application\Form\Element\Phone' - ) - ); + return [ + 'aliases' => [ + 'phone' => Phone::class, + ], + 'factories' => [ + Phone::class => ElementFactory::class, + ], + ]; } } ``` @@ -178,16 +183,19 @@ class Module implements FormElementProviderInterface Or, you can do the same in your `module.config.php` file: ```php -return array( - 'form_elements' => array( - 'invokables' => array( - 'phone' => 'Application\Form\Element\Phone' - ) - ) -); +return [ + 'form_elements' => [ + 'aliases' => [ + 'phone' => Phone::class, + ], + 'factories' => [ + Phone::class => ElementFactory::class, + ], + ], +]; ``` -You can use a factory instead of an invokable in order to handle dependencies in your +`ElementFactory` is the default factory for form elements. Use your own if you need to handle dependencies in your elements/fieldsets/forms. **And now comes the first catch.** @@ -240,22 +248,27 @@ same key as the element you want to replace: ```php namespace Application; +use Application\Form\Element\MyEmail; +use Zend\Form\ElementFactory; use Zend\ModuleManager\Feature\FormElementProviderInterface; class Module implements FormElementProviderInterface { public function getFormElementConfig() { - return array( - 'invokables' => array( - 'Email' => 'Application\Form\Element\MyEmail' - ) - ); + return [ + 'aliases' => [ + 'email' => MyEmail::class, + ], + 'factories' => [ + MyEmail::class => ElementFactory::class, + ], + ]; } } ``` -Now, whenever you'll create an element whose `type` is 'Email', it will create the custom Email +Now, whenever you'll create an element whose `type` is 'email', it will create the custom Email element instead of the built-in one. > ## Note diff --git a/composer.json b/composer.json index 71b06737..b1541b93 100644 --- a/composer.json +++ b/composer.json @@ -13,26 +13,24 @@ } }, "require": { - "php": ">=5.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-hydrator": "~1.0", - "zendframework/zend-stdlib": "~2.7" + "php": "^5.5 || ^7.0", + "zendframework/zend-inputfilter": "^2.6", + "zendframework/zend-hydrator": "^1.1 || ^2.1", + "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { "doctrine/annotations": "~1.0", - "zendframework/zend-cache": "~2.5", - "zendframework/zend-captcha": "~2.5", - "zendframework/zend-code": "~2.5", - "zendframework/zend-di": "~2.5", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-i18n": "~2.5", - "zendframework/zend-mvc": "~2.5", - "zendframework/zend-servicemanager": "~2.5", - "zendframework/zend-session": "~2.5", - "zendframework/zend-text": "~2.5", - "zendframework/zend-validator": "~2.5", - "zendframework/zend-view": "~2.5", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-captcha": "^2.5", + "zendframework/zend-code": "^2.6", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-filter": "^2.6", + "zendframework/zend-i18n": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-session": "^2.5", + "zendframework/zend-text": "^2.6", + "zendframework/zend-validator": "^2.6", + "zendframework/zend-view": "^2.6.2", "zendframework/zendservice-recaptcha": "*", "fabpot/php-cs-fixer": "1.7.*", "phpunit/PHPUnit": "~4.0" diff --git a/src/Annotation/AnnotationBuilder.php b/src/Annotation/AnnotationBuilder.php index 553774fa..b339a32f 100644 --- a/src/Annotation/AnnotationBuilder.php +++ b/src/Annotation/AnnotationBuilder.php @@ -126,8 +126,8 @@ public function setEventManager(EventManagerInterface $events) __CLASS__, get_class($this), ]); - $events->attach(new ElementAnnotationsListener()); - $events->attach(new FormAnnotationsListener()); + (new ElementAnnotationsListener())->attach($events); + (new FormAnnotationsListener())->attach($events); $this->events = $events; return $this; } @@ -279,7 +279,7 @@ protected function configureForm($annotations, $reflection, $formSpec, $filterSp foreach ($annotations as $annotation) { $events->trigger(__FUNCTION__, $this, [ 'annotation' => $annotation, - 'name' => $name, + 'name' => $name, 'formSpec' => $formSpec, 'filterSpec' => $filterSpec, ]); @@ -318,31 +318,30 @@ protected function configureElement($annotations, $reflection, $formSpec, $filte 'name' => $name, ]); - $event = new Event(); - $event->setParams([ + $params = [ 'name' => $name, 'elementSpec' => $elementSpec, 'inputSpec' => $inputSpec, 'formSpec' => $formSpec, 'filterSpec' => $filterSpec, - ]); + ]; foreach ($annotations as $annotation) { - $event->setParam('annotation', $annotation); - $events->trigger(__FUNCTION__, $this, $event); + $params['annotation'] = $annotation; + $events->trigger(__FUNCTION__, $this, $params); } // Since "type" is a reserved name in the filter specification, // we need to add the specification without the name as the key. // In all other cases, though, the name is fine. - if ($event->getParam('inputSpec')->count() > 1) { + if ($params['inputSpec']->count() > 1) { if ($name === 'type') { - $filterSpec[] = $event->getParam('inputSpec'); + $filterSpec[] = $params['inputSpec']; } else { - $filterSpec[$name] = $event->getParam('inputSpec'); + $filterSpec[$name] = $params['inputSpec']; } } - $elementSpec = $event->getParam('elementSpec'); + $elementSpec = $params['elementSpec']; $type = (isset($elementSpec['spec']['type'])) ? $elementSpec['spec']['type'] : 'Zend\Form\Element'; @@ -389,12 +388,20 @@ public function preserveDefinedOrder() */ protected function discoverName($annotations, $reflection) { - $results = $this->getEventManager()->trigger('discoverName', $this, [ + $event = new Event(); + $event->setName(__FUNCTION__); + $event->setTarget($this); + $event->setParams([ 'annotations' => $annotations, 'reflection' => $reflection, - ], function ($r) { - return (is_string($r) && !empty($r)); - }); + ]); + + $results = $this->getEventManager()->triggerEventUntil( + function ($r) { + return (is_string($r) && !empty($r)); + }, + $event + ); return $results->last(); } @@ -406,11 +413,17 @@ protected function discoverName($annotations, $reflection) */ protected function checkForExclude($annotations) { - $results = $this->getEventManager()->trigger('checkForExclude', $this, [ - 'annotations' => $annotations, - ], function ($r) { - return (true === $r); - }); + $event = new Event(); + $event->setName(__FUNCTION__); + $event->setTarget($this); + $event->setParams(['annotations' => $annotations]); + + $results = $this->getEventManager()->triggerEventUntil( + function ($r) { + return (true === $r); + }, + $event + ); return (bool) $results->last(); } diff --git a/src/Annotation/ElementAnnotationsListener.php b/src/Annotation/ElementAnnotationsListener.php index 9ea5de9e..a66aa094 100644 --- a/src/Annotation/ElementAnnotationsListener.php +++ b/src/Annotation/ElementAnnotationsListener.php @@ -39,27 +39,27 @@ class ElementAnnotationsListener extends AbstractAnnotationsListener /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { - $this->listeners[] = $events->attach('configureElement', [$this, 'handleAllowEmptyAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleAttributesAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleComposedObjectAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleContinueIfEmptyAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleErrorMessageAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleFilterAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleFlagsAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleHydratorAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleInputAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleObjectAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleOptionsAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleRequiredAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleTypeAnnotation']); - $this->listeners[] = $events->attach('configureElement', [$this, 'handleValidatorAnnotation']); - - $this->listeners[] = $events->attach('discoverName', [$this, 'handleNameAnnotation']); - $this->listeners[] = $events->attach('discoverName', [$this, 'discoverFallbackName']); - - $this->listeners[] = $events->attach('checkForExclude', [$this, 'handleExcludeAnnotation']); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleAllowEmptyAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleAttributesAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleComposedObjectAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleContinueIfEmptyAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleErrorMessageAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleFilterAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleFlagsAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleHydratorAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleInputAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleObjectAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleOptionsAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleRequiredAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleTypeAnnotation'], $priority); + $this->listeners[] = $events->attach('configureElement', [$this, 'handleValidatorAnnotation'], $priority); + + $this->listeners[] = $events->attach('discoverName', [$this, 'handleNameAnnotation'], $priority); + $this->listeners[] = $events->attach('discoverName', [$this, 'discoverFallbackName'], $priority); + + $this->listeners[] = $events->attach('checkForExclude', [$this, 'handleExcludeAnnotation'], $priority); } /** diff --git a/src/Annotation/FormAnnotationsListener.php b/src/Annotation/FormAnnotationsListener.php index 56ade307..832f71b6 100644 --- a/src/Annotation/FormAnnotationsListener.php +++ b/src/Annotation/FormAnnotationsListener.php @@ -37,19 +37,19 @@ class FormAnnotationsListener extends AbstractAnnotationsListener * @param EventManagerInterface $events * @return void */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { - $this->listeners[] = $events->attach('configureForm', [$this, 'handleAttributesAnnotation']); - $this->listeners[] = $events->attach('configureForm', [$this, 'handleFlagsAnnotation']); - $this->listeners[] = $events->attach('configureForm', [$this, 'handleHydratorAnnotation']); - $this->listeners[] = $events->attach('configureForm', [$this, 'handleInputFilterAnnotation']); - $this->listeners[] = $events->attach('configureForm', [$this, 'handleObjectAnnotation']); - $this->listeners[] = $events->attach('configureForm', [$this, 'handleOptionsAnnotation']); - $this->listeners[] = $events->attach('configureForm', [$this, 'handleTypeAnnotation']); - $this->listeners[] = $events->attach('configureForm', [$this, 'handleValidationGroupAnnotation']); - - $this->listeners[] = $events->attach('discoverName', [$this, 'handleNameAnnotation']); - $this->listeners[] = $events->attach('discoverName', [$this, 'discoverFallbackName']); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleAttributesAnnotation'], $priority); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleFlagsAnnotation'], $priority); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleHydratorAnnotation'], $priority); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleInputFilterAnnotation'], $priority); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleObjectAnnotation'], $priority); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleOptionsAnnotation'], $priority); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleTypeAnnotation'], $priority); + $this->listeners[] = $events->attach('configureForm', [$this, 'handleValidationGroupAnnotation'], $priority); + + $this->listeners[] = $events->attach('discoverName', [$this, 'handleNameAnnotation'], $priority); + $this->listeners[] = $events->attach('discoverName', [$this, 'discoverFallbackName'], $priority); } /** diff --git a/src/ElementFactory.php b/src/ElementFactory.php new file mode 100644 index 00000000..bfd6dd76 --- /dev/null +++ b/src/ElementFactory.php @@ -0,0 +1,133 @@ +setCreationOptions($creationOptions); + } + + /** + * Create an instance of the requested class name. + * + * @param ContainerInterface $container + * @param string $requestedName + * @param null|array $options + * @return object + */ + public function __invoke(ContainerInterface $container, $requestedName, array $options = null) + { + if ($options === null) { + $options = []; + } + + if (isset($options['name'])) { + $name = $options['name']; + } else { + // 'Zend\Form\Element' -> 'element' + $parts = explode('\\', $requestedName); + $name = strtolower(array_pop($parts)); + } + + if (isset($options['options'])) { + $options = $options['options']; + } + + return new $requestedName($name, $options); + } + + /** + * Create an instance of the named service. + * + * First, it checks if `$canonicalName` resolves to a class, and, if so, uses + * that value to proxy to `__invoke()`. + * + * Next, if `$requestedName` is non-empty and resolves to a class, this + * method uses that value to proxy to `__invoke()`. + * + * Finally, if the above each fail, it raises an exception. + * + * The approach above is performed as version 2 has two distinct behaviors + * under which factories are invoked: + * + * - If an alias was used, $canonicalName is the resolved name, and + * $requestedName is the service name requested, in which case $canonicalName + * is likely the qualified class name; + * - Otherwise, $canonicalName is the normalized name, and $requestedName + * is the original service name requested (typically the qualified class name). + * + * @param ServiceLocatorInterface $serviceLocator + * @param null|string $canonicalName + * @param null|string $requestedName + * @return object + * @throws InvalidServiceException + */ + public function createService(ServiceLocatorInterface $serviceLocator, $canonicalName = null, $requestedName = null) + { + if (class_exists($canonicalName)) { + return $this($serviceLocator, $canonicalName, $this->creationOptions); + } + + if (is_string($requestedName) && class_exists($requestedName)) { + return $this($serviceLocator, $requestedName, $this->creationOptions); + } + + throw new InvalidServiceException(sprintf( + '%s requires that the requested name is provided on invocation; please update your tests or consuming container', + __CLASS__ + )); + } + + /** + * {@inheritdoc} + */ + public function setCreationOptions(array $creationOptions) + { + if ($creationOptions instanceof Traversable) { + $creationOptions = iterator_to_array($creationOptions); + } + + if (! is_array($creationOptions)) { + throw new InvalidServiceException(sprintf( + '%s cannot use non-array, non-traversable creation options; received %s', + __CLASS__, + (is_object($creationOptions) ? get_class($creationOptions) : gettype($creationOptions)) + )); + } + + $this->creationOptions = $creationOptions; + } +} diff --git a/src/Factory.php b/src/Factory.php index 12b96aab..7e433960 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -14,6 +14,7 @@ use Zend\Hydrator; use Zend\InputFilter\Factory as InputFilterFactory; use Zend\InputFilter\InputFilterInterface; +use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\ArrayUtils; class Factory @@ -85,7 +86,7 @@ public function setFormElementManager(FormElementManager $formElementManager) public function getFormElementManager() { if ($this->formElementManager === null) { - $this->setFormElementManager(new FormElementManager()); + $this->setFormElementManager(new FormElementManager(new ServiceManager())); } return $this->formElementManager; @@ -439,7 +440,7 @@ protected function prepareAndInjectHydrator($hydratorOrName, FieldsetInterface $ } if (is_string($hydratorOrName)) { - $hydrator = $this->getHydratorFromName($hydratorOrName); + $hydrator = $this->getFormElementManager()->getHydratorFromName($hydratorOrName); } if (! isset($hydrator) || !$hydrator instanceof Hydrator\HydratorInterface) { @@ -483,7 +484,7 @@ protected function prepareAndInjectFactory($factoryOrName, FieldsetInterface $fi } if (is_string($factoryOrName)) { - $factoryOrName = $this->getFactoryFromName($factoryOrName); + $factoryOrName = $this->getFormElementManager()->getFactoryFromName($factoryOrName); } if (!$factoryOrName instanceof Factory) { @@ -583,28 +584,12 @@ protected function prepareAndInjectValidationGroup($spec, FormInterface $form, $ */ protected function getHydratorFromName($hydratorName) { - $services = $this->getFormElementManager()->getServiceLocator(); + trigger_error(sprintf( + 'Usage of %s is deprecated since v3.0.0; please use FormElementManager::getHydratorFromName() instead', + __METHOD__ + ), E_USER_DEPRECATED); - if ($services && $services->has('HydratorManager')) { - $hydrators = $services->get('HydratorManager'); - if ($hydrators->has($hydratorName)) { - return $hydrators->get($hydratorName); - } - } - - if ($services && $services->has($hydratorName)) { - return $services->get($hydratorName); - } - - if (!class_exists($hydratorName)) { - throw new Exception\DomainException(sprintf( - 'Expects string hydrator name to be a valid class name; received "%s"', - $hydratorName - )); - } - - $hydrator = new $hydratorName; - return $hydrator; + return $this->getFormElementManager()->getHydratorFromName($hydratorName); } /** @@ -616,20 +601,11 @@ protected function getHydratorFromName($hydratorName) */ protected function getFactoryFromName($factoryName) { - $services = $this->getFormElementManager()->getServiceLocator(); - - if ($services && $services->has($factoryName)) { - return $services->get($factoryName); - } - - if (!class_exists($factoryName)) { - throw new Exception\DomainException(sprintf( - 'Expects string factory name to be a valid class name; received "%s"', - $factoryName - )); - } + trigger_error(sprintf( + 'Usage of %s is deprecated since v3.0.0; please use FormElementManager::getFactoryFromName() instead', + __METHOD__ + ), E_USER_DEPRECATED); - $factory = new $factoryName; - return $factory; + return $this->getFormElementManager()->getFactoryFromName($factoryName); } } diff --git a/src/FormAbstractServiceFactory.php b/src/FormAbstractServiceFactory.php index f99a8b8a..47e3aaa7 100644 --- a/src/FormAbstractServiceFactory.php +++ b/src/FormAbstractServiceFactory.php @@ -9,6 +9,7 @@ namespace Zend\Form; +use Interop\Container\ContainerInterface; use Zend\InputFilter\InputFilterInterface; use Zend\ServiceManager\AbstractFactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; @@ -31,16 +32,38 @@ class FormAbstractServiceFactory implements AbstractFactoryInterface protected $factory; /** - * Can we create the requested service? + * Create a form (v3) * - * @param ServiceLocatorInterface $serviceLocator - * @param string $name Service name (as resolved by ServiceManager) - * @param string $requestedName Name by which service was requested + * @param ContainerInterface $container + * @param string $requestedName + * @param array|null $options + * @return ElementInterface + */ + public function __invoke(ContainerInterface $container, $requestedName, array $options = null) + { + $config = $this->getConfig($container); + $config = $config[$requestedName]; + $factory = $this->getFormFactory($container); + + $this->marshalInputFilter($config, $container, $factory); + return $factory->createForm($config); + } + + /** + * Can we create the requested service? (v3) + * + * @param ContainerInterface $container + * @param string $requestedName * @return bool */ - public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + public function canCreate(ContainerInterface $container, $requestedName) { - $config = $this->getConfig($serviceLocator); + // avoid infinite loops when looking up config + if ($requestedName == 'config') { + return false; + } + + $config = $this->getConfig($container); if (empty($config)) { return false; } @@ -49,7 +72,20 @@ public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator } /** - * Create a form + * Can we create the requested service? (v2) + * + * @param ServiceLocatorInterface $serviceLocator + * @param string $name Service name (as resolved by ServiceManager) + * @param string $requestedName Name by which service was requested + * @return bool + */ + public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + { + return $this->canCreate($serviceLocator, $requestedName); + } + + /** + * Create a form (v2) * * @param ServiceLocatorInterface $serviceLocator * @param string $name Service name (as resolved by ServiceManager) @@ -58,32 +94,27 @@ public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator */ public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) { - $config = $this->getConfig($serviceLocator); - $config = $config[$requestedName]; - $factory = $this->getFormFactory($serviceLocator); - - $this->marshalInputFilter($config, $serviceLocator, $factory); - return $factory->createForm($config); + return $this($serviceLocator, $requestedName); } /** * Get forms configuration, if any * - * @param ServiceLocatorInterface $services + * @param ServiceLocatorInterface $container * @return array */ - protected function getConfig(ServiceLocatorInterface $services) + protected function getConfig(ContainerInterface $container) { if ($this->config !== null) { return $this->config; } - if (!$services->has('Config')) { + if (!$container->has('config')) { $this->config = []; return $this->config; } - $config = $services->get('Config'); + $config = $container->get('config'); if (!isset($config[$this->configKey]) || !is_array($config[$this->configKey]) ) { @@ -98,18 +129,18 @@ protected function getConfig(ServiceLocatorInterface $services) /** * Retrieve the form factory, creating it if necessary * - * @param ServiceLocatorInterface $services + * @param ContainerInterface $services * @return Factory */ - protected function getFormFactory(ServiceLocatorInterface $services) + protected function getFormFactory(ContainerInterface $container) { if ($this->factory instanceof Factory) { return $this->factory; } $elements = null; - if ($services->has('FormElementManager')) { - $elements = $services->get('FormElementManager'); + if ($container->has('FormElementManager')) { + $elements = $container->get('FormElementManager'); } $this->factory = new Factory($elements); @@ -126,10 +157,10 @@ protected function getFormFactory(ServiceLocatorInterface $services) * attaches the FilterManager and ValidatorManager to it. * * @param array $config - * @param ServiceLocatorInterface $services + * @param ContainerInterface $container * @param Factory $formFactory */ - protected function marshalInputFilter(array &$config, ServiceLocatorInterface $services, Factory $formFactory) + protected function marshalInputFilter(array &$config, ContainerInterface $container, Factory $formFactory) { if (!isset($config['input_filter'])) { return; @@ -140,9 +171,9 @@ protected function marshalInputFilter(array &$config, ServiceLocatorInterface $s } if (is_string($config['input_filter']) - && $services->has('InputFilterManager') + && $container->has('InputFilterManager') ) { - $inputFilters = $services->get('InputFilterManager'); + $inputFilters = $container->get('InputFilterManager'); if ($inputFilters->has($config['input_filter'])) { $config['input_filter'] = $inputFilters->get($config['input_filter']); return; @@ -150,7 +181,7 @@ protected function marshalInputFilter(array &$config, ServiceLocatorInterface $s } $inputFilterFactory = $formFactory->getInputFilterFactory(); - $inputFilterFactory->getDefaultFilterChain()->setPluginManager($services->get('FilterManager')); - $inputFilterFactory->getDefaultValidatorChain()->setPluginManager($services->get('ValidatorManager')); + $inputFilterFactory->getDefaultFilterChain()->setPluginManager($container->get('FilterManager')); + $inputFilterFactory->getDefaultValidatorChain()->setPluginManager($container->get('ValidatorManager')); } } diff --git a/src/FormElementManager.php b/src/FormElementManager.php index d950fd1d..3362e50e 100644 --- a/src/FormElementManager.php +++ b/src/FormElementManager.php @@ -9,9 +9,10 @@ namespace Zend\Form; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\AbstractPluginManager; use Zend\ServiceManager\ConfigInterface; -use Zend\ServiceManager\Exception\ServiceNotCreatedException; +use Zend\ServiceManager\Exception\InvalidServiceException; use Zend\ServiceManager\ServiceLocatorInterface; use Zend\Stdlib\InitializableInterface; @@ -23,78 +24,202 @@ class FormElementManager extends AbstractPluginManager { /** - * Default set of helpers + * Aliases for default set of helpers * * @var array */ - protected $invokableClasses = [ - 'button' => 'Zend\Form\Element\Button', - 'captcha' => 'Zend\Form\Element\Captcha', - 'checkbox' => 'Zend\Form\Element\Checkbox', - 'collection' => 'Zend\Form\Element\Collection', - 'color' => 'Zend\Form\Element\Color', - 'csrf' => 'Zend\Form\Element\Csrf', - 'date' => 'Zend\Form\Element\Date', - 'dateselect' => 'Zend\Form\Element\DateSelect', - 'datetime' => 'Zend\Form\Element\DateTime', - 'datetimelocal' => 'Zend\Form\Element\DateTimeLocal', - 'datetimeselect' => 'Zend\Form\Element\DateTimeSelect', - 'element' => 'Zend\Form\Element', - 'email' => 'Zend\Form\Element\Email', - 'fieldset' => 'Zend\Form\Fieldset', - 'file' => 'Zend\Form\Element\File', - 'form' => 'Zend\Form\Form', - 'hidden' => 'Zend\Form\Element\Hidden', - 'image' => 'Zend\Form\Element\Image', - 'month' => 'Zend\Form\Element\Month', - 'monthselect' => 'Zend\Form\Element\MonthSelect', - 'multicheckbox' => 'Zend\Form\Element\MultiCheckbox', - 'number' => 'Zend\Form\Element\Number', - 'password' => 'Zend\Form\Element\Password', - 'radio' => 'Zend\Form\Element\Radio', - 'range' => 'Zend\Form\Element\Range', - 'select' => 'Zend\Form\Element\Select', - 'submit' => 'Zend\Form\Element\Submit', - 'text' => 'Zend\Form\Element\Text', - 'textarea' => 'Zend\Form\Element\Textarea', - 'time' => 'Zend\Form\Element\Time', - 'url' => 'Zend\Form\Element\Url', - 'week' => 'Zend\Form\Element\Week', + protected $aliases = [ + 'button' => Element\Button::class, + 'Button' => Element\Button::class, + 'captcha' => Element\Captcha::class, + 'Captcha' => Element\Captcha::class, + 'checkbox' => Element\Checkbox::class, + 'Checkbox' => Element\Checkbox::class, + 'collection' => Element\Collection::class, + 'Collection' => Element\Collection::class, + 'color' => Element\Color::class, + 'Color' => Element\Color::class, + 'csrf' => Element\Csrf::class, + 'Csrf' => Element\Csrf::class, + 'date' => Element\Date::class, + 'Date' => Element\Date::class, + 'dateselect' => Element\DateSelect::class, + 'DateSelect' => Element\DateSelect::class, + 'datetime' => Element\DateTime::class, + 'DateTime' => Element\DateTime::class, + 'datetimelocal' => Element\DateTimeLocal::class, + 'DateTimeLocal' => Element\DateTimeLocal::class, + 'datetimeselect' => Element\DateTimeSelect::class, + 'DateTimeSelect' => Element\DateTimeSelect::class, + 'element' => Element::class, + 'Element' => Element::class, + 'email' => Element\Email::class, + 'Email' => Element\Email::class, + 'fieldset' => Fieldset::class, + 'Fieldset' => Fieldset::class, + 'file' => Element\File::class, + 'File' => Element\File::class, + 'form' => Form::class, + 'Form' => Form::class, + 'hidden' => Element\Hidden::class, + 'Hidden' => Element\Hidden::class, + 'image' => Element\Image::class, + 'Image' => Element\Image::class, + 'month' => Element\Month::class, + 'Month' => Element\Month::class, + 'monthselect' => Element\MonthSelect::class, + 'MonthSelect' => Element\MonthSelect::class, + 'multicheckbox' => Element\MultiCheckbox::class, + 'MultiCheckbox' => Element\MultiCheckbox::class, + 'number' => Element\Number::class, + 'Number' => Element\Number::class, + 'password' => Element\Password::class, + 'Password' => Element\Password::class, + 'radio' => Element\Radio::class, + 'Radio' => Element\Radio::class, + 'range' => Element\Range::class, + 'Range' => Element\Range::class, + 'select' => Element\Select::class, + 'Select' => Element\Select::class, + 'submit' => Element\Submit::class, + 'Submit' => Element\Submit::class, + 'text' => Element\Text::class, + 'Text' => Element\Text::class, + 'textarea' => Element\Textarea::class, + 'Textarea' => Element\Textarea::class, + 'time' => Element\Time::class, + 'Time' => Element\Time::class, + 'url' => Element\Url::class, + 'Url' => Element\Url::class, + 'week' => Element\Week::class, + 'Week' => Element\Week::class, ]; /** - * Don't share form elements by default + * Factories for default set of helpers + * + * @var array + */ + protected $factories = [ + Element\Button::class => ElementFactory::class, + Element\Captcha::class => ElementFactory::class, + Element\Checkbox::class => ElementFactory::class, + Element\Collection::class => ElementFactory::class, + Element\Color::class => ElementFactory::class, + Element\Csrf::class => ElementFactory::class, + Element\Date::class => ElementFactory::class, + Element\DateSelect::class => ElementFactory::class, + Element\DateTime::class => ElementFactory::class, + Element\DateTimeLocal::class => ElementFactory::class, + Element\DateTimeSelect::class => ElementFactory::class, + Element::class => ElementFactory::class, + Element\Email::class => ElementFactory::class, + Fieldset::class => ElementFactory::class, + Element\File::class => ElementFactory::class, + Form::class => ElementFactory::class, + Element\Hidden::class => ElementFactory::class, + Element\Image::class => ElementFactory::class, + Element\Month::class => ElementFactory::class, + Element\MonthSelect::class => ElementFactory::class, + Element\MultiCheckbox::class => ElementFactory::class, + Element\Number::class => ElementFactory::class, + Element\Password::class => ElementFactory::class, + Element\Radio::class => ElementFactory::class, + Element\Range::class => ElementFactory::class, + Element\Select::class => ElementFactory::class, + Element\Submit::class => ElementFactory::class, + Element\Text::class => ElementFactory::class, + Element\Textarea::class => ElementFactory::class, + Element\Time::class => ElementFactory::class, + Element\Url::class => ElementFactory::class, + Element\Week::class => ElementFactory::class, + + // v2 normalized variants + + 'zendformelementbutton' => ElementFactory::class, + 'zendformelementcaptcha' => ElementFactory::class, + 'zendformelementcheckbox' => ElementFactory::class, + 'zendformelementcollection' => ElementFactory::class, + 'zendformelementcolor' => ElementFactory::class, + 'zendformelementcsrf' => ElementFactory::class, + 'zendformelementdate' => ElementFactory::class, + 'zendformelementdateselect' => ElementFactory::class, + 'zendformelementdatetime' => ElementFactory::class, + 'zendformelementdatetimelocal' => ElementFactory::class, + 'zendformelementdatetimeselect' => ElementFactory::class, + 'zendformelement' => ElementFactory::class, + 'zendformelementemail' => ElementFactory::class, + 'zendformfieldset' => ElementFactory::class, + 'zendformelementfile' => ElementFactory::class, + 'zendformform' => ElementFactory::class, + 'zendformelementhidden' => ElementFactory::class, + 'zendformelementimage' => ElementFactory::class, + 'zendformelementmonth' => ElementFactory::class, + 'zendformelementmonthselect' => ElementFactory::class, + 'zendformelementmulticheckbox' => ElementFactory::class, + 'zendformelementnumber' => ElementFactory::class, + 'zendformelementpassword' => ElementFactory::class, + 'zendformelementradio' => ElementFactory::class, + 'zendformelementrange' => ElementFactory::class, + 'zendformelementselect' => ElementFactory::class, + 'zendformelementsubmit' => ElementFactory::class, + 'zendformelementtext' => ElementFactory::class, + 'zendformelementtextarea' => ElementFactory::class, + 'zendformelementtime' => ElementFactory::class, + 'zendformelementurl' => ElementFactory::class, + 'zendformelementweek' => ElementFactory::class, + ]; + + /** + * Don't share form elements by default (v3) + * + * @var bool + */ + protected $sharedByDefault = false; + + /** + * Don't share form elements by default (v2) * * @var bool */ protected $shareByDefault = false; + protected $instanceOf = ElementInterface::class; + /** - * @param ConfigInterface $configuration + * @param null|ConfigInterface|ContainerInterface $configOrContainerInstance + * @param array $v3config If $configOrContainerInstance is a container, this + * value will be passed to the parent constructor. */ - public function __construct(ConfigInterface $configuration = null) + public function __construct($configInstanceOrParentLocator = null, array $v3config = []) { - parent::__construct($configuration); + parent::__construct($configInstanceOrParentLocator, $v3config); $this->addInitializer([$this, 'injectFactory']); - $this->addInitializer([$this, 'callElementInit'], false); + $this->addInitializer([$this, 'callElementInit']); } /** * Inject the factory to any element that implements FormFactoryAwareInterface * - * @param $element + * @param mixed $first + * @param mixed $second */ - public function injectFactory($element) + public function injectFactory($first, $second) { - if ($element instanceof FormFactoryAwareInterface) { - $factory = $element->getFormFactory(); + if ($first instanceof ContainerInterface) { + $container = $first; + $instance = $second; + } else { + $container = $second; + $instance = $first; + } + if ($instance instanceof FormFactoryAwareInterface) { + $factory = $instance->getFormFactory(); $factory->setFormElementManager($this); - if ($this->serviceLocator instanceof ServiceLocatorInterface - && $this->serviceLocator->has('InputFilterManager') - ) { - $inputFilters = $this->serviceLocator->get('InputFilterManager'); + if ($container instanceof ServiceLocatorInterface && $container->has('InputFilterManager')) { + $inputFilters = $container->get('InputFilterManager'); $factory->getInputFilterFactory()->setInputFilterManager($inputFilters); } } @@ -105,32 +230,58 @@ public function injectFactory($element) * * @internal param $element */ - public function callElementInit($element) + public function callElementInit($first, $second) { - if ($element instanceof InitializableInterface) { - $element->init(); + if ($first instanceof ContainerInterface) { + $instance = $second; + } else { + $instance = $first; + } + if ($instance instanceof InitializableInterface) { + $instance->init(); } } /** - * Validate the plugin + * Validate the plugin is of the expected type (v3). * - * Checks that the element is an instance of ElementInterface + * Validates against `$instanceOf`. * - * @param mixed $plugin - * @throws Exception\InvalidElementException + * @param mixed $instance + * @throws InvalidServiceException * @return void */ - public function validatePlugin($plugin) + public function validate($instance) { - if ($plugin instanceof ElementInterface) { - return; // we're okay + if (! $instance instanceof $this->instanceOf) { + throw new InvalidServiceException(sprintf( + '%s can only create instances of %s; %s is invalid', + get_class($this), + $this->instanceOf, + (is_object($instance) ? get_class($instance) : gettype($instance)) + )); } + } - throw new Exception\InvalidElementException(sprintf( - 'Plugin of type %s is invalid; must implement Zend\Form\ElementInterface', - (is_object($plugin) ? get_class($plugin) : gettype($plugin)) - )); + /** + * Validate the plugin is of the expected type (v2). + * + * Proxies to `validate()`. + * + * @param mixed $instance + * @throws Exception\InvalidElementException + */ + public function validatePlugin($instance) + { + try { + $this->validate($instance); + } catch (InvalidServiceException $e) { + throw new Exception\InvalidElementException( + $e->getMessage(), + $e->getCode(), + $e + ); + } } /** @@ -154,40 +305,73 @@ public function get($name, $options = [], $usePeeringServiceManagers = true) } /** - * Attempt to create an instance via an invokable class + * Try to pull hydrator from the creation context, or instantiates it from its name * - * Overrides parent implementation by passing $creationOptions to the - * constructor, if non-null. - * - * @param string $canonicalName - * @param string $requestedName - * @return null|\stdClass - * @throws ServiceNotCreatedException If resolved class does not exist + * @param string $hydratorName + * @return mixed + * @throws Exception\DomainException */ - protected function createFromInvokable($canonicalName, $requestedName) + public function getHydratorFromName($hydratorName) { - $invokable = $this->invokableClasses[$canonicalName]; - - if (null === $this->creationOptions - || (is_array($this->creationOptions) && empty($this->creationOptions)) - ) { - $instance = new $invokable(); + if (method_exists($this, 'configure')) { + // v3 + $services = $this->creationContext; } else { - if (isset($this->creationOptions['name'])) { - $name = $this->creationOptions['name']; - } else { - $name = $requestedName; - } + // v2 + $services = $this->serviceLocator; + } - if (isset($this->creationOptions['options'])) { - $options = $this->creationOptions['options']; - } else { - $options = $this->creationOptions; + if ($services && $services->has('HydratorManager')) { + $hydrators = $services->get('HydratorManager'); + if ($hydrators->has($hydratorName)) { + return $hydrators->get($hydratorName); } + } + + if ($services && $services->has($hydratorName)) { + return $services->get($hydratorName); + } + + if (!class_exists($hydratorName)) { + throw new Exception\DomainException(sprintf( + 'Expects string hydrator name to be a valid class name; received "%s"', + $hydratorName + )); + } + + $hydrator = new $hydratorName; + return $hydrator; + } + + /** + * Try to pull factory from the creation context, or instantiates it from its name + * + * @param string $factoryName + * @return mixed + * @throws Exception\DomainException + */ + public function getFactoryFromName($factoryName) + { + if (method_exists($this, 'configure')) { + // v3 + $services = $this->creationContext; + } else { + // v2 + $services = $this->serviceLocator; + } + + if ($services && $services->has($factoryName)) { + return $services->get($factoryName); + } - $instance = new $invokable($name, $options); + if (!class_exists($factoryName)) { + throw new Exception\DomainException(sprintf( + 'Expects string factory name to be a valid class name; received "%s"', + $factoryName + )); } - return $instance; + $factory = new $factoryName; + return $factory; } } diff --git a/src/View/HelperConfig.php b/src/View/HelperConfig.php index 46a97093..470bfaa3 100644 --- a/src/View/HelperConfig.php +++ b/src/View/HelperConfig.php @@ -10,6 +10,7 @@ namespace Zend\Form\View; use Zend\ServiceManager\ConfigInterface; +use Zend\ServiceManager\Factory\InvokableFactory; use Zend\ServiceManager\ServiceManager; /** @@ -22,55 +23,256 @@ class HelperConfig implements ConfigInterface * * @var array */ - protected $invokables = [ - 'form' => 'Zend\Form\View\Helper\Form', - 'formbutton' => 'Zend\Form\View\Helper\FormButton', - 'formcaptcha' => 'Zend\Form\View\Helper\FormCaptcha', - 'captchadumb' => 'Zend\Form\View\Helper\Captcha\Dumb', - 'formcaptchadumb' => 'Zend\Form\View\Helper\Captcha\Dumb', - 'captchafiglet' => 'Zend\Form\View\Helper\Captcha\Figlet', - 'formcaptchafiglet' => 'Zend\Form\View\Helper\Captcha\Figlet', - 'captchaimage' => 'Zend\Form\View\Helper\Captcha\Image', - 'formcaptchaimage' => 'Zend\Form\View\Helper\Captcha\Image', - 'captcharecaptcha' => 'Zend\Form\View\Helper\Captcha\ReCaptcha', - 'formcaptcharecaptcha' => 'Zend\Form\View\Helper\Captcha\ReCaptcha', - 'formcheckbox' => 'Zend\Form\View\Helper\FormCheckbox', - 'formcollection' => 'Zend\Form\View\Helper\FormCollection', - 'formcolor' => 'Zend\Form\View\Helper\FormColor', - 'formdate' => 'Zend\Form\View\Helper\FormDate', - 'formdatetime' => 'Zend\Form\View\Helper\FormDateTime', - 'formdatetimelocal' => 'Zend\Form\View\Helper\FormDateTimeLocal', - 'formdatetimeselect' => 'Zend\Form\View\Helper\FormDateTimeSelect', - 'formdateselect' => 'Zend\Form\View\Helper\FormDateSelect', - 'formelement' => 'Zend\Form\View\Helper\FormElement', - 'formelementerrors' => 'Zend\Form\View\Helper\FormElementErrors', - 'formemail' => 'Zend\Form\View\Helper\FormEmail', - 'formfile' => 'Zend\Form\View\Helper\FormFile', - 'formfileapcprogress' => 'Zend\Form\View\Helper\File\FormFileApcProgress', - 'formfilesessionprogress' => 'Zend\Form\View\Helper\File\FormFileSessionProgress', - 'formfileuploadprogress' => 'Zend\Form\View\Helper\File\FormFileUploadProgress', - 'formhidden' => 'Zend\Form\View\Helper\FormHidden', - 'formimage' => 'Zend\Form\View\Helper\FormImage', - 'forminput' => 'Zend\Form\View\Helper\FormInput', - 'formlabel' => 'Zend\Form\View\Helper\FormLabel', - 'formmonth' => 'Zend\Form\View\Helper\FormMonth', - 'formmonthselect' => 'Zend\Form\View\Helper\FormMonthSelect', - 'formmulticheckbox' => 'Zend\Form\View\Helper\FormMultiCheckbox', - 'formnumber' => 'Zend\Form\View\Helper\FormNumber', - 'formpassword' => 'Zend\Form\View\Helper\FormPassword', - 'formradio' => 'Zend\Form\View\Helper\FormRadio', - 'formrange' => 'Zend\Form\View\Helper\FormRange', - 'formreset' => 'Zend\Form\View\Helper\FormReset', - 'formrow' => 'Zend\Form\View\Helper\FormRow', - 'formsearch' => 'Zend\Form\View\Helper\FormSearch', - 'formselect' => 'Zend\Form\View\Helper\FormSelect', - 'formsubmit' => 'Zend\Form\View\Helper\FormSubmit', - 'formtel' => 'Zend\Form\View\Helper\FormTel', - 'formtext' => 'Zend\Form\View\Helper\FormText', - 'formtextarea' => 'Zend\Form\View\Helper\FormTextarea', - 'formtime' => 'Zend\Form\View\Helper\FormTime', - 'formurl' => 'Zend\Form\View\Helper\FormUrl', - 'formweek' => 'Zend\Form\View\Helper\FormWeek', + protected $aliases = [ + 'form' => Helper\Form::class, + 'Form' => Helper\Form::class, + 'formbutton' => Helper\FormButton::class, + 'form_button' => Helper\FormButton::class, + 'formButton' => Helper\FormButton::class, + 'FormButton' => Helper\FormButton::class, + 'formcaptcha' => Helper\FormCaptcha::class, + 'form_captcha' => Helper\FormCaptcha::class, + 'formCaptcha' => Helper\FormCaptcha::class, + 'FormCaptcha' => Helper\FormCaptcha::class, + 'captchadumb' => Helper\Captcha\Dumb::class, + 'captcha_dumb' => Helper\Captcha\Dumb::class, + // weird alias used by Zend\Captcha + 'captcha/dumb' => Helper\Captcha\Dumb::class, + 'CaptchaDumb' => Helper\Captcha\Dumb::class, + 'captchaDumb' => Helper\Captcha\Dumb::class, + 'formcaptchadumb' => Helper\Captcha\Dumb::class, + 'form_captcha_dumb' => Helper\Captcha\Dumb::class, + 'formCaptchaDumb' => Helper\Captcha\Dumb::class, + 'FormCaptchaDumb' => Helper\Captcha\Dumb::class, + 'captchafiglet' => Helper\Captcha\Figlet::class, + // weird alias used by Zend\Captcha + 'captcha/figlet' => Helper\Captcha\Figlet::class, + 'captcha_figlet' => Helper\Captcha\Figlet::class, + 'captchaFiglet' => Helper\Captcha\Figlet::class, + 'CaptchaFiglet' => Helper\Captcha\Figlet::class, + 'formcaptchafiglet' => Helper\Captcha\Figlet::class, + 'form_captcha_figlet' => Helper\Captcha\Figlet::class, + 'formCaptchaFiglet' => Helper\Captcha\Figlet::class, + 'FormCaptchaFiglet' => Helper\Captcha\Figlet::class, + 'captchaimage' => Helper\Captcha\Image::class, + // weird alias used by Zend\Captcha + 'captcha/image' => Helper\Captcha\Image::class, + 'captcha_image' => Helper\Captcha\Image::class, + 'captchaImage' => Helper\Captcha\Image::class, + 'CaptchaImage' => Helper\Captcha\Image::class, + 'formcaptchaimage' => Helper\Captcha\Image::class, + 'form_captcha_image' => Helper\Captcha\Image::class, + 'formCaptchaImage' => Helper\Captcha\Image::class, + 'FormCaptchaImage' => Helper\Captcha\Image::class, + 'captcharecaptcha' => Helper\Captcha\ReCaptcha::class, + // weird alias used by Zend\Captcha + 'captcha/recaptcha' => Helper\Captcha\ReCaptcha::class, + 'captcha_recaptcha' => Helper\Captcha\ReCaptcha::class, + 'captchaRecaptcha' => Helper\Captcha\ReCaptcha::class, + 'CaptchaRecaptcha' => Helper\Captcha\ReCaptcha::class, + 'formcaptcharecaptcha' => Helper\Captcha\ReCaptcha::class, + 'form_captcha_recaptcha' => Helper\Captcha\ReCaptcha::class, + 'formCaptchaRecaptcha' => Helper\Captcha\ReCaptcha::class, + 'FormCaptchaRecaptcha' => Helper\Captcha\ReCaptcha::class, + 'formcheckbox' => Helper\FormCheckbox::class, + 'form_checkbox' => Helper\FormCheckbox::class, + 'formCheckbox' => Helper\FormCheckbox::class, + 'FormCheckbox' => Helper\FormCheckbox::class, + 'formcollection' => Helper\FormCollection::class, + 'form_collection' => Helper\FormCollection::class, + 'formCollection' => Helper\FormCollection::class, + 'FormCollection' => Helper\FormCollection::class, + 'formcolor' => Helper\FormColor::class, + 'form_color' => Helper\FormColor::class, + 'formColor' => Helper\FormColor::class, + 'FormColor' => Helper\FormColor::class, + 'formdate' => Helper\FormDate::class, + 'form_date' => Helper\FormDate::class, + 'formDate' => Helper\FormDate::class, + 'FormDate' => Helper\FormDate::class, + 'formdatetime' => Helper\FormDateTime::class, + 'form_date_time' => Helper\FormDateTime::class, + 'formDateTime' => Helper\FormDateTime::class, + 'FormDateTime' => Helper\FormDateTime::class, + 'formdatetimelocal' => Helper\FormDateTimeLocal::class, + 'form_date_time_local' => Helper\FormDateTimeLocal::class, + 'formDateTimeLocal' => Helper\FormDateTimeLocal::class, + 'FormDateTimeLocal' => Helper\FormDateTimeLocal::class, + 'formdatetimeselect' => Helper\FormDateTimeSelect::class, + 'form_date_time_select' => Helper\FormDateTimeSelect::class, + 'formDateTimeSelect' => Helper\FormDateTimeSelect::class, + 'FormDateTimeSelect' => Helper\FormDateTimeSelect::class, + 'formdateselect' => Helper\FormDateSelect::class, + 'form_date_select' => Helper\FormDateSelect::class, + 'formDateSelect' => Helper\FormDateSelect::class, + 'FormDateSelect' => Helper\FormDateSelect::class, + 'form_element' => Helper\FormElement::class, + 'formelement' => Helper\FormElement::class, + 'formElement' => Helper\FormElement::class, + 'FormElement' => Helper\FormElement::class, + 'form_element_errors' => Helper\FormElementErrors::class, + 'formelementerrors' => Helper\FormElementErrors::class, + 'formElementErrors' => Helper\FormElementErrors::class, + 'FormElementErrors' => Helper\FormElementErrors::class, + 'form_email' => Helper\FormEmail::class, + 'formemail' => Helper\FormEmail::class, + 'formEmail' => Helper\FormEmail::class, + 'FormEmail' => Helper\FormEmail::class, + 'form_file' => Helper\FormFile::class, + 'formfile' => Helper\FormFile::class, + 'formFile' => Helper\FormFile::class, + 'FormFile' => Helper\FormFile::class, + 'formfileapcprogress' => Helper\File\FormFileApcProgress::class, + 'form_file_apc_progress' => Helper\File\FormFileApcProgress::class, + 'formFileApcProgress' => Helper\File\FormFileApcProgress::class, + 'FormFileApcProgress' => Helper\File\FormFileApcProgress::class, + 'formfilesessionprogress' => Helper\File\FormFileSessionProgress::class, + 'form_file_session_progress' => Helper\File\FormFileSessionProgress::class, + 'formFileSessionProgress' => Helper\File\FormFileSessionProgress::class, + 'FormFileSessionProgress' => Helper\File\FormFileSessionProgress::class, + 'formfileuploadprogress' => Helper\File\FormFileUploadProgress::class, + 'form_file_upload_progress' => Helper\File\FormFileUploadProgress::class, + 'formFileUploadProgress' => Helper\File\FormFileUploadProgress::class, + 'FormFileUploadProgress' => Helper\File\FormFileUploadProgress::class, + 'formhidden' => Helper\FormHidden::class, + 'form_hidden' => Helper\FormHidden::class, + 'formHidden' => Helper\FormHidden::class, + 'FormHidden' => Helper\FormHidden::class, + 'formimage' => Helper\FormImage::class, + 'form_image' => Helper\FormImage::class, + 'formImage' => Helper\FormImage::class, + 'FormImage' => Helper\FormImage::class, + 'forminput' => Helper\FormInput::class, + 'form_input' => Helper\FormInput::class, + 'formInput' => Helper\FormInput::class, + 'FormInput' => Helper\FormInput::class, + 'formlabel' => Helper\FormLabel::class, + 'form_label' => Helper\FormLabel::class, + 'formLabel' => Helper\FormLabel::class, + 'FormLabel' => Helper\FormLabel::class, + 'formmonth' => Helper\FormMonth::class, + 'form_month' => Helper\FormMonth::class, + 'formMonth' => Helper\FormMonth::class, + 'FormMonth' => Helper\FormMonth::class, + 'formmonthselect' => Helper\FormMonthSelect::class, + 'form_month_select' => Helper\FormMonthSelect::class, + 'formMonthSelect' => Helper\FormMonthSelect::class, + 'FormMonthSelect' => Helper\FormMonthSelect::class, + 'formmulticheckbox' => Helper\FormMultiCheckbox::class, + 'form_multi_checkbox' => Helper\FormMultiCheckbox::class, + 'formMultiCheckbox' => Helper\FormMultiCheckbox::class, + 'FormMultiCheckbox' => Helper\FormMultiCheckbox::class, + 'formnumber' => Helper\FormNumber::class, + 'form_number' => Helper\FormNumber::class, + 'formNumber' => Helper\FormNumber::class, + 'FormNumber' => Helper\FormNumber::class, + 'formpassword' => Helper\FormPassword::class, + 'form_password' => Helper\FormPassword::class, + 'formPassword' => Helper\FormPassword::class, + 'FormPassword' => Helper\FormPassword::class, + 'formradio' => Helper\FormRadio::class, + 'form_radio' => Helper\FormRadio::class, + 'formRadio' => Helper\FormRadio::class, + 'FormRadio' => Helper\FormRadio::class, + 'formrange' => Helper\FormRange::class, + 'form_range' => Helper\FormRange::class, + 'formRange' => Helper\FormRange::class, + 'FormRange' => Helper\FormRange::class, + 'formreset' => Helper\FormReset::class, + 'form_reset' => Helper\FormReset::class, + 'formReset' => Helper\FormReset::class, + 'FormReset' => Helper\FormReset::class, + 'formrow' => Helper\FormRow::class, + 'form_row' => Helper\FormRow::class, + 'formRow' => Helper\FormRow::class, + 'FormRow' => Helper\FormRow::class, + 'formsearch' => Helper\FormSearch::class, + 'form_search' => Helper\FormSearch::class, + 'formSearch' => Helper\FormSearch::class, + 'FormSearch' => Helper\FormSearch::class, + 'formselect' => Helper\FormSelect::class, + 'form_select' => Helper\FormSelect::class, + 'formSelect' => Helper\FormSelect::class, + 'FormSelect' => Helper\FormSelect::class, + 'formsubmit' => Helper\FormSubmit::class, + 'form_submit' => Helper\FormSubmit::class, + 'formSubmit' => Helper\FormSubmit::class, + 'FormSubmit' => Helper\FormSubmit::class, + 'formtel' => Helper\FormTel::class, + 'form_tel' => Helper\FormTel::class, + 'formTel' => Helper\FormTel::class, + 'FormTel' => Helper\FormTel::class, + 'formtext' => Helper\FormText::class, + 'form_text' => Helper\FormText::class, + 'formText' => Helper\FormText::class, + 'FormText' => Helper\FormText::class, + 'formtextarea' => Helper\FormTextarea::class, + 'form_text_area' => Helper\FormTextarea::class, + 'formTextArea' => Helper\FormTextarea::class, + 'FormTextArea' => Helper\FormTextarea::class, + 'formtime' => Helper\FormTime::class, + 'form_time' => Helper\FormTime::class, + 'formTime' => Helper\FormTime::class, + 'FormTime' => Helper\FormTime::class, + 'formurl' => Helper\FormUrl::class, + 'form_url' => Helper\FormUrl::class, + 'formUrl' => Helper\FormUrl::class, + 'FormUrl' => Helper\FormUrl::class, + 'formweek' => Helper\FormWeek::class, + 'form_week' => Helper\FormWeek::class, + 'formWeek' => Helper\FormWeek::class, + 'FormWeek' => Helper\FormWeek::class, + ]; + + protected $factories = [ + Helper\Form::class => InvokableFactory::class, + Helper\FormButton::class => InvokableFactory::class, + Helper\FormCaptcha::class => InvokableFactory::class, + Helper\Captcha\Dumb::class => InvokableFactory::class, + Helper\Captcha\Dumb::class => InvokableFactory::class, + Helper\Captcha\Figlet::class => InvokableFactory::class, + Helper\Captcha\Figlet::class => InvokableFactory::class, + Helper\Captcha\Image::class => InvokableFactory::class, + Helper\Captcha\Image::class => InvokableFactory::class, + Helper\Captcha\ReCaptcha::class => InvokableFactory::class, + Helper\Captcha\ReCaptcha::class => InvokableFactory::class, + Helper\FormCheckbox::class => InvokableFactory::class, + Helper\FormCollection::class => InvokableFactory::class, + Helper\FormColor::class => InvokableFactory::class, + Helper\FormDate::class => InvokableFactory::class, + Helper\FormDateTime::class => InvokableFactory::class, + Helper\FormDateTimeLocal::class => InvokableFactory::class, + Helper\FormDateTimeSelect::class => InvokableFactory::class, + Helper\FormDateSelect::class => InvokableFactory::class, + Helper\FormElement::class => InvokableFactory::class, + Helper\FormElementErrors::class => InvokableFactory::class, + Helper\FormEmail::class => InvokableFactory::class, + Helper\FormFile::class => InvokableFactory::class, + Helper\File\FormFileApcProgress::class => InvokableFactory::class, + Helper\File\FormFileSessionProgress::class => InvokableFactory::class, + Helper\File\FormFileUploadProgress::class => InvokableFactory::class, + Helper\FormHidden::class => InvokableFactory::class, + Helper\FormImage::class => InvokableFactory::class, + Helper\FormInput::class => InvokableFactory::class, + Helper\FormLabel::class => InvokableFactory::class, + Helper\FormMonth::class => InvokableFactory::class, + Helper\FormMonthSelect::class => InvokableFactory::class, + Helper\FormMultiCheckbox::class => InvokableFactory::class, + Helper\FormNumber::class => InvokableFactory::class, + Helper\FormPassword::class => InvokableFactory::class, + Helper\FormRadio::class => InvokableFactory::class, + Helper\FormRange::class => InvokableFactory::class, + Helper\FormReset::class => InvokableFactory::class, + Helper\FormRow::class => InvokableFactory::class, + Helper\FormSearch::class => InvokableFactory::class, + Helper\FormSelect::class => InvokableFactory::class, + Helper\FormSubmit::class => InvokableFactory::class, + Helper\FormTel::class => InvokableFactory::class, + Helper\FormText::class => InvokableFactory::class, + Helper\FormTextarea::class => InvokableFactory::class, + Helper\FormTime::class => InvokableFactory::class, + Helper\FormUrl::class => InvokableFactory::class, + Helper\FormWeek::class => InvokableFactory::class, ]; /** @@ -79,13 +281,24 @@ class HelperConfig implements ConfigInterface * * Adds the invokables defined in this class to the SM managing helpers. * - * @param ServiceManager $serviceManager - * @return void + * @param ServiceManager $serviceManager + * @return ServiceManager */ public function configureServiceManager(ServiceManager $serviceManager) { - foreach ($this->invokables as $name => $service) { - $serviceManager->setInvokableClass($name, $service); + foreach ($this->factories as $service => $factory) { + $serviceManager->setFactory($service, $factory); + } + + foreach ($this->aliases as $alias => $target) { + $serviceManager->setAlias($alias, $target); } + + return $serviceManager; + } + + public function toArray() + { + return ['aliases' => $this->aliases, 'factories' => $this->factories]; } } diff --git a/test/Element/CaptchaTest.php b/test/Element/CaptchaTest.php index 5db57bb5..192f67c9 100644 --- a/test/Element/CaptchaTest.php +++ b/test/Element/CaptchaTest.php @@ -19,6 +19,16 @@ class CaptchaTest extends TestCase { + public function setUp() + { + if (! class_exists(Captcha\Dumb::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + } + public function testCaptchaIsUndefinedByDefault() { $element = new CaptchaElement(); diff --git a/test/Element/CsrfTest.php b/test/Element/CsrfTest.php index 7c0fce57..a8383a8f 100644 --- a/test/Element/CsrfTest.php +++ b/test/Element/CsrfTest.php @@ -11,9 +11,20 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\Form\Element\Csrf as CsrfElement; +use Zend\Session\Container; class CsrfTest extends TestCase { + public function setUp() + { + if (! class_exists(Container::class)) { + $this->markTestSkipped( + 'zend-session-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + } + public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttributes() { $element = new CsrfElement('foo'); diff --git a/test/FactoryTest.php b/test/FactoryTest.php index a85ec06f..817b6373 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -24,10 +24,15 @@ class FactoryTest extends TestCase */ protected $factory; + /** + * @var ServiceManager + */ + protected $services; + public function setUp() { - $elementManager = new FormElementManager(); - $elementManager->setServiceLocator(new ServiceManager()); + $this->services = new ServiceManager(); + $elementManager = new FormElementManager($this->services); $this->factory = new FormFactory($elementManager); } @@ -257,10 +262,10 @@ public function testCanCreateFormsWithInputFilterSpecifications() 'required' => false, 'validators' => [ [ - 'name' => 'not_empty', + 'name' => 'NotEmpty', ], [ - 'name' => 'string_length', + 'name' => 'StringLength', 'options' => [ 'min' => 3, 'max' => 5, @@ -272,10 +277,10 @@ public function testCanCreateFormsWithInputFilterSpecifications() 'allow_empty' => true, 'filters' => [ [ - 'name' => 'string_trim', + 'name' => 'StringTrim', ], [ - 'name' => 'string_to_lower', + 'name' => 'StringToLower', 'options' => [ 'encoding' => 'ISO-8859-1', ], @@ -333,10 +338,7 @@ public function testCanCreateFormsAndSpecifyHydrator() public function testCanCreateFormsAndSpecifyHydratorManagedByHydratorManager() { - $hydrators = new HydratorPluginManager(); - $services = $this->factory->getFormElementManager()->getServiceLocator(); - $hydrators->setServiceLocator($services); - $services->setService('HydratorManager', new HydratorPluginManager()); + $this->services->setService('HydratorManager', new HydratorPluginManager($this->services)); $form = $this->factory->createForm([ 'name' => 'foo', @@ -415,7 +417,7 @@ public function testCanCreateFactoryFromConcreteClass() public function testCanCreateFormFromConcreteClassAndSpecifyCustomValidatorByName() { - $validatorManager = new \Zend\Validator\ValidatorPluginManager(); + $validatorManager = new \Zend\Validator\ValidatorPluginManager($this->services); $validatorManager->setInvokableClass('baz', 'Zend\Validator\Digits'); $defaultValidatorChain = new \Zend\Validator\ValidatorChain(); @@ -692,8 +694,7 @@ public function testAutomaticallyAddFormTypeWhenCreateForm() public function testCanPullHydratorThroughServiceManager() { - $serviceLocator = $this->factory->getFormElementManager()->getServiceLocator(); - $serviceLocator->setInvokableClass('MyHydrator', 'Zend\Hydrator\ObjectProperty'); + $this->services->setInvokableClass('MyHydrator', 'Zend\Hydrator\ObjectProperty'); $fieldset = $this->factory->createFieldset([ 'hydrator' => 'MyHydrator', diff --git a/test/FormAbstractServiceFactoryTest.php b/test/FormAbstractServiceFactoryTest.php index 045d7928..c04431a3 100644 --- a/test/FormAbstractServiceFactoryTest.php +++ b/test/FormAbstractServiceFactoryTest.php @@ -23,17 +23,11 @@ class FormAbstractServiceFactoryTest extends TestCase public function setUp() { $services = $this->services = new ServiceManager; - $elements = new FormElementManager; - $filters = new FilterPluginManager; - $hydrators = new HydratorPluginManager; - $inputFilters = new InputFilterPluginManager; - $validators = new ValidatorPluginManager; - - $elements->setServiceLocator($services); - $filters->setServiceLocator($services); - $hydrators->setServiceLocator($services); - $inputFilters->setServiceLocator($services); - $validators->setServiceLocator($services); + $elements = new FormElementManager($services); + $filters = new FilterPluginManager($services); + $hydrators = new HydratorPluginManager($services); + $inputFilters = new InputFilterPluginManager($services); + $validators = new ValidatorPluginManager($services); $services->setService('FilterManager', $filters); $services->setService('FormElementManager', $elements); @@ -43,7 +37,7 @@ public function setUp() $inputFilters->setInvokableClass('FooInputFilter', 'Zend\InputFilter\InputFilter'); - $forms = $this->forms = new FormAbstractServiceFactory; + $forms = $this->forms = new FormAbstractServiceFactory($services); $services->addAbstractFactory($forms); } @@ -54,31 +48,31 @@ public function testMissingConfigServiceIndicatesCannotCreateForm() public function testMissingFormServicePrefixIndicatesCannotCreateForm() { - $this->services->setService('Config', []); + $this->services->setService('config', []); $this->assertFalse($this->forms->canCreateServiceWithName($this->services, 'foo', 'foo')); } public function testMissingFormManagerConfigIndicatesCannotCreateForm() { - $this->services->setService('Config', []); + $this->services->setService('config', []); $this->assertFalse($this->forms->canCreateServiceWithName($this->services, 'Form\Foo', 'Form\Foo')); } public function testInvalidFormManagerConfigIndicatesCannotCreateForm() { - $this->services->setService('Config', ['forms' => 'string']); + $this->services->setService('config', ['forms' => 'string']); $this->assertFalse($this->forms->canCreateServiceWithName($this->services, 'Form\Foo', 'Form\Foo')); } public function testEmptyFormManagerConfigIndicatesCannotCreateForm() { - $this->services->setService('Config', ['forms' => []]); + $this->services->setService('config', ['forms' => []]); $this->assertFalse($this->forms->canCreateServiceWithName($this->services, 'Form\Foo', 'Form\Foo')); } public function testMissingFormConfigIndicatesCannotCreateForm() { - $this->services->setService('Config', [ + $this->services->setService('config', [ 'forms' => [ 'Bar' => [], ], @@ -88,7 +82,7 @@ public function testMissingFormConfigIndicatesCannotCreateForm() public function testInvalidFormConfigIndicatesCannotCreateForm() { - $this->services->setService('Config', [ + $this->services->setService('config', [ 'forms' => [ 'Foo' => 'string', ], @@ -98,7 +92,7 @@ public function testInvalidFormConfigIndicatesCannotCreateForm() public function testEmptyFormConfigIndicatesCannotCreateForm() { - $this->services->setService('Config', [ + $this->services->setService('config', [ 'forms' => [ 'Foo' => [], ], @@ -108,7 +102,7 @@ public function testEmptyFormConfigIndicatesCannotCreateForm() public function testPopulatedFormConfigIndicatesFormCanBeCreated() { - $this->services->setService('Config', [ + $this->services->setService('config', [ 'forms' => [ 'Foo' => [ 'type' => 'Zend\Form\Form', @@ -138,7 +132,7 @@ public function testFormCanBeCreatedViaInteractionOfAllManagers() 'input_filter' => 'FooInputFilter', ]; $config = ['forms' => ['Foo' => $formConfig]]; - $this->services->setService('Config', $config); + $this->services->setService('config', $config); $form = $this->forms->createServiceWithName($this->services, 'Foo', 'Foo'); $this->assertInstanceOf('Zend\Form\Form', $form); @@ -177,19 +171,19 @@ public function testFormCanBeCreatedViaInteractionOfAllManagersExceptInputFilter 'required' => true, 'filters' => [ [ - 'name' => 'string_trim', + 'name' => 'StringTrim', ], ], 'validators' => [ [ - 'name' => 'email_address', + 'name' => 'EmailAddress', ], ], ], ], ]; $config = ['forms' => ['Foo' => $formConfig]]; - $this->services->setService('Config', $config); + $this->services->setService('config', $config); $form = $this->forms->createServiceWithName($this->services, 'Foo', 'Foo'); $this->assertInstanceOf('Zend\Form\Form', $form); diff --git a/test/FormElementManagerFactoryTest.php b/test/FormElementManagerFactoryTest.php deleted file mode 100644 index d9537f16..00000000 --- a/test/FormElementManagerFactoryTest.php +++ /dev/null @@ -1,118 +0,0 @@ - []]); - $services = $this->services = new ServiceManager(); - $services->setService('Zend\ServiceManager\ServiceLocatorInterface', $services); - $services->setFactory('FormElementManager', $formElementManagerFactory); - $services->setService('Config', $config); - $services->setFactory('Di', new DiFactory()); - $services->setFactory('DiAbstractServiceFactory', new DiAbstractServiceFactoryFactory()); - $services->setFactory('DiServiceInitializer', new DiServiceInitializerFactory()); - - $this->manager = $services->get('FormElementManager'); - - $this->standaloneManager = new FormElementManager(); - } - - public function tearDown() - { - $ref = new \ReflectionClass('Zend\Validator\Csrf'); - $hashCache = $ref->getProperty('hashCache'); - $hashCache->setAccessible(true); - $hashCache->setValue(new Csrf, []); - SessionContainer::setDefaultManager(null); - } - - public function testWillInstantiateFormFromInvokable() - { - $form = $this->manager->get('form'); - $this->assertInstanceof('Zend\Form\Form', $form); - } - - public function testWillInstantiateFormFromDiAbstractFactory() - { - //without DiAbstractFactory - $this->assertFalse($this->standaloneManager->has('ZendTest\Form\TestAsset\CustomForm')); - //with DiAbstractFactory - $this->assertTrue($this->manager->has('ZendTest\Form\TestAsset\CustomForm')); - $form = $this->manager->get('ZendTest\Form\TestAsset\CustomForm'); - $this->assertInstanceof('ZendTest\Form\TestAsset\CustomForm', $form); - } - - public function testNoWrapFieldName() - { - $form = $this->manager->get('ZendTest\Form\TestAsset\CustomForm'); - $this->assertFalse($form->wrapElements(), 'ensure wrapElements option'); - $this->assertTrue($form->has('email'), 'ensure the form has email element'); - $emailElement = $form->get('email'); - $this->assertEquals('email', $emailElement->getName()); - } - - public function testCsrfCompatibility() - { - $_SESSION = []; - $formClass = 'ZendTest\Form\TestAsset\CustomForm'; - $ref = new \ReflectionClass('Zend\Validator\Csrf'); - $hashPropRef = $ref->getProperty('hash'); - $hashPropRef->setAccessible(true); - //check bare born - $preForm = new $formClass; - $csrf = $preForm->get('csrf')->getCsrfValidator(); - $this->assertNull($hashPropRef->getValue($csrf), 'Test "new Form" has no hash'); - //check FormElementManager - $postForm = $this->manager->get($formClass); - $postCsrf = $postForm->get('csrf')->getCsrfValidator(); - $this->assertNull($hashPropRef->getValue($postCsrf), 'Test "form from FormElementManager" has no hash'); - } - - public function testCsrfWorkFlow() - { - $_SESSION = []; - $formClass = 'ZendTest\Form\TestAsset\CustomForm'; - - $preForm = new $formClass; - $preForm->prepare(); - $requestHash = $preForm->get('csrf')->getValue(); - - $postForm = $this->manager->get($formClass); - $postCsrf = $postForm->get('csrf')->getCsrfValidator(); - - $this->assertTrue($postCsrf->isValid($requestHash), 'Test csrf validation'); - } -} diff --git a/test/FormElementManagerTest.php b/test/FormElementManagerTest.php index a641797e..b88c10d1 100644 --- a/test/FormElementManagerTest.php +++ b/test/FormElementManagerTest.php @@ -9,9 +9,12 @@ namespace ZendTest\Form; +use Zend\Form\Exception\InvalidElementException; use Zend\Form\Factory; use Zend\Form\Form; use Zend\Form\FormElementManager; +use Zend\ServiceManager\Exception\InvalidServiceException; +use Zend\ServiceManager\ServiceManager; /** * @group Zend_Form @@ -25,7 +28,7 @@ class FormElementManagerTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->manager = new FormElementManager(); + $this->manager = new FormElementManager(new ServiceManager()); } public function testInjectToFormFactoryAware() @@ -45,24 +48,32 @@ public function testInjectsFormElementManagerToFormComposedByFormFactoryAwareEle $form->setFormFactory($factory); return $form; }); - $form = $this->manager->get('my-Form'); + $form = $this->manager->get('my-form'); $this->assertSame($factory, $form->getFormFactory()); $this->assertSame($this->manager, $form->getFormFactory()->getFormElementManager()); } public function testRegisteringInvalidElementRaisesException() { - $this->setExpectedException('Zend\Form\Exception\InvalidElementException'); + $this->setExpectedException($this->getInvalidServiceException()); $this->manager->setService('test', $this); } public function testLoadingInvalidElementRaisesException() { $this->manager->setInvokableClass('test', get_class($this)); - $this->setExpectedException('Zend\Form\Exception\InvalidElementException'); + $this->setExpectedException($this->getInvalidServiceException()); $this->manager->get('test'); } + protected function getInvalidServiceException() + { + if (method_exists($this->manager, 'configure')) { + return InvalidServiceException::class; + } + return InvalidElementException::class; + } + public function testStringCreationOptions() { $args = 'foo'; diff --git a/test/FormTest.php b/test/FormTest.php index 142166ef..c4515764 100644 --- a/test/FormTest.php +++ b/test/FormTest.php @@ -92,10 +92,10 @@ public function populateForm() 'required' => false, 'validators' => [ [ - 'name' => 'not_empty', + 'name' => 'NotEmpty', ], [ - 'name' => 'string_length', + 'name' => 'StringLength', 'options' => [ 'min' => 3, 'max' => 5, @@ -107,10 +107,10 @@ public function populateForm() 'allow_empty' => true, 'filters' => [ [ - 'name' => 'string_trim', + 'name' => 'StringTrim', ], [ - 'name' => 'string_to_lower', + 'name' => 'StringToLower', 'options' => [ 'encoding' => 'ISO-8859-1', ], @@ -124,10 +124,10 @@ public function populateForm() 'required' => true, 'validators' => [ [ - 'name' => 'not_empty', + 'name' => 'NotEmpty', ], [ - 'name' => 'string_length', + 'name' => 'StringLength', 'options' => [ 'min' => 3, 'max' => 5, @@ -139,10 +139,10 @@ public function populateForm() 'allow_empty' => true, 'filters' => [ [ - 'name' => 'string_trim', + 'name' => 'StringTrim', ], [ - 'name' => 'string_to_lower', + 'name' => 'StringToLower', 'options' => [ 'encoding' => 'ISO-8859-1', ], @@ -1722,7 +1722,7 @@ public function testFileInputFilterNotOverwritten() $this->assertInstanceOf('Zend\InputFilter\FileInput', $fileInput); $chain = $fileInput->getFilterChain(); - $this->assertCount(1, $chain, var_export($chain, 1)); + $this->assertCount(1, $chain, print_r($chain, 1)); } public function testInputFilterNotAddedTwiceWhenUsingFieldsets() diff --git a/test/View/Helper/Captcha/DumbTest.php b/test/View/Helper/Captcha/DumbTest.php index 724e5415..e4fefbf4 100644 --- a/test/View/Helper/Captcha/DumbTest.php +++ b/test/View/Helper/Captcha/DumbTest.php @@ -18,6 +18,13 @@ class DumbTest extends CommonTestCase { public function setUp() { + if (! class_exists(DumbCaptcha::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $this->helper = new DumbCaptchaHelper(); $this->captcha = new DumbCaptcha(); parent::setUp(); diff --git a/test/View/Helper/Captcha/FigletTest.php b/test/View/Helper/Captcha/FigletTest.php index 2d36c77d..37b669f5 100644 --- a/test/View/Helper/Captcha/FigletTest.php +++ b/test/View/Helper/Captcha/FigletTest.php @@ -18,6 +18,13 @@ class FigletTest extends CommonTestCase { public function setUp() { + if (! class_exists(FigletCaptcha::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $this->helper = new FigletCaptchaHelper(); $this->captcha = new FigletCaptcha(); parent::setUp(); diff --git a/test/View/Helper/Captcha/ImageTest.php b/test/View/Helper/Captcha/ImageTest.php index 10a177b4..540f6293 100644 --- a/test/View/Helper/Captcha/ImageTest.php +++ b/test/View/Helper/Captcha/ImageTest.php @@ -33,6 +33,13 @@ public function setUp() $this->markTestSkipped("Image CAPTCHA requires FT fonts support"); } + if (! class_exists(ImageCaptcha::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $this->testDir = $this->getTmpDir() . '/ZF_test_images'; if (!is_dir($this->testDir)) { @mkdir($this->testDir); diff --git a/test/View/Helper/Captcha/ReCaptchaTest.php b/test/View/Helper/Captcha/ReCaptchaTest.php index 2c638366..7b4a9db2 100644 --- a/test/View/Helper/Captcha/ReCaptchaTest.php +++ b/test/View/Helper/Captcha/ReCaptchaTest.php @@ -22,6 +22,13 @@ public function setUp() $this->markTestSkipped('Enable TESTS_ZEND_FORM_RECAPTCHA_SUPPORT to test PDF render'); } + if (! class_exists(ReCaptcha::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $this->helper = new ReCaptchaHelper(); $this->captcha = new ReCaptcha(); $service = $this->captcha->getService(); diff --git a/test/View/Helper/CommonTestCase.php b/test/View/Helper/CommonTestCase.php index 5426ef98..55d099c6 100644 --- a/test/View/Helper/CommonTestCase.php +++ b/test/View/Helper/CommonTestCase.php @@ -36,7 +36,7 @@ public function setUp() $this->renderer = new PhpRenderer; $helpers = $this->renderer->getHelperPluginManager(); $config = new HelperConfig(); - $config->configureServiceManager($helpers); + $this->renderer->setHelperPluginManager($config->configureServiceManager($helpers)); $this->helper->setView($this->renderer); } diff --git a/test/View/Helper/FormCaptchaTest.php b/test/View/Helper/FormCaptchaTest.php index 850143f1..a99c7a76 100644 --- a/test/View/Helper/FormCaptchaTest.php +++ b/test/View/Helper/FormCaptchaTest.php @@ -21,6 +21,13 @@ class FormCaptchaTest extends CommonTestCase public function setUp() { + if (! class_exists(Captcha\Dumb::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $this->helper = new FormCaptchaHelper(); parent::setUp(); } diff --git a/test/View/Helper/FormElementTest.php b/test/View/Helper/FormElementTest.php index be90fd73..d8e0c966 100644 --- a/test/View/Helper/FormElementTest.php +++ b/test/View/Helper/FormElementTest.php @@ -14,6 +14,7 @@ use Zend\Form\Element; use Zend\Form\View\HelperConfig; use Zend\Form\View\Helper\FormElement as FormElementHelper; +use Zend\Session\Container; use Zend\View\Helper\Doctype; use Zend\View\Renderer\PhpRenderer; @@ -134,6 +135,13 @@ public function testRendersMultiElementsAsExpected($type, $inputType, $additiona public function testRendersCaptchaAsExpected() { + if (! class_exists(Captcha\Dumb::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $captcha = new Captcha\Dumb(); $element = new Element\Captcha('foo'); $element->setCaptcha($captcha); @@ -144,6 +152,13 @@ public function testRendersCaptchaAsExpected() public function testRendersCsrfAsExpected() { + if (! class_exists(Container::class)) { + $this->markTestSkipped( + 'zend-session-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $element = new Element\Csrf('foo'); $inputSpec = $element->getInputSpecification(); $hash = ''; diff --git a/test/View/Helper/FormRowTest.php b/test/View/Helper/FormRowTest.php index 5a562f16..2c26de45 100644 --- a/test/View/Helper/FormRowTest.php +++ b/test/View/Helper/FormRowTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Form\View\Helper; use PHPUnit_Framework_TestCase as TestCase; +use Zend\Captcha as ZendCaptcha; use Zend\Form\Element; use Zend\Form\Element\Captcha; use Zend\Form\View\HelperConfig; @@ -345,7 +346,7 @@ public function testErrorShowTwice() $element->setMessages($validator->getMessages()); $markup = $this->helper->__invoke($element); - $this->assertEquals(2, count(explode("", $markup))); + $this->assertEquals(2, count(explode("", $markup))); } public function testInvokeWithNoRenderErrors() @@ -520,6 +521,13 @@ public function testCanSetOptionToWrapElementInLabel() */ public function testWrapFieldsetAroundCaptchaWithLabel() { + if (! class_exists(ZendCaptcha\Dump::class)) { + $this->markTestSkipped( + 'zend-captcha-related tests are skipped until the component ' + . 'is forwards-compatible with zend-servicemanager v3' + ); + } + $this->assertRegexp( '#^
baz<\/legend>' . 'Please type this word backwards [a-z0-9]{8}<\/b>'