Skip to content

Commit

Permalink
Allow DoctrineExtensions to be configured to use attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
mbabker authored and phansys committed Nov 5, 2023
1 parent 1d367c1 commit 0af12a0
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 46 deletions.
37 changes: 37 additions & 0 deletions example/app/Entity/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

namespace App\Entity;

use App\Entity\Repository\CategoryRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

Expand All @@ -23,13 +25,20 @@
*
* @Gedmo\TranslationEntity(class="App\Entity\CategoryTranslation")
*/
#[Gedmo\Tree(type: 'nested')]
#[ORM\Table(name: 'ext_categories')]
#[ORM\Entity(repositoryClass: CategoryRepository::class)]
#[Gedmo\TranslationEntity(class: CategoryTranslation::class)]
class Category
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
#[ORM\Column(type: Types::INTEGER)]
#[ORM\Id]
#[ORM\GeneratedValue]
private $id;

/**
Expand All @@ -39,6 +48,8 @@ class Category
*
* @ORM\Column(length=64)
*/
#[Gedmo\Translatable]
#[ORM\Column(length: 64)]
private $title;

/**
Expand All @@ -48,6 +59,8 @@ class Category
*
* @ORM\Column(type="text", nullable=true)
*/
#[Gedmo\Translatable]
#[ORM\Column(type: Types::TEXT, nullable: true)]
private $description;

/**
Expand All @@ -58,20 +71,27 @@ class Category
*
* @ORM\Column(length=64, unique=true)
*/
#[Gedmo\Translatable]
#[Gedmo\Slug(fields: ['created', 'title'])]
#[ORM\Column(length: 64, unique: true)]
private $slug;

/**
* @Gedmo\TreeLeft
*
* @ORM\Column(type="integer")
*/
#[Gedmo\TreeLeft]
#[ORM\Column(type: Types::INTEGER)]
private $lft;

/**
* @Gedmo\TreeRight
*
* @ORM\Column(type="integer")
*/
#[Gedmo\TreeRight]
#[ORM\Column(type: Types::INTEGER)]
private $rgt;

/**
Expand All @@ -80,53 +100,69 @@ class Category
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
*/
#[Gedmo\TreeParent]
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
#[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
private $parent;

/**
* @Gedmo\TreeRoot
*
* @ORM\Column(type="integer", nullable=true)
*/
#[Gedmo\TreeRoot]
#[ORM\Column(type: Types::INTEGER, nullable: true)]
private $root;

/**
* @Gedmo\TreeLevel
*
* @ORM\Column(name="lvl", type="integer")
*/
#[Gedmo\TreeLevel]
#[ORM\Column(name: 'lvl', type: Types::INTEGER)]
private $level;

/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
#[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')]
private Collection $children;

/**
* @Gedmo\Timestampable(on="create")
*
* @ORM\Column(type="datetime")
*/
#[Gedmo\Timestampable(on: 'create')]
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private $created;

/**
* @Gedmo\Timestampable(on="update")
*
* @ORM\Column(type="datetime")
*/
#[Gedmo\Timestampable(on: 'update')]
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private $updated;

/**
* @Gedmo\Blameable(on="create")
*
* @ORM\Column(type="string")
*/
#[Gedmo\Blameable(on: 'create')]
#[ORM\Column(type: Types::STRING)]
private $createdBy;

/**
* @Gedmo\Blameable(on="update")
*
* @ORM\Column(type="string")
*/
#[Gedmo\Blameable(on: 'update')]
#[ORM\Column(type: Types::STRING)]
private $updatedBy;

/**
Expand All @@ -136,6 +172,7 @@ class Category
* cascade={"persist", "remove"}
* )
*/
#[ORM\OneToMany(targetEntity: CategoryTranslation::class, mappedBy: 'object', cascade: ['persist', 'remove'])]
private $translations;

public function __construct()
Expand Down
7 changes: 6 additions & 1 deletion example/app/Entity/CategoryTranslation.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,21 @@
* })}
* )
*/
#[ORM\Entity]
#[ORM\Table(name: 'category_translations')]
#[ORM\UniqueConstraint(name: 'lookup_unique_idx', columns: ['locale', 'object_id', 'field'])]
class CategoryTranslation extends AbstractPersonalTranslation
{
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="translations")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
*/
#[ORM\ManyToOne(targetEntity: Category::class, inversedBy: 'translations')]
#[ORM\JoinColumn(name: 'object_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
protected $object;

/**
* Convinient constructor
* Convenient constructor
*
* @param string $locale
* @param string $field
Expand Down
64 changes: 43 additions & 21 deletions example/em.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use Gedmo\Blameable\BlameableListener;
use Gedmo\DoctrineExtensions;
use Gedmo\Mapping\Driver\AttributeReader;
use Gedmo\Sluggable\SluggableListener;
use Gedmo\Timestampable\TimestampableListener;
use Gedmo\Translatable\TranslatableListener;
Expand Down Expand Up @@ -65,12 +67,23 @@
// For larger applications, you may use multiple cache pools to store cacheable data in different locations.
$cache = new ArrayAdapter();

// Build the annotation reader for the application,
// by default we will use a decorated reader supporting a backend cache.
$annotationReader = new PsrCachedReader(
new AnnotationReader(),
$cache
);
$annotationReader = null;
$extensionReader = null;

// For PHP 8, we will provide the extensions an attribute reader, while PHP 7 will require the annotation reader
// (which will only be created when `doctrine/annotations` is installed)
if (PHP_VERSION_ID >= 80000) {
$extensionReader = new AttributeReader();
}

// Build the annotation reader for the application when the `doctrine/annotations` package is installed.
// By default, we will use a decorated reader supporting a backend cache.
if (class_exists(AnnotationReader::class)) {
$extensionReader = $annotationReader = new PsrCachedReader(
new AnnotationReader(),
$cache
);
}

// Create the mapping driver chain that will be used to read metadata from our various sources.
$mappingDriver = new MappingDriverChain();
Expand All @@ -83,46 +96,55 @@
);

// Register the application entities to our driver chain.
// Our application uses Annotations for mapping, but you can also use XML.
$mappingDriver->addDriver(
new AnnotationDriver(
$annotationReader,
[__DIR__.'/app/Entity']
),
'App\Entity'
);
// Our application uses Annotations or Attributes for mapping, but you can also use XML.
if (PHP_VERSION_ID >= 80000) {
$mappingDriver->addDriver(
new AttributeDriver(
[__DIR__.'/app/Entity']
),
'App\Entity'
);
} else {
$mappingDriver->addDriver(
new AnnotationDriver(
$annotationReader,
[__DIR__.'/app/Entity']
),
'App\Entity'
);
}

// Next, we will create the event manager and register the listeners for the extensions we will be using.
$eventManager = new EventManager();

// Sluggable extension
$sluggableListener = new SluggableListener();
$sluggableListener->setAnnotationReader($annotationReader);
$sluggableListener->setAnnotationReader($extensionReader);
$sluggableListener->setCacheItemPool($cache);
$eventManager->addEventSubscriber($sluggableListener);

// Tree extension
$treeListener = new TreeListener();
$treeListener->setAnnotationReader($annotationReader);
$treeListener->setAnnotationReader($extensionReader);
$treeListener->setCacheItemPool($cache);
$eventManager->addEventSubscriber($treeListener);

// Loggable extension, not used in example
// $loggableListener = new Gedmo\Loggable\LoggableListener;
// $loggableListener->setAnnotationReader($annotationReader);
// $loggableListener->setAnnotationReader($extensionReader);
// $loggableListener->setCacheItemPool($cache);
// $loggableListener->setUsername('admin');
// $eventManager->addEventSubscriber($loggableListener);

// Timestampable extension
$timestampableListener = new TimestampableListener();
$timestampableListener->setAnnotationReader($annotationReader);
$timestampableListener->setAnnotationReader($extensionReader);
$timestampableListener->setCacheItemPool($cache);
$eventManager->addEventSubscriber($timestampableListener);

// Blameable extension
$blameableListener = new BlameableListener();
$blameableListener->setAnnotationReader($annotationReader);
$blameableListener->setAnnotationReader($extensionReader);
$blameableListener->setCacheItemPool($cache);
$blameableListener->setUserValue('MyUsername'); // determine from your environment
$eventManager->addEventSubscriber($blameableListener);
Expand All @@ -134,13 +156,13 @@
// but most importantly, it must be set before the entity manager is flushed.
$translatableListener->setTranslatableLocale('en');
$translatableListener->setDefaultLocale('en');
$translatableListener->setAnnotationReader($annotationReader);
$translatableListener->setAnnotationReader($extensionReader);
$translatableListener->setCacheItemPool($cache);
$eventManager->addEventSubscriber($translatableListener);

// Sortable extension, not used in example
// $sortableListener = new Gedmo\Sortable\SortableListener;
// $sortableListener->setAnnotationReader($annotationReader);
// $sortableListener->setAnnotationReader($extensionReader);
// $sortableListener->setCacheItemPool($cache);
// $eventManager->addEventSubscriber($sortableListener);

Expand Down
Loading

0 comments on commit 0af12a0

Please sign in to comment.