Form builder for a related entity Symfony 3 - symfony-3.4

Well let's say I have 2 entities:
category
product
I want to create a form builder for the entity product in which there is a select to choose the category of the product.
How can I do that with Symfony 3.4?
Can you guys give me an example?

You want to use the EntityType.
See below for an example:
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
// ...
->add('category', EntityType::class, [
'class' => 'AppBundle:Category',
'multiple' => false,
'expanded' => false,
'choice_label' => 'title',
'query_builder' => function (EntityRepository $er) {
// use query builder for ordering/filtering choices
return $er->createQueryBuilder('cat')
->orderBy('cat.title', 'ASC');
},
])
I assume your category entity has a property called title. This would be in your Product form type class.

Related

Class override doesn't work anymore in Prestashop 1.7.6?

I simply need to add a custom field named 'color' in Category admin. I've always used this method in previous version but it seems that's not working anymore in 1.7.6 :
override/classes/Category.php
/**
* Class CategoryCore
*/
class Category extends CategoryCore
{
public $color;
public function __construct($id_category = null, $id_lang = null, $id_shop = null){
self::$definition['fields']['color'] = array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml');
parent::__construct($id_category, $id_lang, $id_shop);
}
}
override/controllers/admin/AdminCategoriesController.php
class AdminCategoriesController extends AdminCategoriesControllerCore
{
public function renderForm()
{
$this->fields_form_override =array(
array(
'type' => 'text',
'label' => $this->trans('Color', array(), 'Admin.Global'),
'name' => 'color',
'maxlength' => 70,
'maxchar' => 70,
'lang' => true,
'rows' => 5,
'cols' => 100,
'hint' => $this->trans('Forbidden characters:', array(), 'Admin.Notifications.Info').' <>;=#{}'
),
);
return parent::renderForm();
}
}
Finally, I added a text field in the Database (ps_category_lang) and I deleted all the cache.
The field doesn't appear. Someone has this problem? Do I need to use a module instead of this method?
Thanks !
It seems that this process is not longer supported in 1.7.6 version. We also need to create a module with the new Symfony model.
There is a french source that explain how to. Here is the link.
I created a new post with my own code and the new procedure. I'm stucked in the save of the field in database. Here is the link.
Same here, i don't know why its not working. I follow all the instruction.
Im using Prestashop 1.7.6, maybe this procedure is not working with the latest prestashop version. Because based on what i read, they use prestashop v1.6 older.
You don't need a module.
I tried your code and it work for me
Try to clear cache in the backoffice interface and where are you put each file ?

how to pass the id of the click CButtonColumn of CGridView going to the controller in Yii1.x?

I have a custom CButtonColumn within the CGridView.
one of the custom buttons is firing a CJuiDialog. now the problem is,
how to pass the id when clicked, so that the Controller will get the id, then I can do pass a model and renderPartial it inside the CJuiDialog?
here's what i have so far
'see' => array(
'label' => 'View',
'url' => 'Yii::app()->controller->createUrl("mycontrollerName/view,array("id" => "$data->id"))',
'click' => "function( e ){
e.preventDefault();
$( '#view-dialog' ).data('id',$(this).attr('id'))
.dialog( { title: 'View Details' } )
.dialog( 'open' ); }"
),
having given that code snippet.. in the controller action, I want to have the id ..is it $_GET['id'] ?, or $_POST['id'] ?..it doesn't matter for as long as I can get it so that I can use it to query in the model function
There are a few syntax errors in your code, but more importantly, you shouldn't wrap $data->id in any quotes.
'see' => array(
'label' => 'View',
'url' => 'Yii::app()->createUrl("mycontrollerName/view", array("id" => $data->id))',
'click' => "function( e ){
e.preventDefault();
$( '#view-dialog' ).data('id',$(this).attr('id'))
.dialog( { title: 'View Details' } )
.dialog( 'open' ); }",
),
So you are trying to pass the id value in the javascript code.
This is more of a jQuery issue rather than having much to do with Yii.
Run console.log($(this).attr('id')); you will probably see that you get an 'undefined' value. That is because the tag generated by Yii for the button does not contain an id parameter.
The easiest solution is to use jQuery to work with the url parameter.
e.g.
$( '#view-dialog' ).data('id',$(this).attr('href'))
if the entire URL is not needed, you could use a regex to parse only the numerical ID.
Alternatively you will have to pass the id in the buttons option parameter.
e.g.
'see' => array(
'label' => 'View',
'url' => 'Yii::app()->createUrl("mycontrollerName/view", array("id" => $data->id))',
'options' => array('id' => $data->id),
'click' => "function( e ){
...
However, please note that Yii will not render the value of $data->id in the 'option' parameter as this is not evaluated in CButtonColumn.
You will have to override Yii's CButtonColumn (see http://www.yiiframework.com/wiki/372/cbuttoncolumn-use-special-variable-data-for-the-id-in-the-options-of-a-button/)
Personally, if I were you, I'd implement some Javascript in some external code and have a regex to parse the id from the URL.

Filter empty values in DetailView

Is there an easy way to force DetailView in Yii2 to ignore these fields in its attributes list, that for particular model are empty?
Or the only way is to define every attribute on attributes list with own function and filter empty fields inside it (sound like a little bit of madness)?
Edit: I thought, that this is pretty self-explanatory, but it turned out, it isn't. So, basically, I want to force DetailView to ignore (not render) rows for these elements of attributes list, that have empty (null, empty string) values in corresponding model and thus would result in rendering empty table cell:
You can define template parameter of DetailView widget as a callback function with following signature function ($attribute, $index, $widget) and this callback will be called for each attribute, so you can define desired rendering for your rows:
DetailView::widget([
'model' => $model,
'template' => function($attribute, $index, $widget){
//your code for rendering here. e.g.
if($attribute['value'])
{
return "<tr><th>{$attribute['label']}</th><td>{$attribute['value']}</td></tr>";
}
},
//other parameters
]);
Would something like this work better? It preserves some of the niceties like: updated_at:datetime, which with one of the solutions above will just show the underlying value, not a converted value.
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
[
'attribute' => 'my_attribute',
'visible' => !empty($model->my_attribute)
],
]
]);

Creating Prestashop back-office module with settings page

I'm creating a back-office module for Prestashop and have figured out everything except the best way to display the admin page. Currently I'm using the renderView() method to display the content of view.tpl.
I would like to display a table with values and an option to add a new row. Should I just create it in the view.tpl or is there a better way? I've seen the renderForm() method but haven't figured out how it works yet.
The biggest question I have is, how do I submit content back to my controller into a specific method?
ModuleAdminController is meant for managing some kind of records, which are ObjectModels. Defauly page for this controller is a list, then you can edit each record individually or view it's full data (view).
If you want to have a settings page, the best way is to create a getContent() function for your module. Besides that HelperOptions is better than HelperForm for this module configuration page because it automatically laods values. Define the form in this function and above it add one if (Tools::isSubmit('submit'.$this->name)) - Submit button name, then save your values into configuration table. Configuration::set(...).
Of course it is possible to create some sort of settings page in AdminController, but its not meant for that. If you really want to: got to HookCore.php and find exec method. Then add error_log($hook_name) and you will all hooks that are executed when you open/save/close a page/form. Maybe you'll find your hook this way. Bettter way would be to inspect the parent class AdminControllerCore or even ControllerCore. They often have specific function ready to be overriden, where you should save your stuff. They are already a part of execution process, but empty.
Edit: You should take a look at other AdminController classes, they are wuite simple; You only need to define some properties in order for it to work:
public function __construct()
{
// Define associated model
$this->table = 'eqa_category';
$this->className = 'EQACategory';
// Add some record actions
$this->addRowAction('edit');
$this->addRowAction('delete');
// define list columns
$this->fields_list = array(
'id_eqa_category' => array(
'title' => $this->l('ID'),
'align' => 'center',
),
'title' => array(
'title' => $this->l('Title'),
),
);
// Define fields for edit form
$this->fields_form = array(
'input' => array(
array(
'name' => 'title',
'type' => 'text',
'label' => $this->l('Title'),
'desc' => $this->l('Category title.'),
'required' => true,
'lang' => true
),
'submit' => array(
'title' => $this->l('Save'),
)
);
// Call parent constructor
parent::__construct();
}
Other people like to move list and form definitions to actual functions which render them:
public function renderForm()
{
$this->fields_form = array(...);
return parent::renderForm();
}
You don't actually need to do anything else, the controller matches fields to your models, loads them, saves them etc.
Again, the best way to learn about these controller is to look at other AdminControllers.

Yii multiple update of child records based on current parent record

I am trying to come up with a way of updating multiple records of a model and as I am using YiiBooster I have seen that you can do bulk actions using the Extended Grid.
Most of the examples that I have found on the web are showing how to delete multiple records using Ajax but my requirements are slightly different. As a newbie to Yii I am struggling to work out a suitable solution to this.
Basically I have 2 models, a parent and a child with a one-to-many relation. In the child model I have a field which references which parent it belongs to using the parent ID.
In the front end of the application the user is supposed to navigate to the parent update view and then see a list of all children assigned to that parent. I have created a modal window that shows a grid list of all children with the ability to perform a bulk update action. This will then assign the parent ID to all of the children that were selected.
Can anyone help me out with this as I am unsure what I need to edit in the extended grid view and controller that will be used to update the records?
In my parent update view I pull in the index view of the children using renderPartial, as follows:
<?php $this->renderPartial('application.modules.children.views.childviews.addChild', array('dataProvider' => new CActiveDataProvider('Children'))); ?>
I then have an Extended grid in my child index view:
<?php
$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'type' => 'striped bordered',
'id' => 'children-grid',
'dataProvider' => $dataProvider,
'bulkActions' => array(
'actionButtons' => array(
array(
'buttonType' => 'link',
'type' => 'primary',
'size' => 'small',
'label' => 'Bulk Action',
'url' => array('batchUpdate'),
'htmlOptions' => array(
'class' => 'bulk-action'
),
'id' => 'child_id',
'click' => ''
)
),
'checkBoxColumnConfig' => array(
'name' => 'child_id'
),
),
'columns' => array(
'child_id',
'child_status',
'parent_id',
array(
'class' => 'bootstrap.widgets.TbButtonColumn',
'buttons' => array(
'update' => array(
'label' => '<i class="icon-user"></i> <span>View Child</span>',
'options' => array('class' => 'btn btn-small'),
'url' => 'Yii::app()->createUrl("children/update", array("id"=>$data->child_id))',
),
),
),
),
));
?>
I am guessing that I need some kind of onclick event that calls an update action in the controller and this action updates the parent_id column of all selected records to the parent id of the current parent update page?
I hope someone can help and many thanks in advance.
Instead of a one to many relationship as you stated in your question, it seams that you really want a many to many relationship. The reason I say that is you seem to want to select from a set of pre-defined properties for your auction. In that case you would display the parent (auction), and the list of perspective children (properties), and using a checkbox or something like that to indicate the selection of the perspective children. You will have to use a separate data model to record the selections. I don't have an example right now, but I will need to do something like this in my current Yii project, and I will blog about it when I get there.