How to convert symfony gedmo annotation to PHP 8 Attributes - php

I'm working on Symfony 6 PHP 8 project and i'm using gedmo doctrine extension .
I can't find a full documentation about converting gedmo annotation to PHP 8 Attributes.
I'm tring to convert like this :
/**
* #ORM\Column(type="string", length=255)
* #Gedmo\Slug(fields={"title"})
*/
private $slug;
#[Gedmo\Slug(fields: title)]
but it doesn't work !
How can i use gedmo with PHP 8 Attributes ?

Rector supports this. The rule comes from rector-doctrine, which is included with the standard install method.
Follow the rector install guide and edit the rector.php config to add the required rules.
Rector also has rule sets for updating Symfony to see rector-symfony.
Example of converting the Doctrine and Gedmo annotation to PHP 8 attributes.
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([
DoctrineSetList::DOCTRINE_CODE_QUALITY,
DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
DoctrineSetList::GEDMO_ANNOTATIONS_TO_ATTRIBUTES,
]);
};
e.g. converts this
/**
* #Gedmo\Slug(fields={"title"})
* #ORM\Column(length=128, unique=true)
*/
private $slug;
to
#[ORM\Column(length: 128, unique: true)]
#[Gedmo\Slug(fields: ['title'])]
private $slug;

you'll have to do the whole class property with attributes.
the fields property at slug needs to be an array.
#[\Gedmo\Mapping\Annotation\Slug(fields: ['name'])]
#[\Doctrine\ORM\Mapping\Column(
type: 'string',
length: 255,
)]

Related

Is there a replacement for the Doctrine Gedmo-Extension (Timestampable, Softdeletable ...) in Symfony 5?

With prior versions of Symfony (<5), it was possible to automatically populate DateTime-fields on creation or when updating existing entries.
Example:
/**
* #var \DateTime $createdAt
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $createdAt;
These annotations do not seem to have any effect if applied onto an Entity in a Symfony5 project. Has a replacement for the Gedmo-extension been released or is there a workaround to be used to avoid manually setting data fields with a current timestamp?
Editing /config/packages/stof_doctrine_extensions.yaml did the trick. I had to activate the timestampable-listener:
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
tree: true
timestampable: true
softdeleteable: true

JMS serializer. How to use Exclude condition?

i'm using JMS serializer in my symfony project and i have a question about "Exlude condition". Is it possible to specify that one property of entity would be exlude for all routes (methods) exept one.
I mean something like this:
/**
* #var string
*
* #ORM\Column(name="full_name", type="text", nullable=true)
* #JMS\Exlude(if="!someAction()")
*/
private $fullName;
If this possible, what is the correct syntax for this? Thanks)
To utilize #Exclude annotation, you need to have a bit of Symfony's ExpressionLanguage understanding.
Obviously, the function used in the annotation (e.g. someAction()) does not belong to the current object but rather to Expression language instance. To register it, do the following:
$language = new ExpressionLanguage();
$language->register('someAction', function(){}, function ($arguments, $object) {
// your logic goes here
return false;
});
Then bind it to your serializer:
$serializer = SerializerBuilder::create()
->setExpressionEvaluator(new ExpressionEvaluator($language))
->build();
Then you should be able to serialize using this exclusion strategy:
/**
* #var string
*
* #ORM\Column(name="full_name", type="text", nullable=true)
* #JMS\Exlude(if="!someAction(object)")
*/
private $fullName;
The one thing I am unsure of is passing empty callable to register call (for compiler) and I have no means of giving it a spin and confirming that is valid.
Hope this helps...

Doctrine MongoDB rename reference field

I have the following reference in my class:
/**
* #Expose
* #Groups({"personal"})
*
* #MongoDB\ReferenceMany(targetDocument="AppBundle\Document\Correspondence", cascade={"remove"})
*/
protected $archiveCorrespondences;
And I want to save this reference in my database under the name archive_correspondences
But whatever I did, doctrine always keeps it under archiveCorrespondences
I use the following:
php 7
mongodb 3.2
symfony 2.8
doctrine/mongodb-odm : dev-master
doctrine/mongodb-odm-bundle: dev-master
From the doctrine mongodb documentation I did't find any possibilities, like for #Field annotation, where you can specify name.
By some reasons I can't rename $archiveCorrespondences to $archive_correspondences in code.
I suggest you to try name property. It should work for ReferenceMany:
/**
* #Expose
* #Groups({"personal"})
*
* #MongoDB\ReferenceMany(name="archive_correspondences", targetDocument="AppBundle\Document\Correspondence", cascade={"remove"})
*/
protected $archiveCorrespondences;

Symfony2 Override Constraints

I have BaseEntity class:
class BaseEntity
{
/**
* The name.
*
* #var string
*
* #ORM\Column(name="name", type="string", length=255, unique=true, nullable=false)
* #Assert\Length(min=2, max=255, minMessage="default.name.short", maxMessage="default.name.long")
* #Assert\NotBlank(message = "default.name.not_blank")
*/
private $name;
}
and
class UserEntity extends BaseEntity
{
/**
* {#inheritDoc}
*
* #Assert\Length(min=2, max=255, minMessage="user.name.short", maxMessage="default.name.long")
* #Assert\NotBlank(message = "user.name.not_blank")
*/
private $name;
}
Now, When I post a new UserEntity into the form with long or short name Symfony gives me 2 errors: (for long:)
default.name.long
user.name.long
But I want it to show only ONE error, so :
- user.name.long
e.g. I want to override, but do not add another one
I think what you are looking for a validator group. So you can split up you validation rules into groups.
There is a excellent documentation about this feature:
http://symfony.com/doc/current/validation/groups.html
Maybe a Custom Validation Constraint could help you if you could (depending of your application logic) remove those two validations and make your own.
Something like this maybe?
http://symfony.com/doc/current/cookbook/validation/custom_constraint.html
If you're happy to set up at least some of your validation rules via a YAML file rather than annotations, you can override the base class's validation settings without needing to edit the class file itself.
Your YAML file would look something like this and would need to be in a location like src/YourApp/YourBundle/Resources/config/validation.yml to be picked up automatically:
BaseEntity:
properties:
name:
- NotBlank:
message: user.name.not_blank
- Length:
min: 2
minMessage: user.name.short
max: 255
maxMessage: default.name.long
If you want to put your validation file in a non-standard location, see https://stackoverflow.com/a/24210501/328817

Doctrine 2 annotations and "var"

Could someone tell me whats the meaning of "#var" in annotations configuration?
For example:
/**
* #Column(type="string", length=20, unique=TRUE)
* #var string
*/
protected $login;
It tells you what type of variable is it. Whether it's integer, string or an object, for example. It's used for auto-documentating processes
This is an annotation used for automatic documentation generation with phpDocumentor. For #var see their documentation.

Categories