Multiple items with the same ID in the view - ZF2 - php

I am building a web application using ZF2 and Doctrine. I have a view containing a base form to which the user can add multiple instances of a fieldset, the filedsets are added via HTML template and js cloning. We are making use of the Doctrine hydrator and cascade=persist to write to the dB. It is all working but I am concerned when the fieldsets are added it results in multiple items with the same ID which breaks w3 standards. Has anyone a solution or work around for this? Or would it be considered acceptable in this instance?
An example of one fieldset element:
$this->add(array(
'name' => 'glassAssemblyID',
'attributes' => array(
'type'=> 'hidden',
'id' => 'glassAssemblyID',
),
));
Many thanks
James

You should set the ID in JavaScript after cloning the element.

This is an easy one. Just just change your code to:
$this->add(array(
//'name' => 'glassAssemblyID',
'attributes' => array(
'type'=> 'hidden',
//'id' => 'glassAssemblyID',
),
));
No point in putting out an element id which is obviously not being used.
If you really feel you do need ids for some reason then put out something like EntityType-id for your ids.

Related

How to specify a target entity type with sonata_type_collection

I am using Sonata Page Bundle to build a set of page with information about items -- one item per page. On each page, I want to include multiple synonyms for the item. I have created a Synonym entity with two fields.
I now want to use an add() method within my configureFormFields definition to add a reference to my new Synonym entity. The following code yields an error saying that The current field 'Synonym' is not linked to an admin. Please create one for the target entity : '':
->add('Synonym', 'sonata_type_collection', array(
'label' => "Synonyms",
'cascade_validation' => true,
'required' => false
), array(
'edit' => 'inline',
'inline' => 'table'
))
... and I have tried modifying the code so it looks like:
'cascade_validation' => true,
'required' => false,
'target_entity' => 'AppBundle\Entity\Synonym'
), array(
... which results in the same error.
How do I tell my admin class that this is a reference to a set of Synonym objects that I want to edit inline?
Edit:
I have also tried
'targetEntity' => 'AppBundle\Entity\Synonym'
... with no luck. The application is still seemingly having trouble figuring out what the entity I'm targeting is.
An at least partial answer was found in adding an "admin_code" definition to my array, as described at
https://symfony.com/doc/master/bundles/SonataAdminBundle/reference/form_types.html
I still get an error, but it is now at least a different error.

Best practice for Zend 2 FieldSets, re-use them or re-create them for every specific situation?

Me and my colleague were arguing about whether or not we should re-use certain Zend2 FieldSet classes in our project.
Using the framework we create many different forms, and there are quite a few forms for which the same information needs to be filled in.
For example, we have a form to create a new employee and a form to create a new contactperson. For both forms, contact information needs to be filled in, so both forms add an AccountFieldSet to the form.
Now currently, for every new form, a new AccountFieldSet is created so we have Customer\Form\Contact\AccountFieldset and Employee\Form\AccountFieldSet which both contain code like:
<?php
namespace Employee\Form;
use Zend\InputFilter\InputFilterProviderInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Zend\Form\Fieldset;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
use OurProject\Entity\Account;
class AccountFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $oObjectManager)
{
parent::__construct('account');
$this->setHydrator(new DoctrineObject($oObjectManager))->setObject(new Account());
$oAccountAddressFieldset = new AccountAddressFieldset($oObjectManager);
$this->add($oAccountAddressFieldset);
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'listGender',
'options' => array(
'empty_option' => '',
'object_manager' => $oObjectManager,
'target_class' => 'OurProject\Entity\ListGender',
'property' => 'name'
),
'attributes' => array(
'class' => 'select2',
'data-placeholder' => 'Gender'
)
));
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'firstname',
'attributes' => array(
'class' => 'form-control input-xs',
'placeholder' => 'First name',
'required' => 'required'
)
));
My colleague argues that this is the correct way to go, because there are also forms for which not every field of the Contact should appear, and re-using that FieldSet would then give extra overhead by loading more info then necessary.
I in turn believe that have two classes with (almost) the same code is always bad practice and that therefore we should re-use the same class, and only create a new one when there are in fact differences. This way we do not have the same code at different places, which should reduce the amount of places where we should change code if changes should occur.
Alternatively, I suggested there should be a base class with the minimal FieldSet called BaseContactFieldSet that contains all fields that will always be used by all forms, and that that other FieldSet classes should extend upon that class and add any input elements that are not in the BaseContactFieldSet.
My colleague believes that there are too many exceptions for every form and that therefore it is necessary to just create a lot of duplicate code in different places, and that we should not re-use FieldSet classes at all to prevent creating code to handle exceptions.
So we were wondering what others think. Should we re-use as many code as we can, or should we create duplicate code because there may be exceptions for specific forms?
Best practice is a DRY approach (Don't Repeat Yourself) rather then a WET approach (Write Everything Twice).
Add the common elements to the AccountFieldset (consider an abstract class here) and then extend it using EmployeeAccountFieldset and CustomerAccountFieldset.
Register the concrete fieldset classes with the FormElementManager Service and you can then access the fieldset objects from anywhere you have access to the serviceManager, they will be lazy-loaded so if you don't call the service they will never get instantiated.
in your module config:
return [
'form_elements' => [
'invokables'=>[
'MyNameSpace\Form\Fieldset\EmployeeAccount'=>'MyNameSpace\Form\Fieldset\EmployeeAccountFieldset'
]]];
You can also then tweak the fieldsetObjects (rather than the class itself) if you need to add/remove certain elements for specific usages.
//get fieldset object via the FormElementManager ServiceManager
$employeeAccountFieldset=$this->getServiceLocator()->get('FormElementManager')->get('MyNameSpace\Form\Fieldset\EmployeeAccount');
//remove password element
$employeeAccountFieldset->remove('password');
//tweak an element
$employeeAccountFieldset->get('email')->setAttribute('class','myCSSClass');
//add tweaked fieldset to form
$myFormObject->add($employeeAccountFieldset);

Where do I find a list of all possible input filters for Zend\InputFilter\InputFilter

Zend\InputFilter\InputFilter creates inputs with the createInput() method of Zend\InputFilter\Factory. But I was digging through the code and could not find where the actual input filter key value pairs are defined. For example:
$inputFilter->add($factory->createInput(array(
'name' => 'id',
'required' => true,
'filters' => array(
array('name' => 'Int'),
), ...
'Int' is a filter. Where is that defined in the zf2 library so I can see what other possible filters there are. I know the docs have info on this, but I'd like to know where it is defined in the actual library.
You'll find it in the class Zend\Filter\FilterPluginManager.
The path of the file is your_project/vendor/zendframework/zendframework/library/Zend/Filter
In this directory you'll also find all the filter's classes (like the Int one).

ZF2 empty output on underscore method

I've got an ZF2 application which is an extended skeletonapplication with a few extra modules like authentication and authorization, running on Zend Server comunity edition.
In order for poedit to find the strings it has to translate i use the _("string") method like so:
$this->add(array(
'name' => 'eaddress',
'type' => 'Zend\Form\Element\Text',
'attributes' => array(
'id' => 'eaddress',
'type' => 'email',
),
'options' => array(
'label' => _('EMAIL'),
),
));
But when I do that the application outputs nothing to the browser not even an error:
Firefox: The connection was reset
Chrome: No data received
Safari: {shows epmty page}
Does anyone know how to fix this?
Thanks in advance
As far as i know, you dont need to write any function in order to have ZF2 translating your literals. Actually it is working with poedit like a charm.
If you look at this manual page you will see how to easily translate stuff in your views, just using $this->translate(), and there is where actually you have to do it.
About forms labels, you dont even have to worry since the form view helpers already translate label if everything is well configured.
If you want to know more about poedit and zf2 you can go to this blog post or this great sams's post

Zend Framework with PHP, changing class labels

I am using Zend Framework with Dojo to make tab containers. I need for the dt tags to be createEventForm-waiverDetail-addElement-label instead of addElement-label. However I cannot figure it out. You can see them as the id in the following code snippet
http://pastie.org/780362
I have looked and looked for this. I think it may be something in the decorators. The following is the decorators that I set for the Zend Dojo Form:
$this->setDecorators(
array(
'FormElements',
array(
'TabContainer',
array(
'id' => 'tabContainer',
'style' => 'width: 100%; height: 500px;',
'dijitParams' => array(
'tabPosition' => 'top'
),
),
),
'DijitForm',
)
);
For future users of the site that are looking for similar information. In order to do this you must reset the decorator stack, setting the id while you are doing it.

Categories