========= UPDATE =========
I accepted simonthesorcerer response, but it didn't work for me.
I found a free module you can get on this url: http://www.magentocommerce.com/magento-connect/thirty4+interactive/extension/841/catalog-sale-items
it works fine on CE 1.7.0.2 if you install it manually from here: http://freegento.com/magento-extensions/Thirty4_CatalogSale-0.6.3_ready2paste.tgz
Download, unzip and move the files in the folders into your magento installation.
Hope this gonna be useful to somebody!!
========= END OF UPDATE =========
I'm trying to make a special price page... After trying and retrying and after several fails, I came up with this:
I've created a file called: special.php into this path: app/code/local/Mage/Catalog/Block/Product/
with this code:
<?php
class Mage_Catalog_Block_Product_Special extends Mage_Catalog_Block_Product_List {
function get_prod_count() {
Mage::getSingleton('catalog/session')->unsLimitPage();
return (isset($_REQUEST['limit'])) ? intval($_REQUEST['limit']) : 300;
}
function get_cur_page() {
return (isset($_REQUEST['p'])) ? intval($_REQUEST['p']) : 1;
}
protected function _getProductCollection() {
$todayDate = Mage::app()->getLocale()->date()->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
$tomorrow = mktime(0, 0, 0, date('m'), date('d')+1, date('y'));
$dateTomorrow = date('m/d/y', $tomorrow);
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
$collection = $this->_addProductAttributesAndPrices($collection)
->addStoreFilter()
->addAttributeToSort('entity_id', 'desc')
->addAttributeToFilter('special_from_date', array('date' => true, 'to' => $todayDate))
->addAttributeToFilter('special_to_date', array('or'=> array(0 => array('date' => true, 'from' => $dateTomorrow), 1 => array('is' => new Zend_Db_Expr('null')))), 'left')
->setPageSize($this->get_prod_count())
->setCurPage($this->get_cur_page());
$this->setProductCollection($collection);
return $collection;
}
}
?>
after that
I've created a file called: special.phtml into this path: app/design/frontend/default/MY THEME NAME/template/catalog/product/
with this code:
<?php
$columnsCount = 3;
if (($_products = $this->getProductCollection()) && $_products->getSize()):
?>
<div class="category-products">
<ol class="products-grid" style="list-style: none;">
<?php $i = 0; foreach ($_products->getItems() as $_product): ?>
<?php // if($i++%$columnsCount == 0) : ?><?php // endif; ?>
<li class="item<?php if( ++$_iterator == sizeof($_productCollection) ): ?> last<?php endif; ?>">
<?php // Product Image ?>
<a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(300, 200); ?>" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" />
</a>
<div class="product-shop">
<div class="f-fix">
<?php // Product Title ?>
<h2 class="the-product-manufacturer-grid"><a href=""><?php echo $_product->getAttributeText('manufacturer') ?></a><span class="the-product-name-grid"> / <a class="product-name" href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->htmlEscape($_product->getName()) ?>)"><?php echo $this->htmlEscape($_product->getName()) ?></a></span></h2>
<?php // Product Price ?>
<div class="listpricebox"><?php echo $this->getPriceHtml($_product, true, $this->getPriceSuffix()) ?></div>
</div>
</div>
</li>
<?php // if($i%$columnsCount == 0 || $i == count($_products)): ?><?php // endif; ?>
<?php endforeach; ?>
</ol>
</div>
<script type="text/javascript">decorateGeneric($$('.grid-row'), ['first', 'last', 'odd', 'even']);</script>
<?php endif; ?>
and finally I'm calling all this stuff into a CMS page
{{block type="catalog/product_special" template="catalog/product/special.phtml"}}
now, everything is working fine except the fact that this page only shows products with a special price set one-by-one by editing the product. But the biggest part of my products are made in sale via Catalog Price Rules Do somebody have an idea can I show both Catalog Price Rules products and "Special Price" Products?
====== UPDATE ======
Here's the code
<?php
class Mage_Catalog_Block_Product_Special extends Mage_Catalog_Block_Product_List {
protected function _getProductCollection() {
// we need the date to filter for the special price
$dateToday = date('m/d/y');
$tomorrow = mktime(0, 0, 0, date('m'), date('d')+1, date('y'));
$dateTomorrow = date('m/d/y', $tomorrow);
// this gets the product collection and filters for special price;
// grabs products with special_from_date at least today, and special_to_date at least tomorrow
$_productCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('special_from_date', array('date' => true, 'to' => $dateToday))
->addAttributeToFilter('special_to_date', array('date' => true, 'from' => $dateTomorrow))
->load();
// this loads the standard magento catalog proce rule model
$rules = Mage::getResourceModel('catalogrule/rule_collection')->load();
// read: if there are active rules
if($rules->getData()) {
$rule_ids = array(); // i used this down below to style the products according to which rule affected
$productIds[] = array(); // this will hold the ids of the products
foreach($rules as $rule) {
$rule_ids[] = $rule->getId();
$productIds = $rule->getMatchingProductIds(); // affected products come in here
}
// merge the collections: $arr is an array and keeps all product IDs we fetched before with the special-price-stuff
$arr = $_productCollection->getAllIds();
if($productIds) {
// if there are products affected by catalog price rules, $arr now also keeps their IDs
$arr = array_merge($arr,$productIds);
}
// we initialize a new collection and filter solely by the product IDs we got before, read: select all products with their entity_id in $arr
$_productCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id',array('in'=>$arr))
->load();
}
}
}