Snc_redis exception when loading - symfony

I'm getting the following exception:
InvalidConfigurationException: The child node "clients" at path "snc_redis" must be configured.
I use Symfony 2.3 SncRedisBundle 1.1.x-dev
In config.yml I have
clients:
default:
type: predis
alias: default
dsn: redis://localhost
logging: %kernel.debug%
And I've followed the docs here for installation...
Any idea what would cause this ?

The bundle is looking for configuration values under snc_redis root (as you can see here), which you did not provide.
Now, all this wouldn't normally be a problem, but the clients child node is mandatory (as you can see here), which causes the error above.
Simply make the root configuration node in your config.yml to be snc_redis and the problem will go away. You probably simply missed it when doing copy-paste.

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?

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

Why am I getting "Cannot redeclare class" on Symfony2 + vagrant + moved vendors optimalization setup?

Recently I've been working on improveing my vagrant enviroment and I've stumbled upon Running the Symfony application on Vagrant without NFS below 100ms blog post.
I've moved the vendor dir outside the VM shared directory, as suggested, by createing /tmp/app/vendor dir inside the VM and setting
export COMPOSER_VENDOR_DIR=/tmp/app/vendor
export COMPOSER_BIN_DIR=/tmp/app/bin
export SF2_ENV=vagrant
enviroment variables before running composer install.
Now, with vendors correctly installed to another path, I've modified the app/autoload.php file to detect if the app is running inside the VM by looking for the SF2_ENV enviroment variable:
if (array_key_exists('SF2_ENV', $_SERVER) && $_SERVER['SF2_ENV'] === 'vagrant') {
// vagrant enviroment detected
$loader = require sys_get_temp_dir().'/app/vendor/autoload.php';
} else {
// default
$loader = require __DIR__.'/../vendor/autoload.php';
}
This worked fine for one project, however on another project I kept getting the
PHP Fatal error: Cannot redeclare class Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry in /var/www/public_html/vendor/gedmo/doctrine-extensions/lib/Gedmo/Loggable/Entity/MappedSuperclass/AbstractLogEntry.php on line 13
error when trying to initialize the app cache php app/console cache:clear -e=prod.
Why was this happening?
Note: I've anwsered myself, as this is a Q&A style question (a note to my future self).
I am posting this as a reminder to my future self or anyone else interested. The problem was becouse in the second project I used Gedmo library and in my config.yml I defined:
doctrine:
orm:
entity_managers:
default:
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
mappings:
gedmo_translatable:
type: annotation
prefix: Gedmo\Translatable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
alias: GedmoTranslatable
is_bundle: false
So, the problem was clearly the %kernel.root_dir% part, which was hardcoded.
Solution
I've simply changed it to %vendor_dir% and defined this parameter in my parameters.yml - for production as vendor_dir: '%kernel.root_dir%/../vendor' and for local (dev) as vendor_dir: /tmp/app/vendor.
I already have problem with symfony2 project on Vagrant. But I resolve this without change location of /vendor directory.
Just disable the nfs share and locate your projects directly on /var/www
you can use this on vagrantFile :
config.vm.synced_folder '.', '/vagrant', disabled: true
Work with your Vagrant as like you work with a remote server...
What happening when you deploying in production environment your autoload.php file ? it's not very useful to change this only for dev environment (I don't speak only for this file but general idea).

Non-existing setting in Doctrine bridge in Symfony2

I've just installed Sylius Settings bundle.
After composer finished its work, and after setting everything as in docs (link above), enabling Sylius Settings bundle causes the following error:
The service definition "doctrine.orm.default_metadata_driver" does not exist.
I searched for this keywords (whole service name) for the whole vendors folder, but it found it only in some Doctrine test files, nowhere else. Anyone knows what is it about? Perhaps it's just a "legacy bug" in SF2?
Or perhaps not. I found this class for the moment:
Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass
in particular this part (constructor):
public function __construct($driver, array $namespaces, array $managerParameters, $enabledParameter = false, array $aliasMap = array())
{
$managerParameters[] = 'doctrine.default_entity_manager';
parent::__construct(
$driver,
$namespaces,
$managerParameters,
'doctrine.orm.%s_metadata_driver',
$enabledParameter,
'doctrine.orm.%s_configuration',
'addEntityNamespace',
$aliasMap
);
}
(Note: "'doctrine.orm.%s_metadata_driver'," as a partly hard-coded param)
I wonder if it has anything to do with the fact that I'm not using ORM, but PHPCR-ODM as a default connection type (ORM is non-default additional connection layer).
config.yml part referring to the bundle:
sylius_settings:
driver: doctrine/orm
doctrine_cache:
providers:
my_apc_metadata_cache:
type: apc
namespace: metadata_cache_ns
my_apc_query_cache:
namespace: query_cache_ns
apc: ~
sylius_settings:
type: file_system
Nothing extra ordinary.

Symfony2 bundle configuration parameters

My team develops a very large e-commerce project. Up to now, we had something like 40 configuration parameters in that bundle and I didn't know their final relations nor had a way to structure them properly, so we ended up using the standard parameters structure in the app/config.yml file. But, somewhere along the way I decided to move the config to the semantic configuration structure - so I can validate it, have a clean structure, easily extend it by means of bundle inheritance and so on.
The problem is I can't import our bundle parameters to another bundle config, now.
Here's what I could do before:
(...)
parameters:
company.bundle.email.user: user#domain.com
company.bundle.email.pass: #MyBeAUtiFULpA55w0Rd!
(...)
swiftmailer:
(...)
username: %company.bundle.email.user%
password: %company.bundle.email.pass%
Here's what I'm trying to do now and it doesn't work at all:
(...)
company_bundle:
(...)
settings:
(...)
mailer:
(...)
user: user#domain.com
pass: #MyBeAUtiFULpA55w0Rd!
(...)
swiftmailer:
(...)
username: %company_bundle.settings.mailer.user%
password: %company_bundle.settings.mailer.pass%
(...)
Of course the company_bundle node contains the semantic configuration, processed by the DIC and defined in Company\Bundle\DependencyInjection\Configuration.php.
All I end up with for now is the following error:
[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]
You have requested a non-existent parameter "company_bundle.settings.mailer.user".
So the question is: how to make my bundle parameters accessible in another bundle configuration parameters (I've already taken care of including my bundle configuration always before the Swiftmailer bundle)?
NOTICE: Swiftmailer bundle configuration is shown here only for demonstration purposes, I want to be able to reuse my bundle parameters across some other bundles as well.
What's the motivation behind that?
Well I want our product to be configured by a person who doesn't know Symfony well - so she must be able to open our bundle config file and just tweak the parameters, which will then be used in some Symfony bundles we use. So I want all application configuration to be accessible in our bundle's semantic conf, since I'd want not to expose the whole configuration to that person (I've already divided everything into separate config files, one of them containing the configuration for our bundle, the rest - for all the other ones).
So, is what I'm asking even possible?
As the parameters are to be modified in each installation (they probably differ at least between development and production environments), so (as Sgoettschkes said in comment) external file is the best solution.
In Symfony2 by default place for such parameters is parameters.yml file located in app/config/ dir.
In standard installation you can find for example such entries:
parameters:
database_driver: pdo_mysql
database_host: 127.0.0.1
(...)
These params are used in config.yml this way:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
(...)
So you can define your params (in parameters.yml):
parameters:
(...)
company_bundle_email_user: user#domain.com
company_bundle_email_pass: #MyBeAUtiFULpA55w0Rd!
and use them (in config.yml):
swiftmailer:
(...)
username: %company_bundle_email_user%
password: %company_bundle_email_pass%

Resources