Skip to content

Commit

Permalink
Merge pull request #110 from W0rma/optional-doctrine-annotations
Browse files Browse the repository at this point in the history
Make doctrine/annotations optional + drop PHP < 8.1
  • Loading branch information
goetas authored Nov 4, 2024
2 parents 08c014d + 09fb7c5 commit d00ab70
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 104 deletions.
44 changes: 35 additions & 9 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,52 @@ jobs:
fail-fast: false
matrix:
php-version:
- "7.2"
- "7.3"
- "7.4"
- "8.0"
- "8.1"
- "8.2"
- "8.3"
- "8.4"
dependencies:
- "highest"
- "lowest"
symfony-require:
- "^3.0"
- "^4.0"
- "^5.0"
- "^6.0"
include:
- php-version: 8.0
symfony-require: "^6.0"
- php-version: 8.1
symfony-require: "^6.0"
- php-version: 8.2
symfony-require: "^5.0"
remove-annotations: "yes"
- php-version: 8.2
symfony-require: "^6.0"
remove-annotations: "yes"
- php-version: 8.2
symfony-require: "^7.0"
- php-version: 8.2
symfony-require: "^7.0"
remove-annotations: "yes"
- php-version: 8.3
symfony-require: "^5.0"
remove-annotations: "yes"
- php-version: 8.3
symfony-require: "^6.0"
- php-version: 8.2
remove-annotations: "yes"
- php-version: 8.3
symfony-require: "^7.0"
- php-version: 8.3
symfony-require: "^7.0"
remove-annotations: "yes"
- php-version: 8.4
symfony-require: "^5.0"
remove-annotations: "yes"
- php-version: 8.4
symfony-require: "^6.0"
remove-annotations: "yes"
- php-version: 8.4
symfony-require: "^7.0"
- php-version: 8.4
symfony-require: "^7.0"
remove-annotations: "yes"

steps:
- name: Checkout code
Expand All @@ -57,6 +76,13 @@ jobs:
ini-values: "zend.assertions=1"
tools: "flex"

- name: "Remove remove-annotations if required"
if: "${{ matrix.remove-annotations == 'yes' }}"
env:
SYMFONY_REQUIRE: "${{ matrix.symfony-require }}"
run: |
composer remove --no-update --dev doctrine/annotations
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coding-standards.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
php-version:
- "7.4"
- "8.1"

steps:
- name: "Checkout"
Expand Down
6 changes: 4 additions & 2 deletions DependencyInjection/Compiler/AttributeDriverPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Bazinga\Bundle\HateoasBundle\DependencyInjection\Compiler;

use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

Expand All @@ -20,8 +21,9 @@ class AttributeDriverPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
if (PHP_VERSION_ID < 80100) {
$container->removeDefinition('hateoas.configuration.metadata.attribute_driver');
if (!class_exists(AnnotationReader::class)) {
$container->removeDefinition('hateoas.configuration.metadata.annotation_reader');
$container->removeDefinition('hateoas.configuration.metadata.annotation_driver');
}
}
}
2 changes: 1 addition & 1 deletion DependencyInjection/Compiler/CacheWarmupPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function process(ContainerBuilder $container)

$warmupService->setArgument(1, $container->findDefinition('hateoas.configuration.metadata_factory'));
$container->setDefinition('hateoas.configuration.metadata.cache.cache_warmer', $warmupService);
} catch (ServiceNotFoundException $exception) {
} catch (ServiceNotFoundException) {
}
}
}
2 changes: 1 addition & 1 deletion Resources/config/configuration.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<service id="hateoas.configuration.metadata.annotation_or_attribute_driver" class="Metadata\Driver\DriverChain" public="false">
<argument type="collection">
<argument type="service" id="hateoas.configuration.metadata.attribute_driver" on-invalid="ignore" />
<argument type="service" id="hateoas.configuration.metadata.annotation_driver" />
<argument type="service" id="hateoas.configuration.metadata.annotation_driver" on-invalid="ignore" />
</argument>
</service>

Expand Down
76 changes: 40 additions & 36 deletions Resources/doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,37 @@ This command requires you to have Composer installed globally, as explained
in the [installation chapter](https://getcomposer.org/doc/00-intro.md)
of the Composer documentation.

If you want to use annotations for configuration you need
to install the `doctrine/annotations` package:

```sh
composer require doctrine/annotations
```

If your app uses PHP 8.1 or higher it is recommended to use native PHP
attributes.
In this case you don't need to install the Doctrine package.

### Step 2: Enable the Bundle

> Note: this step is not required if you are using Symfony Flex
Then, enable the bundle by adding the following line in the `app/AppKernel.php`
Then, enable the bundle by adding the following line in the `src/AppKernel.php`
file of your project:

```php
<?php
// app/AppKernel.php
// src/AppKernel.php

// ...
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
$bundles = [
// ...
new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),
);
];

// ...
}
Expand All @@ -51,15 +62,15 @@ class AppKernel extends Kernel
> registered. If you haven't done that already, you should register it in the kernel aswell:
>
> ```php
> // app/AppKernel.php
> // src/AppKernel.php
>
> // ...
> public function registerBundles()
> {
> $bundles = array(
> $bundles = [
> // ...
> new JMS\SerializerBundle\JMSSerializerBundle(),
> );
> ];
>
> // ...
> }
Expand Down Expand Up @@ -88,7 +99,7 @@ class SomeController extends Controller
$post = $repository->find('BlogBundle:post');
$json = $this->container->get('jms_serializer')->serialize($post, 'json');
return new Response($json, 200, array('Content-Type' => 'application/json'));
return new Response($json, 200, ['Content-Type' => 'application/json']);
}
}
````
Expand All @@ -102,19 +113,16 @@ use JMS\Serializer\SerializerInterface;
class SomeController extends Controller
{
private $serializer;
public function __consttruct(SerializerInterface $serializer)
public function __construct(private readonly SerializerInterface $serializer)
{
$this->serializer = $serializer;
}
public function resourceAction(Request $request)
{
$post = $repository->find('BlogBundle:post');
$json = $this->serializer->serialize($post, 'json');
return new Response($json, 200, array('Content-Type' => 'application/json'));
return new Response($json, 200, ['Content-Type' => 'application/json']);
}
}
````
Expand All @@ -132,18 +140,16 @@ has certain permissions or not. For example:
```php
use Hateoas\Configuration\Annotation as Hateoas;
/**
* @Hateoas\Relation(
* "delete",
* href = @Hateoas\Route(
* "post_delete",
* parameters = { "id" = "expr(object.getId())" }
* ),
* exclusion = @Hateoas\Exclusion(
* excludeIf = "expr(not is_granted('ROLE_ADMIN'))"
* )
* )
*/
#[Hateoas\Relation(
'delete',
href: new Hateoas\Route(
"post_delete",
parameters: ['id' => 'expr(object.getId())'],
),
exclusion: new Hateoas\Exclusion(
excludeIf: "expr(not is_granted('ROLE_ADMIN'))",
)
)]
class Post
{
// ...
Expand All @@ -157,16 +163,14 @@ the route will be excluded.

Allows you to fetch a parameter from the service container:

```
/**
* @Hateoas\Relation(
* "delete",
* href = @Hateoas\Route(
* "post_delete",
* parameters = { "foo" = "expr(parameter('foo'))" }
* )
* )
*/
```php
#[Hateoas\Relation(
'delete',
href: new Hateoas\Route(
'post_delete',
parameters: ['foo' => "expr(parameter('foo'))"],
)
)]
class Post
{
// ...
Expand Down Expand Up @@ -243,7 +247,7 @@ class AcmeFooConfigurationExtension implements ConfigurationExtensionInterface
*/
public function decorate(ClassMetadataInterface $classMetadata)
{
if (0 === strpos('Acme\Foo\Model', $classMetadata->getName())) {
if (str_starts_with('Acme\Foo\Model', $classMetadata->getName())) {
// Add a "root" relation to all classes in the `Acme\Foo\Model` namespace
$classMetadata->addRelation(
new Relation(
Expand Down
34 changes: 18 additions & 16 deletions Tests/DependencyInjection/BazingaHateoasExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

use Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle;
use Bazinga\Bundle\HateoasBundle\Tests\Fixtures\SimpleObject;
use Bazinga\Bundle\HateoasBundle\Tests\Fixtures\SimpleObjectAnnotation;
use Bazinga\Bundle\HateoasBundle\Tests\Fixtures\SimpleObjectAnnotationAndAttribute;
use Doctrine\Common\Annotations\AnnotationReader;
use JMS\SerializerBundle\JMSSerializerBundle;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -27,7 +30,8 @@ public function tearDown(): void
$this->clearTempDir();
}

public function testLoad()
/** @dataProvider getTestLoadData */
public function testLoad($object)
{
$container = $this->getContainerForConfig([[]]);
$container->compile();
Expand All @@ -49,10 +53,21 @@ public function testLoad()
'e2' => 2.0,
],
], JSON_PRESERVE_ZERO_FRACTION),
$serializer->serialize(new SimpleObject('hello'), 'json')
$serializer->serialize($object, 'json')
);
}

/** @return array<SimpleObject|SimpleObjectAnnotation|SimpleObjectAnnotationAndAttribute> */
public static function getTestLoadData(): iterable
{
yield [new SimpleObject('hello')];

if (class_exists(AnnotationReader::class)) {
yield [new SimpleObjectAnnotation('hello')];
yield [new SimpleObjectAnnotationAndAttribute('hello')];
}
}

public function testRelationProviderPassInvalidProvider()
{
$container = $this->getContainerForConfig([[]]);
Expand Down Expand Up @@ -142,19 +157,6 @@ public function testLoadInvalidConfigurationExtension()
$container->compile();
}

public function testSupportedAttributeDriver()
{
$container = $this->getContainerForConfig([[]]);
$container->compile();

// Hateoas attributes are supported as of php 8.1.
if (PHP_VERSION_ID < 80100) {
self::assertFalse($container->hasDefinition('hateoas.configuration.metadata.attribute_driver'));
} else {
self::assertTrue($container->hasDefinition('hateoas.configuration.metadata.attribute_driver'));
}
}

private function clearTempDir()
{
// clear temporary directory
Expand All @@ -179,7 +181,7 @@ private function getTempDir()
}

/** @see https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Tests/DependencyInjection/JMSSerializerExtensionTest.php */
private function getContainerForConfig(array $configs, ?KernelInterface $kernel = null)
private function getContainerForConfig(array $configs, KernelInterface|null $kernel = null)
{
if (null === $kernel) {
$kernel = $this->createMock(KernelInterface::class);
Expand Down
Loading

0 comments on commit d00ab70

Please sign in to comment.