One of the most bewildering missing features I have come across in Magento is the inability to look up orders by ordered products. There are occasions where this feature is sorely needed. For example, you may discover a product needs to be recalled and need a list of every order in the past month containing that product. I discovered I wasn’t the only soul begging for this feature. There is one solution posted which worked but had a few problems. To be precise, it breaks the pager, it replaces a core file and filtering doesn’t work. So, I’ve fixed the major problems and packaged and released it as a free module on github!
This module adds a column to the orders grid which displays either the product name and ordered quantities or the product SKU and ordered quantities which is configurable under Sales > Orders Grid Products Column. The one not selected to be displayed will be added to the title attribute so it can be seen with a mouse hover. The column is filterable by either the product name or SKU depending on the configuration.
You might someday (or perhaps you already have) come across a case where you want one module to be loaded after another module, but don’t necessarily want it to depend on the other module. Reasons might be that one config value should override another (such as a model/block/controller rewrite), or one layout should be applied after another (such as to remove a block added by the former). There might not actually be a dependence, or perhaps adding a dependence would create a circular dependency. There are two possible solutions for this:
- Merge the two (or more) module .xml files manually into one .xml file with the proper XML element order.
- Name the .xml files (or symlinks a.la. modman) such that they sort alphabetically in the proper order.
The element order within a single file will be stable (SimpleXML), and Magento loads the files alphabetically except that those beginning with Mage_ come first. Problem solved.
Before: app/etc/modules/My_Module.xml app/etc/modules/Their_Module.xml After: app/etc/modules/50_Their_Module.xml app/etc/modules/60_My_Module.xml
Now “My_Module” is loaded after “Their_Module” so I can override their config and/or layout without modifying their files and without My_Module depending on Their_Module!
The Zend_Cache module from the Zend Framework is a nice piece of work. It has a slew of programmer-friendly frontends and a respectable set of backends with a well-designed interface. I love the a-la-carte approach, but I am only really interested in the Zend_Cache_Core frontend and the backends that support tagging since that is what is required by Magento. This begs the question, which backend should you use? While I have my own opinion on that matter (ahem, Redis. -post coming soon-ish), I wanted a reliable way to test Zend_Cache backend performances so I wrote a benchmark! This benchmark was both forked from and inspired by the benchmark found in Vinai Kopp’s Symlink Cache. It uses Magento’s core/cache model rather than Zend_Cache_Core directly so a Magento (or Magento-lite) installation and bash are the only requirements.
The purpose of this post is not to provide a bunch of cache backend benchmarks, but rather to simply introduce my benchmark code in the hopes that others conduct their own tests and hopefully publish their findings. A link to this post is appreciated. Also, if there are any criticisms of the benchmark I’d love to see a pull request. :)
I recently had a need to include some code from two subversion repositories in a git-based project. A bit of Googling brought me to the disappointing conclusion that there is no easy maintenance-free way of doing this with git.. Modman to the rescue! With a simple one-liner added to my modman file I can accomplish what is essentially an svn:externals declaration in my git-based project, or a subversion repository as a git submodule! Behold:
EDIT: Updated to use multi-line continuations for readability.
# Substitute for svn:externals @shell \ SRC=https://example.com/source/magento/common; \ DEST=modules; \ if [ -d $DEST/.svn ]; then \ svn update $DEST; \ else \ svn checkout $SRC $DEST; \ fi # Import subversion-based modules @import modules/Foo @import modules/Bar
Now, when I clone the module (git is supported natively as of 1.1.0) or any time I run an update, deploy or repair, the subversion modules will be checked out or updated as well. So, if you ever need to mix and match SCM’s, go right ahead. I still recommend the use of git submodules for all-git projects and svn:externals for all-subversion projects, of course.
I’ll consider adding a builtin function that tidies up the above and handles things like switching urls..
While researching Magento performance optimizations you have probably already read about how to optimize Apache’s configuration by moving your configuration directives into the configuration files and out of the .htaccess files. Of course you need root to do this, but assuming you can, there are still very very wrong ways to do this that will result in no real performance gains, leave gaping security holes, and consume more time than necessary. Read on, a handy script for solving these problems and before and after performance benchmarks to prove the gains are included.
I recently updated Module Manager (first post) to support nested modules and renamed the
.modman definitions file to simply
modman for easier editing in IDEs. To top it off I am officially releasing it to the public under the Apache License 2.0 so that you may start using it in your own projects.
Additionally, Module Manager now has it’s own home on Google Code so check it out! (pun intended)
Here is an example of the new nested modules feature:
# My template files skin skin/frontend/my/default design app/design/frontend/my/default # Import Colin_HotDealz module @import modules/Colin_HotDealz
Added nested modules, renamed .modman file to modman, released under Apache License 2.0, and hosted on Google Code.
This project was inspired by my recent Magento development work so I’m not sure how much application it has outside of that, but if you’ve ever wanted to use svn:externals with individual files (you can’t btw) then this is the next best thing (and therefore the best thing). Perhaps some other VCS supports this functionality natively , if you know of it please clue me in. I’ve used git and bazaar but still like the simplicity of subversion for small, non-distributed projects.
Magento’s source code is split among several different groups of files: code, design, locale, skin, libs, etc (as in config), etc.. (as in etcetera)
You really cannot avoid ever having to mix a file in here or there which means svn:externals won’t cut it. Besides, svn:externals won’t let you make one commit from all of your externals so to commit your changes you have to do it once for each folder which makes your commit history nearly useless. Enter “modman”, my Magento module manager. While it could be used for deployment it is primarily geared towards developers. Here is how it works:
Update: Bug fix
It turns out that when layered navigation indexes are refreshed the
website_id is 0 which causes the filtered results to be empty which makes layered navigation disappear. The fix is to simply place an if statement around the filter dependent on the website id no being 0. The Magento Connect module has been updated with this fix (0.3.1).
Ok, I think this will finally be the last update to this module… I’ve learned a lot about Magento since the first version of this module, and think I finally did it right this time. This update adds support for advanced search (thanks saho for the bug report) and also every other aspect of the store I could find.
See the latest post in this series: Yet Another “Hiding Out-Of-Stock Products” Update, for an update that fixes advanced search, tags, up-sells, cross-sells, etc..
Updated once again to add support for filtering search results. (Added CatalogSearch/Model/Layer.php, moved Model/Layer.php to Catalog/Model/Layer.php, updated config.xml)
My previous post about “Hiding Out of Stock Items in Magento” had one pretty major downfall, in that it did not handle the product counts in the layered navigation. In response to a forum post regarding this I looked into fixing my original solution and have come up with a more concise and complete approach which I present now as a replacement to my original InStockOnly module.