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!

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.

PHP: Convert curly quotes to straight quotes

A client of mine writes, “Take a look at the personal message (from our web form) on the quote below….what is happening with the characters in those fields. I believe there was likely abbreviation for foot: 8’”

Cause: This is typically caused by someone creating string of text in Microsoft Word and then pasting it into a web form.

Solution: Set up the following search and replace parameters in your PHP script:

$search = array("\xe2\x80\x9c", "\xe2\x80\x9d", "\xe2\x80\x98", "\xe2\x80\x99");
$replace = array('"', '"', "'", "'"); 

$formmessage = str_replace($search, $replace, $_POST['message']);

Magento: display and round prices to 3rd decimal point

Second time now I’ve had the client request that set their Magento prices to display and round to the third (3rd) decimal point. This time I will share with you how I performed this change in Magento (ver. 1.3.2.4).

First I FTP to my lib/Zend/Currency.php file and change the following:


protected $_options = array(
 'position'  => self::STANDARD,
 'script'    => null,
 'format'    => null,
 'display'   => self::NO_SYMBOL,
 'precision' => 2,
 'name'      => null,
 'currency'  => null,
 'symbol'    => null
 );

to


protected $_options = array(
 'position'  => self::STANDARD,
 'script'    => null,
 'format'    => null,
 'display'   => self::NO_SYMBOL,
 'precision' => 3,
 'name'      => null,
 'currency'  => null,
 'symbol'    => null
 );

Please note that if you upgrade Magento this will be overwritten and this change will be required again after upgrade!!!

Second, copy app/code/core/Mage/Core/Model/Store.php to app/code/local/Mage/Core/Model/Store.php. By doing this you protect this file from being overwritten during upgrades. Next change the following code in that file from:


public function roundPrice($price)
 {
 return round($price, 2);
 }

to


public function roundPrice($price,$roundTo=3)
 {
 return round($price, $roundTo);
 }

Lastly, I suggest copying app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Price.php to app/code/local/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Price.php. Then you can change the following code in that file from:


public function getEscapedValue($index=null)
 {
 $value = $this->getValue();

 if (!is_numeric($value)) {
 return null;
 }

 return number_format($value, 2, null, '');
 }

to


public function getEscapedValue($index=null)
 {
 $value = $this->getValue();

 if (!is_numeric($value)) {
 return null;
 }

 return number_format($value, 3, null, '');
 }

Clear your Magento Cache and now you have prices that extend to the third (3rd) decimal point both on the front end and in the admin section of Magento!!!

If you have any suggestions on how to improve this post please feel free to drop me a line!

Types of Includes

The include statement is only one of four statements that you can use to include another PHP file in a currently running script. Those four statements are:

  • include
  • require
  • include_once
  • require_once

include and require are almost identical. The only difference between them is what happens when the specified file is unable to be included (that is, if it does not exist, or if the web server doesn’t have permission to read it). With include, a warning is displayed[1] and the script continues to run. With require, an error is displayed and the script stops.

In general, therefore, you should use require whenever the main script is unable to work without the script to be included. I do recommend using include whenever possible, however. Even if the db.inc.php file for your site is unable to be loaded, for example, you might still want to let the script for your front page continue to load. None of the content from the database will display, but the user might be able to use the Contact Us link at the bottom of the page to let you know about the problem!

include_once and require_once work just like include and require, respectively — but if the specified file has already been included at least once for the current page request (using any of the four statements described here), the statement will be ignored. This is handy for include files that perform a task that only needs to be done once , like connecting to the database.

Figure 1 shows include_once in action. In the figure, index.php includes two files: categories.inc.php and top10.inc.php. Both of these files use include_once to include db.inc.php, as they both need a database connection in order to do their job. As shown, PHP will ignore the attempt to include db.inc.php in top10.inc.php because the file was already included in categories.inc.php. As a result, only one database connection is created.

Figure 1. Use include_once to avoid opening a second database connection

include_once2_5

include_once and require_once are also useful for loading function libraries.


[1] In production environments, warnings and errors are usually disabled in php.ini . In such environments, a failed include has no visible effect (aside from the lack of content that would normally have been generated by the include file); a failed require causes the page to stop at the point of failure. When a failed require occurs before any content is sent to the browser, the unlucky user will see nothing but a blank page!

Types of Includes
by Kevin Yank

WordPress: remove category posts from RSS feed

Want to say thanks to jangro.com for having a WordPress function to block a specific WordPress category from appearing in my RSS feed. I just added this to my theme’s function.php file and changed the category number to the number of the category to omit and voila, the RSS feed is now free of the other category.

function myFilter($query) {
if ($query->is_feed) {
$query-&gt;set('cat','-5');
}
return $query;
}
add_filter('pre_get_posts','myFilter');

PHP Array output offset by 1?

Today I was writing some code for another site and I was looping through a DB query and outputting the results and I noticed that the output was one index off. If you ever encounter this problem make sure that you do not have your query string followed by $row = mysql_fetch_array($query) and then have $row = mysql_fetch_array($query) in the WHILE statement for your loop.