diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c667a42 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [2.0.2] - 2022-06-29 +### Added +- More documentation and examples +- Changelog + +### Fixed +- Translation not being properly removed with setTranslations(). + +## [2.0.1] - 2022-06-29 +### Added +- Translatable behaviour +- More tests +- Github action to automatically run tests + +## [2.0.0] - 2022-06-15 +### Changed +- Timestampable columns createdAt and updatedAt are no longer nullable. + +## [1.0.1] - 2022-05-18 +### Added +- Timestampable subscriber to automatically add entity listener to timestampable entities. + +[Unreleased]: https://github.com/Cloudstek/doctrine-behaviour/compare/v2.0.2...develop +[2.0.2]: https://github.com/Cloudstek/doctrine-behaviour/compare/v2.0.1...v2.0.2 +[2.0.1]: https://github.com/Cloudstek/doctrine-behaviour/compare/v2.0.0...v2.0.1 +[2.0.0]: https://github.com/Cloudstek/doctrine-behaviour/compare/v1.0.1...v2.0.0 +[1.0.1]: https://github.com/Cloudstek/doctrine-behaviour/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.com/Cloudstek/doctrine-behaviour/releases/tag/v1.0.0 diff --git a/README.md b/README.md index 1b78dd6..82a6e87 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ # Cloudstek Doctrine Behaviour +[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fcloudstek%2Fdoctrine-behaviour%2Fbadge%3Fref%3Dmain&style=flat)](https://github.com/Cloudstek/doctrine-behaviour/actions) [![issues](https://img.shields.io/github/issues/cloudstek/doctrine-behaviour)](https://github.com/Cloudstek/doctrine-behaviour/issues) [![license](https://img.shields.io/github/license/cloudstek/doctrine-behaviour)](https://github.com/Cloudstek/doctrine-behaviour/blob/main/LICENSE) [![dependencies](https://img.shields.io/librariesio/github/cloudstek/doctrine-behaviour)](https://libraries.io/packagist/cloudstek%2Fdoctrine-behaviour) [![downloads](https://img.shields.io/packagist/dt/cloudstek/doctrine-behaviour)](https://packagist.org/packages/cloudstek/doctrine-behaviour) + > Library of different entity behaviours (timestampable etc.) ## Requirements - PHP 8.1+ - Doctrine ORM 2 +- intl extension ## Installation @@ -13,35 +16,20 @@ $ composer require cloudstek/doctrine-behaviour ``` -## Behaviours - -### Timestampable - -Adds createdAt and updatedAt properties to an entity. A listener automatically makes sure these properties are populated -on creation and updating. +## Running tests -### Expirable +``` +$ composer run-script test +``` -Adds expiredAt property to an entity with methods to for example easily expire and unexpire the entity. Use -the [expirable filter](./src/Filter/ExpirableFilter.php) to filter expired entities from query results. +## Documentation -### Soft-deletable +Please see the [docs](./docs/README.md) folder for available behaviours and their documentation. -Adds deletedAt property to an entity with methods to for example easily soft-delete and recover the entity. Use -the [soft-delete filter](./src/Filter/SoftDeleteFilter.php) to filter soft-deleted entities from query results. +## License -## Usage +MIT -Extensive documentation has not been written but have a look at the [tests](./tests). +## Changelog -1. Create your entity class -2. Make it implement the behaviour interface (e.g. [TimestampableInterface](./src/TimestampableInterface.php)) -3. Use the matching trait to implement the required methods for the chosen behaviour interface ( - e.g. [TimestampableTrait](./src/TimestampableTrait.php)) or write your own version of it. -4. In case of timestampable entities, register the [entity listener](./src/Listener/TimestampableListener.php) for your - entity, other behaviours don't require a listener. If you want this done automatically, use - the [timestampable subscriber](./src/Subscriber/TimestampableSubscriber.php) to have this done automatically for each - timestampable entity. -5. Set up [filters](https://www.doctrine-project.org/projects/doctrine-orm/en/2.11/reference/filters.html) in case of - expirable or soft-deletable entities. See [ExpirableFilter](./src/Filter/ExpirableFilter.php) - and [SoftDeleteFilter](./src/Filter/SoftDeleteFilter.php). +See [CHANGELOG](./CHANGELOG.md) diff --git a/docs/Expirable.md b/docs/Expirable.md new file mode 100644 index 0000000..e828b1c --- /dev/null +++ b/docs/Expirable.md @@ -0,0 +1,51 @@ +# Expirable Behaviour + +1. Create your entity class implementing `Cloudstek\DoctrineBehaviour\ExpirableInterface`. +2. Use the `Cloudstek\DoctrineBehaviour\ExpirableTrait` trait. +3. Optionally set up the `Cloudstek\DoctrineBehaviour\Filter\ExpirableFilter` filter (please see + the [Doctrine documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/2.11/reference/filters.html) + on filters). + +## Example + +```php +getEntityManager(); + $entity = new MyExpirableEntity(); + + // Let the entity expire in 1 hour from now. + $entity->setExpiresIn('1h'); + + $em->persist($entity); + $em->flush(); + } +} +``` diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b070ac2 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,26 @@ +# Documentation + +## Timestampable + +Adds createdAt and updatedAt properties to an entity. A listener automatically makes sure these properties are populated +on creation and updating. + +[Documentation](./Timestampable.md) + +## Expirable + +Adds expiredAt property to an entity with methods to for example easily expire and unexpire the entity. Use +the [expirable filter](../src/Filter/ExpirableFilter.php) to filter expired entities from query results. + +[Documentation](./Expirable.md) + +## Soft-deletable + +Adds deletedAt property to an entity with methods to for example easily soft-delete and recover the entity. Use +the [soft-delete filter](../src/Filter/SoftDeleteFilter.php) to filter soft-deleted entities from query results. + +[Documentation](./Expirable.md) + +## Translatable + +[Documentation](./Translatable.md) diff --git a/docs/SoftDeletable.md b/docs/SoftDeletable.md new file mode 100644 index 0000000..2e2925e --- /dev/null +++ b/docs/SoftDeletable.md @@ -0,0 +1,51 @@ +# Soft-deletable Behaviour + +1. Create your entity class implementing `Cloudstek\DoctrineBehaviour\SoftDeletableInterface`. +2. Use the `Cloudstek\DoctrineBehaviour\SoftDeletableTrait` trait. +3. Optionally set up the `Cloudstek\DoctrineBehaviour\Filter\SoftDeleteFilter` filter (please see + the [Doctrine documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/2.11/reference/filters.html) + on filters). + +## Example + +```php +getEntityManager(); + $entity = new MySoftDeletableEntity(); + + // Soft-delete the entity, will not _actually_ delete it. + $entity->delete(); + + $em->persist($entity); + $em->flush(); + } +} +``` diff --git a/docs/Timestampable.md b/docs/Timestampable.md new file mode 100644 index 0000000..6bd1982 --- /dev/null +++ b/docs/Timestampable.md @@ -0,0 +1,50 @@ +# Timestampable Behaviour + +1. Create your entity class implementing `Cloudstek\DoctrineBehaviour\TimestampableInterface`. +2. Use the `Cloudstek\DoctrineBehaviour\TimestampableTrait` trait. +3. Either add the `Cloudstek\DoctrineBehaviour\Listener\TimestampableListener` entity listener to each timestampable + entity yourself. Or register the `Cloudstek\DoctrineBehaviour\Subscriber\TimestampableSubscriber` Symfony event + subscriber to automatically apply the listener to each timestampable entity (preferred). + +## Example + +```php +getEntityManager(); + $entity = new MyTimestampableEntity(); + + $em->persist($entity); + $em->flush(); + + // Entity will now have created and updated timestamps set. + } +} +``` diff --git a/docs/Translatable.md b/docs/Translatable.md new file mode 100644 index 0000000..6905952 --- /dev/null +++ b/docs/Translatable.md @@ -0,0 +1,106 @@ +# Translatable Behaviour + +1. Create your entity class implementing `Cloudstek\DoctrineBehaviour\TranslatableInterface`. +2. Create your translation class implementing `Cloudstek\DoctrineBehaviour\TranslationInterface`. +3. Use the `Cloudstek\DoctrineBehaviour\TranslatableTrait` trait on the translatable entity. +4. Use the `Cloudstek\DoctrineBehaviour\TranslationTrait` trait on the translation entity. +5. Either add the required mappings to each translatable and translation entity yourself or register + the `Cloudstek\DoctrineBehaviour\Subscriber\TranslatableSubscriber` Symfony event + subscriber to automatically apply the required mappings to all translatable and translation entities (preferred). + +## Example + +```php +initTranslations(); + } + + public function __clone() { + // Make sure that the translations are cloned properly. + $this->cloneTranslations(); + } + + // ... Your entity code here with non-translatable properties. + public function getBar() { + return $this->bar; + } + + public function setBar(string $value): void { + $this->bar = $value; + } +} +``` + +```php +foo; + } + + public function setFoo(string $value): void { + $this->foo = $value; + } +} +``` + +```php +getEntityManager(); + $entity = new MyTranslatableEntity(); + + $entity->setBar('baz'); + + $englishEntity = $entity->translate('en'); + $englishEntity->setFoo('bar'); + // ... + + // Translations are saved too (cascaded). + $em->persist($entity); + $em->flush(); + + $entity->getBar() // baz + $entity->hasTranslation('en'); // true + $entity->translate('en')->getFoo() // bar + } +} +```