I was using Gedmo\Blameable with the Stof\DoctrineExtensionsBundle and everything was working great with the following config:
# config/packages/stof_doctrine_extensions.yaml
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
blameable : true
timestampable: true
Later I had a need to have a console command add a record so looked for the applicable services:
$ bin/console debug:container | grep blame
stof_doctrine_extensions.event_listener.blame Stof\DoctrineExtensionsBundle\EventListener\BlameListener
stof_doctrine_extensions.listener.blameable Gedmo\Blameable\BlameableListener
injected the service into my command:
services:
App\Command\ClassThatAddsRecord:
arguments:
$blameableListener: '#stof_doctrine_extensions.listener.blameable'
and called it:
class ClassThatAddsRecord extends Command
{
public function __construct(private BlameableListener $blameableListener)
{
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ...
$this->blameableListener->setUserValue($user);
}
}
But then I changed to database-less tokens and thus changed the user provider to return App\Security\User instead of App\Entity\User, gave it a try, and CRASH, Doctrine complained about the user not being in the chain configured namespaces. Looking at Stof\DoctrineExtensionsBundle\EventListener\BlameListener, I see it is being inected with Gedmo\Blameable\BlameableListener and executes $this->blameableListener->setUserValue($token->getUser()), and since $token->getUser() is not an Doctrine entity, I am getting the error.
So, looking at the docs, I see I can override the listener and changed the config to the following:
stof_doctrine_extensions:
default_locale: en_US
class:
blameable: App\EventListener\MyBlameableListener
orm:
default:
blameable : true
timestampable: true
But now when I check my services, I know longer have Gedmo\Blameable\BlameableListener which I need but only Stof\DoctrineExtensionsBundle\EventListener\BlameListener which I don't want.
$ bin/console debug:container | grep blame
app.blame_listner App\EventListener\MyBlameableListener
stof_doctrine_extensions.event_listener.blame Stof\DoctrineExtensionsBundle\EventListener\BlameListener
stof_doctrine_extensions.listener.blameable App\EventListener\BlameListener
How can I use my own blameable listner?
Related
I want to configure the Doctrine bundle to have a DBAL connection. For some reason the configuration needs a bit of logic to retrieve. I tried to use a container extension and then a compiler pass to execute the logic while the container is compiled and store the configuration as container parameters.
During my attempts, I registered the extension and compiler pass like this in the Kernel class:
protected function build(ContainerBuilder $container)
{
// Those lines weren't there at the same time
$container->registerExtension(new MyCustomExtension());
$container->addCompilerPass(new MyCustomCompilerPass());
}
It seemed to work well as I could see my parameters in the console:
# ./bin/console debug:container --parameters
Symfony Container Parameters
============================
------------------------------------------------------------- ------------------------------------------------------------------------
Parameter Value
------------------------------------------------------------- ------------------------------------------------------------------------
...
some.prefix.host some-mariadb-host
some.prefix.dbname some-database-name
...
The problem is that when I try to use those parameters in my config/packages/doctrine.yaml I get an error on my next console command:
doctrine:
dbal:
driver: pdo_mysql
host: '%some.prefix.host%'
dbname: '%some.prefix.dbname%'
# ...
# ./bin/console debug:container --parameters
In ParameterBag.php line 98:
You have requested a non-existent parameter "some.prefix.host".
I am using Symfony 5.3 and Doctrine bundle 2.4.
Why do my parameters seem inaccessible for 3rd party bundle configuration ?
How can I make this work ?
Is there a better way to achieve this ?
I think the Doctrine bundle configuration gets processed before my compiler pass can declare the parameters. It probably can't be solved using the DependencyInjection component.
Solved it by importing a PHP configuration file in the services.yaml:
imports:
- { resource: my_custom_file.php }
With the following content:
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return function(ContainerConfigurator $configurator) {
// My specific logic
// Saving the configuration as parameters
$configurator->parameters()->set('some.prefix.host', $host);
$configurator->parameters()->set('some.prefix.dbname', $dbname);
// ...
};
I have changed the configuration of my Symfony project to use PHP attributes with Doctrine in my Entities. I was really happy about this and wanted to give it a try.
I have changed my doctrine.yaml from annotation to attribute
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
App:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
and use attributes in my entities
#[ORM\Entity(UserRepository::class)]
class User implements UserInterface
{
#[ORM\Id()]
#[ORM\GeneratedValue()]
#[ORM\Column(type: "integer")]
private ?int $id;
#[ORM\Column(type: "string", length: 180, unique: true)]
private ?string $email;
#[ORM\Column(type: "json")]
private array $roles = [];
}
With this configuration my php bin/console do:sc:up -f works well.
But when I try to generate a new entity with php bin/console make:entity I get this error:
[ERROR] Only annotation mapping is supported by make:entity, but the
App\Entity\Toto class uses a different
format. If you would like this command to generate the properties & getter/setter methods, add your mapping
configuration, and then re-run this command with the --regenerate flag.
It seems like it's not possible yet to use maker to generate entity with attribute.
Does anyone have found a way to fix this issue or do we just have to wait a new release?
For now I'm using:
"doctrine/annotations": "1.13.1"
"doctrine/doctrine-bundle": "2.4.2",
"doctrine/orm": "2.9.3"
"symfony/maker-bundle": "1.31.1",
Currently, it's not supported. There is an issue created asking for this, although I'm 120% sure that the developers already know about PHP attributes, and this feature will get done whenever possible.
In the meantime, you can create your entities manually, without using maker (not that hard), or even use something like Rector to convert Annotations to Attributes. There is a built-in rule for that.
Hello, i need to explain what i'm was doing at first:
I was on a project and for some reason I ended up having to use two databases instead of just one. so i do what it was needed to do, i change my doctrine.yaml settings with what is explain in the symfony doc and in that moment the error appeared
An SQL error that says that it was no column found for X request on X table
(the error is SQLSTATE[42S02], but it's not important)
(in parallel of that error i need to say that the "--em" shit didn't work for me when i do php bin/console doctrine:migrations:diff/migrate --em=default or customer so i does indeed php bin/console doctrine:schema:update --force --em=default or customer and i don't know why ! so if you have something to say here i'll take it too.)
Anyway i go back to what i was explaining,
This sql error appear because of my controller, they working with default Repository implementation (MyClassNameRepository $myClasNameReposiotry for an exemple) that was normaly implement the default EntityManager but it doesn't and that throw this error.
At this point i though that i had an error in some files in symfony because of a shit i probably does. I don't have the time for replacing all the repository implementation, soo i create a new project with the doctrine config that is needed for working with two database according to the symfony doc. Is the same as the One in my project :
doctrine:
dbal:
default_connection: default
connections:
default:
# configure these for your database server
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
customer:
# configure these for your database server
url: '%env(resolve:DATABASE_CUSTOMER_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
orm:
entity_managers:
default:
connection: default
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: Main
customer:
connection: customer
mappings:
Customer:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Customer'
prefix: 'App\Entity\Customer'
alias: Customer
That is the same config than the one in symfony doc except for the Main dir.
i created my entities, one in each database and i does a crud on them.
The Hierarchy files:
src/
-----Entity/
----Product
----Customer/
-ProductCustomer
-----Repository/
----ProductRepository
----Customer/
-----ProductCustomerRepository
And same for the form
And with this testApplication i saw a new error, for the customer part i had the same sql error, because the column was searched in the wrong bdd, after changing the code for :
this
/**
* #Route("/", name="customer_produit_customer_index", methods={"GET"})
*/
public function index(ProductCustomerRepository $productCustomerRepository): Response
{
return $this->render('customer/produit_customer/index.html.twig', [
'produit_customers' => $productCustomerRepository->findAll(),
]);
}
to this
/**
* #Route("/", name="customer_produit_customer_index", methods={"GET"})
*/
public function index(): Response
{
$productCustomers = $this->getDoctrine()
->getRepository(ProduitCustomerRepository::class, "customer")
->findAll()
;
return $this->render('customer/produit_customer/index.html.twig', [
'produit_customers' => $productCustomers,
]);
}
The error has changed, as I expected and know i have :
The class 'App\Repository\Customer\ProduitCustomerRepository' was not found in the chain configured namespaces App\Entity\Customer
No matter how much I search the internet, I can't find anything that really solves my mistakes. Now I'm tired of looking, especially since I don't understand these errors because it's not the first time I've set up an application connected to two databases, but it's the first time that I have these errors.
So please help me =D.
I am trying to use different cache system on my environments. I would like to have, for example, Filesystem for dev and memcached for prod.
I am using symfony 3.3.10.
To achieve this, I would like to autowire the CacheInterface as follow:
use Psr\SimpleCache\CacheInterface;
class Api {
public function __construct(CacheInterface $cache)
{
$this->cache = $cache;
}
}
Here are my configuration files:
config_dev.yml:
framework:
cache:
app: cache.adapter.filesystem
config_prod.yml:
framework:
cache:
app: cache.adapter.memcached
...
Here is the error I get:
The error disappears when the FilesystemCache is declared as a service:
services:
Symfony\Component\Cache\Simple\FilesystemCache: ~
But now I cannot have another cache system for the test environment like NullCache. In fact, I have to declare only one service inheriting from CacheInterface. It is not possible as config_test is using config_dev too.
This is the beginning of services.yml if it can help:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Any idea on how to autowire different cache system depending on the environment?
EDIT:
Here is the working configuration:
use Psr\Cache\CacheItemPoolInterface;
class MyApi
{
/**
* #var CacheItemPoolInterface
*/
private $cache;
public function __construct(CacheItemPoolInterface $cache)
{
$this->cache = $cache;
}
}
config.yml:
framework:
# ...
cache:
pools:
app.cache.api:
default_lifetime: 3600
services.yml:
# ...
Psr\Cache\CacheItemPoolInterface:
alias: 'app.cache.api'
Even though factory pattern is a good option to solve this kind of problem, normally you don't need to do that for Symfony cache system. Typehints CacheItemPoolInterface instead:
use Psr\Cache\CacheItemPoolInterface;
public function __construct(CacheItemPoolInterface $cache)
It automatically injects the current cache.app service depending on the active environment, so Symfony does the job for you!
Just make sure to configure the framework.cache.app for each environment config file:
# app/config/config_test.yml
imports:
- { resource: config_dev.yml }
framework:
#...
cache:
app: cache.adapter.null
services:
cache.adapter.null:
class: Symfony\Component\Cache\Adapter\NullAdapter
arguments: [~] # small trick to avoid arguments errors on compile-time.
As cache.adapter.null service isn't available by default, you might need to define it manually.
In Symfony 3.3+/4 and 2017/2019 you can omit any config dependency and keep full control of the behavior with factory pattern:
// AppBundle/Cache/CacheFactory.php
namespace AppBundle\Cache;
final class CacheFactory
{
public function create(string $environment): CacheInterface
{
if ($environment === 'prod') {
// do this
return new ...;
}
// default
return new ...;
}
}
And services.yml of course:
# app/config/services.yml
services:
Psr\SimpleCache\CacheInterface:
factory: 'AppBundle\Cache\CacheFactory:create'
arguments: ['%kernel.environment%']
See more about service factory in Symfony Documentation.
You can read more about this in my Why Config Coding Sucks post.
After creating entity with:
php app/console doctrine:generate:entity
and while using:
php app/console doctrine:schema:update --force
I encountered:
No Metadata Classes to process.
Entity
namespace ISLab\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="menu_items")
*/
class MenuItem
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="parent", type="integer")
*/
private $parent;
// ...
}
I had a similar problem and took me a while until I find out how to clear out the cache. Clearing only doctrine's cache did not work for me. Use the command below to clear the entire environment (production one in this case)
php app/console cache:clear --env=prod
I had the same problem when I generate an Entity through the interactive generator from command line. When I first created I set the Configuration Format to PHP and that didn't work. So I deleted it and tried again but this time I selected format = annotation. Then it worked! Maybe this could solve someone's problem.
So entity manager didn't create metadata for your entity. Here are things I would check first:
Clear your cache
Make sure your AdminBundle is registered in AppKernel.
Make sure that entity manager's automapping is true. Or set it up correctly if you're using custom EM.
A bit offtopic:
I see you're making a menu system and I would strongly suggest you to check out Doctrine Extensions Tree which should allow you to query and edit items much more efficiently than with your structure.
I had the same problem when i update the database.
So i follow this solution and i tried to adapt in my case and it works.
I think that is a problem of automapping indeed also with auto_mapping setted true, symfony wasn't able to find the entities.
I hope that it can help.
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
AppBundle:
type: annotation
is_bundle: false
dir: %kernel.root_dir%/../src/AppBundle/Entity/
prefix: AppBundle\Entity
alias: AppBundle
for anyone on the same thing, these are few steps to go:
1. Clear the cache:
bin/console c:c --env=dev
bin/console c:c --env=prod
If you see any errors meanwhile, try to cover it by inspecting source of problem.
2. Inspect your configuration:
According to this sample directory structure:
Application
|
└- src
|
└- Acme
|
└- Bundle
|
└- BlogBundle
|
└- Model
|
└- Entity
You should have this configuration inside your app/config/config.yml file:
doctrine:
...
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
AcmeBlogBundle:
mapping: true
type: annotation
dir: Model/Entity
alias: Blog
prefix: Acme\Bundle\BlogBundle\Model\Entity
is_bundle: true
3. Update your database schema:
You can now update your database schema without any problems:
bin/console doctrine:schema:update
despite of this being the final step for most cases, you may still use --verbose to find any further possible problems.
bin/console doctrine:schema:update --verbose
Make sure your entities are placed in your bundle's Entity directory. In my case they were in Entities instead.
For me generating all the entities from the cmd did the work.
In my case, i solve the problem creating the Entity folder. For some reason it had been eliminated. I hope that it can help.
I've had the same issue. For me it was that my directory called 'Entity' was not in the 'AppBundle' but in the 'src' directory. Moving the 'Entity' directory into the 'AppBundle' directory fixed the problem for me!