Sonata Media Bundle remove gallery - symfony-sonata

I have the Sonata Media Bundle installed but I don't use the gallery portion of the bundle.
How do I disable the Gallery?
I am using Symfony 2.3 and I have the standard Media Bundle install as per the documentation.
Solution thus far:
If you look at this issue https://github.com/sonata-project/SonataAdminBundle/issues/460 from the admin bundle you can disable a admin by adding the show_in_dashboard: false tag to the yaml file.
To do this I simply add my own compiler that adds this flag for me then:
Create your compiler: http://symfony.com/doc/current/components/dependency_injection/tags.html
Add your compiler to your bundle: http://symfony.com/doc/2.3/cookbook/service_container/compiler_passes.html
And you are done. If there is a better solution I'd love to hear about it.
Example of compiler:
namespace YourBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class OverrideMediaGalleryCompilerPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* #param ContainerBuilder $container
*
* #api
*/
public function process( ContainerBuilder $container )
{
$definition = $container->getDefinition( 'sonata.media.admin.gallery' );
if ( $definition ) {
/**
* The purpose here is to disable the sonata admin gallery from showing up
* in the dashboard. This goes through and adds show_in_dashboard parameter
* that disables this.
*/
if ( $definition->hasTag( 'sonata.admin' ) ) {
$tags = $definition->getTag( 'sonata.admin' );
$tags[ 0 ][ 'show_in_dashboard' ] = false;
$definition->clearTag( 'sonata.admin' );
$definition->addTag( 'sonata.admin', $tags[ 0 ] );
}
}
}
}

Just add below service configuration into your config.yml or sonata_admin.yml file to disable gallery and media menu from admin panel or use services.yml file in config directory and load it from dependencyInjection class
#Application/Sonata/MediaBundle/DependencyInjection/ApplicationSonataMediaExtension.php
<?php
namespace Application\Sonata\MediaBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {#link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class ApplicationSonataMediaExtension extends Extension
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
Use only sonata.media.admin.gallery: service if you want to remove only gallery menu
#Application/Sonata/MediaBundle/Resources/config/services.yml
#Disable gallery & media menu from admin panel
services:
sonata.media.admin.media:
class: %sonata.media.admin.media.class%
tags:
- { name: sonata.admin, manager_type: orm, show_in_dashboard: false, label_catalogue: %sonata.media.admin.media.translation_domain% , label_translator_strategy: sonata.admin.label.strategy.underscore }
arguments:
- ~
- %sonata.media.admin.media.entity%
- %sonata.media.admin.media.controller%
- "#sonata.media.pool"
calls:
- [setModelManager, ["#sonata.media.admin.media.manager"]]
- [setTranslationDomain, [%sonata.media.admin.media.translation_domain%]]
- [setTemplates, [{ inner_list_row: SonataMediaBundle:MediaAdmin:inner_row_media.html.twig , base_list_field: SonataAdminBundle:CRUD:base_list_flat_field.html.twig , list: SonataMediaBundle:MediaAdmin:list.html.twig , edit: SonataMediaBundle:MediaAdmin:edit.html.twig }]]
sonata.media.admin.gallery:
class: %sonata.media.admin.gallery.class%
tags:
- { name: sonata.admin, manager_type: orm, show_in_dashboard: false, label_catalogue: %sonata.media.admin.media.translation_domain% , label_translator_strategy: sonata.admin.label.strategy.underscore }
arguments:
- ~
- %sonata.media.admin.gallery.entity%
- %sonata.media.admin.gallery.controller%
- "#sonata.media.pool"
calls:
- [setTranslationDomain, [%sonata.media.admin.media.translation_domain%]]
- [setTemplates, [{ list: SonataMediaBundle:GalleryAdmin:list.html.twig }]]
then clear your cache to reflect changes
php app/console cache:clear

I've achieved this by listing the allowed items for the dashboard in sonata.yaml, effectively hiding the gallery:
sonata_admin:
dashboard:
groups:
sonata_media:
label: "Media Library"
label_catalogue: SonataMediaBundle
items:
- sonata.media.admin.media

why don't you just edit app\config\sonata\sonata_admin.yml file end comment or remove line containing sonata.media.admin.gallery?

The quickest way - but - dirty way it to edit the sonata media config file:
vendor/sonata-project/media-bundle/Resources/config/doctrine_orm_admin.xml
You only need too add this
show_in_dashboard="false"
in the tag attribute of the service sonata.media.admin.gallery
<tag name="sonata.admin" show_in_dashboard="false" manager_type="orm" group="sonata_media" label="gallery" label_catalogue="%sonata.media.admin.gallery.translation_domain%" label_translator_strategy="sonata.admin.label.strategy.underscore"/>
If you use mongodb or phpcr then edit the corresponding file.
Also you can do the same for the sonata.media.admin.media service in the same file, so all the "Media" block in the admin will disapeared. But the services are still enable, so you manage your picture in your own entity admin as a sub-entity.
I hope this will help someone as it took me 30min to find the right file ...

Related

Doctrine - Set $id as UUID instead of Integer when creating new entity

I am working on a new project in Symfony 5.3. I am using this command bin/console make:entity for creating entities.
This wizard automatically creates an entity with $id as primary key of type integer. I am prefering UUID instead of integer.
How I should change settings to get Entity like this?
Thank you
namespace App\Entity;
use App\Repository\EventRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
/**
* #ORM\Entity(repositoryClass=EventRepository::class)
*/
class Event
{
/**
* #ORM\Id
* #ORM\Column(type="uuid", unique=true)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class=UuidGenerator::class)
*/
private $id;
...
}
There is no option to set the generated identifier strategy on make entity.
You can see all available option using php bin/console make:entity -h
Also there are no configuration in doctrine.yaml file to define this.
It could be a good feature to add for current and next version
To request a new feature, you can create a new issue feature request type:
https://github.com/symfony/symfony/issues/new/choose
You will need a github account

How to Force Phalcon to pick view from another module instead of defined?

Currently I am loading all users on URL/Route /admin/config/users which is picking this view ( private/apps/Admin/Views/user/users.volt ) from Admin module.
Now I have set a flag for custom layout. So if custom layout is enabled I want the phalcon to pick view from AdminExtension module i.e ( private/apps/Admin/Extension/Views/user/users.volt )
How can I achive this? I want both views. Because private/apps/Admin/Views/user/users.volt is default view for listing all users. However private/apps/Admin/Extension/Views/user/users.volt is customised view for client where a lot of design changes are done.
Here is how dispatcher code looks like:
/**
* #param Dispatcher $dispatcher
*/
public function afterExecuteRoute(Dispatcher $dispatcher) {
// Check if Json response is required
if ($this->_isJsonResponse) {
//if body
} else {
if(CxSettingCustomLayout::loadFromDb()->isCustomLayout()) {
//pick custom view here" `private/apps/Admin/Extension/Views/user/users.volt`
}
// Build current module configuration settings section name
$moduleConfigName = 'app_' . $this->dispatcher->getModuleName();
// Include assets configuration file where assets collections are defined
if(file_exists($this->config[ $moduleConfigName ]['assetsFile']))
include $this->config[ $moduleConfigName ]['assetsFile'];
// Set a view variable with the current language code
$this->view->setVar('current_language_code', $this->CxTranslation->getLanguage()->getCode());
}
}
As #num8er said already, try to use setViewsDir. I'm using Phalcons Simple view class in the following way
use Phalcon\Mvc\View\Simple;
$view = new Simple();
$view->setViewsDir(BASE_PATH . '/app/views/');
echo $view->render('admin/users');

How to change default prefix "Create/Update" that comes with CRUD?

How can i change, prefix that comes with CRUD operation ie CREATE / UPDATE in laravel NOVA?
And if i can change them, how can i apply translations on them?
prefix "Create" is shown in image.
There is no need to install packages or edit core files 😱. You can easily change this in the language files. Assuming that your app's locale is set to en, the translation file can be found in /resources/lang/vendor/nova/en.json.
In this file, go to the entry you need to edit, in this case
"Create :resource": "Create :resource"
and change the value to what you want it to be. For example, changing it to
"Create :resource": "Create a new :resource"
will turn the text into
Note: You don't need to change core files, You can also do this following way
"Create :resource": "Create :resource"
to "Create :resource": "Create a new :resource"
lets say resource name is post. then the new heading will become Create a new Post You can change heading the way you like from here.
And it will update your heading, without updating core files. #Govert Verschuur provided this solution.
Other way around is -> Default name "Create/Update" is provided in Panel.php file.
/**
* Get the default panel name for a create panel.
*
* #param \Laravel\Nova\Resource $resource
* #return string
*/
public static function defaultNameForCreate(Resource $resource)
{
return __('Create :resource', [
'resource' => $resource->singularLabel(),
]);
}
/**
* Get the default panel name for the update panel.
*
* #param \Laravel\Nova\Resource $resource
* #return string
*/
public static function defaultNameForUpdate(Resource $resource)
{
return __('Update :resource', [
'resource' => $resource->singularLabel(),
]);
}
Change the String here and boom, it will solve your issue.
And as far as translation is concerned is already applied, You just need to provide translation in your en.json or any other file.
Note:
Translation will only be applied on final string, so Add "Create" / "Update" with your label name and if label is not set then with your default name.

How to use Ajax within Sonata Admin forms?

I have a Merchant entity with the following fields and associations:-
/**
* #ORM\ManyToMany(targetEntity="Category", inversedBy="merchants")
*/
public $categories;
/**
* #ORM\ManyToMany(targetEntity="Tag", inversedBy="merchants")
*/
public $tags;
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="merchants")
*/
protected $primaryCategory;
/**
* #ORM\ManyToOne(targetEntity="Tag", inversedBy="merchants")
*/
protected $primaryTag;
The Tags and Categories also have a ManyToMany mapping.
So we have Tag_Category, Merchant_Tag, Merchant_Category mapping tables.
Now I want to perform some ajax on these fields.
I want to allow the user to select the Primary Tag first. On the basis of the Primary Tag, ajax refresh the categories to only those which belong to this Tag and some more operations.
How can I achieve this?
Thanks!
I was able to make this work a few months back. While what a.aitboudad has shared is accurate. There are a few gotcha's that first timers with Symfony/Sonata might face.
Here are the steps.
1> Extend Sonata CRUD's edit.html.twig / base_edit.html.twig .
For simplicity, I'll use only the latter.
Copy vendor/bundles/Sonata/AdminBundle/Resources/views/CRUD/base_edit.html.twig into the views folder corresponding to the MerchantAdminController - YourBundle/Resources/views/Merchant/base_edit.html.twig
2> We need to tell our MerchantAdmin class to use this template. So we override SonataAdmin's getEditTemplate method like this:
public function getEditTemplate()
{
return 'YourBundle:Merchant:base_edit.html.twig';
}
3> Next we need to code the Ajax functionality in our base_edit.html.twig . Standard Ajax comprises of the following:
3.1> -- Create an Action in the controller for the Ajax request
We primarily want to get a list of category IDs corresponding to a particular tag. But most likely you are just using Sonata's CRUD Controller.
Define your MerchantAdminController which extends CRUDController
<?php
namespace GD\AdminBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use GD\AdminBundle\Entity\Merchant;
class MerchantAdminController extends Controller
{
}
3.2> -- Tell your Admin service to use this newly created controller instead of the default CRUDController by defining it in YourBundle/Resources/config/services.yml
gd_admin.merchant:
class: %gd_admin.merchant.class%
tags:
- { name: sonata.admin, manager_type: orm, group: gd_merchant, label: Merchants }
arguments: [null, GD\AdminBundle\Entity\Merchant, GDAdminBundle:MerchantAdmin]
Notice that the 3rd argument is the name of your controller. By default it would have been null.
3.3> -- Create an Action named getCategoryOptionsFromTagAction in your controller. Your Ajax call will be to this Action.
// route - get_categories_from_tag
public function getCategoryOptionsFromTagAction($tagId)
{
$html = ""; // HTML as response
$tag = $this->getDoctrine()
->getRepository('YourBundle:Tag')
->find($tagId);
$categories = $tag->getCategories();
foreach($categories as $cat){
$html .= '<option value="'.$cat->getId().'" >'.$cat->getName().'</option>';
}
return new Response($html, 200);
}
3.4> -- Create the corresponding route in app/config/routing.yml. Remember to expose your route if you are using the FOSJsRoutingBundle (else you'll have to hardcode which is not a good idea).
get_categories_from_tag:
pattern: /{_locale}/admin/gd/admin/merchant/get-categories-from-tag/{tagId}
defaults: {_controller: GDAdminBundle:MerchantAdmin:getCategoryOptionsFromTag}
options:
expose: true
3.5> -- Make the Ajax Request and use the response
{% block javascripts %}
{{ parent() }}
<script type="text/javascript">
$(document).ready(function(){
var primaryTag = $("#{{ admin.uniqId }}_primaryTag");
primaryTag.change(updateCategories()); // Bind the function to updateCategories
primaryTag.change(); // Manual trigger to update categories in Document load.
function updateCategories(){
return function () {
var tagId = $("#{{ admin.uniqId }}_primaryTag option:selected").val();
var primaryCategory = $("#{{ admin.uniqId }}_primaryCategory");
primaryCategory.empty();
primaryCategory.trigger("liszt:updated");
var locale = '{{ app.request.get('_locale') }}';
var objectId = '{{ admin.id(object) }}'
var url = Routing.generate('get_categories_from_tag', { '_locale': locale, 'tagId': tagId, _sonata_admin: 'gd_admin.merchant', id: objectId });
$.post(url, { tagId: tagId }, function(data){
primaryCategory.empty().append(data);
primaryCategory.trigger("liszt:updated");
},"text");
primaryCategory.val("option:first").attr("selected", true);
};
}
});
</script>
{% endblock %}
Gotcha 1: How to get the Unique ID that is appended to all Sonata elements
Solution: Use the admin variable which will give you access to all the Admin Class's properties including uniqId. See code on how to use it.
Gotcha 2: How to get the Router in your JS.
Solution: By default Symfony2 Routing doesn't work in JS. You need to use a bundle called FOSJSRouting (explained above) and expose the route. This will give you access to the Router object within your JS too.
I have modified my solution slightly to make this example clearer. If you notice anything wrong, please feel free to comment.
At step 1 of Amit and Lumbendil answer you should change
{% extends base_template %}
into
{% extends 'SonataAdminBundle::standard_layout.html.twig' %}
if you get an error like
Unable to find template "" in YourBundle:YourObject:base_edit.html.twig at line 34.
Very detailed post, just to update the way of override and use the edit template in the Admin class.
Now, you should do it this way:
// src/AppBundle/Admin/EntityAdmin.php
class EntityAdmin extends Admin
{
public function getTemplate($name)
{
if ( $name == "edit" )
{
// template 'base_edit.html.twig' placed in app/Resources/views/Entity
return 'Entity/base_edit.html.twig' ;
}
return parent::getTemplate($name);
}
}
Or inject it in the service definition used the provided method, to keep the Admin class as cleaner as possible:
// app/config/services.yml
app.admin.entity:
class: AppBundle\Admin\EntityAdmin
arguments: [~, AppBundle\Entity\Entity, ~]
tags:
- {name: sonata.admin, manager_type: orm, group: "Group", label: "Label"}
calls:
- [ setTemplate, [edit, Entity/base_edit.html.twig]]
in the block javascripts, you have to change "liszt:updated" to "chosen:updated"
hope it helps someone ;)

Symfony2 custom validator

i am trying to build an custom validator with symfony2 but something strange happens:
i have created both Password and PasswordValidate by following the steps in symfony2 cookbook but first time when i load the page i get this error:
AnnotationException: [Semantical Error] The annotation "#Symfony\Component\Validator\Constraints\Password" in property NMSP\MyBundle\Entity\User::$password does not exist, or could not be auto-loaded.
after reloading the error disappears and the validation still not fires and it return the code is valid.
here is the relevant code:
//annotation declaration:
/**
* #ORM\Column(type="string", length="32", unique="true")
*
* #Assert\MinLength(3)
* #Assert\Password2()
*/
protected $password;
//load files with the following in the code
services:
validator.password:
class: NMSP\MyBundle\Validator\PasswordValidator
tags:
- { name: validator.constraint_validator, alias: password }
can`t figure this one out:(
Assuming your custom validator constraint is not in the Symfony\Component\Validator\Constraints namespace, but your own namespace: NMSP\MyBundle\Validator.
You should add the following use statement:
use NMSP\MyBundle\Validator as NMSPAssert;
Then use the following annotation on the $username property:
#NMSPAssert\Password()
That should do it.

Resources