Giải pháp được cung cấp bởi @SanderMangel là đỉnh cao. Tôi có thể giúp mở rộng điều này bằng một số mã mà tôi hiện đang sử dụng trong các sản phẩm Mô-đun Tự động / Động của mô-đun của mình - có khả năng thực hiện các quy tắc Danh mục sản phẩm đặc biệt
Mã điều chỉnh một bộ sưu tập sản phẩm tiêu chuẩn để có được tất cả các sản phẩm với giá được đặt đặc biệt, vào ngày mã chạy. Bạn có thể sử dụng điều này trong cron để điền lại các danh mục vào lúc 00:00 và đảm bảo chúng luôn được cập nhật.
Lưu ý rằng mã được trích xuất từ một mô-đun lớn hơn, do đó tôi đã nén các phần có liên quan ở đây cho bạn. Có thể có một hoặc hai biến không được biểu thị trong trích xuất thsi, nhưng chúng sẽ dễ dàng suy ra, hoặc chỉ cần hỏi :)
Đối tượng $ loại là danh mục thực tế có chứa các sản phẩm. Mã dưới đây cũng sẽ cho phép bạn chỉ định giảm giá theo% giá trị :)
$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);
}
Bây giờ, cần lưu ý là bộ sưu tập sẽ không trả lại sản phẩm, vì nó chứa các liên kết đến danh mục sản phẩm thông thường <-> bảng liên kết sản phẩm. Vì bạn không quan tâm đến các sản phẩm được liên kết hiện tại, bạn cần xóa mối quan hệ bảng đó ra khỏi bộ sưu tập.
Tôi sử dụng đoạn mã sau để hoàn thành nó:
/**
* 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;
}
như một phần thưởng bổ sung, bạn có thể sử dụng cùng teqnique trong việc điều chỉnh bộ sưu tập sản phẩm danh mục và tìm các sản phẩm ở chế độ đặc biệt do quy tắc danh mục:
$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);
Khi bạn có bộ sưu tập đang hoạt động, tất cả những gì bạn cần làm là lấy tất cả các id từ bộ sưu tập, lật mảng và sử dụng $category->setPostedProducts($products);
và một danh mục $ -> save () l; để hoàn thành cập nhật.
Để hoàn thiện, đây là cron hàng ngày của tôi giúp cập nhật các danh mục động. (một lần nữa, nó đề cập đến các phương pháp không được bao gồm ở đây, nhưng tôi chắc chắn rằng nó sẽ giúp bạn đi đúng hướng
Chúc vui vẻ :)
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();
}
}
ref: http://www.proxiblue.com.au/magento-dynamic-carget-products.html