创建类别页面,显示所有特价产品


12

基本上,我创建了一个“待售产品”类别,我想自动在目录中包含已应用特殊价格的所有产品(通过目录>管理产品)。我希望页面保留标准Magento类别页面包含的分层导航排序功能。

对于大多数Magento用户来说,这似乎是有价值的东西,但令我惊讶的是,它没有包含在核心功能中。

我已经尝试了十多个Stack Exchange答案,博客文章和论坛,但到目前为止没有任何效果。有人为此提供程序化解决方案吗?

===编辑===

基于下面评论中@pspahn的评论,我决定寻求一种实现类似功能的替代方法。话虽如此,如果您有兴趣追求这一行,@ sander-mangel介绍了一种似乎完全可行的方法。


在我看来,“自动包含所有特价产品”的要求有点过分。我认为最终结果是您想要一个上面有特价产品的页面,并使它看起来像类别页面。似乎您可以改为创建自己的模型/集合(基于具有特殊价格的产品),然后根据类别视图页面在模板中使用该集合。我只是没有看到可以自动填充类别的一个很好的解决方案,例如,如何防止用户对其进行修改?
pspahn

@pspahn谢谢您的回复。我了解您的批评并同意您的推理。我可以将Sander Mangel所描述的方法与另外的category_save_after观察者一起使用,以取得良好的效果,但这似乎有些过头。我将提出替代解决方案。
rokkor 2013年

@pspahn-我不明白您的意思是“如何防止用户对其进行修改”-您能否进一步说明?
ProxiBlue 2014年

@ProxiBlue基本上,如果您创建一个类别并自动填充产品,则管理员用户只需在后端进入该类别并手动添加/删除产品即可。
pspahn 2014年

@pspahn好的,我被误解为前端用户。
ProxiBlue 2014年

Answers:


8

最简单的方法是创建一个与Observer和Cronjob一起使用的自定义扩展。

为销售产品创建类别。这样,您可以在前端使用常规的Magento功能,例如分层导航等。

为了自动获得该类别的产品,我们将使用观察者和cronjob。观察者将观察到将catalog_product_save_after产品保存在后端时触发的事件。发生这种情况时,您可以检查special_pricespecial_price_from日期和special_date_to日期,以确定是否需要将产品放入销售类别或从中删除。

cronjob在这里有特别的日期和日期。午夜后的每个晚上,首先清空所有产品的销售类别。然后,使用一个集合来检索所有具有特殊价格且自该日期至今为止处于特殊范围内的产品。如果是这样,请将其移至该销售类别。


7

@SanderMangel提供的解决方案是一流的。我可以通过一些代码来帮助扩展这一点,目前我在模块“自动/动态类别”产品中使用该代码-能够对特殊的产品执行类别规则

该代码调整了标准产品集合,以在代码运行当天获得具有特殊价格设置的所有产品。您可以在cron中使用它在00:00时重新填充类别,并确保它们保持更新。

请注意,代码是从更大的模块中提取的,因此,我在这里为您压缩了相关部分。可能没有一两个变量未在此提取中表示,但是很容易推断出来,或者问一下:)

$ category对象是包含产品的实际类别。下面的代码也将允许您以%值指定折扣:)

$collection = $category->getProductCollection();

$todayDate = Mage::app()->getLocale()->date()->toString(Varien_Date::DATE_INTERNAL_FORMAT);
$collection->addAttributeToFilter(array(
    array(
        'attribute' => "special_to_date",
        'null' => true
    ),
    array(
        'attribute' => "special_to_date",
        'from' => $todayDate,
        //'to'      => $todayDate,
        'date' => true
    )
));
$collection->addAttributeToFilter(array(
    array(
        'attribute' => "special_from_date",
        'null' => true
    ),
    array(
        'attribute' => "special_from_date",
        //'from'    => $todayDate,
        'to' => $todayDate,
        'date' => true
    )
));

$collection->addAttributeToSelect('special_price','left');
$collection->addAttributeToSelect('price','left');
$select = $collection->getSelect();

if (strpos($value, '%') > 0) {
    $value = str_replace('%', '', $value);
    $select->where('( 100 - (( at_special_price.value * 100 ) / at_price.value ) )  ' . $operator . ' ' . $value);
} else {
    $select->where('((at_price.value - at_special_price.value)) ' . $operator . ' ' . $value);
}

现在,要注意的是,该集合将不会返回产品,因为它包含指向常规目录<->产品链接表的链接。由于您对当前的链接产品不感兴趣,因此需要从集合中清除该表关系。

我使用以下代码来完成该任务:

/**
 * Remove Catalog Product Link elements from collection
 * 
 * @param type $collection
 * @return type
 */
public function removeCatProPart($collection)
{
    $select = $collection->getSelect();
    $fromPart = $select->getPart(Zend_Db_Select::FROM);
    $select->reset(Zend_Db_Select::FROM);

    if (array_key_exists('cat_pro', $fromPart)) {
        unset($fromPart['cat_pro']);
        // also remove any reference to the table in the rest of the query
        $columns = $select->getPart(Zend_Db_Select::COLUMNS);
        $columnRemoved = false;
        foreach ($columns as $columnKey => $column) {
            if ($column[0] == 'cat_pro') {
                unset($columns[$columnKey]);
                $columnRemoved = true;
            }
        }

        if ($columnRemoved) {
            $select->setPart(Zend_Db_Select::COLUMNS, $columns);
        }

        $orderPart = $select->getPart(Zend_Db_Select::ORDER);
        $orderRemoved = false;
        foreach ($orderPart as $orderKey => $order) {
            if ($order[0] == 'cat_pro') {
                unset($orderPart[$orderKey]);
                $orderRemoved = true;
            }
        }

        if ($orderRemoved) {
            $select->setPart(Zend_Db_Select::ORDER, $orderPart);
        }
    }
    $select->setPart(Zend_Db_Select::FROM, $fromPart);
    return $collection;
}

另外,您可以使用相同的技巧来调整目录产品集合,并查找由于目录规则而处于特殊模式的产品:

$storeDate = Mage::app()->getLocale()->storeTimeStamp($this->getStoreId());
$value = $this->getValue();
$conditions = 'price_rule.product_id = e.entity_id AND ';
$conditions .= "(from_time = 0
    OR from_time <= " . $storeDate . ")
    AND (to_time = 0
    OR to_time >= " . $storeDate . ") AND ";
$conditions .= "price_rule.rule_id IN (" . $value . ")";
$collection->getSelect()->joinInner(
        array('price_rule' => $collection->getTable('catalogrule/rule_product')), $conditions);
$collection->setFlag('applied_catalog_rule_id', true);
$collection->setFlag('applied_rule', true);

一旦有了工作集合,您所需要做的就是从集合中获取所有ID,翻转数组,然后使用$category->setPostedProducts($products);和$ category-> save()l;。完成更新。

为了完整起见,这是我的日常cron,用于使动态类别保持最新。(再次,它指的是此处未包括的方法,但是我敢肯定,它将为您提供正确的方向

玩得开心 :)

public static function rebuildAllDynamic($schedule)
{
    try {
        $tempDir = sys_get_temp_dir() . "/";
        $fp = fopen($tempDir . "dyncatprod_rebuild.lock", "w+");
        if (flock($fp, LOCK_EX | LOCK_NB)) {
            if (Mage::getStoreConfig('dyncatprod/debug/enabled')) {
                   mage::log("DynCatProd - rebuildAllDynamic");
            }
            if (!Mage::getStoreConfig('dyncatprod/rebuild/max_exec')) {
                ini_set('max_execution_time', 3600); // 1 hour
            }
            $categories = Mage::getModel('catalog/category')
                ->getCollection()
                ->addAttributeToSelect('*')
                ->addIsActiveFilter()
                ->addAttributeToFilter('dynamic_attributes', array('notnull' => true));

            foreach ($categories as $category) {
                $products = Mage::helper('dyncatprod')->getDynamicProductIds($category);
                if (is_array($products)) {
                    if (Mage::getStoreConfig('dyncatprod/debug/enabled')) {
                        mage::log("rebuilding :" . $category->getName() . ' ' . $category->getPath() );
                    }
                    $products = array_flip($products);
                    $category->setPostedProducts($products);
                    $category->setIsDynamic(true);
                    $category->save();
                }
            }
            flock($fp, LOCK_UN); 
            unlink($tempDir . "dyncatprod_rebuild.lock");
        } else {
            mage::log('Could not execute cron for rebuildAllDynamic -file lock is in place, job may be running');
        }
    } catch (Exception $e) {
        flock($fp, LOCK_UN); 
        unlink($tempDir . "dyncatprod_rebuild.lock");
        mage::logException($e);
        return $e->getMessage();
    }
}

参考:http : //www.proxiblue.com.au/magento-dynamic-category-products.html


5

这是应该为您提供目录中所有特价产品的结果集的集合,您可以在一页中显示

$collection = Mage::getResourceModel('catalog/product_collection')
    ->addAttributeToSelect('price')
    ->setStoreId($this->getStoreId());

$date = strtotime(date('Y-m-d')); $current_date = date("Y-m-d hh:mm:ss",$date);

$collection = $collection
    ->addAttributeToFilter('price',
        array('gt'=>0))
    ->addAttributeToFilter('visibility',
        array('neq'=>Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE));

if (Mage::getStoreConfigFlag(Mage_Catalog_Helper_Product_Flat::XML_PATH_USE_PRODUCT_FLAT, $this->getStoreId())){
    $collection = $collection->addAttributeToFilter('special_price',array('lt'=>new Zend_Db_Expr('e.price')));
}
else{
    $collection = $collection->addAttributeToFilter(array(
        array('attribute'=>'special_price','lt'=>new Zend_Db_Expr('at_price.value'))
    ));
}

$collection = $collection->addAttributeToFilter(array(
        array('attribute'=>'special_from_date','lteq'=>$current_date),
        array('attribute'=>'special_from_date','eq'=>''),
        array('attribute'=>'special_from_date','null'=>true)
    ),'','left')
    ->addAttributeToFilter(array(
        array('attribute'=>'special_to_date','gteq'=>$current_date),
        array('attribute'=>'special_to_date','eq'=>''),
        array('attribute'=>'special_to_date','null'=>true)
            ),'','left');

$collection->getSelect()->group('e.entity_id');

return $collection;

有多种方法可以执行此操作,或者创建一个具有自己的控制器,模块和模型的新模块,该模块与Mage类别模块非常相似,或者您可以覆盖Mage类别模块以仅在客户选择特殊类别时运行上述集合。这可以在系统->模块配置中轻松配置。

如果您可以花一些钱,那么我建议在Magento connect上使用以下扩展

对于Magento 1-:

http://www.magentocommerce.com/magento-connect/dynamic-sale-category.htmlhttp://www.scommerce-mage.co.uk/magento-dynamic-sale-category.html

对于Magento 2-:

https://www.scommerce-mage.com/magento2-dynamic-sale-category.html

希望能帮助到你!

干杯


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.