0

I'm trying to build a tree behaving entity similar to the categories in Magento 2.
Of course I used the Catalog category entity as an example, but this works up to a point.
I'm planning to implement it properly using service contracts.
So in my Move action (similar to this one) my _initEntity method (equivalent to the _initCategory) I don't instantiate the entity model.

I have it something like this (code was changed for explanation purposes so ignore the possible syntax errors. It actually works):

protected method _initEntity()
{
    $entityId = $this->request->getParam('entity_id');
    try {
        return $this->entityRepository->getById($entityId);
    } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
        return false;
    }
}

entityRepository is Api\EntityRepositoryInterface similar to the Cms page repository interface.
This works nicely but my IDE complains that the method move is not available in the interface.
I'm calling $entity->move() similar to this line.

Keep in mind that this works, since the actual implementation of the EntityInterface I'm using is the actual Entity model that contains the move method. So I don't need a way to make it work. I need a way to code it properly.

How should I proceed on this so I would not care about the implementation of the interface?
I could just add the method move in my entity interface but this seams wrong since I should not have this kind of logic in the model itself.
So I don't want to do that.
Any suggestions?

1

For solve IDE autocomplete you need to create php doc for repository and _initEntity method with correct return type (@return ...Api\Data\EntityInterface). After that you IDE can autocomplete methods from interface after typing.

Moreover i think, that undefined entity_id is exceptional state and you can catch this exception in controller execute method and will not problems with mixed return types in initEntity method and unnecessary if statements after getting result of initEntity.

Moreover i think, that placing any service methods in DTO is bad style. You need to use data objects only for data transfer. this classes can contain only getters and setters. OrderInterface::place(), CategoryInterface::move(), CmsPageInterface::save() is legacy style.

You need to create service model (MyEntityManagement for example) with method move(MyEntityInterface $entity, MyEntityInterface $parent) which will move your entity to new parent.

Example:

public function execute()
{
    $id = $this->getRequest()->getParam('id');
    $parentId = $this->getRequest()->getParam('parent_id');

    try {
        $entity = $this->myEntityRepository->getById($id);
        $parent = $this->myEntityRepository->getById($parentId);

        $this->myEntityManagement->move($entity, $parent);
    } catch (NoSuchEntityException $e) {
        //....
    } catch (MoveException $e) {
        // ....
    }

}
  • This makes sense. I'm not really a big fan though of adding @var comments, just to trick the IDE. But having a entity management class should solve my issue properly. Any idea on what this entity management class should be? A model, a helper (I hope not), something custom, a resource model? – Marius Jan 10 '17 at 17:16
  • i do not propose to trick IDE. I think, that you use resource models in your repository and it is return AbstractModel (or something similar), so IDE cannot cast correct type to return values and you need to define correct interface. For naming i think, that you can use \Magento\Catalog\Api\CategoryManagementInterface::move as example – Max Jan 10 '17 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.