Related
I am creating a form using factories and specified form structure by configuring Fieldsets.
However, user with the role "admin" may edit form with all fields of an Entity and regular user "client" edit just few fields. That is why I have to delete elements from fieldsets in controller.
$this->form->getBaseFieldset()->remove('name');
$this->form->getBaseFieldset()->remove('title');
$this->form->getBaseFieldset()->remove('message');`
Is it possible to specify in Fieldset or Form configuration for what role element must be added or deleted?
class ZoneDefaultElement extends Fieldset implements InputFilterProviderInterface
{
public function __construct($name, $entity)
{
parent::__construct($name);
$this->add([
'name' => 'title',
'type' => Element\Text::class,
'attributes' => [
'class' => 'form-control',
],
'options' => [
'label' => 'Title',
'label_attributes' => [
'class' => 'col-sm-2 control-label required',
],
],
], ['priority' => 1])
};
}
The second parameter of the constructor can be anything (in fact in Fieldset it is an empty array if not given), so you should be able to just pass in an array of items to use:
class ZoneDefaultElement extends Fieldset implements InputFilterProviderInterface
{
public function __construct($name, $options)
{
parent::__construct($name);
$entity = $options['entity'];
$user = $options['user'];
// Standard element
$this->add([
'name' => 'title',
'type' => Element\Text::class,
'attributes' => [
'class' => 'form-control',
],
'options' => [
'label' => 'Title',
'label_attributes' => [
'class' => 'col-sm-2 control-label required',
],
],
], ['priority' => 1]);
if ($user->isAdmin()) {
// Add "admin-only" elements
}
};
}
Solution provided above is pretty ok. If system is not very large and contains few elements in forms it is possible to maintain it. As fare as system is a little bit complex I decided to provide more OOP solution.
class ZoneDefaultElement extends Fieldset implements InputFilterProviderInterface
{
public function __construct($name, $entity)
{
parent::__construct($name);
$this->add([
'name' => 'title',
'options' => [
'label' => 'Title',
],
], ['priority' => 1, 'access' => ['allow' => ['admin'])
}
};
And deny configuration will be like this :
$this->add([
'name' => 'message',
'options' => [
'label' => 'Message',
],
], ['priority' => 1, 'access' => ['deny' => ['guest'])
I have added one more layer between Fieldset and my custom fieldsets:
class ExtendedFieldset extends Fieldset
{
public $formMiddleware;
public function __construct($name = null, $options = array())
{
parent::__construct($name);
}
public function add($elementOrFieldset, array $flags = [])
{
if (array_key_exists('access', $flags)) {
if(!$this->getFormMiddleware()->filter($flags['access'])){
return false;
};
}
parent::add($elementOrFieldset, $flags);
}
public function setFormMiddleware(FormMiddleware $formMiddleware)
{
$this->formMiddleware = $formMiddleware;
}
public function getFormMiddleware()
{
if (!$this->formMiddleware) {
throw new \InvalidArgumentException("FormMiddleware not specified");
}
return $this->formMiddleware;
}
}
Now we have to extend from this ExtendedFiedset witch overwrites parent add() method and has setter and getter for middleware where filter logic realized.
class UserFieldset extends ExtendedFieldset implements InputFilterProviderInterface
{
private $entityManager;
public function __construct(EntityManager $entity, FormMiddleware $formMiddleware)
{
$this->setFormMiddleware($formMiddleware);
parent::__construct('fieldset');
$this->add([
'name' => 'email',
'type' => Element\Email::class,
'attributes' => [
'class' => 'form-control',
'required' => 'required',
],
'options' => [
'label' => 'Email:',
'label_attributes' => [
'class' => 'col-sm-4 control-label required',
],
],
], ['priority' => 1, ['access' => ['deny' => ['guest']]]]);
}
}
And finally FormMiddleware:
class FormMiddleware
{
private $authenticationService;
public function __construct(AuthenticationServiceInterface $service)
{
$this->authenticationService = $service;
}
private function getUserRole() : string
{
$this->getIdentity()->getRole();
}
public function getIdentity()
{
$identity = $this->authenticationService->getIdentity();
return $identity;
}
public function filter(array $resource = [])
{
$marker = true;
if(!empty($resource)){
if(array_key_exists('deny', $resource)){
if(in_array($this->getUserRole(), $resource['deny'])){
$marker = false;
}else{
$marker = true;
}
}
if(array_key_exists('allow', $resource)) {
if(in_array($this->getUserRole(), $resource['allow'])){
$marker = true;
}else{
$marker = false;
}
}
}
return $marker;
}
}
It depends on project structure, I hope an idea is clear...
I have an registration form User\UserForm which contains a fieldset User\UserFieldset. In User\UserFieldset I put an field called "passwordVerify" which should be identical with another field in the fieldset called "password".
This works fine.
However, if an admin wants to modify an user account within the Admin\UserForm, which also contains the User\UserFieldset, the field "passwordVerify" in the fieldset User\UserFieldset should be removed. Therefore I call the following within the Admin\UserForm:
$this->get('user')->remove('passwordVerify');
$this->getInputFilter()->get('user')->remove('passwordVerify')
As expected, the form lacks the field "passwordVerify" now.
If I save the form after editing some stuff, my custom filter "PasswordFilter" cannot retrieve the bound object of the fieldset anymore ($this->getOption('object'); returns an User-object) - but all properties of the bound object are nulled. If I use the Admin\UserForm without removing "passwordVerify"-field and "passwordVerify"-inputfilter everything works fine and the bound object is passed to "PasswordFilter" with populated properties (in respect of values, inserted by the user in the Admin\UserForm). The line which breaks everything is $this->getInputFilter()->get('user')->remove('passwordVerify'). So this leads to my assumption, that by removing an inputfilter, the hydrated object gets somehow nulled / emptied. Below are my some excerpts of my code, if needed I can provide more information about factories, etc.
Admin\UserForm:
class UserForm extends Form
{
/**
* #var EntityManager
*/
protected $entityManager = null;
/**
* #var Translator
*/
protected $translator = null;
public function __construct(EntityManager $entityManager, Translator $translator)
{
$this->entityManager = $entityManager;
$this->translator = $translator;
parent::__construct("userForm");
$this->setHydrator(new DoctrineHydrator($entityManager));
}
public function init()
{
// Adding UserFieldset
$this->add(array(
'name' => 'user',
'type' => \User\Form\UserFieldset::class,
'options' => array(
'use_as_base_fieldset' => true,
),
));
$this->get('user')->remove('passwordVerify');
$this->getInputFilter()->get('user')->remove('passwordVerify');
$this->add(array(
'type' => 'Zend\Form\Element\Csrf',
'name' => 'csrf',
));
$this->add(array(
'type' => 'submit',
'name' => 'submit',
'options' => array(
'label' => $this->translator->translate('Btn.submit.user', 'Form')
),
));
}
}
User\UserFieldset:
class UserFieldset extends Fieldset implements InputFilterProviderInterface
{
/**
* #var EntityManager
*/
protected $entityManager = null;
/**
* #var Translator
*/
protected $translator = null;
public function __construct(EntityManager $entityManager, Translator $translator)
{
$this->entityManager = $entityManager;
$this->translator = $translator;
parent::__construct("userFieldset");
$this->setHydrator(new DoctrineHydrator($entityManager))->setObject(new User());
}
public function init()
{
$this->add(array(
'type' => 'text',
'name' => 'firstName',
'options' => array(
'label' => $this->translator->translate('label.firstName', 'Form'),
'label_attributes' => array(
'class' => 'col-sm-3',
),
'column-size' => 'sm-5',
),
'attributes' => array(
'id' => 'firstName',
),
));
/* ... */
$this->add(array(
'type' => 'text',
'name' => 'password',
'options' => array(
'label' => $this->translator->translate('label.password', 'Form'),
'label_attributes' => array(
'class' => 'col-sm-3',
),
'column-size' => 'sm-5',
),
'attributes' => array(
'id' => 'password',
),
));
$this->add(array(
'type' => 'password',
'name' => 'passwordVerify',
'options' => array(
'label_attributes' => array(
'class' => 'col-sm-3 control-label'
),
'label' => $this->translator->translate('label.verifyPassword', 'Form'),
'column-size' => 'sm-8',
),
'attributes' => array(
'class' => 'form-control',
'id' => 'password'),
));
/* ... */
// Adding AddressFieldset
$this->add(array(
'name' => 'address',
'type' => \User\Form\AddressFieldset::class,
));
/* ... */
$this->add(array(
'type' => 'datetime',
'name' => 'created',
'options' => array(
'label' => $this->translator->translate('label.created', 'Form'),
'format' => 'd.m.Y H:i',
'label_attributes' => array(
'class' => 'col-sm-3',
),
'column-size' => 'sm-5',
),
'attributes' => array(
'id' => 'created',
),
));
}
public function getInputFilterSpecification()
{
return array(
'firstName' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags'),
),
'validators' => array(),
),
/* ... */
'password' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags'),
[
'name' => PasswordFilter::class,
'options' => [
'object' => $this->getObject(),
'field' => 'password'
]
]
),
'validators' => array(),
),
'passwordVerify' => array(
'required' => true,
'filters' => [
[
'name' => PasswordFilter::class,
'options' => [
'object' => $this->getObject(),
'field' => 'password'
]
]
],
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'min' => 6
)
),
array(
'name' => 'Identical',
'options' => array(
'token' => 'password'
)
)
)
),
/* ... */
'created' => array(
'required' => false,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'Date',
'options' => array('format' => 'd.m.Y H:i')
),
),
)
);
}
}
PasswordFilter:
class PasswordFilter extends AbstractFilter
{
/** #var EntityManager */
protected $entityManager;
/** #var PasswordInterface */
protected $passwordManager;
/**
* PasswordFilter constructor.
* #param EntityManager $entityManager
* #param PasswordInterface $passwordManager
* #param array $options
*/
public function __construct(EntityManager $entityManager, PasswordInterface $passwordManager, $options = [])
{
$this->entityManager = $entityManager;
$this->passwordManager = $passwordManager;
$this->options = $options;
}
public function filter($value)
{
$object = $this->getOption('object');
$field = $this->getOption('field');
$getter = 'get'.ucfirst($field);
if (!$object || !$field) {
throw new \Exception('Options "object" and "field" are required.');
}
if ($object->getId()) {
$dbObject = $this->entityManager->getRepository(get_class($object))->find($object->getId());
if ($value === $dbObject->{$getter}()) {
return $value;
}
}
// hash password here...
return $this->passwordManager->create($value);
}
private function getOption($option)
{
if (array_key_exists($option, $this->options)) {
return $this->options[$option];
}
return false;
}
}
Any clues? Do I call remove inputfilter of "passwordVerify" to early in the process of instantiation?
I also tested to remove the inputFilter and field after "$this->form->bind($user)" in my controller, which also works. Why it does not work then if I remove it in Admin\UserForm, which is in my opinion the cleaner way of managing the "passwordVerify"-stuff?
If you call $this->getInputFilter(), the InputProviderInterface::getInputSpecification method in your UserForm is being called.
If you did not attached the object already, it cannot retrieve it.
But I dont get why you would even need that. You are hashing the password if the value does not fit to the database value, but obviously the database value seems to be plain text as the input or why would you compare it?
IMHO you just should hash the password, no matter what the current value in your database is.
If you are using doctrine and the password wont change, it wont execute an UPDATE query anyway.
The problem
I have a Form and a FieldSet. I would like to validate that the FieldSet is not empty. Also, I want to validate each field in the FieldSet.
So far, whatever I have tried is validating one or the other, but not both. If elements is present in the Form's input filter specification, then it validates that elements is not empty, but does not validate the bar and baz fields of FieldSet. And, of course, the other way around. Any clue as to how to approach this issue would be much appreciated.
The Form
class FooForm extends Form implements InputFilterProviderInterface
{
public function init()
{
$this->add([
'name' => 'elements',
'type' => Collection::class,
'required' => true,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class
]
]
]);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'elements',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
The FieldSet
class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
public function init()
{
$this->add(['name' => 'bar']);
$this->add(['name' => 'baz']);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'bar',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
[
'name' => 'baz',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
Edit: Added full validation spec.
After getting some hints on Google and digging through the source code, I found a solution. Unfortunately the zend-inputfilter implementation is a little buggy and won't work nicely with getInputFilterSpecification(), but we can just construct our own InputFilter and return that directly:
The Form
class FooForm extends BaseForm
{
public function init()
{
$this->add([
'name' => 'elements',
'type' => Collection::class,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class
]
]
]);
}
public function getInputFilter()
{
if (!$this->filter) {
$this->filter = new InputFilter();
/** #var Collection $elementsCollection */
$elementsCollection = $this->fieldsets['elements'];
/** #var SomeElementFieldSet $elementsFieldSet */
$elementsFieldSet = $elementsCollection->getTargetElement();
$collectionFilter = new CollectionInputFilter();
$collectionFilter->setIsRequired(true);
$collectionFilter->setInputFilter(
$elementsFieldSet->getInputFilterSpecification()
);
$this->filter->add($collectionFilter, 'elements');
}
return $this->filter;
}
}
This will validate that there is at least one element in the collection. And will validate all the elements one by one by the FieldSet's specification.
One problem persists, though. Whenever the collection is empty, the validation will return false, but will not return any messages. This is due to a bug in the zend-inputfilter component. Issues reported here and here. But that is another problem altogether.
Use setValidationGroup() method in the Form object by specifying an array of input fields you want to validate. Please refer to the Doc!
You may give a try this way. Though I have added some extra fields to the form for testing purpose only.
class FooForm extends Form implements InputFilterProviderInterface
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->add(['name' => 'title']);
$this->add([
'name' => 'elements',
'type' => Collection::class,
'required' => true,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class,
],
],
]);
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Post'
],
]);
// I pointed this. Here you can specify fields to be validated
$this->setValidationGroup([
'title',
'elements' => [
'bar',
],
]);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'title',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
];
}
}
And your fieldset class should be
class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
public function init()
{
$this->add(['name' => 'bar']);
$this->add(['name' => 'baz']);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'bar',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
[
'name' => 'baz',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
Hope this would help!
I have a simple form currently consisting of a single fieldset. Now I want the fields to be filtered and validated. So I implemented the method getInputFilterSpecification() in my Fieldset class:
...
class FooFieldset extends \Zend\Form\Fieldset
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->setHydrator(new ClassMethods(false));
$this->setObject(new Buz());
$this->setLabel('Baz');
$this->add(array(
'type' => 'text',
'name' => 'bar',
'options' => array(
'label' => _('bar')
)
));
}
public function getInputFilterSpecification()
{
return [
'bar' => [
'required' => true,
'filters' => [
0 => [
'name' => 'Zend\Filter\StringTrim',
'options' => []
]
],
'validators' => [],
'description' => _('bar lorem ipsum'),
'allow_empty' => false,
'continue_if_empty' => false
]
];
}
}
and added the Fieldset to the Form:
...
class BuzForm extends \Zend\Form\Form
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->setAttribute('role', 'form');
$this->add(array(
'name' => 'baz-fieldset',
'type' => 'Buz\Form\BazFieldset'
));
$this->add(array(
'type' => 'submit',
'name' => 'submit',
'attributes' => array(
'value' => 'preview'
)
));
}
}
The problem is, that the InputFilter specifications are completely ignored. I've set a breakpoint into FooFieldset#getInputFilterSpecification() and to be sure even checked it witha die() -- the method is not called.
What is wrong here and how to get it working correctly?
You will need to implement Zend\InputFilter\InputFilterProviderInterface interface in order for the getInputFilterSpecification() method to be called.
I have a login Form LoginForm.php with its Filter LoginFilter.php, that has a View /login/index.phtml, a Controller LoginController.php, two Factory LoginControllerFactory.php & LoginFormFactory.php and it is called in the config.module.php and works perfect. The Form is correctly displayed.
I have a ViewController.php that has a method idAction that shows a post by its id passed by parameter from the homepage in a View called /view/id.phtml. I want to display this Form I created within this View and I don't know how. First, I created the Form exactly as I created the login Form, but I realized that I already configured my id child-route, inside of view route with a Factory in module.config.php.
Then, I tried to set the form in the idAction method, exactly as I did in indexAction in LoginController.php Controller, but I'm receiving the following error: An exception was raised while creating "Rxe\Factory\ViewController"; no instance returned.
I will now show you what I did to try to display this new Form.
First, the Form itself:
class CommentForm extends Form
{
public function buildForm()
{
$this->setAttribute('method', 'POST');
$this->setAttribute('id', 'add-comment-form');
$this->add(array(
'name' => 'comment',
'type' => 'textarea',
'options' => array(
'label' => 'Category'
),
'attributes' => array(
'class' => 'form-control'
)
));
$this->add(array(
'name' => 'submit',
'type' => 'submit',
'attributes' => array(
'class' => 'btn btn-success',
'value' => 'Comment'
)
));
}
}
Form's CommentFormFactory.php calling its Filter and building the Form:
class CommentFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$form = new CommentForm();
$form->setInputFilter($serviceLocator->get('Rxe\Factory\CommentFilter'));
$form->buildForm();
return $form;
}
}
The ViewControllerFactory.php calling the CommentFormFactory.php, just like in LoginControllerFactory.php:
class ViewControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$viewController = new ViewController();
$viewController->setPostsTable($serviceManager->get('Rxe\Factory\PostsTable'));
$viewController->setCommentsTable($serviceManager->get('Rxe\Factory\CommentsTable'));
$viewController->setCommentForm($serviceManager->get('Rxe\Factory\CommentForm'));
return $viewController;
}
}
The ViewController.php, calling the form within its idAction's ViewModel:
class ViewController extends AbstractActionController
{
use PostsTableTrait;
use CommentsTableTrait;
private $commentForm;
function setCommentForm($commentForm)
{
$this->commentForm = $commentForm;
}
public function indexAction()
{
$category = $this->params()->fromRoute('category');
return new ViewModel(array(
'posts' => $this->postsTable->getPostsByCategory($category),
'categories' => $category
));
}
public function idAction()
{
$id = $this->params()->fromRoute('id');
$viewModel = new ViewModel(array(
'commentForm' => $this->commentForm,
'commentParams' => $this->params()->fromPost(),
'messages' => $this->flashMessenger()->getMessages(),
'posts' => $this->postsTable->getPostById($id),
'posts' => $this->commentsTable->getNumberOfCommentsByPost($id),
'comments' => $this->commentsTable->getCommentsByPost($id)
));
$viewModel->setTemplate('rxe/view/id.phtml');
if ($this->getRequest()->isPost()) {
$this->commentForm->setData($this->params()->fromPost());
if ($this->commentForm->isValid()) {
$this->flashMessenger()->addMessage('Thank you for your comment. :)');
} else {
$this->flashMessenger()->addMessage('Your comment wasn\'t sent.');
}
}
return $viewModel;
}
}
And finally my module.config.php
'controllers' => array(
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
'factories' => array(
'Rxe\Factory\LoginController' => 'Rxe\Factory\LoginControllerFactory',
'Rxe\Factory\ViewController' => 'Rxe\Factory\ViewControllerFactory',
'Rxe\Factory\IndexController' => 'Rxe\Factory\IndexControllerFactory'
)
),
'service_manager' => array(
'factories' => array(
'Rxe\Factory\LoginForm' => 'Rxe\Factory\LoginFormFactory',
'Rxe\Factory\LoginFilter' => 'Rxe\Factory\LoginFilterFactory',
'Rxe\Factory\CommentForm' => 'Rxe\Factory\CommentFormFactory',
'Rxe\Factory\CommentFilter' => 'Rxe\Factory\CommentFilterFactory',
'Rxe\Factory\PostsTable' => 'Rxe\Factory\PostsTableFactory',
'Rxe\Factory\CategoriesTable' => 'Rxe\Factory\CategoriesTableFactory',
'Rxe\Factory\CommentsTable' => 'Rxe\Factory\CommentsTableFactory',
'Zend\Db\Adapter\AdapterService' => 'Zend\Db\Adapter\AdapterServiceFactory'
)
),
Please, let me know if you need me to show you more codes. Thank you in advance.
EDIT #1
If I remove the line that calls the Form in the ViewControllerFactory.php, I get the following error: Fatal error: Call to a member function prepare() on a non-object in /home/vol12_3/byethost4.com/b4_16354889/htdocs/module/Rxe/view/rxe/view/id.phtml on line 31
The id.phtml is:
<!-- Comment form -->
<div id="comment-form-area" class="col-xs-3">
<?php $this->commentForm->prepare() ?>
<?php echo $this->form()->openTag($this->commentForm); ?>
<div class="form-group comment-area">
<?php echo $this->formRow($this->commentForm->get('comment_content')); ?>
</div>
<div class="form-group">
<?php echo $this->formRow($this->commentForm->get('submit')); ?>
</div>
<?php echo $this->form()->closeTag(); ?>
</div>
<!-- /Comment form -->
Try removing these lines
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
If it doesn't work, have a look at this tutorial how to create proper controller factories and pass dependencies. https://samsonasik.wordpress.com/2015/03/31/zend-framework-2-using-__invokepluginmanager-manager-in-services-factory/
An example how I build my forms:
namespace Admin\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
class ContentForm extends Form implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct("content");
}
public function init()
{
$this->setAttribute('method', 'post');
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'title',
'attributes' => [
'required' => true,
'size' => 40,
'id' => "seo-caption",
'placeholder' => 'Title',
],
'options' => [
'label' => 'Title',
],
]);
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'text',
'attributes' => [
'class' => 'ckeditor',
'rows' => 5,
'cols' => 80,
],
'options' => [
'label' => 'Text',
],
]);
}
public function getInputFilterSpecification()
{
return [
[
"name"=>"title",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 200,
],
],
],
],
[
"name"=>"text",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
],
],
],
],
];
}
}
Than I create a Factory
namespace Admin\Factory\Controller;
use Admin\Controller\ContentController;
use Zend\Mvc\Controller\ControllerManager;
class ContentFormFactory
{
/**
* #{inheritDoc}
*/
public function __invoke(ControllerManager $controllerManager)
{
return new ContentController(
$controllerManager->getServiceLocator()->get('FormElementManager')->get('Admin\Form\ContentForm')
);
}
}
Inside module.config.php I have this code
'controllers' => [
'factories' => [
'Admin\Controller\Content' => "Admin\Factory\Controller\ContentFormFactory",
],
'invokables' => [
...
],
],
Please, show us some more code.