Monday, December 5, 2011

Add category names in product view page

Here is an other short but useful for some people thing you can do in Magento.
Here is how you can add the category tree path in the product view page.

Edit file app/design/frontend/{interface}/{theme}/template/catalog/product/view.phtml

And in the section that you want the categories to appear add this code:
<?php $categoryIds = $_product->getCategoryIds();?>
 <?php foreach ($categoryIds as $categoryId) :?>
  <?php $tmpId = $categoryId;?>
  <?php $categories = array();?>
  <?php while($tmpId != Mage::app()->getStore()->getRootCategoryId()) : ?>
   <?php $category = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->load($tmpId);?>
   <?php $categories[] = $category;?>
   <?php $tmpId = $category->getParentId();?>
  <?php endwhile;?>
  <?php for ($i = count($categories) - 1; $i>=0;$i--) :?>
   <a href="<?php echo $categories[$i]->getUrl() ?>"><?php echo $categories[$i]->getName() ?></a>
   <?php if ($i >0 ):?>
    -&gt;<!-- this is the tree separator. change to whatever you like-->
   <?php endif;?>
  <?php endfor;?>
  <br />
  <?php //break;//uncomment this if you want only one category tree to appear.?>
 <?php endforeach;?>

I hope this helps someone.
Keep in mind that this will make your page load a little slower, but I don't think it's something you should worry about.
Any comments are welcomed.

Marius.

Thursday, October 6, 2011

New Customer Account Breadcrumbs Extension

I've just developed & released under the name AnaisSoftware (the company I work worked for) a new FREE Magento Extension.
It is called 'Customer Account Breadcrumbs' (Anais_Breadcrumbs). It's not a big technical achievement but I saw some people on the forum requesting this.
All it does is it adds breadcrumbs to the customer account pages.
You can select from the back-end to enable the breadcrumbs for all the available account pages or select from a list the pages you want to have breadcrumbs.

It works Magento 1.4.2.0, 1.5.0.1, 1.5.1.0 and 1.6.0.0.
I have a hunch it works for previous versions also, I just didn't test them.
It has also been tested on Magneto Enterprise 1.9.1.1 but it doesn't work for enterprise specific pages (Gift registry, Reward points, ...).
The extension can be found here http://www.magentocommerce.com/magento-connect/AnaisSoftware/extension/8220/anais_breadcrumbs

Waiting for your feedback.

Cheers,
Marius.

Friday, September 30, 2011

Upload issue for Magento 1.6.0.0

I've seen lately the magento forum flooded with this issue.
When trying to upload an image for the product the section with the image name gets a red border and an error message appears.
When trying to upload something for the downloadable products...well..
same s**t different a**h**e (pardon my French).

Here is what I did to fix it:
The problem seems to be caused by the prototype v1.7.
It works great with prototype 1.6
Get the 1.6 version from here http://prototypejs.org/assets/2009/8/31/prototype.js
Create this file: js/prototype/prototype1.6.js and put the contents from the link above in it.
Now edit app/design/adminhtml/default/default/layout/main.xml and add this line
<action method="addJs"><script>prototype/prototype1.6.js</script></action>
right below
<action method="addJs"><script>prototype/prototype.js</script></action>

I don’t think it’s a problem if you edit this core file. I can assume that the guys at Magento will fix the issue with the uploader untill the next version (at least I hope it’s the same issue as reported here: http://www.magentocommerce.com/bug-tracking/issue?issue=12265 - and they claim it’s fixed)

I hope this helps someone
Cheers,
Marius.

Friday, September 9, 2011

Why can't you override some classes in Magento?

I saw a lot of pleaople having this issue on the magento forum.
Some classes cannot pe overridden the clasical way.
First of all, this is the classical way: http://magedev.com/2009/06/03/magento-overriding-model-block-or-helper/
It's a old post but is still very useful and it saved me a lot of time in the past.

But there are some classes that cannot be overridden this way.
Here are some examples: Mage_Core_Block_Template, Mage_Core_Model_Abstract, Varien_Object, Mage_Core_Block_Abstract, Mage_Customer_Model_Address_Abstract and the list can go on.

Basically these are the classes that are not instantiated in the application. They are used just to create other classes with common behavior.

But if you need to override these classes here are your 2 options. (I only know 2. If you know others please share.)

1. Quick and dirty. Using this there is a small change that on an upgrade you will lose some functionality or even crash. but don't dismiss it yet. Using the second method it's even worse.
The basics of this method is that Magento uses an autoloader to load classes. The autoloader first searches in the 'app/code/local' folder then in 'app/code/community' and in the end 'app/code/core'.
What you have to do is to copy the class you want to override in the app/code/local folder.
Let's take as an example Mage_Core_Model_Abstract. You need to copy the file app/code/core/Mage/Core/Model/Abstract.php to app/code/local/Mage/Core/Model/Abstract.php.
You can make the changes in this file.
Now when all the other classes that extend this are declared
class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
{ ...}
they will extend your own class because when searching for Mage_Core_Model_Abstract magento will find it in your app/code/local folder and will stop looking for the one in app/code/core.

2. Long and 'clean?' - You can still lose functionality on the upgrade, it's more time consuming
and a bigger source of errors.
You can create your own class. Let's call it 'Mycomp_Core_Model_Abstract' that extends Mage_Core_Model_Abstract and put your custom code in this.
In order for this to affect all the other models that extend Mage_Core_Model_Abstract you need to override each class that extend Mage_Core_Model_Abstract and make them extend the class you just created. Using the same example as above..
class Mycomp_Customer_Model_Customer extends Mycomp_Core_Model_Abstract
{ ...}
But now you need to copy all the functionality from Mage_Customer_Model_Customer to Mycomp_Customer_Model_Customer because, unfortunately, PHP does not support multiple inheritance (yet?)
And for Mage_Core_Model_Abstract there are around 70 classes that extend it. You have to do this 70 times.

Pick your own method. I strongly recommend the first one.
I hope this helps someone.

Cheers,
Marius.

Thursday, September 8, 2011

New Accessories Extension

Because you asked for it, well at least 6 of you asked for it, the 'Product accessories' extension is out. More will follow.
You can find it here: http://www.magentocommerce.com/magento-connect/AnaisSoftware/extension/7880/anais_accessories
The extension is developed by myself under the name of AnaisSoftware (the company I work worked for).

I hope it's what you wanted. If not, well, I'm waiting for suggestions to improve it.

Please contact the e-mail address associated to the extension for the install/uninstall guide. I don't think you need it, it's plug and play, but just in case, or for the PHPDoc.

You can also contact me directly.

I'm waiting for reviews

Cheers,
Marius.

Tuesday, June 7, 2011

Add category names to the product list

In order to add category names to the product list (grid)
you have 2 options. For both of them you have to edit app/design/frontend/{interface}/{theme}/template/catalog/product/list.phtml
1. Add the category (categories) link(s) for all the products in any list (search results included). Keep in mind that any product can be in one or more categories (or none).
At the top of the file add this:
<?php $_category = Mage::regsitry('current_category');?>
<?php if ($_category) : ?>
<a href="<?php echo $_category->getUrl();?>"><?php echo $_category->getName();?></a>
<?php endif;?>
2.
At the top of the file add this:
<?php $_categories = array();?>
This will work as some kind of cache.
Now below the $_product item (inside the foreach) add this
<?php foreach ($_product->getCategoryIds() as $categoryId) : ?>
 <?php if (isset($_categories[$categoryId])) : ?>
  <?php $_category = $_categories[$categoryId];?>
 <?php else:?>
  <?php $_category = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->load($categoryId);?>
  <?php $_categories[$categoryId] = $_category;?>
 <?php endif;?>
 <a href="<?php echo $_category->getUrl()?>"><?php echo $_category->getName();?></a>
 <?php //if you want only the first category link add a break here; ?>
<?php endforeach;?>
This second method covers all the cases but it's a little bit slower than the first one.

Thursday, June 2, 2011

How to change 'My account' menu link in the customer name for logged in users

Hello.
Here is how you can change the 'My account' menu link into the customer name (John Doe) for logged in users.
I'm going to use the same system that the checkout module uses to add the cart and the checkout link.
First of all create a new module that will extend the Mage_Customer module. We will call it Custom_Customer.
In app/code/local folder create a folder named 'Custom'.
[UPDATE]
Inside the Custom folder create a folder 'Customer'.
/* Thanks for the comment 'Anonymous' - see first comment*/
[/UPTATE]
In this folder create a subfolder called 'Block' (because we need a new block).
Inside 'Block' folder create a php file named 'Links.php' with this content
<?php 
class Custom_Customer_Block_Links extends Mage_Core_Block_Template
{
/**
ads my account link to some block
*/
    public function addAccountLink()
    {
        $parentBlock = $this->getParentBlock();//this block will have a parent
        if ($parentBlock && Mage::helper('core')->isModuleOutputEnabled('Mage_Customer')) {//check if the customer module is not disabled
            $customerSession = Mage::getSingleton('customer/session');//the customer session

            if( $customerSession->isLoggedIn() ) {//if the customer is logged in get the name
                $text = $customerSession->getCustomer()->getName();
            } else {//if the customer is not logged in print 'My account'
                $text = Mage::helper('customer')->__('My Account');
            }
//add the block to the set of links.
            $parentBlock->addLink($text, Mage::helper('customer')->getAccountUrl(), $text, false, array(), 10, null, '');
        }
        return $this;
    }
}

Now create the config.xml file for the module.

In folder 'Custom' create a subfolder 'etc' and inside it the config.xml with this content.
[UPDATE]
inside the Customer folder create a subfolder 'etc' and inside it the config.xml with this content.
/* Thanks for the comment 'Anonymous' - see first comment*/
[/UPTATE]
<?xml version="1.0"?>
<config>
    <modules>
        <!-- the  version of the module-->
        <Custom_Customer>
            <version>0.0.1</version>
        </Custom_Customer>
    </modules>
    <!-- Hack to tell magento that our block overrides a core block (that does not exits) -->
    <global>
     <blocks>
      <customer>
       <rewrite>
        <links>Custom_Customer_Block_Links</links>
       </rewrite>
      </customer>
     </blocks>
    </global>
</config>
Now we have to use out block in the design.
in app/design/frontend/{interface}/{theme}/layout/customer.xml replace this:
<default>
        <!-- Mage_Customer -->
        <reference name="top.links">
            <action method="addLink" translate="label title" module="customer"><label>My Account</label><url helper="customer/getAccountUrl"/><title>My Account</title><prepare/><urlParams/><position>10</position></action>
            
        </reference>
    </default>
with this
<default>
        <!-- Mage_Customer -->
        <reference name="top.links">
            <!-- THe block we've just created and the method to add the link -->
            <block type="customer/links" name="customer_links">
             <action method="addAccountLink" />
            </block>
        </reference>
    </default>

Now all we have to do is to tell Magento that we have a new module.
in app/etc/modules create a new file called Custom_Customer.xml (the name is not important) with this content:
<?xml version="1.0"?>
<config>
    <modules>
        <Custom_Customer>
            <active>true</active>
            <codePool>local</codePool>
            <depends><Mage_Customer /></depends>
        </Custom_Customer>
    </modules>
</config>

Clear the contents of 'var/cache' and enjoy.

Tested on Magento CE 1.5.1.0

Tuesday, May 31, 2011

Disabling customer logging

All the tables that start with 'log_' become pretty big after some uptime.
If you don't need these here is a solution to disable them.
[UPDATE]
It seams that the product compare feature is based on this logging. If you disable all the logging you won't be able to compare products. This is a big no-no Magento Team. (see the logging methods marked in the xml below)
[/UPDATE] Create your own Magento extension. Let's call it 'Custom_Log'.
For this you need to create in app/code/local the folder 'Custom' and inside it the folder 'Log'.
Each module needs a config file.
Create inside the 'Log' folder a folder named 'etc' and inside it a file called config.xml with this content:
<?xml version="1.0"?>
<config>
    <modules>
         <Custom_Log>
            <version>0.0.1</version>
        </Custom_Log>
    </modules>
    <frontend>
 <!-- [+] Disable logging -->
   <events>
            <controller_action_predispatch><!--disabling this will 'kill' the product compare-->
                <observers>
                    <log>
                        <type>disabled</type>
                    </log>
                </observers>
            </controller_action_predispatch>
            <controller_action_postdispatch><!--disabling this will 'kill' the product compare-->
                <observers>
                    <log>
                        <type>disabled</type>
                    </log>
                </observers>
            </controller_action_postdispatch>
            <customer_login>
                <observers>
                    <log>
                        <type>disabled</type>
                    </log>
                </observers>
            </customer_login>
            <customer_logout>
                <observers>
                    <log>
                        <type>disabled</type>
                    </log>
                </observers>
            </customer_logout>
            <sales_quote_save_after>
                <observers>
                    <log>
                        <type>disabled</type>
                    </log>
                </observers>
            </sales_quote_save_after>
            <checkout_quote_destroy>
                <observers>
                    <log>
                        <type>disabled</type>
                    </log>
                </observers>
            </checkout_quote_destroy>
        </events>
   <!-- [-] Disable logging -->
    </frontend>
</config>

now you need to tell Magento to use your module.
In app/etc/modules create the file 'Custom_Log.xml' with this content:
<?xml version="1.0"?>
<config>
    <modules>
        <Custom_Log>
            <active>true</active>
            <codePool>local</codePool>
        </Custom_Log>
    </modules>
</config>

now just clear the cache (contents of folder var/cache) and you are done.
The downside of doing this is that you won't get any details of the customers visits. But you can live with that. There's Google Analytics for this.

New design

Based on the visitor suggestions (if they were needed) I decided to change the design of this 'so called blog' to a 'less ugly one'.
I hope this is more readable.

Magento extensions you would like to see or to improuve

Hello everyone.
I decided to make a list and a poll (I hope it's still active when you read this) of extensions that people would like to see or to have perfected.

Here is the the short list I came up with.
Save a product as pdf
Tree like sitemap
Live chat
Yahoo weather widget
Multilanguage FAQ (with categories)
Product accessories
Price based on dimensions (WxHxD)
Multi-language e-mail templates

If you have any other ideas please put them here and maybe you will get that extension.

Please do not suggest online payment extensions.

Marius.

Tuesday, April 12, 2011

Adding 'on the fly' form validation

Here is how you can add 'on the fly' validation for forms in Magento. I mean to validate the forms not only on submit but after editing a field.
Put the following line in a js file included in all the pages or in the <head> tag
Validation.defaultOptions.immediate = true; 

If you also want the classes of the validation to be added not only for the input but fur it's parent also add the following line in the same place as the one above.
Validation.defaultOptions.addClassNameToContainer = true;

Hope it helps