Doctrine - Set $id as UUID instead of Integer when creating new entity - doctrine

I am working on a new project in Symfony 5.3. I am using this command bin/console make:entity for creating entities.
This wizard automatically creates an entity with $id as primary key of type integer. I am prefering UUID instead of integer.
How I should change settings to get Entity like this?
Thank you
namespace App\Entity;
use App\Repository\EventRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
/**
* #ORM\Entity(repositoryClass=EventRepository::class)
*/
class Event
{
/**
* #ORM\Id
* #ORM\Column(type="uuid", unique=true)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class=UuidGenerator::class)
*/
private $id;
...
}

There is no option to set the generated identifier strategy on make entity.
You can see all available option using php bin/console make:entity -h
Also there are no configuration in doctrine.yaml file to define this.
It could be a good feature to add for current and next version
To request a new feature, you can create a new issue feature request type:
https://github.com/symfony/symfony/issues/new/choose
You will need a github account

Related

"AuthenticatorInterface" not found on Security\Guard, Symfony 6.2

I'm trying to create a custom Token authenticator for my Symfony 6.2 and API Platform project
class TokenAuthenticator extends JWTTokenAuthenticator
{
/**
* #param PreAuthenticationJWTUserToken $preAuthToken
* #param UserProviderInterface $userProvider
* #return UserInterface
*/
public function getUser($preAuthToken, UserProviderInterface $userProvider): UserInterface
{
$user = parent::getUser($preAuthToken, $userProvider);
var_dump($preAuthToken->getPayload());exit;
}
}
But I always get this error:
Attempted to load interface "AuthenticatorInterface" from namespace "Symfony\Component\Security\Guard".
Did you forget a "use" statement for "Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface"?
that means, there's no AuthenticatorInterface on Security\Guard and Http\Authenticator replaces it, so the LexikJWTAuthenticationBundle must be updated to include the new change.
This new class contains new functions so is there any documentation regarding them? Also, the purpose of establishing this class TokenAuthenticator is to make the old token invalid when changing the password, so is there a better way to do this?

Unable to find "Proxies\__CG__\App\Entity\EnseigneNationale" entity identifier associated with the UnitOfWork

Client.php
/**
* #ORM\ManyToOne(targetEntity="EnseigneNationale", inversedBy="clients")
* ...
*/
private ?EnseigneNationale $enseigneNationale;
/**
* #ORM\OneToMany(targetEntity="ClientBanque", mappedBy="client", cascade={"persist", "remove"})
* ...
*/
private ?Collection $clientBanques;
My data comes from an old database, I have to create a command that corrects some data in the database.
if (Condition) {
/** #var ClientBanque $clientBanque */
$clientBanque = $clientBanques[0];
$clientBanque->setAA($aa);
$this->manager->persist($client);
}
When I persist, I got the error saying that doctrine unable to find "EnseigneNationale", that it can be nullable and I m not using it in my persist changes.
Somthing wrong with my code ?? Help Please
PHP : 7.4
Symfony : 5.3
Doctrine : 2.4
It was me !! Sorry for disturb, I was adding $manger->clear() who breaks everything
What is happening is basically you've detached your object from entity manager. The object was removed from the identity map and is no longer managed by this entity manager.
You can attach the object back by calling $managedCopy = $em->merge($object);
Pay attention to the fact that merge returns a new object.
The state of the passed entity will be merged into a managed copy of this entity and this copy will subsequently be returned.

Use entities from composer package in api platform

As we use the entities in multiple projects we have required our entities via composer.
All the stuff that would normally be in the annotations I have written into a yaml file.
But I don't get any routes shown in the frontend or the swagger documentation.
I have found the following configuration: api_platform.resource_class_directories
But you have to set a directory there. I would not really like to have a hardcoded path like vendor/my-company/my-entity-package/src/Entity.
So how do I solve this issue?
Is there a magic variable in symfony like the %kernel.project_dir% which points to the vendor directory?
Did I forget to set some configuration?
I was able to get this working by extending the classes of my composer package.
So in api/src/Entity/Order.php I have the following:
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Company\ComposerPackage\Entity\Order as ComposerOrder;
use Doctrine\ORM\Mapping as ORM;
/**
* #ApiResource()
* #ORM\Entity
*/
class Order extends ComposerOrder
{
/**
* #var int The id of this order entity.
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
}
For some reason api-platform was not recognizing the id property and it's annotations so I had to copy it to the child class.
The entity in the composer package also needed a change for this to work:
namespace Company\ComposerPackage\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\MappedSuperclass
*/
class Order
{
// all properties are defined here including the #ORM, #Assert etc. annotations
}
I had to add the #ORM\MappedSuperclass annotation.
The #ORM\HasLifecycleCallbacks annotation also had to be done in the childclass for some reason. Also if you have additional configuration for the table e.g. table name or unique constraints these also have to be added to the child class.

Doctrine + CodeIgniter: after generate entities with namespace, "cannot redeclare class" on schema create

I'm trying to generate both entities and the database schema with Doctrine under CodeIgniter 2.0, using annotations. I'm not sure if I'm doing this correctly.
I've setup base classes which have only the classname and properties defined, and then annotated. I'm trying to use the generate-entities command to have it create the get/set methods.
<?php
namespace Entities;
include('ContentItem.php');
/**
* #Entity
* #Table(name="blobs")
*/
class Blob extends ContentItem {
/**
* #var ContentItemId
*
* #ManyToOne(targetEntity="ContentItem")
* #JoinColumn(name="contentitem_id", referencedColumnName="id")
*/
protected $contentitem;
/**
* #Column(type="string", length=64, nullable=true)
*/
protected $content;
/**
* #Column(name="date_created", type="datetime", nullable=false)
*/
protected $date_created;
/**
* #Column(type="datetime", nullable=false)
*/
protected $date_updated;
}
This file is located in a folder named 'models'. If I run the command 'orm:generate-entities models', then it creates new classes inside of '/models/Entities' folder. This only happens because of the 'namespace Entities' declaration. If I run 'orm:schema-tool:create' to try and create my database schema, I get: "Fatal error: Cannot redeclare class Entities\Blob in /Users/rw3iss/Sites/ci/application/models/Entities/Blob.php on line 11".
This is happening because the generated 'models/Entities' classes inherit the namespace from the files they're generated from in the parent 'models' folder, hence the dual class conflict.
Now if I remove the namespace declaration from the parent files, and call generate entities, passing 'models/Entities' as the destination, I get the same file layout. Except then, when trying to use the models in my code:
$blob = new Entities\Blob;
this throws the same error, obviously because there are still two classes with the same name, without a namespace.
I have declared the Entities class loader like this:
$entityClassLoader = new \Doctrine\Common\ClassLoader('Entities', APPPATH.'models');
So my question is:
Is there anyway to generate these entity classes from a basic class (which has my annotations declared for the class and properties), preserving namespaces, so that I can still instantiate them using 'new Entities\Blob'? If there was even a way to tell the generated classes to use a different namespace from the file's they're generated from, that would be fine. I'd like to setup basic properties, and have the 'generate entities' command create my get/set methods for me. It seems that whenever I use namespaces, it will auto-create the classes inside of the namespace subfolders, and then I get the 'cannot redeclare class' error.
Maybe I'm doing something fundamentally wrong...
Thanks for any help!
UPDATE: Solution:
I may have gotten it working by putting the Entities folder side by side with my models folder. If I change the Entities ClassLoader to point to just 'APPPATH', and then instantiate my Entities using 'new Entities\Blob', then that works.
It seems like there is no way to put the Entities folder as a subfolder within the models folder without it complaining in some way. If anyone know of a way to do this, I'd be interested to hear.
i got the same problem. That's because you specify a subfolder in the command.
Just type : "orm:generate-entities ." (without quotes)
"." is meaning actual folder.
I have this working with entities and models in two different subfolders. Here is how i processed :
my files structure :
+ framework (root folder)
index.php
+ entities (model folder)
Formation.php
+ repositories (repositories folder)
FormationRepository.php
+ controllers ( controllers folder)
HomeController.php
in index.php :
require 'vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php';
$entitiesLoader = new ClassLoader('entities', __DIR__);
$entitiesLoader->setFileExtension('.php'); // not necessary, i think that .php is set by default
$entitiesLoader->register();
// registering entities repositories classloader
$repositoriesLoader = new ClassLoader('entities\repositories', __DIR__);
$repositoriesLoader->setFileExtension('.php');
$repositoriesLoader->register();
here is an entity : (Formation.php)
// Formation.php
<?php
namespace entities;
/**
* #Entity(repositoryClass="entities\repositories\FormationRepository")
* #Table(name="formations")
*/
class Formation
{
....
here is how i use it : (in HomeController.php)
// in HomeController.php
<?php
// if i need it directly :
use entities\Formation;
$formation = new Formation();
// if i want to use it with its repository (and Doctrine)
$formation = $this->getApp()->getDbConnection()->getRepository('entities\Formation')->findOneById(1);
pay attention to "getRepository('entities\Formation')". My mistake was to not specifying the namespace "entities\" before the name of the entity.

Symfony2 custom validator

i am trying to build an custom validator with symfony2 but something strange happens:
i have created both Password and PasswordValidate by following the steps in symfony2 cookbook but first time when i load the page i get this error:
AnnotationException: [Semantical Error] The annotation "#Symfony\Component\Validator\Constraints\Password" in property NMSP\MyBundle\Entity\User::$password does not exist, or could not be auto-loaded.
after reloading the error disappears and the validation still not fires and it return the code is valid.
here is the relevant code:
//annotation declaration:
/**
* #ORM\Column(type="string", length="32", unique="true")
*
* #Assert\MinLength(3)
* #Assert\Password2()
*/
protected $password;
//load files with the following in the code
services:
validator.password:
class: NMSP\MyBundle\Validator\PasswordValidator
tags:
- { name: validator.constraint_validator, alias: password }
can`t figure this one out:(
Assuming your custom validator constraint is not in the Symfony\Component\Validator\Constraints namespace, but your own namespace: NMSP\MyBundle\Validator.
You should add the following use statement:
use NMSP\MyBundle\Validator as NMSPAssert;
Then use the following annotation on the $username property:
#NMSPAssert\Password()
That should do it.

Resources