<?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>Data-Diggers.com &#187; Uncategorized</title>
	<atom:link href="http://www.data-diggers.com/index.php/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.data-diggers.com</link>
	<description>Zen Cart Optimization, Performance and A/B Split Testing Modules for Zen Cart</description>
	<lastBuildDate>Mon, 26 Sep 2011 15:21:09 +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>DDQuery &#8211; little class to help with database queries</title>
		<link>http://www.data-diggers.com/index.php/2011/09/ddquery-little-class-to-help-with-database-queries/</link>
		<comments>http://www.data-diggers.com/index.php/2011/09/ddquery-little-class-to-help-with-database-queries/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 14:58:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[Zen Cart]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=345</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2011%2F09%2Fddquery-little-class-to-help-with-database-queries%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2011%2F09%2Fddquery-little-class-to-help-with-database-queries%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: left;">After spending much time coding queries in Zen Cart I can say that database layer object ($db, includes/classes/db/mysql/query_factory.php) is not quite developer friendly when it comes to ease of use. Let&#8217;s have a look at typical query to database using this object:</p>
<p style="text-align: left;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$cid</span> <span class="sy0">=</span> <span class="nu0">12345</span><span class="sy0">;</span> <span class="co1">// any customer id</span><br />
<span class="re0">$cur</span> <span class="sy0">=</span> <span class="st0">&quot;USD&quot;</span><span class="sy0">;</span><br />
<span class="re0">$query</span> <span class="sy0">=</span> <span class="st0">&quot;SELECT * FROM &quot;</span> <span class="sy0">.</span> TABLE_ORDERS <span class="sy0">.</span> <span class="st0">&quot; WHERE customers_id = :cid AND currency= :currency&quot;</span><span class="sy0">;</span><br />
<span class="re0">$query</span> <span class="sy0">=</span> <span class="re0">$db</span><span class="sy0">-&gt;</span><span class="me1">bindVars</span><span class="br0">&#40;</span><span class="re0">$query</span><span class="sy0">,</span> <span class="st0">&quot;:cid&quot;</span><span class="sy0">,</span><span class="re0">$cid</span><span class="sy0">,</span><span class="st0">&quot;integer&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$query</span> <span class="sy0">=</span> <span class="re0">$db</span><span class="sy0">-&gt;</span><span class="me1">bindVars</span><span class="br0">&#40;</span><span class="re0">$query</span><span class="sy0">,</span><span class="st0">&quot;:currency&quot;</span><span class="sy0">,</span><span class="re0">$cur</span><span class="sy0">,</span><span class="st0">&quot;string&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$result</span> <span class="sy0">=</span> <span class="re0">$db</span><span class="sy0">-&gt;</span><span class="me1">Execute</span><span class="br0">&#40;</span><span class="re0">$query</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$result</span><span class="sy0">-&gt;</span><span class="me1">EOF</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="re0">$result</span><span class="sy0">-&gt;</span><span class="me1">fields</span><span class="br0">&#91;</span><span class="st0">&quot;customers_id&quot;</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$result</span><span class="sy0">-&gt;</span><span class="me1">MoveNext</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p style="text-align: left;">Why it is inconvenient? First of all binding variables to query string takes too many characters to write AND You have to bind one value at a time. Imagine that You have to bind ten variables &#8211; it would take ten lines of code just to prepare the query!</p>
<p>Also writing manually each time type of variable (&#8216;integer&#8217;,'string&#8217;,'date&#8217;,'double&#8217;) is error prone and inconvenient. I find myself from time to time writing &#8216;int&#8217; instead of &#8216;integer&#8217;. This is an error that goes unnoticed until the line of code is executed.</p>
<p>The way I want to bind variables is like:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$query</span> <span class="sy0">=</span> <span class="kw2">new</span> DDQuery<span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM &quot;</span> <span class="sy0">.</span> TABLE_ORDERS <span class="sy0">.</span> <span class="st0">&quot; WHERE customers_id = :cid AND currency= :currency&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$result</span> <span class="sy0">=</span> <span class="re0">$query</span><span class="sy0">-&gt;</span><span class="me1">int</span><span class="br0">&#40;</span><span class="st0">&quot;:cid&quot;</span><span class="sy0">,</span><span class="re0">$cid</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">string</span><span class="br0">&#40;</span><span class="st0">&quot;:currency&quot;</span><span class="sy0">,</span><span class="re0">$cur</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">Query</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<p>It&#8217;s just two line of code instead of four and much, much less characters to write. With six variables the code would still take just two lines of code instead of eight. It&#8217;s also less error prone to typos since any good IDE will show hint that method &#8216;sting&#8217; is not defined in DDQuery class.</p>
<h2 style="text-align: left;">Iterating through results</h2>
<p style="text-align: left;">I also personally hate the way Zen Cart forces me to iterate through query result. First it&#8217;s just hard for me to write !$result->EOF. I would much better prefer to write while($result->next()) (yeah, much like Java java.sql.ResultSet). Second I constantly forgot to write this additional $result->MoveNext() line, especially when while() body has more then five lines of code. So basicly I want to itreate through database results using:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$result</span><span class="sy0">-&gt;</span><span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="re0">$result</span><span class="sy0">-&gt;</span><span class="me1">fields</span><span class="br0">&#91;</span><span class="st0">&quot;customers_id&quot;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>It&#8217;s just one line of code less to write but I get rid of &#8216;!$result->EOF&#8217; which (maybe just to me) is hard to write and in addition I never again will face endless loop.</p>
<h2 style="text-align: left;">DDQuery class code</h2>
<p style="text-align: left;">You can download<a title="DDQuery class" href="http://www.data-diggers.com/contribs/DDQuery/DDQuery.zip"> DDQuery class code here</a>. As far as I tested it it works fine. There&#8217;s no documentation to the class other then comments in .php file. I don&#8217;t have time/I&#8217;m too lazy to write it. Still I think that it&#8217;s usable piece of code and few of more advanced users of Zen Cart may use it.</p>
<p>Here&#8217;s code of the class</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="kw2">class</span> DDQuery <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$query</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="re0">$query</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">query</span> <span class="sy0">=</span> <span class="re0">$query</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> bind<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="re0">$type</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$db</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">query</span> <span class="sy0">=</span> <span class="re0">$db</span><span class="sy0">-&gt;</span><span class="me1">bindVars</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">query</span><span class="sy0">,</span> <span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="re0">$type</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> int<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;integer&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> integer<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;integer&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> str<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;string&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> string<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;string&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> float<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;float&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> <a href="http://www.php.net/date"><span class="kw3">date</span></a><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;date&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> currency<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;currency&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> csv<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;csv&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> <a href="http://www.php.net/passthru"><span class="kw3">passthru</span></a><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;passthru&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> noquotestring<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;noquotestring&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> enum<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;enum&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> regexp<span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$var</span><span class="sy0">,</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="st_h">&#8216;regexp&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> getQuery<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">query</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> Execute<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$db</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><span class="re0">$db</span><span class="sy0">-&gt;</span><span class="me1">Execute</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getQuery</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> Query<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><span class="kw2">new</span> DDQueryResult<span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">Execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">class</span> DDQueryResult <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$result</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$fields</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw2">function</span> DDQueryResult<span class="br0">&#40;</span><span class="re0">$zc_result</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">result</span> <span class="sy0">=</span> <span class="re0">$zc_result</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">function</span> <a href="http://www.php.net/next"><span class="kw3">next</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">result</span><span class="sy0">-&gt;</span><span class="me1">EOF</span><span class="br0">&#41;</span> <span class="kw1">return</span><span class="br0">&#40;</span><span class="kw4">FALSE</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">fields</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">result</span><span class="sy0">-&gt;</span><span class="me1">fields</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">result</span><span class="sy0">-&gt;</span><span class="me1">MoveNext</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><span class="kw4">TRUE</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<h3 style="text-align: left;">Usage examples</h3>
<p><div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$q</span> <span class="sy0">=</span> <span class="kw2">new</span> DDQuery<span class="br0">&#40;</span><span class="st0">&quot;INSERT INTO &quot;</span> <span class="sy0">.</span> TABLE_CUSTOMERS_UPLOADS <span class="sy0">.</span> <span class="st0">&quot;(customers_id, original_name, name, last_update, date_added, ip, status, file_size, hash_md5) VALUES(:cid, <img src='http://www.data-diggers.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> name, :name, NOW(), NOW(), :ip, &#8216;PENDING&#8217;, :size, :md5)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">int</span><span class="br0">&#40;</span><span class="st0">&quot;:cid&quot;</span><span class="sy0">,</span> <span class="re0">$cid</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">string</span><span class="br0">&#40;</span><span class="st0">&quot;:oname&quot;</span><span class="sy0">,</span><span class="re0">$fileStruct</span><span class="br0">&#91;</span><span class="st_h">&#8216;name&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">string</span><span class="br0">&#40;</span><span class="st0">&quot;:name&quot;</span><span class="sy0">,</span><span class="re0">$fileName</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">string</span><span class="br0">&#40;</span><span class="st0">&quot;:ip&quot;</span><span class="sy0">,</span><span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">&#8216;REMOTE_ADDR&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">int</span><span class="br0">&#40;</span><span class="st0">&quot;:size&quot;</span><span class="sy0">,</span><span class="re0">$fileStruct</span><span class="br0">&#91;</span><span class="st_h">&#8216;size&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">string</span><span class="br0">&#40;</span><span class="st0">&quot;:md5&quot;</span><span class="sy0">,</span><span class="re0">$md5</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">Execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$q</span> <span class="sy0">=</span> <span class="kw2">new</span> DDQuery<span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM &quot;</span> <span class="sy0">.</span> TABLE_CUSTOMERS_UPLOADS <span class="sy0">.</span> <span class="st0">&quot; WHERE hash_md5 = :md5&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$q</span> <span class="sy0">=</span> <span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">string</span><span class="br0">&#40;</span><span class="st0">&quot;:md5&quot;</span><span class="sy0">,</span> <span class="re0">$md5</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">Execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">EOF</span><span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw4">FALSE</span><span class="sy0">;</span></div>
</div>
<h3 style="text-align: left;">Installation instructions</h3>
<ol>
<li style="text-align: left;">Download the class code (<a href="http://www.data-diggers.com/contribs/DDQuery/DDQuery.zip">DDQuery.zip</a>) and extract it to root folder with Zen Cart installation.</li>
<li style="text-align: left;">Use it!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2011/09/ddquery-little-class-to-help-with-database-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Useful Zen Cart InitSystem breakpoints</title>
		<link>http://www.data-diggers.com/index.php/2011/09/useful-zen-cart-initsystem-breakpoints/</link>
		<comments>http://www.data-diggers.com/index.php/2011/09/useful-zen-cart-initsystem-breakpoints/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 15:37:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=335</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2011%2F09%2Fuseful-zen-cart-initsystem-breakpoints%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2011%2F09%2Fuseful-zen-cart-initsystem-breakpoints%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<div style="text-align: left;">Here&#8217;s list of useful Zen Cart breakpoints taken from includes/auto_load/config.core.php</div>
<ul>
<li style="text-align: left;">[0] &#8211; <strong>$zco_notifier</strong> is created</li>
<li style="text-align: left;">[10] &#8211; <strong>$db</strong> database object is up and running</li>
<li style="text-align: left;">[40] &#8211; configuration values are read from <strong>configuration</strong> table and defined</li>
<li style="text-align: left;">[60] &#8211; functions from includes/functions, includes/functions/extra_functions are loaded</li>
<li style="text-align: left;">[70] &#8211; session related functions/classes are loaded, session is created/loaded</li>
<li style="text-align: left;">[80] &#8211; <strong>shopping car</strong>t object is created</li>
<li style="text-align: left;">[90] &#8211; currencies are loaded</li>
<li style="text-align: left;">[130] &#8211; <strong>$messageStack</strong> object is created</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2011/09/useful-zen-cart-initsystem-breakpoints/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Embrace ugliness ;)</title>
		<link>http://www.data-diggers.com/index.php/2011/05/embrace-ugliness/</link>
		<comments>http://www.data-diggers.com/index.php/2011/05/embrace-ugliness/#comments</comments>
		<pubDate>Thu, 26 May 2011 19:14:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=333</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2011%2F05%2Fembrace-ugliness%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2011%2F05%2Fembrace-ugliness%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>You know these words&#8230;They are like mantra<br />
<strong>&#8216;Backup! Backup! Backup!&#8217;</strong><br />
One should really do backups before making updates <img src='http://www.data-diggers.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Unfortunately I didn&#8217;t and now the site looks like.. well, it&#8217;s not pretty <img src='http://www.data-diggers.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  It will take me a while to clean up the mess, sorry <img src='http://www.data-diggers.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2011/05/embrace-ugliness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UTI 1.5 is coming.</title>
		<link>http://www.data-diggers.com/index.php/2010/10/uti-1-5-is-coming/</link>
		<comments>http://www.data-diggers.com/index.php/2010/10/uti-1-5-is-coming/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 09:51:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[UTI]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[User Tracking Interface]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=310</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F10%2Futi-1-5-is-coming%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F10%2Futi-1-5-is-coming%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">User Tracking Interface version 1.5 will be released next week. There are few important bug fixes, some performance improvements and new features. In nutshell:</p>
<ul style="text-align: justify;">
<li>IP is no longer stored in database as VARCHAR(15) but as INT, so each UTI record takes less space</li>
<li>uti table prune is no longer triggered on catalog activity. Prune is triggered by admin activity and is executed only once per day.</li>
<li>some indexes on uti table might be changed</li>
<li>support for custom uti attributes merge functions (I&#8217;ll elaborate on it on UTI 1.5 release)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2010/10/uti-1-5-is-coming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with UTI &#8211; personalized &#8216;Welcome back&#8217; message.</title>
		<link>http://www.data-diggers.com/index.php/2010/05/fun-with-uti-personalized-welcome-back-message/</link>
		<comments>http://www.data-diggers.com/index.php/2010/05/fun-with-uti-personalized-welcome-back-message/#comments</comments>
		<pubDate>Mon, 24 May 2010 18:56:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=261</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F05%2Ffun-with-uti-personalized-welcome-back-message%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F05%2Ffun-with-uti-personalized-welcome-back-message%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">If You visit any Zen Cart store You may notice greeting message that says something like &#8216;<em>Welcome Guest! Would you like to log yourself in?</em>&#8216;. Have You ever wondered what&#8217;s purpose of this message? Does it give any information to the visitor? Does it make him feel special? Does it serve any purpose other then providing link to &#8216;Log In&#8217; page? No, it does not. Zen Cart displays personalized greetings like &#8216;<em>Welcome back, John!</em>&#8216;, but only to registered users who are <span style="text-decoration: underline;">already logged in.</span></p>
<div id="attachment_302" class="wp-caption aligncenter" style="width: 606px"><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/default_greeting.gif" rel="prettyPhoto"><img class="size-full wp-image-302" title="Default Zen Cart greeting message to Guest visitors." src="http://www.data-diggers.com/wp-content/uploads/2010/05/default_greeting.gif" alt="" width="596" height="87" /></a><p class="wp-caption-text">Default Zen Cart greeting message to Guest visitors.</p></div>
<p style="text-align: justify;">Compare it to Amazon store. Let&#8217;s say that the visitor (John)  has account there and occasionally visits their website. Every time he goes back he is greeted with personalized message: &#8216;<em>Hello, John. We have recommendations for You.</em>&#8216;. John does not have to log in, provide any information or do anything special &#8211; yet he is still recognized as returning customer. How&#8217;s that different from Zen Cart greeting?</p>
<ul style="text-align: justify;">
<li>John knows that he already has account at Amazon so he does not have to create one</li>
<li>John gets personalized message</li>
<li>he has access to his shopping cart without logging in</li>
<li>he sees his recently viewed products</li>
<li>Amazon recommends some items based on his shopping/browsing history</li>
<li>even if the visitor is not John Johns identity and private data is not revealed.</li>
</ul>
<p style="text-align: justify;">Pretty cool, right? When John visits Amazon.com he feels like he was already logged in (but he&#8217;s not). Can Zen Cart to that? Yes, with User Tracking Interface.</p>
<h2 style="text-align: justify;">UTI to the rescue!</h2>
<p style="text-align: justify;">If You&#8217;re not familiar with User Tracking Interface (UTI) please read about it <a href="http://www.data-diggers.com/index.php/tag/user-tracking-interface/" target="_blank">here</a>. <strong>You will need to install <a href="http://www.data-diggers.com/index.php/tag/user-tracking-interface/">UTI</a> if You want to implement this functionality on Your store.</strong></p>
<p style="text-align: justify;">With UTI We can make Zen Cart a bit more friendly to returning visitors. UTI recognizes returning visitors by cookie, ip address or both and stores basic information about them (time of last visit, last IP address, customer ID if visitor created account).</p>
<p style="text-align: justify;">What We need to do</p>
<ul style="text-align: justify;">
<li>check if UTI recognized the visitor as returning customer (UTI does it automatically)</li>
<li>if it did We display personalized message</li>
</ul>
<h2 style="text-align: justify;">Code</h2>
<p style="text-align: justify;">We&#8217;ll be working with default template that comes with Zen Cart: template_default. In case of custom templates the same steps should be applied.</p>
<p style="text-align: justify;">Zen Cart uses zen_customer_greeting() function to display greeting message to the visitor. Here&#8217;s snippet of code that uses this function (includes/templates/template_default/templates/tpl_index_default.php), lines 19-21:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span>SHOW_CUSTOMER_GREETING <span class="sy0">==</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="sy1">?&gt;</span><br />
&lt;h2 class=&quot;greeting&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> zen_customer_greeting<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>&lt;/h2&gt;<br />
<span class="kw2">&lt;?php</span> <span class="br0">&#125;</span> <span class="sy1">?&gt;</span></div>
</div>
<p style="text-align: justify;">Unfortunately We can&#8217;t use zen_customer_greeting() as We don&#8217;t want to change Zen Cart core  code. We&#8217;ll create our own greeting function instead. We&#8217;ll put it in includes/functions/extra_functions/personalized_greeting.php.</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<span class="kw2">function</span> personalized_greeting<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$uti</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$db</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="co1">// revert back to default greeting function if the visitor is not recognized by UTI</span><br />
&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="sy0">!</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$uti</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">return</span><span class="br0">&#40;</span>zen_customer_greeting<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> <span class="sy0">!</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$uti</span><span class="sy0">-&gt;</span><span class="me1">customerID</span><span class="br0">&#41;</span> <span class="sy0">||</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>int<span class="br0">&#41;</span><span class="re0">$uti</span><span class="sy0">-&gt;</span><span class="me1">customerID</span><span class="br0">&#41;</span> <span class="sy0">==</span> 0<span class="br0">&#41;</span> <span class="kw1">return</span><span class="br0">&#40;</span>zen_customer_greeting<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">// UTI recognizes the visitor as returning customer, let&#8217;s get his first name</span><br />
&nbsp; &nbsp; <span class="re0">$q</span> <span class="sy0">=</span> <span class="re0">$db</span><span class="sy0">-&gt;</span><span class="me1">Execute</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM &quot;</span> <span class="sy0">.</span> TABLE_CUSTOMERS <span class="sy0">.</span> <span class="st0">&quot; WHERE customers_id = &quot;</span> <span class="sy0">.</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span><span class="re0">$uti</span><span class="sy0">-&gt;</span><span class="me1">customerID</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span>TEXT_GREETING_PERSONAL<span class="sy0">,</span> zen_output_string_protected<span class="br0">&#40;</span><span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">fields</span><span class="br0">&#91;</span><span class="st_h">&#8216;customers_firstname&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">,</span> zen_href_link<span class="br0">&#40;</span>FILENAME_PRODUCTS_NEW<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p style="text-align: justify;">We reuse default Zen Cart greeting message, TEXT_GREETING_PERSONAL. We now need to modify our template to use personalized_greeting() instead of zen_customer_greeting(). Go to includes/templates/template_default/templates/tpl_index_default.php and change:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span>SHOW_CUSTOMER_GREETING <span class="sy0">==</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="sy1">?&gt;</span><br />
&lt;h2 class=&quot;greeting&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> zen_customer_greeting<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>&lt;/h2&gt;<br />
<span class="kw2">&lt;?php</span> <span class="br0">&#125;</span> <span class="sy1">?&gt;</span></div>
</div>
<p>to:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span>SHOW_CUSTOMER_GREETING <span class="sy0">==</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="sy1">?&gt;</span><br />
&lt;h2 class=&quot;greeting&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> personalized_greeting<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>&lt;/h2&gt;<br />
<span class="kw2">&lt;?php</span> <span class="br0">&#125;</span> <span class="sy1">?&gt;</span></div>
</div>
<p style="text-align: justify;">And that&#8217;s it! From now on returning customers will be greeted with personalized message.</p>
<h2 style="text-align: justify;">Test</h2>
<p style="text-align: justify;">Visit Your store and create test account. Close Your browser and return to Your website after half hour. Default  Zen Cart session lifespan is 15 minutes so any saved Zen Cart session should be invalidated by now. If our little module works correctly You should be greeted by Your name.</p>
<div id="attachment_299" class="wp-caption aligncenter" style="width: 604px"><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/greeting_personalized.gif" rel="prettyPhoto"><img class="size-full wp-image-299" title="Personalized greeting message to returning customers (using UTI)" src="http://www.data-diggers.com/wp-content/uploads/2010/05/greeting_personalized.gif" alt="" width="594" height="101" /></a><p class="wp-caption-text">Personalized greeting message to returning customers (using UTI)</p></div>
<h2 style="text-align: justify;">Download</h2>
<p style="text-align: justify;">For Your convenience I prepared .zip file with personalized_greeting() function. You can download it here. However, You&#8217;ll have to make necessary changes to the template yourself.</p>
<p style="text-align: center;"><strong><a href="http://www.data-diggers.com/contribs/personalized-greeting-message/downloads/personalized_greeting_message-current.zip">Download the package.</a></strong></p>
<p style="text-align: justify;"><strong>Remember that You have to have <a href="http://www.data-diggers.com/index.php/tag/user-tracking-interface/">UTI</a> installed for this module to work.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2010/05/fun-with-uti-personalized-welcome-back-message/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A/B Split Test: Is McAffee or WebSafeShield seal worth its price?</title>
		<link>http://www.data-diggers.com/index.php/2010/05/ab-split-test-is-mcaffee-or-websafeshield-seal-worth-its-price/</link>
		<comments>http://www.data-diggers.com/index.php/2010/05/ab-split-test-is-mcaffee-or-websafeshield-seal-worth-its-price/#comments</comments>
		<pubDate>Sun, 23 May 2010 10:38:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=274</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F05%2Fab-split-test-is-mcaffee-or-websafeshield-seal-worth-its-price%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F05%2Fab-split-test-is-mcaffee-or-websafeshield-seal-worth-its-price%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">Many sites have fancy seals like &#8216;HackerSafe&#8217;, &#8216;WebsSafeShield&#8217;,'BuyerShield&#8217; and so on. Their issuers claim that those seals give confidance to customers and they are more likely to buy on site that has security seal. Some seal issuers claim boost of sales around 20%. The question is &#8211; is it true that store owner&#8217;s get more orders? How to determine that? If You&#8217;re store owner and Your store is using Zen Cart You can perform Your own A/B split test to find out if those seals improve sales.</p>
<h2 style="text-align: justify;">First, do the math</h2>
<p style="text-align: justify;">Business is about income &#8211; if investment does not earn You more money than it costs You shouldn&#8217;t put money into it. Before You purchase security scanning service You should calculate if it is worth to pay $40-$80/month just to get the seal?</p>
<p style="text-align: justify;">Let&#8217;s say that Your store has income of $200/month (hey, maybe You&#8217;re just starting?). In best case scenario You&#8217;ll get 20% boost in sales, which is $40/month. In not-so-optimistic scenario sales will improve by 10% &#8211; $20/month. You&#8217;re spending $40-$80/month for the seal, and it provides $20-$40/month, so You&#8217;re spending more than You earn. In that case You shouldn&#8217;t get the seal &#8211; it&#8217;s just not worth it.</p>
<p style="text-align: justify;">Now, if You get $1000 or more out of Your store things start to look bit different.  The seals earns $200/$100 per month in optimistic/not-so-optimistic scenario, so You earn more than You spend. You definitely should get the seal. Keep in mind however that You&#8217;re still unsure that the seal will provide more money than it costs. You need to perform A/B split test to know that.</p>
<h2 style="text-align: justify;">The Test</h2>
<p style="text-align: justify;">I&#8217;ll show You exactly how to perform such A/B split test using <a title="Randomized Tests" href="http://www.data-diggers.com/index.php/tag/randomized-tests/">Randomized Tests</a>. You&#8217;ll need Randomized Tests contribution which allows You to perform A/B split tests on Your site. Randomized Tests requires also <a href="http://www.data-diggers.com/index.php/category/utils/uti-utils/">User Tracking Interface</a> contribution which You can find <a href="http://www.data-diggers.com/contribs/uti/downloads/uti-current.zip">here</a>.</p>
<p style="text-align: justify;">I will be using default Zen Cart template to insert the seal, but steps should be very similar with Your custom template. I also decided to use WebSafeShield seal in the test.</p>
<h2>Step 1 &#8211; create the groupset</h2>
<p>I want perform A/B split test with two test groups:</p>
<ul>
<li>Control  Group &#8211; visitors in this group will see old version of the page without  the seal.</li>
<li>Test Group &#8211; visitors in this group will see changed  header with the seal displayed.</li>
</ul>
<p>Before I create the test I  need first create set of visitor groups &#8211; groupset. To do this I go to  Admin -&gt; Tools -&gt; [RT] Groupsets and I create &#8216;Standard Groupset&#8217;.</p>
<p><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/create_groupset.gif" rel="prettyPhoto"><img class="aligncenter size-full wp-image-278" title="create_groupset" src="http://www.data-diggers.com/wp-content/uploads/2010/05/create_groupset.gif" alt="" width="498" height="138" /></a>I then click twice on it and create two groups:</p>
<ul>
<li>Control Group (name: &#8216;Control Group&#8217;, id: &#8216;cg&#8217;, control group: <strong>checked</strong>)</li>
</ul>
<ul>
<li>Test Group (name: &#8216;Test Group&#8217;, id: &#8216;tg&#8217;, control group: <strong>unchecked</strong>)</li>
</ul>
<p><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/create_control_group.gif" rel="prettyPhoto"><img class="aligncenter size-full  wp-image-280" title="create_control_group" src="http://www.data-diggers.com/wp-content/uploads/2010/05/create_control_group.gif" alt="" width="494" height="162" /></a></p>
<h2 style="text-align: justify;">Step 2 &#8211; prepare the template</h2>
<p>I want  the seal to be clearly visible to visitors so I&#8217;m going to  insert it  into header area. With  this in mind I change the template file   (includes/templates/template_default/common/tpl_header.php) around line 77 from:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;">&lt;div id=&quot;tagline&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> HEADER_SALES_TEXT<span class="sy0">;</span><span class="sy1">?&gt;</span>&lt;/div&gt;</div>
</div>
<p>to:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;">&lt;div id=&quot;tagline&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> HEADER_SALES_TEXT<span class="sy0">;</span><span class="sy1">?&gt;</span>&lt;/div&gt;<br />
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$exp</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$exp</span><span class="sy0">-&gt;</span><span class="me1">groupID</span> <span class="sy0">==</span> <span class="st_h">&#8216;tg&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
<span class="sy1">?&gt;</span><br />
&lt;div id=&quot;securitySeal&quot;&gt;&lt;!&#8211; Begin WebSafe Shield code &#8211;&gt;<br />
&lt;script src=&quot;https://www.websafeshield.com/seals/my_domain110x56_com/websafeshield.js&quot;&gt;&lt;/script&gt;<br />
&lt;!&#8211; End WebSafe Shield code &#8211;&gt;<br />
&lt;/div&gt;<br />
<span class="kw2">&lt;?php</span> <span class="br0">&#125;</span> <span class="sy1">?&gt;</span></div>
</div>
<h2 style="text-align: justify;">Step 3 &#8211; create the test</h2>
<p style="text-align: justify;">Now You just need to create the test. Go To Admin-&gt;Tools-&gt;[RT] Experiments and use form on the bottom to create new experiment:</p>
<ul style="text-align: justify;">
<li>Name &#8211; enter &#8216;Seal Test&#8217;</li>
<li>ID &#8211; enter &#8216;seal_test&#8217;</li>
<li>Last From &#8211; enter current <span style="text-decoration: underline;">server</span> date, e.g.: 2010-05-21 19:00:00</li>
<li>Last To &#8211; enter test end date &#8211; I recommend entering date far in the future as You can always end the test earlier. Enter 2011-01-01 00:00:00</li>
<li>GroupSet &#8211; choose &#8216;Standard&#8217;</li>
<li>Impression Detection Function &#8211; leave as it is (&#8216;default_rt_idf&#8217;)</li>
<li>Click &#8216;Create&#8217;</li>
</ul>
<div class="mceTemp mceIEcenter">
<div id="attachment_281" class="wp-caption aligncenter" style="width: 651px"><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/create_test.gif" rel="prettyPhoto"><img class="size-full wp-image-281" title="create_test" src="http://www.data-diggers.com/wp-content/uploads/2010/05/create_test.gif" alt="" width="641" height="147" /></a><p class="wp-caption-text">Creation of the experiment</p></div>
<dl id="attachment_282" class="wp-caption aligncenter" style="width: 740px;">
<dt class="wp-caption-dt"><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/after_create_test.gif" rel="prettyPhoto"><img class="size-full wp-image-282" title="after_create_test" src="http://www.data-diggers.com/wp-content/uploads/2010/05/after_create_test.gif" alt="" width="730" height="215" /></a></dt>
<dd class="wp-caption-dd">View of test stats just after the test has been created</dd>
</dl>
</div>
<h2 style="text-align: justify;">Step 4 &#8211; verify that the test is running</h2>
<p style="text-align: justify;">Go to Your store and check that the test is running. Make sure that &#8216;Impressions&#8217; counter in Experiment Statistics has been increased by 1 on Your visit (this counter is increased ONLY ONCE per visitor). Visit Your store from few computers or smartphones &#8211; You should be able to see modified version of the header on some (unfortunately Randomized Tests does not provide yet tool to store owners to switch test group &#8211; You have to test from several computers or clean cookies to be moved to different test group).</p>
<p style="text-align: justify;">
<div id="attachment_294" class="wp-caption aligncenter" style="width: 762px"><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/header_control_group.gif" rel="prettyPhoto"><img class="size-full wp-image-294" title="Header of Control Group" src="http://www.data-diggers.com/wp-content/uploads/2010/05/header_control_group.gif" alt="" width="752" height="199" /></a><p class="wp-caption-text">Header of Control Group</p></div>
<p style="text-align: justify;">
<div id="attachment_295" class="wp-caption aligncenter" style="width: 762px"><a href="http://www.data-diggers.com/wp-content/uploads/2010/05/header_test_group.gif" rel="prettyPhoto"><img class="size-full wp-image-295" title="Header of Test Group" src="http://www.data-diggers.com/wp-content/uploads/2010/05/header_test_group.gif" alt="Header of Test Group" width="752" height="197" /></a><p class="wp-caption-text">Header of Test Group</p></div>
<h2 style="text-align: justify;">Step 5 &#8211; wait for the results</h2>
<p style="text-align: justify;">Wait until  the test will provide statistically significant results. Result is statistically significant if some group is clear winner &#8211; it has 95% or more chance to beat control group and has been fed with enough data. If test group has 5% or less chance to beat control group You may consider  control group as clear winner. As the rule of thumb let the test run until:</p>
<ul style="text-align: justify;">
<li>One of groups get 95% chance to be clear winner</li>
<li><strong><span style="text-decoration: underline;">and</span></strong> there has been at least 100 impressions and 50 order conversions in each group.</li>
</ul>
<h2 style="text-align: justify;">Step 6 &#8211; do the math again</h2>
<p style="text-align: justify;">You finished Your test and have the clear winner. If the clear winner is control group then it means that the seal does more harm than good and Your customers are less willing to buy when the seal is displayed (it would be strange though &#8211; maybe HTML code is not properly formatted and it breaks design of Your store?)</p>
<p style="text-align: justify;">If test group (the one to which seal was displayed) is the winner You should check how much more money it earned. If &#8216;Total Orders Value&#8217; rose by %10 and You earn $1000/month then the seal earns: 0.1 * $1000 = $100/month, so it&#8217;s a good idea to keep it.</p>
<p style="text-align: justify;">If You decide to perform the test please post Your results in comments &#8211; I&#8217;m curious how much such seals boost sales in real life.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2010/05/ab-split-test-is-mcaffee-or-websafeshield-seal-worth-its-price/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to create custom impression detection function for Randomized Tests</title>
		<link>http://www.data-diggers.com/index.php/2010/05/how-to-create-custom-impression-detection-function-for-randomized-tests/</link>
		<comments>http://www.data-diggers.com/index.php/2010/05/how-to-create-custom-impression-detection-function-for-randomized-tests/#comments</comments>
		<pubDate>Tue, 18 May 2010 12:36:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[A/B Split Tests]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[UTI]]></category>

		<guid isPermaLink="false">http://www.data-diggers.eu/?p=140</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F05%2Fhow-to-create-custom-impression-detection-function-for-randomized-tests%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F05%2Fhow-to-create-custom-impression-detection-function-for-randomized-tests%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;"><a href="http://www.data-diggers.com/index.php/2009/11/randomized-tests-version-1-3/">Randomized Tests version 1.3</a> introduces new feature &#8211; custom impression functions. It allows You to decide who and under what conditions participates in A/B split test. In this post I would like to show You how to create custom impression detection function and how to use it to speed up experiments.</p>
<h2 style="text-align: justify;">The need for custom impression detection functions</h2>
<p style="text-align: justify;">Let&#8217;s assume that You want to change Your registration page. You hope that new version will ease process of registration and more customers will register/order. You want to include in experiment only those visitors that actually viewed &#8216;Register&#8217; page and remove from experiment those visitors that never intended to register / make purchase and never visited &#8216;Register&#8217; page. Why? Because You can get more accurate results more quickly. Let me show it to You on example.</p>
<h2 style="text-align: justify;">Example</h2>
<p style="text-align: justify;">Let&#8217;s assume that Your site gets 1000 visits daily (excluding bots). Of those 1000 visitors only 100 intend to buy anything ( other visitors are just surfing, comparing prices or doing anything else &#8211; they are not customers). Those 100 visitors get to &#8216;Register&#8217; page where You  already set up A/B split test with two versions of the page.  You know &#8211; from Google Analytics or anywhere else &#8211; that old version of the page (version A or control group) has  20% conversion rate. You expect new version of the page to have 40% conversion rate. How quickly will You know that the new page is better? Here&#8217;s comparison of default IDF vs custom IDF:</p>
<ul>
<li>Default impression detection function (all visitors are included in the experiment)</li>
</ul>
<p style="text-align: justify;"><!--   		BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:"Arial"; font-size:x-small } --></p>
<table border="1" cellspacing="0" cellpadding="2">
<colgroup>
<col width="80"></col>
<col width="88"></col>
<col width="108"></col>
<col width="130"></col>
<col width="145"></col>
<col width="129"></col>
</colgroup>
<tbody>
<tr>
<td width="90" height="20" align="CENTER"><strong>Group</strong></td>
<td width="88" align="CENTER"><strong>Visitors</strong></td>
<td width="108" align="CENTER"><strong>Impressions</strong></td>
<td width="130" align="CENTER"><strong>Conversions</strong></td>
<td width="145" align="CENTER"><strong>Conv. Rate</strong></td>
<td width="129" align="CENTER"><strong>Duration</strong></td>
</tr>
<tr>
<td height="17" align="CENTER">Group #A</td>
<td align="CENTER">500</td>
<td align="CENTER">500</td>
<td style="text-align: center;">10</td>
<td align="CENTER">2%</td>
<td rowspan="2" align="CENTER" valign="MIDDLE"><strong><span style="color: #ff0000; font-size: large;">6.41 days</span></strong></td>
</tr>
<tr>
<td height="20" align="CENTER">Group #B</td>
<td align="CENTER">500</td>
<td align="CENTER">500</td>
<td align="CENTER">20</td>
<td align="CENTER">4%</td>
</tr>
</tbody>
</table>
<ul>
<li>Custom impression detection function (impression occurs only when visitor views &#8216;Register&#8217; page<span style="text-decoration: underline;"> for the first time</span>)</li>
</ul>
<p><!--   		BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:"Arial"; font-size:x-small } --></p>
<table border="1" cellspacing="0" cellpadding="2">
<colgroup>
<col width="80"></col>
<col width="88"></col>
<col width="108"></col>
<col width="130"></col>
<col width="145"></col>
<col width="129"></col>
</colgroup>
<tbody>
<tr>
<td width="90" height="17" align="CENTER"><strong>Group</strong></td>
<td width="88" align="CENTER"><strong>Visitors</strong></td>
<td width="108" align="CENTER"><strong>Impressions</strong></td>
<td width="130" align="CENTER"><strong>Conversions</strong></td>
<td width="145" align="CENTER"><strong>Conv. Rate</strong></td>
<td width="129" align="CENTER"><strong>Duration</strong></td>
</tr>
<tr>
<td height="20" align="CENTER">Group #A</td>
<td align="CENTER">500</td>
<td align="CENTER">50</td>
<td align="CENTER">10</td>
<td align="CENTER">20%</td>
<td rowspan="2" align="CENTER" valign="MIDDLE"><strong><span style="color: #00ff00; font-size: large;">5.66 days</span></strong></td>
</tr>
<tr>
<td height="20" align="CENTER">Group #B</td>
<td align="CENTER">500</td>
<td align="CENTER">50</td>
<td align="CENTER">20</td>
<td align="CENTER">40%</td>
</tr>
</tbody>
</table>
<p style="text-align: justify;">As You can see from this simple example there&#8217;s 15% decrease in duration of experiment. In other scenarios improvement may be even better.</p>
<h2 style="text-align: justify;">How to create IDF (Impression Detection Function)</h2>
<p style="text-align: justify;">Randomized Tests can make use of any function that:</p>
<ul style="text-align: justify;">
<li>is located in &#8216;includes/functions/extra_functions&#8217; directory</li>
<li>ends with &#8216;_rt_idf&#8217; string (e.g. my_custom_rt_idf())</li>
<li>takes five arguments in following order:
<ul>
<li><strong>$experimentRowID</strong> &#8211; ID of row in rt_experiments table representing current experiment</li>
<li><strong>$experimentID</strong> &#8211; ID of current experiment You created (e.g. &#8216;login_test&#8217;)</li>
<li><strong>$groupRowID</strong> &#8211; ID of row in rt_experiments_groups table representing group to which customer has been assigned</li>
<li> <strong>$groupID</strong> &#8211; ID above group (e.g. &#8216;control_group&#8217;, &#8216;test_group&#8217;)</li>
<li><strong>$newlyAssigned</strong> &#8211; TRUE if visitor has just been assigned to group (e.g. it&#8217;s his first visit to Your store)</li>
</ul>
</li>
<li>returns:
<ul>
<li>TRUE &#8211; if impression occured</li>
<li>FALSE &#8211; otherwise</li>
</ul>
</li>
</ul>
<p style="text-align: justify;">Ok, so let&#8217;s create such function and upload it to /includes/functions/extra_functions:</p>
<p style="text-align: justify;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">function</span> visited_register_page_rt_idf<span class="br0">&#40;</span><span class="re0">$e_row_id</span><span class="sy0">,</span> <span class="re0">$eid</span><span class="sy0">,</span> <span class="re0">$g_row_id</span><span class="sy0">,</span> <span class="re0">$gid</span><span class="sy0">,</span> <span class="re0">$new</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$uti</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$current_page_base</span><span class="sy0">;&lt;/</span>p<span class="sy0">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$current_page_base</span> <span class="sy0">==</span> <span class="st_h">&#8216;create_account&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$flag</span> <span class="sy0">=</span> <span class="re0">$uti</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="st_h">&#8216;visited_create_account_page&#8217;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$flag</span> <span class="sy0">===</span> <span class="kw4">FALSE</span> <span class="sy0">||</span> <span class="re0">$flag</span> <span class="sy0">==</span> <span class="st_h">&#8216;FALSE&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$uti</span><span class="sy0">-&gt;</span><span class="me1">set</span><span class="br0">&#40;</span><span class="st_h">&#8216;visited_create_account_page&#8217;</span><span class="sy0">,</span> <span class="st_h">&#8216;TRUE&#8217;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><span class="kw4">TRUE</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><span class="br0">&#40;</span><span class="kw4">FALSE</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p style="text-align: justify;">First, function checks if currently visited page is &#8216;create_account&#8217; page &#8211; We want impression to occur only on registration form page (which in Zen Cart is &#8216;create_account&#8217; page). Impression should occur only once per visitor so function checks using UTI if visitor already viewed &#8216;create_account&#8217; page. If he didn&#8217;t function does two things:</p>
<ul style="text-align: justify;">
<li>saves information that visitor viewed &#8216;create_account&#8217; page in UTI</li>
<li>return TRUE &#8211; impression occured</li>
</ul>
<p style="text-align: justify;">If visitor already visited &#8216;create_account&#8217; page impression does not occur and function returns FALSE.</p>
<p style="text-align: justify;">Now upload the function to includes/functions/extra_functions and create experiment that uses it to detect impression.</p>
<h2 style="text-align: justify;">Modify &#8216;Create Account&#8217; page</h2>
<p style="text-align: justify;">Let&#8217;s modify &#8216;Create Account&#8217; page. We just want to test two versions of &#8216;Create Account&#8217; page so I used &#8216;Standard Groupset&#8217; (Admin-&gt;Tools-&gt;[RT] Groupsets) as groupset. Standard Groupset has two groups: control group (id &#8216;cg&#8217;) and test group (id &#8216;tg&#8217;).</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw1">if</span><span class="br0">&#40;</span><span class="sy0">!</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$exp</span><span class="br0">&#41;</span> <span class="sy0">||</span> <span class="re0">$exp</span><span class="sy0">-&gt;</span><span class="me1">groupID</span> <span class="sy0">==</span> <span class="st_h">&#8216;cg&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// control group</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// display old &#8216;Create Account&#8217; page</span><br />
<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// test group</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// display new version of &#8216;Create Account&#8217; page</span><br />
<span class="br0">&#125;</span></div>
</div>
<p style="text-align: justify;">If visitor has been assigned to control group (&#8216;cg&#8217;) old version of page is displayed. In other case new &#8216;Create Account&#8217; page is used.</p>
<h2 style="text-align: justify;">How to use IDF in experiment</h2>
<p style="text-align: justify;">Go to Admin-&gt;Tools-&gt; [RT] Experiments page. Create new experiment as usually. In &#8216;<strong>Impression Detection Function</strong>&#8216; box paste name of Your impression detection function: &#8216;visited_create_account_page_rt_idf&#8217;  (without braces). Click on &#8216;Create&#8217;. That&#8217;s it!</p>
<h2 style="text-align: justify;">Test that Your IDF works</h2>
<p>Visit Your site and check that impression only occurs on first visit to &#8216;Create Account&#8217; page.</p>
<p style="text-align: justify;">That&#8217;s it. If anything isn&#8217;t clear please post comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2010/05/how-to-create-custom-impression-detection-function-for-randomized-tests/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>User Tracking Interface v1.1</title>
		<link>http://www.data-diggers.com/index.php/2010/03/user-tracking-interface-v1-1/</link>
		<comments>http://www.data-diggers.com/index.php/2010/03/user-tracking-interface-v1-1/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 22:43:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[UTI]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[User Tracking Interface]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=216</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F03%2Fuser-tracking-interface-v1-1%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F03%2Fuser-tracking-interface-v1-1%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">It&#8217;s mainly bug fix release. Update is <strong>STRONGLY </strong>recommended.</p>
<p style="text-align: justify;">Changelog:</p>
<ul style="text-align: justify;">
<li>Changed file name of <em>includes/auto_loaders/config.utis.php.php to includes/auto_loaders/config.utis.php</em></li>
<li>uti_install.sql missed some inserts</li>
<li>Fix to: [DELETE FROM uti_attributes WHERE uti_row_id = ? AND name IN () ]</li>
<li>UTI tables now use DB_PREFIX</li>
</ul>
<p style="text-align: justify;">You can download it from: <a title="Current version of UTI" href="http://www.data-diggers.com/contribs/uti/downloads/uti-v1.1.zip">UTI v1.1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2010/03/user-tracking-interface-v1-1/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>[Solved] FireFox doesn&#8217;t save cookies &#8211; sort of&#8230;</title>
		<link>http://www.data-diggers.com/index.php/2009/12/solved-firefox-doesnt-save-cookies-sort-of/</link>
		<comments>http://www.data-diggers.com/index.php/2009/12/solved-firefox-doesnt-save-cookies-sort-of/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 11:06:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=198</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F12%2Fsolved-firefox-doesnt-save-cookies-sort-of%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F12%2Fsolved-firefox-doesnt-save-cookies-sort-of%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">Funny thing (and <span style="text-decoration: underline;">very</span> annoying) &#8211; my FireFox 3.5.5 doesn&#8217;t save cookies anymore. It saves cookies until browser is running, but after I close it and open it again only those cookies that are meant to be save until &#8216;end of session&#8217; are preserved. My cookie policy is ok ( cookies are stored until they expire ), cache isn&#8217;t cleared after I close FireFox and there are no sites on &#8216;Exceptions&#8217; list. Clearing cache &amp; purging cookies does not help at all.</p>
<p style="text-align: justify;"><strong>Update:</strong> I finally found solution &#8211; just delete<em> cookies.sqlite</em> and <em>cookies.sqlite-journal</em> from %<span>USERPROFILE</span>%\AppData\Roaming\Mozilla\FireFox\Profiles directory.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2009/12/solved-firefox-doesnt-save-cookies-sort-of/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Query Cache v1.7 will be released soon</title>
		<link>http://www.data-diggers.com/index.php/2009/12/query-cache-v1-7-will-be-released-soon/</link>
		<comments>http://www.data-diggers.com/index.php/2009/12/query-cache-v1-7-will-be-released-soon/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 09:45:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=194</guid>
		<description><![CDATA[ ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F12%2Fquery-cache-v1-7-will-be-released-soon%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F12%2Fquery-cache-v1-7-will-be-released-soon%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">After long break new version of <strong>Query Cache</strong> for Zen Cart will be released in next week/two weeks. Few of You reported some &#8216;Out of memory&#8217; errors that could be avoided so new version of QC will focus on memory consumption.  I&#8217;m not sure if performance per single http request is going to improve by using less memory &#8211; probably it will but possibly not significantly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2009/12/query-cache-v1-7-will-be-released-soon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

