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

Product association : ajax product search fails #9364

Closed
edouardT opened this issue Apr 24, 2018 · 39 comments · Fixed by #11424
Closed

Product association : ajax product search fails #9364

edouardT opened this issue Apr 24, 2018 · 39 comments · Fixed by #11424
Labels
Potential Bug Potential bugs or bugfixes, that needs to be reproduced.

Comments

@edouardT
Copy link

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Sylius version 1.1

With more than 100 products in database and long text contents, espacially in description field (including html), when you modify a product in back-office and want to make a new product association, if you search a product in the dropdown selector, the request is really slow or fails.

The first thing is that the response returns all fields of the product in the JSON Response while we only need the name and the code of the product. So, it takes a lot of time to serialize the whole object and after, it takes a lot of time to display the list in the javascript function.

I didn't find if it's possible to request a part of the product field and not the whole object.

That's problematic because in a lot of case the request take too much time and stops, so we can't select any product for the association...

@Zales0123 Zales0123 added the Potential Bug Potential bugs or bugfixes, that needs to be reproduced. label Apr 25, 2018
@stefandoorn
Copy link
Contributor

More information in duplicate ticket #9411.

@stefandoorn
Copy link
Contributor

I can confirm this issue also occurs on 1.2.x.

@rpierlot
Copy link

Hi,
It appears issue #9411 points to #9364, and #9364 points to #9411. Both are closed, so I don't know if anyone's working on a fix or has already found a solution?
Thanks

@pamil
Copy link
Contributor

pamil commented Oct 3, 2018

Should be fixed by #9775.

@Zales0123
Copy link
Member

Thank you, @edouardT, for reporting this bug, should be fixed right now, don't hesitate to reopen this issue if there still will be some problems :)

@andychan94
Copy link

@Zales0123 Has this really been fixed? Because my project still fails to load the list of products. I am using symfony 4.2 with sylius 1.3. Sorry for disturbing but I really cannot find a solution to this problem

@edouardT
Copy link
Author

@Zales0123 @andychan94 I confirm this bug is not fixed. Like I said, the problem is in the json response which returns all product data instead of product name. I don't know if it's easy to change it... Let me know if you find a solution. I will try to fix this in the next few weeks if I can.

@andychan94
Copy link

@edouardT sorry, any progress yet? If you are busy maybe I could try to work on it if you can give me details? Thanks!

@jcgdjob
Copy link

jcgdjob commented Jan 17, 2019

Issue still there in v1.3.5...
Below actually won't fix.
af6b891

@andychan94
Copy link

Correct. Would appreciate if anyone shares a solution they found for this

@Takeno
Copy link
Contributor

Takeno commented Jan 17, 2019

My workaround was replace the route with a custom action.

routes.yaml

sylius_admin_ajax_product_index:
    path: /admin/ajax/products/
    methods: [GET]
    defaults:
        _controller: AppBundle:Admin\Custom:searchProduct
        _format: json

CustomController.php

    public function searchProductAction(Request $request) {
        $repo = $this->get('sylius.repository.product');

        $criteria = $request->query->get('criteria');
        $q = $criteria['search']['value'];

        $items = $repo->findBySearch($q);

        return new JsonResponse([
            '_embedded' => [
                'items' => $items,
            ]
        ]);
    }

findBySearch is a simple query in ProductRepository.php which returns just id, name and code. You should be able to get the json's schema from a fresh installation.

@stefandoorn
Copy link
Contributor

@Zales0123 @pamil What about adding the suggestion above into core?

@andychan94
Copy link

@Takeno could you please show ur custom method in ProductRepository.php? I followed the sylius docs to customize repositories, but I cannot figure out how to return just id, name and code. Thanks in advance!

@Takeno
Copy link
Contributor

Takeno commented Feb 3, 2019

@andychan94 something like this:

    public function findBySearch($term)
    {
        return $this->createQueryBuilder('o')
            ->select('translation.name')
            ->addSelect('o.code')
            ->innerJoin('o.translations', 'translation', 'WITH', 'translation.locale = :locale')
            ->addOrderBy('o.updatedAt', 'DESC')
            ->andWhere('o.code LIKE :term')
            ->orWhere('translation.name LIKE :term')
            ->setParameter('locale', 'it_IT')
            ->setParameter('term', '%' . $term . '%')
            ->setMaxResults(20)
            ->getQuery()
            ->getResult();
    }

@andychan94
Copy link

andychan94 commented Feb 3, 2019

@Takeno thanks for your help!
So I customized the Product Repository according to the docs and added ur method to it. And then I just created a CustomController class which looks like this:

namespace App\Controller;

use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

class CustomController extends ResourceController
{
    public function searchProductAction(Request $request)
    {
        $repo = $this->container->get('sylius.repository.product');

        $criteria = $request->query->get('criteria');
        $q = $criteria['search']['value'];

        $items = $repo->findBySearch($q);

        return new JsonResponse([
            '_embedded' => [
                'items' => $items,
            ]
        ]);
    }
}

But I am getting the following error

Cannot autowire service "App\Controller\CustomController": argument "$metadata" of method "Sylius\Bundle\ResourceBundle\Controller\ResourceController::__construct()" references interface "Sylius\Component\Resource\Metadata\MetadataInterface" but no such service exists. Did you create a class that implements this interface?

I cannot disable the autowiring for this controller, so I dont know what to do.

If I do not extend the ResourceController, then I obviously get

{
"code": 500,
"message": "Notice: Undefined property: App\Controller\CustomController::$container"
}

I tried to follow the docs, read the Customizing Controller section, but I still dont know how to implement it in this case.

Sorry if it is getting annoying but I would really appreciate your help! Thanks!

@jcgdjob
Copy link

jcgdjob commented Feb 4, 2019

If I do not extend the ResourceController, then I obviously get

{
"code": 500,
"message": "Notice: Undefined property: App\Controller\CustomController::$container"
}

Try extends AbstractController instead.

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

@andychan94
Copy link

@jcgdjob thank you! Seems like this is working fine! Thank you guys so much!

@Prometee
Copy link
Contributor

Prometee commented Jul 17, 2019

This bug occurred also for me (Sylius 1.5.2, Sf 4.3.2) and surprisingly it's stop happening when I add the serialization_groups into the route :

(EDITED after @olia-bn comment)

sylius_admin_ajax_product_index:
    path: /admin/ajax/products
    methods: [GET]
    defaults:
        _controller: sylius.controller.product:indexAction
        _format: json
        _sylius:
            serialization_groups: [Default]
            permission: true
            grid: sylius_admin_product

I also try with Autocomplete but it wasn't working giving back an empty json object ({}) but only Default is working.

Xdebugging it without the serialization_groups it appears to loop infinitely into the JMS serialization process.

@mmenozzi
Copy link
Contributor

Hi guys,
I think that this should be re-opened. I experimented the same bug with the latest Sylius version 1.6.0... The workaround proposed by @Prometee works for me!

@lchrusciel lchrusciel reopened this Sep 13, 2019
@olia-bn
Copy link

olia-bn commented Jan 21, 2020

It is still present in 1.6.4

GraphNavigator is timing out:
Maximum execution time of x seconds exceeded in /vendor/jms/serializer/src/JMS/Serializer/GraphNavigator.php on line 331, referer: /admin/products/{id}/edit

@Prometee 's solution works perfectly as a work-around, with one note: the path in his solution is incorrect; this will work tho:

sylius_admin_ajax_product_index:
    path: /admin/ajax/products/
    methods: [GET]
    defaults:
        _controller: sylius.controller.product:indexAction
        _format: json
        _sylius:
            permission: true
            grid: sylius_admin_product
            serialization_groups: [Default]

@Prometee
Copy link
Contributor

Prometee commented Jan 21, 2020

@olia-bn you are right to fix the bug you have to put an override with the correct path into config/routes/sylius_admin.yaml for example.

@TELLO0815
Copy link

TELLO0815 commented May 3, 2020

Hi all, I tried the solution:

sylius_admin_ajax_product_index:
path: /admin/ajax/products/
methods: [GET]
defaults:
_controller: sylius.controller.product:indexAction
_format: json
_sylius:
permission: true
grid: sylius_admin_product
serialization_groups: [Default]

But for me its not working. (Not in 1.6 and also not in 1.7.3

Any ideas?

@Prometee
Copy link
Contributor

Prometee commented May 4, 2020

@TELLO0815 rechecking my fix proposition on 1.7.3 and it's working, do you debug the route definition in console : ./bin/console debug:route sylius_admin_ajax_product_index

@TELLO0815
Copy link

@Prometee

| Route Name   | sylius_admin_ajax_product_index                                                                                           |
| Path         | /                                                                                                                         |
| Path Regex   | #^/$#sD                                                                                                                   |
| Host         | ANY                                                                                                                       |
| Host Regex   |                                                                                                                           |
| Scheme       | ANY                                                                                                                       |
| Method       | GET                                                                                                                       |
| Requirements | NO CUSTOM                                                                                                                 |
| Class        | Symfony\Component\Routing\Route                                                                                           |
| Defaults     | _controller: sylius.controller.product:indexAction                                                                        |
|              | _format: json                                                                                                             |
|              | _sylius: array ('permission' => true,'grid' => 'sylius_admin_product','serialization_groups' => array (0 => 'Default',),) |
| Options      | compiler_class: Symfony\Component\Routing\RouteCompiler 

@Prometee
Copy link
Contributor

Prometee commented May 4, 2020

@TELLO0815 I don't have the same Path Regexp and Path I got :

| Route Name   | sylius_admin_ajax_product_index                                                                                           |
| Path         | /admin/ajax/products                                                                                                      |
| Path Regex   | #^/admin/ajax/products$#sD                                                                                                |
| Host         | ANY                                                                                                                       |
| Host Regex   |                                                                                                                           |
| Scheme       | ANY                                                                                                                       |
| Method       | GET                                                                                                                       |
| Requirements | NO CUSTOM                                                                                                                 |
| Class        | Symfony\Component\Routing\Route                                                                                           |
| Defaults     | _controller: sylius.controller.product:indexAction                                                                        |
|              | _format: json                                                                                                             |
|              | _sylius: array ('serialization_groups' => array (0 => 'Default',),'permission' => true,'grid' => 'sylius_admin_product',) |
| Options      | compiler_class: Symfony\Component\Routing\RouteCompiler                                                                   |

@Prometee
Copy link
Contributor

Prometee commented May 4, 2020

Here is my full override, maybe you don't see the @olia-bn comment altering my comment (I edit my first post to avoid others having this issue too) :

# config/routes/sylius_admin.yaml

sylius_admin:
    resource: "@SyliusAdminBundle/Resources/config/routing.yml"
    prefix: /admin

# Bug infinite loop into admin product associations selection
# https://github.com/Sylius/Sylius/issues/9364
sylius_admin_ajax_product_index:
    path: /admin/ajax/products
    methods: [GET]
    defaults:
        _controller: sylius.controller.product:indexAction
        _format: json
        _sylius:
            serialization_groups: [Default]
            permission: true
            grid: sylius_admin_product

@TELLO0815
Copy link

Works. THX

@lchrusciel
Copy link
Member

Hey folks, it seems like it is something we could fix in the core. Would you like to open a PR with the fix? Preferably with some PHPUnit test (if you will be able to make this call there, as it would be a first one).

You can find some inspirations for tests here: https://github.com/Sylius/Sylius/blob/master/tests/Controller/AdminUserApiTest.php

@Prometee
Copy link
Contributor

Prometee commented May 5, 2020

@lchrusciel I'm on it, I see that there is a fixture with an admin user now I have to found how to authenticate it in the unit test.

@lchrusciel
Copy link
Member

if you are using nelmio fixtures, just add following array:

private static $authorizedHeaderWithContentType = [
'HTTP_Authorization' => 'Bearer SampleTokenNjZkNjY2MDEwMTAzMDkxMGE0OTlhYzU3NzYyMTE0ZGQ3ODcyMDAwM2EwMDZjNDI5NDlhMDdlMQ',
'CONTENT_TYPE' => 'application/json',
];

Also, there are fixtures with a product already as well

@Prometee
Copy link
Contributor

Prometee commented May 5, 2020

I see, authenticate with the bearer will work even if it's an /admin/ajax route, I'll test it. Thanks @lchrusciel !

@Prometee
Copy link
Contributor

Prometee commented May 5, 2020

@lchrusciel pushed it, I have to authenticate the user before making a request. Same process is used for behat tests into the service sylius.behat.admin_security

pamil added a commit that referenced this issue May 12, 2020
This PR was merged into the 1.7-dev branch.

Discussion
----------

| Q               | A
| --------------- | -----
| Branch?         |  master
| Bug fix?        | yes
| New feature?    | no
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | fixes #9364
| License         | MIT


Commits
-------

8022191 Fix ajax product search when too many products
f93262c Add upgrade note
c400b69 Add product associations to avoid regression
560bf13 Add old behaviour
@starmate
Copy link

starmate commented Sep 1, 2020

Hi @Prometee,

I just found this thread and as I am facing similar issue, I though maybe you could give some insights.

When I try to add associated products (v1.7.6), I am not able to see the drop down list. There is no ajax requets (verified with developer tool). Seems to me that it is js issue, but I don't have any error message.

When I manually load url from data-url attribut, I get a json list, which seems to work, but when I am on the input text for associated product selection, nothing happens.

Do you know what may cause this?

Thanks in advance

@Prometee
Copy link
Contributor

Prometee commented Sep 1, 2020

@starmate I suspect something related with javascript setup at first sight, maybe you can ask for more help on Sylius's Slack support channel.

@starmate
Copy link

starmate commented Sep 2, 2020

Hi @Prometee ,

Yes it was actually. It was generated by glitch with mollie module in their app.js (v3.2.3).

Seems to be fixed from v2.3.4.

@bellu
Copy link

bellu commented Nov 17, 2021

I'm using Sylius 1.10 and the problem is still here.
The only solution that works is the @Takeno one.

@mickael-naturopera
Copy link

My workaround was replace the route with a custom action.

routes.yaml

sylius_admin_ajax_product_index:
    path: /admin/ajax/products/
    methods: [GET]
    defaults:
        _controller: AppBundle:Admin\Custom:searchProduct
        _format: json

CustomController.php

    public function searchProductAction(Request $request) {
        $repo = $this->get('sylius.repository.product');

        $criteria = $request->query->get('criteria');
        $q = $criteria['search']['value'];

        $items = $repo->findBySearch($q);

        return new JsonResponse([
            '_embedded' => [
                'items' => $items,
            ]
        ]);
    }

findBySearch is a simple query in ProductRepository.php which returns just id, name and code. You should be able to get the json's schema from a fresh installation.

thank you very mutch you are the best

@seizan8
Copy link

seizan8 commented Jun 9, 2023

Sylius 1.10.14, still running into this issue. I either get an out of memory or max execution time reached error. Or the response simply contains no data. I tried to debug it for like 2 hours but it's not really that simple.
My best guess would be that the JMS serializer gets trapped in an endless loop when it actually finds a product.

Overwritting the route with a custom action is very simple and works easily. So thanks once more to @Takeno for this work around.

@carlosromero
Copy link

carlosromero commented Jun 6, 2024

I think the error is related with new attributes added to Product entity that the Default serilization is not able to serialize properly, in my case it was solved replacing in the route declaration serialization_groups:[Default] by serialization_groups: {0: Default, items: [Autocomplete]}

Add to the final of config/routes/sylius_admin.yaml:

sylius_admin_ajax_product_index:
    path: /admin/ajax/products/
    methods: [GET]
    defaults:
        _controller: sylius.controller.product::indexAction
        _format: json
        _sylius:
            serialization_groups: {0: Default, items: [Autocomplete]}
            permission: true
            grid: sylius_admin_product

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Potential Bug Potential bugs or bugfixes, that needs to be reproduced.
Projects
None yet
Development

Successfully merging a pull request may close this issue.