<?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; Utils</title>
	<atom:link href="http://www.data-diggers.com/index.php/tag/utils/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>UTI v1.5 released</title>
		<link>http://www.data-diggers.com/index.php/2010/10/uti-v1-5-released/</link>
		<comments>http://www.data-diggers.com/index.php/2010/10/uti-v1-5-released/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 20:44:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[UTI]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[User Tracking Interface]]></category>

		<guid isPermaLink="false">http://www.data-diggers.com/?p=315</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-v1-5-released%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F10%2Futi-v1-5-released%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">New version of User Tracking Interface (1.5) has been released.  Changes:</p>
<ul style="text-align: justify;">
<li>performance improvements</li>
<li>uti table size improvements</li>
<li>IP is stored as INT, not as VARCHAR(15)</li>
<li>few minor bug fixes</li>
<li>support for uti merge functions ( I&#8217;m going to write about this feature within few days)</li>
</ul>
<p style="text-align: justify;">UTI v1.5 has been tested with Zen Cart 1.3.8a but it should also work with newer versions. Update instructions for v1.1 users are included in .zip package.</p>
<p style="text-align: center;"><a href="http://www.data-diggers.com/contribs/uti/downloads/uti-v1.5.zip">Download UTI v1.5.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2010/10/uti-v1-5-released/feed/</wfw:commentRss>
		<slash:comments>1</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>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>Bug in User Tracking Interface 1.0</title>
		<link>http://www.data-diggers.com/index.php/2010/03/bug-in-user-tracking-interface-1-0/</link>
		<comments>http://www.data-diggers.com/index.php/2010/03/bug-in-user-tracking-interface-1-0/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 19:28:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<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=209</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%2Fbug-in-user-tracking-interface-1-0%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2010%2F03%2Fbug-in-user-tracking-interface-1-0%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">It seems that I&#8217;ve forgotten to add installation commands to the sql installation file and there are no options under &#8216;UTI Variables&#8217; in Configuration Menu. To Go to Admin-&gt;Tools-&gt;Install SQL patches and execute following commands:</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;"><span class="kw1">SELECT</span> <span class="br0">&#40;</span>@group_id:<span class="sy0">=</span>configuration_group_id<span class="br0">&#41;</span> <span class="kw1">FROM</span> configuration_group <span class="kw1">WHERE</span> configuration_group_title <span class="kw1">LIKE</span> <span class="st0">&#8216;UTI Variables&#8217;</span>;<br />
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> configuration <span class="br0">&#40;</span>configuration_title<span class="sy0">,</span> configuration_key<span class="sy0">,</span> configuration_value<span class="sy0">,</span> configuration_description<span class="sy0">,</span> configuration_group_id<span class="sy0">,</span> sort_order<span class="br0">&#41;</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span><span class="st0">&#8216;[Recent Products] Max recent products to show&#8217;</span><span class="sy0">,</span> <span class="st0">&#8216;UTI_RECENT_PRODUCTS_MAX&#8217;</span><span class="sy0">,</span> <span class="st0">&#8217;5&#8242;</span><span class="sy0">,</span> <span class="st0">&#8216;How many recent products should be displayed in sidebox?&#8217;</span><span class="sy0">,</span> @group_id<span class="sy0">,</span> 1<span class="br0">&#41;</span>;<br />
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> configuration <span class="br0">&#40;</span>configuration_title<span class="sy0">,</span> configuration_key<span class="sy0">,</span> configuration_value<span class="sy0">,</span> configuration_description<span class="sy0">,</span> configuration_group_id<span class="sy0">,</span> sort_order<span class="br0">&#41;</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span><span class="st0">&#8216;[Recent Searches] Max recent searches to show&#8217;</span><span class="sy0">,</span> <span class="st0">&#8216;UTI_RECENT_SEARCHES_MAX&#8217;</span><span class="sy0">,</span> <span class="st0">&#8217;5&#8242;</span><span class="sy0">,</span> <span class="st0">&#8216;How many recent search results should be displayed in sidebox?&#8217;</span><span class="sy0">,</span>@group_id<span class="sy0">,</span> 2<span class="br0">&#41;</span>;</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2010/03/bug-in-user-tracking-interface-1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Randomized Tests version 1.3</title>
		<link>http://www.data-diggers.com/index.php/2009/11/randomized-tests-version-1-3/</link>
		<comments>http://www.data-diggers.com/index.php/2009/11/randomized-tests-version-1-3/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 10:05:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[A/B Split Tests]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[Zen Cart]]></category>

		<guid isPermaLink="false">http://www.data-diggers.eu/?p=77</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%2F11%2Frandomized-tests-version-1-3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F11%2Frandomized-tests-version-1-3%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">Randomized tests version 1.3 is here (<a href="http://www.data-diggers.com/contribs/rt/downloads/rt.zip">download</a>). This release brings quite few new features that should be very helpful. I added 95% trust intervals for each statistic. There&#8217;s also probability that given experiment will beat control group. You can now also decide when impression occurs. Read below for more.</p>
<h2 style="text-align: justify;">Installation</h2>
<p style="text-align: justify;">Refer to <em>INSTALL.txt</em> in .zip file.</p>
<p style="text-align: center;"><strong><span style="text-decoration: underline;">If You already have RT installed refer to<em> INSTALL.txt</em> file for UPGRADE instructions.</span></strong></p>
<h2 style="text-align: justify;">Trust intervals</h2>
<p style="text-align: justify;">Randomized Tests provides few estimates:</p>
<ul style="text-align: justify;">
<li>order conversion rate</li>
<li>visitor to customer conversion rate</li>
<li>total items bought</li>
<li>total order value</li>
</ul>
<p style="text-align: justify;">You have to remember that RT presents only estimated values &#8211; for example after tracking ten orders RT might calculate that order conversion rate is 0.9%, but You&#8217;re almost sure (because You know that from earlier experiments) that Your conversion rate is 1.1%. Unfortunately RT can&#8217;t do much better since it hasn&#8217;t collected enough data yet. In new version RT will however present also 95% chance intervals for each estimated value. So now instead of conversion rate 0.9% You&#8217;ll see 0.9% +/- 0.2% which means that there&#8217;s 95% chance that true conversion rate is between 1.1% and 0.7%.</p>
<h2 style="text-align: justify;">Chance to beat Control Group</h2>
<p style="text-align: justify;">Previous versions of RT leaved to You decision if changes You made were actually useful. In version 1.3 RT will give You probability that those changes outpeform original version of Your Zen Cart store. RT displays now &#8216;Chance to Beat Original&#8217; value. This value should be around 95% or 5% before You decide that new version perform better/worse then original version of Your store.</p>
<h2 style="text-align: justify;">Custom impression detection functions</h2>
<p style="text-align: justify;">This new feature lets You decide if and when to include particular visitor in experiment. You might want for example test performance of Your new customer registration form and include in experiment only those visitors who actually visited customer registration form. Thanks to that You&#8217;ll get more accurate results very quickly.</p>
<p style="text-align: justify;">There will be separate post about this new feature &#8211; so stay tuned <img src='http://www.data-diggers.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2 style="text-align: justify;">Download</h2>
<p style="text-align: justify;">You can download latests release of RT here:</p>
<p style="text-align: center;"><a href="http://www.data-diggers.com/contribs/rt/downloads/rt.zip">www.data-diggers.com/contribs/rt/downloads/rt.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2009/11/randomized-tests-version-1-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New feature in upcoming version of Randomized Tests</title>
		<link>http://www.data-diggers.com/index.php/2009/10/new-feature-in-upcoming-version-of-randomized-tests/</link>
		<comments>http://www.data-diggers.com/index.php/2009/10/new-feature-in-upcoming-version-of-randomized-tests/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 20:14:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[A/B Split Tests]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[Zen Cart]]></category>

		<guid isPermaLink="false">http://www.data-diggers.eu/?p=75</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%2F10%2Fnew-feature-in-upcoming-version-of-randomized-tests%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F10%2Fnew-feature-in-upcoming-version-of-randomized-tests%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">Yeah, I&#8217;m not dead. I don&#8217;t have much time but I still work on my modules. I spent most time on Randomized Tests module &#8211; sorry to all people counting on new Query Cache version <img src='http://www.data-diggers.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . In upcoming release of Randomized Tests You&#8217;ll be able to:</p>
<ul style="text-align: justify;">
<li>decide whether or not impression occurred (and when it happened). For example, You want to count in experiment only visitors that viewed &#8216;login&#8217; page. Now You can <img src='http://www.data-diggers.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>get more accurate results. Experiment stats view in Admin area will give You probability that given test group will beat control group. All stats will be also presented with 95% probability range. For example visitor/customer conversion ratio will be presented as: 1% +/- 0.02% which mean that conversion ratio is in [0.98%, 1.02%] with 95% probability.</li>
<li>maybe more&#8230; for example support for Your own statistics (like &#8216;search form usage stats&#8217;, &#8216;contact us page stats&#8217; etc).</li>
</ul>
<p style="text-align: justify;">Would You like to see more features in next version? Let me know through comments / mail.</p>
<p style="text-align: justify;">Sorry, multivariate testing will probably not be included in upcoming version. I&#8217;ll add support for it most probably in next next version.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2009/10/new-feature-in-upcoming-version-of-randomized-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Randomized Tests V1.2 for Zen Cart Released</title>
		<link>http://www.data-diggers.com/index.php/2009/07/randomized-tests-v1-2-for-zen-cart-released/</link>
		<comments>http://www.data-diggers.com/index.php/2009/07/randomized-tests-v1-2-for-zen-cart-released/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 12:08:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[A/B Split Tests]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[Zen Cart]]></category>

		<guid isPermaLink="false">http://www.data-diggers.eu/?p=73</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%2F07%2Frandomized-tests-v1-2-for-zen-cart-released%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F07%2Frandomized-tests-v1-2-for-zen-cart-released%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">New version of <strong>Randomized Tests for Zen Cart</strong> is available. New version introduces few bug fixes and one very important feature &#8211; orders filters and customer filter. Order/Customer filters can be used to dynamically remove (not permanently) from statistics certain customers/orders and recalculate statistics without them. Why is it important?</p>
<p style="text-align: justify;">Let&#8217;s assume that You have store with many customers. You use <strong>Randomized Tests</strong> to check how new layout affects sales. Unfortunately after You run Your experiment for few days You notice that one group is biased because it includes one or two top buyers. Those two buyers are different from regular customer &#8211; they buy a lot of items, place orders every few days and probably aren&#8217;t affected by new layout &#8211; they already know Your store and don&#8217;t care about it as long as they can place orders.</p>
<p style="text-align: justify;">Group containing these customers is biased since it includes data outliers. You probably would like to remove them from statistics. New version of <strong>Randomized Tests</strong> can do that using filter functions. Currently there are two types of filter functions:</p>
<ul style="text-align: justify;">
<li><strong>order filter functions</strong> &#8211; executed for each order in group &#8211; allows removal certain orders from statistics.</li>
<li><strong>customer filter functions</strong> &#8211; executed for each customer in group. Orders from rejected customers will not included in statistics.</li>
</ul>
<p style="text-align: justify;">Randomized Tests V1.2 contain two sample filter functions:</p>
<ul style="text-align: justify;">
<li><em><strong>ddigers_2std_customer_total_rt_cff()</strong></em> &#8211; removes top buyers (formally &#8211; customers with total spent in 2+ standard deviation from average) from statistics.</li>
<li><em><strong>ddigers_2std_order_total_rt_off()</strong></em> &#8211; removes super big orders from statistics.</li>
</ul>
<p style="text-align: justify;">To check how they&#8217;re implemented view <strong><em>admin/includes/functions/extra_functions/randomized_tests.php</em></strong></p>
<p style="text-align: justify;">You can implement Your own functions by following below pattern.</p>
<h2 style="text-align: justify;"><strong>Custom Customer Filter Functions</strong></h2>
<p style="text-align: justify;">Randomized Tests will recognize any function with name ending with &#8220;_rt_cff&#8221; as customer filter function and allow You to use it. For example following function will be recognized as filter:</p>
<div style="text-align: justify;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">function</span> customer_filter_rt_cff<span class="br0">&#40;</span><span class="re0">$customer_id</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">$cid</span> <span class="sy0">==</span> 12345<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="kw1">else</span> <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 />
<span class="br0">&#125;</span></div>
</div>
</div>
<p style="text-align: justify;">Randomized Tests passes to customer filter functions single attribute &#8211; id of customer in database. If function returns <em><strong>TRUE </strong></em>customer is accepted in calculation of statistics, and is rejected otherwise.</p>
<h2 style="text-align: justify;"><strong>Order Filter Functions</strong></h2>
<p style="text-align: justify;">Order filter functions are similar to customer filter functions &#8211; any function with name ending with &#8220;_rt_off&#8221; will be recognized as order filter function. Example filter function:</p>
<div style="text-align: justify;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">function</span> order_filter_rt_off<span class="br0">&#40;</span><span class="re0">$eid</span><span class="sy0">,</span> <span class="re0">$gid</span><span class="sy0">,</span> <span class="re0">$cid</span><span class="sy0">,</span> <span class="re0">$oid</span><span class="sy0">,</span> <span class="re0">$itemsBought</span><span class="sy0">,</span> <span class="re0">$ordersTotal</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">$orderTotal</span> <span class="sy0">&gt;</span> 1000<span class="sy0">.</span>0<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="kw1">else</span> <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 />
<span class="br0">&#125;</span></div>
</div>
</div>
<p style="text-align: justify;">Randomized Tests passes few more parameters to order filter functions:</p>
<ul style="text-align: justify;">
<li><strong>$eid</strong> &#8211; experiment row id in database</li>
<li><strong>$gid</strong> &#8211; group row id in database</li>
<li><strong>$cid</strong> &#8211; customer id in database</li>
<li><strong>$oid</strong> &#8211; order id in database</li>
<li><strong>$itemsBought</strong> &#8211; number of items in order</li>
<li><strong>$totalValue</strong> &#8211; total value of order</li>
</ul>
<p style="text-align: justify;">As with customer filter functions order filter functions should return <em><strong>TRUE </strong></em>to accept order in statistics and <em><strong>FALSE </strong></em>to reject it.</p>
<h2 style="text-align: justify;">Making Filter Functions Visible to Randomized Tests Module</h2>
<p style="text-align: justify;">Let&#8217;s assume that You&#8217;ve placed Your custom filter functions in <em><strong>admin/includes/functions/extra_functions/my_custom_filters.php</strong></em> file. The best way to make them visible to RandomizedTests is to include the file through autoloaders interface. Create <em>config.filters.php</em> file in <em><strong>admin/includes/auto_loaders/</strong></em> and paste there:</p>
<div style="text-align: justify;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$autoLoadConfig</span><span class="br0">&#91;</span>180<span class="br0">&#93;</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">&#8216;autoType&#8217;</span><span class="sy0">=&amp;</span>gt<span class="sy0">;</span><span class="st_h">&#8216;require&#8217;</span><span class="sy0">,</span><br />
<span class="st_h">&#8216;loadFile&#8217;</span><span class="sy0">=&amp;</span>gt<span class="sy0">;</span> DIR_FS_CATALOG <span class="sy0">.</span> DIR_WS_FUNCTIONS <span class="sy0">.</span> <span class="st_h">&#8216;extra_functions/my_custom_filters.php&#8217;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
</div>
<p style="text-align: justify;">That&#8217;s it &#8211; Randomized Tests module will now be able to use Your filters.</p>
<h2 style="text-align: justify;">Screenshot</h2>
<p style="text-align: justify;">Here&#8217;s screenshot of experiment with applied filters:</p>
<p style="text-align: center;"><a rel="lightbox" href="http://www.data-diggers.com/contribs/rt/images/experiment_stats_demo.jpg" rel="prettyPhoto"> <img src="http://www.data-diggers.com/contribs/rt/images/experiment_stats_demo.jpg" alt="" width="500" height="109" /> </a></p>
<h2 style="text-align: justify;">Download</h2>
<p style="text-align: justify;">You can download current version of Randomized Tests <a href="http://www.data-diggers.com/contribs/rt/downloads/rt.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2009/07/randomized-tests-v1-2-for-zen-cart-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Randomized Tests v1.0 Released</title>
		<link>http://www.data-diggers.com/index.php/2009/07/randomized-tests-v1-0-released/</link>
		<comments>http://www.data-diggers.com/index.php/2009/07/randomized-tests-v1-0-released/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 13:38:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[A/B Split Tests]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[UTI]]></category>
		<category><![CDATA[Zen Cart]]></category>

		<guid isPermaLink="false">http://www.data-diggers.eu/?p=71</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%2F07%2Frandomized-tests-v1-0-released%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F07%2Frandomized-tests-v1-0-released%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;">This module allows You to perform experiments on Your website. You can test for example how Your new &#8216;Add to Cart&#8217; button performs compared to old one.</p>
<p style="text-align: justify;">I don&#8217;t have much time to write long post, so I&#8217;ll cut it to most important things. You can <a href="http://www.data-diggers.com/contribs/rt/downloads/rt.zip">download the module here</a>. This module requires UTI to work properly (<a href="http://www.data-diggers.com/content/user-tracking-interface-v10-released">download it here</a> ). Installation instructions are in .zip file. Here&#8217;s how You can use it.</p>
<p style="text-align: justify;">To create experiment follow these steps:</p>
<ol style="text-align: justify;">
<li>Go to Admin-&gt;Tools-&gt;[RT] Groupsets.</li>
<li>Create groupset (it&#8217;s set of groups). Call it &#8216;Basic Test Groupset&#8217;.</li>
<li>Click on Basic Test Groupset &#8211; You will be forwarded to page where You can edit it.</li>
<li>Each groupset must have EXACTLY one control group. I usually call it &#8216;Control Group&#8217;. Create two groups (you can create as many groups in groupset as You want, but for simplicity We use 2 now):</li>
<li>Control Group &#8211; with id &#8216;cg&#8217; (as ControlGroup). Check &#8216;control group&#8217; checkbox</li>
<li>Test Group &#8211; with id &#8216;tg&#8217;. DO NOT check &#8216;control group&#8217; checkbox.</li>
<li>Go to Admin-&gt;Tools-&gt;[RT] Experiments.</li>
<li>Create Experiment &#8216;Exp #1&#8242; using groupset &#8216;Basic Test Groupset&#8217;.</li>
</ol>
<p style="text-align: justify;">Click on Exp #1 &#8211; You will be forwarded to its stats:</p>
<ul style="text-align: justify;">
<li><strong>Impressions </strong>- in this version of Randomized Tests its simply number of visitors in each group</li>
<li><strong>Customers Registered</strong> &#8211; (visitor to customer conversion rate) / (change in regard to control group) / (total count of newly registered customers in this group)</li>
<li><strong>Orders Placed</strong> &#8211; (visitor to order conversion rate) / as above / (total number of orders visitors in this group placed)</li>
<li><strong>Items Bought</strong> &#8211; (avg. size of order) / as above / (total number of items bought)</li>
<li><strong>Orders Value</strong> &#8211; (avg. order value) / as above / (total orders value)</li>
</ul>
<p style="text-align: justify;">Ok, You&#8217;ve created experiment, now You have to create two versions of Your page. Let&#8217;s assume that You want to change &#8216;Add to Cart&#8217; button on product_info page. Edit <em><strong>includes/templates/your_template/templates/tpl_product_info_display.php</strong></em>.Find code responsible for displaying &#8216;Add to Cart&#8217; button &#8211; in my case it&#8217;s:</p>
<div style="text-align: justify;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw1">echo</span> <span class="re0">$display_button</span><span class="sy0">;</span></div>
</div>
</div>
<p style="text-align: justify;">Change it to:</p>
<div style="text-align: justify;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw1">if</span><span class="br0">&#40;</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 />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// visitor has been assigned to Test Group</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="re0">$display_my_new_button</span><span class="sy0">;</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">// user is in Control Group &#8211; We don&#8217;t change anything</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="re0">$display_button</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div>
</div>
</div>
<p style="text-align: justify;"><em><strong>$exp</strong></em> is global variable (it&#8217;s instance of <strong>ExperimentManager</strong> defined in <em>includes/classes/randomized_tests.php</em>) and holds basic information about experiment and group to which has been assigned current visitor<br />
<em><strong>$exp-&gt;groupID</strong></em> is &#8216;<strong>id</strong>&#8216; of group that You assigned in step 4. You can use it to detect in which group is current visitor and perform custom action.</p>
<p style="text-align: justify;">You&#8217;re done. Wait until experiment becomes statistically significant ( &gt;2000 visitors in each group, many orders ) and check results.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2009/07/randomized-tests-v1-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>User Tracking Interface v1.0 Released</title>
		<link>http://www.data-diggers.com/index.php/2009/07/user-tracking-interface-v1-0-released/</link>
		<comments>http://www.data-diggers.com/index.php/2009/07/user-tracking-interface-v1-0-released/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 21:07:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[UTI]]></category>
		<category><![CDATA[Utils]]></category>
		<category><![CDATA[User Tracking Interface]]></category>
		<category><![CDATA[Zen Cart]]></category>

		<guid isPermaLink="false">http://www.data-diggers.eu/?p=68</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%2F07%2Fuser-tracking-interface-v1-0-released%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.data-diggers.com%2Findex.php%2F2009%2F07%2Fuser-tracking-interface-v1-0-released%2F&amp;source=datadiggers&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p style="text-align: justify;"><strong>UTI </strong>is tiny module that tracks visitors to Zen Cart site even if they aren&#8217;t logged in or even never created any account. It allows developers to keep in UTI memory small amounts of information about each visitor. For example, <strong>UTI </strong>can be used to store list of recently viewed products by any particular user. <strong>UTI </strong>will remember this information and when the visitor will come back to Zen Cart store week later <strong>UTI </strong>will recognize him and present list of previously viewed products.</p>
<p style="text-align: justify;"><strong>UTI </strong>takes care of:</p>
<ul style="text-align: justify;">
<li>recognizing visitors &#8211; even if they never created any account</li>
<li>storing and retrieving information about them in database</li>
</ul>
<p style="text-align: justify;"><strong>UTI </strong>does not store any personal information in visitors browser.</p>
<h2 style="text-align: justify;">How to use UTI</h2>
<p style="text-align: justify;"><strong>UTI</strong> is very simple class. It creates global <em><strong>$uti </strong></em>object that contains all information about current visitor. From developer point of view <strong>UTI </strong>class has four methods:</p>
<ul style="text-align: justify;">
<li><em>$uti-&gt;set($name, $value) </em>- stores in database <em>$value</em> as value for attribute <em>$name</em></li>
<li><em>$uti-&gt;get($name)</em> &#8211; retrieves from database value for attribute<em> $name</em>. If there&#8217;s no such attribute<em> </em>method returns <em>FALSE</em>.</li>
<li><em>$uti-&gt;has($name)</em> &#8211; checks if current <strong>$uti</strong> object has attribute <em>$name</em> set</li>
<li><em>$uti-&gt;delete($name)</em> &#8211; deletes attribute.</li>
</ul>
<p style="text-align: justify;"><em><strong>$uti</strong></em> is automatically instantiated through <em>auto_loaders/ </em>mechanism. Developer can use it in any function/class since it&#8217;s global variable.</p>
<p style="text-align: justify;">To show how easy it is to use <strong>UTI </strong>and what it can be used for I&#8217;ve created simple contributions that:</p>
<ul style="text-align: justify;">
<li>records and displays in sidebox list of products visitor viewed recently.</li>
<li>records and displays in sidebox list of searches visitor performed recently.</li>
<li>records when visitor changes currency and saves it as his/hers default. When visitor comes back to Zen Cart contribution automatically switches currency to most recent one.</li>
</ul>
<p style="text-align: justify;">Example contributions are included in UTI package. You can download it here: <a href="http://www.data-diggers.com/contribs/uti/downloads/uti-current.zip">current version of UTI</a>.</p>
<p style="text-align: justify;">In next blog post I&#8217;ll describe how I&#8217;ve created one of those contributions using <strong>UTI</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.data-diggers.com/index.php/2009/07/user-tracking-interface-v1-0-released/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

