Blog

Octa.com gets a complete redesign

Thursday, July 18th, 2013

Using the gorgeous graphics they created in-house, we’re rolling out the new site in a big way.  Given that the site is visited primarily on mobile devices, we are ensuring that the site looks good on a variety of screen sizes by leveraging responsive design.

Magento Backorders – Complete with Notifications to Customers

Tuesday, July 2nd, 2013

There’s many articles out there that cover how to enable backorders in Magento, and that is simple enough.

However – there are several pieces of this puzzle that are nowhere brought together for a “full” backorder solution.

This solution allows:

  1. Your products to be set to backordered
  2. You to set a custom notification for the product page
  3. Your customers to be notified in the cart page

Enable Backorders in the Dashboard

  1. Log into your Magento admin dashboard.
  2. Hover over the “System” menu.
  3. Click “Configuration”
  4. On the left-side menu, choose “Catalog”
  5. In the Catalog sub-menu, choose “Inventory”
  6. In the pane on the right, find the select box titled “Backorders”, and choose “Allow Qty Below 0 and Notify Customer”

Now that you’ve enabled backorders, a few things happen.  First, products with a quantity of zero are still displayed, and may still be added to the cart.  However, they do not show any indication of being backordered in the product page, which these next two steps will correct:

Modify Your Theme File to Display a Custom Backorder Message

Find the following theme file:

[your theme]/[your_theme]/template/catalog/product/view/type/default.phtml

Open it up, and you should see a line of code that says

$_product = $this->getProduct()

Add the following code immediately after that line:

 // Backorder message
	$backorder_message = '';
	$inventory =  Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product);

	if((int)$inventory->getQty()<=0 && $inventory->getBackorders()>=1) {
		$backorder_message = '

' . $_product->getData('backorder_message') . '

'; }

Then, immediately below / after the

endif;

line, add this:

echo $backorder_message;

Add the Custom Backorder Message to the Product
The final step in bringing this all together is adding a new attribute to the product that is going to be backordered.

This is simple to do via the Magento dashboard:

  1. Edit the product in question.
  2. On the left menu, choose “Description”
  3. Near the top of the page, click the orange button titled “Create New Attribute”
  4. Important: be sure to set the Attribute code to backorder_message (this is the exact code that the template changes are looking for, so it has to be correct).
  5. Set the rest of the attribute up as desired.
  6. Save the attribute.
  7. The attribute will now be displayed for you to fill in on the product. Enter your custom message.
  8. Save the product.

You may need to reindex in Magento, or clear cache, but when you do, your message will display if, and only if, you have zero quantity (or less) and the site is set to backorder.

Magento Staging Setup Accessing Live Database with SSL Certificate

Saturday, June 22nd, 2013

With a recent project, we needed to get the Magento staging environment on the same server and accessing the same database as the live environment.  There was lots of setup, product adjusting, etc. that needed to be done, and the client didn’t want to have to do it twice.

Setting up the staging environment was fairly straightforward, thanks to the excellent article over at Mag Life.  However, the article didn’t quite get the job done.

The live site, like all good live ecommerce sites should, was using an SSL certificate to provide a secure connection.  However, the SSL was for a fully qualified domain name (www.sitename.com) and the staging site was on a subdomain (dev.sitename.com).  Because the SSL settings are in the database, every time we attempted to hit a secure page, the dev site would no longer load, and instead would attempt to load the live site again.

Additionally, I felt lazy and didn’t want to set up server environment variables like the article at Mag Life, so I made a few other alterations to the code.

When attempting to set this up, follow the directions over at Mag Life, but utilize this code in your Store.php file:

class Alphachannel_Core_Model_Store extends Mage_Core_Model_Store
{

    /**
     *  This function is modified per the Mag Life article.
     *  With one modification to avoid setting server environment variables
     **/
    public function getBaseUrl($type=self::URL_TYPE_LINK, $secure=null)
    {
    	// This is the lazy bit.  Rather than setting 
        // environment variables, just set the url's here
    	$urls = array("www.sitename.com"=>"dev.sitename.com");
        $store_code = $this->getCode();
        $url = parent::getBaseUrl($type, $secure);
        // Several nested ifs are removed from Mag Life version 
        // that deal with the environment variables
        $host = parse_url($url, PHP_URL_HOST);
        if (isset($urls[$host]))
        {
            $url = str_replace('://'.$host.'/', '://'.$urls[$host].'/', $url);
            $url = str_replace("https:", "http:", $url);
                }
        return $url;
    }

    /**
     * This is the same function as the core files, with one 
     * minor alteration to prevent https redirects
     **/
    public function isCurrentlySecure()
    {
        $standardRule = !empty($_SERVER['HTTPS']) && 'off' != $_SERVER['HTTPS'];
        $offloaderHeader = trim(Mage::getStoreConfig('web/secure/offloader_header'));

        if ((!empty($offloaderHeader) && !empty($_SERVER[$offloaderHeader])) || $standardRule) {
            return true;
        }

        if (Mage::isInstalled()) {
            $secureBaseUrl = Mage::getStoreConfig('web/secure/base_route_url');
            if ( ! $secureBaseUrl) 
            {
                // Here's our hack.  Lie to tell it is secure!
            	return true;
                return false;
            }
            $uri = Zend_Uri::factory($secureBaseUrl);
            $isSecure = ($uri->getScheme() == 'https' )
                && isset($_SERVER['SERVER_PORT'])
                && ($uri->getPort() == $_SERVER['SERVER_PORT']);
            return $isSecure;
        } else {
            $isSecure = isset($_SERVER['SERVER_PORT']) && (443 == $_SERVER['SERVER_PORT']);
            return $isSecure;
        }
    }
}

And, for a little icing on this cake, check out the simple debugging script I whipped up that made it fast and easy to trace back which class / method is calling the current function: Get the calling function or class method

Conversion Rates – What is Your Site’s Job?

Wednesday, June 19th, 2013

We focus on conversion rate optimization with our clients.  We want the site to be effective at it’s job, and the best measure of that is to measure how often a visitor “converts”.

When you are building a site, it is important that you decide – up front – the job of your site.  Part of defining that is deciding what a “conversion” looks like for your site.  After all, in order to improve conversion rates, you need to first measure conversions.  And to measure conversions, you need to be able to describe what a conversion is for your site.

For an e-commerce site, that’s simple: a conversion is when someone purchases.  Maybe there’s a secondary, lower priority conversion of signing up for a newsletter, but the primary conversion is clearly for someone to purchase.

For other sites, it may be less obvious.  Maybe it’s completing a “Contact Us” form, maybe it’s signing up for a survey, maybe it’s something else.

And for other sites, there may be several different conversion objectives.  In a discussion with a non-profit client recently, it became clear that they had many potential conversions.  I suspect when we are done identifying them, we will end up with a list of somewhere between 8 and 12 different conversions.

It’s not until you’ve identified what a conversion means that you can then structure your pages to be effective.  Each page has a job, and that job should be to help move the visitor towards one of your conversions.  See how it would be difficult to design a page without knowing what it’s job is?

Once you’ve defined your conversions, you can then use Google Analytics to track conversions, and to calculate (quickly and easily) the conversion rate for each and every one of your conversions.  Then, using Google Analytic’s tools, you can see where people are bouncing, where they are maybe getting stuck in loops, or where you are losing them in the conversion process.

Get the Calling Function or Class Method

Wednesday, June 19th, 2013

During a recent Magento project, I needed to get the calling class and method from a class that was being called multiple times. Due to the construction of Magento, the simplest way would be to use php’s debug_backtrace function. However, in this case when it was output there were over 82,000 lines of debug information. All I was concerned with was the calling function and class, so trying to wade through all of that information was rather overwhelming.

So, I whipped up this little function that takes care of things quite nicely, even formatting the output in the standard class->method structure:

        $callers=debug_backtrace();
        foreach($callers as $call) {
        	echo "
" . $call['class'] . '->' . $call['function']; }

Integrating LimeSurvey

Monday, June 3rd, 2013

Our first foray into the world of LimeSurvey, we’ve discovered the power and flexibility it offers.  With an easy theme system, and powerful options for creating useful surveys, we like it so far.  And, for a free, Open Source package, it sure packs a lot of power.

Pixuru

Friday, April 19th, 2013

pixuru-screenshot
We just wrapped up the e-commerce site for Pixuru (if you visit, be sure to look for a few Easter eggs we built in for them!) Their site allows you to order a canvas via a very cool interface. Upload your image, then you can crop it, zoom it, and even select the frame color all in an easy to use interface that shows you what your canvas will look like. Place your order, and before you know it you’ll receive a high quality canvas print of your image. Super cool! Developed in OpenCart, with a sister WordPress site for the content management, it looks great and works beautifully.

Textarea Dynamic MaxLength jQuery Plugin

Tuesday, December 11th, 2012

I needed to set the max length of a textarea, but the textarea size was not known beforehand.  That is, some textareas might be large, some might be small, and there was no way to know what size they were.

Since the textareas were part of a situation where the form was absolutely positioned, it was imperative that the user could not enter more information than the textarea size.

Note that modern browsers allow you to resize a textarea – this can be overcome with some simple css:

textarea {
    resize: none;
}

Now that the textarea size is fixed, I just need to limit the amount of text the user can enter, so that it doesn’t overflow the given space.

All of the javascript solutions out there assumed a predefined maxlength for the textarea.  But that’s a bit problematic, too – most fonts aren’t fixed-width, which means that some letters take more space than others.  I wanted to allow completely dynamic, automatic calculation of the space required, and limit the text based on that real information.

So, using some creative programming, I’ve developed a jQuery plugin that can determine the dynamic maximum size of the textarea, and limits the user input to that maximum length.

The code is simple to use. Just include the script file (there’s a link for you below), and then call the following line:

jQuery(function($) {
    $("textarea").textareaMaxLength();
});

And voila! Your textareas magically will limit the amount of text to just the text that fits within the textarea.

How it works

Some of you are going to want to know how it works.  Here you go:

The plugin detects the key-up stroke in a textarea.  When the keyup takes places, it does the following:

  1. It creates a hidden div (off screen) with the same size, shape, and font properties as the textarea.
  2. It adds the text from the textarea to that div
  3. It compares the height of the hidden div (which is allowed to stretch vertically) to that of the textarea.
  4. If the hidden div is taller than the textarea, it trims characters off the end of the input until the height is no longer too tall.
  5. Once the focus has left the textarea (on blur), it removes the div from the DOM.

Using Sessions in WordPress themes and Plugins

Monday, November 12th, 2012

Without hacking core files

WordPress aims to be stateless, so it uses cookies, not sessions.

Which is fine, except for there are things you may need to do that would best be accomplished by tapping into PHP’s sessions.

But, there’s a problem: WordPress iterates over the $_SESSION variable and unsets any session data in wp-settings.php file.

There’s articles out there suggesting editing the wp-settings.php file, but I have a hard and fast rule about not modifying core files for WordPress (or Magento, or Open Cart), because the next time you update your installation (which is important for security), you may wipe your modifications.

There’s a better way.  Why not just hook the session_start AFTER wp-settings.php has run?

Simple as can be with just five lines of code. First, we set up the action to hook into wp-loaded:

add_action('wp_loaded', 'start_my_custom_session');

And then we set our function start_my_custom_session:

function start_my_custom_session() {
	if (!session_id()) {
		session_start();
	}
}

Customizing and Styling Magento Order Confirmation

Monday, July 23rd, 2012

Magento is powerful, but man does it make some things more laborious than they need to be.

Out of the box, Magento’s order confirmation is weak. The client wanted a more robust solution, and after scraping the web for resources and dumping class methods out, I was able to put together a very robust solution.
Read More →