JMS Serializer: overriding default naming strategy in symfony 4 has no effect - symfony

I found this thread proposing a neat way of overriding globally the default naming strategy in config.yml
but this is for symfony 3 and I am on symfony 4 so I added the line to my config > packages > jms_serializer.yaml but this has no effect at all.
jms_serializer:
visitors:
xml_serialization:
format_output: '%kernel.debug%'
property_naming:
id: 'jms_serializer.identical_property_naming_strategy'
Does anyone understand why ?
I do dependency injection of SerializerInterface $serializer to use the serializer as it is not possible to call the service from AbstractController in SF4. Controller is deprecated in SF4.

Try removing var/cache manually. When I cleared cache with cache:clear command it didn't work, but after I cleaned it manually it did!
I hope this solution will help you too.

Add jms_serializer.camel_case_naming_strategy.class: JMS\Serializer\Naming\IdenticalPropertyNamingStrategy to your parameters configuration.

Related

Issue with Doctrine namespace aliases during upgrade from Symfony 3 to 4

I am trying to upgrade a Symfony 3 application to Symfony 4, but I am having trouble with Doctrine's namespace aliases. My entities are located under AppBundle\Entity (as was the default in older Symfony versions) and there was an alias for that, so my entities are referred to via AppBundle:SomeEntity all over my codebase. I understand that the new way to do this is to use the FQCN instead, but I would like to avoid having to do a massive find&replace operation right now.
I modified config/packages/doctrine.yaml with the following mapping:
mappings:
AppBundle:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/AppBundle/Entity'
prefix: 'AppBundle\Entity'
alias: AppBundle
However, I only get a ReflectionException saying Class AppBundle:SomeEntity does not exist. As far as I can tell from the stack trace, the alias is never resolved, just passed directly down to AbstractManagerRegistry as a class name, which then just passes it to the ReflectionClass constructor. The calling code, e.g., looks like this (inside a controller): $this->getDoctrine()->getRepository("AppBundle:SomeEntity")->...
I have now idea what the problem is. It looks like there is just no logic that would resolve aliases in this code path. It is probably a configuration issue. However, the configuration is mostly the default that comes with Symfony 4. I basically just replaced "App" with "AppBundle". Can anyone help me out here?

bundle's service (autowire) not available in controller's method

I'd like to use https://github.com/tedious/TedivmStashBundle bundle in my symfony 4 project. Added by composer, configured in /config/stash.yaml file and according to the profiler bar, it's working basically.
Now, I want to use to caching values in my controller. I've try to add the service stash by its name to the method's parameter, using the same name as the example says:
$pool = $this->container->get('stash');
but the framework did not find the service. It can't be added like the example explained neither.
How can I use this bundle as a service (autowired) in my symfony 4 app?
UPDATE
services.yaml:
stash.default_cache:
class: Tedivm\StashBundle\Service\CacheService
public: true
arguments:
$name: 'stash'
Tedivm\StashBundle\Service\CacheService: '#stash.default_cache'
Controller:
public function something(Request $request, CacheService $service, ...
It's looks like working now :)
Thanx for the suggestion (and the correct solution later) to #Cerad
Here is an example of how to approach this sort of problem when dealing with bundles that are not quite ready for autowire.
Start by installing a test project:
symfony new --full stash --version=lts
composer require tedivm/stash-bundle
Note that the bundle does not directly support Symfony 5 hence the lts. Note also that the bundles does not support Flex so you have to add your own config/packages/stash.yaml file per the bundle's readme file.
# config/packages/stash.yaml
stash:
drivers: [ FileSystem ]
FileSystem: ~
At this point we can determine which service we need to inject:
bin/console debug:container stash
Information for Service "stash.default_cache"
=============================================
Class CacheService
---------------- -----------------------------------------
Option Value
---------------- -----------------------------------------
Service ID stash.default_cache
Class Tedivm\StashBundle\Service\CacheService
Most of the time you would like to use an interface for injection but a peek at the source code reveals that the bundle does not use interfaces. As a side note, calling a third party service 'stash' is not a good idea. It really should have been 'tedivm.stash' but I digress.
We can now create an alias and then typehint against it:
# config/services.yaml
Tedivm\StashBundle\Service\CacheService : '#stash' # alias for typehinting
# Controller class
public function index(CacheService $cacheService)
{
return new Response('Cache ' . get_class($cacheService));
}
And that should do it.

Symfony Bundle references "#Bundle" - FileLocatorFileNotFoundException

I am currently building my own Symfony bundle (I am using version 3.3). It works fine so far, but now I wanted to move the bundle-specific service definition out of my app/config/services.yml to a service definition within the bundle.
I created a src/MyBundle/Resources/config/services.yml and followed the guide How to Load Service Configuration inside a Bundle to load it. That works just fine, but I thought that the paths inside the newly created services.yml look a bit ugly:
MyBundle\:
resource: '../../*'
exclude: '../../{Tests}'
So I thought it would look a little cleaner, if I use the #Bundle-notation instead:
MyBundle\:
resource: '#MyBundle/*'
exclude: '#MyBundle/{Tests}'
However, than I was facing the error:
FileLocatorFileNotFoundException
The file "#MyBundle" does not exist (in: <...>\MyBundle\DependencyInjection/../Resources/config), where <...> corresponds to an absolute path.
I also tested whether it was a naming issue of the bundle name, but when I have a wrongly named bundle reference in the app/config/services.yml, e.g. #SomeBundleThatDoesNotExist then I get a different error:
FileLoaderLoadException
Bundle "SomeBundleThatDoesNotExist" does not exist or it is not enabled.
So my question is: Why does the #Bundle-notation work fine in the app/config/services.yml but not in the src/MyBundle/Resources/config/services.yml?
If you use the service remember make public for external use:
autowire: true
public: true
But, if your symfony dont know where is the bundle please chec this answer:
Symfony generated Bundle doesn't work

Symfony Dependency Injection: Set a repository as a service using php

I have the set the following respository as a service on my Symfony 3.2 project:
person_in_need_repository:
class: AppBundle\Repository\PersonInNeedRepository
factory: ["#doctrine","getRepository"]
arguments: ["AppBundle:PersonInNeed"]
How can I change its annotation in php format?
It can be done by like this:
use AppBundle\Repository\PersonInNeedRepository;
$container->register('app.person_in_need_repository',PersonInNeedRepository::class)
->setFactory([new Reference("doctrine"),"getRepository"])
->addArgument('AppBundle:PersonInNeed');
Also ensure that you have replaced the services.yml with services.php on config.yml when using it as a global way to set the services. Also rename properly the services.yml.

Provide Doctrine with custom cache factory for second level cache

Background: we're using Symfony 3.1 + Doctrine 2.5.5 + symfony doctrine bundle.
While trying to enable second level caching for our entities, we have encountered the following issue. If we use NONSTRICT_READ_WRITE, everything works fine. However, when we tried to use READ_WRITE, we got the following error
0)
Type error: Argument 2 passed to Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister::__construct() must be an instance of Doctrine\ORM\Cache\ConcurrentRegion, instance of Doctrine\ORM\Cache\Region\DefaultRegion given, called in vendor/doctrine/orm/lib/Doctrine/ORM/Cache/DefaultCacheFactory.php on line 133
As far as I understood, we need to actually implement our own version of ConcurrentRegion and CacheFactory to make it work (FileLockRegion does not suit us due to its usage of file system to handle cache locks). So I wrote those implementations, but the main issue now lies in following: I cannot find where to put my custom factory class' name in the configuration. We have tried the following locations in config:
1)
doctrine:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: master
second_level_cache:
default_cache_factory:
class: AppBundle\Cache\MyCacheFactory
This fails due to
Unrecognized option "second_level_cache" under "doctrine.orm"
even though in our other project using Symfony 2.8 option "second_level_cache" does not throw any errors.
So we went to doctrine bundle code and found the following node description (vendor/doctrine/doctrine-bundle/DependencyInjection/Configuration.php:492)
->arrayNode('second_level_cache')
->children()
->append($this->getOrmCacheDriverNode('region_cache_driver'))
->scalarNode('region_lock_lifetime')->defaultValue(60)->end()
->booleanNode('log_enabled')->defaultValue($this->debug)->end()
->scalarNode('region_lifetime')->defaultValue(0)->end()
->booleanNode('enabled')->defaultValue(true)->end()
->scalarNode('factory')->end()
->end()
So we decided we should try this config in our master entity manager section:
2)
second_level_cache:
region_cache_driver:
type: memcache
enabled: true
log_enabled: true
factory: AppBundle\Cache\MyCacheFactory
regions:
hour_region:
lifetime: 3600
However, even though this config is considered valid, when we actually try to access the entity with configured caching, we get the error 0), which makes us think that this option is being ignored by doctrine/symfony.
Is there any way to do it via .yml config at all? Doctrine docs only propose to implement CacheFactory and provide a PHP code example, but it's still quite unclear where should this PHP code go, even if we decide to abandon the idea of putting our class in .yml config and go the PHP way.
Use type - filelock for configurate FilelockRegion
regions:
default:
cache_driver:
type: service
id: 'Doctrine\Common\Cache\RedisCache'
lifetime: 3600
type: filelock

Resources