Is there a way to get the config for a dynamically loaded behavior in CakePHP 2.x? - cakephp-2.6

Example:
$Model->Behaviors->load('Some.Behaviour', $options);
// Now how do I get $options back from the model?
Is there a way to get $options? $Model->actsAs remains empty.

Those options are stored in the settings property of the Behavior itself. You can get to it by using:
$this->Behaviors->Behavior->settings[''];
For example:
$this->Behaviors->load('Containable', array('hello' => 'world'));
var_dump($this->Behaviors->Containable->settings);
Would return:
array (size=2)
'priority' => int 10
'' =>
array (size=4)
'recursive' => boolean true
'notices' => boolean true
'autoFields' => boolean true
'hello' => string 'world' (length=5)
As you can see, the "hello world option" is right there at the bottom.

Related

Check a radio button by default (unmapped ChoiceType field)

I'm trying to have one of the options of a ChoiceType field selected by deafult using Symfony's FormBuilder.
I found a lot of similar questions, but most are about a field mapped to an entity, which is not my case here. The other answers I found involved using the "data" or the "empty_data" attribute, none of which seem to work for me.
Here's my current "add" method (in my FormBuilder):
$builder->add('type2', ChoiceType::class, [
'mapped' => false,
'label' => false,
'choices' => [
"Incoming" => ComEntry::INCOMING,
"Outgoing" => ComEntry::OUTGOING,
],
'expanded' => true,
'empty_data' => 'Incoming',
]);
(I also tried with 'empty_data' => ComEntry::INCOMING,.)
When rendering the form, no radio box is selected, what I would like is to have the first one ("Incoming") selected by default.
Thanks by advance for any reply :-)
EDIT : Here's what I used in the end (instead of 'empty_data' => 'Incoming',), because type2 is a subset of type (type is a sum of bits, type2 is a choice between the INCOMING and the OUTGOING bits).
'choice_attr' => function($choice, $key, $value) use ($options) {
// If the record is being edited and the user selected "Outgoing" at creation, check the "Outgoing" choice.
if($options['data']->getType() & ComEntry::OUTGOING and $choice == ComEntry::OUTGOING)
return ['checked' => 'checked'];
// Else, check the "Incoming" choice.
elseif($choice == ComEntry::INCOMING)
return ['checked' => 'checked'];
else
return [];
},```
You can try using the choice_attr option in its callable form:
This can be an associative array where the keys match the choice keys
and the values are the attributes for each choice, a callable or a
property path.
'choice_attr' => function($choice, $key, $value) use ($options) {
// If no value is set mark INCOMING as checked
if (empty($options['data']->type2) && ComEntry::INCOMING == $value) {
return ['checked' => 'checked'];
}
return [];
},
What you can do is : 'data' => ComEntry::INCOMING instead of the empty_data
The empty_data is useful when the form is submitted.
But this method will work only for creation. For the edition you will have to check if the form has been initialized with data.

How to set default selected option for Entity Type select?

so I'm trying to set a selected option in my form but I can't seem to find out how to do this. I've Googled around and everything seems to be for Symfony2 where default was a thing, this seems to be no longer the case for Symfony4.
I've tried using data and empty_data but both don't select the correct value..
# weirdly, setting to ['guru'] gets undefined index error,
# setting to $options doesn't error
->add('guru', EntityType::class, array(
'class' => User::class,
'choice_label' => 'username',
'data' => $options['guru']
))
and how I pass $options:
$form = $this->createForm(EditCategoryType::class, array('guru' => $guruName));
So with the help of #Juan I. Morales Pestana I found an answer, the only reason I've added the below as an answer rather than marking his as correct was because there seems to be a slight difference in how it works now..:
Controller now reads (Thanks to #Juan):
$category = $this->getDoctrine()->getRepository(Category::class)->find($id);
$category->setGuru($category->getGuru());
$form = $this->createForm(EditCategoryType::class, $category);
My EditCategoryType class:
->add('guru', EntityType::class, array(
'class' => User::class,
'choice_label' => 'username',
'mapped' => false,
'data' => $options['data']->getGuru()
))
updated twig template:
{{ form_widget(form.guru, { 'attr': {'class': 'form-control'} }) }}
<a href="{{ path('register_new', { idpackage: p.id }) }}" class="btn_packages">
//sends to form type the package id
$fromPackage = '';
if($request->query->get('idpackage')) {
$fromPackage = $request->query->get('idpackage');
}
$form = $this->createForm(RegisterFormType::class, $register, ['fromPackage' => $fromPackage]);
in formType set the param in options:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Register::class,
'fromPackage' => null
]);
}
->add('package',EntityType::class, [
'label' => 'Select one item',
'class' => Package::class,
'choice_label' => function($package) {
return $package->getTitle() . ' | crédits : ' . $package->getAmount();
},
'attr' => ['class' => 'input-text', ],
'placeholder' => '...',
'required' => false,
'choice_attr' => function($package) use ($idFromPackage) {
$selected = false;
if($package->getId() == $idFromPackage) {
$selected = true;
}
return ['selected' => $selected];
},
])
$parentCategory = $categoryRepository->repository->find(2);
$category = new Category();
$category->setParentCategory(parentCategory);
$form = $this->createForm(CategoryType::class, $category);
we chose the predefined top category, it works if you use it this way.
try this :
empty_data documentation
As I said in my comments you are doing something wrong. I will explain all the process:
calling the form in the controller
$person = new Person();
$person->setName('My default name');
$form = $this->createForm('AppBundle\Form\PersonType', $person);
$form->handleRequest($request);
then the createForm function is executed here is the code
Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait
protected function createForm($type, $data = null, array $options = array())
{
return $this->container->get('form.factory')->create($type, $data, $options);
}
As you can see the data or options are nos setted directly in the form, another function is called and then the form is created
This is the result when I make a dump inside the PersonType
PersonType.php on line 20:
array:35 [▼
"block_name" => null
"disabled" => false
"label" => null
"label_format" => null
"translation_domain" => null
"auto_initialize" => true
"trim" => true
"required" => true
"property_path" => null
"mapped" => true
"by_reference" => true
"inherit_data" => false
"compound" => true
"method" => "POST"
"action" => ""
"post_max_size_message" => "The uploaded file was too large. Please try to upload a smaller file."
"error_mapping" => []
"invalid_message" => "This value is not valid."
"invalid_message_parameters" => []
"allow_extra_fields" => false
"extra_fields_message" => "This form should not contain extra fields."
"csrf_protection" => true
"csrf_field_name" => "_token"
"csrf_message" => "The CSRF token is invalid. Please try to resubmit the form."
"csrf_token_manager" => CsrfTokenManager {#457 ▶}
"csrf_token_id" => null
"attr" => []
"data_class" => "AppBundle\Entity\Person"
"empty_data" => Closure {#480 ▶}
"error_bubbling" => true
"label_attr" => []
"upload_max_size_message" => Closure {#478 ▶}
"validation_groups" => null
"constraints" => []
"data" => Person {#407 ▼ // Here is the data!!!
-id: null
-name: "My default name"
-salary: null
-country: null
}
]
As you can see the data is indexed at data so that is the reason why you get an undefined index error
So the proper way is to set the entity value from the controller or use your form as a service and call the repository and set the value using the data option which has not changed since version 2. My point is that you are using the form wrong.
Please change your code.
Hope it help
EDITED IN THE SYMFONY 4 WAY(with out namespaces bundles)
Let's see please, I have a Person Entity with a name just for this example
The controller
$person = new Person(); //or $personsRepository->find('id from request')
$person->setName('My default name');
$form = $this->createForm(PersonType::class, $person);
$form->handleRequest($request);
The form
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name',TextType::class,[
//'data' => 'aaaaa' // <= this works too
]);
}
The options array value which proves that you are accessing wrong
PersonType.php on line 20:
array:35 [▼
"block_name" => null
"disabled" => false
"label" => null
"label_format" => null
"translation_domain" => null
"auto_initialize" => true
"trim" => true
"required" => true
"property_path" => null
"mapped" => true
"by_reference" => true
"inherit_data" => false
"compound" => true
"method" => "POST"
"action" => ""
"post_max_size_message" => "The uploaded file was too large. Please try to upload a smaller file."
"error_mapping" => []
"invalid_message" => "This value is not valid."
"invalid_message_parameters" => []
"allow_extra_fields" => false
"extra_fields_message" => "This form should not contain extra fields."
"csrf_protection" => true
"csrf_field_name" => "_token"
"csrf_message" => "The CSRF token is invalid. Please try to resubmit the form."
"csrf_token_manager" => CsrfTokenManager {#457 ▶}
"csrf_token_id" => null
"attr" => []
"empty_data" => Closure {#480 ▶}
"error_bubbling" => true
"label_attr" => []
"upload_max_size_message" => Closure {#478 ▶}
"validation_groups" => null
"constraints" => []
"data" => Person {#407 ▼
-id: null
-name: "My default name" //Here is the data
-salary: null
-country: null
}
]
AppBundle is just another folder in my folder structure. Be pleased to test your self. The second parameter to the formCreate function is the entity or data not the options you are thinking that the options is the data.

How to set a default values to input field type in Prestashop backoffice in renderform

In renderform I have one input field and its type is "text". How to set a value to that input field, so at every time when the form is loaded the value should be displayed. I am using Prestashop 1.7.
Sample code:
array(
'type' => 'text',
'label' => $this->l('VENDOR_SERVER_IP'),
'name' => 'serverip',
'size' => 50,
'class' => 'fixed-width-xxl',
'required' => true,
'desc' => $this->l('Please enter your server ip.')
),
You need to use the fields_value property
$helper = new HelperForm();
//...
$helper->fields_value = array(
'serverip' => 'x:x:x:x'
);
You have no option to pass default value of input field in the form array. To provide default value, you have to use fields_value property of form helper.
$hlper = new HelperForm();
$value = 'Your already saved value if any';
if (empty($value)) {
$value = 'your default value';
}
$hlper->field_values = array('YOUR_FORM_INPUT_NAME' => $value);
echo $hlper->generate($your_form_array);

Magento, add and set a checkbox on grid and form backend

I've a fully working backend page with a grid and a corresponding form to edit the changes on the corresponding model. I added a new field on the table, bit type, as it will answer to a yes/no configuration option from the user. I added the checkbox on both grid and form.
My problem is that after a couple of hours of searching and trying different approaches I can not set the checkbox checked value both on the grid and the form reading the corresponding field from the database. Also when I click on save on the form the value corresponding to the checkbox is always saved with 1. Everything else on the grid and the form works as it should. I have read here, here, here, here and some more sites and SO questions/answers but still no clue on what I'm doing wrong. Some solutions recommend using a combo box with YES/NO options, but I want a checkbox, can't be so difficult.
Grid code inside the function _prepareColumns():
protected function _prepareColumns() {
...
$this->addColumn('banner_gral', array(
'header' => Mage::helper('banners')->__('General'),
'align' => 'center',
'index' => 'banner_gral',
'type' => 'checkbox',
'values' => $this->getBannerGral()==1 ? 'true' : 'false',
));
...
}
public function __construct()
{
parent::__construct();
$this->setId('bannersgrid');
$this->setDefaultSort('bannerid');
$this->setDefaultDir('asc');
$this->setSaveParametersInSession(true);
$this->setUseAjax(true);
}
public function getGridUrl()
{
return $this->getUrl('*/*/grid', array('_current'=>true));
}
protected function _prepareCollection()
{
$collection = Mage::getModel('banners/bannersadmin')->getCollection();
$this->setCollection($collection);
return parent::_prepareCollection();
}
Form code to add the checkbox inside the function _prepareForm():
protected function _prepareForm()
{
$id = $this->getRequest()->getParam('id');
$params = array('id' => $this->getRequest()->getParam('id'));
if (Mage::registry('banners_data')->getdata()) {
$data = Mage::registry('banners_data')->getdata();
}
elseif (Mage::getSingleton('adminhtml/session')) {
$data = Mage::getSingleton('adminhtml/session')->getdata();
Mage::getSingleton('adminhtml/session')->getdata(null);
}
else {
$data = array();
}
$form = new Varien_Data_Form(array(
'id' => 'edit_form',
'action' => $this->getUrl('*/*/save', $params),
'method' => 'post',
'enctype' => 'multipart/form-data',
));
...
$fieldset->addField('banner_gral', 'checkbox', array(
'label' => Mage::helper('banners')->__('Is general'),
'name' => 'banner_gral',
'class' => 'banner_gral',
'checked' => $this->getBannerGral()==1 ? 'true' : 'false',
'onclick' => 'this.value == this.checked ? 1 : 0',
'note' => Mage::helper('banners')->__('blablablabla'),
'tabindex' => 2
));
...
}
On the saveAction() of my form I have:
$campaign->setbanner_gral(!empty($data['banner_gral']));
In your controller saveAction() when saving the checkbox data do
$banner_gral = isset($your_form_Data['banner_gral']) ? 1 : 0;
For Grid and Form Page
In your controller you should have Mage::register(...)->getData() or Mage::register(...)
public function editAction()
....
Mage::register('example_data', $model);
On your form _prepareForm()
$model = Mage::registry('example_data'); // NOTE registry('example_data'); NOT registry('example_data')->getData();
$fieldset->addField('entire_range', 'checkbox', array(
....
'checked' => $model->getBannerGral()==1 ? 'true' : 'false',
......
))
see http://www.magentocommerce.com/boards/viewthread/20536/
On your grid _prepareColumns()
$this->addColumn('banner_gral', array(
....
'type' => 'checkbox',
'index' => 'banner_gral',
'values' => array(1,2),
'field_name' => 'checkbox_name',
....
));
#R.S answered one issue, how to save the checkbox value on the corresponding model/database field. But the issue on how to correctly display the checkbox on both the grid and the form was not solved. After doing some more searches I finally got to these two links that helped me solve my problem.
To correct the grid issue: Understanding the Grid Serializer Block
Now the part of code where the checkbox column is added, see that I added array(1,2) on the values element.
$this->addColumn('banner_gral', array(
'header' => Mage::helper('banners')->__('General'),
'width' => '20px',
'type' => 'checkbox',
'align' => 'center',
'index' => 'banner_gral',
'values' => array(1,2),
'editable' => 'false',
));
Also if you take a look into the core code of Magento, the class Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Checkbox returns an array of values. Taking a look here finally got me into the right path.
/**
* Returns values of the column
*
* #return array
*/
public function getValues()
{
if (is_null($this->_values)) {
$this->_values = $this->getColumn()->getData('values') ? $this->getColumn()->getData('values') : array();
}
return $this->_values;
}
To correct the form issue: Mage_Adminhtml_Block_System_Store_Edit_Form Class Reference
The issue on this case was that I was trying to use the $this but what I needed to use was the $data that is loaded at the beginning of the _prepareForm function. #R.S pointed the right direction, but it is not possible to use $model->getBannerGral() as the $data on the registry is an array, not a model. So, using $data["banner_gral"] I could get the needed value for the checkbox. Tested and it is working.
$fieldset->addField('banner_gral', 'checkbox', array(
'label' => Mage::helper('banners')->__('Is general'),
'name' => 'banner_gral',
'checked' => $data["banner_gral"],
'onclick' => 'this.value = this.checked ? 1 : 0;',
'note' => Mage::helper('banners')->__('blablablabla'),
'tabindex' => 2
));

Validating a choice field against an array Symfony2

I am building a form class in Symfony2. In my class, I have a choice field. I built a function to return my choice array:
public function getCardTypes() {
return array('visa' => 'Visa', 'mc' => 'MasterCard', 'amex' => 'American Express');
}
Later, I add a choice field to my form with this array:
$builder->add('PaymentCCType', 'choice', array('choices' => $this->getCardTypes()));
And then in getDefaultOptions function I have a choice constraint for this field:
'PaymentCCType' => new Choice(array('choices' => $this->getCardTypes())),
I seem to be having a problem with this validator. When I submit this form, I get the following error underneath my select box: "The value you selected is not a valid choice". Of course, I am using one of the choices in my array.
What am I doing wrong?
/* edit */
I have noticed that of the 4 fields I have like this, I only get the error on 3 of them. the one where the choice is month (simple 1-12), validation works.
/* edit 2 */
the issue appears to occur when the array key does not match the value. i switched my array to array('Visa' => 'Visa', 'MasterCard' => 'MasterCard', 'American Express' => 'American Express') and now it works.
Is there any way around this? I feel like I can't be the only one with this issue. it occurs even when you have a regular (non-associative) array like array('Visa', 'MasterCard', 'American Express')
IMHO you should do it in different way, create class with ChoiceListInterface with methods:
public function getChoices()
{
return self::$choices;
}
public static function getTypeChoicesKeys()
{
return array_keys(self::$choices);
}
in form class:
$builder->add('type', 'choice',
array(
'expanded' => true,
'multiple' => false,
'choice_list' => new TypeChoices(),
'required' => true,
)
)
in validation.yml
type:
- NotNull: ~
- Choice: { callback: [TypeChoices, getTypeChoicesKeys] }
edit
In response to my issue, the Symfony team pointed out the choice validator accepts an array of possible values (not possible choices like the choice field). the easiest way to do this is to use the array_keys function:
'PaymentCCType' => new Choice(array('choices' => array_keys($this->getCardTypes()))),