【问题标题】:Virtuemart fails when ps_cart->add() returns false当 ps_cart->add() 返回 false 时,Virtuemart 失败
【发布时间】:2011-11-05 03:59:50
【问题描述】:

我在为某人修改 VM 模块时遇到了一个奇怪的小问题。

我们使用以下代码更改了 ps_cart 类函数 add() 和 update(): 但是,我们注意到,当验证产品数量(负数或字母字符)的任何函数时,页面不会像代码中那样显示错误。

相反,它会将用户带到一个列出所有产品的页面,其中包含以下链接: /index.php?keyword=&category_id=&limitstart=&page=shop.browse&option=com_virtuemart&Itemid=2

我们添加了一个 if 条件来检查购物车中的产品数量,但是当您使用负数或字母数量时,VM 也会这样做。

此外,当发生这种情况时,Firebug 在添加到购物车“事件”生成的 POST 的响应中报告“无法加载源:http://[website]/index.php”。

有没有人知道 ps_cart->add() 的返回值在哪里进行评估以便我们进行故障排除,或者有人对原因有任何想法吗? 以下是 ps_cart 返回 false 的代码,我们插入了中间的 if 条件,但正如我之前提到的,VM 自己的数量检查也会发生同样的情况。

// Check for negative quantity
        if ($quantity < 0) {
            vmRequest::setVar('product_id', $product_id );
            $vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_NEGATIVE',false) );
            return False;
        }

        if ($quantity > 1 || $_SESSION['cart']["idx"] >= 1) {
            vmRequest::setVar('product_id', $product_id );
            $vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_ONLY_ONE',false) );
            return False;
        }

        if ( !is_numeric($quantity) ) {
            vmRequest::setVar('product_id', $product_id );
            $vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_VALID_QUANTITY',false) );
            return False;
        }

将此作为错误报告归档并不是一个解决方案,因为我们有高度定制的虚拟机,升级将是一个巨大的痛苦。

任何帮助将不胜感激。

【问题讨论】:

    标签: php joomla-extensions virtuemart


    【解决方案1】:

    经过一番研究,我设法解决了这个问题。

    对于所有想了解更多有关美国德行如何处理实际添加到购物车的信息的人,我将解释我最终确定问题的过程。不过解决方法很简单。

    表格

    您可能已经注意到大多数 VM 表单都使用 PHP_SELF 作为表单操作。该表单实际上通过隐藏的输入字段提交了大量您无法看到的数据,以向 PHP_SELF 页面提供必要的信息,说明“用户希望使用这些 [产品] 执行此操作 [addCart]”。 addtocartform.tpl.php 的示例,它是“添加到购物车”按钮和数量控制(如果打开)的小表单:

    <form action="<?php echo $mm_action_url ?>index.php" method="post" name="addtocart" id="addtocart<?php echo $i ?>" class="addtocart_form" <?php if( $this->get_cfg( 'useAjaxCartActions', 1 ) && !$notify ) { echo 'onsubmit="handleAddToCart( this.id );"'; } ?>>
    <?php echo $ps_product_attribute->show_quantity_box($product_id,$product_id); ?><br />
    <input type="submit" class="<?php echo $button_cls ?>" value="<?php echo $button_lbl    ?>" title="<?php echo $button_lbl ?>" />
    <input type="hidden" name="category_id" value="<?php echo  @$_REQUEST['category_id'] ?>" />
    <input type="hidden" name="product_id" value="<?php echo $product_id ?>" />
    <input type="hidden" name="prod_id[]" value="<?php echo $product_id ?>" />
    <input type="hidden" name="page" value="shop.cart" />
    <input type="hidden" name="func" value="cartadd" />
    <input type="hidden" name="Itemid" value="<?php echo $sess->getShopItemid() ?>" />
    <input type="hidden" name="option" value="com_virtuemart" />
    <input type="hidden" name="set_price[]" value="" />
    <input type="hidden" name="adjust_price[]" value="" />
    <input type="hidden" name="master_product[]" value="" />
    

    因此,除了数量控件(由 show_quantity_box() 添加)和提交按钮外,您还可以看到正在传递的大量其他数据。其中有 func="cartadd" 和 product_id=[product id]。

    处理表单

    与简单的表单 POST 不同,您只需要一个预先确定的表单中的数据,VM 使用一个名为“virtuemart_parser.php”的文件。该文件检查提交的“func”以检查用户正在尝试做什么。然后解析器将检查是否注册了这样的函数(请记住,您可以在 VM 配置中添加自己的函数),如果是,它将执行它。 [virtuemart_parser.php 第 215-274 行]

    现在,在我们的例子中,当被调用的函数返回 boolean false 时,解析器将执行以下代码:

    $last_page = vmGet( $_SESSION, 'last_page' );
    if( $last_page != HOMEPAGE && !empty( $last_page ) && empty($_REQUEST['ignore_last_page']) ) {
    $page = $last_page;
    }
    

    基本上它检查$_SESSION 中的last_page。在我们的例子中,我们来自 shop.browse,但我们发现的“last_page”实际上设置为 shop.productdetails,因此将我们重定向到产品列表而没有任何警告。

    解决方案

    所以解决方案很简单,我们自己设置了 last_page var,剩下的修改代码如下:

    // Check for negative quantity
            if ($quantity < 0) {
                $_SESSION['last_page'] = 'shop.browse';
                vmRequest::setVar('product_id', $product_id );
                $vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_NEGATIVE',false) );
                return False;
            }
    
            if ($quantity > 1 || $_SESSION['cart']["idx"] >= 1) {
                //$_SESSION['last_page'] = 'shop.browse';
                vmRequest::setVar('product_id', $product_id );
                $vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_ONLY_ONE',false) );
                return False;
            }
    
            if ( !is_numeric($quantity) ) {
                $_SESSION['last_page'] = 'shop.browse';
                vmRequest::setVar('product_id', $product_id );
                $vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_VALID_QUANTITY',false) );
                return False;
            }
    

    ps_cart->add() 自动设置 $_SESSION['last_page']="shop.productdetails" [第 109 行]。我们将其更改为

    $_SESSION['last_page'] = $_SESSION['last_page']=="shop.product_details" ? $_SESSION['last_page'] : 'shop.browse';

    这样您就可以处理客户是从详细信息页面还是从类别浏览页面添加产品的。如果客户从浏览页面添加产品 - 这将显示错误,如果他从 product_details 页面添加产品,他将在 shop.cart 页面收到错误。 [product_details 似乎没有对函数返回的错误进行任何处理]

    希望这对某些人有所帮助。

    【讨论】:

    • 注意:ps_cart->add() 自动设置 $_SESSION['last_page']="shop.productdetails" [第 109 行]。我们将其更改为 $_SESSION['last_page'] = $_SESSION['last_page']=="shop.product_details" ? $_SESSION['last_page'] : 'shop.browse';
    • 请将您的上述评论添加到您的答案中:-)
    猜你喜欢
    • 2023-03-20
    • 2016-01-27
    • 1970-01-01
    • 2018-03-02
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    相关资源
    最近更新 更多