<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Magento Design and Development</title>
	<atom:link href="http://inchoo.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://inchoo.net</link>
	<description>Magento Design and Magento Development Professionals - Inchoo</description>
	<lastBuildDate>Thu, 02 Feb 2012 13:42:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>What&#8217;s your Super Bowl game plan?</title>
		<link>http://inchoo.net/ecommerce/whats-your-super-bowl-game-plan/</link>
		<comments>http://inchoo.net/ecommerce/whats-your-super-bowl-game-plan/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 10:08:53 +0000</pubDate>
		<dc:creator>Aron Stanic</dc:creator>
				<category><![CDATA[E-Commerce]]></category>
		<category><![CDATA[Online Marketing]]></category>
		<category><![CDATA[advertising]]></category>
		<category><![CDATA[game plan]]></category>
		<category><![CDATA[niche marketing]]></category>
		<category><![CDATA[super bowl]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12378</guid>
		<description><![CDATA[As Giants and Patriots get ready for Super Bowl XLVI in Indianapolis this weekend, so do 100 million viewers in US alone. Many of them will show up not for the biggest single game in US sports, but another thing &#8230;<p><a href="http://inchoo.net/ecommerce/whats-your-super-bowl-game-plan/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>As Giants and Patriots get ready for Super Bowl XLVI in Indianapolis this weekend, so do 100 million viewers in US alone. Many of them will show up not for the biggest single game in US sports, but another thing it represents &#8211; the advertising industry day of the year.</p>
<p>While Super Bowl clearly caters to the masses, are there similar events you can use to reach your specific target audiences? What is the Super Bowl of your niche market and how do you prepare for the game day?</p>
<p><span id="more-12378"></span></p>
<p>On Super Bowl Sunday the biggest brands from auto, retail, insurance, film, food and beverages industries, with an occasional outsider joining this traditional roster, bring out the big guns &#8211; a 30 second slot during the game <a title="Super Bowl 2012 ad price" href="http://adage.com/article/special-report-super-bowl/buying-super-bowl-2012/231122/" target="_blank">will cost them 3.5 million USD</a>, so I imagine they would certainly hope to make the most of it.</p>
<h2>Why Super Bowl?</h2>
<p>It is a single day when big brands can reach tens of millions of viewers at once and drive them online to socialize and create a week- or month-long buzz by sharing and commenting on new creative accomplishments they were presented with.</p>
<p>And since Super Bowl is a family event, there will be many people watching the game who don’t really care who takes home the Lombardi trophy, and most certainly don’t know there’s even a <a title="David Diehl" href="http://en.wikipedia.org/wiki/David_Diehl" target="_blank">left guard of Croatian descent</a> playing for the NY Giants. They will gather to spend some quality family time together, and some will be there for the commercials alone.</p>
<p>For these viewers it will matter more to see if Hyundai creative team beats Kia than how many times Tom Brady gets sacked by the Giants’ defensive line.</p>
<p>This incredible audience reach plays a major role in brand awareness potential of the event, and is the sole reason why the biggest brands come back year after year.</p>
<p>It has even gone so far that it has become a must for certain brands to appear &#8211; not showing up on the ad roster could be perceived as the sign of a weakening brand &#8211; just ask Pepsi how many Super Bowls have they decided to skip recently.</p>
<p>So, what if you had this kind of opportunity for your business &#8211; to reach out to many members of your target audience at once and amaze them? Oh, wait &#8211; you probably do&#8230;</p>
<h2>What is your niche market Super Bowl event and how do you prepare for it?</h2>
<p>Brands that appear in Super Bowl ads mostly prepare stories that relate to the masses, and have huge budgets to work with.</p>
<p>However, every industry and each niche market you’re doing business in inevitably has a &#8220;Super Bowl&#8221; event of its own, it’s only a matter of recognizing it, scaling it and preparing for it adequately.</p>
<p>This can be a specific trade show, an awards ceremony, an arts festival &#8211; you name it &#8211; it’s only important that you define it as <strong>a time and place where you can reach your most precious audience members</strong>. And the beauty of it is that telling your story to your target audience won’t cost you an arm and a leg.</p>
<p>Once you have that figured out &#8211; it’s your turn to prepare a game plan and rise to the occasion.</p>
<p>Of course, brand awareness isn’t something that can happen in a single day, and there’s very little you can do if you don’t have a great product or service to begin with, but let’s imagine you are really good at whatever you do on a daily basis.</p>
<p>In that case, a Super Bowl event for your niche market is where you get the chance to be at the top of your game in front of those that matter most to your business.</p>
<p>Your approach can be to prepare any number of things:</p>
<ul>
<li>a customer-engaging campaign leading up to the main event</li>
<li>a fun, emotional or educational &#8220;hope-to-go-viral&#8221; video</li>
<li>a creative booth team with a stunning visual presentation of your product</li>
<li>a special once-in-a-lifetime offer to your customers</li>
<li>a fundraiser for an important cause</li>
<li>an unexpected celebrity endorsement</li>
</ul>
<p>I’m sure you have more than enough good ideas on how to get your message across and raise awareness, but you should definitely strive to make an impact on your own Super Bowl &#8211; after all, it doesn’t come around that often.</p>
<p>I believe this goes without saying, but just in case &#8211; any action you decide to take should be highly leveraged by a wide array of social media channels at your disposal.</p>
<p>If you manage to shine when the stakes are high, your audience will start expecting your presence on such events, and that will be a sure sign of their good will and appreciation towards your hard work &#8211; once you achieve that, that’s where the fun actually starts as you’ve only just begun.</p>
<p>Imagine a Super Bowl without a commercial for Bud Light or Pepsi, or a <a title="Comic Con" href="http://comic-con.org/" target="_blank">Comic Con</a> without a Marvel booth.</p>
<p>Better yet &#8211; imagine a Black Friday with everyone at Best Buy taking a day off or a Cyber Monday with Amazon offering no special deals.</p>
<p>You should aim to become someone without whom your Super Bowl just doesn’t feel the same.</p>
<p>Now, what are the Super Bowl events in your niche markets? Find them, prepare for them and make sure you’re at the top of your game when it matters most.</p>
<h2>Magento Super Bowl</h2>
<p>We as Magento developers have one such event coming up shortly &#8211; <a title="Magento Imagine 2012" href="http://www.imagineecommerce.com/" target="_blank">Imagine eCommerce</a> Conference in Vegas (April 23-25) &#8211; a showcase of who’s who in Magento and X.commerce.</p>
<p>The organizers aren’t even trying to hide that with this event they are actually looking to become “<em>the Super Bowl of eCommerce</em>” as that’s the tagline they go by &#8211; so, there you go &#8211; if your business is evolving around Magento &#8211; that’s where you should be.</p>
<p>Can this conference live up to its expectations? We certainly hope so, and you’ll get the chance to meet some Inchooers there in April &#8211; Viva Las Vegas!</p>
<p><iframe src="http://www.youtube.com/embed/YjBh1pSoeuI" frameborder="0" width="609" height="342"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/whats-your-super-bowl-game-plan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top 5 shopping applications of 2011 were&#8230;</title>
		<link>http://inchoo.net/ecommerce/top-5-shopping-applications-of-2011-were/</link>
		<comments>http://inchoo.net/ecommerce/top-5-shopping-applications-of-2011-were/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 10:14:21 +0000</pubDate>
		<dc:creator>Toni Anicic</dc:creator>
				<category><![CDATA[E-Commerce]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[group shopping]]></category>
		<category><![CDATA[shopping]]></category>
		<category><![CDATA[shopping cart]]></category>
		<category><![CDATA[trends]]></category>
		<category><![CDATA[web shop]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12359</guid>
		<description><![CDATA[As the Crunchies awards have been handed out, we&#8217;re interested in analyzing the world&#8217;s best shopping start-ups of 2011. In the category of shopping applications, these were the online stores that appeared: Fab (Winner) A New York based start-up founded &#8230;<p><a href="http://inchoo.net/ecommerce/top-5-shopping-applications-of-2011-were/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>As the Crunchies awards have been handed out, we&#8217;re interested in analyzing the world&#8217;s best shopping start-ups of 2011. In the category of shopping applications, these were the online stores that appeared<span id="more-12359"></span>: </p>
<h2>Fab (Winner)</h2>
<p><img src="http://inchoo.net/wp-content/uploads/2012/02/Fab-600x379.png" alt="" title="Fab" width="600" height="379" class="alignnone size-medium wp-image-12360" /></p>
<p>A New York based start-up founded by Jason Goldberg with over $51 million in funding so far with investors like Andreessen Horowitz and Kevin Rose takes this year&#8217;s Crunchie award for the best shopping application. </p>
<p><a href="http://www.fab.com">Fab</a> started as a gay social network, but during 2011 transformed into a website that offers daily design inspirations and sales of up to 70% off retail. Although membership for the Fab.com is free, it is invitation only. </p>
<h2>Warby Parker (Runner Up)</h2>
<p><img src="http://inchoo.net/wp-content/uploads/2012/02/warbyparker-600x385.png" alt="" title="warbyparker" width="600" height="385" class="alignnone size-medium wp-image-12362" /></p>
<p>New York tech scene seems to be on a roll this year, as the runner up is <a href="http://www.warbyparker.com/">Warby Parker</a>. This online store is well known for its home try-on program. Whenever you buy a frame from them, they give another frame to someone in need. Find out more in this video:</p>
<p><iframe width="600" height="335" src="http://www.youtube.com/embed/Pn2kiySyTzY" frameborder="0" allowfullscreen></iframe></p>
<h2>BirchBox</h2>
<p><img src="http://inchoo.net/wp-content/uploads/2012/02/birchbox-600x398.png" alt="" title="birchbox" width="600" height="398" class="alignnone size-medium wp-image-12363" /></p>
<p>Then we have <a href="https://www.birchbox.com/">BirchBox</a>, again a New York based online store start-up which delivers beauty product samples to users on a monthly basis. The website is not just an online store but also a good source of industry related content and news. </p>
<h2>Gilt Groupe</h2>
<p><img src="http://inchoo.net/wp-content/uploads/2012/02/gilt-600x374.png" alt="" title="gilt" width="600" height="374" class="alignnone size-medium wp-image-12364" /></p>
<p><a href="http://www.gilt.com/">Gilt</a> comes from New York as well. It&#8217;s an event driven shopping website. They introduce each designer and brand of the event to their members through videos.</p>
<h2>Lot18</h2>
<p><img src="http://inchoo.net/wp-content/uploads/2012/02/lot18-600x394.png" alt="" title="lot18" width="600" height="394" class="alignnone size-medium wp-image-12365" /></p>
<p>Last but not least in this blog post is <a href="http://www.lot18.com/">Lot18</a>, another New York based invitation only shopping site. Lot18 sells wines and specialty foods.</p>
<p><strong>Which one was your favorite? Any comments on the fact that all 5 are New York based?</strong> </p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/top-5-shopping-applications-of-2011-were/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Android &#8211;  creating simple service</title>
		<link>http://inchoo.net/mobile-development/android-development/android-simple-service/</link>
		<comments>http://inchoo.net/mobile-development/android-development/android-simple-service/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 09:33:29 +0000</pubDate>
		<dc:creator>Darko Goles</dc:creator>
				<category><![CDATA[Android development]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Android service]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[Mobile development]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12219</guid>
		<description><![CDATA[When you look at my posts on this blog, you will, besides few posts about WordPress and Zend find most articles about Symfony2 development. Well, now things are about to change slightly. Depending on next project needs and features, I &#8230;<p><a href="http://inchoo.net/mobile-development/android-development/android-simple-service/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>When you look at my posts on this blog, you will, besides few posts about WordPress and Zend find most articles about Symfony2 development.<br />
Well, now things are about to change slightly.<span id="more-12219"></span><br />
Depending on next project needs and features, I will maybe start to write about Magento platform like other developers here on the blog, but in this transitional times between projects I have to do, let me write about some other platform that I am planning to use and to master knowledge about: Android platform.</p>
<p>This is my first android touches so, please don&#8217;t be too strict in comments. Keep in mind that I will do my best! <img src='http://inchoo.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>So, let&#8217;s start.</p>
<p>What is Android service anyway?</p>
<blockquote><p>&#8220;A Service is an application component representing either an application&#8217;s desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.&#8221;</p></blockquote>
<p>You guessed, that definition  came from <a title="Android service" href="http://developer.android.com/reference/android/app/Service.html" target="_blank">http://developer.android.com/reference/android/app/Service.html</a>.</p>
<p>One more thing about service in Android:<br />
<strong> Service is NOT a separate process</strong><br />
<strong> Service is not a Thread</strong></p>
<p>Please keep this in mind when trying to develop multithreading application …</p>
<p>Let&#8217;s get to work.</p>
<p>Assuming that we have created basic android project, here is our activity:</p>
<pre class="brush: php; title: ; notranslate">

//AndroidservicetutorialActivity.java
package com.inchoo.tutorial;

import android.app.Activity;
import android.os.Bundle;

public class AndroidservicetutorialActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
</pre>
<p>Let&#8217;s create simple service:</p>
<p>Create class called FirstService in your namespace, make it extends Service class and Eclipse will guide you to import necessary namespaces and also to add unimplemented methods (onBind):</p>
<pre class="brush: php; title: ; notranslate">

package com.inchoo.tutorial;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class FirstService extends Service{

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

}
</pre>
<p>Now we will override two more methods: onStart and onDestroy, so our FirstService class looks like this:</p>
<pre class="brush: php; title: ; notranslate">

package com.inchoo.tutorial;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class FirstService extends Service{

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

}
</pre>
<p>Don&#8217;t forget to add this service declaration in your AndroidManifest.xml in order to be set up properly:</p>
<pre class="brush: php; title: ; notranslate">

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
package=&quot;com.inchoo.tutorial&quot;
android:versionCode=&quot;1&quot;
android:versionName=&quot;1.0&quot; &gt;

&lt;uses-sdk android:minSdkVersion=&quot;7&quot; /&gt;

&lt;application
android:icon=&quot;@drawable/ic_launcher&quot;
android:label=&quot;@string/app_name&quot; &gt;
&lt;activity
android:name=&quot;.AndroidservicetutorialActivity&quot;
android:label=&quot;@string/app_name&quot; &gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

&lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;service android:name=&quot;.FirstService&quot; &gt;&lt;/service&gt;
&lt;/application&gt;

&lt;/manifest&gt;
</pre>
<p>Let&#8217;s add log to find out when service is started and destroyed and also we will immediately stop service after starting like someone from Google said somewhere: “Be nice to other applications, start your service, do whatever you need to do and then stop the service after that”&#8230;</p>
<p>Finally out FirstService.java class looks like this:</p>
<pre class="brush: php; title: ; notranslate">

package com.inchoo.tutorial;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class FirstService extends Service{

	private static String TAG = &quot;Inchoo.net tutorial&quot;;

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
		Log.d(TAG, &quot;FirstService started&quot;);
		this.stopSelf();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d(TAG, &quot;FirstService destroyed&quot;);
	}

}
</pre>
<p>And now it&#8217;s time to start it from our Activity (AndroidservicetutorialActivity.java):</p>
<pre class="brush: php; title: ; notranslate">

package com.inchoo.tutorial;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class AndroidservicetutorialActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        startService(new Intent(this, FirstService.class));
    }
}
</pre>
<p>Start your android application and if you look inside LogCat you will find this lines:</p>
<p><a href="http://inchoo.net/wp-content/uploads/2012/01/FirstService_log.jpg"><img class="aligncenter size-full wp-image-12240" title="FirstService_log" src="http://inchoo.net/wp-content/uploads/2012/01/FirstService_log.jpg" alt="" width="600" height="162" /></a></p>
<p>Hope this helps someone <img src='http://inchoo.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Cheers.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/mobile-development/android-development/android-simple-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting selected simple product id in configurable product on client side.</title>
		<link>http://inchoo.net/ecommerce/magento/getting-selected-simple-product-id-in-configurable-product-on-client-side/</link>
		<comments>http://inchoo.net/ecommerce/magento/getting-selected-simple-product-id-in-configurable-product-on-client-side/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 09:23:11 +0000</pubDate>
		<dc:creator>Goran Sambolic</dc:creator>
				<category><![CDATA[Magento]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[catalog]]></category>
		<category><![CDATA[configurable]]></category>
		<category><![CDATA[product]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12355</guid>
		<description><![CDATA[If you need to get id of selected simple product in configurable product on client side you can do it in many different ways. Here is simple function how to achieve that with no code modification, new templates or even &#8230;<p><a href="http://inchoo.net/ecommerce/magento/getting-selected-simple-product-id-in-configurable-product-on-client-side/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>If you need to get id of selected simple product in configurable product on client side you can do it in many different ways.</p>
<p>Here is simple function how to achieve that with no code modification, new templates or even modules.<br />
Just one Javascript file and layout update.</p>
<p><span id="more-12355"></span></p>
<pre class="brush: jscript; title: ; notranslate">
Product.Config.prototype.getIdOfSelectedProduct = function()
{
     var existingProducts = new Object();

     for(var i=this.settings.length-1;i&gt;=0;i--)
     {
         var selected = this.settings[i].options[this.settings[i].selectedIndex];
         if(selected.config)
         {
         	for(var iproducts=0;iproducts&lt;selected.config.products.length;iproducts++)
         	{
         		var usedAsKey = selected.config.products[iproducts]+&quot;&quot;;
         		if(existingProducts[usedAsKey]==undefined)
         		{
         			existingProducts[usedAsKey]=1;
         		}
         		else
         		{
         			existingProducts[usedAsKey]=existingProducts[usedAsKey]+1;
         		}
             }
         }
     }

     for (var keyValue in existingProducts)
     {
     	for ( var keyValueInner in existingProducts)
         {
         	if(Number(existingProducts[keyValueInner])&lt;Number(existingProducts[keyValue]))
         	{
         		delete existingProducts[keyValueInner];
         	}
         }
     }

     var sizeOfExistingProducts=0;
     var currentSimpleProductId = &quot;&quot;;
     for ( var keyValue in existingProducts)
     {
     	currentSimpleProductId = keyValue;
     	sizeOfExistingProducts=sizeOfExistingProducts+1
     }

     if(sizeOfExistingProducts==1)
     {
    	 alert(&quot;Selected product is: &quot;+currentSimpleProductId)
     }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/getting-selected-simple-product-id-in-configurable-product-on-client-side/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding magento attribute with custom input renderer</title>
		<link>http://inchoo.net/ecommerce/magento/adding-magento-attribute-with-custom-input-renderer/</link>
		<comments>http://inchoo.net/ecommerce/magento/adding-magento-attribute-with-custom-input-renderer/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 10:33:31 +0000</pubDate>
		<dc:creator>Domagoj Potkoc</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[frontend input renderer]]></category>
		<category><![CDATA[renderer]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12250</guid>
		<description><![CDATA[This is example which will explain you, how to add new attribute with custom input render. You will be able to modify existing functionality, add javascript, some other option or change default input renderer by your wishes. You probably will &#8230;<p><a href="http://inchoo.net/ecommerce/magento/adding-magento-attribute-with-custom-input-renderer/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>This is example which will explain you, how to add new attribute with custom input render. You will be able to modify existing functionality, add javascript, some other option or change default input renderer by your wishes.<br />
<span id="more-12250"></span><br />
You probably will ask yourself, what is magento input renderer and I will explain. This is Magento php class which is in charge for &#8220;rendering&#8221; html form elements. In magento there are different classes for rendering, you can find them in next folder: <strong>/lib/Varien/Data/Form/Element</strong>. In this folder you will notice next classes for rendering: price, date, image and so on. </p>
<p>Let&#8217;s go with our example.</p>
<p>First of all, you should create magento setup file which will add new product attribute with custom frontend input render, example is below:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
$installer = $this;

$installer-&gt;startSetup();

$installer-&gt;addAttribute(Mage_Catalog_Model_Product::ENTITY, 'example_field', array(
    'group'             =&gt; 'General',
    'type'              =&gt; 'text',
    'backend'           =&gt; '',
    'input_renderer'    =&gt; 'test/catalog_product_helper_form_example',//definition of renderer
    'label'             =&gt; 'Example field',
    'class'             =&gt; '',
    'global'            =&gt; Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE,
    'visible'           =&gt; true,
    'required'          =&gt; false,
    'user_defined'      =&gt; true,
    'searchable'        =&gt; false,
    'filterable'        =&gt; false,
    'comparable'        =&gt; false,
    'visible_on_front'  =&gt; false,
    'unique'            =&gt; false,
    'apply_to'          =&gt; 'simple,configurable,bundle,grouped',
    'is_configurable'   =&gt; false,
));

$installer-&gt;endSetup();
</pre>
<p>You can see that we are adding attribute with method <strong>&#8220;addAttribute&#8221;</strong>, variable <strong>&#8220;$installer&#8221;</strong> is instance of <strong>&#8220;Mage_Catalog_Model_Resource_Setup&#8221;</strong>, and frontend input rendere is defined in array <strong>&#8216;input_renderer&#8217; => &#8216;test/catalog_product_helper_form_example&#8217;</strong></p>
<p>Next step, you have to create your own input renderer. My example of renderer class (<strong>Inchoo_Test_Block_Catalog_Product_Helper_Form_Price</strong>) is below, this is very simple class, only for demonstration purpose.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
class Inchoo_Test_Block_Catalog_Product_Helper_Form_Example extends Varien_Data_Form_Element_Text
{
    public function getAfterElementHtml()
    {
        $html = parent::getAfterElementHtml();
        return $html.&quot;  &lt;script&gt;
        				$('&quot;.$this-&gt;getHtmlId().&quot;').disable();
        				&lt;/script&gt;&quot;;
    }

}
</pre>
<p>In my example you can see that I added javascript code which disable input element, admin user can&#8217;t edit this field.<br />
I hope that is helpful <img src='http://inchoo.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/adding-magento-attribute-with-custom-input-renderer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Backorders Report Magento Extension</title>
		<link>http://inchoo.net/ecommerce/magento/backorders-report-magento-extension/</link>
		<comments>http://inchoo.net/ecommerce/magento/backorders-report-magento-extension/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 07:02:38 +0000</pubDate>
		<dc:creator>Dejan Radic</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Orders]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12167</guid>
		<description><![CDATA[Recently, i had a request to display a list of all backorders. Backorders have to be grouped by Manufacturers, also should be option to filter backorders by manufacturers. In this article, I will present you the extension, which solved the &#8230;<p><a href="http://inchoo.net/ecommerce/magento/backorders-report-magento-extension/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>Recently, i had a request to display a list of all backorders. Backorders have to be grouped by Manufacturers, also should be option to filter backorders by manufacturers.</p>
<p>In this article, I will present you the extension, which solved the above requirement.<br />
<span id="more-12167"></span><br />
Backorder report is placed under Reports menu.</p>
<p>Backorder report contains information about order such as: Order id, Purchased on, Customer, Order total. Backorder report also contains information about the order items such as: Name, Quantity on stock, Quantity in order, Undelivered quantity etc.</p>
<pre class="brush: php; title: ; notranslate">
public function getBackorderItems($orderId)
{
    $backOrderItems = Mage::getModel('sales/order_item')-&gt;getCollection()
        -&gt;addFieldToFilter('order_id', $orderId);

    $backOrderItems-&gt;getSelect()-&gt;join(
        array('sales_product_stock' =&gt; 'cataloginventory_stock_item'),
        'main_table.product_id = sales_product_stock.product_id',
        'qty'
        );

    $conditionsVarchar = array(
        'main_table.product_id = sales_product_manufacturer_varchar.entity_id',
        'sales_product_manufacturer_varchar.attribute_id = 102'
    );

    $backOrderItems-&gt;getSelect()-&gt;joinLeft(
        array('sales_product_manufacturer_varchar' =&gt; 'catalog_product_entity_varchar'),
        implode(' AND ', $conditionsVarchar),
        array('value_varchar' =&gt; 'value')
        );

    $conditionsInt = array(
        'main_table.product_id = sales_product_manufacturer_int.entity_id',
        'sales_product_manufacturer_int.attribute_id = 102'
    );

    $backOrderItems-&gt;getSelect()-&gt;joinLeft(
        array('sales_product_manufacturer_int' =&gt; 'catalog_product_entity_int'),
        implode(' AND ', $conditionsInt),
        array('value_int' =&gt; 'value')
        );

    return $backOrderItems;
}
</pre>
<p>For example:<br />
The customer has made an order that contains:<br />
Product name: “a”; Manufacturer: “x”; Qty: 10 (Qty on stock 20);<br />
Product name: “b”; Manufacturer: “y”; Qty: 10 (Qty on stock 5);<br />
Product name: “c”; Manufacturer: “z”; Qty: 10 (Qty on stock 15);</p>
<p>Backorder will be displayed on three place. In the group of manufacturer “x”, in the group of manufacturer “y” and in the group of manufacturer “z”.</p>
<p><a href="http://inchoo.net/wp-content/uploads/2012/01/backorder_report2.jpg"><img src="http://inchoo.net/wp-content/uploads/2012/01/backorder_report2-600x237.jpg" alt="backorder_report" title="backorder_report" width="600" height="237" class="alignnone size-medium wp-image-12178" /></a></p>
<p>Note: As you can assume, this extension will only work if your store allows backorders. To allow backorders go to: System &gt; Configuration &gt; Catalog &gt; Inventory &gt; Product Stock Options, and set Backorders =&gt; “Allow Qty bellow 0” or “Allow Qty bellow 0 and notify Customer”.</p>
<p>Extension is tested on Magento 1.6.2.0 CE. <a href="http://inchoo.net/wp-content/uploads/2012/01/Inchoo_Backorderreport.zip">Download extension</a>.</p>
<p>Cheers.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/backorders-report-magento-extension/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Symfony2 &#8211;  remember me cookies</title>
		<link>http://inchoo.net/tools-frameworks/symfony/symfony2-remember-me-cookies/</link>
		<comments>http://inchoo.net/tools-frameworks/symfony/symfony2-remember-me-cookies/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 11:58:53 +0000</pubDate>
		<dc:creator>Darko Goles</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[persistent session]]></category>
		<category><![CDATA[Remember me]]></category>
		<category><![CDATA[Session]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12208</guid>
		<description><![CDATA[When developing web services for mobile devices to handle user log-in, I had to make it persistent somehow, so the user should not log-in each time when starts mobile application, but I rather wanted log in to be permanent somehow &#8230;<p><a href="http://inchoo.net/tools-frameworks/symfony/symfony2-remember-me-cookies/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>When developing web services for mobile devices to handle user log-in, I had to make it persistent somehow, so the user should not log-in each time when starts mobile application, but I rather wanted log in to be permanent somehow while user does not log-out manually.<span id="more-12208"></span><br />
Because we used form based authentication with cookies, the cookie with PHPSESSID was always set, but it was not guarantee that user session will not expire sometimes.<br />
I wanted avoid that and that&#8217;s why I implemented native Symfony&#8217;s &#8216;remember me&#8217; functionality inside project.</p>
<p>config.yml</p>
<pre class="brush: php; title: ; notranslate">
#...

framework:
    secret:          %secret%
    charset:         UTF-8
    router:          { resource: &quot;%kernel.root_dir%/config/routing.yml&quot; }
    form:            true
    csrf_protection: true
    #validation:      true
    validation:      { enable_annotations: true }
    templating:      { engines: ['twig'] } #assets_version: SomeVersionScheme
    translator:    { fallback: en }
    session:
        default_locale: %locale%
        lifetime:       31536000
        auto_start:     true
#...
</pre>
<p>Inside security.yml:</p>
<pre class="brush: php; title: ; notranslate">
#...
    firewalls:
        login:
            pattern:  ^/admin/login$
            security: false

        secured_area:
            pattern:    ^/admin.*
            form_login:
                check_path: /admin/login_check
                login_path: /admin/login
                always_use_default_target_path: false
                default_target_path: /admin
            logout:
                path:   /admin/logout
                target: /admin/
            remember_me:
                key:      divine_office_hub_1234567
                lifetime: 31536000
                path: /
                domain: ~

        api_free:
           pattern: ^/v1.*
           form_login:
                check_path: /v1/user/login_check
                login_path: /v1/user/login
                always_use_default_target_path: true
                default_target_path: /v1/user/login_success
                username_parameter: username
                password_parameter: password
                remember_me: true
           logout:
                path:   /v1/user/logout
                target: /v1/user/logout_success
           remember_me:
                key:      divine_office_hub_76543211
                lifetime: 31536000
                path: /
                domain: ~
           anonymous: ~
#..
</pre>
<p>As you can see in security.yml I implemented remember_me on both firewalls, but one thing is missing here.<br />
As you probably know, to make this work, client besides $_POST variables _username and _password when submitting login form, should add either check box or just include $_POST variable named: _remember_me inside POST request.</p>
<p>So, the case was next:<br />
We have already published mobile app v1.0 to App Store and if we want remember_me functionality, we have to include in mobile version 1.1, but if users don&#8217;t update their apps it will not work for them.<br />
Luckily, Symfony2 has also one more functionality for that:</p>
<pre class="brush: php; title: ; notranslate">
always_remember_me: true
</pre>
<p>That way xou do not have to include “_remember_me” POST parameter on client side, but Symfony2 will assume that parameter is present and set to true.</p>
<p>So, the final working security.yml looks like this:</p>
<pre class="brush: php; title: ; notranslate">
#...
     firewalls:
 	#...
        api_free:
           pattern: ^/v1.*
           form_login:
                check_path: /v1/user/login_check
                login_path: /v1/user/login
                always_use_default_target_path: true
                default_target_path: /v1/user/login_success
                username_parameter: username
                password_parameter: password
                remember_me: true
           logout:
                path:   /v1/user/logout
                target: /v1/user/logout_success
           remember_me:
                key:      divine_office_hub_123456
                lifetime: 31536000
                always_remember_me: true
                remember_me_parameter: _remember_me
                path: /
                domain: ~
           anonymous: ~
#...
</pre>
<p>In the moment of log-in, server will besides cookie PHPSESSID also set cookie REMEMBER_ME<br />
and user session even deleted on server (I tried) will be recreated with proper user token data.</p>
<p>Hope this helps to solve some of your problems too.<br />
Cheers <img src='http://inchoo.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/tools-frameworks/symfony/symfony2-remember-me-cookies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Custom Magento Events: Customer First Order</title>
		<link>http://inchoo.net/ecommerce/magento/custom-magento-events-customer-first-order/</link>
		<comments>http://inchoo.net/ecommerce/magento/custom-magento-events-customer-first-order/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 11:09:20 +0000</pubDate>
		<dc:creator>Branko Ajzele</dc:creator>
				<category><![CDATA[Events & Observers]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[custom event]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[observer]]></category>
		<category><![CDATA[order]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12190</guid>
		<description><![CDATA[Often you will stumble upon a case where Magento lacks certain events that you can easily observe. Various business cases can sometimes truly stretch the boundaries of even the best shopping carts like Magento. Luckily, creating or more properly said &#8230;<p><a href="http://inchoo.net/ecommerce/magento/custom-magento-events-customer-first-order/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>Often you will stumble upon a case where Magento lacks certain events that you can easily observe. Various business cases can sometimes truly stretch the boundaries of even the best shopping carts like Magento. Luckily, creating or more properly said dispatching your own event in Magento is pretty straight forward task.<span id="more-12190"></span></p>
<p>Imagine the following business case, where your client, the merchant says: <em><strong>I need to give some reward points to Customer A who invited Customer B. These reward points will be assigned one time only and at the moment when Customer B creates it&#8217;s first order in the system</strong></em>.</p>
<p>Ideal scenario would be if you had the built in Magento event like &#8220;customer_first_order&#8221; or if you need more finer tuning to target the very state of the order, for example &#8220;customer_first_order_that_reached_state_complete&#8221;. Following along with the client requirement above, I will show you how you can easily make additional events with just some basic thinking invested into the whole process.</p>
<p>So where do we start? I will start from the built in &#8220;sales_order_save_after&#8221; event. Logically I need to do something after the order is created. From there I will do the logic that checks if this is customers first order or not. If you are new to Magento and you do a lookup/search on entire Magento installation code you will not find the expression <em>Mage::dispatchEvent(&#8216;sales_order_save_after&#8217;, array(&#8216;object&#8217;=>$this));</em> anywhere.</p>
<p>However you will find the defined values for <em>$_eventPrefix</em> and <em>$_eventObject</em> properties under the <em>Mage_Sales_Model_Order</em> class. Since <em>Mage_Sales_Model_Order</em> somewere down the line inherits from <em>Mage_Core_Model_Abstract</em> you can check it&#8217;s <em>_afterSave()</em> method and easily conclude that <em>sales_order_save_after</em> event comes from the expression <em>Mage::dispatchEvent($this->_eventPrefix.&#8217;_save_after&#8217;, $this->_getEventData());</em>.</p>
<p>The most important thing here for us is to &#8220;catch&#8221; the parameters that are passed to event. Function call <em>$this->_getEventData())</em> basically returns the array of <em>array(&#8216;data_object&#8217; => $this, $this->_eventObject => $this);</em>. As we mentioned previously <em>$_eventObject</em> property has the value of &#8220;<em>order</em>&#8221; set under the <em>Mage_Sales_Model_Order</em> class. What this means that all we need to do in our &#8220;<em>sales_order_save_after</em>&#8221; event observer in order to grab the order passed to the event is an expression like <em>$observer->getEvent()->Order();</em>.</p>
<p>From there on, we will start implementing the code for our specific client requirement. Before we do so, here is the actual code you need in order to have your <em>sales_order_save_after</em> event observer functional.</p>
<p><strong>config.xml</strong> from within your extension:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;config&gt;
//...
	&lt;frontend&gt;
		&lt;events&gt;
            &lt;sales_order_save_after&gt;
                &lt;observers&gt;
                    &lt;customer_first_order&gt;
                        &lt;class&gt;myClassGroup/observer&lt;/class&gt;
                        &lt;method&gt;handleCustomerFirstOrder&lt;/method&gt;
                    &lt;/customer_first_order&gt;
                &lt;/observers&gt;
            &lt;/sales_order_save_after&gt;
		&lt;/events&gt;
	&lt;/frontend&gt;
//...
&lt;/config&gt;
</pre>
<p><strong>Observer.php</strong> from within your extension:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

class MyCompany_MyExtension_Model_Observer
{
	public function handleCustomerFirstOrder($observer)
	{

	}
}
</pre>
<p>Now we need to add the necessary logic that implements client&#8217;s specific requirement, which transforms the above Observer.php into something like this:</p>
<pre class="brush: php; title: ; notranslate">
class MyCompany_MyExtension_Model_Observer
{
    private static $_handleCustomerFirstOrderCounter = 1;

	public function handleCustomerFirstOrder($observer)
	{
        $orders = Mage::getModel('sales/order')
                    -&gt;getCollection()
                    -&gt;addFieldToSelect('increment_id')
                    -&gt;addFieldToFilter('customer_id', array('eq' =&gt; $observer-&gt;getEvent()-&gt;getOrder()-&gt;getCustomerId()));

        //$orders-&gt;getSelect()-&gt;limit(2);

        //if ($orders-&gt;count() == 1) {
        if ($orders-&gt;getSize() == 1) {
            if (self::$_handleCustomerFirstOrderCounter &gt; 1) {
                return $this;
            }

            self::$_handleCustomerFirstOrderCounter++;

			Mage::dispatchEvent('customer_first_order', array('order' =&gt; $observer-&gt;getEvent()-&gt;getOrder()));
		}		

		return $this;
	}
}
</pre>
<p>Several things to explain here. </p>
<p>First the use of <em>$_handleCustomerFirstOrderCounter</em>. I have noticed that during the same page request on order after save action, depending on possible other existing event observers that might do order re-save action, etc. my code within <em>handleCustomerFirstOrder($observer)</em> method can get executed twice or more times, thus I used static variable in a form of counter to specifically allow it to execute only once.</p>
<p>Second, you will notice the limit I put on the colelction, <em>$orders->getSelect()->limit(2);</em>. Reason for this is the logic that says &#8220;check if this is customers first order&#8221;. In order to do that, I need to know if there are other order in the system for the same customer. Since there is no need to fetch/load or even query for all of the order&#8217;s of the same customers I merely said &#8220;tray to grab two orders from this customer&#8221; then with <em>if ($orders->count() == 1)</em> expression I merely said, if total count of grabbed orders is one then this is the first order by this customer. Now you will notice that I commented out the <em>$orders->getSelect()->limit(2);</em> and <em>if ($orders->count() == 1)</em> expressions at the end and went with the use of getSize() method on the collection. Looks nicer and does the same thing. Method getSize() comes from the Varien_Data_Collection_Db class and internally it actually calls the getSelectCountSql() method that specifically executes count on the database, <em>$countSelect->columns(&#8216;COUNT(*)&#8217;);</em> ,and returns just the count value. Thus making it even faster.</p>
<p>And finally, in place of implementing my reward points logic code directly there, I decided to trigger the <em>customer_first_order</em> event for this case. Reason is simply, maybe other developers in the system would like do do something else on this event, so why not dispatch it.</p>
<p>To conclude the client&#8217;s request I simply implement one more observer that handles the <em>customer_first_order</em> event and within that observer I give customer A it&#8217;s earned reward points.</p>
<p>Hopefully this article was helpful for some.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/custom-magento-events-customer-first-order/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What is base64 encoding and how can we benefit from it</title>
		<link>http://inchoo.net/ecommerce/magento/what-is-base64-encoding-and-how-can-we-benefit-from-it/</link>
		<comments>http://inchoo.net/ecommerce/magento/what-is-base64-encoding-and-how-can-we-benefit-from-it/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 11:00:09 +0000</pubDate>
		<dc:creator>Ivan Galambos</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[encode]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=9809</guid>
		<description><![CDATA[What is base64 encoding/decoding and how we can benefit from this representation Base64 schemes represent binary data in an ASCII string format (English alphabet, common punctuation chars, control chars) by translating it into a base-64 representation. This basically means that &#8230;<p><a href="http://inchoo.net/ecommerce/magento/what-is-base64-encoding-and-how-can-we-benefit-from-it/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>What is base64 encoding/decoding and how we can benefit from this representation</p>
<p>Base64 schemes represent binary data in an ASCII string format (English alphabet, common punctuation chars, control chars) by translating it into a base-64 representation.<span id="more-9809"></span> This basically means that all kind of characters (ASCII, UTF8, UTF16&#8230;) with control characters can be mapped for example in English alphabet a-z, A-Z, 0-9 and you would be able to read them all on screen, or even print them out.<br />
First of all, Magento is using base64 encode/decode each time you want to add product in your cart. Magento will redirect you to something like this: <a href="http://loc.magento.com/checkout/cart/add/uenc/aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s/product/93/">&#8220;http://loc.magento.com/checkout/cart/add/uenc/aHR0cDovL2xvYy5tYWdlbn&#8230;93/&#8221;</a> with some POST data (product=93&amp;related_product=&amp;super_attribute[502]=37&amp;qty=2).</p>
<p>These chars &#8220;aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s&#8221; are base64 encoded strings and POST data you can see (HTTP header traffic) with Firebug, LiveHTTPHeaders (addon for FF), Charles proxy,&#8230;</p>
<p>If you don&#8217;t know what does it mean (encoded chars) and how they are generated &#8211; <strong>keep reading</strong>.</p>
<p>Additionally, if you have any useful example where did you use base64 encode/decode, feel free to share your ideas with others.</p>
<p>From wiki: &#8220;Base64 encoding schemes are commonly used when there is a need to encode binary data that needs be stored and transferred over media that are designed to deal with textual data. This is to ensure that the data remains intact without modification during transport&#8221;.</p>
<p>In our case uenc = url encoded = aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s = http://loc.magento.com/asics-men-s-gel-kayano-xii.html.</p>
<p>What do you think why doesn&#8217;t Magento use normal strings in URL instead of base64 which is <strong>around 33%</strong> longer? Hint: you&#8217;ll get this later in the article&#8230;</p>
<p>As you can see we can&#8217;t put char &#8220;/&#8221; in URL if we want to send last visited URL as parameter because we would break attribute/value rule for &#8220;MOD rewrite&#8221; &#8211; GET parameter.<br />
A full example would be: &#8220;http://loc.magento.com/checkout/cart/add/uenc/http://loc.magento.com/asics-men-s-gel-kayano-xii.html/product/93/&#8221; &#8211; sure it&#8217;s wrong.</p>
<p>This is just one example where you can use base64. Also in administration part when you search in grid in some column some value you can see that Magento is using base64 to encode your filter(s). In other words, you don&#8217;t need to worry about which character sets client&#8217;s browser can accept. You are sure that all characters will be transferred over the wire with base64!</p>
<p><strong>So, what do I need to do to convert characters into base64 encoded schema?</strong> Just a little bit of math or you can use any trusted code which will do that for you. You have bunch of &#8220;<strong>online base64 decode/encode</strong>&#8221; scripts on web, just google them. What programming language to use to develop scripts for such of things? Sure, javascript to send &#8220;safe&#8221; data over the wire and you can use PHP to decode them, vice-versa.</p>
<p>Additionally, you can find base64 encoding algorithms in javascript in Magento&#8217;s folder <strong>webroot/js/mage/adminhtml/hash.js</strong> around line 57, function encode_base64( what ) {&#8230;</p>
<p><strong>Another example</strong> could be the following: you have a web service that accept only ASCII chars. You want to save and then transfer user&#8217;s data to some other location (API) but recipient want receive untouched data. Again base64 is for that also. The only downside is that base64 encoding will require <strong>around 33%</strong>  more space than regular strings.</p>
<p>So with base64 you can encode and transfer any sets of binary data through any system and then decode them to original binary data. Cool, right?</p>
<p>Does gmail use base64? Sure!</p>
<p>Instead of &#8220;<strong>reinventing the wheel</strong>&#8221; and showing you how base64 works please take a look this pdf where you can see nice examples and table with ASCII chars. <a title="Base64" href="http://www.aardwulf.com/tutor/base64/base64.pdf">http://www.aardwulf.com/tutor/base64/base64.pdf</a></p>
<p>You can also build your own base64 algorithm for your specific needs!</p>
<p>For the end, did you maybe buy some extension that has weird characters in it and you didn&#8217;t know how to see source code? If your answer is yes, while reading this article did you maybe recognize that the code you have is probably base64 encoded? And can you perhaps see &#8220;eval()&#8221; function in that code?</p>
<p>If the answer is yes, then in my next article I&#8217;ll show you how to do &#8220;<strong>reverse engineering</strong>&#8221; and see your source code for bunch of extensions,&#8230; which you can buy and which are base64 encoded.</p>
<p>Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/what-is-base64-encoding-and-how-can-we-benefit-from-it/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Symfony2 – Guzzle using cookies</title>
		<link>http://inchoo.net/tools-frameworks/symfony2%e2%80%93-guzzle-using-cookies/</link>
		<comments>http://inchoo.net/tools-frameworks/symfony2%e2%80%93-guzzle-using-cookies/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 11:19:07 +0000</pubDate>
		<dc:creator>Darko Goles</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools & Frameworks]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[http client]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12034</guid>
		<description><![CDATA[As seen in previous posts, Guzzle is easy to use php web client library. I explained how it can be used inside controller. But there is one problem more&#8230; If you are using this for example to test log in &#8230;<p><a href="http://inchoo.net/tools-frameworks/symfony2%e2%80%93-guzzle-using-cookies/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>As seen in previous posts, Guzzle is easy to use php web client library. I explained how it can be used inside controller. But there is one problem more&#8230;<br />
If you are using this for example to test log in with cookies based on PHPSESSID, you will get different PHPSESSID for client that runs inside controller then inside your browser from where you making Ajax call.<span id="more-12034"></span></p>
<p>I investigated the way to handle this problem little bit and found workaround that works for me.<br />
So in this article you will see how to use Guzzle with cookies and also some kind of workaround to make this cookies persistent so &#8216;test user&#8217; log in will be persisted.</p>
<p>Inside Guzzle library you have also Cookie plug-in that will help us to handle cookie management in our code.</p>
<p>We will not using ArrayCookieJar but FileCookieJar to be able to make our cookies persistent, so when we fire up browser again and test same thing, cookie will be there where we saved it and we can continue using Guzzle web client with same session.</p>
<pre class="brush: php; title: ; notranslate">
//somecontroller.php

                 $client = new \Guzzle\Service\Client();

                 $filename = $this-&gt;get('kernel')-&gt;getCacheDir() . '/client_ses_' . $sess_id;

                 $cj = new \Guzzle\Http\CookieJar\FileCookieJar($filename);

                 $plugin = new CookiePlugin($cj);

                 $client-&gt;getEventManager()-&gt;attach($plugin);

                 $req = $client-&gt;post($url, $headers, $body);
                 $req-&gt;setOnComplete(function(\Guzzle\Http\Message\RequestInterface $req, \Guzzle\Http\Message\Response $resp, array $default) use($headers, &amp;$ret, &amp;$response) {

                                $resp_content = $resp-&gt;getBody();
                                $resp_headers = $resp-&gt;getRawHeaders();

//... do something with response
                            });

                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYHOST, false);
                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYPEER, false);
                    $req-&gt;setCookie($cookies);

                    $req-&gt;send();

//...
</pre>
<p>And that&#8217;s it. Now cookies are automatically handled and saved inside cache folder, and also automatically retreived next time we make request.</p>
<p>Cheers.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/tools-frameworks/symfony2%e2%80%93-guzzle-using-cookies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Authentic Lacrosse</title>
		<link>http://inchoo.net/portfolio/authentic-lacrosse/</link>
		<comments>http://inchoo.net/portfolio/authentic-lacrosse/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 12:48:04 +0000</pubDate>
		<dc:creator>Toni Anicic</dc:creator>
				<category><![CDATA[Portfolio]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=11781</guid>
		<description><![CDATA[Authentic Lacrosse is a store founded in 2006 by Jonathan and JC, father and son with over 40 years of experience in the lacrosse game.]]></description>
			<content:encoded><![CDATA[<p>Authentic Lacrosse is a store founded in 2006 by Jonathan and JC, father and son with over 40 years of experience in the lacrosse game.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/portfolio/authentic-lacrosse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Symfony2 Guzzle basic usage with callback</title>
		<link>http://inchoo.net/tools-frameworks/symfony2-guzzle-usage/</link>
		<comments>http://inchoo.net/tools-frameworks/symfony2-guzzle-usage/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 13:17:19 +0000</pubDate>
		<dc:creator>Darko Goles</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools & Frameworks]]></category>
		<category><![CDATA[Guzzle]]></category>
		<category><![CDATA[http client]]></category>
		<category><![CDATA[request]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12022</guid>
		<description><![CDATA[In previous posts I wrote about Guzzle php web client. Let me continue to show more about that. Today I am going to make few different request types with Guzzle to https url with self-signed SSL certificate implementing several request &#8230;<p><a href="http://inchoo.net/tools-frameworks/symfony2-guzzle-usage/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>In previous posts I wrote about Guzzle php web client. Let me continue to show more about that.</p>
<p>Today I am going to make few different request types with Guzzle to https url with self-signed SSL certificate implementing several request types.<span id="more-12022"></span></p>
<p>Assuming that you read my previous posts, let&#8217;s jump straight into the code:</p>
<pre class="brush: php; title: ; notranslate">
// somecontroller.php
//...
$client = new \Guzzle\Service\Client();
        try {
            switch ($method) {
                case 'GET':
                    $req = $client-&gt;get($url, $headers);
                    $req-&gt;setOnComplete(function(\Guzzle\Http\Message\RequestInterface $req, \Guzzle\Http\Message\Response $resp, array $default) {

                                $resp_content = $resp-&gt;getBody(true);
                                $resp_headers = $resp-&gt;getRawHeaders();

                                //do something with this
                            });
                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYHOST, false);
                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYPEER, false);
                    $req-&gt;send();
                    break;

                case 'POST':

                    $req = $client-&gt;post($url, $headers, $body);
                    $req-&gt;setOnComplete(function(\Guzzle\Http\Message\RequestInterface $req, \Guzzle\Http\Message\Response $resp, array $default) {

                                $resp_content = $resp-&gt;getBody();
                                $resp_headers = $resp-&gt;getRawHeaders();

                                //do something with this
                            });

                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYHOST, false);
                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYPEER, false);
                    $req-&gt;send();
                    break;

                case 'PUT':
                    $req = $client-&gt;put($url, null, $body);
                    $req-&gt;setOnComplete(function(\Guzzle\Http\Message\RequestInterface $req, \Guzzle\Http\Message\Response $resp, array $default) {
                                $resp_content = $resp-&gt;getBody();
                                $resp_headers = $resp-&gt;getRawHeaders();

                                //do something with this
                            });

                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYHOST, false);
                    $req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYPEER, false);
                    $req-&gt;send();
                    break;

                default:
                    $ret = 'Unknown method';
                    break;
            }
        } catch (\Exception $e) {
            echo 'ERROR' . $e-&gt;getMessage();
        }

//...
</pre>
<p>Hope that helps to show how to make requests with Guzzle web client and get data from inside callback function.</p>
<p>Cheers.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/tools-frameworks/symfony2-guzzle-usage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Symfony2 – Guzzle using with SSL self-signed certificate</title>
		<link>http://inchoo.net/tools-frameworks/symfony2-guzzle-ssl-self-signed-certificate/</link>
		<comments>http://inchoo.net/tools-frameworks/symfony2-guzzle-ssl-self-signed-certificate/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 09:22:14 +0000</pubDate>
		<dc:creator>Darko Goles</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools & Frameworks]]></category>
		<category><![CDATA[certificate]]></category>
		<category><![CDATA[Guzzle]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[symfony2]]></category>
		<category><![CDATA[web client]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12009</guid>
		<description><![CDATA[In previous post I explained to install and setup Guzzle Php web client library with help of GuzzleBundle for Symfony2. Now I am going to explain how to use it with SSL self-signed certificate. It&#8217;s pretty easy to implement, since &#8230;<p><a href="http://inchoo.net/tools-frameworks/symfony2-guzzle-ssl-self-signed-certificate/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>In<a href="http://inchoo.net/tools-frameworks/symfony2-web-client-guzzle-setup/"> previous post</a> I explained to install and setup Guzzle Php web client library with help of GuzzleBundle for Symfony2.</p>
<p>Now I am going to explain how to use it with SSL self-signed certificate.<span id="more-12009"></span></p>
<p>It&#8217;s pretty easy to implement, since Guzzle web client library is built on top of cURL and have options to set manually needed cURL parameters as we need to.</p>
<p>Let&#8217;s make some sample GET request to some &#8216;https://&#8217;</p>
<pre class="brush: php; title: ; notranslate">
//somecontroller.php
//...
$client = new \Guzzle\Service\Client();
$req = $client-&gt;get('https://someurl.com/with_self_signed_certificate');
$response = $req-&gt;send();
print_r($response);exit;
//...
</pre>
<p>It will not be enough yet …<br />
Let&#8217;s add two more lines to make it work:</p>
<pre class="brush: php; title: ; notranslate">
//somecontroller.php
//...
$client = new \Guzzle\Service\Client();
$req = $client-&gt;get('https://someurl.com/with_self_signed_certificate');
$req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYHOST, false);
$req-&gt;getCurlOptions()-&gt;set(CURLOPT_SSL_VERIFYPEER, false);
$response = $req-&gt;send();
print_r($response);exit;
//...
</pre>
<p>And that&#8217;s it.<br />
Of course, you can set any cURL option that is available and about that you can read <a href="http://php.net/manual/en/function.curl-setopt.php">here [http://php.net/manual/en/function.curl-setopt.php]</a></p>
<p>Cheers.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/tools-frameworks/symfony2-guzzle-ssl-self-signed-certificate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2011 infographics</title>
		<link>http://inchoo.net/fun-zone/2011-infographics/</link>
		<comments>http://inchoo.net/fun-zone/2011-infographics/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 13:50:28 +0000</pubDate>
		<dc:creator>Zeljko Prsa</dc:creator>
				<category><![CDATA[Fun & Events]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=12045</guid>
		<description><![CDATA[Dear visitors and clients as the year approaches it&#8217;s very end we&#8217;ve crunched some interesting facts about the highlights of 2011 in inchoo. So called &#8220;Infographics&#8221; awaits to be seen. Please click on the image to see it&#8217;s full potential: &#8230;<p><a href="http://inchoo.net/fun-zone/2011-infographics/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>Dear visitors and clients as the year approaches it&#8217;s very end we&#8217;ve crunched some interesting facts about the highlights of 2011 in inchoo. So called &#8220;Infographics&#8221; awaits to be seen.<span id="more-12045"></span></p>
<p>Please <a href="http://inchoo.net/wp-content/uploads/2011/12/inchoo-2011-infographics.jpg">click on the image</a> to see it&#8217;s full potential:</p>
<div id="attachment_12046" class="wp-caption alignnone" style="width: 207px"><a href="http://inchoo.net/wp-content/uploads/2011/12/inchoo-2011-infographics.jpg"><img class="size-large wp-image-12046" title="inchoo-2011-infographics" src="http://inchoo.net/wp-content/uploads/2011/12/inchoo-2011-infographics-197x1024.jpg" alt="" width="197" height="1024" /></a><p class="wp-caption-text">Inchoo 2011 InfoGraphics</p></div>
<hr />
<blockquote><p>We wish you all a very<br />
healthy, joyful and successful 2012! See you there!</p></blockquote>
<p>Your Inchooers</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/fun-zone/2011-infographics/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Symfony2 web client – Guzzle setup</title>
		<link>http://inchoo.net/tools-frameworks/symfony2-web-client-guzzle-setup/</link>
		<comments>http://inchoo.net/tools-frameworks/symfony2-web-client-guzzle-setup/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 08:55:02 +0000</pubDate>
		<dc:creator>Darko Goles</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools & Frameworks]]></category>
		<category><![CDATA[Guzzle]]></category>
		<category><![CDATA[REST client]]></category>
		<category><![CDATA[setup]]></category>
		<category><![CDATA[symfony2]]></category>
		<category><![CDATA[web client]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=11994</guid>
		<description><![CDATA[Once I made some of REST API features/calls in my project, except unit testing, there was a need for me to build some kind of web client inside my project, so I could have a screen with different options to &#8230;<p><a href="http://inchoo.net/tools-frameworks/symfony2-web-client-guzzle-setup/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>Once I made some of REST API features/calls in my project, except unit testing, there was a need for me to build some kind of web client inside my project, so I could have a screen with different options to custom build my REST calls and analyze results.<span id="more-11994"></span></p>
<p>There was an option to build either JavaScript, .NET or some other kind of web client with pre-configured parameters that I need in my API calls to analyze and test my new REST API. But because I wanted to have this client available to other developers that use different operating systems, I decided to build it in Php with help of AJAX to make parametrized calls to my REST API and display results in screen.</p>
<p>I made some kind of &#8216;investigation&#8217; on Google to find some Php web client library higher level then cURL that I can use in my Symfony2 project easily.</p>
<p>There are several php web client libraries out there. But if you want to use Symfony2 – ready php web client library, I suggest use the <a href="https://github.com/guzzle/guzzle">Guzzle </a>because of many available options for fine tuning your php web client.<br />
Also except Guzzle php library, there is a Symfony2 bundle for integration with your Symfony2 project available: <a href="http://knpbundles.com/ddeboer/GuzzleBundle">GuzzleBundle</a></p>
<p>Let&#8217;s setup our project for Guzzle to be used:</p>
<p>First go to links above and download Guzzle library from github, unpack it inside &#8216;vendor&#8217; folder like this:</p>
<p><a href="http://inchoo.net/wp-content/uploads/2011/12/guzzle_lib_vendors.jpg"><img class="aligncenter size-full wp-image-11999" title="guzzle_lib_vendors" src="http://inchoo.net/wp-content/uploads/2011/12/guzzle_lib_vendors.jpg" alt="guzzle_lib_vendors" width="440" height="396" /></a></p>
<p>Then download Guzzle bundle for Symfony2 from above link and place it in vendor like this:</p>
<p><a href="http://inchoo.net/wp-content/uploads/2011/12/guzzle_bundle_vendors.jpg"><img class="aligncenter size-full wp-image-12003" title="guzzle_bundle_vendors" src="http://inchoo.net/wp-content/uploads/2011/12/guzzle_bundle_vendors.jpg" alt="guzzle_bundle_vendors" width="434" height="227" /></a></p>
<p>Don&#8217;t forget to add it inside autoload.php and AppKernel.php properly in order to make it work:</p>
<pre class="brush: php; title: ; notranslate">
//autoload.php
//...

$loader-&gt;registerNamespaces(array(
//...
    'Guzzle'           =&gt; __DIR__.'/../vendor/guzzle/src',
    'Ddeboer'          =&gt; __DIR__.'/../vendor/bundles',
//...
//...
</pre>
<pre class="brush: php; title: ; notranslate">
// AppKernel.php
//...
    public function registerBundles()
    {
        $bundles = array(
//...
            new Ddeboer\GuzzleBundle\DdeboerGuzzleBundle(),
//...
</pre>
<p>And now is time to use it inside your controller:</p>
<pre class="brush: php; title: ; notranslate">
// somecontroller.php

$client = new \Guzzle\Service\Client();
$req = $client-&gt;get('http://someurl.com');
$response = $req-&gt;send();

print_r($response);
//...
</pre>
<p>And that&#8217;s it for now. In some of next articles, I will explain how to set some cUrl parameters to use client with SSL unsigned certificate, how to make GET, POST calls, use callback for retreiving results and, of course how to use it with cookie support…</p>
<p>Cheers for now <img src='http://inchoo.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/tools-frameworks/symfony2-web-client-guzzle-setup/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multiple configurable products with options on one page in Magento</title>
		<link>http://inchoo.net/ecommerce/magento/display-multiple-configurable-products-with-options-on-one-page-in-magento/</link>
		<comments>http://inchoo.net/ecommerce/magento/display-multiple-configurable-products-with-options-on-one-page-in-magento/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 11:36:51 +0000</pubDate>
		<dc:creator>Goran Sambolic</dc:creator>
				<category><![CDATA[Frontend]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[configurable]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[options]]></category>
		<category><![CDATA[product]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=11973</guid>
		<description><![CDATA[Displaying configurable products with options on one page can be problem because Javascript in Magento is setup to work only with one configurable product. You can write your own Javascript or U can reuse Magento code. To accomplish that we &#8230;<p><a href="http://inchoo.net/ecommerce/magento/display-multiple-configurable-products-with-options-on-one-page-in-magento/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>Displaying configurable products with options on one page can be problem because Javascript in Magento is setup to work only with one configurable product.<br />
You can write your own Javascript or U can reuse Magento code.<br />
<span id="more-11973"></span></p>
<p>To accomplish that we need to modify product Javascript (js/varien/product.js) and configurable (catalog\product\view\type\options\configurable.phtml) select element template.</p>
<p>In configurable.phtml call our new JS class (we will create that class later in article) and add product id to configurable select element class.</p>
<p>configurable.phtml:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
$_product    = $this-&gt;getProduct();
$_attributes = Mage::helper('core')-&gt;decorateArray($this-&gt;getAllowAttributes());
?&gt;
&lt;?php if ($_product-&gt;isSaleable() &amp;&amp; count($_attributes)):?&gt;
    &lt;dl&gt;
    &lt;?php foreach($_attributes as $_attribute): ?&gt;
        &lt;dt&gt;&lt;label class=&quot;required&quot;&gt;&lt;em&gt;*&lt;/em&gt;&lt;?php echo $_attribute-&gt;getLabel() ?&gt;&lt;/label&gt;&lt;/dt&gt;
        &lt;dd&lt;?php if ($_attribute-&gt;decoratedIsLast){?&gt; class=&quot;last&quot;&lt;?php }?&gt;&gt;
            &lt;div class=&quot;input-box&quot;&gt;
                &lt;select name=&quot;super_attribute[&lt;?php echo $_attribute-&gt;getAttributeId() ?&gt;]&quot; id=&quot;attribute&lt;?php echo $_attribute-&gt;getAttributeId() ?&gt;&quot; class=&quot;required-entry super-attribute-select_&lt;?php echo $_product-&gt;getId()?&gt;  &quot;&gt;
                    &lt;option&gt;&lt;?php echo $this-&gt;__('Choose an Option...') ?&gt;&lt;/option&gt;
                  &lt;/select&gt;
              &lt;/div&gt;
        &lt;/dd&gt;
    &lt;?php endforeach; ?&gt;
    &lt;/dl&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
        var spConfig_&lt;?php echo $_product-&gt;getId()?&gt; = new Inchoo_Product.Config(&lt;?php echo $this-&gt;getJsonConfig() ?&gt;);
    &lt;/script&gt;
&lt;?php endif;?&gt;
</pre>
<p>Then create Javascript file and Javascript class.<br />
Copy javascript code from js/varien/product.js for configurable product (use own namespace to avoid JS collision with Magento).</p>
<pre class="brush: jscript; title: ; notranslate">
if(typeof Inchoo_Product =='undefined') {
    var Inchoo_Product  = {};
}

/**************************** CONFIGURABLE PRODUCT **************************/
Inchoo_Product.Config = Class.create();
Inchoo_Product.Config.prototype = {
</pre>
<p>Because we change selector name we have to modify our JS code to work with new selector.</p>
<pre class="brush: jscript; title: ; notranslate">
var settingsClassToSelect = '.super-attribute-select_'+this.config.productId;
this.settings   = $$(settingsClassToSelect);
</pre>
<p>Magento code is stripping &#8220;attribute&#8221; string from class of configurable select element but we also have to strip product id (we added product id to class name in configurable.phtml).</p>
<pre class="brush: jscript; title: ; notranslate">
        // fill state
        this.settings.each(function(element){
            var attributeId = element.id.replace(/[a-z]*/, '');
            attributeId = attributeId.replace(/_.*/, '');

            ........

        fillSelect: function(element){
        var attributeId = element.id.replace(/[a-z]*/, '');
        attributeId = attributeId.replace(/_.*/, '');
</pre>
<p>Now we can have multiple configurable products with options on same page.</p>
<p><strong>Update, as requested complete JS file </strong></p>
<p>product.js:</p>
<pre class="brush: jscript; title: ; notranslate">

if(typeof Inchoo_Product =='undefined') {
    var Inchoo_Product  = {};
}

/**************************** CONFIGURABLE PRODUCT **************************/
Inchoo_Product.Config = Class.create();
Inchoo_Product.Config.prototype = {
    initialize: function(config){
        this.config     = config;
        this.taxConfig  = this.config.taxConfig;
        var settingsClassToSelect = '.super-attribute-select_'+this.config.productId;
        this.settings   = $$(settingsClassToSelect);
        this.state      = new Hash();
        this.priceTemplate = new Template(this.config.template);
        this.prices     = config.prices;

        this.settings.each(function(element){
            Event.observe(element, 'change', this.configure.bind(this))
        }.bind(this));

        // fill state
        this.settings.each(function(element){
            var attributeId = element.id.replace(/[a-z]*/, '');
            attributeId = attributeId.replace(/_.*/, '');
            if(attributeId &amp;&amp; this.config.attributes[attributeId]) {
                element.config = this.config.attributes[attributeId];
                element.attributeId = attributeId;
                this.state[attributeId] = false;
            }
        }.bind(this))

        // Init settings dropdown
        var childSettings = [];
        for(var i=this.settings.length-1;i&gt;=0;i--){
            var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
            var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
            if(i==0){
                this.fillSelect(this.settings[i])
            }
            else {
                this.settings[i].disabled=true;
            }
            $(this.settings[i]).childSettings = childSettings.clone();
            $(this.settings[i]).prevSetting   = prevSetting;
            $(this.settings[i]).nextSetting   = nextSetting;
            childSettings.push(this.settings[i]);
        }

        // Set default values - from config and overwrite them by url values
        if (config.defaultValues) {
            this.values = config.defaultValues;
        }

        var separatorIndex = window.location.href.indexOf('#');
        if (separatorIndex != -1) {
            var paramsStr = window.location.href.substr(separatorIndex+1);
            var urlValues = paramsStr.toQueryParams();
            if (!this.values) {
                this.values = {};
            }
            for (var i in urlValues) {
                this.values[i] = urlValues[i];
            }
        }

        this.configureForValues();
        document.observe(&quot;dom:loaded&quot;, this.configureForValues.bind(this));
    },

    configureForValues: function () {
        if (this.values) {
            this.settings.each(function(element){
                var attributeId = element.attributeId;
                element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
                this.configureElement(element);
            }.bind(this));
        }
    },

    configure: function(event){
        var element = Event.element(event);
        this.configureElement(element);
    },

    configureElement : function(element) {
        this.reloadOptionLabels(element);
        if(element.value){
            this.state[element.config.id] = element.value;
            if(element.nextSetting){
                element.nextSetting.disabled = false;
                this.fillSelect(element.nextSetting);
                this.resetChildren(element.nextSetting);
            }
        }
        else {
            this.resetChildren(element);
        }
        //this.reloadPrice();
//      Calculator.updatePrice();
    },

    reloadOptionLabels: function(element){
        var selectedPrice;
        if(element.options[element.selectedIndex].config){
            selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
        }
        else{
            selectedPrice = 0;
        }
        for(var i=0;i&lt;element.options.length;i++){
            if(element.options[i].config){
                element.options[i].text = this.getOptionLabel(element.options[i].config, element.options[i].config.price-selectedPrice);
            }
        }
    },

    resetChildren : function(element){
        if(element.childSettings) {
            for(var i=0;i&lt;element.childSettings.length;i++){
                element.childSettings[i].selectedIndex = 0;
                element.childSettings[i].disabled = true;
                if(element.config){
                    this.state[element.config.id] = false;
                }
            }
        }
    },

    fillSelect: function(element){
        var attributeId = element.id.replace(/[a-z]*/, '');
        attributeId = attributeId.replace(/_.*/, '');
        var options = this.getAttributeOptions(attributeId);
        this.clearSelect(element);
        element.options[0] = new Option(this.config.chooseText, '');

        var prevConfig = false;
        if(element.prevSetting){
            prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
        }

        if(options) {
            var index = 1;
            for(var i=0;i&lt;options.length;i++){
                var allowedProducts = [];
                if(prevConfig) {
                    for(var j=0;j&lt;options[i].products.length;j++){
                        if(prevConfig.config.allowedProducts
                            &amp;&amp; prevConfig.config.allowedProducts.indexOf(options[i].products[j])&gt;-1){
                            allowedProducts.push(options[i].products[j]);
                        }
                    }
                } else {
                    allowedProducts = options[i].products.clone();
                }

                if(allowedProducts.size()&gt;0){
                    options[i].allowedProducts = allowedProducts;
                    element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
                    element.options[index].config = options[i];
                    index++;
                }
            }
        }
    },

    getOptionLabel: function(option, price){
        var price = parseFloat(price);
        if (this.taxConfig.includeTax) {
            var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
            var excl = price - tax;
            var incl = excl*(1+(this.taxConfig.currentTax/100));
        } else {
            var tax = price * (this.taxConfig.currentTax / 100);
            var excl = price;
            var incl = excl + tax;
        }

        if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
            price = incl;
        } else {
            price = excl;
        }

        var str = option.label;
        if(price){
            if (this.taxConfig.showBothPrices) {
                str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
            } else {
                str+= ' ' + this.formatPrice(price, true);
            }
        }
        return str;
    },

    formatPrice: function(price, showSign){
        var str = '';
        price = parseFloat(price);
        if(showSign){
            if(price&lt;0){
                str+= '-';
                price = -price;
            }
            else{
                str+= '+';
            }
        }

        var roundedPrice = (Math.round(price*100)/100).toString();

        if (this.prices &amp;&amp; this.prices[roundedPrice]) {
            str+= this.prices[roundedPrice];
        }
        else {
            str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
        }
        return str;
    },

    clearSelect: function(element){
        for(var i=element.options.length-1;i&gt;=0;i--){
            element.remove(i);
        }
    },

    getAttributeOptions: function(attributeId){
        if(this.config.attributes[attributeId]){
            return this.config.attributes[attributeId].options;
        }
    },

    reloadPrice: function(){
        var price    = 0;
        var oldPrice = 0;
        for(var i=this.settings.length-1;i&gt;=0;i--){
            var selected = this.settings[i].options[this.settings[i].selectedIndex];
            if(selected.config){
                price    += parseFloat(selected.config.price);
                oldPrice += parseFloat(selected.config.oldPrice);
            }
        }

        optionsPrice.changePrice('config', {'price': price, 'oldPrice': oldPrice});
        optionsPrice.reload();

        return price;

        if($('product-price-'+this.config.productId)){
            $('product-price-'+this.config.productId).innerHTML = price;
        }
        this.reloadOldPrice();
    },

    reloadOldPrice: function(){
        if ($('old-price-'+this.config.productId)) {

            var price = parseFloat(this.config.oldPrice);
            for(var i=this.settings.length-1;i&gt;=0;i--){
                var selected = this.settings[i].options[this.settings[i].selectedIndex];
                if(selected.config){
                    price+= parseFloat(selected.config.price);
                }
            }
            if (price &lt; 0)
                price = 0;
            price = this.formatPrice(price);

            if($('old-price-'+this.config.productId)){
                $('old-price-'+this.config.productId).innerHTML = price;
            }

        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/display-multiple-configurable-products-with-options-on-one-page-in-magento/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Snowflakes Magento Extension</title>
		<link>http://inchoo.net/ecommerce/magento/snowflakes-magento-extension/</link>
		<comments>http://inchoo.net/ecommerce/magento/snowflakes-magento-extension/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 10:08:22 +0000</pubDate>
		<dc:creator>Davor Budimcic</dc:creator>
				<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[Fun & Events]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[christmas]]></category>
		<category><![CDATA[extension]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=11925</guid>
		<description><![CDATA[Happy holidays everyone. As you could notice, we have a new holiday header, new holiday wallpapers, and today we have something new. Creative sparks did their magic making us proud to present you Inchoo Snowflakes Magento Extension. Demo Update: As &#8230;<p><a href="http://inchoo.net/ecommerce/magento/snowflakes-magento-extension/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>Happy holidays everyone. As you could notice, we have a new holiday header, new <a href="/fun-zone/inchooers-wallpaper-christmas-edition/" title="Inchoo Christmas Wallpaper">holiday wallpapers</a>, and today we have something new. Creative sparks did their magic making us proud to present you <strong>Inchoo Snowflakes Magento Extension</strong>.<br />
<span id="more-11925"></span></p>
<h2>Demo</h2>
<p><a href="http://inchoo.net/wp-content/uploads/2011/12/InchooSnowflakes/snow.html" target="_blank"><img src="http://inchoo.net/wp-content/uploads/2011/12/ISdemo.png" alt="" title="ISdemo" width="581" height="258" class="alignnone size-full wp-image-11966" /></a></p>
<p><strong>Update:</strong> As you requested, we added a few &#8220;live&#8221; variations that you can archieve with this extension to <a href="http://inchoo.net/wp-content/uploads/2011/12/InchooSnowflakes/snow.html" target="_blank">Snowflakes Demo</a>.</p>
<h2>Screenshots</h2>
<p style="text-align: center;">&#8220;Look Ma&#8217;, it&#8217;s snowing on frontend!&#8221;<br />
<img class="alignnone size-medium wp-image-11936" style="background: #fff; padding: 4px; border: 1px solid #C3D16F;" title="front1" src="http://inchoo.net/wp-content/uploads/2011/12/front1-600x300.jpg" alt="" width="600" height="300" /></p>
<p style="text-align: center;">If you feel cold from all that snow, add some stars instead&#8230;<br />
<img class="alignnone size-medium wp-image-11937" style="background: #fff; padding: 4px; border: 1px solid #C3D16F;" title="front2" src="http://inchoo.net/wp-content/uploads/2011/12/front2-600x300.jpg" alt="" width="600" height="300" /></p>
<p style="text-align: center;">&#8230;or write your own message to customers<br />
<img class="alignnone size-medium wp-image-11938" style="background: #fff; padding: 4px; border: 1px solid #C3D16F;" title="front3" src="http://inchoo.net/wp-content/uploads/2011/12/front3-600x300.jpg" alt="" width="600" height="300" /></p>
<p style="text-align: center;">Configuration options are located in<br />
System -&gt; Configuration -&gt; Inchoo Snowflakes Config<br />
<img class="alignnone size-medium wp-image-11935" style="background: #fff; padding: 4px; border: 1px solid #C3D16F;" title="admin" src="http://inchoo.net/wp-content/uploads/2011/12/admin-600x300.jpg" alt="" width="600" height="300" /></p>
<h2>Download</h2>
<p>Just download <a href="http://inchoo.net/wp-content/uploads/2011/12/InchooSnowflakes.zip">InchooSnowflakes.zip</a>, extract files following directory structure, reload cache and let it snow! <img src='http://inchoo.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/snowflakes-magento-extension/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Inchooers Wallpaper &#8211; Christmas Edition</title>
		<link>http://inchoo.net/fun-zone/inchooers-wallpaper-christmas-edition/</link>
		<comments>http://inchoo.net/fun-zone/inchooers-wallpaper-christmas-edition/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 15:00:57 +0000</pubDate>
		<dc:creator>Hrvoje Jurisic</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Fun & Events]]></category>
		<category><![CDATA[inchooers]]></category>
		<category><![CDATA[magento wallpaper]]></category>
		<category><![CDATA[wallpaper]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=11917</guid>
		<description><![CDATA[Christmas is near, and the Inchooers are already in Holidays mood. Feel free to join us. Download the wallpaper and enjoy Holidays even on your desktops Christmas Day 1920&#215;1080 &#124; 1680&#215;1050]]></description>
			<content:encoded><![CDATA[<p>Christmas is near, and the Inchooers are already in Holidays mood. Feel free to join us. Download the wallpaper and enjoy Holidays even on your desktops <img src='http://inchoo.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-11917"></span></p>
<p style="text-align: center;">
<img src="http://inchoo.net/wp-content/uploads/2011/12/christmas_night_thumb.jpg" alt="Christmas night wallpaper" style="background: #fff; padding: 4px; border: 1px solid #C3D16F; title="christmas_night_thumb" width="350" height="221" class="alignnone size-full wp-image-11920" /></p>
<p style="text-align: center;"><strong>Christmas Night</strong><br />
<a href="http://inchoo.net/wp-content/uploads/2011/12/christmas_night_1920x1080.jpg#" target="_blank">1920&#215;1080</a> | <a href="http://inchoo.net/wp-content/uploads/2011/12/christmas_night_1680x1050.jpg#" target="_blank">1680&#215;1050</a></p>
<p style="text-align: center;">
<img src="http://inchoo.net/wp-content/uploads/2011/12/christmas_wallpaper_thumb.jpg" style="background: #fff; padding: 4px; border: 1px solid #C3D16F; alt="Christmas wallpaper" title="christmas_wallpaper_thumb" width="350" height="221" class="alignnone size-full wp-image-11923" /></p>
<p style="text-align: center;"><strong>Christmas Day</strong><br />
<a href="http://inchoo.net/wp-content/uploads/2011/12/christmas_wallpaper.jpg#" target="_blank">1920&#215;1080</a> | <a href="http://inchoo.net/wp-content/uploads/2011/12/christmas_wallpaper_1680x1050.jpg#" target="_blank">1680&#215;1050</a></p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/fun-zone/inchooers-wallpaper-christmas-edition/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Facebook Connect Magento Extension</title>
		<link>http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/</link>
		<comments>http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 21:56:43 +0000</pubDate>
		<dc:creator>Ivan Weiler</dc:creator>
				<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[facebook]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=4133</guid>
		<description><![CDATA[We&#8217;re proud to present free Facebook Connect Magento extension which enables customers fast and easy registration and login with their Facebook identity. And it&#8217;s just been updated! Important Facebook updated it&#8217;s authentication mechanism but so did we, so please update &#8230;<p><a href="http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re proud to present <strong>free Facebook Connect Magento extension</strong> which enables customers fast and easy registration and login with their Facebook identity. And it&#8217;s <strong>just been updated</strong>!</p>
<p><span id="more-4133"></span></p>
<h2>Important</h2>
<p>Facebook updated it&#8217;s authentication mechanism but so did we, so please update your extension to the newest version since older versions won&#8217;t work anymore.<br />
Also, if you&#8217;re getting &#8220;An error occurred. Please try again later.&#8221; message in connect popup, you need to get <strong>new &#8220;App ID/API Key&#8221;</strong> from Facebook and enter it into Magento. Check your Application Secret along the way.</p>
<h2>Download</h2>
<p>Download <a href="http://inchoo.net/wp-content/uploads/2011/05/Inchoo_Facebook-0.9.9.zip" target="_blank"><strong>Inchoo_Facebook-0.9.9.zip</strong></a>, extract files to appropriate place following directory structure and reload cache.<br />
Latest pre-relase versions can always be downloaded on <a href="https://github.com/ivanweiler/Inchoo_Facebook" target="_blank">my github project page</a>.</p>
<h2>About</h2>
<p>Facebook Connect Magento extension enables customers one click registration and login with their Facebook identity. It automatically registers new users and logs in existing ones.</p>
<p>Current extension is compatible with latest Magento CE 1.6, but also with older 1.5, 1.4 and 1.3.2.x versions. It&#8217;s using brand new Facebook thingies like open graph protocol and open source JavaScript SDK.</p>
<p>If you&#8217;re interested to see additional languages in future releases, <a href="http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/comment-page-3/#comment-20942">help us translate it by following instructions</a>.</p>
<h2>Facebook App</h2>
<p>For Facebook Connect to work you need to <a href="http://www.facebook.com/developers/createapp.php" target="_blank">Setup Application on Facebook</a> and obtain its App ID/API Key and Application Secret.</p>
<p>Use your store name as application name and read and accept terms of service. On second screen set App Domain and Site URL(under checked Web Site tab), both to the store domain where you plan to implement Facebook Connect. Save Changes. Other Connect settings are optional, but you might want to add store logo for example.</p>

<a href='http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/attachment/facebook-setup-1/' title='facebook-setup-1'><img width="300" height="182" src="http://inchoo.net/wp-content/uploads/2011/05/facebook-setup-1-300x182.png" class="attachment-thumbnail" alt="facebook-setup-1" title="facebook-setup-1" /></a>
<a href='http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/attachment/facebook-setup-2/' title='facebook-setup-2'><img width="300" height="199" src="http://inchoo.net/wp-content/uploads/2011/05/facebook-setup-2-300x199.png" class="attachment-thumbnail" alt="facebook-setup-2" title="facebook-setup-2" /></a>
<a href='http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/attachment/facebook-setup-3/' title='facebook-setup-3'><img width="300" height="201" src="http://inchoo.net/wp-content/uploads/2011/05/facebook-setup-3-300x201.png" class="attachment-thumbnail" alt="facebook-setup-3" title="facebook-setup-3" /></a>
<a href='http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/attachment/facebook-setup-4/' title='facebook-setup-4'><img width="300" height="201" src="http://inchoo.net/wp-content/uploads/2011/05/facebook-setup-4-300x201.png" class="attachment-thumbnail" alt="facebook-setup-4" title="facebook-setup-4" /></a>

<h2>Magento Setup</h2>
<p>Once you obtain two keys navigate to Magento Administration, copy/paste them to appropriate fields under Configuration-&gt;Customer-&gt;Facebook Connect, set Enabled to Yes and you&#8217;re good to go. If you&#8217;re updating from previous releases, you also need to Enable it to work.</p>
<p>Default template files (frontend/default/default/template/facebook/*) and layout (layout/facebook.xml) makes Facebook Connect work out of the box with default theme, but we tried to make customizations as easy as possible so all you need to do is add button or link with &#8220;facebook-connect&#8221; rel attribute set anywhere in the theme, static block or cms page, for example:</p>
<p>&lt;button rel=&#8221;facebook-connect&#8221; class=&#8221;form-button&#8221; type=&#8221;submit&#8221;&gt;&lt;span&gt;Connect with Facebook&lt;/span&gt;&lt;/button&gt;<br />
&lt;a rel=&#8221;facebook-connect&#8221;&gt;Connect with Facebook&lt;/a&gt;</p>
<h2>Latest Changes</h2>
<p>v.0.9.9<br />
- Client and javascript compatible with new Facebook authentication changes.<br />
- Event.fire changed to document object to avoid javascript conflicts.<br />
- Asking for user_birthday permission from now on.<br />
- Norwegian translation added thanks to Magnus Alexander.</p>
<p>v.0.9.8<br />
- Version fix, licenses added, connect release.</p>
<p>v.0.9.7<br />
- Estonian, Swedish, Czech, Turkish and Korean translations added thanks to Sir Mull, Andreas Karlsson, Pavel Hrdlicka, ea and COBAY.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/ecommerce/magento/facebook-connect-magento-extension/feed/</wfw:commentRss>
		<slash:comments>403</slash:comments>
		</item>
		<item>
		<title>Symfony2 DBAL QueryBuilder</title>
		<link>http://inchoo.net/tools-frameworks/symfony2-dbal-querybuilder/</link>
		<comments>http://inchoo.net/tools-frameworks/symfony2-dbal-querybuilder/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 10:26:24 +0000</pubDate>
		<dc:creator>Darko Goles</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools & Frameworks]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[DBAL]]></category>
		<category><![CDATA[Doctrine2]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[querybuilder]]></category>
		<category><![CDATA[statements]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://inchoo.net/?p=11712</guid>
		<description><![CDATA[Sometimes, when we have some relatively complex queries to write, it&#8217;s so long and inflexible statement that it&#8217;s pretty hard to understand few days after we wrote it, or we have to add some dynamic parameters or conditions that writing &#8230;<p><a href="http://inchoo.net/tools-frameworks/symfony2-dbal-querybuilder/">Read more</a><p>]]></description>
			<content:encoded><![CDATA[<p>Sometimes, when we have some relatively complex queries to write, it&#8217;s so long and inflexible statement that it&#8217;s pretty hard to understand few days after we wrote it, or we have to add some dynamic parameters or conditions that writing plain DBAL statement could be real nightmare …<span id="more-11712"></span></p>
<p>Luckily, in Symfony2, for Doctrine2 DBAL statements like for ORM we also can use integrated QueryBuilder to build those complex queries and make our life easier.</p>
<p>So, instead of this kind of writing queries:</p>
<pre class="brush: php; title: ; notranslate">
//...
        $stmt = $conn-&gt;executeQuery(
                &quot;SELECT items.id as item_id,
                 items.item_name as item_name,
                 it.mobile_type as item_type,
                 st.status_symbol as status,
                 items.date_modified as date_modified,
                 fav.sort_order favorite_sort_order
                 FROM items
                 INNER JOIN item_types it on it.id = items.item_type_id
                 INNER JOIN statuses st on st.id = items.status_id
                 INNER JOIN favorites fav on fav.item_id = items.id
                 WHERE fav.user_id = ?
                 AND fav.appname= ?
                 AND
                 st.status_symbol = 'st_live'
                 ORDER BY items.id ASC&quot;, array($user_id, $appname), array(\PDO::PARAM_INT, \PDO::PARAM_STR)
        );

        $items = $stmt-&gt;fetchAll(\PDO::FETCH_ASSOC);
//...
</pre>
<p>we always could use this approach to make the same thing:</p>
<pre class="brush: php; title: ; notranslate">
//...
        $qb = $this-&gt;conn-&gt;createQueryBuilder();

        $qb-&gt;select('DISTINCT itc.item_id');
        $qb-&gt;from('items_to_collections', 'itc');
        $qb-&gt;innerJoin('itc', 'statuses', 's', 's.id = itc.status_id');
        $qb-&gt;innerJoin('itc', 'tags_to_items', 'tti', 'tti.item_id = itc.item_id');

        $and_cond = $qb-&gt;expr()-&gt;andx();
        $and_cond-&gt;add($qb-&gt;expr()-&gt;eq('s.status_symbol', $qb-&gt;expr()-&gt;literal('st_live')));
        $and_cond-&gt;add($qb-&gt;expr()-&gt;eq('tti.tag_id', $tag_id));
        $and_cond-&gt;add($qb-&gt;expr()-&gt;like('itc.path', $qb-&gt;expr()-&gt;literal($parent_path)));

        $qb-&gt;andWhere($and_cond);
        $qb-&gt;orderBy('itc.' . $sort_order, 'ASC');

        if ($limit &gt; 0) {
            //$qb-&gt;setFirstResult(0);
            $qb-&gt;setMaxResults($limit);
        }

        if ($existing != null) {
            $qb-&gt;andWhere('itc.item_id NOT IN (?)');
            $q = $qb-&gt;getSql();
            $stmt = $this-&gt;conn-&gt;executeQuery($q, array($existing), array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY));
        } else {
            $q = $qb-&gt;getSql();
            $stmt = $this-&gt;conn-&gt;executeQuery($q);
        }
        $items_ids = $stmt-&gt;fetchAll(\PDO::FETCH_COLUMN);
// ...
</pre>
<p>Also in above example it&#8217;s shown how to pass array as query parameter inside query builder, considering that I wrote about array parameters in DBAL statements in my last article ….</p>
<p>That&#8217;s it for now.</p>
<p>Cheers.</p>
]]></content:encoded>
			<wfw:commentRss>http://inchoo.net/tools-frameworks/symfony2-dbal-querybuilder/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.458 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-04 02:20:16 -->

