最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - ApiPlatform re-usable custom controller - Stack Overflow

programmeradmin1浏览0评论

I have a controller which does some file management related to entities. I want this controller reusable:

#[ApiResource(
    itemOperations: [
        'deleteApiFile' => [
            'method' => 'DELETE',
            'path' => '/foo/{id}/delete-file',
            'read' => false,
            'controller' => ApiFileDeleteController::class,
        ],
    ],
)]
class Foo { /* ... */ }



#[ApiResource(
    itemOperations: [
        'deleteApiFile' => [
            'method' => 'DELETE',
            'path' => '/bar/{id}/delete-file',
            'read' => false,
            'controller' => ApiFileDeleteController::class,
        ],
    ],
)]
class Bar { /* ... */ }

And this is the controller:

class ApiFileDeleteController
{
    public function __invoke(string $id): void
    {
        // I have the $id now, how do I determine which entity it belongs to?
        //
        // Logic in this controller is always the same and always for an entity
        $example = $this->em->getRepository($class)->find($id);
        // How do I get $class?
    }
}

Question: How can I get the ApiPlatform config in the controller (or __construct)?

  • I could make a FooApiFileDeleteController and a BarApiFileDeleteController, but in the future if I want to expand I need to keep adding controller, just for the classname. I'd radther have a little effort now and in the future dont need to worry about this.
  • I could add a parameter and add a default value, but then it might be affected by a user, I do not want that.
  • Edit: Currently checking out processors, based of this similar question ApiPlatform v2.6 doesnt support that unfortunately

I have a controller which does some file management related to entities. I want this controller reusable:

#[ApiResource(
    itemOperations: [
        'deleteApiFile' => [
            'method' => 'DELETE',
            'path' => '/foo/{id}/delete-file',
            'read' => false,
            'controller' => ApiFileDeleteController::class,
        ],
    ],
)]
class Foo { /* ... */ }



#[ApiResource(
    itemOperations: [
        'deleteApiFile' => [
            'method' => 'DELETE',
            'path' => '/bar/{id}/delete-file',
            'read' => false,
            'controller' => ApiFileDeleteController::class,
        ],
    ],
)]
class Bar { /* ... */ }

And this is the controller:

class ApiFileDeleteController
{
    public function __invoke(string $id): void
    {
        // I have the $id now, how do I determine which entity it belongs to?
        //
        // Logic in this controller is always the same and always for an entity
        $example = $this->em->getRepository($class)->find($id);
        // How do I get $class?
    }
}

Question: How can I get the ApiPlatform config in the controller (or __construct)?

  • I could make a FooApiFileDeleteController and a BarApiFileDeleteController, but in the future if I want to expand I need to keep adding controller, just for the classname. I'd radther have a little effort now and in the future dont need to worry about this.
  • I could add a parameter and add a default value, but then it might be affected by a user, I do not want that.
  • Edit: Currently checking out processors, based of this similar question ApiPlatform v2.6 doesnt support that unfortunately
Share Improve this question edited Jan 20 at 15:07 Martijn asked Jan 20 at 14:34 MartijnMartijn 16.1k4 gold badges38 silver badges72 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

In my case I could get away with using a DataPersister (or in ApiPlatform 2.7+) called Processor). Not 100% what I was looking for*, but for now it will do.

class ApiFileUploaderDeleteDataPersister implements ContextAwareDataPersisterInterface
{
    public function supports($data, array $context = []): bool
    {
        return is_a($context['resource_class'], ApiFileUploadInterface::class, true);
    }

    public function persist($data, array $context = [])
    {
        return $data;
    }

    public function remove($data, array $context = [])
    {
        $this->removeFile($context);
    }
}
  • Its important to set read: true in your entity (by omitting it). Controller isnt needed either:
    #[ApiResource(
      itemOperations: [
          'deleteApiFile' => [
              'method' => 'DELETE',
              'path' => '/bar/{id}/delete-file', // See: ApiFileUploaderDeleteDataPersister
          ],
      ],
    )]
    class Bar { /* ... */ }
    

* The reason this isnt what I was looking for is because this is now a 'hidden' file. A controller gets defined in the ApiPlatform config and is therefor easy to find. This is more a background step. Not the worst though.

发布评论

评论列表(0)

  1. 暂无评论