0

Я не могу загрузить мой CustomValidator через завод:ZF2 - валидатора через завод

namespace My\Validator; 
class CustomValidator extends AbstractValidator 
{ 
public function __construct(EntityManager $em, AuthenticationService $auth) 
{ 
    $this->auth = $auth; 
    $this->em = $em; 

    parent::__construct(); 
} 

Module (My) Config:

namespace My; 
... 
'service_manager' => array(
    'abstract_factories' => array(
    'Application\Factory\FormAbstractFactory' 
), 
), 
'controllers' => array(
    'factories' => array(
     'My\Controller\CustomController' => 'My\Factory\Controller\CustomControllerFactory', 
    ), 
), 
'validators' => array(
    'factories' => array(
     'My\Validator\CustomValidator' => 'My\Factory\Validator\CustomValidatorFactory' 
    ), 
), 

CustomForm:

namespace My\Form; 
class CustomForm extends SearchForm implements InputFilterProviderInterface { 
    public function __construct(ObjectManager $objectManager, Translator $translator) { 
     parent::__construct ($objectManager, $translator, "customForm"); 
     // Here are some elements added... 
     $this->add(array("name" => "search", /* some more properties */)); 
    } 

    public function getInputFilterSpecification() 
    { 
     return array(
      'search' => array(
       'validators' => array(
        array(
         'name' => 'My\Validator\CustomValidator' 
        ) 
       ) 
      ) 
     ); 
    } 
} 

CustomValidatorFactory:

namespace My\Factory\Validator; 
class CustomValidatorFactory implements FactoryInterface { 
public function createService(ServiceLocatorInterface $serviceLocator) 
{ 
    $sl = $serviceLocator->get("service_manager"); 
    $entityManager = $sl->get('doctrine.entitymanager.orm_default'); 
    $auth = $sl->get('zfcuser_auth_service'); 

    return new CustomValidator($entityManager, $auth); 
} 

я получаю ошибку PHP, говоря первый параметр ($ их) этот __construct должен быть экземпляром EntityManager, никто не дал ... Моей фабрики не инстанцированная ... Я думаю, что мое CustomValidator по-прежнему создается какой-либо другой фабрикой (или ValidatorPluginManager?) ... Как мне изменить свой код, чтобы работать с моим CustomValidatorFactory?

EDIT - полное исключение, оказывая вид с формой, которая имеет свой собственный валидатор прилагается:

(!) Fatal error: Uncaught TypeError: Argument 1 passed to My\Validator\CustomValidator::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /xxxxxx/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php on line 252 and defined in /xxxxxx/module/My/src/My/Validator/CustomValidator.php on line 32 
(!) TypeError: Argument 1 passed to My\Validator\CustomValidator::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /xxxxxx/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php on line 252 in /xxxxxx/module/My/src/My/Validator/CustomValidator.php on line 32 
Call Stack 
# Time Memory Function Location 
1 0.0001 369208 {main}() .../index.php:0 
2 0.1165 11279664 Zend\Mvc\Application->run() .../index.php:28 
3 0.2780 17578688 Zend\Mvc\Application->completeRequest() .../Application.php:356 
4 0.2780 17578688 Zend\EventManager\EventManager->triggerEvent() .../Application.php:384 
5 0.2780 17578688 Zend\EventManager\EventManager->triggerListeners() .../EventManager.php:251 
6 0.2781 17580376 call_user_func:{/xxxxxx/vendor/zendframework/zend-eventmanager/src/EventManager.php:490} () .../EventManager.php:490 
7 0.2781 17580376 Zend\Mvc\View\Http\DefaultRenderingStrategy->render() .../EventManager.php:490 
8 0.2781 17580376 Zend\View\View->render() .../DefaultRenderingStrategy.php:103 
9 0.2786 17591848 Zend\View\View->renderChildren() .../View.php:200 
10 0.2787 17592840 Zend\View\View->render() .../View.php:236 
11 0.2789 17593272 Zend\View\Renderer\PhpRenderer->render() .../View.php:207 
12 0.2792 17633952 include('/xxxxxx/module/My/view/my/view/index.phtml') .../PhpRenderer.php:502 
13 0.2810 17743208 Zend\Form\Form->prepare() .../index.phtml:13 
14 0.2810 17743208 Zend\Form\Form->getInputFilter() .../Form.php:203 
15 0.2819 17885496 Zend\Form\Form->attachInputFilterDefaults() .../Form.php:696 
16 0.2836 18054248 Zend\InputFilter\Factory->createInput() .../Form.php:801 
17 0.2837 18054888 Zend\InputFilter\Factory->populateValidators() .../Factory.php:265 
18 0.2837 18054944 Zend\Validator\ValidatorChain->attachByName() .../Factory.php:408 
19 0.2837 18054944 Zend\Validator\ValidatorChain->plugin() .../ValidatorChain.php:194 
20 0.2837 18057312 Zend\ServiceManager\AbstractPluginManager->get() .../ValidatorChain.php:97 
21 0.2839 18068224 Zend\ServiceManager\ServiceManager->get() .../AbstractPluginManager.php:161 
22 0.2839 18068920 Zend\ServiceManager\ServiceManager->create() .../ServiceManager.php:532 
23 0.2839 18068920 Zend\ServiceManager\ServiceManager->doCreate() .../ServiceManager.php:599 
24 0.2839 18068920 Zend\ServiceManager\AbstractPluginManager->createFromInvokable() .../ServiceManager.php:640 
25 0.2839 18069160 My\Validator\CustomValidator->__construct() .../AbstractPluginManager.php:252 

EDIT2 - FormAbstractFactory:

class FormAbstractFactory implements AbstractFactoryInterface { 

    public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 
    { 
     return (fnmatch('*Form', $requestedName)) ? true : false; 
    } 

    public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 
    { 
     if (class_exists($requestedName)) { 
      $entityManager = $serviceLocator->get('doctrine.entitymanager.orm_default'); 
      $translator = $serviceLocator->get('translator'); 

      return new $requestedName($entityManager, $translator); 
     } 

     return false; 
    } 

} 

CustomControllerFactory:

namespace My\Factory\Controller; 
use My\Controller\CustomController; 
class CustomControllerFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $realServiceLocator = $serviceLocator->getServiceLocator(); 
     $entityManager  = $realServiceLocator->get('doctrine.entitymanager.orm_default'); 
     // Created through FormAbstractFactory 
     $customForm   = $realServiceLocator->get('My\Form\CustomForm'); 
     $orderByService  = $realServiceLocator->get('Application\Service\OrderByServiceAbstract'); 

     return new CustomController($entityManager, $customForm, $orderByService); 
    } 
} 

CustomController

namespace My\Controller; 

class CustomController extends AbstractActionController 
{ 
    public function __construct(ObjectManager $entityManager, CustomForm $customForm, OrderByService $orderByService) 
    { 
     $this->em = $entityManager; 
     $this->form = $customForm; 
     $this->orderByService = $orderByService; 
    } 

    public function indexAction() 
    { 
     // some code... 

     $vm = new ViewModel (array(
      "form" => $this->form 
     )); 

     $vm->setTemplate("my/custom/index"); 

     return $vm; 
    } 
} 

мой/пользовательский/индекс - Вид:

<?php 
namespace My; 
$form = $this->form; 
$form->prepare(); ?> 
<!-- HTML Stuff... -> 
<?php echo $this->form($form, null); ?> 
<!-- HTML Stuff... -> 

Ну я использую пользовательский форм-визуализатор тоже - https://github.com/neilime/zf2-twb-bundle.

я подал вопрос на ZF2 в мерзавце: https://github.com/zendframework/zf2/issues/7688

+1

Первая строка '$ serviceLocator-> get (" service_manager ")' 'должна быть' $ serviceLocator-> getServiceLocator() '. Кроме того, может возникнуть смысл переименовать переменную '$ serviceLocator' в' $ validatorPluginManager', чтобы сохранить путаницу. – AlexP

+0

Спасибо ... Я редактировал мой код и повторил - но все равно не повезло. Отображаемое исключение все еще намекает, что AbstractPluginManager пытается создать Validator из Invokable: Zend \ ServiceManager \ AbstractPluginManager-> createFromInvokable(). Я думаю, что что-то не так, как я настроил свой валидатор ... Любая подсказка? – mfuesslin

+0

То, что у вас есть, должно работать, хотя мне кажется странным, что входные фильтры, выбрасывающие эту ошибку в представлении, а не контроллер, заставляют меня думать, что представление - это первое место, где создается форма? Кроме того, вы создаете форму через '$ formElementManager-> get ('name_of_form')'? – AlexP

ответ

1

Вы создаете форму-е через ServiceManager.

$customForm = $realServiceLocator->get('My\Form\CustomForm'); 

Это значит, у вас есть абстрактный завод, зарегистрированный с менеджером службы, а не менеджером элемента формы. При этом будет создана форма without form factory's input filter being correctly prepared.

Переместите эту конфигурацию в ключ 'form_elements'.

'form_elements' => [ 
    'abstract_factories' => [ 
      'My\Form\FormAbstractFactory', 
    ], 
] 

В CustomControllerFactory вам необходимо будет обновить.

$formElementManager = $realServiceLocator->get('FormElementManager'); 
$customForm = $formElementManager->get('My\Form\CustomForm'); 

И, наконец, метод FormAbstractFactory::createServiceWithName() теперь нужно $serviceLocator = $serviceLocator->getServiceLocator() на самом верху.

+1

Большое спасибо! Я этого не видел! Валидатор теперь создается через фабрику. – mfuesslin

+1

oh одна вещь для добавления: массив-ключ «abstract_factories» not «abstract_factory» ... – mfuesslin

+0

Вы можете предлагать редактирование самостоятельно на чьи-либо сообщения. –

Смежные вопросы