Are there really limitations in Magento?

We frequently hear that Magento doesn’t allow this or that because it’s not built that way, putting us in an awkward situation having no solution to meet our clients’ needs.
Let’s say for a few examples:

– Magento does not support high volumes of attribute’s options
– Magento is slow
– Magento cannot use reddis server prior the community edition 1.8
– Magento does not allow to connect to PostgresSQL db
– Magento does not allow to support more than 1M products
– The pictures displayed in a configurable product sheet are the pictures of the configurable product and not the ones of the simple product itself, that is not possible

I’ve always seen these requests solved by a strange usage of the back-office or in the worst case, by a non answer. This is weird 🙂 We are really very far far away from the communication used in the tenders, where, versus another e-commerce technical solution, we highlight the better native support of Magento to the customer client request 🙂

Every time I hear these common sentences I’m quite a bit in trouble: where are these limitations? Continue reading “Are there really limitations in Magento?”

Optimize Eclipse and Zend studio refresh in Magento projects with the resources filters

If you’re using Zend Studio or eclipse and have kept the native structure of a Magento project (in its first version), refreshing a project could sometime be a long task.

This is partly due to the number of files that change and need to be refreshed: Magento needs to take their new content into account.

To avoid refreshing every file changing frequently, you can exclude them: they won’t appear in the project folder, and so, won’t be
refreshed

Continue reading “Optimize Eclipse and Zend studio refresh in Magento projects with the resources filters”

Looking for (Magento) developers

Develop : « enrich, growth a software »

Yes it’s my definition of the word « develop ». I checked the Internet to ensure that I wasn’t wrong and I agree with the correct definition.

Many years ago, on the first 1.0 Magento release, we made a comparison for a request between the commerce server and Magento plateforms. At this time, the clients chose Magento in part because of its functionalities : Yes Magento is rich, and cover many e-merchandiser requirements.

And in case it’s not enough, there is perhaps a module allowing you to customize it according to your specificities. You know it’s quite easily to reach your customer requirement with this solution.

But I’m always despite when I want to use a functionality on my client’s plateform and see it does not work anymore… Why ? How could that happen ? This function was working, and now, it does not exist anymore….

Yes, web developers have broken it, one more time.

Continue reading “Looking for (Magento) developers”

Magento tips: Display a Magento category path in SQL

Yes, it’s been quite a long time I’ve not been sharing something with you: many projects to handle and no time to share something. And when we are busy, it’s a bit disappointing to see how many time we may lost to do some repetitive tasks

One of these tasks, when you study a Magento sales catalog, is to find in which categories is published a product Continue reading “Magento tips: Display a Magento category path in SQL”

Magento layouts: the limit of reference syntax

If you ever tried to update the Magento page content, you probably used the reference node: this instruction tells that every node under the reference node is applied to the block having the name used in the reference. Here’s an example:

<reference name="head">
<action method="addJs"><script>prototype/prototype.js</script></action>
</reference>

The example above will perform the addJs action on the block with the attribute name head.

This syntax is very useful when, in your custom layouts files, you want to refer to another page content block without updating the layout file which contains the referenced block. This instruction is very useful when you create your own modules and want to only customize Magento page

But sometimes, it does not work.

Why the Magento reference node’s content is sometimes not interpreted?

To understand when this case happens, take a look at the following two modules

Test_FirstModule and Test_SecondModule; Each of these modules embeds its own layout update. The layout of the second module defines a block in the content node called test_secondmodule_content

<?xml version="1.0" encoding="UTF-8">
<layout version="1.0">
    <default>
        <reference name="content">
            <block type="test_secondmodule/content" name="test_secondmodule_content" template="test/secondmodule/content.phtml" />
        </reference>
    </default>
</layout>

The first module refers to this block to provide a child block

<?xml version="1.0" encoding="UTF-8">
<layout version="1.0">
    <default>
        <reference name="test_secondmodule_content">
            <block type="test_firstmodule/content_child" name="test_secondmodule_content_child" template="test/firstmodule/content.phtml" />
        </reference>
    </default>
</layout>

In this case block “test_secondmodule_content_child” will never be available: when Magento builds the blocks list composing the page content, it iterates all defined nodes in the appropriate handles within the Mage_Core_Model_Layout::generateBlock method. But merged layout are parsed in the order they have been added in the configuration, so by default by their name. So in our case, firstmodule.xml will be handled before secondmodule.xml. And this is the problem: Reference expects that referenced block already exists. In our example, it won’t be the case because it will be processed after; so the child block won’t make any render

If you call a reference prior the block, all the references content won’t be processed

The only way to use reference is when they have already be defined

Possible solutions to bypass the reference layout limitation

Play with names of your modules and your database layout updates

You can try to manage order by updating the name of your modules and name of the layout files, but this solution depends on the installed modules: there’s still a risk that your layout will be handled before the expected one.

Use the Magento database layout updates

The database layout updates are always managed after the file’s ones: so if you define your references in database layout updates, they should always refer to a valid defined block. But it’s a more complicated way to develop your module.

Remove reference instructions from the layout

This is a cleaner way: before generating blocks, you’ll move all the references nodes content into the appropriate block node: no more references in your layout, no more risk that there is something wrong because they have been loaded in the wrong order.

The Kyp_LayoutFix module

I’ve created a module, Kyp_LayoutFix, that does that very thing: before generating block content, it removes all references instructions from the used layout

This module has been tested on all Community Editions from 1.4.1 to 1.7.0.2 and on the related Enterprises versions and is a sure way to avoid this references problem

This module is provided under the Open Software License

Download the Kyp_LayoutFix module

This module can be downloaded from my pear channel:

pear channel-discover channel.kyp.fr
pear install kyp/kyp_layoutfix

Or you can download it in a tar.gz file here

Let me know if you have any issue with this module.

Init Magento cache block policy in _construct method… or not

We often see the Magento cache block policy initialization in the _construct method, like in this example:

class Namespace_Module_Block_Type extends Mage_Core_Block_Template
{
     protected function _construct() {
          $category = Mage::registry('current_category');

          $this->addData(array(
               'cache_lifetime' => 86400,
               'cache_tags'     => array(Mage_Catalog_Model_Category::CACHE_TAG."_".$category->getId()),
               'cache_key'      => $category->getId(),
          ));
     }
     ....

This is not a quit good example of cache block policy initialization, for the following reasons

Init cache block policy in _construct adds unnecessary treatment

The problem is due to the way of how Magento loads the page structure and how it will render blocks content loaded from cache:

When you load the layout, Magento will parse and build all defined elements in layouts files. This means instantiate all defined blocks. After, Magento will check if your block content is already in cache, and will use it if yes, or build it if not.

But instantiating one block will call the _construct method. This means even if your block content is in cache, your block will execute each time all instructions within _construct method.

Do you require to rebuild cache tags list each time?

The answer is no. The cache_tags list is required only when saving generated content into cache. So if you initialize the cache tags list in _construct, it would have an interest only if your block content doesn’t come from your cache

Init Magento cache block policy in _construct let you avoid to use layout properties

Another problem is due to accessible data in _construct method: when calling _construct, block initialization is not finished: Magento will populate data, set name in layout, reference current layout in block and so all these informations won’t yet be available.

so layout informations are not yet available, and you restrict cache block policy only to data managed in block

Possible solutions to avoid these problems?

Specifying a cache block policy is not an option for performances reasons. But defining it in _construct method can reduce performances benefits if you continue to load some data within. A possible solution to bypass these problems is to define on your block the methods getCacheLifetime, getCacheKey and getCacheTags: treatments within will be executed only when they’ll be called

Cancel commits on Magento core files with subversion hooks

As a best practice, it is not recommended to update Magento core files. This can be done by Magento overloading mechanism

This morning, an old colleague of mine mentioned that a developer committed some updates in the app/code/core files.

This could be blocked by subversions hooks scripts

What is a subversion hook?

Introduction to subversions hooks: the hook events

Subversion implement a hook mechanism which allows to call some externals scripts on some repository events. This functionality allows you to customize your repository work-flow. The most common hook usages are:

  • Sending email notification (on each commit, when a tag is done, …)
  • Control access to repository (when locking files, …)

List of available hooks events can be found in the subversion documentation

Hook event we’ll use to control our commit must be executed before transaction is completed: the pre-commit hook

What subversion does on a subversion hook event?

On this predefined event list, Subversion will check if there is an executable script in the hooks folder of your subversion repository with the name of the event

If yes, subversion user will call this script with some arguments. Arguments list sent to this script depends on the hook event. For example, for the pre-commit hook script, arguments are:

  • Full path to repository involved
  • Current transaction number
  • With these arguments, you can do what you want within, especially calling all the administrative subversion commands:

    • svnadmin
    • svnlook

    Setting up a subversion hook which cancels the transaction in case core files are updated

    Here’s an example of the script you can use as pre-commit hook for Magento projects

    #!/bin/bash
    ##################################
    # render more readable parameters
    ##################################
    REPOS="$1"
    TXN="$2"
    ################
    # configuration 
    ################
    # path to svnlook script
    SVNLOOK=/usr/bin/svnlook
    #############
    # librairies
    #############
    # a method to send message to client and end transaction
    show_error_message() {
        echo $1 1>&2;
        exit $2;
    }
    ###############################
    # run
    ###############################
    # fetch the account user from the current transaction informations
    AUTHOR=`$SVNLOOK author -t "$TXN" "$REPOS"`
    
    # check if we do not updating file in core files
    $SVNLOOK changed -t "$TXN" "$REPOS" | grep "^U \+app/code/core" > /dev/null
    if test $? -eq 0 
    then 
        show_error_message "$AUTHOR, You cannot update Magento core files" 2
    fi
    

    This script will look for files involved in current transaction with the svnlook script and look for path app/code/core in the output answer. (this svnlook command lists all files and their state in a transaction). If we find something matching, we send a message on the STDERR (STDERR will be sent to subversion client) and exit script with a non 0 error code, which will cancel the transaction and so block the commit

    To use it, just copy this script content in a hooks/pre-commit file of your repository folder and make it executable by the system

    Conclusion about usage of hooks on Magento scripts

    No more reasons to leave developers committing app/code/core files with this script!

    But you can extend hooks to do many other things on your repository: block Magento core files commit, block update on tagged versions, notifications of branch creation, block commit of PHP files which contains parse errors, etc…

    Do you use these events on your Magento repositories?

    Update Magento page structure by overloading the layout content

    There are many ways to update Magento page structure content: all lead to the same thing, a custom page, but not in the same ways. Each method has its own advantages and drawbacks.

    Within this topic we’ll overview overloading page structure by overloading native Magento layout files

    How to overload Magento page structure using loading mechanism ?

    All this process is based upon template loading mechanism which I explained before:

    • You define your design through back-office
    • You copy the Magento layout file to update in the layout folder of your custom design folder

    For example, if you want to overload Magento customer account page content, you can do it by copying the original customer.xml into your custompackage layout folder

    When Magento will be looking for the customer.xml file it will find yours before the default one: this is yours which will be used instead of the native one

    Very easy and quick method to update Magento layout…

    Advantages of updating Magento page content by overloading native layouts

    You are totally independent of the native page structure

    With this method, you are totally independent of the existing page structure: you can do what you want inside

    Quick way to update page structure content

    This is also the quickest way to update page structure: you’ve found which layout file contains the element you want to update, you just have to copy it and update it. No layout update definition, no new module to load to embed some update

    Code more clear

    Almost everybody knows now which files describe Magento page structure. Using this method makes the code reading easier: no many layout update to find which are involved in a page, this is our layout copy which is involved in your page. There are also less treatments to build your page because there are less files to parse to build your page

    Drawback of updating Magento page content by overloading native layouts

    Difficult to capitalize

    Your new layout page structure depends on the design applied. Even if you can add files of some specific packages in a Magento connect package, it’ll only work if the Magento has configured the same design: force users to use a specific value of design is a difficult choice and will make all other modules installation harder

    Difficult to maintain

    Creating a fork makes it more difficult to take advantage of developments that may contain Magento updates, and generally the community.

    Do you use this kind of method to overload Magento page structure?

    A tutorial to enable Firebug console.log in Magento

    Firebug is probably one of the most used extensions for developpers.

    One of the common firebug extension usage is to log and debug elements in console; this is done through the syntax:


    console.log(somethingtolog);

    Problem is this syntax does not render anything with Magento. This tutorial will help you to reactivate this functionnality:

    Why cannot we use console.log syntax within Magento?

    For security reasons, Varien has rendered silently all the methods availables on console object. This is made in the js/varien/js.js javascript file:

    js.js file is loaded on frontend and adminhtml default layout; so in every page, we won’t be able to use console

    Well, and how are we gonna be able to use it?

    How will we be able to reuse the console methods?

    I hope that you’ve not thought of edit js.js and comment the varien code…. 🙂

    We will keep the native functions but want to be able to use it for developments purpose.

    Because this is a javascript framework file, we cannot use the skin overload mechanism. So, we’ll load a copy of the native script but only for development purposes

    Make a copy of the original js.js file

    cd js/varien
    cp js.js jswithconsole.js
    

    Commnent the original code source that disables the console methods

    In the copy, we’ll comment the console function overload. You should have something like this:

    Load firebug console native methods only for Magento developments purposes

    In vhost configuration file, or .htaccess file, we’ll replace our file with the new one containing the following rewrite rule:

    <IfModule mod_rewrite.c>
    
    ############################################
    ## enable rewrites
    
        Options +FollowSymLinks
        RewriteEngine on
    ## begin update to load a specific file 
    ## which enable firebug console when developper mode is set
    ## http://blog.kyp.fr
        RewriteCond %{REQUEST_URI} js/varien/js.js
        RewriteCond %{ENV:MAGE_IS_DEVELOPER_MODE} =1
        RewriteRule ^js/varien/js.js$ /js/varien/jswithconsole\.js [R=302,L]
    ## end update
    ...
    </ifModule>
    

    Make sure that MAGE_IS_DEVELOPER_MODE value can be tested

    The only problem with this rewrite rule is that we test a value for an environnement variable. It will never work if you used to declare MAGE_IS_DEVELOPER_MODE with the following syntax:

    	<Directory /your/magento/root/folder>
    		Options Indexes FollowSymLinks MultiViews
    		AllowOverride All
    		Order allow,deny
    		allow from all
    		DirectoryIndex index.php
    		setEnv MAGE_IS_DEVELOPER_MODE "1"
    	</Directory>
    

    One way to ensure that testing environnement value will work could be the following MAGE_IS_DEVELOPER_MODE definition:

    	<Directory /your/magento/root/folder>
    		Options Indexes FollowSymLinks MultiViews
    		AllowOverride All
    		Order allow,deny
    		allow from all
    		DirectoryIndex index.php
    		#setEnv MAGE_IS_DEVELOPER_MODE "1"
    		SetEnvIf _ .* MAGE_IS_DEVELOPER_MODE=1
    	</Directory>