<?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/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>Ovalpixels Blog about Web-Building &#187; CakePHP</title>
	<atom:link href="http://www.ovalpixels.com/blog/tag/cakephp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ovalpixels.com/blog</link>
	<description>Tips &#38; Tricks on Web Design and Development</description>
	<lastBuildDate>Fri, 28 Jan 2011 09:17:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CakePHP Migrations without PEAR</title>
		<link>http://www.ovalpixels.com/blog/2008/11/17/cakephp-migrations-without-pear/</link>
		<comments>http://www.ovalpixels.com/blog/2008/11/17/cakephp-migrations-without-pear/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 21:19:31 +0000</pubDate>
		<dc:creator>georgi</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Bakery Joel Moss]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Chris Wanstrath]]></category>
		<category><![CDATA[installed applications]]></category>
		<category><![CDATA[Joel Moss]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.ovalpixels.com/blog/?p=67</guid>
		<description><![CDATA[Rails fans out there? It is no secret that CakePHP was born to implement the ideas of Ruby on Rails to the world of PHP &#8211; wonderful ideas, indeed, and I think we should pay tribute to the guys at 37signals. But what CakePHP still lacks, in my opinion, is pure and complete DB abstraction. [...]]]></description>
			<content:encoded><![CDATA[<h3>Rails fans out there?</h3>
<p>It is no secret that CakePHP was born to implement the ideas of Ruby on Rails to the world of PHP &#8211; wonderful ideas, indeed, and I think we should pay tribute to the guys at 37signals.</p>
<p>But what CakePHP still lacks, in my opinion, is pure and complete DB abstraction. It is true that most recent versions of Cake ( v.2 RC3 as of now ) have done a lot in that area &#8211; the framework is now strongly decoupled from MySQL, although I personally have never heard of study cases that use Oracle, for example.</p>
<p>To the point &#8211; in a multi-developer environment it is critical to have a versioning control system ( you know you should be using <a  href="http://git.or.cz" target="_blank">git</a>, right? ) and a database &#8216;versioning&#8217; system &#8211; that is where Rails is much more powerful than CakePHP &#8211; it has <strong>database migrations</strong>.<span id="more-67"></span></p>
<h3>Some migrations&#8217; background</h3>
<p>If you know what migrations are &#8211; skip that part and go directly to the next one. Otherwise &#8211; here is a simple explanation: they are related to the database like git ( or svn or cvs ) is related to the source. They simple provide a way to go back or forth to a previous or succeeding state ( or version ) of the database schema. The features of migrations are:</p>
<ul>
<li>They are DB agnostic &#8211; this means that they are not affected by the type of the DB server you&#8217;re using and help you in deploying your apps on different environments</li>
<li>They help you with your agile development &#8211; you can put info in and out without affecting the rest of the project</li>
<li>They provide you with a quick way to revert back to a previous state of the DB in case something went wrong</li>
<li>DB migrations can save your life if you work in a team</li>
</ul>
<p>To illustrate the all said, I have a simple example: You create a blog ( of course a blog &#8211; that&#8217;s probably the most often used example in the world ). Let&#8217;s split the development into three simple parts &#8211; development of blog posts CRUD; adding ACL; adding Comments to posts and.. that&#8217;s it &#8211; we want a simple example, after all.</p>
<p>So, first &#8211; blog posts Create, Read, Update, Delete. You begin by creating your DB schema. You need a simple posts&#8217; table with a few fields &#8211; id, title, body, created. Then you write your PHP code, of course ( out of scope here ).</p>
<p>But one beautiful day you decide more than one person should be able to add posts and modify their own posts only &#8211; that&#8217;s when you read about Access Control Lists. Now you need a few more tables &#8211; users, aros, acos, acl and you need to add a field to the posts&#8217; table ( user_id, for example ). Our small blog is getting just a bit more complex.</p>
<p>Finally, you want comments! But you have no time and ask your cousin for a favor ( he is a good dev, after all ). He adds another table for that. And then decides only registered users ( who cannot write new posts ) can add comments. And, of course, writes some more code. And inserts some more data in the db.</p>
<p>You ( and your cousin ) have went through 3 distinctive phases of agile development. You have, of course, used git ( oh, well, maybe svn or cvs ) to keep track of your code and make sure everything is ok and that you can revert back to a previous, stable version, if anything goes wrong. But then, one day &#8211; something really goes wrong. And you need to revert from state 3 to state 2 &#8211; i.e. remove the comments. But &#8230; your cousin is</p>
<ul>
<li> out of town</li>
<li>mad at you because you behaved badly on his last birthday party</li>
<li>has no idea what he did for you so many months ago</li>
</ul>
<p>No problem &#8211; you use your source versioning system and do the reversal. But.. something is still wrong &#8211; your database stays unchanged. What did you add from v2 to v3? Did you remove something? And you know nothing about Database Server X &#8211; can you write the SQLs to revert the schema?</p>
<p>That is where DB migrations come in and save your life. Well, maybe not that important with your blog but imagine 100+ development iterations and 10+ developers working simultaneously on your project and maintaining it on many different platforms &#8211; this can turn into a <em>small</em> nightmare.</p>
<h3>Joel Moss and his migrations</h3>
<p>In his <a  href="http://bakery.cakephp.org/articles/view/cake-db-migrations-v2-1">article</a> at the Bakery Joel Moss describes how to use his CakePHP migrations shell. Although that project was my inspiration and I highly respect his work, his approach has several drawbacks:</p>
<ul>
<li>it uses PEAR &#8211; I don&#8217;t like it &#8211; that&#8217;s why I use CakePHP. I do not find necessary to explain this &#8211; I guess it is highly subjective.</li>
<li>it is non-modular &#8211; you cannot use it to deploy applications &#8211; it is just a shell with no &#8216;core&#8217;</li>
<li>it cannot make a snapshot of your already existing schema &#8211; you haven&#8217;t used migrations yet? That&#8217;s something you will need.</li>
<li>it cannot merge your tables &#8211; that can be crucial when you already have different versions of the schema on different platforms and you just want them all to be standardized</li>
</ul>
<p>So, I proudly present you with</p>
<h3>My CakePHP Yaml Migrations and Fixtures</h3>
<p>The idea was born when <a  href="http://pagebakers.nl" target="_blank">Eelco</a> and I started working on PagebakeryCMS some time ago and was later further developed when we decided we needed a standardized CakePHP App Installer. You can get a <a  href="http://github.com/georgious/cakephp-yaml-migrations-and-fixtures" target="_blank">copy</a> of the project and follow it, too. What I personally find useful in it:</p>
<ul>
<li>no external libraries &#8211; only the SPYC class used to parse YAML files ( that is authored by Chris Wanstrath )</li>
<li>can easily complement your source versioning system &#8211; use it for team collaboration</li>
<li>can be used for DB abstraction installers &#8211; when deploying your applications on different platforms you don&#8217;t want to modify your SQLs &#8211; and the project is DB agnostic. The package also has fixtures ( well, the terms is not used correctly &#8211; this is for adding initial data to your database )</li>
<li>can be used to standardize already installed applications on different platforms</li>
<li>can help you make your apps DB agnostic by generating a YAML structure of your schema from where you can go on with the agnostic aproach</li>
</ul>
<h4>How it works</h4>
<p>Just put all files in your CakePHP vendors folder.</p>
<p>If you want to use the API only, simply include the classes in your code</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">App<span style="color: #339933;">::</span><span style="color: #004000;">Import</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'vendor'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'migrations'</span> <span style="color: #009900;">&#41;</span></pre></div></div>

<p>and/or</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">App<span style="color: #339933;">::</span><span style="color: #004000;">Import</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'vendor'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'fixtures'</span> <span style="color: #009900;">&#41;</span></pre></div></div>

<p>And then, for example</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$migrations</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Migrations<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$migrations</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>load<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comments.yml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$migrations</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>up<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>For more usages &#8211; dig into the code a bit <img src='http://www.ovalpixels.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.ovalpixels.com/blog/2008/11/17/cakephp-migrations-without-pear/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Highly responsive ajax applications without excess requests and bandwidth waste?</title>
		<link>http://www.ovalpixels.com/blog/2008/11/15/highly-responsive-ajax-applications-without-excess-bandwidth-waste/</link>
		<comments>http://www.ovalpixels.com/blog/2008/11/15/highly-responsive-ajax-applications-without-excess-bandwidth-waste/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 00:42:17 +0000</pubDate>
		<dc:creator>georgi</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Pagebaker]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[real time]]></category>
		<category><![CDATA[responsive ajax applications]]></category>

		<guid isPermaLink="false">http://www.ovalpixels.com/blog/?p=3</guid>
		<description><![CDATA[Ajax is not as powerful as one would imagine If you have ever tried to develop a robust ajax application, you have probably reached a point where you want the client to be notified about a change on the server in &#8220;real time&#8221;. The most simple example &#8211; you need to create a chat application [...]]]></description>
			<content:encoded><![CDATA[<h3>Ajax is not as powerful as one would imagine</h3>
<p>If you have ever tried to develop a robust ajax application, you have probably reached a point where you want the client to be notified about a change on the server in &#8220;real time&#8221;. The most simple example &#8211; you need to create a chat application and want the client to instantly receive new messages upon their arrival on the server. And, if you like me, are not a fan of Flash ( which may be one of your major flaws ) and want to achieve this using only ajax techniques, you have found out that is not that simple. <span id="more-3"></span></p>
<h3>There is no real channel between the server and the client</h3>
<p>In that case you have no real permament connection between the server and the client and there is no real way of &#8220;triggering&#8221; events or sending data from the server to the client in any traditional way. Moreover, ajax does not support the client &#8220;listening&#8221; and waiting for a server&#8217;s call ( well, that&#8217;s a client after all ). You googled for some time, asked some fellow developers and almost all you could find was &#8211; &#8220;Just use javascript&#8217;s (notorious) setTimeout() or setInterval() function to repeatedly poll the server and check whether there is new data for the client&#8221;.</p>
<p>Like, for example ( using jQuery ) :</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> read<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  jQuery.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">'url'</span>     <span style="color: #339933;">:</span> <span style="color: #3366CC;">'chat/read/'</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">'cache'</span>   <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">'dataType'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'json'</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">'success'</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>messages<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">//if there are new messages - write them on the wall</span>
      <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> messages <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #006600; font-style: italic;">//write messages to the chat wall</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
setTimeout<span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> read<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2000</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>( I will not show any server-side code examples as they are simple enough &#8211; the method being /chat/read/ would just read from the database and return new records. Moreover, what we have here <strong>is not</strong> what we&#8217;re trying to achieve &#8211; the example here is for descriptive purposes only. )</p>
<p>Is that what we call highly-responsive, flexible applications, you&#8217;d ask? No. This technique has several drawbacks:</p>
<ul>
<li>it sends http requests from the client to the server and gets response ( most of the time empty ones ) on every X number of seconds. X usually is a far too small number and that can translate into way too much wasted bandwidth, if we are talking about a high-traffic website and if we need that polling done for multiple actions</li>
<li>it can eventually make the client hang-up as most modern browsers ( except for Chrome &#8211; or at least &#8211; what Chrome pleads ) don&#8217;t have smart javascript garbage collection and all those requests can be quite costly.</li>
<li>it is not really highly-responsive &#8211; it has a lag of 2 seconds which may be enough to make the users nervous</li>
<li>this just doesn&#8217;t feel like the right way of doing things</li>
</ul>
<h3>Comet</h3>
<p>Well, I need to be honest &#8211; the <a  title="Comet" href="http://en.wikipedia.org/wiki/Comet_(programming)" target="_blank">Comet</a> technique ( also known as <strong>long-polling</strong> ) seems like nothing new but I personally was not aware of it&#8217;s power till recently ( <a  href="http://pagebakers.nl">Eelco</a> pointed it to me ). But you will be amazed how many open- and closed-source projects have no idea that it is out there and do not try to use it. And it is simple &#8211; you make a request to the server, it gets it and just&#8230; <em>waits</em>. Waits till there is meaningful data to be returned or returns something less useful ( like null ), if the request is about to timeout. On a standard apache configuration that would mean 5 minutes &#8211; <strong>you can make just one single request on every 5 minutes</strong>, not on every 2 seconds ( which a traditional ajax app would do ). That is 150+ times less requests, less bandwidth, less javascript functions&#8217; calls and the application would feel <strong>much more responsive</strong>.</p>
<p>There is, however, a small side note to mention&#8230;</p>
<h3>PHP Sessions are not keen on long-polling</h3>
<p>And, if you hadn&#8217;t read this post, you&#8217;d have had some hard time finding this out. It is just that in every normal application, you can be 97% sure you will be using sessions. And in most of the time, you will rely on the built-in php sessions&#8217; handler. So far, so good. But the small problem is that you cannot simultaneously be running different scripts ( or more than one instantiation of a script ) which use one and the same user session ( that, again, was a discovery by <a  href="http://pagebakers.nl">Mr. Pagebaker</a> ). PHP will just queue all subsequent requests which try to interact with that session, until the first one has been closed. Well, that is not much of an <em>asynchroneous</em> technique either then. Getting back to our chat application &#8211; if you want to long-poll the server and wait for new messages ( what we will call read() ) and simultaneously send new messages to the server ( write() ), the application will not write() until the read() request has finished ( which we have set to 5 mins, if in the worst case there is no new data to be received ) &#8211; that is absolutely not what we need.</p>
<h3>Frameworks to the rescue</h3>
<p>But, as all self-respectful developers, you have adopted a php framework which provides an alternative to the native php sessions&#8217; handler &#8211; be it file, database or any other geeky approach. I&#8217;d prefer CakePHP where it is simple &#8211; just open your /app/config/core.php and find</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">Configure<span style="color: #339933;">::</span><span style="color: #004000;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Session.save'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>change that to</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">Configure<span style="color: #339933;">::</span><span style="color: #004000;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Session.save'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'database'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>and uncomment the few lines below that line with respective data.</p>
<p>So, now let&#8217;s see what we have:</p>
<p>Our client-side script ( jQuery again ):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> read<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  jQuery.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">'url'</span>     <span style="color: #339933;">:</span> <span style="color: #3366CC;">'/chat/read/'</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">'cache'</span>   <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">'dataType'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'json'</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">'success'</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>messages<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> messages.<span style="color: #660066;">length</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #006600; font-style: italic;">//write to chat wall</span>
      <span style="color: #009900;">&#125;</span>
      read<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It is important to notice that even though I have not shown the write() function, you should use <a  href="http://plugins.jquery.com/project/ajaxqueue">jQuery&#8217;s Ajax Queue Plugin</a>, so that our write requests are kept in good order. That is not needed when we read() as no subsequent read() requests will be fired before the first one has ended.</p>
<p>And, our cakephp chat controller method:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> read<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$lastMessage_id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Session<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>read<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Conversation.lastMessage_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$lastMessage_id</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Json<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>encode<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Session<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>write<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Conversation.lastMessage_id'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000088;">$now</span> <span style="color: #339933;">=</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$timeout</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">300</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">connection_aborted</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$messages</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Conversation<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>read<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$lastMessage_id</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$messages</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Session<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>write<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Conversation.lastMessage_id'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$messages</span><span style="color: #009900;">&#91;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$messages</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Message'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Json<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>encode<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$messages</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #000088;">$now</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$timeout</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Json<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>еncode<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #990000;">sleep</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In short &#8211; we get the last message id from the user session then use it to fetch newer records from the model. If there are none and the user hasn&#8217;t left our webpage, we start looking for new messages once again and so on. We also keep track on the time we have spent so far in that iteration &#8211; we don&#8217;t want an ugly timeout, that is why we just send an empty response, if we have reached a critical level ( $timeout = 300 in that case ).</p>
<p>For simplicity, I do not use views in that example but it is highly recommended that you avoid using the JSON component and use views instead ( who knows, you might need a different format in the future ).</p>
<p>Notice the sleep(1) line &#8211; we don&#8217;t want our CPU to burn out after a few hours of work, so some time for rest is highly recommended. You may, of course, use smaller intervals but at your own risk.</p>
<p>That is it for now &#8211; feel free to comment and thanks for reading <img src='http://www.ovalpixels.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.ovalpixels.com/blog/2008/11/15/highly-responsive-ajax-applications-without-excess-bandwidth-waste/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

