Rendering and not rendering


July 28, 2007
One of the most common questions I see on IRC is "How do I stop the view from displaying?". <br/> <br/>The controller has a handy little attribute <em>autoRender</em>, setting it to false will stop the view from being displayed. <br/> <br/>Also using the <em>render(...)</em> method automatically sets autoRender to false. This is handy if you want to another view aside from the default one for an action. <br/> <br/>Some example code: <br/><div class="code"><pre><span class="cp">&lt;?php</span> <span class="c">// in a controllers action</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">autoRender</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span> <span class="nf">header</span><span class="p">(</span><span class="s1">&#39;Content-type: application/pdf&#39;</span><span class="p">);</span> <span class="nf">readfile</span><span class="p">(</span><span class="s1">&#39;/path/tp/pdf_file&#39;</span><span class="p">);</span> <span class="c">// or say you want to render an element as a view. </span> <span class="c">// maybe you are using ajax</span> <span class="k">if</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">RequestHandler</span><span class="o">-&gt;</span><span class="na">isAjax</span><span class="p">())</span> <span class="p">{</span> <span class="c">// is a cake component</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">viewPath</span> <span class="o">=</span> <span class="s1">&#39;elements&#39;</span><span class="o">.</span><span class="nx">DS</span><span class="o">.</span><span class="s1">&#39;products&#39;</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">render</span><span class="p">(</span><span class="s1">&#39;product_table&#39;</span><span class="p">,</span> <span class="s1">&#39;ajax&#39;</span><span class="p">);</span> <span class="p">}</span> <span class="cp">?&gt;</span><span class="x"></span> </pre></div> <div style='display:none'>&lt;?php <br/> <br/>// in a controllers action <br/>$this-&gt;autoRender = false; <br/>header('Content-type: application/pdf'); <br/>readfile('/path/tp/pdf_file'); <br/> <br/>// or say you want to render an element as a view. <br/>// maybe you are using ajax <br/>if($this-&gt;RequestHandler-&gt;isAjax()) { // is a cake component <br/> $this-&gt;viewPath = 'elements'.DS.'products'; <br/> $this-&gt;render('product_table', 'ajax'); <br/>} <br/> <br/>?&gt;</div> <br/> <br/>Some links: <br/><a href="http://api.cakephp.org/1.2/class_controller.html#90046e6b62c91452a987c9573372c2ac">Controller::render</a> [api.cakephp.org] <br/><a href="http://api.cakephp.org/1.2/class_request_handler_component.html">RequestHandler</a> [api.cakephp.org] <br/> <br/>-rtconner
0 Comments >> Tags: CakePHP, PHP

Static Data Helper


July 27, 2007
<strong>Static Data in my Database?</strong> Why would I want to store data in the database that never changes? <br/> <br/><strong>First,</strong> with proper usage you can minimize the load on your database server by permanently caching the results of the queries. <br/><strong>Secondly,</strong> it becomes easy to JOIN to when you do need it. You never should need it though. <br/><strong>Third,</strong> it becomes very easy for you as a developer to get data from a single row or get a full list of data with which you can create a &lt;SELECT&gt; dropdown. <br/><strong>Fourth,</strong> It becomes exceedingling easy to say add a 51st state to your website. Just add a row to the table, and delete the cache. Perhaps adding an Order status at the request of a customer is a more common thing. <br/> <br/>A very simple to understand example of this is states. All you need to do is store all states in your database, and say you want to store where each user in your system lives. In the <em>Users</em> table create a <em>state_id</em> field. After you have installed the Helper, you can simply call <em>&lt;?= $static-&gt;status($User, 'name'); ?&gt;</em> to get the name of the state. This will not query your database, and will add zero extra load onto your database server. And notice how easy it was for you to write in code. <br/> <br/>Some real life usage examples <br/><div class="code"><pre><span class="x">&lt;!-- it&#39;s easy to make dropdown to choose a country --&gt;</span> <span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">input</span><span class="p">(</span><span class="s1">&#39;country_id&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;options&#39;</span> <span class="o">=&gt;</span> <span class="nv">$static</span><span class="o">-&gt;</span><span class="na">countries</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">)));</span> <span class="cp">?&gt;</span><span class="x"></span> <span class="x">&lt;!-- quickly get the description of the status with ID = 40 --&gt;</span> <span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nv">$static</span><span class="o">-&gt;</span><span class="na">status</span><span class="p">(</span><span class="m">40</span><span class="p">,</span> <span class="s1">&#39;desc&#39;</span><span class="p">);</span> <span class="cp">?&gt;</span><span class="x"></span> <span class="x">&lt;!-- dropdown of abbreviated states (NY, CA, etc) --&gt;</span> <span class="cp">&lt;?</span><span class="o">=</span> <span class="nv">$form</span><span class="o">-&gt;</span><span class="na">select</span><span class="p">(</span><span class="s1">&#39;user/state_id&#39;</span><span class="p">,</span> <span class="nv">$static</span><span class="o">-&gt;</span><span class="na">states</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="s1">&#39;abbrev&#39;</span><span class="p">),</span> <span class="nv">$user</span><span class="p">[</span><span class="s1">&#39;User&#39;</span><span class="p">][</span><span class="s1">&#39;state_id&#39;</span><span class="p">]);</span> <span class="cp">?&gt;</span><span class="x"></span> </pre></div> <div style='display:none'>&lt;!-- it's easy to make dropdown to choose a country --&gt; <br/>&lt;?php echo $form-&gt;input('country_id', array('options' =&gt; $static-&gt;countries('id', 'name'))); ?&gt; <br/> <br/>&lt;!-- quickly get the description of the status with ID = 40 --&gt; <br/>&lt;?php echo $static-&gt;status(40, 'desc'); ?&gt; <br/> <br/>&lt;!-- dropdown of abbreviated states (NY, CA, etc) --&gt; <br/>&lt;?= $form-&gt;select('user/state_id', $static-&gt;states('id', 'abbrev'), $user['User']['state_id']); ?&gt; <br/></div> <br/> <br/>Sorry, you have to get the data to put into your database on your own. This Helper will cache the data from that data for 1 year, making it so the data is almost never selected from your database. <br/> <br/>Installation1. Take the code below and put it into the file app/views/helpers/static.php <br/>2. Config the file if you want (I suggest changing the $tmp_folder var) <br/>3. In your controller add <em>var $helpers = array('Static'); <br/> <br/>The Code (intended to go in a helper named static.php) <br/><div class="code"><pre><span class="cp">&lt;?php</span> <span class="c">/**</span> <span class="c"> * CakePHP Helper to handle use of data in database that never changes</span> <span class="c"> * </span> <span class="c"> * array plural($order, $field=&#39;name&#39;); // ready for use in FormHelper::select</span> <span class="c"> * string singular($id, $field=&#39;name&#39;);</span> <span class="c"> * </span> <span class="c"> * usage examples (in Views):</span> <span class="c"> * </span> <span class="c"> * $static-&gt;states(&#39;abbrev&#39;); // all states sorted by abbrev</span> <span class="c"> * $static-&gt;statuses(&#39;id&#39;, &#39;name&#39;); // get list of all status names, sorted by id </span> <span class="c"> * $static-&gt;status(40, &#39;desc&#39;); // description of status with id 40</span> <span class="c"> * $status-&gt;countries(); // get all countries sorted by id</span> <span class="c"> * </span> <span class="c"> * @author Rob Conner aka rtconner</span> <span class="c"> */</span> <span class="k">class</span> <span class="nc">StaticHelper</span> <span class="k">extends</span> <span class="nx">Helper</span> <span class="p">{</span> <span class="c">// set this to a folder within your app/tmp folder to store the data (no trailing slash)</span> <span class="k">var</span> <span class="nv">$tmp_folder</span> <span class="o">=</span> <span class="s1">&#39;cache&#39;</span><span class="p">;</span> <span class="k">var</span> <span class="nv">$cache_expires</span> <span class="o">=</span> <span class="s1">&#39;+1 Year&#39;</span><span class="p">;</span> <span class="k">var</span> <span class="nv">$database</span> <span class="o">=</span> <span class="s1">&#39;default&#39;</span><span class="p">;</span> <span class="c">//plural only please, will enable both plural and singular methods (status needs to be added to inflections.php)</span> <span class="k">var</span> <span class="nv">$methods</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;states&#39;</span><span class="p">,</span> <span class="s1">&#39;countries&#39;</span><span class="p">,</span> <span class="s1">&#39;statuses&#39;</span><span class="p">);</span> <span class="k">function</span> <span class="nf">__call</span><span class="p">(</span><span class="nv">$method</span><span class="p">,</span> <span class="nv">$args</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$plural</span> <span class="o">=</span> <span class="nx">Inflector</span><span class="o">::</span><span class="na">pluralize</span><span class="p">(</span><span class="nv">$method</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="nf">in_array</span><span class="p">(</span><span class="nv">$plural</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">methods</span><span class="p">))</span> <span class="p">{</span> <span class="nf">array_unshift</span><span class="p">(</span><span class="nv">$args</span><span class="p">,</span> <span class="nv">$method</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="nv">$plural</span><span class="o">==</span><span class="nv">$method</span><span class="p">)</span> <span class="c">// return list of all static items</span> <span class="k">return</span> <span class="nf">call_user_func_array</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$this</span><span class="p">,</span> <span class="s1">&#39;all&#39;</span><span class="p">),</span> <span class="nv">$args</span><span class="p">);</span> <span class="k">else</span> <span class="c">// return single item</span> <span class="k">return</span> <span class="nf">call_user_func_array</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">$this</span><span class="p">,</span> <span class="s1">&#39;row&#39;</span><span class="p">),</span> <span class="nv">$args</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="c">// try to imitate php&#39;s errors</span> <span class="nf">trigger_error</span><span class="p">(</span><span class="nf">sprintf</span><span class="p">(</span><span class="s1">&#39;Call to undefined function: %s::%s().&#39;</span><span class="p">,</span> <span class="nf">get_class</span><span class="p">(</span><span class="nv">$this</span><span class="p">),</span> <span class="nv">$method</span><span class="p">),</span> <span class="nx">E_USER_ERROR</span><span class="p">);</span> <span class="p">}</span> <span class="c">/**</span> <span class="c"> * @param string $table to get list from</span> <span class="c"> * @param string $order sort order of list</span> <span class="c"> * @param string $field field data to return</span> <span class="c"> * @return array</span> <span class="c"> */</span> <span class="k">function</span> <span class="nf">all</span><span class="p">(</span><span class="nv">$table</span><span class="p">,</span> <span class="nv">$order</span><span class="o">=</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="nv">$field</span><span class="o">=</span><span class="s1">&#39;name&#39;</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$cache_name</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">tmp_folder</span><span class="o">.</span><span class="nx">DS</span><span class="o">.</span><span class="nv">$table</span><span class="o">.</span><span class="s1">&#39;_&#39;</span><span class="o">.</span><span class="nv">$order</span><span class="o">.</span><span class="s1">&#39;_&#39;</span><span class="o">.</span><span class="nv">$field</span><span class="p">;</span> <span class="nv">$cache_data</span> <span class="o">=</span> <span class="nx">cache</span><span class="p">(</span><span class="nv">$cache_name</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">cache_expires</span><span class="p">,</span> <span class="s1">&#39;tmp&#39;</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$cache_data</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$db</span> <span class="o">=&amp;</span> <span class="nx">ConnectionManager</span><span class="o">::</span><span class="na">getDataSource</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">database</span><span class="p">);</span> <span class="nv">$table</span> <span class="o">=</span> <span class="nx">Inflector</span><span class="o">::</span><span class="na">tableize</span><span class="p">(</span><span class="nv">$table</span><span class="p">);</span> <span class="nv">$qs</span> <span class="o">=</span> <span class="s1">&#39;SELECT * FROM `&#39;</span><span class="o">.</span><span class="nv">$table</span><span class="o">.</span><span class="s1">&#39;` ORDER BY `&#39;</span><span class="o">.</span><span class="nv">$order</span><span class="o">.</span><span class="s1">&#39;`;&#39;</span><span class="p">;</span> <span class="nv">$results</span> <span class="o">=</span> <span class="nv">$db</span><span class="o">-&gt;</span><span class="na">fetchAll</span><span class="p">(</span><span class="nv">$qs</span><span class="p">,</span> <span class="k">false</span><span class="p">,</span> <span class="s1">&#39;States&#39;</span><span class="p">);</span> <span class="nv">$list</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> <span class="k">foreach</span><span class="p">(</span><span class="nv">$results</span> <span class="k">as</span> <span class="nv">$r</span><span class="p">)</span> <span class="nv">$list</span><span class="p">[</span><span class="nv">$r</span><span class="p">[</span><span class="nv">$table</span><span class="p">][</span><span class="s1">&#39;id&#39;</span><span class="p">]]</span> <span class="o">=</span> <span class="nv">$r</span><span class="p">[</span><span class="nv">$table</span><span class="p">][</span><span class="nv">$field</span><span class="p">];</span> <span class="nv">$cache_data</span> <span class="o">=</span> <span class="nx">cache</span><span class="p">(</span><span class="nv">$cache_name</span><span class="p">,</span> <span class="nf">serialize</span><span class="p">(</span><span class="nv">$list</span><span class="p">),</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">cache_expires</span><span class="p">,</span> <span class="s1">&#39;tmp&#39;</span><span class="p">);</span> <span class="p">}</span> <span class="k">return</span> <span class="o">@</span><span class="nf">unserialize</span><span class="p">(</span><span class="nv">$cache_data</span><span class="p">);</span> <span class="p">}</span> <span class="c">/**</span> <span class="c"> * @param string $table to get row from</span> <span class="c"> * @param string $field name to return (ex: name, abbrev, etc)</span> <span class="c"> * @param int $id primary id or item in row</span> <span class="c"> * @return string $value</span> <span class="c"> */</span> <span class="k">function</span> <span class="nf">row</span><span class="p">(</span><span class="nv">$table</span><span class="p">,</span> <span class="nv">$id</span><span class="p">,</span> <span class="nv">$field</span><span class="o">=</span><span class="s1">&#39;name&#39;</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$all</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">all</span><span class="p">(</span><span class="nv">$table</span><span class="p">,</span> <span class="nv">$field</span><span class="p">);</span> <span class="k">return</span> <span class="nf">array_key_exists</span><span class="p">(</span><span class="nv">$id</span><span class="p">,</span> <span class="nv">$all</span><span class="p">)</span> <span class="o">?</span> <span class="nv">$all</span><span class="p">[</span><span class="nv">$id</span><span class="p">]</span> <span class="o">:</span> <span class="k">null</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <div style='display:none'>&lt;?php <br/>/** <br/> * CakePHP Helper to handle use of data in database that never changes <br/> * <br/> * array plural($order, $field='name'); // ready for use in FormHelper::select <br/> * string singular($id, $field='name'); <br/> * <br/> * usage examples (in Views): <br/> * <br/> * $static-&gt;states('abbrev'); // all states sorted by abbrev <br/> * $static-&gt;statuses('id', 'name'); // get list of all status names, sorted by id <br/> * $static-&gt;status(40, 'desc'); // description of status with id 40 <br/> * $status-&gt;countries(); // get all countries sorted by id <br/> * <br/> * @author Rob Conner aka rtconner <br/> */ <br/>class StaticHelper extends Helper { <br/> <br/> // set this to a folder within your app/tmp folder to store the data (no trailing slash) <br/> var $tmp_folder = 'cache'; <br/> <br/> var $cache_expires = '+1 Year'; <br/> <br/> var $database = 'default'; <br/> <br/> //plural only please, will enable both plural and singular methods (status needs to be added to inflections.php) <br/> var $methods = array('states', 'countries', 'statuses'); <br/> <br/> function __call($method, $args) { <br/> $plural = Inflector::pluralize($method); <br/> if(in_array($plural, $this-&gt;methods)) { <br/> array_unshift($args, $method); <br/> if($plural==$method) // return list of all static items <br/> return call_user_func_array(array(&amp;$this, 'all'), $args); <br/> else // return single item <br/> return call_user_func_array(array(&amp;$this, 'row'), $args); <br/> } else // try to imitate php's errors <br/> trigger_error(sprintf('Call to undefined function: %s::%s().', get_class($this), $method), E_USER_ERROR); <br/> } <br/> <br/> /** <br/> * @param string $table to get list from <br/> * @param string $order sort order of list <br/> * @param string $field field data to return <br/> * @return array <br/> */ <br/> function all($table, $order='id', $field='name') { <br/> $cache_name = $this-&gt;tmp_folder.DS.$table.'_'.$order.'_'.$field; <br/> $cache_data = cache($cache_name, null, $this-&gt;cache_expires, 'tmp'); <br/> <br/> if (empty($cache_data)) { <br/> <br/> $db =&amp; ConnectionManager::getDataSource($this-&gt;database); <br/> <br/> $table = Inflector::tableize($table); <br/> $qs = 'SELECT * FROM `'.$table.'` ORDER BY `'.$order.'`;'; <br/> <br/> $results = $db-&gt;fetchAll($qs, false, 'States'); <br/> <br/> $list = array(); <br/> foreach($results as $r) <br/> $list[$r[$table]['id']] = $r[$table][$field]; <br/> <br/> $cache_data = cache($cache_name, serialize($list), $this-&gt;cache_expires, 'tmp'); <br/> } <br/> <br/> return @unserialize($cache_data); <br/> } <br/> <br/> /** <br/> * @param string $table to get row from <br/> * @param string $field name to return (ex: name, abbrev, etc) <br/> * @param int $id primary id or item in row <br/> * @return string $value <br/> */ <br/> function row($table, $id, $field='name') { <br/> $all = $this-&gt;all($table, $field); <br/> return array_key_exists($id, $all) <br/> ? $all[$id] <br/> : null; <br/> } <br/> <br/>} <br/></div></em>
0 Comments >> Tags: CakePHP, PHP

Welcome to my CakePHP Blog


July 26, 2007
Hello folks. Welcome to the <a href="http://cakephp.org">CakePHP</a> [cakephp.org] portion of my Blog. I intend to use this as a space to share tips and hints and other such helpfulness that I can offer for you CakePHP users (or should I say bakers). I've been coding in Cake for a while now. I've had to go through some tough times with that blasted framework. I've loved it, I've hated, but we always seem to make peace at the end. <br/> <br/>Since I've been through so much I've been forced to learn a lot about CakePHP. I won't say I've mastered it, as I still learn new things all of the time. But through thick and thin, for the most part I've learned best practices and how to get it to what I want. As with everything I've found ways to make Cake work better for me. Hopefully some of what I've learned can also benefit you. <br/> <br/>If it means anything I really only using Cake 1.2. Sorry to those of you still on 1.1 but for the most part I will not be able to offer large amounts of help to you. Some tips I will post will be helpful. I'll try to document what versions of CakePHP any given concept or bit of code will work with. <br/> <br/>Thanks for stopping by and Happy Baking <br/>-Rob Conner (aka rtconner) <br/>
14 Comments >> Tags: CakePHP, PHP