Sonata admin: list one to many in edit page - php

I have a many many to many relation in Sonata (two one to many relations to be exact), Brand and Retailer.
In the Brand admin Edit page, I want to display all the retailers as a list (so just a read only version), instead of having the normal edit (at the moment, on this brand edit page, I can manage the relationship between this brand and retailers - add a new one, delete an existing one).
I tried to explore two routes so far:
Edit page will load a custom twig
Using a custom field type for this field only
My issue is, with both options, I didn't manage to get to a solution
So here is what I have done:
1 - Loading a custom edit twig:
services:
xx_brand.admin.brand_brand:
calls:
- [ setTemplate, [edit, xxBrandBundle:Admin:base_edit.html.twig]]
On this case, base_edit is an exact copy of the sonata base_edit, but it loads my custom base_edit_form:
{% use 'xxBrandBundle:Admin:base_edit_form.html.twig' with form as parentForm %}
From here I can exclude the default rendering of the retailers, but can't find a way to then render it as I want, as I am not sure how the retailers entity is managed here:
{% if admin.formfielddescriptions[field_name] is defined and field_name != 'retailers' %}
{{ form_row(form[field_name])}}
{% else %}
<ul>
<li>retailer1</li>
<li>retailer2</li>
</ul>
{% endif %}
2 - For the approach of a custom field type, I tried to follow the documentation
Creating the Bundle/Form/Type/ListType.php
Creating the /BrandBundle/Resources/views/form/list.html.twig
Using the ListType in configureFormFields:
use XX\BrandBundle\Form\Type\ListType;
...
->add('retailers', 'ListType');
But I then get an error XX\BrandBundle\Form\Type\ListType
So basically, because I couldn't get it to work, are any of these two options good to solve my issue ?
If so, could anyone please advice on what I am missing there ??
Any help will be very much appreciated :)

You can use sonata_type_model_list: https://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html#example
Like so:
class BrandAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('retailer', 'sonata_type_model_list', array(
'btn_add' => false,
'btn_delete' => false,
));
}
}

Related

Perform merge between views of two or more modules

I have a Phalcon PHP modular application. I am making an administrative interface to control which modules should be used in the system.
One module controls the application's default interface, while the other modules add functionalities.
I have the problem: when another module to enabled, it can add the HTML content to the other interface control module. In this way I would like to merge two or more views. I am using Volt as template engine.
Is this possible in Phalcon?
Note: This was asked on the official Phalcon forums. I answered it over there and it got accepted. I am just mirroring my answer so future readers can get an answer here without being redirected from StackOverflow. Phalcon forum mirror: https://forum.phalconphp.com/discussion/15891/perform-merge-between-views-of-two-or-more-modules
config.php
You will need to define your modules in the app/config/config.php file like so;
return new \Phalcon\Config([
// ...
'modules' => [
'module01',
'module02',
...
'moduleN',
],
// ...
]);
*Controller.php
Then, in your controller, you'd set a view property to store the active modules like so;
$this->view->modules_enabled = $this->di->get("config")->modules;
*.volt
And finally in your volt file, just check the module is in the array holding active modules, and if so, display the view using partials.
{% if module01 in modules_enabled %}
<div id="module">{{ partial("partials/module01") }}</div>
{% endif %}

Default variant options on Sylius product show page

I am using Sylius eCommerce framework. I want to preselect product options for provided route parameters. I created a custom route for the product show page. An additional parameter of the route should result in another pre-selection (default value) of the product option.
For example http://example.org/products/t-shirt/red will add the route parameter color=red and preselect the color option the the value "red".
Actually I am not sure how to solve my problem. Any ideas?
I resolved my problem providing the parameter from the main request to the rendered one:
{{ render(url('sylius_shop_partial_cart_add_item', {'template': '#SyliusShop/Product/Show/_addToCart.html.twig', 'productId': product.id, 'manufacturer': app.request.get('myparam')})) }}
An in the rendered template I used this value for the default param:
{{ form_row(option_form, { 'attr': { 'data-option': option_form.vars.name, 'disabled': 'disabled' }, 'value': ~ app.request.get('myparam') }) }}
I think it's not the best solution but it fits my needs.

Symfony / Sonata Admin: List form on Edit form

I have a one (category) to many (product) relationship set up, and I'd like to have a list of products show up at the bottom of the edit category page.
It seems like this would be a common thing to do, but I haven't found any way to do it (or any examples of it). I have managed to get the product to display using sonata_type_collection but that gives me a whole edit form for the Product, when I really just want a list of products associated with the category.
Two questions here, really:
Is this possible?
Is it discouraged (which would explain the lack of examples)? If so, why?
The fastest way to do what you are looking for is overriding the edit template. At your admin serivce declaration you can do so:
services:
sonata.admin.mail:
class: %sonata.admin.category.class%
tags:
- { name: sonata.admin, manager_type: orm, group: "Categories", label: "Category" }
arguments:
- ~
- %skooli.category.class%
- ~
calls:
- [ setTemplate, ["edit", "AcmeAdminBundle:CategoryAdmin:edit.html.twig"] ]
Then, under AcmeBundle/Resources/views/CategoryAdmin/edit.html.twig you can have something like this:
{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}
{# Override any block from the parent view if necessary #}
{% block products %}
<ul>
{% for product in object.products%}
<li>{{ product.name }}</li>
{% endfor %}
</ul>
{% endblock products %}
In your original question you were talking about the edit template of the category. In your comment you want the list to appear in the show action.
The latter is easy. As soon as you add your relation to your showFields action they will be shown:
use Sonata\AdminBundle\Show\ShowMapper;
class CategoryAdmin extends Admin
{
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('products')
;
}
}
If you don't like the look you can create a custom template. This will work for show and edit:
https://sonata-project.org/bundles/admin/master/doc/reference/action_show.html#setting-up-a-custom-show-template-very-useful

symfony2 -How to retrieve data from database globally in every page

I want to retrieve Cities names from a table in the database and put them as options in a select input (combobox) which is defined in 'layout.html.twig' . All my views extends 'layout.html.twig', so how can I access to cities names in every page?
[Solution]
I'm not able to respond to my topic ,I didn't have much reputation so I edit my topic
I have found the solution, using "embedding controllers"
first I've created an action to retreive all cities names:
public function listCitiesAction(){
// retreiving cities
$entities = $this->getDoctrine()->getRepository("MedAdBundle:City")->findAll();
return $this->render('MedAdBundle:Ville:list_cities.html.twig',
array('entities' => $entities));
}
this action render list_cities.html.twig defined as :
<select class="form-control">
{% for entity in entities %}
<option>{{ entity.name}}</option>
{% endfor %}
</select>
finnaly I edit my layout.html.twig
<div>
{{ render(controller('MedAdBundle:City:listCities'))}}
</div>
In this way I can access to cities combobox in every page in my app ;)
Another nice way would be use render.
This allows you to call a controller out of your layout.html.twig
{{ render(controller("AcmeDemoBundle:Helper:citySelector")) }}
you also can cache the output with ESI.
It's well explained in the cookbook.
http://symfony.com/doc/current/cookbook/templating/global_variables.html
I would go with these steps:
Write a form hosting a symfony entity field configured to work with the Cities table
Define this form as a service in the DIC
Define a twig extension that exposes a function to output the form HTML
Use the twig function in the layout.html.twig that is extended by all the other templates
As an optimization I would look how I could wire Doctrine with some caching system (e.g. memcached) to avoid hitting the database on each page load.
This is where you can find documentation about the entity field: http://symfony.com/doc/current/reference/forms/types/entity.html
Use the Symfony documentation to find how to define a form as a service and how to write your own twig extension.

Symfony 2 - Accessing Hierarchical Roles in a twig template

In my template, I need to know if a user has certain role to display things according to it. So far, I've implemented a little function in my user class:
public function hasRole($role) {
$roles = array();
foreach ($this->getRoles() as $rol) {
$roles[] = $rol->getRole();
}
return in_array($role, $roles);
}
which tells me if this user has the role specified by the string passed as a parameter. This work and can be called from a twig template, but doesn't allow me to know anything about the roles hierarchy. Is there a way to access the role hierarchy from a controller? and directly from a twig template? I've looked through the official docs and didn't find anything about.
You can check the roles in twig templete by using below code,It explains that if the current user has the below role,then show something
{% if is_granted('ROLE_ADMIN') %}
//show things related to admin role
{%else if is_granted('ROLE_USER')%}
//show things related to user role
{% endif %}
Hope this helps you.
Happy Coding!!

Categories