How can I make Magento sort products in the catalog by the date they were added? This isn't an option in the admin so guessing it needs to be done in the code somewhere.
Thanks.
It is quite easy to add a sorting by date option if you're OK (you shouldn't be) with modifying core files. Simply modify app/code/core/Mage/Catalog/Model/Config.php file as in example below:
public function getAttributeUsedForSortByArray()
{
$options = array(
'position' => Mage::helper('catalog')->__('Position'),
// HERE IS OUR NEW OPTION
'created_at' => Mage::helper('catalog')->__('Date')
);
foreach ($this->getAttributesUsedForSortBy() as $attribute) {
/* #var $attribute Mage_Eav_Model_Entity_Attribute_Abstract */
$options[$attribute->getAttributeCode()] = $attribute->getStoreLabel();
}
return $options;
}
It is not so easy, if you are not into modifying core files. In that case you must create this bunch of files:
app/etc/modules/Stackoverflow_Catalog.xml
<?xml version="1.0"?>
<config>
<modules>
<Stackoverflow_Catalog>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog />
</depends>
</Stackoverflow_Catalog>
</modules>
</config>
app/code/local/Stackoverflow/Catalog/etc/config.xml
<?xml version="1.0"?>
<config>
<global>
<models>
<catalog>
<rewrite>
<config>Stackoverflow_Catalog_Model_Config</config>
</rewrite>
</catalog>
</models>
</global>
</config>
app/code/local/Stackoverflow/Catalog/Model/Config.php
<?php
class Stackoverflow_Catalog_Model_Config extends Mage_Catalog_Model_Config {
public function getAttributeUsedForSortByArray() {
$options = parent::getAttributeUsedForSortByArray();
if (!isset($options['created_at'])) {
$options['created_at'] = Mage::helper('catalog')->__('Date');
}
return $options;
}
}
TIP: Go for a clean way, it will pay of in a long run.
Place this code into your local.xml no need to override any Magento core files.
If you override any Magento core files in future upgrade problem will occur
<layout>
<catalog_category_default>
<reference name="product_list">
<action method="setAvailableOrders" json="value">
<value><![CDATA[
{"created_at" : "Latest","price":"Price"}
]]>
</value>
</action>
</reference>
<reference name="product_list_toolbar">
<action method="setDefaultDirection">
<dir>desc</dir>
</action>
</reference>
</catalog_category_default>
</layout>
I solved this by copying app/code/core/Mage/Catalog/Block/Product/List.php into app/code/local and adding some sorting code at the end of its _getProductCollection() method:
// sort by created_at date or entity_id
if(!isset($_GET['order'])) {
$this->_productCollection->getSelect()->reset( Zend_Db_Select::ORDER );
$this->_productCollection->getSelect()->order('e.entity_id desc');
}
return $this->_productCollection;
You can use either 'e.entity_id desc' or 'e.created_at desc' to sort.
Like this
$_newest_productCollection = Mage::getResourceModel('reports/product_collection')
->addAttributeToSelect('*')
->addAttributeToFilter('visibility', $visibility)
->setOrder('created_at', 'desc')
$_newest_productCollection->load();
Yust for update (works with Mage 1.7.0.2):
in an setupscript of an own module:
$installer = $this;
$installer->startSetup();
$productEntityTypeId = Mage::getModel('catalog/product')->getResource()->getEntityType()->getId();
//lets change created_at properties
//////////////////////////////////////////////////
$installer->updateAttribute($productEntityTypeId, 'created_at', array(
'visible_on_front' => true,
'used_in_product_listing' => true
'used_for_sort_by' => 1,
'frontend_label' => 'Created at'
));
$installer->endSetup();
// mark index as "reindex required"
$indexerCodes = array(
'catalog_product_flat'
);
$indexer = Mage::getModel('index/process');
foreach ($indexerCodes as $code) {
$indexer->load($code, 'indexer_code')
->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
}
and in the catalog.xml layout handle:
<block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
...
<action method="setDefaultDirection"><dir>desc</dir></action>
</block>
After this you can select created_at as default sorting in the system configuration or in the catagory display
settings
I'm not sure that there is an easy way to do that, without digging into the core code. However, I haven't tried this but it seems like it should work:
Create a new Date attribute. You'll see that there is an option at the bottom of the attribute options called "Used for sorting in product listing". Select Yes for that. Then and add it to your attribute group. Then when you add a product, just select the current date, and you should be able to use that for sorting. To set the default of that, go into System >> Configuration >> Catalog >> Frontend and you'll see your attribute in the "Product listing sort by" option.
Hope that works out for you.
You can try below
app/code/core/mage/catalog/model/resource/eav/mysql4/product/collection.php
in "public function addAttributeToSort($attribute, $dir='asc')"
after
$this->getSelect()->order("cat_index_position {$dir}");
add this
$this->getSelect()->order("e.entity_id desc");
I've done it by rewriting the class:
Mage_Catalog_Model_Category_Attribute_Source_Sortby
and function:
public function getAllOptions()
{
if (is_null($this->_options)) {
$this->_options = array(array(
'label' => Mage::helper('catalog')->__('Best Value'),
'value' => 'position'
));
$this->_options = array(array(
'label' => Mage::helper('catalog')->__('Created At'),
'value' => 'created_at'
));
foreach ($this->_getCatalogConfig()->getAttributesUsedForSortBy() as $attribute) {
$this->_options[] = array(
'label' => Mage::helper('catalog')->__($attribute['frontend_label']),
'value' => $attribute['attribute_code']
);
}
}
return $this->_options;
}
Related
I am trying to rewrite product_new block. Purpose is that i want to add category_id field and fetch new products of one category only. Here is the code
app\code\local\Foo\Bar\Block\Product\New.php
class Foo_Bar_Block_Product_New extends Mage_Catalog_Block_Product_New
{
protected function _beforeToHtml()
{
// echo "aaaaaaasdfa";
$todayDate = Mage::app()->getLocale()->date()->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
$collection = $this->_addProductAttributesAndPrices($collection)
->addStoreFilter()
->addAttributeToFilter('news_from_date', array('date' => true, 'to' => $todayDate))
->addAttributeToFilter('news_to_date', array('or'=> array(
0 => array('date' => true, 'from' => $todayDate),
1 => array('is' => new Zend_Db_Expr('null')))
), 'left')
->addAttributeToSort('news_from_date', 'desc')
->setPageSize($this->getProductsCount())
->setCurPage(1)
;
if($categoryId=$this->getData('category_id')){
$category = Mage::getModel('catalog/category')->load($categoryId);
$collection->addCategoryFilter($category);
}
$this->setProductCollection($collection);
return parent::_beforeToHtml();
}
}
Added block in local.xml using below code
<block type="foo_bar/product_new" name="new_products_list" template="catalog/product/new.phtml">
<action method="setCategoryId"><category_id>4</category_id></action>
<action method="setColumnCount"><columns>4</columns></action>
</block>
module's config.xml is
<global>
<blocks>
<catalog>
<rewrite>
<product_new>Foo_Bar_Block_Product_New</product_new>
</rewrite>
</catalog>
</blocks>
</global>
Please guide me where I am making mistake
Thanks
Issue is on parent::_beforeToHtml(); statement it will call _beforeToHtml method of parent class which is Mage_Catalog_Block_Product_New. So parent function will override collection which you have set.
Solution:
Replace :
parent::_beforeToHtml();
to :
Mage_Catalog_Block_Product_Abstract::_beforeToHtml();
I'm not sure why, but I can't filter my attribute (it works fine with defaults ones).
Here is my code :
Config.xml
<global>
<blocks>
<adminhtml>
<rewrite>
<customer_grid>SaponeWebConcept_PrivateSells_Adminhtml_Block_Customer_Grid</customer_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
Grid.php
public function setCollection($collection)
{
$collection->addAttributeToSelect('wants_to_be_vip');
parent::setCollection($collection);
}
protected function _prepareColumns()
{
parent::_prepareColumns();
$attributeCollection = Mage::getResourceModel('eav/entity_attribute_collection')
->setCodeFilter('wants_to_be_vip')
->getFirstItem();
$itemsOptions = $attributeCollection->getSource()->getAllOptions(false);
$optionsArr = array();
foreach ($itemsOptions as $option) {
$optionsArr[$option['value']] = $option['label'];
}
$this->addColumn('V.I.P', array(
'header'=> Mage::helper('customer')->__('Veut devenir V.I.P'),
'index' => 'wants_to_be_vip',
'type' => 'options',
'options' => $optionsArr,
));
$this->addColumnsOrder('customer_id','wants_to_be_vip');
}
Thanks for you help !
Edit : It may need some more infos :
- Values display ok.
- My select box is ok too.
- When I press the filter button, it loads, and nothing changes.
I am looking for some advice or information on how to do the following. I want to add one more menu in magento admin panel. I am trying many ways but not working. How can i add extra one menu in admin panel. please advise...
If this is your custom module what you need to do is in etc/config.xml add the following:
<adminhtml>
<menu>
<report>
<children>
<module name>
<title>Title to show in the menu bar</title>
<sort_order>0</sort_order>
<action>Modules controller action</action>
</module name>
</children>
</report>
</menu>
</adminhtml>
The example above will add a new item to the reports tab and trigger an action in the controller to do something. Hope this helps.
You can add menu using custom module
the below tutorial help me a lot
please click here
I am creating one module.
info - Company name folder
ExtendedMenu - Module Name
I am creating 2 new folders in modules folder.
etc & Block
etc folder I am creating config.xml file
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Info_ExtendedMenu>
<version>0.1.0</version>
</Info_ExtendedMenu>
</modules>
<global>
<blocks>
<configurable>
<class>Info_Configurable_Block</class>
</configurable>
<adminhtml>
<rewrite>
<page_menu>Info_ExtendedMenu_Block_Adminhtml_Menu</page_menu>
</rewrite>
</adminhtml>
</blocks>
<blocks>
<configurable>
<class>Inchoo_Configurable_Block</class>
</configurable>
</blocks>
</global>
</config>
Block -- Adminhtml - Menu.php
<?php
class Info_ExtendedMenu_Block_Adminhtml_Menu extends Mage_Adminhtml_Block_Page_Menu
{
public function getMenuArray()
{
//Load standard menu
$parentArr = parent::getMenuArray();
//Prepare "View Sites" menu
$parentArr['view_sites'] = array(
'label' => 'Web2Print',
'active'=>false ,
'sort_order'=>0,
'click' => 'return false;',
'url'=>'#',
'level'=>0,
'last'=> true,
'children' => array()
);
$app = Mage::app();
$j = 0;
$allWebsites = $app->getWebsites();
$totalWebsiteCount = count($allWebsites) - 1;
foreach ($allWebsites as $_eachWebsiteId => $websiteVal){
$_storeName = $app->getWebsite($_eachWebsiteId)->getName();
$baseUrl = $app->getStore($_eachStoreId)->getUrl();
$_websiteUrl = array(
'label' => 'View Admin',
'active' => false ,
'click' => "var extraurl='w2p/admin/index.php';alert(this.href+extraurl); window.open(this.href+extraurl, 'Website - '+ this.href); return false;",
'sort_order' => $i++ * 10,
'level' => 2,
'url' => $baseUrl
);
if(count($parentArr['view_sites']['children']) == $totalWebsiteCount){
$_websiteUrl['last'] = true;
} else {
$_websiteUrl['last'] = false;
}
$parentArr['view_sites']['children'][$j - 1] = $_websiteUrl;
$allStores = $app->getWebsite($app->getWebsite($_eachWebsiteId)->getId())->getStores();
$totalCount = count($allStores);
$i = 0;
foreach ($allStores as $_eachStoreId => $val){
$_websiteId = $app->getStore($_eachStoreId)->getWebsiteId();
if($_websiteId == $j){
$_storeName = 'View Admin';
$baseUrl = $app->getStore($_eachStoreId)->getUrl();
$_websiteUrl = array(
'label' => $_storeName,
'active' => false ,
'click' => "var extraurl='w2p/admin/index.php';alert(this.href+extraurl); window.open(this.href+extraurl, 'Website - '+ this.href); return false;",
'sort_order' => $i++ * 10,
'level' => 2,
'url' => $baseUrl
);
if(count($parentArr['view_sites']['children'][$j - 1]['children']) + 1 == $totalCount or $totalCount == 0)
$_websiteUrl['last'] = true;
else
$_websiteUrl['last'] = false;
$parentArr['view_sites']['children'][$j - 1]['children'][$i] = $_websiteUrl;
}
}
}
return $parentArr;
}
}
Also you need to go to magento base folder path app-etc-modules-youemodule name(Inchoo_ExtendedMenu.xml)
<?xml version="1.0"?>
<config>
<modules>
<Inchoo_ExtendedMenu>
<active>true</active>
<codePool>local</codePool>
</Inchoo_ExtendedMenu>
</modules>
</config>
Menu creation over. cheers.
What menu? Are you talking about an extension?
In order to do that you have: System > Magento connect > Magento connect manager
EDIT:
Theres an extension to manage this, take a look: Custom Menu Magento
On this page I want to add the Manufacturer name directly below the name of the item, but can't seem to get this to work. Have tried a number of suggestions, but none seem to work.
Please be specific on the file and lines to edit.
Try this, assuming that you are using attribute set to create a 'manufacturer' field in Admin -> Catalog -> Manage Attributes.
Write a custom module that extend Catalog Product Block Grid
/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Grid.php
Create Block File: app/code/local/MageIgniter/ManufacturerGrid/Block/AdminhtmlCatalog/Product/Grid.php
class MageIgniter_ManufacturerGrid_Block_Adminhtml_Catalog_Product_Grid extends Mage_Adminhtml_Block_Catalog_Product_Grid
{
Copy method _prepareCollection() to you custom block and update (line 58)
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('sku')
->addAttributeToSelect('name')
->addAttributeToSelect('manufacturer') // added this line
->addAttributeToSelect('attribute_set_id')
->addAttributeToSelect('type_id');
Copy method _prepareColumns() to you custom block and add
$this->addColumn('manufacturer',
array(
'header'=> Mage::helper('catalog')->__('Manufacturer'),
'width' => '60px',
'index' => 'manufacturer',
'type' => 'options';
'options' => Mage::helper('manufacturergrid')->getManufacturerOption(),
));
Create Helper File: app/code/local/MageIgniter/ManufacturerGrid/Helper/Data.php
class MageIgniter_ManufacturerGrid_Helper_Data extends Mage_Core_Helper_Abstract
{
public function getManufacturerOption(){
$_opt = array();
foreach (Mage::getModel('eav/config')->getAttribute('catalog_product','manufacturer')->getSource()->getAllOptions(false,true) as $option){
$_opt[$option['value']] = $option['label'];
}
return $_opt;
}
}
Create: app/code/local/MageIgniter/ManufacturerGrid/etc/config.xml
<config>
<modules>
<MageIgniter_ManufacturerGrid>
<version>1.0.0</version>
</MageIgniter_ManufacturerGrid>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<catalog_product_grid>MageIgniter_ManufacturerGrid_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
</rewrite>
</adminhtml>
</blocks>
<helpers>
<localship>
<class>MageIgniter_ManufacturerGrid_Helper</class>
</localship>
</helpers>
</global>
</config>
Create: app/etc/modules/MageIgniter_ManufacturerGrid.xml
<?xml version="1.0"?>
<config>
<modules>
<MageIgniter_ManufacturerGrid>
<active>true</active>
<codePool>local</codePool>
</MageIgniter_ManufacturerGrid>
</modules>
</config>
$manufacturer_items = Mage::getModel('eav/entity_attribute_option')->getCollection()->setStoreFilter()
->join('attribute','attribute.attribute_id=main_table.attribute_id', 'attribute_code');
foreach ($manufacturer_items as $manufacturer_item) :
if ($manufacturer_item->getAttributeCode() == 'manufacturer')
$manufacturer_options[$manufacturer_item->getOptionId()] = $manufacturer_item->getValue();
endforeach;
$this->addColumn('manufacturer',
array(
'header'=> Mage::helper('catalog')->__('Manufacturer'),
'width' => '100px',
'type' => 'options',
'index' => 'manufacturer',
'options' => $manufacturer_options,
));
Put this code in Gird.php file and this code in apoximate line number 58 to 63 in same file
->addAttributeToSelect('manufacturer')
I'm trying to create a tab called Additonal in admin customer edit and place my custom employee attribute in it. Is this possible in via my modules sql setup? This question is relevant only to Magento >= 1.5.1.
$installer = $this;
$installer->startSetup();
$installer->addAttribute('customer', 'employee', array(
'type' => 'int',
'backend' => '',
'frontend' => '',
'label' => 'Employee Status',
'input' => 'select',
'class' => '',
'source' => 'boilerplate/customer_attribute_status',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'visible' => true,
'required' => false,
'user_defined' => false,
'default' => '',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'unique' => false
));
$attribute = Mage::getSingleton('eav/config')->getAttribute('customer', 'employee');
$attribute->addData(array('sort_order'=>50));
$attribute->setData('used_in_forms', array('adminhtml_customer'));
$attribute->save();
Below is not working. Here I'm trying to create a tab in backend admin customer edit and place my emploee attribute in it.
$entityTypeId = $installer->getEntityTypeId('customer');
$attributeId = $installer->getAttributeId('customer', 'employee');
$attributeSets = $installer->_conn->fetchAll('select * from '.$this->getTable('eav/attribute_set').' where entity_type_id=?', $entityTypeId);
foreach ($attributeSets as $attributeSet) {
$setId = $attributeSet['attribute_set_id'];
$installer->addAttributeGroup($entityTypeId, $setId, 'Additional');
$groupId = $installer->getAttributeGroupId($entityTypeId, $setId, 'Additional');
$installer->addAttributeToGroup($entityTypeId, $setId, $groupId, $attributeId);
}
$installer->endSetup();
Here is the code to add a tab in admin's customer edit view:
At your module's admin's layout's .xml file, put:
<adminhtml_customer_edit>
<reference name="customer_edit_tabs">
<action method="addTab"><name>tabs_name</name><block>ModuleAlias/path_to_block_file</block></action>
</reference>
</adminhtml_customer_edit>
your block file should extends Mage_Adminhtml_Block_Template and implements Mage_Adminhtml_Block_Widget_Tab_Interface (meaning that you'll have to implement some methods), and in the construct you can set the template file, ie:
class Namespace_Module_Block_Adminhtml_Customer_Edit_Tab_History
extends Mage_Adminhtml_Block_Template
implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
public function __construct()
{
parent::__construct();
$this->setTemplate('path/to/file.phtml');
}
//down here are the mandatory methods you have to include
public function getTabLabel()
{
return Mage::helper('points')->__('Tab label');
}
public function getTabTitle()
{
return Mage::helper('points')->__('Tab title');
}
public function canShowTab()
{
if (Mage::registry('current_customer')->getId()) {
return true;
}
return false;
}
public function isHidden()
{
if (Mage::registry('current_customer')->getId()) {
return false;
}
return true;
}
}
You also can add AJAX tab instead of load all data with page
for example
<layout>
<adminhtml_catalog_product_edit>
<reference name="product_tabs">
<action method="addTab">
<id>mediagallery</id>
<tab>
<label>MediaGallery</label>
<class>ajax</class>
</tab>
</action>
<action method="setTabData">
<id>mediagallery</id>
<key>url</key>
<value>*/catalog_product_mediagallery/index</value>
</action>
</reference>
</adminhtml_catalog_product_edit>
<adminhtml_catalog_product_mediagallery_index>
<block type="mediagallery/adminhtml_catalog_product_edit_tab_gallery" name="root" output="toHtml" template="mediagallery/container.phtml">
</block>
</adminhtml_catalog_product_mediagallery_index>
<adminhtml_catalog_product_mediagallery_image>
<block type="mediagallery/adminhtml_catalog_product_edit_tab_gallery_image" name="root"></block>
</adminhtml_catalog_product_mediagallery_image>
</layout>
add tab link on handler
set Tab data to set correct url from wehre load conten
in controller you can render content or call layout as in my example
adminhtml_catalog_product_mediagallery_index - render content: grid contained and some custom buttons/
adminhtml_catalog_product_mediagallery_image - grid url for grid which was rendered in previous handle