Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[api-platform/core: v2.4.3] [BUG] Binary UUID in search filter returns an empty array #2838

Closed
farazive opened this issue Jun 4, 2019 · 5 comments

Comments

@farazive
Copy link

farazive commented Jun 4, 2019

This issue was raised as a comment in this issue here, but since that issue is labeled won't fix I am not sure if my comment will be ignored, so creating a new issue here.

The Entity

/**
 * @ORM\Entity
 */
class User
{
    /**
     * @var \Ramsey\Uuid\UuidInterface
     *
     * @ORM\Id
     * @ORM\Column(name="uuid", type="uuid_binary_ordered_time", unique=true)
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidOrderedTimeGenerator")
     */
    public $id;

    /**
     * First name of user
     *
     * @ORM\Column(name="first_name",type="string", length=255)
     */
    protected $firstName;

doctrine.yaml

doctrine:
    dbal:
        types:
            uuid_binary_ordered_time: Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType
...
        connections:
            default:
                mapping_types:
                    uuid_binary_ordered_time: binary
...

Search filter

    app.api_resource.filter.search_filter.user:
        parent: 'api_platform.doctrine.orm.search_filter'
        arguments:
          -
            id: exact
            firstName: partial
        tags:  [ { name: 'api_platform.filter', id: 'app.api_resource.filter.search_filter.user' } ]

Because the id is exact, we can filter on multiple ids in a single query.

The API Resource file

resources:
    'App\Entity\User':

        shortName: 'User'
        class: 'App\Entity\User'

        description: 'The User resource'

        collectionOperations:
            api_users_get_collection:
                filters: [ 'app.api_resource.filter.search_filter.user' ]
                method: 'GET'
                normalization_context:
                    groups: [ 'userRead' ]
            get:
                openapi_context:
                    summary: Get's all the users specified in the system
                    description: >
                        Get all the users from the system
                    parameters:
                    -
                        name: id
                        in: query
                        required: false
                        schema:
                            type: array
                            items:
                                type: string
                        description: Exact match of Ids. Its possible to send multiple Ids
                        style: deepObject
                        explode: true

The bug

When visiting the route /users/{id}, where id is a UUID v1, everything works.

When visiting the route /users?id[0]={id} the system returns an empty array since its not converting the string UUIDs to Ramsey UUID objects.

It was cited in a comment here that the actual bug is this one. So I added the following in class Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType

...
    /**
     * @inheritdoc
     *
     * @return int
     */
    public function getBindingType()
    {
        return ParameterType::BINARY;
    }

But the UUID is still not converted.

For item operations, it works fine since in the identifiers are converted here. But for collection operations, the id filter is not converted.

Regarding the solution provided here I have reservations mentioned in this comment here.

Please let me know if you need any more details. Thanks.

@farazive farazive changed the title [api-platform/core: v2.4.3] [BUG] Binary UUID filter not working [api-platform/core: v2.4.3] [BUG] Binary UUID in search filter returns an empty array Jun 4, 2019
@soyuka
Copy link
Member

soyuka commented Jun 4, 2019

Do you have an idea on how we could fix this? Should we add the identifier conversion on collections?

@farazive
Copy link
Author

farazive commented Jun 4, 2019

Do you have an idea on how we could fix this? Should we add the identifier conversion on collections?

Yeah. That's what I was thinking. We should be able to fix this when the ReadListener is processing the filters and saving it into the context. After parsing the filters from RequestParser::parseRequestParams or whereever, we should check the field type of the id and call the denormalize method to convert them. Can work on a PR if you're interested.

@soyuka
Copy link
Member

soyuka commented Jun 4, 2019

Can work on a PR if you're interested.

This'd be very welcome

farazive added a commit to farazive/core that referenced this issue Jun 18, 2019
…platform#2838". Fixed by adding support for custom types in the ORM SearchFilter.
@farazive
Copy link
Author

farazive commented Jun 18, 2019

All done @soyuka .
The fix was a lot easier than messing with the ReadListener or the CollectionDataProvider. Simply changed the search filter to include IdConverter when it normalizes the values.

Caveat

The fix is only for ORM. I didn't have the time to look at ODM SearchFilter.

Let me know there's anything else needed. Thanks.

Update: Found a simpler way to do it without changing service definition.

@soyuka
Copy link
Member

soyuka commented Oct 17, 2023

This bug is targeting 2.7, as API Platform 3.2 is out, version 2.7 has reached end of life. Therefore we'll close this issue.

We recommend to upgrade to API Platform 3.0, Les-Tilleuls.coop can offer paid support to help or even migrate your projects if they have tests.

We want to fund a Long Term Stable version of API Platform, if you or your organization would like to contribute to LTS support, please visit our Open Collective crowdfunding.

@soyuka soyuka closed this as completed Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants