thirtybees / blocklayered

Academic Free License v3.0
0 stars 5 forks source link

Manufacturer URL truncates when the word 'Manufacturer' gets translated to anything other (any language). #17

Closed therampagerado closed 1 month ago

therampagerado commented 8 months ago

thirtybees: edge

layered navigation block: last version

When I want to use preselected filters (let's say in my megamenu, like 'products under xx, products of manufacturer XYZ, etc' the manufacturer filter does not work when loading it from URL link if the word manufacturer gets translated. So it's only working in English.

If it's translated the URL is truncated to www.domain.com/category# that displays all products in this category.

If the translation is left empty it works as expected. If Manufacturer is entered it works also.

This bug is centuries old and it's really driving me crazy from the PS times... :D

Hope I managed to describe how to reproduce it.

getdatakick commented 8 months ago

I can't reproduce this.

I translated string Manufacturer in Localization > Translatsions > Installed Modules Translations > Block Layered to "Custom Translation".

This was properly displayed in filters:

image

When clicked, it generated correct uri: /en/coffee-and-tea#/custom_translation-bee_hive

And products were properly filtered.

Please provide exact reprosteps

therampagerado commented 8 months ago

Just tested again, even the latin string 'custom translation' does not work if it's different than 'manufacturer'.

The steps:

  1. Translate 'Manufacturer' to 'something' or 'Производител' (in Bulgarian).
  2. The filters are applied correctly in the URL - domain.eu/bg/gifts#/proizvoditel-bee_hive
  3. Copy this string and enter it in incognito mode.
  4. Anything after #/ is truncated.

If you don't copy and use this link externally everything is fine with whatever is put there.

In PS forum there was a ancient thread that they thought any symbol other than UTF causes this but as you can see 'Производител' is transliterated to 'proizvoditel' and it still does not work.

If I put 'Manufacturer' in my BG translation it is working but it's also displayed in FO which is not nice (not something to die from but... :P )

Use case for this pregenerated URL is lets say in Mega menu (or other links) - 'products of manufacturer X under Y Euro', 'products of manufacturer Z with pink color'. Also it's useful for sharing in social media.

https://www.test.rampagesport.eu/bg/gifts#/proizvoditel-bee_hive

Ancient PS thread: https://www.prestashop.com/forums/topic/227492-layered-navigation-url-link/

therampagerado commented 7 months ago

@getdatakick could you replicate this with my last comments?

therampagerado commented 1 month ago

After long searching I managed to get a potential fix for this issue:

In PS forum: https://www.prestashop.com/forums/topic/617905-filters-in-prestashop-not-working/?do=findComment&comment=3004411

After I changed my modded PS layered module now I'm able to use the manufacturer filter in links. My code becomes:

// Force attributes selection (by url '.../2-mycategory/color-blue' or by get parameter 'selected_filters')
        if (strpos($_SERVER['SCRIPT_FILENAME'], 'blocklayered_mod-ajax.php') === false || Tools::getValue('selected_filters') !== false)
        {
            if (Tools::getValue('selected_filters'))
                $url = Tools::getValue('selected_filters');
            else
                $url = preg_replace('/\/(?:\w*)\/(?:[0-9]+[-\w]*)([^\?]*)\??.*/', '$1', Tools::safeOutput($_SERVER['REQUEST_URI'], true));

            $url_attributes = explode('/', ltrim($url, '/'));
            $selected_filters = array('category' => array());
            if (!empty($url_attributes))
            {
                foreach ($url_attributes as $url_attribute)
                {
                    /* Pagination uses - as separator, can be different from $this->getAnchor() */
                    if (strpos($url_attribute, 'page-') === 0)
                        $url_attribute = str_replace('-', $this->getAnchor(), $url_attribute);
                    $url_parameters = explode($this->getAnchor(), $url_attribute);
                    $attribute_name  = array_shift($url_parameters);

                    if ($attribute_name == 'page')
                        $this->page = (int)$url_parameters[0];
                    else if (in_array($attribute_name, array('price', 'weight')))
                        $selected_filters[$attribute_name] = array($this->filterVar($url_parameters[0]), $this->filterVar($url_parameters[1]));
                    else if ($attribute_name == 'производител') { // Translation for 'manufacturer' as 'Производител'
                        // Replace underscores and dashes with appropriate characters for manufacturer names
                        $manufacturer_name = str_replace("_", " ", $url_parameters[0]);
                        $manufacturer_name_alternate = str_replace("_", "-", $url_parameters[0]);

                        // First attempt to find the manufacturer by name
                        $manufacturers = Db::getInstance()->executeS('SELECT id_manufacturer FROM '._DB_PREFIX_.'manufacturer WHERE name = "'.pSQL($manufacturer_name).'"');

                        if (!empty($manufacturers)) {
                            $selected_filters['manufacturer'] = array($manufacturers[0]['id_manufacturer']);
                        } else {
                            // Try with alternate name format
                            $manufacturers = Db::getInstance()->executeS('SELECT id_manufacturer FROM '._DB_PREFIX_.'manufacturer WHERE name = "'.pSQL($manufacturer_name_alternate).'"');
                            if (!empty($manufacturers)) {
                                $selected_filters['manufacturer'] = array($manufacturers[0]['id_manufacturer']);
                            }
                        }
                    }
                    else {
                        foreach ($url_parameters as $url_parameter) {
                            $data = Db::getInstance()->getValue('SELECT data FROM `'._DB_PREFIX_.'layered_friendly_url` WHERE `url_key` = \''.md5('/'.$attribute_name.$this->getAnchor().$url_parameter).'\'');
                            if ($data) {
                                foreach (Tools::unSerialize($data) as $key_params => $params) {
                                    if (!isset($selected_filters[$key_params]))
                                        $selected_filters[$key_params] = array();
                                    foreach ($params as $key_param => $param) {
                                        if (!isset($selected_filters[$key_params][$key_param]))
                                            $selected_filters[$key_params][$key_param] = array();
                                        $selected_filters[$key_params][$key_param] = $this->filterVar($param);
                                    }
                                }
                            }
                        }
                    }

                }
                return $selected_filters;
            }
        }

Dirty fix but until somebody is able to replicate the issue, this might help.

In the thirty bees Layered Navigation module this part is around line 2135, the code of course is slightly different but I'm able to replicate the same issue there.

getdatakick commented 1 month ago

I've reproduced the problem. The issue was in custom translation function this module is using. It did not load translations stored in themes, and it also incorrectly merged them.

@therampagerado you have to rebuild URL index after you apply the fix.

therampagerado commented 1 month ago

Thank you for looking into this @getdatakick !

I'm afraid it is not quite fixed. Please go to this link and see how the manufacturer part is removed: https://test2.rampagesport.eu/bg/подаръци#/производител-bee_hive

getdatakick commented 1 month ago

Works for me on my local environment.

Did you rebuild URL index?

image

therampagerado commented 1 month ago

Yes, but let me check if it populates in the table as I had problems with those previously.

getdatakick commented 1 month ago

There was another bug, see latest commit. Please re-test and let me know if it helped. If not, please PM me access to your test environment (ftp would be best)

therampagerado commented 1 month ago

Yes, the second fix sorted it. Thank you! Will merge with my PS version!