Wiz 0.9.3-beta: Better Admin User Creation, Cache Clearing & Indexing

It has been a while, but Wiz has not been forgotten! The latest update, 0.9.3-beta, brings the following new features and improvements:

  1. Indexing functions and information are now available.
  2. Caching now supports clearing and viewing invalidated caches.
  3. Caching now has more options to clear all of the various Magento caches.
  4. Errors setting up admin users on Linux systems should be resolved.
  5. Adding Admin users should now work for every version and configuration. The SQL method for creating users was removed in favor of using the admin user model.

Enjoy! Browse on Github

eBay Acquires Magento (Inside Information)

As you’ve heard by now, eBay will be closing on a 100% acquisition of Magento in the third quarter of 2011.  This should not surprise anyone too much considering eBay took a substantial stake in Magento with a $20-something million investment in February with the string attached that Magento develops Magento Go to compete with the entry-level eCommerce market, equipping eBay to offer a plug-and-play SaaS eCommerce solution to their millions of eCommerce customers using PayPal.  Add in the fact that eBay is a huge player in the eCommerce world, and it makes sense they would want to create a comprehensive offering by blending together their eBay and PayPal offerings with an eCommerce platform offering.

So, it makes sense.  Now the real question:  What does the future of Magento look like?  I’m going to stick my neck out here and take a guess based on my conversations with Magento insiders yesterday, my knowledge of Magento’s market position development since its inception, and eBay’s current position.

First, let’s take a look back and see what eBay has been doing up to this point to build this X.Commerce “operating system.”  PayPal purchased a 49% stake of Magento back in February, and Magento then builds a hosted SaaS version of its software, Magento Go, to service the lowest end of the market.  Then eBay acquires GSI Commerce, a company that services the highest end of the eCommerce market, for $2.4 billion.  Shortly before this, eBay announced that they would be bringing together their eBay and PayPal developers to one conference in October 2011 to begin the process of collaboration and unity.  And earlier this week, eBay has now completed their conquest and purchases Magento, which services the mid-sized eCommerce market.  While there are still certainly more acquisitions to be had, eBay has positioned itself to effectively service eCommerce merchants of all sizes

That’s all easy stuff, though.  The real question is, how is eBay going to bring all of this together under one roof?  Will there be one software platform to rule them all?  Or will eBay keep them segregated?  I believe that eBay must keep the GSI Commerce side of the business separate from the Magento and Magento Go side of the business.  If nothing else, for this simple reason:  Magento is open-source and PHP-based.  GSI is proprietary and Java-based.  Combining two completely different platforms would be very challenging, and if they did combine them, they would nearly certainly have to maintain Magento’s open-source nature to retain the development community’s buy-in, which is a leading reason for Magento’s massive success.

What I do think is more possible is that Magento, Magento Go, and GSI will be rebranded under the X.Commerce flag in some way, but not immediately.  I am very confident eBay doesn’t want to make one ring to rule them all.  Rather, they’re building a ring shop, so if you want a ring, you know where to go:  X.Commerce.

So for the time being, it appears as though this is going to have a primarily positive impact on Magento’s future.  My primary concern is that eBay’s size will inhibit one of Magento’s most redeemable qualities:  It’s agility and responsiveness to market demand.  To my satisfaction, Magento’s leadership will remain in place, but there will be additional oversight from this point forward.  Only time will tell how that will affect Magento’s agility in the future.
The good news is that we at Classy Llama will continue to be increasingly more agile and effective on the Magento platform, and we are prepared to flex with the changes as they come.  We will be attending eBay’s Innovative X Conference on October 12th and 13th, which will be the first coming together of eBay, PayPal, and Magento developers (and probably GSI Commerce and others) under one roof to collaborate and build X.Commerce, the most comprehensive eCommerce offering on the market.  We’re excited.  We have a bigger arena in which to play the game we love.

Add Custom Layout Handles (e.g. Parent Categories)

If you ever need custom layout handles in your local.xml, it’s fairly simple. In this example, the observer method will make a new handle for categories that have children or not, but you can just modify the method to make whatever handle you desire. (I realized after creating this there’s already a handler for anchored categories with no subcategories,catalog_category_layered_nochildren)

First, add this to your config.xml in yourcustommodule:

<config>
<frontend>
        <events>
            <controller_action_layout_load_before>
                <observers>
                    <yourcustomtheme_observer>
                        <class>yourcustomtheme/observer</class>
                        <method>addHandles</method>
                    </yourcustomtheme_observer>
                </observers>
            </controller_action_layout_load_before>
        </events>
</frontend>
</config>

Then add this method to your observer:

class YourPackage_YourCustomTheme_Model_Observer extends CLS_Core_Model_Abstract
{
    public function addHandles($observer) {
        $category = Mage::registry('current_category');
        if ($category instanceof Mage_Catalog_Model_Category) {
            $update = Mage::getSingleton('core/layout')->getUpdate();
            $fertilility = (count($category->getChildrenCategories()->getData())) ? 'parent' : 'nochildren';
            $update->addHandle('catalog_category_' . $fertilility);
        }
        return $this;
    }
}

Create a Priority Inbox in Mail (only show unread + flagged emails)

I have come up with a system of managing my emails in Mail (OS X only) that has helped me tremendously in managing the dozens of emails I receive each day. Before this system, I used to mark emails as unread that I needed to take action on. This became very unwieldy as I would lose track of what I had read vs what I just needed to take action on at a later point. I had many emails fall through the cracks, and urgent emails didn’t get regarded as promptly as they should have.

To solve this problem, I spent time experimenting with Mail’s Smart Mailboxes. I wanted a Smart Mailbox that showed me only unread + flagged messages. This would allow me to read a message, and if I needed to regard it at a later point, I could just flag it (Cmd + Shift + L) and know that my mailbox would force me to see it until I unflagged the message. If you are familiar with Gmail’s new Priority Inbox functionality, this is system is essentially that (minus the algorithms that Gmail has that removes irrelevant emails from your Priority Inbox – eg, I get emails from a Cron system every night that Priority Inbox would exclude).

Mail’s Smart Mailbox functionality forced me to create three different Smart Mailboxes to accomplish what I wanted to accomplish, with two of them feeding my “CLS” Smart Mailbox which is my equivalent of Gmail’s Priority Inbox.

Something to note about this setup: When you’re in the CLS Smart Mailbox and you read an email, that email will continue to show in that mailbox until you either restart Mailbox or click to another mailbox and then click back to CLS. This is sometimes nice, but other times can be a nuisance.

I would highly recommend you trying out this email management system.  It’s revolutionized my email world, and maybe it will revolutionize yours?  If you have questions on how to set it up, feel free to ask in the comments.

Wiz 0.9.0-beta: Specify Scope, Create EE Admin Users, and more…

The initial flow of love for Wiz was greatly appreciated!  I’m not certain how many people actually have downloaded and are using Wiz today.  We may never know fully…  But the buzz that was generated was definitely invigorating!

We have recently rolled Wiz out to our entire team here at Classy Llama.  No doubt within the next few weeks we will see more features being added as our people put it through the hoops.  Enough about that.  Let’s get on with it!

Specifying a scope code

By default, Wiz will execute your commands running inside of the admin scope.  This is great for practically everything, however using the 301-urlskumap to generate a CSV of SKUs to URLs caused issues when running inside of the admin.  Now all you have to do is:

wiz 301-urlskumap --store

And it will execute inside of the store’s scope, giving you the proper rewritten URLs.  If you leave out the code, it will use the default store.

--website

is also available.

Adding EE Admin Users with AdminGWS

Creating admin users on Magento Enterprise and Magento Professional is technically the same.  The both use SHA256 to store passwords instead of MD5.  And they both share the same database structure for users.  However, EE has an additional module called Enterprise_AdminGWS.  This is important because this module actually modifies the structure of the role table to include GWS (Global, Website, Store) level permissions.  Wiz will now check for and properly adapt to the presence of this module.

Log cleaning

One of the comments on the initial post mentioned tying into the Magento provided shell commands.  This is the first part of that excellent idea.  The one curious thing about this conversion is that the –days argument is not present.  Interestingly enough, although Magento provides this option in their shell script it does not work properly.  It ignores it and uses what is in the config.

Roadmap

We currently have only one driving force behind where Wiz development time gets spent: feature requests.  You are more than welcome to submit a feature request/issue on the Wiz Github page.  Here is what is being planned and worked on for future releases:

  • Indexing control (in the same vein as cache control).
  • Compiler functionality.
  • Status (lists version, modules, module versions, the number of products, categories, etc.) in a report format.
  • Auto-updating from within Wiz.
  • Module creation and modification.

As always, your feedback is welcomed and greatly appreciated!

If you have not started using Wiz yet, go get it!

Blog Posts = Free Chocolate… Smart? Umm, yeah.

We at Classy Llama value public contributions from our team members.  We have an open blog policy where anyone on the team can post on our blog about anything they believe is noteworthy and relevant.  Over the past 3 years, we’ve averaged about one post per month.  We noticed that our blog represents fully half of our site traffic, albeit less quality traffic, but we like big traffic numbers because it makes us feel better about ourselves, so we decided it would be awesome if we increased our average number of blog posts per month.

So… we did what any reasonable, balanced agency would do:  We offered chocolate to team members for blog articles.  And since we are Classy Llamas (as opposed to the spitting, filthy, despicable kind), we naturally put up a professionally hand-drawn cardboard sign hung by a telephone cord in the main meeting area in our offices.

The results?  Five blog posts in one week.  And they range in quality from good to great.  I have to admit, I felt like a Wiz after implementing this reward system.  And I was like, “OMG! This could be more successful than Facebook Mail.”  And then I stopped saying silly things and said, “Square things make me angry.”

After having this strange internal chat about it, a deep foreboding overtook me.  It dawned on me that, in an effort to produce more meaningless traffic to our site, we may accidentally forget to get any work done!  Had I made the greatest mistake ever to be made in history?!  Time will tell.  For now, I’ll eat my Turkish Delight and be blissfully unaware of the impending doom it is certainly causing.

The only question that remains:  Will I give myself another dozen delicious Ferrero Rocher for THIS article?  After all, it’s the ONLY REASON I WROTE IT!  Mwahahahahahahah!

Good vs. Great

Since joining the team a little over a year ago I’ve learned some things about myself.  One thing I realized early on is that I was allowing myself to settle for “good”.  It’s easy to create “good” design, and it’s way too popular these days.  I know this because I see “good” design all over the web:  blogs, portfolios, and galleries.  It’s cheap.

When I first joined the team it was difficult to hear Joey (the Classy Llama Creative Director) pick apart my designs, and force me to rethink, redo, and start over.  I would think in the back of my mind, “It’s good enough, why is he creating such a fuss about this?”.  After far too long I finally began to realize that I was unfortunately right.  It was “good enough”.

But should I be satisfied with just being “good enough”?  This was a slap in the face, to say the least.  And although it took some time for me to understand, I finally realized that I didn’t want my work to be “good enough”, and neither did Joey.  Actually, I couldn’t ask for a better environment to grow, learn and stretch myself.  And, luckily, Joey didn’t give up on me.  What I’ve learned from this team will never be forgotten, and I hope that I will continue to apply it to every area of my life, not just design.

I want to be great at what I do, not just good enough.

I challenge you, even if you’re not a designer or artist, to look at yourself and ask “Is the effort I’m putting into this just ‘good enough’, or could I push a little harder?”  Ask yourself this on a daily basis, and be brutally honest with yourself, you won’t regret it.

-Jeremy Wells, Lead Artist

No More Square (White Background) Magento Product Images

Do you have a site with product images of varying proportions? It can be annoying when Magento gives you that white border to make your product image square. Here’s how customize what color that background is: just add backgroundcolor(‘000’, ‘000’, ‘000’)before the resize() method

<code>
<img src="<?php echo $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail',<br/> $_image->getFile())->backgroundcolor('000', '000', '000')->resize(100); ?>" ... />
</code>

Better yet, get rid of the background using keepFrame(false):

<img src="<?php echo $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail',<br/> $_image->getFile())->keepFrame(false)->resize(100); ?>" width="100"  ... />

Resizing after keepFrame(false) will resize the largest dimension. Don’t forget to delete your image height and width attributes (if need be)!

Here’s (most of) the places you’ll want to change these:

  • catalog/product/view/media.phtml
  • checkout/cart/item/default.phtml
  • catalog/product/list.phtml

There may be a few more but I bet you can find them. Enjoy your no longer square (white background) images!

Introducing Wiz, a CLI Tool for Magento

There is a lot of functionality in Magento that is hard to get to or tedious to work with.  There are so many tasks that developers, designers, and administrators do on a daily basis that requires time-consuming trips to the Magento backend.  If you happen to want to do more than one of those operations, you end up having do each of those tasks one after the other… if only there was a better way!

It is my pleasure to announce Wiz: a command-line interface tool for working with Magento installations.  It was built to make your work (and subsequently your life) much easier!

Wiz has a whole bunch of great features, but here are some you’re sure to like:

  • Create an admin user (tested in CE & PE)
  • Toggle template hints
  • Enable/disable module names
  • Enable/disable module output
  • Run xpath queries over the global config
  • Enable/disable/clear caches
  • … and more!

Wiz is a work in progress and hasn’t been thoroughly tested with every Magento version out there.  However, we’ve been using it with Professional and Community Edition installations without any major problems.

Things planned for future releases:

  • Templates for building modules
  • Better support for stores and configuration scopes
  • More useful utilities like reindexing, cron runs, etc.

Your feedback and bug reports are welcome!

A Guide to Currency & Prices for Orders, Invoices, and Quotes

If you’ve ever looked at a var_dump() or var_export() of an order, quote, or invoice object, you might have noticed there are a long list of numbers that are present in that object. Here is a sample taken from an order object:

    'base_currency_code' => 'USD'
    'store_currency_code' => 'USD'
    'order_currency_code' => 'USD'
    'global_currency_code' => 'USD'
    'store_to_base_rate' => '1.0000'
    'store_to_order_rate' => '1.0000'
    'subtotal' => '369.7500'
    'tax_amount' => '0.0000'
    'shipping_amount' => '9.8600'
    'grand_total' => '379.6100'
    'discount_amount' => '0.0000'
    'base_subtotal' => '369.7500'
    'base_discount_amount' => '0.0000'
    'base_tax_amount' => '0.0000'
    'base_shipping_amount' => '9.8550'
    'base_grand_total' => '379.6050'
    'shipping_tax_amount' => '0.0000'
    'base_shipping_tax_amount' => '0.0000'
    'base_to_global_rate' => '1.0000'
    'base_to_order_rate' => '1.0000'
    'subtotal_incl_tax' => '0.0000'
    'base_subtotal_incl_tax' => '0.0000'

There are a lot of fields here and they can be quite confusing.  The goal here is to help you decipher the numbers and explain what they mean.

Note: If the names of those variables don’t look familiar, it’s probably because you won’t see them in the code anywhere. They are accessible via an object’s accessor methods. So to get the ‘base_grand_total’, you’d need to call $object->getBaseGrandTotal(). Sorry for the confusion!

For starters, though, let’s cover a little background on currency.

Currency

It wouldn’t be a good article about money with some discussion about currency. Most people probably won’t have to worry about currency conversion, however, a look at price information would be incomplete without touching on it since it is vital to decoding it. Lines 139 through 155 in app/code/core/Mage/Sales/Model/Quote.php talk about the currency logic Magento uses as well as what to use and not use when dealing with these values.

/**
     * Currency logic
     *
     * global - currency which is set for default in backend
     * base - currency which is set for current website. all attributes that
     *      have 'base_' prefix saved in this currency
     * store - all the time it was currency of website and all attributes
     *      with 'base_' were saved in this currency. From now on it is
     *      deprecated and will be duplication of base currency code.
     * quote/order - currency which was selected by customer or configured by
     *      admin for current store. currency in which customer sees
     *      price thought all checkout.
     *
     * Rates:
     *      store_to_base & store_to_quote/store_to_order - are deprecated
     *      base_to_global & base_to_quote/base_to_order - must be used instead
     */

Magento provides a hierarchal system for managing a currency. Currency can be set globally, at the store or “base” level (for display), and then at the quote and order level based on the customer’s preference. The global currency is used in the backend for setting up prices on products. Even if a store is configured to use a different currency, the prices for the objects will be converted from the base currency to the currency of the store. This is important because decoding the names of the values on the object will require us to know how Magento handles dealing with multiple currencies. (Even if only one is configured and used.)

Keeping in mind the three tiers, if we look closely at the object we can see the three tiers of currency information stored in the values:

            <span style="background: #ff8c90;">'base_to_global_rate' => '1.0000'</span>
            <span style="background: #ff8c90;">'global_currency_code' => 'USD'</span>
            <span style="background: #690;">'base_currency_code' => 'USD'</span>
            <span style="background: #690;">'base_discount_amount' => '0.0000'</span>
            <span style="background: #690;">'base_grand_total' => '379.6050'</span>
            <span style="background: #690;">'base_shipping_amount' => '9.8550'</span>
            <span style="background: #690;">'base_shipping_tax_amount' => '0.0000'</span>
            <span style="background: #690;">'base_subtotal' => '369.7500'</span>
            <span style="background: #690;">'base_subtotal_incl_tax' => '0.0000'</span>
            <span style="background: #690;">'base_tax_amount' => '0.0000'</span>
            <span style="background: #690;">'base_to_order_rate' => '1.0000'</span>
            <span style="background: #8c90ff;">'discount_amount' => '0.0000'</span>
            <span style="background: #8c90ff;">'grand_total' => '379.6100'</span>
            <span style="background: #8c90ff;">'order_currency_code' => 'USD'</span>
            <span style="background: #8c90ff;">'shipping_amount' => '9.8600'</span>
            <span style="background: #8c90ff;">'shipping_tax_amount' => '0.0000'</span>
            <span style="background: #8c90ff;">'subtotal' => '369.7500'</span>
            <span style="background: #8c90ff;">'subtotal_incl_tax' => '0.0000'</span>
            <span style="background: #8c90ff;">'tax_amount' => '0.0000'</span>

In red, we see the global currency as well as the conversion rate from the base (or the store) rate to the global rate. In green, we see nine fields. In blue, there are eight fields. You can tell from these values that we are looking at the dump from an order object because one of the fields listed is order_currency_code. Since we are looking at an order, we know that the fields that are not prefixed with base_ or global_ are in the currency of the order. The green fields are nothing more than the order’s fields recalculated in the base (or store) currency for ease of access.

Totals, Amount, Tax, & Shipping

So we’ve essentially got seven distinct values to work with:

  • discount_amount
  • grand_total
  • shipping_amount
  • shipping_tax_amount
  • subtotal
  • subtotal_incl_tax
  • tax_amount

Discount Amount

This is the dollar value of the discount that was applied to the order.

Shipping Amount

The amount paid for shipping on the entire order.

Shipping Tax Amount

This amount of tax that is paid on the shipping.

Subtotal

The cost of just the products without shipping, taxes, or discounts.

Subtotal Including Tax

This amount of tax that is paid on just the products.

Grand Total

This is the total amount of the order after includes taxes, shipping, and discounts. For an order or quote, this is what would be paid by the customer.

Closing Thoughts

How Magento does it’s calculations is highly configurable. There are many options in the backend that affect how taxes, shipping, and discounts affect the totals and values we’ve seen in this article.

To summarize, Magento stores copies of each of the values in both the currency that the current invoice, order, or quote is in as well as the currency of store.  This allows a programmer to see and use both values.

Contact Us