Magento: Product Image Upload Problem

My client was having an issue on his Godaddy shared hosting account with his Magento product image uploads. I went through a dozen or more troubleshooting steps to determine the cause of the issue. After careful comparison with a Magento instance just like it hosted on another hosting company server I determined Magento was not at fault! Magento tries to write to a tmp directory on your server when it uploads and if it doesn’t have the privileges to do so will fail on image upload everytime.

My solution on Godaddy shared hosting is to create a php5.ini in the root of your Magento installation. Inside the php5.ini file add the following line:

upload_tmp_dir = var/tmp

Then under your Magento var directory create a directory named “tmp” with 755 permissions.

If this does not resolve your issue please contact me as anyone of the other troubleshooting steps could resolve your issue!

Magento: Get RAW MySQL query information

Ok, so you have a project where the client asks you to bypass the Magento API because it’s so painfully slow…what do you do? Not wanting to start digging through the haystack that is Magento to find the needles of MySQL I began Googling for an answer. What I quickly learned is that Magento’s MySQL queries are abstracted through PDO. Therefore I wouldn’t be able to get what I wanted through digging through source code. At this point I began wondering if there was some sort of application that could act as a proxy and then it dawned on me. I wondered if there was some sort of logging that could be done in MySQL to capture every database transaction.

Surprise surprise, there is a very simple way to enable query logging in MySQL! First off you will need shell access to your Linux box so that you can open up /etc/my.cnf which is MySQL’s configuration file. Once you’ve opened that file insert the following and close/save:


[mysqld]
log=/var/log/mysqld.log

If /var/log/mysqld.log doesn’t exist on your system you will need to create it. You can do so by running:

bash> touch /var/log/mysqld.log

Then set owner and group owner for the mysqld.log file to allow MySQL server to write to the file

bash> chown mysql:mysql /var/log/mysqld.log

At this point you should restart MySQL server. On CentOS you can simply run:

bash> /sbin/service mysqld restart

Now you should be ready to watch real-time MySQL transactions. To see those transactions you can run the following command:

bash> tail -f /var/log/mysqld.log

What I suggest doing at this point is to navigate to a particular process in Magento that you are wanting to get RAW MySQL. Stop tailing the log file and then run:

bash> cat /dev/null > /var/log/mysqld.log

This will empty the contents of the MySQL log file.  Start your tail of the log file again and run the Magento process. You should now have an excellent snap shot of exactly what MySQL is being run for a given process.

xpathbuilder.com: An awesome SEO research tool

I have a wide range of development experience with WordPress and Magento.  But I also love to sink my teeth into custom projects.  So when my colleague Ryan Boots approached me about a unique site concept, I had to pursue it.

As an SEO professional, Ryan was looking for an easy way to study search engine results, preferably within a spreadsheet.  After some research, he discovered Google Doc spreadsheets supported an importXML function which, combined with XPath code, can instantly import Google search results.  The problem was that putting the code together for different queries ate up a lot of time.  In addition, he wanted to scrape results from Bing and Yahoo, which require completely different XPath code.

So he approached me about putting together a site that would generate importXML strings quickly for multiple queries and search engines.  The result: xpathbuilder.com.

A few notes:

  • The tool was 100% custom development from the ground up.  The string fields are built with jQuery.
  • We started with a handful of search engines – Google, Yahoo, Bing and Ask.  We also tossed in Google Suggest – the autocomplete feature you see when entering a search term in Google.   But we built the tool with expansion in mind, so we’ll probably add more search engines down the road, pending user feedback.
  • We put quite a bit of thought into the usability of this tool.  We’re hoping that a reasonably intelligent site visitor will find it fairly straightforward to use.

We’re hoping this will become a useful tool in the SEO community.  It’s already getting some positive attention on Twitter, and Distilled had some nice things to say about it, which is gratifying.

Do me a favor?  Go check it out and let me and Ryan know what you think.  If you see a way it could be improved, we especially want to hear from you.

Magento: Sort Product Options by Value

Today I was presented with a Magento configurable product that has options that were not appearing in order when you clicked the drop down. A quick look with Firebug showed me that the drop down option values would be in proper alpha numeric order if I simply sorted the values of the options. First thing I thought to do is fix it with jQuery. So I created and uploaded a JavaScript file with a jQuery function I found online for sorting the options by value. Here’s the contents of that file:


      jQuery.fn.sortOptionsByValue = function()
      {
      var byValueSortCallback = function(x, y)
      {
      var xVal = jQuery(x).val();
      var yVal = jQuery(y).val();
      return (xVal < yVal) ? -1 : (xVal > yVal) ? 1 : 0;
      };
      return this.sortOptions(byValueSortCallback);
      };




Next thing I did was open up my Magento layout/catalog.xml file and locate the XML block that begins with catalog_product_view. Below that you will find a reference name=”head”. In there I inserted the following action which includes the JavaScript file I created and mentioned above:


<action method="addJs"><script>jQuery/sortselectbox.js</script></action>




In order to specifically fix the option order on this one configurable product I opened up that product in the Magento backend and inserted the following javascript into the product’s short description:


<script type="text/javascript">
jQuery(document).ready(function() {
  jQuery('#attribute965').sortOptionsByValue();
  jQuery('#attribute965').val('').attr({selected: 'selected'});
});
</script>




This script will sort the options by value alpha numerically (a-z0-9) and then it will put the empty option for “Choose an Option” as the first option and sets selected=”selected” on that option. From there you should be good to go. If you have a much more elegant method to resolving this feel free to let me know.

Magento: Administration for Beginners

Magento For BeginnersSomeone asked me today how they can quickly come up to speed on Magento Administration. They said everything seems so overwhelming to manage. I recommend the Magento Beginner’s Guide book shown here in this post.

Amazon has this to say about this book: “Magento is the world’s most evolved e-commerce solution. It runs on the Apache/MySQL/PHP platform. From one installation, you can control multiple storefronts, all sharing customer and product information. Magento’s templates and themes enable you to customize the look and feel of your store, even optimizing it for mobile phones. Extensions enable you to connect Magento to a large number of payment gateways and shipping services. Modular code enables you to upgrade your Magento installation while retaining your customizations. Support is provided free by an active open source community and by subscription to Varien, the company behind Magento.

Magento is one of the most exciting, flexible, and customizable e-commerce systems. It offers you an extensive suite of powerful tools for creating and managing an online store. As your online store grows, you can be sure that this robust e-commerce system can handle your needs. However, getting started with Magento can be difficult without the right guidance.

This book provides that guidance in the form of a step-by-step approach to building a simple, effective online store. The book covers the key features of Magento that will help you get your store up and running. It guides you through installation, configuration, populating your store with products, accepting payments, maintaining relationships with your customers, and fulfilling orders.

When you create an online store with Magento, you usually follow a defined series of steps. This book is arranged to support that process. Each chapter shows you how to get the most from one step.

You will learn to customize the default Magento storefront so that it becomes your store and also about Magento’s directory structure and where some of the elements of a store are customized. This experience will help you if you decide to go beyond this book and install new themes or create your own themes.

As you work your way through each chapter, your store will grow in scope and sophistication. By the time you finish this book, you should have a basic but complete, working online store.”

I hope this book helps you get rolling with your own Magento Administration too!

Mobile Phone: Web page click on phone number to dial

The other day I was working on a site for a friend and I suggested he put his business phone number at the top right hand corner of the website so that his visitors could easily find the number and call his business, thus creating a conversion of sorts. I told him that I frequently look up numbers on other people’s websites using my cell phone and click on the number to dial. He agreed that it sounded like a great idea so I went ahead and placed the number in the page and proceeded to test whether it would allow me to click on it or not. To my surprise it didn’t work. So with a little bit of Googling I found my answer.

Some cell phones require you to format the phone number as a HREF like the one shown below:

<a href="wtai://wp/mc;7132340582">713-234-0582</a>

The iPhone requires you to format the number like this:

<a href="tel:1-713-234-0582">1-713-234-0582</a>

Magento: Dynamic SKU display on Configurable Products

A client of mine requested that on a configurable product when a visitor chooses an option (i.e. a simple product) that I display that simple products SKU automatically on the configurable product page.

First thing I did was look at the Simple Configurable Product module by Matt Dean to see if that was an option I could toggle on. Unfortunately that was not an option. I have a feeling that is not an option because some configurable products may require multiple options to be selected in order to present the correct SKU and the code for that could be potentially daunting. Fortunate for me, my client only has one dropdown per configurable product.

To get things going on this little project I opened up app/design/frontend/base/default/template/catalog/product/view/type/options/configurable.phtml and used that page for writing my code. You may want to choose a different directory that is related you your site’s theme.

On about line 38 I changed it from this:

<select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]"
id="attribute<?php echo $_attribute->getAttributeId() ?>">

to this:

<select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]"
id="attribute<?php echo $_attribute->getAttributeId() ?>"
onchange="return changeSku(this);">

At the very bottom of the configurable.phtml page I wrote the following mix of PHP and Prototype code to solve the Dynamic SKU Display:

<?php
$_product    = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
?>
<?php if ($_product->isSaleable() && count($_attributes)):?>
    <dl>
    <?php foreach($_attributes as $_attribute): ?>
        <dt><label class="required"><em>*</em><?php echo $_attribute->getLabel() ?></label></dt>
        <dd<?php if ($_attribute->decoratedIsLast){?> class="last"<?php }?>>
            <div class="input-box">
                <select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="required-entry super-attribute-select" onchange="return changeSku(this);">
                    <option><?php echo $this->__('Choose an Option...') ?></option>
                  </select>
              </div>
        </dd>
    <?php endforeach; ?>
    </dl>
    <script type="text/javascript">
        var spConfig = new Product.Config(<?php echo $this->getJsonConfig() ?>);
    </script>

<?php endif;?>

<?php
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product);
$col = $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions();

echo '<script type="text/javascript">';

echo '
document.observe("dom:loaded", function() {
  $("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
});
';
echo ' function changeSku(sel){';     	

$itemId = array();
foreach($col as $simple_product){
$itemId[] = array($simple_product->getSelectLabel() => $simple_product->getSku());
} 

//echo "<pre>";
//print_r($itemId);
//echo "</pre>";

foreach($itemId as $val){
 foreach($val as $k => $v){
echo "\n".'if(sel.options[sel.selectedIndex].value == "'.$k.'"){'."\n";
echo '$("sku-container").update("<strong>Product Id: </strong>'.$v.'");'. "\n";
echo '}';
	}
}

echo "\n".'if(sel.options[sel.selectedIndex].value == ""){'."\n";
echo '$("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");'. "\n";
echo '}'; 

echo "}";
echo "\n</script>";
?>

Please note that my client requested that the SKU not be shown for the configurable product itself so you will need to comment out and/or remove those areas of the code shown above that do not display the SKU for the configurable product.

If you have a questions or comments please reply to this post and I would be happy to discuss it with you.

WordPress: WordPress coders have no class

Just read a fantastic article entitled, “WordPress coders have no class“. Make sure to read the comments following the article as it provides a pretty lively debate OOP vs Procedural Code writing in WordPress.

Magento: IE8 adds wrong quantity to cart

Ran into a bug issued by a client where some of his customers reported that IE8 adds the wrong product quantity to the shopping cart.

After doing a little Googling I found that this resolves the issue for IE8 users:

Open the template yourdesign/template/catalog/product/view/addToCart.phtml

and replace
<input … onclick=”productAddToCartForm.submit()” type=”text” />

with

<input … onclick=”productAddToCartForm.submit(); return false;” type=”text” />

Magento: Category Products Sort Position

If you want to manually sort products in your category for any reason, assign numbers to each product, under the Category Products tab of your category, in order of your desired sort order and then go to the Category Display Settings Tab and uncheck the check box under Available Product Listing Sort By and then select “Best Value”.

Your products will now sort correctly using the position numbers you specified.

Next Page »