Solusi yang ditawarkan oleh @SanderMangel adalah yang terbaik. Saya dapat membantu mengembangkan ini dengan beberapa kode, yang saat ini saya gunakan dalam modul saya Otomatis / Produk Kategori Dinamis - yang memiliki kemampuan untuk melakukan aturan Kategori produk pada khusus
Kode menyesuaikan kumpulan produk standar untuk mendapatkan semua produk dengan harga khusus yang ditetapkan, pada hari kode berjalan. Anda dapat menggunakan ini di cron untuk mengisi kembali kategori pada pukul 00:00, dan memastikan mereka tetap diperbarui.
Perhatikan bahwa kode diekstraksi dari modul yang lebih besar, jadi saya telah memadatkan bagian yang relevan di sini untuk Anda. Mungkin ada satu atau dua variabel yang tidak terwakili dalam ekstrak ini, tetapi mereka akan mudah untuk menyimpulkan, atau hanya bertanya :)
Objek $ kategori adalah kategori aktual yang berisi produk. Kode di bawah ini juga akan memungkinkan Anda untuk menentukan diskon dalam nilai% juga :)
$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);
}
Sekarang, yang perlu diperhatikan adalah bahwa koleksi tidak akan mengembalikan produk, karena berisi tautan ke katalog normal <-> tabel tautan produk. Karena Anda tidak tertarik dengan produk tertaut saat ini, Anda perlu menghapus relasi tabel yang keluar dari koleksi.
Saya menggunakan kode berikut untuk menyelesaikannya:
/**
* 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;
}
sebagai bonus tambahan, Anda dapat menggunakan teknik yang sama dalam menyesuaikan koleksi produk katalog, dan menemukan produk yang berada dalam mode khusus karena aturan katalog:
$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);
Setelah Anda memiliki koleksi yang berfungsi, yang perlu Anda lakukan adalah mendapatkan semua id dari koleksi, membalikkan array, dan menggunakan $category->setPostedProducts($products);
dan $ kategori-> save () l; untuk menyelesaikan pembaruan.
Untuk kelengkapan, berikut adalah cron harian saya yang membuat kategori dinamis tetap mutakhir. (Sekali lagi, ini mengacu pada metode yang tidak termasuk di sini, tapi saya yakin itu akan membuat Anda ke arah yang benar
Selamat bersenang-senang :)
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-category-products.html