Die von @SanderMangel angebotene Lösung ist erstklassig. Ich kann dazu beitragen, dies mit einem Code zu erweitern, den ich derzeit in meinem Modul Automated / Dynamic Category-Produkte verwende - das die Möglichkeit bietet, Kategorieregeln für bestimmte Produkte zu erstellen
Der Code passt eine Standardproduktkollektion an, um alle Produkte mit einem Sonderpreis zu erhalten, der an dem Tag festgelegt wird, an dem der Code ausgeführt wird. Sie können dies im Cron verwenden, um die Kategorien um 00:00 Uhr neu aufzufüllen und sicherzustellen, dass sie auf dem neuesten Stand sind.
Beachten Sie, dass der Code aus einem größeren Modul extrahiert wird. Daher habe ich die relevanten Teile hier für Sie komprimiert. Es kann eine oder zwei Variablen geben, die in diesem Auszug nicht enthalten sind, aber sie lassen sich leicht ableiten, oder fragen Sie einfach :)
Das $ category-Objekt ist die tatsächliche Kategorie, die die Produkte enthalten soll. Mit dem folgenden Code können Sie den Rabatt auch in% angeben :)
$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);
}
Nun ist zu beachten, dass die Sammlung keine Produkte zurückgibt, da sie Links zu den normalen Katalog- <-> Produktlink-Tabellen enthält. Da Sie nicht an den aktuell verknüpften Produkten interessiert sind, müssen Sie diese Tabellenbeziehung aus der Sammlung löschen.
Ich benutze den folgenden Code, um das zu erledigen:
/**
* 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;
}
Als zusätzlichen Bonus können Sie dieselbe Methode zum Anpassen der Katalogproduktsammlung verwenden und Produkte suchen, die sich aufgrund von Katalogregeln im Spezialmodus befinden:
$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);
Sobald Sie die funktionierende Sammlung haben, müssen Sie nur noch alle IDs aus der Sammlung abrufen, das Array umdrehen und verwenden $category->setPostedProducts($products);
und ein $ category-> save () l; um das Update abzuschließen.
Der Vollständigkeit halber ist hier mein täglicher Cron, der die dynamischen Kategorien auf dem neuesten Stand hält. (Wiederum bezieht es sich auf Methoden, die hier nicht enthalten sind, aber ich bin sicher, dass Sie damit in die richtige Richtung gelangen
Habe Spaß :)
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