Magento 2.2 Advanced Search – Search Multiple SKUs

advanced-searchmagento2magento2.2

I am trying to use Magento's Advanced search in an effort to return multiple SKUs.

I have tried methods via the frontend/url like searching using quotes, +, & and more..

"SKU1""SKU2"
SKU1&SKU2
SKU1+SKU2
etc.

but they always tend to return either no result or the first SKU and nothing more. Is there a way to change the advanced search formula (and only the advanced search version as we have an extension working perfectly for regular use, we are just attempting to use the advanced search as another means to get this side necessity accomplished)

Be it from the backend editing within /vendor/magento/module-catalog-search/ or anywhere else? Surely there should be a possible/relatively easy solution.

UPDATE EDITS:

Trying to use the URL directly by replacing SKU1 and SKU2 with proper sku's doesn't work and throws the below error. Trying to use the advanced search form and searching with either a space between the SKUs or a comma just throws the error of not finding any matches.

The error at this time that I am receiving is;

Exception #0 (Exception): Notice: Array to string conversion in /app/design/frontend/CleverSoft/core/Magento_CatalogSearch/templates/advanced/result.phtml on line 39
#0 [internal function]: Magento\Framework\App\ErrorHandler->handler(8, 'Array to string...', '/home/location...', 39, Array)
#1 /app/design/frontend/CleverSoft/core/Magento_CatalogSearch/templates/advanced/result.phtml(39): implode(',', Array)
#2 /vendor/magento/framework/View/TemplateEngine/Php.php(59): include('/home/location...')
#3 /vendor/magento/framework/View/Element/Template.php(270): Magento\Framework\View\TemplateEngine\Php->render(Object(Magento\CatalogSearch\Block\Advanced\Result), '/home/location...', Array)
#4 /vendor/magento/framework/View/Element/Template.php(300): Magento\Framework\View\Element\Template->fetchView('/home/location...')
#5 /vendor/magento/framework/View/Element/AbstractBlock.php(667): Magento\Framework\View\Element\Template->_toHtml()
#6 /vendor/magento/framework/View/Layout.php(558): Magento\Framework\View\Element\AbstractBlock->toHtml()
#7 /vendor/magento/framework/View/Layout.php(534): Magento\Framework\View\Layout->_renderBlock('catalogsearch_a...')
#8 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('catalogsearch_a...')
#9 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('catalogsearch_a...')
#10 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('content')
#11 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('content')
#12 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('content')
#13 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('main.content.wr...')
#14 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('main.content.wr...')
#15 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('main.content.wr...')
#16 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('main')
#17 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('main')
#18 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('main')
#19 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('columns_schedul...')
#20 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('columns_schedul...')
#21 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('columns_schedul...')
#22 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('columns_schedul...')
#23 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('columns_schedul...')
#24 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('columns_schedul...')
#25 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('columns')
#26 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('columns')
#27 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('columns')
#28 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('main.content_sc...')
#29 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('main.content_sc...')
#30 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('main.content_sc...')
#31 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('main.content')
#32 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('main.content')
#33 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('main.content')
#34 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('page.wrapper')
#35 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('page.wrapper')
#36 /vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout->renderElement('page.wrapper')
#37 /vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('root')
#38 /vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout->renderNonCachedElement('root')
#39 /vendor/magento/framework/View/Layout.php(954): Magento\Framework\View\Layout->renderElement('root')
#40 /vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\Layout->getOutput()
#41 /vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\View\Layout\Interceptor->___callParent('getOutput', Array)
#42 /vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\View\Layout\Interceptor->Magento\Framework\Interception\{closure}()
#43 /generated/code/Magento/Framework/View/Layout/Interceptor.php(39): Magento\Framework\View\Layout\Interceptor->___callPlugins('getOutput', Array, Array)
#44 /vendor/magento/framework/View/Result/Page.php(257): Magento\Framework\View\Layout\Interceptor->getOutput()
#45 /vendor/magento/framework/View/Result/Layout.php(170): Magento\Framework\View\Result\Page->render(Object(Magento\Framework\App\Response\Http\Interceptor))
#46 /vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\Result\Layout->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#47 /vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\View\Result\Page\Interceptor->___callParent('renderResult', Array)
#48 /vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#49 /generated/code/Magento/Framework/View/Result/Page/Interceptor.php(26): Magento\Framework\View\Result\Page\Interceptor->___callPlugins('renderResult', Array, Array)
#50 /vendor/magento/framework/App/View.php(221): Magento\Framework\View\Result\Page\Interceptor->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#51 /vendor/magento/module-catalog-search/Controller/Advanced/Result.php(55): Magento\Framework\App\View->renderLayout()
#52 /vendor/magento/framework/App/Action/Action.php(107): Magento\CatalogSearch\Controller\Advanced\Result->execute()
#53 /vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\Action\Action->dispatch(Object(Magento\Framework\App\Request\Http))
#54 /vendor/magento/framework/Interception/Interceptor.php(138): Magento\CatalogSearch\Controller\Advanced\Result\Interceptor->___callParent('dispatch', Array)
#55 /vendor/magento/framework/Interception/Interceptor.php(153): Magento\CatalogSearch\Controller\Advanced\Result\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#56 /generated/code/Magento/CatalogSearch/Controller/Advanced/Result/Interceptor.php(26): Magento\CatalogSearch\Controller\Advanced\Result\Interceptor->___callPlugins('dispatch', Array, Array)
#57 /vendor/magento/framework/App/FrontController.php(55): Magento\CatalogSearch\Controller\Advanced\Result\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#58 /vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#59 /vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#60 /vendor/magento/module-store/App/FrontController/Plugin/RequestPreprocessor.php(94): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#61 /vendor/magento/framework/Interception/Interceptor.php(135): Magento\Store\App\FrontController\Plugin\RequestPreprocessor->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#62 /vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php(73): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#63 /vendor/magento/framework/Interception/Interceptor.php(135): Magento\PageCache\Model\App\FrontController\BuiltinPlugin->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#64 /vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#65 /generated/code/Magento/Framework/App/FrontController/Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, NULL)
#66 /vendor/magento/framework/App/Http.php(135): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#67 /vendor/magento/framework/App/Bootstrap.php(256): Magento\Framework\App\Http->launch()
#68 /index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http\Interceptor))
#69 {main}

While having the code as is;
/app/design/frontend/CleverSoft/core/Magento_CatalogSearch/templates/advanced/result.phtml

<div class="search summary">
    <?php foreach (['left', 'right'] as $side): ?>
        <?php if (@$searchCriterias[$side]): ?>
            <ul class="items">
                <?php foreach ($searchCriterias[$side] as $criteria): ?>

    <?php $criteria['value'] = is_array($criteria['value']) ? implode(",",$criteria['value']) : $criteria['value']; ?>

                    <li class="item"><strong><?= $block->escapeHtml(__($criteria['name'])) ?>:</strong> <?= $block->escapeHtml($criteria['value']) ?></li>

    <script>console.log('testing if works');</script>

                <?php endforeach; ?>
            </ul>
        <?php endif; ?>
    <?php endforeach; ?>

Using the Advanced Search page (/catalogsearch/advanced/) and searching shows the message in the console so it's loading it, but shows incorrectly in that it isn't seeing the separate SKUs. However when trying to use the exact URL and replacing SKU1 with SKU2 is when the error seems to come.

I am using Magento CE 2.2.4 for clarity.

EDIT 2:

Success! Kind of. 🙂 So the below string will work and supply the three requested SKUs;

https://example.com/catalogsearch/advanced/result/?sku[in][]=SKU1&sku[in][]=SKU2&sku[in][]=SKU3

What I did (and had to remove to get there);

What works now;

<div class="search summary">
    <?php foreach (['left', 'right'] as $side): ?>
        <?php if (@$searchCriterias[$side]): ?>
            <ul class="items">
                <?php foreach ($searchCriterias[$side] as $criteria): ?>

                <?php endforeach; ?>
            </ul>
        <?php endif; ?>
    <?php endforeach; ?>
</div>

What was removed;

<li class="item"><strong><?= $block->escapeHtml(__($criteria['name'])) ?>:</strong> <?= $block->escapeHtml($criteria['value']) ?></li>

Which was inside the foreach loop. Not sure if this was ideal, but I gave it a shot and removing so got everything working correct. I knew the criteria was correct because doing a print_r($criteria['value']); would give:

Array
(
    [in] => Array
        (
            [0] => SKU1
            [1] => SKU2
            [2] => SKU3
        )

)

Best Answer

By default the sku attribute is configured to provide wildcard searches, that means that the query for the value of this field is build in the way sku LIKE '%[FIELD_VALUE]%'.

So if you want to use another type of search (i.e. in your case one solution would be to use IN (FIELD_VALUE1, FIELD_VALUE2) insetad of sku LIKE '%[FIELD_VALUE]%') you have first of all change the filter for the sku field. Then you can either change the form for advanced search (to provide an array for the values) or manipulate the input using a plugin before the execute method in controller Magento\CatalogSearch\Controller\Advanced\Result and split the input to get the needed array.

change of search configuration:

  1. Copy vendor/Magento/CatalogSearch/etc/search_request.xml into the etc directory of your module (i.e. /app/code/Vendor/Module/etc/)

  2. Change the filter for the sku attribute from wildcardFilter to termFilter

  3. change the version of your module and run php bin/magento setup:upgrade

With this changes done you can use an array for sku parameter with the key in (which defines the type of the query) and multiple values for skus. Just call http://yourmagentohost/index.php/catalogsearch/advanced/result/?sku[]=SKU1&sku[]=SKU2 and will get the result.

There is also a small issue in the result.phtml template, where the usage of an array for the sku causes an error because a string is expected, you just have to do something like implode there, for example this line in the serachCriterias loop would do it:

<?php $criteria['value'] = is_array($criteria['value']) ? implode(",",$criteria['value']) : $criteria['value']; ?>

To overwrite the template you need to copy the original template from vendor/magento/module-catalog-search/view/frontend/templates/advanced/result.phtml into your theme directory app/design/frontend/Vendor/themename/Magento_CatalogSearch/templates/advanced/result.phtml

Now you can change the logic in the form to create this kind of requests for your sku and you're done.

If you don't want to change the form, you can use a plugin before the execute method in controller Magento\CatalogSearch\Controller\Advanced\Result like the following:

namespace Vendor\Module\Plugin;

class AdvancedSearch
{
    protected $_context;

    public function __construct(
        Context $context
        ){
        $this->_context = $context;   

    }
    public function beforeExecute(\Magento\CatalogSearch\Controller\Advanced\Result $subject)
    {
        $request = $this->_context->getRequest();
        $queryValue = $request->getQueryValue();
        if (isset($queryValue['sku'])){
            $queryValue['sku'] = explode(" ", $queryValue['sku']);
        }
        $request->setQueryValue($queryValue);
    }
}

With this changes you will be able to search for multiple skus spearated by space but you won't be able to search for parts of skus (i.e. LIKE queries). Setting the filter (e.g. wildcard filter if no list of skus is given) depending on your input would be more complicated, I guess.

Related Topic