【问题标题】:Problem with ajax price update when changing options更改选项时出现 ajax 价格更新问题
【发布时间】:2022-08-13 20:46:37
【问题描述】:

我在 Prestashop 网站 (1.7.7.8) 上遇到问题,更改选项时更新价格。 在某些特定情况下,会发生错误并且不显示价格。

你可以在这里看到错误:https://bacom.lebonweb.fr/accueil/32-bache.html

当我们有几个选项时,这个附加在一个特定的场景中;并非所有其他选项都可用(不确定..)。在这种情况下 :

  • “卷起”类型只有 1 个可用尺寸(200 厘米和 85 厘米)。
  • “Bache”类型有其他可用的维度,但与 ROLL UP 类型不同

因此,要查看错误,您可以按照以下步骤操作:

1/去https://bacom.lebonweb.fr/accueil/32-bache.html

2/ 默认情况下 TYPE 是汇总。更改类型选择,选择“Bache”

3/ 选择 Hauteur 和 Largeur 得到了很好的更新,具有 BACHE 类型的可用值(不同于 ROLLUP 类型值)。但是价格消失了,错误是\"无法检索 id_product_attribute\"(调试模式开启)

如果您重新加载页面,该错误就会消失。

一些测试确认问题来自主题;使用经典默认主题相同的场景工作正常(http://www.lebonweb.fr/dev/bacom-test/femmes/2-42-brown-bear-printed-sweater.html

我已经尝试逐个文件(tpl 和 js),用默认主题代码替换自定义主题代码。 但是无法解决这个错误....

我可能缺少 ajax 和 JS 的东西。 我在控制台上注意到了这个警告:\"jQuery(window).on(\'load\'...) 在加载事件发生后调用\"...

但是经过2天的搜索,阅读和测试,仍然无法找到解决方案。 您对我应该在哪里进行更多调查有什么建议或建议吗?

非常感谢


编辑:到以不同的方式解释(更短的^^)问题与我遇到的组合:

示例:我们有 3 种 T 恤组合:

T 恤 - 红色 - 尺码 : 1

T 恤 - 红色 - 2 号

T 恤 - 黑色 - 1 号

更改一个选项可能会自动更改另一个选项值:

第 1 步:选择选项:颜色:红色/尺寸 2

第 2 步:将选项颜色更改为黑色 = 尺寸自动更改为 1

就我而言,似乎默认组合数据(在此示例场景中自动加载的数据)没有发送到获取价格数据的 ajax 请求。 而在页面的其他地方,那些默认数据是很好的。

在另一个根据选项更改计算默认组合的调用之前,可能会调用类似于获取价格的 ajax 调用......?

希望我的问题的其他介绍会有所帮助:)

谢谢 !

    标签: javascript jquery ajax prestashop-1.7


    【解决方案1】:

    所以我更深入地研究了这个,这是一个相当长的细节,所以请告诉我,php堆栈跟踪是:

    Can not retrieve the id_product_attribute
    at line 6582 in file classes/Product.php
    
    6577.                 );
    6578.             }
    6579.         }
    6580. 
    6581.         if (empty($idProductAttribute)) {
    6582.             throw new PrestaShopObjectNotFoundException('Can not retrieve the id_product_attribute');
    6583.         }
    6584. 
    6585.         return $idProductAttribute;
    6586.     }
    6587. 
    
        ProductCore::getIdProductAttributeByIdAttributes - [line 6594 - classes/Product.php] - [3 Arguments]
    
        6589.      * @deprecated 1.7.3.1
        6590.      * @see Product::getIdProductAttributeByIdAttributes()
        6591.      */
        6592.     public static function getIdProductAttributesByIdAttributes($id_product, $id_attributes, $find_best = false)
        6593.     {
        6594.         return self::getIdProductAttributeByIdAttributes($id_product, $id_attributes, $find_best);
        6595.     }
        6596. 
        6597.     /**
        6598.      * Get the combination url anchor of the product.
        6599.      *
    
        ProductCore::getIdProductAttributesByIdAttributes - [line 1391 - modules/ttproductcountdown/ttproductcountdown.php] - [2 Arguments]
    
        1386.             $groups = Tools::getValue('group');
        1387. 
        1388.             if (!empty($groups) && method_exists('Product', 'getIdProductAttributesByIdAttributes')) {
        1389.                 $id_product_attribute = (int) Product::getIdProductAttributesByIdAttributes(
        1390.                     $id_product,
        1391.                     $groups
        1392.                 );
        1393.             }
        1394.         }
        1395.         if ($id_product_attribute === null) {
        1396.             $id_product_attribute = Tools::getValue('id_product_attribute');
    
        TTProductCountdown->hookPSPC - [line 1439 - modules/ttproductcountdown/ttproductcountdown.php] - [1 Arguments]
    
        1434.             ($this->product_position == 'displayProductPriceBlock'
        1435.             || $this->product_list_position == 'over_img'
        1436.             || $this->product_list_position == 'displayProductPriceBlock')
        1437.         ) {
        1438.             $params['hook'] = 'displayProductPriceBlock';
        1439.             return $this->hookPSPC($params);
        1440.         }
        1441.     }
        1442. 
        1443.     public function hookDisplayProductButtons($params)
        1444.     {
    

    电话仍然/现在来自:

    emit("updateProduct", {
                    eventType: "updatedProductCombination",
                    event: e,
                    resp: {},
                    reason: {
                        productUrl: o.default.urls.pages.product || ""
                    }
                }
    

    core.js 中似乎有一个函数

     "updatedProductQuantity" === t && (h = 750),
                    u = setTimeout(function() {
                        "" !== f && (s = r.default.ajax({
                            url: n + (-1 === n.indexOf("?") ? "?" : "&") + f + p,
                            method: "POST",
                            data: {
                                quickview: (0,
                                r.default)(".modal.quickview.in").length,
                                ajax: 1,
                                action: "refresh",
                                quantity_wanted: "updatedProductCombination" === t ? c.attr("min") : c.val()
                            },
                            dataType: "json",
                            beforeSend: function() {
                                null !== s && s.abort()
                            },
                            error: function(e, t, n) {
                                "abort" !== t && 0 === (0,
                                r.default)("section#main > .ajax-error").length && l()
                            },
                            success: function(e, n, i) {
                                var a = (0,
                                r.default)("<div>").append(e.product_cover_thumbnails);
                                (0,
                                r.default)(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").html() !== a.find(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").html() && (0,
                                r.default)(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").replaceWith(e.product_cover_thumbnails),
                                (0,
                                r.default)(".quickview .product-prices, .page-product:not(.modal-open) .row .product-prices, .page-product:not(.modal-open) .product-container .product-prices").first().replaceWith(e.product_prices),
                                (0,
                                r.default)(".quickview .product-customization, .page-product:not(.modal-open) .row .product-customization, .page-product:not(.modal-open) .product-container .product-customization").first().replaceWith(e.product_customization),
                                (0,
                                r.default)(".quickview .product-variants, .page-product:not(.modal-open) .row .product-variants, .page-product:not(.modal-open) .product-container .product-variants").first().replaceWith(e.product_variants),
                                (0,
                                r.default)(".quickview .product-discounts, .page-product:not(.modal-open) .row .product-discounts, .page-product:not(.modal-open) .product-container .product-discounts").first().replaceWith(e.product_discounts),
                                (0,
                                r.default)(".quickview .product-additional-info, .page-product:not(.modal-open) .row .product-additional-info, .page-product:not(.modal-open) .product-container .product-additional-info").first().replaceWith(e.product_additional_info),
                                (0,
                                r.default)(".quickview #product-details, #product-details").replaceWith(e.product_details),
                                (0,
                                r.default)(".quickview .product-flags, .page-product:not(.modal-open) .row .product-flags, .page-product:not(.modal-open) .product-container .product-flags").first().replaceWith(e.product_flags),
                                function(e) {
    
    

    此行是该错误消息的来源:

     r.default)(".quickview .product-prices, .page-product:not(.modal-open) .row .product-prices, .page-product:not(.modal-open) .product-container .product-prices").first().replaceWith(e.product_prices)
    

    它正在注入以下 html :

    '\n\x3C!-- begin _partials/notifications.tpl -->\n\n<aside id="notifications">\n  <div class="container">\n    \n          \n        <article class="alert alert-warning" role="alert" data-alert="warning">\n          <ul>\n                          <li>Can not retrieve the id_product_attribute</li>\n                      </ul>\n        </article>\n      \n    \n    \n      </div>\n</aside>\n\n\x3C!-- end _partials/notifications.tpl -->\n'
    

    如果我通过邮递员或提琴手回复相同的 ajax 调用,我可以重新创建错误,

     <script src="https://bacom.lebonweb.fr/themes/core.js"></script>
    

    如您所说,女巫是一个主题脚本,我认为这是您使用的站点主机或某种插件添加的内容?

    当我将它与有效的主题进行比较时 (http://www.lebonweb.fr/dev/bacom-test/femmes/2-42-brown-bear-printed-sweater.html)

    请求完全不同:

    http://www.lebonweb.fr/dev/bacom-test/index.php?controller=product&token=e75591940fae6ed3e01a3adbbbac3d6c&id_product=2&id_customization=0&group%5B1%5D=2&group%5B2%5D=10&qty=1
    

    此外,core.js 文件完全不同,首先它被最小化了......所以你可以尝试将 core.js 文件从有效的主题复制到无效的主题,看看会发生什么,理论上如果它只是一个主题脚本核心功能应该仍然可以工作,如果没有联系站点提供商或提出值得主题提供商的问题(假设有 github 或类似的东西)并询问他们的主题脚本为什么失败,因为主题脚本不应该采取不同的行动,这有点他们的重点,最好还是取消主题并使用您自己的主题,一个非常好的和广泛使用的主题是https://getbootstrap.com/docs/5.0/getting-started/introduction/ 它易于使用并提供非常好的可定制样式和功能

    我希望这有帮助

    【讨论】:

    • 感谢帕特里克的帮助和分析。我认为文件 theme/core.js 是任何主题通用的文件(主题是必要的,默认情况下是经典的)。无论如何,我的逻辑和你一样,所以我已经尝试将 core.js 文件从经典主题安装复制到错误主题。但这并没有解决问题。 (我也为其他文件尝试了相同的过程)那是我在错误主题上取消了 core.js 的最小化,以帮助调试搜索。在来这里之前我已经尝试了很多东西......
    • 我还测试了 updatedProductQuantity 函数接收到的一些 console.log 参数;但它只确认丢失的数据。我仍然无法通过脚本和参数传输来定义确切的“道路”。但是你带来的一些信息给了我更多关于其他脚本的信息来检查。正如您所注意到的,这种类型的 CMS 具有复杂且非常精简的过程....这就是我讨厌它们的原因 ;) 我也尝试联系主题作者,没有答案...我会再做一次,并继续再次搜索引起此错误的窃听主题添加的代码。
    • 更多信息,如果它可以提供帮助:所有名称以 TT 开头的模块都是一些错误的主题模块(TemplateTrip。)今天早上我试图一一停用,强制使用默认模块而不是错误模板模块。
    【解决方案2】:

    这需要一些调试,我不知道这对你有多大帮助,但我想我还是会尝试......

    js正在调用

    https://bacom.lebonweb.fr/index.php?controller=product&token=7dc88db1baee0ecae0e917cf624997d0&id_product=32&id_customization=0&group%5B20%5D=112&group%5B22%5D=124&group%5B21%5D=113&group%5B11%5D=52&qty=1'
    

    使用以下表单数据:

    controller  product
    token   7dc88db1baee0ecae0e917cf624997d0
    id_product  32
    id_customization    0
    group[20]   112
    group[22]   124
    group[21]   113
    group[11]   52
    qty 1
    

    以及以下身体数据

    quickview   0
    ajax    1
    action  refresh
    quantity_wanted 1
    

    然后这个 api 抛出以下错误:

    Can not retrieve the id_product_attribute
    at line 6582 in file classes/Product.php
    6577.                 );
    6578.             }
    6579.         }
    6580. 
    6581.         if (empty($idProductAttribute)) {
    6582.             throw new PrestaShopObjectNotFoundException('Can not retrieve the id_product_attribute');
    6583.         }
    6584. 
    6585.         return $idProductAttribute;
    6586.     }
    

    电话来自

    function ajaxProductCombinationChange(productId, attributes) {
            $.ajax({
                type: 'POST',
                url: prestashopFacebookAjaxController,
                data: {
                    action: 'CustomizeProduct',
                    ajax: true,
                    id_product: productId,
                    attribute_ids: attributes,
                }
            });
        }
    

    所以我想知道这是一个 php 错误而不是一个 jquery 错误,因为即使我在 edge、chrome 或 firefox 中刷新页面我总是会收到错误?

    我希望这有帮助

    【讨论】:

    • 谢谢帕特里克的帮助!我查看了 php 错误日志,但是当我重现错误时会生成 0 错误...只要删除当前主题时错误消失,我想错误来自主题脚本之一... ?花了这么多小时却找不到任何线索真是令人沮丧。我对那些 CMS 机构真的很不自在……我对其他研究途径持开放态度。谢谢
    • 关于帕特里克的回答,我已经看到函数 ajaxProductCombinationChange(productId, attributes) 在 /modules/ps_facebook 脚本中。删除了这个 fb 模块,以及社交分享。但还是同样的问题...
    【解决方案3】:

    我终于找到了解决问题的方法(但不明白为什么):停用 ttcountdown 模块并清理所有缓存。 帕特里克提供的信息非常有帮助,所以再次感谢帕特里克抽出时间提供帮助! 这个解决方案没问题,因为我的客户不需要任何倒计时功能。

    非常令人沮丧,因为我没有清楚地理解代码中的什么地方和什么引起了这个错误;而我们有很多关于它的元素和数据。

    也许有一个关于 prestashop 1.7 属性更改的链接(请参阅:PrestaShop 1.7 How to get id_product_attribute on product page?):

    在 PrestaShop 1.7.x 版本中,产品属性(尺寸、颜色等) 买方选择的 ID 存储在组变量中 数组,但是这个变量不再包含相关的 id_product_attribute 本身。

    有了这些信息,我猜想也许是这个有问题的主题作者在这次更改之后没有对他的脚本进行干净稳定的改编......?所以我已经尝试对 ttproductcountdown.php 代码进行一些更正,只是为了更好地理解,围绕这些行(模块/ttproductcountdown/ttproductcountdown.php 的第 1360 行的函数 hookPSPC)

    // Get id_product_attribute
            $id_product_attribute = null;
            if (isset($params['id_product_attribute'])) {
                $id_product_attribute = $params['id_product_attribute'];
            } elseif (Tools::getValue('group')) {
                $groups = Tools::getValue('group');
    
                if (!empty($groups) && method_exists('Product', 'getIdProductAttributesByIdAttributes')) {
                    $id_product_attribute = (int) Product::getIdProductAttributesByIdAttributes(
                        $id_product,
                        $groups
                    );
                }
            }
            if ($id_product_attribute === null) {
                $id_product_attribute = Tools::getValue('id_product_attribute');
            }
            $has_attributes = $this->checkProductHasAttributes($id_product);
            if (!$id_product_attribute && $has_attributes) {
                $id_product_attribute = $this->getDefaultIdProductAttribute($id_product);
            }
    
            $hook = (isset($params['hook']) ? $params['hook'] : '');
    
            // render timers for all combinations at once at the product page in PS1.6
            if ($has_attributes && $this->getPSVersion() < 1.7 && $this->context->controller->php_self == 'product') {
                $ipas = Product::getProductAttributesIds($id_product, true);
                foreach ($ipas as $ipa) {
                    $return .= $this->renderCountdown($id_product, $ipa['id_product_attribute'], $hook);
                }
            } else {
                $return = $this->renderCountdown($id_product, $id_product_attribute, $hook);
            }
    

    没有成功...所以只要我不打算经常与 prestashop 合作;一天只有 24 小时;我将“放弃”尝试理解问题。

    Patrick,仅供参考,Prestashop 已经在使用 Boostrap。我想自己做,但是为 prestashop 创建一个主题很长,因为它涵盖了很多页面和功能(购物车、目录、用户帐户等)。

    正如我所说,我避免使用 CMS... 通过单击按钮而不学习任何内容来纠正错误不是我喜欢的工作方式。

    谢谢帕特里克!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      • 2021-02-09
      相关资源
      最近更新 更多