Solving Magento

Solutions for Magento E-Commerce Platform

by Oleg Ishenko

PDF and EPUB Versions of Magento Product Types: Developer’s Guide

I am happy to announce that my book Magento Product Types: Developer’s Guide is now available as PDF and EPUB on Leanpub! I have long been promising a version other than Kindle, and now there it is:

magento-product-types-devel

Leanpub offers a .mobi (Kindle) version as well. I still recommend getting the Kindle-formatted book from Amazon, which I have carefully tested. The Amazon links are in this post: Magento Product Types: Developer’s Guide

Your comments and Magento Questions

One of the most rewarding parts of blogging is getting comments and being asked questions on my work. Unfortunately recently I’ve been unable to quickly respond to your comments and give advice on your Magento problems. Currently I am deeply engaged in a startup and this takes all my time. For this reason I must recommend you to post questions on Magento StackExchange – the community there will help you faster and better than I ever could. I’m sorry, I’m not as available to my readers as I wished I would.

Adding Custom Options to Products in Magento

In my post A Magento File Custom Option Type Primer I’ve talked about how file custom product options are handled in Magento. One of the readers posted a comment there asking if there was an alternative to manually adding custom options to existing products. For such a task I can recommend MAGMI, Magento Mass Importer, which was used in one of my projects to import product data including custom options. Another solution would be writing a script which could dynamically add custom options to a set of existing products. In this post I will show you how to create such script.

First, let’s see how custom option data are written to database when a product is saved. The product model class Mage_Catalog_Model_Product has a protected method _afterSave which is called, as the name suggests, after a product model is saved.

Continue reading

Quick Tip: Magento Catalog Price Rules Don’t Work

In this post you’ll find a list of likely reasons to why your catalog price rules do not have any effect on prices of products they are supposed to control. The problems listed below are most likely to occur without being caused by a custom module, i.e. it is assumed that catalog price rule functionality has not been changed. The reasons are not mutually exclusive and it is possible that more than one applies to your case. If you, however, find a reason not listed here, please post it in the comment section. This would be much appreciated. So, to the list:

Continue reading

Magento Global Functions

Reinventing the wheel – what a cliche! Of course you don’t do it, at least not intentionally. And you hate being reminded of code reuse on those rare occasions when someone points to a function you wrote, which allegedly does the same as some other function somewhere in the framework. Yet it happens. Sometimes looking for blueprints for the wheel takes longer than hacking it out yourself. Sometimes you might do it just for fun. And sometimes you simply don’t know a ready solution exists buried in some obscure location in your framework. Magento is no exception – it does have some functionality left there by the core programmers, which is used extensively by the system and yet often overlooked by us, shop maintainers and extension developers.

A few such gems can be found in app/code/core/Mage/Core/functions.php. This file contains no class definition but globally available functions. This file is included early in the application initialization stage in app/Mage.php. Some of its functions may be of little use when developing extensions, since they do core system work. But some can come in handy whenever a trivial task presents itself and you have to:

1. Find out if a Directory is Writable in Magento

It is a true rarity, a Magento shop running on Windows. Still, improbable not impossible. Assuming you are in a Linux environment, this task can be easily accomplished by calling is_dir($path) and is_writable($path). Not so simple with Windows hosts. The function is_dir_writeable($dir) does some additional checks for such cases – by literally trying to write a file into the directory being checked. This function is used by Magento when checking writability of certain paths during a shop installation before creating vartmp and cache directories. Obviously, it is a well-proven approach – why not use it?

2. Output a Current Date

A neat shortcut to generate a MySQL-compatible date string, meet now($dayOnly=false). Leave the $dayOnly empty or set to false to get a Y-m-d H:i:s-formatted string, otherwise it will output a short Y-m-d representation of the current date.

function now($dayOnly=false)
{
    return date($dayOnly ? 'Y-m-d' : 'Y-m-d H:i:s');
}

3. Recursively Delete a Directory in Magento

Ever needed to delete a deeply nested directory structure? Use mageDelTree($dir). Magento uses this function to, for instance, clear user sessions when they are stored on disk.

4. Find out if a Class exists in Magento

If you need to make sure an external dependency is available in your installation, check it with mageFindClassFile($class), where the $class parameter is a class name, e.g. ExtPackage_ExtModule_Model_Classname.

5. Use an Extended Version of ucwords

This nifty little function does the same as the regular ucwords. And more! If you need to uppercase words in a string that is separated by characters other than whitespace – you can save some extra lines of code here. Say, you have a string modulename_model_classname. Converting it into a valid Magento class name will require just one call:

$className = uc_words('modulename_model_classname');
//$className === Modulename_Model_Classname

This function can also swap separators. So if there is a string modulename/model/classname it can be converted into a valid class name by calling:

$className = uc_words('modulename/model/classname', '_', '/');
//$className === Modulename_Model_Classname

Neat, eh?

6. Parse a CSV String in Magento

Now this kind of task comes fairly often. This function will save you time writing a parser – even if such is simple and takes a minute. But why bother if the function already exists? And it can handle quoted values as well. Check it out:

mageParseCsv($string, $delimiter=',', $enclosure='"', $escape='\\')

The last parameter, however, is redundant and used nowhere in the function.

Quickly Create Magento Module Structure with a Powershell Script

Your work on a new module usually begins with a tedious task of creating the basic folder structure. You go to your app folder, cd to code, then to local, then to you working package directory. You add module folder and then etc, Block and Helper. Before you actually get to programming you logic you have to add and edit config.xml, helper.php. And when you are done and ready to fire the first test you remember you forgot to add an xml module file to app/etc/modules.

Sounds familiar? But you are a programmer; so why not try to solve this problem like a programmer?

Its fairly easy to write a shell script for Linux that would do all this dull work for you. But for those who work in Windows (I do) automating this task would mean diving into decades old DOS scripting to create a bat file. Fortunately there is a better alternative: PowerShell. This object oriented scripting framework was first introduced in 2006 and since then had evolved into an incredibly nifty tool for every advanced Windows user.

After some tinkering I was able to produce a script that offers GUI to enter destination app folder, package and module names and creates the basic folder structure and essential files in no time. No installation required: download, unzip, and double-click!

Download it now, its free to use, modify and distribute:

 

Symbolic Links

It is surprising how many people don’t know about symbolic links and do not realize how useful they can be. For instance you are running a test server with multiple instances of out shop configured as separate installations. You can easily update the source code by pulling it from a common repository. But what if you need to update you media files, which normally are not under version control? And what if there are tens of gigabyte of them? You don’t want to copy the files to each installation, instead copy them into one folder and set up symbolic links for the media folders of your test sites:

Creating a symbolic link (syntax):

ln -s [TARGET DIRECTORY OR FILE] [SHORTCUT]

For example:

ln -s /var/media /var/www/vhosts/test01/media

ln -s /var/media /var/www/vhosts/test02/media

and so on…

 

 

Using Macros for Apache Virtual Hosts Configuration for Magento Multistore Environment

When working with a multistore environment it is often necessary to setup several virtual hosts whose configuration is essentially the same apart from one or two settings. Instead of copying and pasting each configuration twice (do not forget about the SSL) one can use a third party extension for Apache web server called mod_macro. This module allows you setting up templates (macros) of your configuration. Your actual vhosts entries will contain references to these templates providing values for variables you defined.

Installing mod_macro on a Ubuntu server is simple by running the apt-get utility:

sudo apt-get install libapache2-mod-macro

Alternatively, download the module and perform a direct installation as described here.

Sample usage

Consider you have to configure two shops running from the same installation. You want them to have two different top level domains (myserver.com and myserver.de) and keep logs separate.
Create a new virtual host configuration file under /etc/apache2/sites-available/ and create your template as follows:

<Macro MyTld $tld>
    ServerAdmin admin@myserver.com
    ServerName www.myserver.$tld
    ServerAlias myserver.$tld
    ErrorLog ${APACHE_LOG_DIR}/error_www.myserver.$tld.log
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/access_www.myserver.$tld.log vhost_combined
    DocumentRoot /var/www/www.myserver.com

    <Directory /var/www/www.myserver.com>
        SetEnv MAGE_RUN_CODE "$tld"
        Options  FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
 </Macro>

Also set up an SSL macro:

<Macro MySSL>
    SSLEngine on
    SSLCertificateFile    /etc/ssl/certs/www.myserver.com-cert.pem
    SSLCertificateKeyFile /etc/ssl/private/www.myserver.com.pem
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
       SSLOptions +StdEnvVars
    </FilesMatch>
    BrowserMatch "MSIE [2-6]" \
        nokeepalive ssl-unclean-shutdown \
        downgrade-1.0 force-response-1.0
   # MSIE 7 and newer should be able to use keepalive
    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
 </Macro>

Finally add your virtual hosts:

NameVirtualHost *:80
NameVirtualHost *:443

 <VirtualHost *:80>
     Use MyTld com
 </VirtualHost>

 <VirtualHost *:443>
     Use MyTld com
     Use MySSL
 </VirtualHost>

 <VirtualHost *:80>
     Use MyTld de
 </VirtualHost>

 <VirtualHost *:443>
     Use MyTld de
     Use MySSL
 </VirtualHost>

Advantages of using mod_macro are self-evident:

  • smaller configuration files to maintain
  • less bugs due to copy-pastes only partially updated
  • better readability

More information on mod_macro can be found here.

Theme: Esquire by Matthew Buchanan.