symfony translation resource path - symfony

I can't make my translator to load a resource yams file.
I have a file admin.ru.yml inside AppBundle/Resources/config/translations/
I have in my other bundle the following lines
$translator = new Translator('ru_RU', new MessageSelector());
$translator->addLoader('yaml', new FileLoader());
$translator->addResource('yaml', 'admin.ru.yml', 'ru_RU', 'admin');
$tt = $translator->trans('Category', array(), 'admin');
It does not load the yml file.
I even have specified in my app/config.yml file of the whole application
translator:
paths:
- '%kernel.root_dir%/../src/AppBundle/Resources/config/translations'
but with no result. I tried many paths but can't find the right way. Any suggestions of what am I doing wrong?

you have to rename your file #AppBundle.ru.yml, the file path is not necessary

Related

Asset manifest file "manifest.json" does not exist

On a symfony5 + webpack encore application I can't access the url of an image in a controller.
Webpack is working and i access the img in twig. (with versionning)
the manifest.json file exist, and I have build the assets
$package = new Package(new JsonManifestVersionStrategy('C:\wamp64\www\svn\athena\public\build\manifest.json'));
echo $package->getUrl('build/images/tree/families.png');
=> This is working with the direct file address of the manifest.
but with :
$package = new Package(new JsonManifestVersionStrategy('manifest.json'));
or
$package = new Package(new JsonManifestVersionStrategy( '/build/manifest.json'));
=> I have the symfony exception : Asset manifest file "manifest.json" does not exist.
How can i make the manifest.json file address being relative ?
Thanks
assets.yaml
framework:
assets:
json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
Well, the path is supposed to be absolute...
You can inject the Packages service, that will be automatically configured:
use Symfony\Component\Asset\Packages;
public function controllerAction(Packages $packages)
{
$url = $packages->getUrl('build/images/tree/families.png');
}

JMS Serializer ignored my YML Entity exclusions

My config is
jms_serializer:
metadata:
auto_detection: true
directories:
NameOfBundle:
namespace_prefix: ""
path: "#VendorNameOfBundle/Resources/config/serializer"
My YML file named Entity.Project.yml contains
Vendor\NameOfBundle\Entity\Project:
exclusion_policy: ALL
properties:
id:
expose: true
I am loading the serializer like so from within a Controller
$serializer = SerializerBuilder::create()
->configureListeners(function(EventDispatcher $dispatcher) {
$dispatcher->addSubscriber(new ProjectSubscriber($this->container));
})
->addDefaultListeners()
->build();
This completely ignored my YML file and exposes all fields from the Project. I have cleared the cache.
But if I use this instead without the custom subscriber, then the exclusions work
$serializer = $this->get("jms_serializer");
Even explicitly adding a dir does not work either
$serializer = SerializerBuilder::create()
->configureListeners(function(EventDispatcher $dispatcher) {
$dispatcher->addSubscriber(new ProjectSubscriber($this->container));
})
->addDefaultListeners()
->addMetadataDir(realpath($this->get('kernel')->getRootDir()."/../") . '/src/Vendor/NameOfBundle/Resources/config/serializer')
->build();
The docs are not clear on how this path should befined. The above method does not error, but does not pull in the YML files. The below method errors and says the directory does not exist;
$serializer = SerializerBuilder::create()
->configureListeners(function(EventDispatcher $dispatcher) {
$dispatcher->addSubscriber(new ProjectSubscriber($this->container));
})
->addDefaultListeners()
->addMetadataDir('#VendorNameOfBundle/Resources/config/serializer')
->build();
How do I make the JMS Serializer look at my YML file in order to exclude the fields and also use the Subscriber?
As i see from documentation you need to setup your Yaml files:
it is necessary to configure a metadata directory where those files are located:
$serializer =
JMS\Serializer\SerializerBuilder::create()
->addMetadataDir($someDir)
->build();
For more information read manual.
This was helpful Using JMSSerialize to serialize Doctrine2 Entities that follow SimplifiedYamlDriver convention
It would appear that the file names needs to be completely different if you do not specify a namespace. I never thought to specify a namespace as this is not mentioned in the main docs.
If there is no namespace then the addMetaDir usage is fine but you also need to make sure your file names look like this
Vendor.NameOfBundle.Entity.Project.yml

Symfony2 cache:clear outputs the content of services.yml file

In Symfony2, everytime I clear my cache via the console:
php app/console cache:clear
The console prints out the contents of my services.yml file! If I manually delete the cache via rm -rf app/cache/* (which I have to do since my console user doesn't have access to the apache user www-data, for some reason, despite being in the same group because the files are created as 640 instead of 660), then the public website also prints it out the FIRST time the page is loaded and the cache is generated.
NOTE: this prints out even if services.yml is NOT loaded in the app/config/config.yml (just by existing, somehow it's being referenced)
We import the services.yml file:
# /app/config/config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: "#AcmeBundle/Resources/config/services.yml" }
Then set global services in the services.yml file:
# /src/Acme/Bundle/Resources/config/services.yml
# TODO: ALERT! this prints out whenever I clear the cache...
services:
#This is a service so that we can access the view object anywhere
acme.view:
class: Acme\Bundle\Controller\ViewController
arguments: [ #doctrine.orm.entity_manager ]
Question: Any ideas why this file is printing out every time I clear the cache?
This was caused by changing the /Acme/Bundle/Resources/config/services.yml services parameters from PHP to YAML format (I created as PHP originally in my testing).
The reference to the service parameters file is hard coded in the /Acme/Bundle/DependencyInjection/AcmeBundleExtension.php in two places.
Here is the broken code:
class AcmeBundleExtension extends Extension
{
/**
* {#inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
Since the services.yml was being loaded as a PHP file, it was just printing out text whenever the cache was recreated. Amazingly, all the services still actually loaded somehow...!
So take note, if you change the config file from PHP to YAML (or vice versa) you have to update:
$loader->load('services.yml');
(which I did)
But also you must update the loader function from Loader\PhpFileLoader to Loader\YamlFileLoader:
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
Of course that seems obvious, but if you are new to Symfony, take note that converting formats of your service config file requires more than just changing your file name.

Custom route configuration with Silex

I know that the basis of Silex approach in which all the application logic in a single file. But my application will be possible to have more than twenty controllers. So I want to have a handy map to manage the router.
My question is to search for solutions in which I would be able to make a router to a separate file. In the best case, the file must be of YAML type:
# config/routing.yml
_home:
pattern: /
defaults: { _controller: MyProject\Controller\MyController::index }
But the native is also a good case (for me):
$routes = new RouteCollection();
$routes->add(
'home',
new Route('/', array('controller' => 'MyProject\Controller\MyController::index')
));
return $routes;
Problem of the second case is that I have to use the match() function for each rule of routing. It is not at all clear.
What are the ways to solve this issue? The condition is that I want to use the existing API Silex or components of Symfony2.
Small note:
I don't use a ControllerProviderInterface for my Controller classes. This is an independent classes.
First of all, the basis of Silex is not that you put everything in one file. The basis of Silex is that you create your own 'framework', your own way of organizing applications.
"Use silex if you are comfortable with making all of your own architecture decisions and full stack Symfony2 if not."
-- Dustin Whittle
Read more about this in this blogpost, created by the creator of Silex.
How to solve your problem
What you basically want is to parse a Yaml file and get the pattern and defaults._controller settings from each route that is parsed.
To parse a Yaml file, you can use the Yaml Component of Symfony2. You get an array back which you can use to add the route to Silex:
// parse the yaml file
$routes = ...;
$app = new Silex\Application();
foreach ($routes as $route) {
$app->match($route['pattern'], $route['defaults']['_controller']);
}
// ...
$app->run();
I thought I'd add my method here as, although others may work, there isn't really a simple solution. Adding FileLocator / YamlFileLoader adds a load of bulk that I don't want in my application just to read / parse a yaml file.
Composer
First, you're going to need to include the relevant files. The symfony YAML component, and a really simple and useful config service provider by someone who actively works on Silex.
"require": {
"symfony/yaml": "~2.3",
"igorw/config-service-provider": "1.2.*"
}
File
Let's say that your routes file looks like this (routes.yml):
config.routes:
dashboard:
pattern: /
defaults: { _controller: 'IndexController::indexAction' }
method: GET
Registration
Individually register each yaml file. The first key in the file is the name it will be available under your $app variable (handled by the pimple service locator).
$this->register(new ConfigServiceProvider(__DIR__."/../config/services.yml"));
$this->register(new ConfigServiceProvider(__DIR__."/../config/routes.yml"));
// any more yaml files you like
Routes
You can get these routes using the following:
$routes = $app['config.routes']; // See the first key in the yaml file for this name
foreach ($routes as $name => $route)
{
$app->match($route['pattern'], $route['defaults']['_controller'])->bind($name)->method(isset($route['method'])?$route['method']:'GET');
}
->bind() allows you to 'name' your urls to be used within twig, for example.
->method() allows you to specify POST | GET. You'll note that I defaulted it to 'GET' with a ternary there if the route doesn't specify a method.
Ok, that's how I solved it.
This method is part of my application and called before run():
# /src/Application.php
...
protected function _initRoutes()
{
$locator = new FileLocator(__DIR__.'/config');
$loader = new YamlFileLoader($locator);
$this['routes'] = $loader->load('routes.yml');
}
Application class is my own and it extends Silex\Application.
Configuration file:
# /src/config/routes.yml
home:
pattern: /
defaults: { _controller: '\MyDemoSite\Controllers\DefaultController::indexAction' }
It works fine for me!
UPD:
I think this is the right option to add collections:
$this['routes']->addCollection($loader->load('routes.yml'));
More flexible.
You could extend the routes service (which is a RouteCollection), and load a YAML file with FileLocator and YamlFileLoader:
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
$app->extend('routes', function($routeCollection) {
$locator = new FileLocator([__DIR__ . '/../config']);
$loader = new YamlFileLoader($locator);
$collection = $loader->load('routes.yml');
$routeCollection->addCollection($collection);
return $routeCollection;
});
You will need symfony/config and symfony/yaml dependencies though.

Symfony2: class MapClassLoader not found

I'm trying to use MapClassLoader in autoload.php but for some reason I keep getting errors saying
Class 'Symfony\Component\ClassLoader\MapClassLoader' not found in ...\autoload.php
autoload.php:
<?php
use Symfony\Component\ClassLoader\UniversalClassLoader;
use Symfony\Component\ClassLoader\MapClassLoader;
use Doctrine\Common\Annotations\AnnotationRegistry;
$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
//some values
));
$mapLoader = new MapClassLoader(array(
//some values
));
$mapLoader->register();
I double checked and MapClassLoader.php does exist in Symfony\Component\ClassLoader
Any idea why is it happening? :/
autoload.php is a file that configures autoloading for classes so autoloading isn't available in it and you need to include any files manually:
require_once __DIR__.'/../vendor/symfony/src/Symfony/ClassLoader/MapClassLoader.php';
Why is UniversalClassLoader available without require? Because symfony uses bootstrap file for system files to reduce file loading overhead.

Resources