Skip to content

[BC Break] 2.7 has undocumented bc breaks cause of namespace changes (e.g. by removal of 'Doctrine\Bridge') #4694

@robertfausk

Description

@robertfausk

API Platform version(s) affected: 2.7/dev-main

Description
As @laryjulien stated in #4556 (comment)

FQCN (fully qualified class name) are not updated in CHANGELOG.md

see e.g.:
10827bb
image

How to reproduce

Implement a class to filter subresources according to solution in #2253 (comment) and update from 2.6.8 to 2.7/dev-main.

This will result in Type error: App\Doctrine\DefaultOrderExtensionDecorator::__construct(): Argument #1 ($decorated) must be of type ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\OrderExtension, ApiPlatform\Doctrine\Orm\Extension\OrderExtension given. See example code below.

Changing use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\OrderExtension; to use ApiPlatform\Doctrine\Orm\Extension\OrderExtension; fixes the error in the example code.

#services.yml
    App\Doctrine\DefaultOrderExtensionDecorator:
        decorates: api_platform.doctrine.orm.query_extension.order
        arguments:
            $decorated: '@App\Doctrine\DefaultOrderExtensionDecorator.inner'
            $orderParameterName: '%api_platform.collection.order_parameter_name%'
<?php
declare(strict_types=1);

namespace App\Doctrine;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\ContextAwareQueryCollectionExtensionInterface;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\OrderExtension;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use App\Entity\Event;
use Doctrine\ORM\QueryBuilder;

final class DefaultOrderExtensionDecorator implements ContextAwareQueryCollectionExtensionInterface
{
    private OrderExtension $decorated;

    private string $orderParameterName;

    public function __construct(OrderExtension $decorated, string $orderParameterName)
    {
        $this->decorated = $decorated;
        $this->orderParameterName = $orderParameterName;
    }

    /**
     * @inheritDoc
     */
    public function applyToCollection(
        QueryBuilder $queryBuilder,
        QueryNameGeneratorInterface $queryNameGenerator,
        string $resourceClass,
        string $operationName = null,
        array $context = []
    ) {
        if ($resourceClass !== Event::class) {
            return;
        }

        // Apply default resource order AFTER none or only some query filters are defined.
        $filters = $context['filters'] ?? [];
        $orderFilters = (array) ($filters[$this->orderParameterName] ?? []);
        $sanitizedOrderFilters = \array_filter($orderFilters);
        $rootAlias = $queryBuilder->getRootAliases()[0];
        if (!isset($sanitizedOrderFilters['date'])) {
            $sanitizedOrderFilters['date'] = 'asc';
            $context['filters'][$this->orderParameterName] = $sanitizedOrderFilters;
            $queryBuilder->addOrderBy(\sprintf('%s.date', $rootAlias), 'asc');
        }
        if (!isset($sanitizedOrderFilters['start'])) {
            $sanitizedOrderFilters['start'] = 'asc';
            $context['filters'][$this->orderParameterName] = $sanitizedOrderFilters;
            $queryBuilder->addOrderBy(\sprintf('%s.start', $rootAlias), 'asc');
        }
        if (!isset($sanitizedOrderFilters['id'])) {
            $sanitizedOrderFilters['id'] = 'asc';
            $context['filters'][$this->orderParameterName] = $sanitizedOrderFilters;
            $queryBuilder->addOrderBy(\sprintf('%s.id', $rootAlias), 'asc');
        }

        $this->decorated->applyToCollection(
            $queryBuilder,
            $queryNameGenerator,
            $resourceClass,
            $operationName,
            $context
        );
    }
}

Possible Solution

  • document all namespace changes as BC breaks for 2.7 in CHANGELOG.md
    OR:
  • prevent BC break by e.g.:
    • provide stub classes which implements/extends the classes in their new location with the old namespace
    • mark these stub classes as deprecated
    • document namespace deprecations in CHANGELOG.md

Additional Context

  • I stumbled across the tweet of @soyuka today and tried dev-main on my api-platform projects.
  • I did not check all namespace changes. Maybe there are more than Core\Bridge

Edit: clarified which exception is occuring.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions