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

Ajax failing in decorating controller. #1008

Open
wants to merge 4 commits into
base: 1.7.x
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ So for example, if you want that people browsing the Back Office on URL `/sell/o
```yaml
# modules/your-module/config/routes.yml
admin_orders_index:
path: /sell/orders/orders/
methods: [GET]
defaults:
_controller: 'MyModule\Controller\DemoController::demoAction'
_disable_module_prefix: true
path: /sell/orders/orders/
methods: [GET]
defaults:
_controller: 'MyModule\Controller\DemoController::demoAction'
_disable_module_prefix: true
```

{{% notice tip %}}
Expand Down Expand Up @@ -77,8 +77,8 @@ For example, the controller responsible for the page "Improve > Design > CMS Pag
With the following configuration item, we can override this configuration to make it target our custom module:
```yaml
# modules/your-module/config/services.yml
'PrestaShopBundle\Controller\Admin\Improve\Design\CmsPageController':
class: MyModule\Controller\DemoController
'PrestaShopBundle\Controller\Admin\Improve\Design\CmsPageController':
class: MyModule\Controller\DemoController

```

Expand All @@ -97,7 +97,7 @@ If you have trouble writing the right service configuration for your controller,
Instead of replacing the whole controller, we recommend _extending_ its behavior using [service decoration](https://symfony.com/doc/3.4/service_container/service_decoration.html). By implementing the [decorator pattern](https://refactoring.guru/design-patterns/decorator), you can keep most or all of the original behavior of the decorated controller, and only customize the parts you want.

{{% notice note %}}
While you could achieve a similar end with an override (by making your controller extend the original one), the composition pattern provides a greater degree of freedom, while leaving all complexity of initialization and dependency management to the service container.
While you could achieve a similar end with an override (by making your controller extend the original one), the decorator pattern provides a greater degree of freedom, while leaving all complexity of initialization and dependency management to the service container.
{{% /notice %}}


Expand Down Expand Up @@ -159,11 +159,29 @@ However we could modify the input request or the output given by decorated contr
}
```

In order for the DemoController to work, we also need to implement all the other Action methods we don't interfere with of the decorated controller and simply return the decorated controller method. Example:

```php
<?php
public function anAction($id, Request $request)
{
return $this->decoratedController->anAction($id, $request);
}
Comment on lines +166 to +169

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function anAction($id, Request $request)
{
return $this->decoratedController->anAction($id, $request);
}
public function anAction($id, Request $request)
{
return $this->decoratedController->anAction($id, $request);
}


```

On some edge cases we might need to perform an Ajax call from our Javascript file (or the Twig template) to our decorating DemoController.
Curently this will not work though, what we need to do in such a case is to create a regular admincontroller e.g. mymodule/src/Controller/Admin/DemoAjaxController.php with a method, create a route for that method in our mymodule/src/config/routes.yml, generate the URL as described here, [symfony docs](https://devdocs.prestashop.com/1.7/modules/concepts/controllers/admin-controllers/route-generation/) and perform our ajax call using the resulting Symfony route.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, this sounds like a bug 😄 actually. Can you tell me more? Would you have a code sample I could analyze?

Copy link
Contributor Author

@Rho-bur Rho-bur May 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
I'll attach the files here as the repository is private.
Ajax does not work in the decorating RmvProductController but works on AdminActionsController.
Routes in main class:
Media::addJsDef([ 'admin_products_url' => $this->context->link->getAdminLink('AdminRmvActions'), 'symfonyUrl' => $this->context->link->getAdminLink('RmvProduct', true, array('route' => 'rmvpreciousmetals_rmv_unit')), 'adminCommandUrl' => $this->context->link->getAdminLink('AdminActions', true, array('route' => 'rmvpreciousmetals_run_command')), ]);

routes.yml:

rmvpreciousmetals_rmv_unit:
  path: rmvpreciousmetals/update-product
  methods:  [POST]
  defaults:
    _controller: 'PrestaShop\Module\RmvPreciousMetals\Controller\Admin\AdminActionsController::setProductPricesAction'
    _legacy_controller: AdminActions

rmvpreciousmetals_run_command:
  path: rmvpreciousmetals/run-product
  methods:  [GET|POST]
  defaults:
    _controller: 'PrestaShop\Module\RmvPreciousMetals\Controller\Admin\AdminActionsController::sendApiRequest'
    _legacy_controller: AdminActions

When using the RmvProductController action (a new action not from the decoratedController) in the rmvpreciousmetals_rmv_unit path the ajax does not work, switching it to a regular controller not decorating anything (AdminActionsController) works.

Here is the slack thread I have opened for this, slack

code.zip

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think seeing the full code will help I could grant you access to my private repo, no problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for late answer, week has been very busy I did not have time to explore the topic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, no worries, I'll wait!

<<<<<<< HEAD
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello I think this was not wanted 😉 ?

=======

>>>>>>> e13410a98aa0aebf79f50e7ceb01a5dd4de3b64c

{{% notice tip %}}
If you have trouble writing the right service configuration for your decoration, you can use Symfony debugger to dump the routes with `php bin/console debug:container`. It can also be helpful to find the service ID of the controller.
{{% /notice %}}


[hooks]: {{< ref "/1.7/modules/concepts/hooks" >}}
[template-override]: {{< ref "/1.7/modules/concepts/templating/admin-views" >}}
[override-services]: {{< ref "/1.7/modules/concepts/services" >}}