Hello everyone! I’ve created a small and simple module that creates “Remember Me” functionality to any Magento website. Its currently in testing phase, so I’d say it’s an alpha release.
Never mind the alpha release (v 0.1.0), if someone is willing to try it and trace possible bugs, I’ll do my best to fix them.
Module doesn’t have any admin functionality. Though it can be disabled through admin at any time. There’s a small change on customer/form/login.phtml file (added checkbox with input name set), and besides that, only thing is that this module will save hashed and salted Magento customer’s password hash in a cookie, so it is safe as it can be (if I’m wrong, I’m opened for suggestions).
There’s nothing else to say besides it’s placed on login form for Magento customers. It looks like this:
As far as setting it up goes, you only need to extract attached file over your “app” folder (it won’t overwrite anything, I’ve set it up like this because of the folder structure).
And a small note, It’s been tested on community version 1.4.
And here’s the download link.
And one last thing, I’d like to hear your opinions on this one, as this is fist module that I’ve created and have given it to public.
Cheers!
December 27, 2010
Magento 1.4.0.1 Google Analytics fix
If you updated to latest Magento 1.4.0.0 or 1.4.0.1 version you may notice that Google Analytics implementation is broken. Here are few easy instructions how to fix this.
Navigate to and open app/code/core/Mage/GoogleAnalytics/Block/Ga.php and add this on line 179
Navigate to and open app/code/core/Mage/GoogleAnalytics/Block/Ga.php and add this on line 179
var _gaq = _gaq || [];
Since this bug is already reported and fix can be seen on latest official svn, I don’t see any harm in modifying core files in this particular situation.
http://www.magentocommerce.com/bug-tracking/issue?issue=8658
http://svn.magentocommerce.com/source/branches/1.4-trunk/app/code/core/Mage/GoogleAnalytics/Block/Ga.php
As Magento Team said, changes will be included in next stable release.
January 12, 2010
Fetching all the options values of attribute.
The below post show he syntax of fetching values of attribute furniturebrand.
“furniturebrand” attribute type is combo.
Syntax ::
$product = Mage::getModel(“catalog/product”);
$attributes = Mage::getResourceModel(“eav/entity_attribute_collection”)
->setEntityTypeFilter($product->getResource()->getTypeId())
->addFieldToFilter(“attribute_code”, “furniturebrand”) // This can be changed to any attribute code
->load(false);
$attribute = $attributes->getFirstItem()->setEntity($product->getResource()); /* @var $attribute Mage_Eav_Model_Entity_Attribute */
$sortby = $attribute->getSource()->getAllOptions(false);
foreach($sortby as $sort_attribute) {
echo $sort_attribute['value'];
}
The above foreach loop is to display all the values of attribute furniturebrand.
“furniturebrand” attribute type is combo.
Syntax ::
$product = Mage::getModel(“catalog/product”);
$attributes = Mage::getResourceModel(“eav/entity_attribute_collection”)
->setEntityTypeFilter($product->getResource()->getTypeId())
->addFieldToFilter(“attribute_code”, “furniturebrand”) // This can be changed to any attribute code
->load(false);
$attribute = $attributes->getFirstItem()->setEntity($product->getResource()); /* @var $attribute Mage_Eav_Model_Entity_Attribute */
$sortby = $attribute->getSource()->getAllOptions(false);
foreach($sortby as $sort_attribute) {
echo $sort_attribute['value'];
}
The above foreach loop is to display all the values of attribute furniturebrand.
To get all level categories name and url…
<?php
require_once ‘app/Mage.php’;
Mage::app();
$category = Mage::getModel(‘catalog/category’);
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds(); // we can get all level categories id
if ($ids):
foreach ($ids as $id){
$cat = Mage::getModel(‘catalog/category’);
$cat->load($id);
if($id != 3): // if category id is not “root catalog” id – here root catalog id is 3
if($cat->getIsActive()): // if category is active
$catName[] = $cat->getName(); // To get name of the category
$path[] = $cat->getUrl(); // to get url of category
endif;
endif;
}
?>
require_once ‘app/Mage.php’;
Mage::app();
$category = Mage::getModel(‘catalog/category’);
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds(); // we can get all level categories id
if ($ids):
foreach ($ids as $id){
$cat = Mage::getModel(‘catalog/category’);
$cat->load($id);
if($id != 3): // if category id is not “root catalog” id – here root catalog id is 3
if($cat->getIsActive()): // if category is active
$catName[] = $cat->getName(); // To get name of the category
$path[] = $cat->getUrl(); // to get url of category
endif;
endif;
}
?>
SQL to delete all orders
This query is very helpful to delete all records of orders from the database.
Please replace “YOUR_DB_NAME” with your database name
– Reset Magento TEST Data
SET FOREIGN_KEY_CHECKS=0;
– reset dashboard search queries
TRUNCATE `catalogsearch_query`;
ALTER TABLE `catalogsearch_query` AUTO_INCREMENT=1;
– reset sales order info
TRUNCATE `sales_order`;
TRUNCATE `sales_order_datetime`;
TRUNCATE `sales_order_decimal`;
TRUNCATE `sales_order_entity`;
TRUNCATE `sales_order_entity_datetime`;
TRUNCATE `sales_order_entity_decimal`;
TRUNCATE `sales_order_entity_int`;
TRUNCATE `sales_order_entity_text`;
TRUNCATE `sales_order_entity_varchar`;
TRUNCATE `sales_order_int`;
TRUNCATE `sales_order_text`;
TRUNCATE `sales_order_varchar`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sendfriend_log`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `wishlist`;
TRUNCATE `log_quote`;
TRUNCATE `report_event`;
ALTER TABLE `sales_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;
– Reset all ID counters
TRUNCATE `eav_entity_store`;
ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1;
SET FOREIGN_KEY_CHECKS=1;
– set appropriate prefixes for orders, invoices, shipments, credit memos
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘1′, ‘11′, ‘1′, ‘1′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 1 where `entity_type_id`=’4′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’4′ and `store_id`=’1′;
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘2′, ‘16′, ‘1′, ‘2′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 2 where `entity_type_id`=’18′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’18′ and `store_id`=’1′;
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘3′, ‘19′, ‘1′, ‘3′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 3 where `entity_type_id`=’24′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’24′ and `store_id`=’1′;
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘4′, ‘23′, ‘1′, ‘4′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 4 where `entity_type_id`=’28′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’28′ and `store_id`=’1′;
Please replace “YOUR_DB_NAME” with your database name
– Reset Magento TEST Data
SET FOREIGN_KEY_CHECKS=0;
– reset dashboard search queries
TRUNCATE `catalogsearch_query`;
ALTER TABLE `catalogsearch_query` AUTO_INCREMENT=1;
– reset sales order info
TRUNCATE `sales_order`;
TRUNCATE `sales_order_datetime`;
TRUNCATE `sales_order_decimal`;
TRUNCATE `sales_order_entity`;
TRUNCATE `sales_order_entity_datetime`;
TRUNCATE `sales_order_entity_decimal`;
TRUNCATE `sales_order_entity_int`;
TRUNCATE `sales_order_entity_text`;
TRUNCATE `sales_order_entity_varchar`;
TRUNCATE `sales_order_int`;
TRUNCATE `sales_order_text`;
TRUNCATE `sales_order_varchar`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sendfriend_log`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `wishlist`;
TRUNCATE `log_quote`;
TRUNCATE `report_event`;
ALTER TABLE `sales_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;
– Reset all ID counters
TRUNCATE `eav_entity_store`;
ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1;
SET FOREIGN_KEY_CHECKS=1;
– set appropriate prefixes for orders, invoices, shipments, credit memos
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘1′, ‘11′, ‘1′, ‘1′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 1 where `entity_type_id`=’4′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’4′ and `store_id`=’1′;
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘2′, ‘16′, ‘1′, ‘2′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 2 where `entity_type_id`=’18′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’18′ and `store_id`=’1′;
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘3′, ‘19′, ‘1′, ‘3′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 3 where `entity_type_id`=’24′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’24′ and `store_id`=’1′;
INSERT INTO `YOUR_DB_NAME`.`eav_entity_store` (`entity_store_id` ,`entity_type_id` ,`store_id` ,`increment_prefix` ,`increment_last_id`) VALUES (‘4′, ‘23′, ‘1′, ‘4′, ‘000000000′);
update `eav_entity_store` set `increment_prefix`= 4 where `entity_type_id`=’28′ and `store_id`=’1′;
update `eav_entity_store` set `increment_last_id`= ‘000000000′ where `entity_type_id`=’28′ and `store_id`=’1′;
How to get different URLs?
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_JS);
http://magesite.extension/js/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
http://magesite.extension/index.php/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA);
http://magesite.extension/media/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN);
http://magesite.extension/skin/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
http://magesite.extension/js/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
http://magesite.extension/index.php/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA);
http://magesite.extension/media/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN);
http://magesite.extension/skin/
* Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
To add custom date field in custom module of admin panel
You can see the below code to add start date and end date field in admin custom module(Which is created using module creator).
Create two fields “start_date” and “end_date” in database table of your custom module.
$dateFormatIso = Mage::app()->getLocale() ->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
$fieldset->addField(’start_date’, ‘date’, array(
‘label’ => Mage::helper(‘banner’)->__(‘Start Date’),
‘title’ => Mage::helper(‘banner’)->__(‘Start Date’),
‘name’ => ’start_date’,
‘image’ => $this->getSkinUrl(‘images/grid-cal.gif’),
‘format’ => $dateFormatIso,
‘value’ => ’start_date’,
//’required’ => true,
));
$fieldset->addField(‘end_date’, ‘date’, array(
‘label’ => Mage::helper(‘banner’)->__(‘End Date’),
‘title’ => Mage::helper(‘banner’)->__(‘End Date’),
‘name’ => ‘end_date’,
‘image’ => $this->getSkinUrl(‘images/grid-cal.gif’),
‘format’ => $dateFormatIso,
‘value’ => ‘end_date’,
//’required’ => true,
));
Copy and paste the above code to your custom_module/block/adminhtml/custom_module/Edit/Tab/Form.php file
and than open controller of the same module
Path :: custom_module/controllers/adminhtml/custommoduleController.php
Add below lines before $model->save() to save dates in
function saveAction().
if($data['start_date'] != NULL )
{
$date = Mage::app()->getLocale()->date($data['start_date'], Zend_Date::DATE_SHORT);
$model->setStartDate($date->toString(‘YYYY-MM-dd HH:mm:ss’));
}
if($data['end_date'] != NULL)
{
$date1 = Mage::app()->getLocale()->date($data['end_date'], Zend_Date::DATE_SHORT);
$model->setEndDate($date1->toString(‘YYYY-MM-dd HH:mm:ss’));
}
Create two fields “start_date” and “end_date” in database table of your custom module.
$dateFormatIso = Mage::app()->getLocale() ->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
$fieldset->addField(’start_date’, ‘date’, array(
‘label’ => Mage::helper(‘banner’)->__(‘Start Date’),
‘title’ => Mage::helper(‘banner’)->__(‘Start Date’),
‘name’ => ’start_date’,
‘image’ => $this->getSkinUrl(‘images/grid-cal.gif’),
‘format’ => $dateFormatIso,
‘value’ => ’start_date’,
//’required’ => true,
));
$fieldset->addField(‘end_date’, ‘date’, array(
‘label’ => Mage::helper(‘banner’)->__(‘End Date’),
‘title’ => Mage::helper(‘banner’)->__(‘End Date’),
‘name’ => ‘end_date’,
‘image’ => $this->getSkinUrl(‘images/grid-cal.gif’),
‘format’ => $dateFormatIso,
‘value’ => ‘end_date’,
//’required’ => true,
));
Copy and paste the above code to your custom_module/block/adminhtml/custom_module/Edit/Tab/Form.php file
and than open controller of the same module
Path :: custom_module/controllers/adminhtml/custommoduleController.php
Add below lines before $model->save() to save dates in
function saveAction().
if($data['start_date'] != NULL )
{
$date = Mage::app()->getLocale()->date($data['start_date'], Zend_Date::DATE_SHORT);
$model->setStartDate($date->toString(‘YYYY-MM-dd HH:mm:ss’));
}
if($data['end_date'] != NULL)
{
$date1 = Mage::app()->getLocale()->date($data['end_date'], Zend_Date::DATE_SHORT);
$model->setEndDate($date1->toString(‘YYYY-MM-dd HH:mm:ss’));
}
Subscriptions and Recurring Payments – new version and new user guide!
Today we are ready to announce 2 pieces of good news about the Subscriptions and Recurring Payments extension!
The first one is that User Guide is available to download from the extension page. The guide will make the work with Subscriptions and Recurring Payments much easier. In addition to covering all moments of the extension functioning – module configuration, managing subscriptions, subscribers and subscription products, etc. – you will find out how to manage subscriptions for customer’s part.
The next important point is the release of new version. The extension works more stable now as the following bugs were fixed:
The first one is that User Guide is available to download from the extension page. The guide will make the work with Subscriptions and Recurring Payments much easier. In addition to covering all moments of the extension functioning – module configuration, managing subscriptions, subscribers and subscription products, etc. – you will find out how to manage subscriptions for customer’s part.
The next important point is the release of new version. The extension works more stable now as the following bugs were fixed:
- It’s available to add product to cart from grid view even if product requires subscription options
- Magento clears quotes after N days and subscription losts billing and shipping addresses
- ePay 0.00 transaction payment fee is displayed on order page for recurring orders
- Subscribers list exporting error
January 8, 2010
Add a tree like left menu in Magento.
Magento in common has no left menu.
So i edit some core and design code to implement a left tree like menu.
Here i give the example of my code.
Step 1:Edit core code in app/code/core/mage/catalog/Block/Navigation.php and add these code in LeftNav.php in same place
So i edit some core and design code to implement a left tree like menu.
Here i give the example of my code.
Step 1:Edit core code in app/code/core/mage/catalog/Block/Navigation.php and add these code in LeftNav.php in same place
<?php /** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/osl-3.0.php * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@magentocommerce.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade Magento to newer * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage * @package Mage_Catalog * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** * Catalog navigation * * @category Mage * @package Mage_Catalog * @author Magento Core Team <core@magentocommerce.com> */ class Mage_Catalog_Block_LeftNav extends Mage_Core_Block_Template { protected $_categoryInstance = null; protected function _construct() { $this->addData(array( 'cache_lifetime' => false, 'cache_tags' => array(Mage_Catalog_Model_Category::CACHE_TAG, Mage_Core_Model_Store_Group::CACHE_TAG), )); } /** * Retrieve Key for caching block content * * @return string */ public function getCacheKey() { return 'CATALOG_NAVIGATION_' . Mage::app()->getStore()->getId() . '_' . Mage::getDesign()->getPackageName() . '_' . Mage::getDesign()->getTheme('template') . '_' . Mage::getSingleton('customer/session')->getCustomerGroupId() . '_' . md5($this->getTemplate() . $this->getCurrenCategoryKey()); } public function getCurrenCategoryKey() { if ($category = Mage::registry('current_category')) { return $category->getPath(); } else { return Mage::app()->getStore()->getRootCategoryId(); } } /** * Get catagories of current store * * @return Varien_Data_Tree_Node_Collection */ public function getStoreCategories() { $helper = Mage::helper('catalog/category'); return $helper->getStoreCategories(); } /** * Retrieve child categories of current category * * @return Varien_Data_Tree_Node_Collection */ public function getCurrentChildCategories() { $layer = Mage::getSingleton('catalog/layer'); $category = $layer->getCurrentCategory(); /* @var $category Mage_Catalog_Model_Category */ $categories = $category->getChildrenCategories(); $productCollection = Mage::getResourceModel('catalog/product_collection'); $layer->prepareProductCollection($productCollection); $productCollection->addCountToCategories($categories); return $categories; } /** * Checkin activity of category * * @param Varien_Object $category * @return bool */ public function isCategoryActive($category) { if ($this->getCurrentCategory()) { return in_array($category->getId(), $this->getCurrentCategory()->getPathIds()); } return false; } protected function _getCategoryInstance() { if (is_null($this->_categoryInstance)) { $this->_categoryInstance = Mage::getModel('catalog/category'); } return $this->_categoryInstance; } /** * Get url for category data * * @param Mage_Catalog_Model_Category $category * @return string */ public function getCategoryUrl($category) { if ($category instanceof Mage_Catalog_Model_Category) { $url = $category->getUrl(); } else { $url = $this->_getCategoryInstance() ->setData($category->getData()) ->getUrl(); } return $url; } /** * Enter description here... * * @param Mage_Catalog_Model_Category $category * @param int $level * @param boolean $last * @return string */ public function drawItem($category, $level=0, $last=false) { $html = ''; if (!$category->getIsActive()) { return $html; } if (Mage::helper('catalog/category_flat')->isEnabled()) { $children = $category->getChildrenNodes(); $childrenCount = count($children); } else { $children = $category->getChildren(); $childrenCount = $children->count(); } $hasChildren = $children && $childrenCount; $html.= '<li'; if ($hasChildren) { //$html.= ' onmouseover="toggleMenu(this,1)" onmouseout="toggleMenu(this,0)"'; //replace $html.= ''; } // $html.= ' class="level'.$level; // $html.= ' nav-'.str_replace('/', '-', Mage::helper('catalog/category')->getCategoryUrlPath($category->getRequestPath())); if ($this->isCategoryActive($category)) { // $html.= ' active'; $html .=''; } if ($last) { // $html .= ' last'; $html .=''; } if ($hasChildren) { $cnt = 0; foreach ($children as $child) { if ($child->getIsActive()) { $cnt++; } } if ($cnt > 0) { // $html .= ' parent'; //$html .=' current'; $html .=''; } } $html.= '>'."\n"; $html.= '<a href="'.$this->getCategoryUrl($category).'"><span>'.$this->htmlEscape($category->getName()).'</span></a>'."\n"; if ($hasChildren){ $j = 0; $htmlChildren = ''; foreach ($children as $child) { if ($child->getIsActive()) { $htmlChildren.= $this->drawItem($child, $level+1, ++$j >= $cnt); } } if (!empty($htmlChildren)) { $html.= '<ul>'."\n" .$htmlChildren .'</ul>'; } } $html.= '</li>'."\n"; return $html; } /** * Enter description here... * * @return Mage_Catalog_Model_Category */ public function getCurrentCategory() { if (Mage::getSingleton('catalog/layer')) { return Mage::getSingleton('catalog/layer')->getCurrentCategory(); } return false; } /** * Enter description here... * * @return string */ public function getCurrentCategoryPath() { if ($this->getCurrentCategory()) { return explode(',', $this->getCurrentCategory()->getPathInStore()); } return array(); } /** * Enter description here... * * @param Mage_Catalog_Model_Category $category * @return string */ public function drawOpenCategoryItem($category) { $html = ''; if (!$category->getIsActive()) { return $html; } $html.= '<li'; if ($this->isCategoryActive($category)) { $html.= ' class="active"'; } $html.= '>'."\n"; $html.= '<a href="'.$this->getCategoryUrl($category).'"><span>'.$this->htmlEscape($category->getName()).'</span></a>'."\n"; if (in_array($category->getId(), $this->getCurrentCategoryPath())){ $children = $category->getChildren(); $hasChildren = $children && $children->count(); if ($hasChildren) { $htmlChildren = ''; foreach ($children as $child) { $htmlChildren.= $this->drawOpenCategoryItem($child); } if (!empty($htmlChildren)) { $html.= '<ul>'."\n" .$htmlChildren .'</ul>'; } } } $html.= '</li>'."\n"; return $html; } }
add categories with images on homepage – magento
to add categories along with images on homepage
just add the code given below to your homepage from admininstration cms management.
================================================
just add the code given below to your homepage from admininstration cms management.
{{block type="catalog/navigation" name="catalog.category" template="catalog/category/list.phtml"}}
Also you need to create a list.phtml file under “/app/design/frontend/default/default/template/catalog/category/list.phtml”
and add the below given code to it:
===========================================
<?php foreach ($this->getStoreCategories() as $_category): ?>
<?php $open = $this->isCategoryActive($_category); ?>
<?php
$cur_category=Mage::getModel('catalog/category')->load($_category->getId());
$layer = Mage::getSingleton('catalog/layer');
$layer->setCurrentCategory($cur_category);
if ($immagine = $this->getCurrentCategory()->getImageUrl()):
?> <div style="float: left; padding-right: 30px; text-align: center;">
<div class="linkimage">
<p>
<a href="<?php echo $this->getCategoryUrl($_category)?>">
<img src="<?php echo $immagine ?>" alt="<?php echo $this->htmlEscape($this->getCurrentCategory()->getName()) ?>" width="135" height="135" />
<?php echo $_category->getName()?>
</a>
</p>
</div>
</div> <?php endif; ?>
<?php endforeach; ?>
January 5, 2010
Manual creation of Google Sitemap in Magento
Most of you probably know this, but let’s define what the sitemaps are. Sitemaps are a simple way for site creators to give search engines the information about pages on their site that are available for public. Basically, those are just 1 or more XML files that lists URLs for a site along with additional meta informatio about each URL (like last update, how often it changes, its importance relevant to other pages). With this in mind, search engines can be more clever while crawling the site. Click here see how sitemap of this site looks like.
You will hear the term Google Sitemap a lot, but XML Schema for the Sitemap protocol is not related only to Google at all. It can be used in many places, but the most important ones are Google Webmaster Tools and Yahoo! Site Explorer.
Catalog -> Google Sitemap
Check to see if the sitemap file is already present. Lets assume we wish to create sitemap in the URL: http://www.yourstore.com/sitemap/sitemap.xml
To do it successfully,
Let’s go to Magento administration now and click on “Add Sitemap” button. Just insert the default values.
After this step, we just told Magento where to create sitemap file. It is not yet created.
http://www.yourstore.com/index.php/admin/sitemap/generate/sitemap_id/[ID of Sitemap from step 1]
Of course, replace the content with square brackets with actual Sitemap ID.
You will hear the term Google Sitemap a lot, but XML Schema for the Sitemap protocol is not related only to Google at all. It can be used in many places, but the most important ones are Google Webmaster Tools and Yahoo! Site Explorer.
How do we create Google Sitemap in Magento?
1. Sitemap File Configuration
First we need to create sitemap file in Magento. This is basically pointer to tell Magento where to create sitemap file and how to name it. Log in to Magento Administration and go to:Catalog -> Google Sitemap
Check to see if the sitemap file is already present. Lets assume we wish to create sitemap in the URL: http://www.yourstore.com/sitemap/sitemap.xml
To do it successfully,
- FTP to the server
- create sitemap folder
- chmod the folder to 777
Let’s go to Magento administration now and click on “Add Sitemap” button. Just insert the default values.
After this step, we just told Magento where to create sitemap file. It is not yet created.
2. Configure Sitemap
Sitemap can be configured from the interface System -> Configuration -> Catalog->Google Sitemap. If you are not sure what does it all mean, check XML Tag definitions section from “Sitemaps XML format” document.3. Create Sitemap Manually
Looks like Magento folks were thinking that sitemap should only be created by a cron job. Yes, it can be done that way also. Be sure to read Wiki article How to Set Up a Cron Job to get familiar with it. If you are looking for manual creation, quit your search for “Create Sitemap” button. You will not find it. But there is a workaround. You can enter manual URL to execute sitemap creation:http://www.yourstore.com/index.php/admin/sitemap/generate/sitemap_id/[ID of Sitemap from step 1]
Of course, replace the content with square brackets with actual Sitemap ID.
January 2, 2010
Programmaticaly adding new customers to the Magento store
Every now and then you will have specific case in Magento store where you might need to programmaticaly add new customers. Adding customer with basic information like First name, Last name, email and password is relatively trivial task. Here is the sample (working code):
Here are some screenshots of the final result:
Ok, so now we now how to add new customer from our code. But this is bare minimum. Where are the addresses you say? Well, below is the code that fulfills the above one and ads an address information to the customer.
And below is the screenshot that reflex the state after executing code above.
As you can see, adding a new customer from within a code is pretty straightforward process. The thing you should keep an eye on are the required fields. Useful way achieving a proper result is to try to add the customer from within Magento admin interface with all the required address fields then do a little “reverse engineering” by loading and dumping the loaded instance of Mage_Customer_Model_Customer and Mage_Customer_Model_Address objects. Examining the dumped ($object->debug()) structure would give you a pretty good idea of what needs to be provided to object when it is created programmaticaly.
Hope I don’t have to mention that all of this “playing” should first be done on developer machine, never on live site.
Hope this was helpful. Cheers.
<?php $websiteId = Mage::app()->getWebsite()->getId(); $store = Mage::app()->getStore(); //$customer = new Mage_Customer_Model_Customer(); $customer = Mage::getModel("customer/customer"); $customer->website_id = $websiteId; $customer->setStore($store); $customer->firstname = "Branko"; $customer->lastname = "Ajzele"; $customer->email = "ajzele@someserver.com"; $customer->password_hash = md5("mycoolpass"); $customer->save(); ?>
Ok, so now we now how to add new customer from our code. But this is bare minimum. Where are the addresses you say? Well, below is the code that fulfills the above one and ads an address information to the customer.
<?php $websiteId = Mage::app()->getWebsite()->getId(); $store = Mage::app()->getStore(); //$customer = new Mage_Customer_Model_Customer(); $customer = Mage::getModel("customer/customer"); $customer->website_id = $websiteId; $customer->setStore($store); $customer->firstname = "Branko"; $customer->lastname = "Ajzele"; $customer->email = "ajzele@someserver.com"; $customer->password_hash = md5("mycoolpass"); $customer->save(); //$address = new Mage_Customer_Model_Address(); $address = Mage::getModel("customer/address"); $address->setCustomerId($customer->getId()); $address->firstname = $customer->firstname; $address->lastname = $customer->lastname; $address->country_id = "HR"; //Country code here $address->postcode = "31000"; $address->city = "Osijek"; /* NOTE: If country is USA, please set up $address->region also */ $address->telephone = "0038531444888"; $address->fax = "0038531555999"; $address->company = "ActiveCodeline"; $address->street = "My Cool Street"; $address->save(); ?>
As you can see, adding a new customer from within a code is pretty straightforward process. The thing you should keep an eye on are the required fields. Useful way achieving a proper result is to try to add the customer from within Magento admin interface with all the required address fields then do a little “reverse engineering” by loading and dumping the loaded instance of Mage_Customer_Model_Customer and Mage_Customer_Model_Address objects. Examining the dumped ($object->debug()) structure would give you a pretty good idea of what needs to be provided to object when it is created programmaticaly.
Hope I don’t have to mention that all of this “playing” should first be done on developer machine, never on live site.
Hope this was helpful. Cheers.
How to delete Magento product from frontend template code
f for some reason (like mine) you need to delete the product from the custom code you placed in lets say view files you might get a bit surprised by the “Cannot complete this operation from non-admin area.” error. Here is a little trick on how to pass behind this.
Here is the working sample code part:
The above code is part of a code extracted form a project I am working on these days. The important stuff is the following part:
Basically the idea is to write the appropriate value in registry, Mage::register(‘isSecureArea’, true);, and remove it once we delete our product.
Here is the working sample code part:
$_authors_product = new Mage_Catalog_Model_Product(); $_authors_product->load($_item_val_id); //echo "DELETED... ".$_POST['submit_item4sale_remove_by_entity_id']; $_item_val_id = $_POST['submit_item4sale_remove_by_entity_id']; $_item_val_id = (int)str_replace('entity_id_', '', $_item_val_id); $_authors_product = new Mage_Catalog_Model_Product(); $_authors_product->load($_item_val_id); $_current_customer_id = Mage::getSingleton('customer/session')->getCustomer()->getId(); //Allow deletion only if product is from author if($_authors_product->submited_by_author == $_current_customer_id) { //var_dump(Mage::registry('isSecureArea')); Mage::register('isSecureArea', true); //$_authors_product->delete(); echo 'ALLOWED DELETED OH YEAAAAAA....'; Mage::unregister('isSecureArea'); }
Mage::register('isSecureArea', true); echo 'ALLOWED DELETED OH YEAAAAAA....'; Mage::unregister('isSecureArea');
Magento – Custom email contact form with notification system
In this article, hopefully, you will learn how to create a module that uses its own controller, programatically creates a block based on core template and assigned via file, handles form submission and utilizes Magento notification system to output the notifications to user.
Although the module it self might look relatively simple in the end, keep in mind that these are powerful concepts that you can latter reuse for much more complex requirements.
file 1:
/app/etc/modules/ActiveCodeline_SimpleContact.xml
content of file 1:
file 2: app/code/local/ActiveCodeline/SimpleContact/etc/config.xml
content of file 2:
As we dissect our module, the first thing that pops up is the “frontend” element. We can see it has lot of sub-elements of which “routers” is first. In order for something in Magento to be accessible on certain url, that something needs to have controller, like all Zend powered applications. Unlike pure Zend apps, Magento has its own way of mapping controllers, trough xml definitions.
I intentionally used “JustSomeFreeRouterNameHereNo1″ for element name making it self explanatory. You can freely assign name to a router wheres “use” and “args” are two parameters each router should have. Parametar “module” if the full name of your module and “frontName” is the actual url path trough which you acccess your controller. In example above I would access my controller indexAction() method trough url like http://shop.local/index.php/activecodeline-simplecontact/index/ or http://shop.local/index.php/activecodeline-simplecontact/. In case we have url rewrite set up we can even access it by omitting the “index.php” part from url.
Now we will look into the content of IndexController.php.
file 3: app/code/local/ActiveCodeline/SimpleContact/controllers/IndexController.php
content of file 3:
Above file, although simple, demonstrates two powerful concepts. First we have an example of creating a block “on the fly”. There are several ways one can add an output block to be shown in Magento, this is the “hardest” way. Most of the materials you will find on the web will show you how to do it from xml files. However, I want you to know how to do it from code.
There is one important reason why you should now how to do this from code: Simplicity! If you were to output the block from layout files then you are adding at leas one more file to your module. The more files you have in your module, bigger the chance for bugs. This is really something you should consider and keep in mind for modules who actually require controllers and are not very user centric.
When I say “not very user centric” I think in terms where designer needs to have full control of layout and the way it is arranged. However in cases where not much layout modifications will be required on custom made controller output I believe that “saving yourself” from writing another layout file is the right way to go.
Note that inside the method call createBlock i use ‘Mage_Core_Block_Template’ as one of the parameters. This is the block class. In this example core block template is used. However, you can freely use one of your own declared blocks (will be shown in latter modules). Created block is appended (inserted actualy) in existing block named “content”. Block “content” is one that is almost always present in the output.
Inside the sendemailAction method we have another important concept, the notification system example. Catch exception block triggers the “adding in the notification message” to the session storage. There are few different storage mechanism inside the Magento. Most of them simply extend core/session without any noticeable diference, therefore unles you wish to extend the existing and write your own, you can use the Mage::getSingleton(‘core/session’). You can use 4 diferent types of notification messages: error, warning, notice, success. Which you can call respectively like trough methods addError(’Custom error here’), addWarning(’Custom warning here’), addNotice(’Custom notice here’), addSuccess(’Custom success here’) as shown above.
Any notifications added to ‘core/session’ storage are outputted to frontend trough view files. For instance one such example is app/design/frontend/default/default/template/page/3columns.phtml file. Inside the file there is the getChildHtml(‘global_messages’) ?> line of code that outputs all global notifications. Note that the “global_messages” referes to block name from within the page.xml layout file, which in turn referes to Magento “core/messages” (Mage_Core_Block_Messages) class type.
Final file for our module is the view file itself. As you might notice from the IndexController, we are using the ‘activecodeline/simple_contact.phtml’ as one of the parameters passed to createBlock method. What this means is that our module is going to look for app/design/frontend/default/default/template/activecodeline/simple_contact.phtml file. Note that if we were to assign diferent template then “default” to be used for our site then ‘activecodeline/simple_contact.phtml’ would refer to folder and file from within that template. If that file is not find in this “other” template then the system would look for one in default template.
file 4: app/design/frontend/default/default/template/activecodeline/simple_contact.phtml
content of file 4:
Content of above file is mostly HTML related so there is not much to talk about it.
That’s it, the end.
Although the module it self might look relatively simple in the end, keep in mind that these are powerful concepts that you can latter reuse for much more complex requirements.
file 1:
/app/etc/modules/ActiveCodeline_SimpleContact.xml
content of file 1:
<?xml version="1.0"?> <config> <modules> <ActiveCodeline_SimpleContact> <active>true</active> <codePool>local</codePool> </ActiveCodeline_SimpleContact> </modules> </config>
content of file 2:
<?xml version="1.0"?> <config> <modules> <ActiveCodeline_SimpleContact> <version>0.1.0</version> </ActiveCodeline_SimpleContact> </modules> <frontend> <routers> <JustSomeFreeRouterNameHereNo1> <use>standard</use> <args> <module>ActiveCodeline_SimpleContact</module> <frontName>activecodeline-simplecontact</frontName> </args> </JustSomeFreeRouterNameHereNo1> </routers> </frontend> </config>
I intentionally used “JustSomeFreeRouterNameHereNo1″ for element name making it self explanatory. You can freely assign name to a router wheres “use” and “args” are two parameters each router should have. Parametar “module” if the full name of your module and “frontName” is the actual url path trough which you acccess your controller. In example above I would access my controller indexAction() method trough url like http://shop.local/index.php/activecodeline-simplecontact/index/ or http://shop.local/index.php/activecodeline-simplecontact/. In case we have url rewrite set up we can even access it by omitting the “index.php” part from url.
Now we will look into the content of IndexController.php.
file 3: app/code/local/ActiveCodeline/SimpleContact/controllers/IndexController.php
content of file 3:
<?php class ActiveCodeline_SimpleContact_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { //Get current layout state $this->loadLayout(); $block = $this->getLayout()->createBlock( 'Mage_Core_Block_Template', 'activecodeline.simple_contact', array( 'template' => 'activecodeline/simple_contact.phtml' ) ); $this->getLayout()->getBlock('content')->append($block); //$this->getLayout()->getBlock('right')->insert($block, 'catalog.compare.sidebar', true); $this->_initLayoutMessages('core/session'); $this->renderLayout(); } public function sendemailAction() { //Fetch submited params $params = $this->getRequest()->getParams(); $mail = new Zend_Mail(); $mail->setBodyText($params['comment']); $mail->setFrom($params['email'], $params['name']); $mail->addTo('somebody_else@example.com', 'Some Recipient'); $mail->setSubject('Test ActiveCodeline_SimpleContact Module for Magento'); try { $mail->send(); } catch(Exception $ex) { Mage::getSingleton('core/session')->addError('Unable to send email. Sample of a custom notification error from ActiveCodeline_SimpleContact.'); } //Redirect back to index action of (this) activecodeline-simplecontact controller $this->_redirect('activecodeline-simplecontact/'); } } ?>
There is one important reason why you should now how to do this from code: Simplicity! If you were to output the block from layout files then you are adding at leas one more file to your module. The more files you have in your module, bigger the chance for bugs. This is really something you should consider and keep in mind for modules who actually require controllers and are not very user centric.
When I say “not very user centric” I think in terms where designer needs to have full control of layout and the way it is arranged. However in cases where not much layout modifications will be required on custom made controller output I believe that “saving yourself” from writing another layout file is the right way to go.
Note that inside the method call createBlock i use ‘Mage_Core_Block_Template’ as one of the parameters. This is the block class. In this example core block template is used. However, you can freely use one of your own declared blocks (will be shown in latter modules). Created block is appended (inserted actualy) in existing block named “content”. Block “content” is one that is almost always present in the output.
Inside the sendemailAction method we have another important concept, the notification system example. Catch exception block triggers the “adding in the notification message” to the session storage. There are few different storage mechanism inside the Magento. Most of them simply extend core/session without any noticeable diference, therefore unles you wish to extend the existing and write your own, you can use the Mage::getSingleton(‘core/session’). You can use 4 diferent types of notification messages: error, warning, notice, success. Which you can call respectively like trough methods addError(’Custom error here’), addWarning(’Custom warning here’), addNotice(’Custom notice here’), addSuccess(’Custom success here’) as shown above.
Any notifications added to ‘core/session’ storage are outputted to frontend trough view files. For instance one such example is app/design/frontend/default/default/template/page/3columns.phtml file. Inside the file there is the getChildHtml(‘global_messages’) ?> line of code that outputs all global notifications. Note that the “global_messages” referes to block name from within the page.xml layout file, which in turn referes to Magento “core/messages” (Mage_Core_Block_Messages) class type.
Final file for our module is the view file itself. As you might notice from the IndexController, we are using the ‘activecodeline/simple_contact.phtml’ as one of the parameters passed to createBlock method. What this means is that our module is going to look for app/design/frontend/default/default/template/activecodeline/simple_contact.phtml file. Note that if we were to assign diferent template then “default” to be used for our site then ‘activecodeline/simple_contact.phtml’ would refer to folder and file from within that template. If that file is not find in this “other” template then the system would look for one in default template.
file 4: app/design/frontend/default/default/template/activecodeline/simple_contact.phtml
content of file 4:
<div class="box simple_contact"> <form id="simple_contact_form" name="simple_contact_form" action="<?php echo $this->getUrl('activecodeline-simplecontact/') ?>index/sendemail" method="post"> <fieldset class="group-select"> <h4 class="legend">ActiveCodeline_SimpleContact module sample</h4> <ul> <li> <div class="input-box"> <label for="name">Gimme your name <span class="required">*</span></label><br /> <input name="name" id="name" title="Name" value="" class="required-entry input-text" type="text" /> </div> <div class="input-box"> <label for="email">And your email <span class="required">*</span></label><br /> <input name="email" id="email" title="Email" value="" class="required-entry input-text validate-email" type="text" /> </div> <div class="clear"></div> <div class="input-box"> <label for="comment">Some comment?</label><br /> <textarea name="comment" id="comment" title="Comment" class="required-entry input-text" style="height:100px;" cols="50" rows="3"></textarea> </div> </li> </ul> </fieldset> <div class="button-set"> <p class="required">* Required Fields</p> <button class="form-button" type="submit"><span>Submit</span></button> </div> </form> </div>
That’s it, the end.
Inchoo_Heared4us – Magento module for adding new tab under Onepage checkout
Just a small update. I wrote a module that you can download from Inchoo.net. Here is the link of article where you can find a module for download. Hope some of you find it useful. Please read the article before installing module.
Invoice printing to PDF taking to long in Magento?
Recently I was assigned a task to check the slowness of PDF printing on invoice page of Magento admin. It took him around 5minutes to print PDF (return PDF document on Invoice page). After diving into the code trying to trace the issue I found what was the cause of slow printing. PDF document that gets created has the ability to include the logo in header.
Code that adds the image into the header is located under the method named “getPdf()” in “app/code/core/Mage/Sales/Model/Order/Pdf/Invoice.php” file. There is a line that says “$this->insertLogo($page, $invoice->getStore());”.
Method “insertLogo()” is located under “app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php”. When commented out the invoice gets printed to PDF in a matter of 2-3 seconds. However, simply commenting out the method is not the proper solution. After short introspection, conclusion was that the image assigned as logo was to big in dimensions (around 3500x… px). Reducing logo in size drastically improved generation of PDF.
Hope this helps someone with the same “slow invoice printing” issue.
Code that adds the image into the header is located under the method named “getPdf()” in “app/code/core/Mage/Sales/Model/Order/Pdf/Invoice.php” file. There is a line that says “$this->insertLogo($page, $invoice->getStore());”.
Method “insertLogo()” is located under “app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php”. When commented out the invoice gets printed to PDF in a matter of 2-3 seconds. However, simply commenting out the method is not the proper solution. After short introspection, conclusion was that the image assigned as logo was to big in dimensions (around 3500x… px). Reducing logo in size drastically improved generation of PDF.
Hope this helps someone with the same “slow invoice printing” issue.
Bulk disable multiple Magento products
With all its ORM, model, resource and so on greatness, sometimes platform limitations are too obvious in Magento when it comes to large number of products in store. Recently I faced a simple task, I needed to disable around 6500 products in Magento that were assigned to a single category called “Inactive Products”. Given that it was an import from old system to Magento it is irrelevant why one would use category “Inactive Products” instead of just setting their status to “disabled”. My point is, whats the fastest way to do a bulk action on large number of products.
There are certain bulk actions you can do from “Catalog > Manage Products” section, however they all fail on large number of products selected. Logical solution is to simply use the raw SQL query. Only one catch, knowing where to look for.
Below is a practical example on “How to bulk update product status based on product category”. In my case, the id of my category in question was 35, while my “status” attribute had an id of 80. Most likely yours “status” attribute will have the same id value given that its a default Magento attribute.
Here is the actual SQL code that disables the products which have only one category assigned, the one with id 35:
Code above executed under two seconds, disabling around 6500 products in one run. Doing something like this purely from PHP or shall I say Magento can turn out to be “mission impossible”.
Only one advice, always do a full database backup prior to any database changes.
There are certain bulk actions you can do from “Catalog > Manage Products” section, however they all fail on large number of products selected. Logical solution is to simply use the raw SQL query. Only one catch, knowing where to look for.
Below is a practical example on “How to bulk update product status based on product category”. In my case, the id of my category in question was 35, while my “status” attribute had an id of 80. Most likely yours “status” attribute will have the same id value given that its a default Magento attribute.
Here is the actual SQL code that disables the products which have only one category assigned, the one with id 35:
UPDATE ma_catalog_product_entity_int SET value = '2' WHERE attribute_id = 80 AND entity_id IN (SELECT entity_id FROM ma_catalog_product_entity WHERE category_ids = '35');
Code above executed under two seconds, disabling around 6500 products in one run. Doing something like this purely from PHP or shall I say Magento can turn out to be “mission impossible”.
Only one advice, always do a full database backup prior to any database changes.
Moving Magento site, missing images in catalog
Recently I have came across one funny issue. Interesting how issue can be funny. One of our clients had a request for Magento upgrade, from version 1.2 to 1.3.2.4. Most of you in in Magento development will likely to agree when I say that Magento upgrades can be a night mare. Luckily for me, this one went rather smoothly with one strange result, half of my product images were not visible on frontend/admin.
After few minutes of debugging I realized what caused the issue. Before I did an upgrade of the site, I pulled entire site locally on my dev machine and set it up so that it runs fully local. Meaning I wanted to upgrade site “offline” on my local machine where its faster and I am not limited to hosting server environment. In the process of “downloading” entire live site to my local machine I forgot the fact that I am using Windows. Windows operating system does not support having two directories, one next to another with the same name like “F” and “f”. It is not case sensitive. Due to this, all my images went to one (first in line) folder.
Once I successfully updated the site and uploaded it to live (Linux powered) server, I ended up with missing photos for about half of my products. Reason being the simple change in folder name from capital to small letter or vice versa.
If you ever do upgrade like I, and come across missing images scenario, try to remember this one.
After few minutes of debugging I realized what caused the issue. Before I did an upgrade of the site, I pulled entire site locally on my dev machine and set it up so that it runs fully local. Meaning I wanted to upgrade site “offline” on my local machine where its faster and I am not limited to hosting server environment. In the process of “downloading” entire live site to my local machine I forgot the fact that I am using Windows. Windows operating system does not support having two directories, one next to another with the same name like “F” and “f”. It is not case sensitive. Due to this, all my images went to one (first in line) folder.
Once I successfully updated the site and uploaded it to live (Linux powered) server, I ended up with missing photos for about half of my products. Reason being the simple change in folder name from capital to small letter or vice versa.
If you ever do upgrade like I, and come across missing images scenario, try to remember this one.
One Step Checkout in Magento
In contrary to all the efforts Magento team put into One Page Checkout functionality there are lot of people that find it annoying and non-user friendly. I would dare to say I am one of them. Besides myself, lot of our clients have expressed their desire for simpler checkout page.
Lets face it, if you are running a web shop, then usability must be one of your prime concerns. How bad would you feel if you knew you had a customer that added bunch of stuff to cart just to say “To hell with it” when he reaches the annoying and non user friendly checkout process.
As I mentioned previously, several of our clients have already asked us to develop a simpler version of One Page checkout for them, however they soon gave up when presented with development cost. Magento is no picnic, coding something like this requires time and knowledge.
Here is one extension that promises to simplify the checkout process, its called OneStepCheckout.
If you come from WordPress, Joomla, Drupal or similar PHP platforms, you are most likely use to not paying your plugins, modules etc. As I noted previously, professional Magento development is not an easy task, so paying for an extension that can boost your user experience, thus possibly increasing sales, should not be a problem for any serious site owner.
Installation of OneStepCheckout extension is a breeze, plus if you stuck, they provide installation services. Attached are few screenshots with some comments for you to see the final result. Numerous configurations options make it even more compelling.
Just by point and click you (your client) can decide to turn off certain input fields like City, Telephone, Company etc.
OneStepCheckout extension comes in two flavors, Standard and Enterprise. Screenshots below show Enterprise version.
Lets face it, if you are running a web shop, then usability must be one of your prime concerns. How bad would you feel if you knew you had a customer that added bunch of stuff to cart just to say “To hell with it” when he reaches the annoying and non user friendly checkout process.
As I mentioned previously, several of our clients have already asked us to develop a simpler version of One Page checkout for them, however they soon gave up when presented with development cost. Magento is no picnic, coding something like this requires time and knowledge.
Here is one extension that promises to simplify the checkout process, its called OneStepCheckout.
If you come from WordPress, Joomla, Drupal or similar PHP platforms, you are most likely use to not paying your plugins, modules etc. As I noted previously, professional Magento development is not an easy task, so paying for an extension that can boost your user experience, thus possibly increasing sales, should not be a problem for any serious site owner.
Installation of OneStepCheckout extension is a breeze, plus if you stuck, they provide installation services. Attached are few screenshots with some comments for you to see the final result. Numerous configurations options make it even more compelling.
Just by point and click you (your client) can decide to turn off certain input fields like City, Telephone, Company etc.
OneStepCheckout extension comes in two flavors, Standard and Enterprise. Screenshots below show Enterprise version.
Subscribe to:
Posts (Atom)