I try to set up a symfony project with the microcontroller trait. But instead of use a config.yml I want to use a config.php file.
return [
'framework' => [
'secret' => 'secret_'
]
];
What is the best practice to achieve this?
when using microkernel trait, you can use the configureContainer method in your front controller (app.php) to load configuration directly from an array, like this:
protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
{
// PHP equivalent of config.yml
$c->loadFromExtension('framework', array(
'secret' => 'S0ME_SECRET'
));
}
docs here
You should use the container to set the parameters like
$container->setParameter('framework.secret', 'secret_');
as explained in the Symfony Docs
Related
I'm using Translatable and EasyAdmin in a Symfony 5 project and I have configured 2 languages.
The issue is I need to be able to edit the different languages of a record in EasyAdmin, I have checked the docs of Translatable, EasyAdmin and Symfony, There is very little information about how to integrate database translations into EasyAdmin.
Therefore, I'm a bit stuck in terms of code, I have tried configuring setTranslationParameters() inside the entity CRUD controller and changing some configuration in the DashboardController however, I don't think this is the right approach.
Any suggestions of how to solve this issue?
Thank you for your effort and time.
as of writing, this feature doesn't exist in EasyAdmin, please see the link to the answer to the issue on Github.
https://github.com/EasyCorp/EasyAdminBundle/issues/4982
However, a work around is possible with a different package:
remove doctrine-extensions/DoctrineExtensions and then install KnpLabs/DoctrineBehaviors
install a2lix/translation-form-bundle
Create a translation field:
<?php
declare(strict_types=1);
namespace App\Controller\Admin\Field;
use A2lix\TranslationFormBundle\Form\Type\TranslationsType;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait;
final class TranslationField implements FieldInterface
{
use FieldTrait;
public static function new(string $propertyName, ?string $label = null, array $fieldsConfig = []): self
{
return (new self())
->setProperty($propertyName)
->setLabel($label)
->setFormType(TranslationsType::class)
->setFormTypeOptions([
'default_locale' => 'cz',
'fields' => $fieldsConfig,
]);
}
}
Use the TranslationField inside your admin CRUD controller:
public function configureFields(string $pageName): iterable
{
return [
TextField::new('title', 'title')->hideOnForm(),
TranslationField::new('translations', 'translations', [
'title' => [
'field_type' => TextType::class,
'required' => true,
]
// add more translatable properties into the array
])->setRequired(true)
->hideOnIndex()
];
}
I'm currently working on an OroPlatform project and I need to add a custom field on the BusinessUnit core entity.
I have read the Oro documentation section about the way to extend core entities : https://doc.oroinc.com/backend/entities/extend-entities/#id1
<?php
namespace MyBundle\Bundle\AppBundle\Migrations\Schema\v1_0;
use Doctrine\DBAL\Schema\Schema;
use Oro\Bundle\EntityExtendBundle\EntityConfig\ExtendScope;
use Oro\Bundle\MigrationBundle\Migration\Migration;
use Oro\Bundle\MigrationBundle\Migration\QueryBag;
class AddColumnsToBusinessUnit implements Migration
{
public function up(Schema $schema, QueryBag $queries)
{
$table = $schema->getTable('oro_business_unit');
$table->addColumn('siret', 'string', [
'oro_options' => [
'extend' => ['owner' => ExtendScope::OWNER_CUSTOM],
'entity' => ['label' => 'siret'],
],
]);
}
}
When I run the command symfony console oro:migration:load --force, it works and the migration is applied to my database.
Now, I want a required field. I have seen the instruction 'notnull' => true to setup a non nullable field on the database.
Everything works well, but my field hasn't any JavaScript validation on the organization/business_unit/create route. Any ideas ?
You can validate the new field by extending the validation metadata that is already defined for the core entity you are extending.
To do this, please follow the official Symfony documentation and use the YML format:
https://symfony.com/doc/4.4/validation.html#constraint-configuration
The constraint that you can use for the field is "not blank."
Here is an example:
# src/<YourBundlePath>/Resources/config/validation.yml
Oro\Bundle\OrganizationBundle\Entity\BusinessUnit:
properties:
siret:
- NotBlank: ~
I am using this tutorial https://docs.zendframework.com/tutorials/getting-started/overview/ for creating album module. It works for me.
Inside project there is /module/Album/config/module.config.php file which contains routes. Routers are located inside an array tree. As my previous experience shows I can have in the future dozens of routes per a project (even per a module).
On this documentation page https://docs.zendframework.com/zend-router/routing/ I found another way to add routers to the module.
// One at a time:
$route = Literal::factory([
'route' => '/foo',
'defaults' => [
'controller' => 'foo-index',
'action' => 'index',
],
]);
$router->addRoute('foo', $route);
Such a way is preferred for me than storing routes in a very deep config array tree.
So, my question is: where I can put php routers code outside a config tree as I have mentioned earlier? Where in the module should be such a routers-file located at?
Next to module.config.php in the modules config/ folder it's common to create a routes.config.php.
I split it further by doing something like user.routes.config.php with roles.routes.config.php. Possibly you'd like front.routes.config.php with admin.routes.config.php.
In the end, it's up to you. For colleagues and future sanity, make sure you do it consistently though.
As an example, the config in a project of mine for the User module:
It's a module that handles anything directly User related, so it's all in there. Should probably split it up more, but for now, that would be unnecessary.
You'd then load all of this config like so in your Module.php:
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface, AutoloaderProviderInterface
{
/**
* #return array
*/
public function getConfig()
{
$config = [];
$path = __DIR__
. DIRECTORY_SEPARATOR . '..'
. DIRECTORY_SEPARATOR . 'config'
. DIRECTORY_SEPARATOR . '*.php';
foreach (glob($path) as $filename) {
$config = array_merge_recursive($config, include $filename);
}
return $config;
}
/**
* #return array
*/
public function getAutoloaderConfig()
{
return [
'Zend\Loader\StandardAutoloader' => [
'namespaces' => [
__NAMESPACE__ => __DIR__ . DIRECTORY_SEPARATOR . 'src',
],
],
];
}
}
Remember, eventual implementation in your project(s) is up to you. However, work out a standard and stick to it. You'll go insane if you have different standards everywhere you go.
I want to create a plugin to use zend-i18n/translate on controller. On zf2 I have a controller plugin that does this for me, but on zf3 I could not get this to work. How can I use zend-i18n inside a controller or via controller plugin with zf3?
==========
I just found what I need here on zf doc: https://docs.zendframework.com/zend-mvc-i18n/services/#mvctranslator-and-translatorfactory
if you already have config the translator as factory on your module.config.php, you can inject on your controller plugin.
You can virtually do the same as the answer that #hkulekci referred to in his comment.
'service_manager' => [
'factories' => [
\Zend\I18n\Translator\TranslatorInterface::class => \Zend\I18n\Translator\TranslatorServiceFactory::class,
]
]
and
'controller_plugins' => [
'invokables' => [
'translate' => \Zend\I18n\View\Helper\Translate::class
]
]
After that you can get the translate plugin like in your controller action methods like this:
public someAction(){
$translator = $this->translate;
}
Check the Zend Framework documentation or this Zend Framework blog for more details on the controller plugin manager.
For translate in model and controller, I did this in my module.config.php
'service_manager' => [
'factories' => [
\Zend\I18n\Translator\Translator::class => \Zend\I18n\Translator\TranslatorServiceFactory::class,
],
],
Then from my controller or model which has serviceContainer initialised I do:
$this->myVar = $serviceContainer->get(\Zend\I18n\Translator\Translator::class);
Then I can access it by doing
$this->myVar->translate('lorem ipsum');
I'm trying to set up an Admin as a child of an other Admin in Sonata Admin Bundle.
I have 2 Admin classes:
CategoryAdmin
This class contains the following method
protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
{
$id = $this->getRequest()->get('id');
$menu->addChild(
$this->trans('Projects'),
array('uri' => $this->getChild('sonata.admin.project')->generateUrl('list', array('id' => $id)))
);
}
ProjectAdmin
This class contains protected $parentAssociationMapping = 'category';
category is the property in the model class representing the ManyToOne association.
I added the following lines to my service configuration for CategoryAdmin
calls:
- [ addChild, ["#sonata.admin.project"]]
The routes for the child Admin are not being generated with this configuration. The link in the SideMenu (top menu) points to /admin/project/list?childId=1&id=1
Here is the output of the children of CategoryAdmin with dump()
array:1 [▼
"sonata.admin.project" => ProjectAdmin {#406 ▶}
]
This means that the configuration for my child admin seems to be correct. I have no idea, why the routes for the child admin are not being generated.
I hope somebody can give me a hint, what the problem could be.
Note for next gen sonata coders:
If your route is not being generated, first check you didn't do:
protected function configureRoutes(RouteCollection $collection)
{
//clear all routes except given !!!
$collection->clearExcept(array('list', 'show'));
}
It costs me two days...
Do you have the $baseRouteName and $baseRoutePattern overriden in your admin class ?
If you do, Sonata will generate both child and parent routes with the same name resulting in the parent routes overriding the child ones.
I bumped into this issue while solving the problem for myself and decided to share the solution, which costed me several debugging hours...
The only way to generate a proper uri in this case is to use low-level routeGenerator which doesn't make any sonata suggestions, made inside generateMenuUrl method.
First you have to debug the routes, you have in your app (including autogenerated by sonata).
php bin/console debug:router
For example I have 3 nesting levels
hall -> seats scheme -> sector
And my routes are following:
adminHall_list ANY ANY ANY /admin/hall/list
adminHall_create ANY ANY ANY /admin/hall/create
adminHall_edit ANY ANY ANY /admin/hall/{id}/edit
adminHall_delete ANY ANY ANY /admin/hall/{id}/delete
adminHall_adminScheme_list ANY ANY ANY /admin/hall/{id}/scheme/list
adminHall_adminScheme_create ANY ANY ANY /admin/hall/{id}/scheme/create
adminHall_adminScheme_edit ANY ANY ANY /admin/hall/{id}/scheme/{childId}/edit
adminHall_adminScheme_delete ANY ANY ANY /admin/hall/{id}/scheme/{childId}/delete
adminHall_adminScheme_adminSector_list ANY ANY ANY /admin/hall/{id}/scheme/{childId}/sector/list
adminHall_adminScheme_adminSector_create ANY ANY ANY /admin/hall/{id}/scheme/{childId}/sector/create
adminHall_adminScheme_adminSector_edit ANY ANY ANY /admin/hall/{id}/scheme/{childId}/sector/{childChildId}/edit
adminHall_adminScheme_adminSector_delete ANY ANY ANY /admin/hall/{id}/scheme/{childId}/sector/{childChildId}/delete
In admin classes baseRouteName and baseRoutePattern has been overridden.
// HallSchemeAdmin.php
$this->baseRouteName = 'adminScheme';
$this->baseRoutePattern = 'scheme';
To generate a most deep listing url:
$url = $admin->getRouteGenerator()->generate('adminHall_adminScheme_adminSector_list', [
'id' => $admin->getRequest()->get('id'),
'childId' => 555, // put required id
]);
It will produce the url like this:
/admin/hall/495/scheme/555/sector/list
If you need edit url, you have to provide childChildId param too:
$url = $admin->getRouteGenerator()->generate('adminHall_adminScheme_adminSector_edit', [
'id' => $admin->getRequest()->get('id'),
'childId' => 555,
'childChildId' => 12345
]);
The result is:
/admin/hall/495/scheme/555/sector/12345/edit