<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8740441542827453634</id><updated>2012-02-08T06:31:37.284-08:00</updated><category term='bake'/><category term='cakephp login'/><category term='code igniter'/><category term='cache'/><category term='check boxes'/><category term='php'/><category term='joomla'/><category term='bug'/><category term='ajax'/><category term='acl'/><category term='core'/><category term='recursive'/><category term='HABTM'/><category term='conditions'/><category term='Auth'/><category term='soft delete'/><category term='query'/><category term='component'/><category term='template engine'/><category term='internationalization'/><category term='redirects problem'/><category term='find'/><category term='datepicker'/><category term='shell'/><category term='smarty'/><category term='model bindings'/><category term='resources'/><category term='behavior'/><category term='mysql function'/><category term='cakephp'/><category term='routing'/><category term='link'/><category term='framework'/><category term='database'/><title type='text'>Abdullah Solutions Using PHP</title><subtitle type='html'>This blog is about the PHP solutions I have to think of when I'm developing systems almost every single day...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-7437113600034699135</id><published>2008-12-05T15:17:00.000-08:00</published><updated>2008-12-05T16:05:49.345-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='core'/><title type='text'>New things in cakePHP core</title><content type='html'>Quite a while back I updated the cakePHP core in MyMeeting. Because of that update I broke so many things in MyMeeting because of some new ways cakePHP implements stuff. Here is a summary of some of the changes I had to make to make it work again.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Complex query is by itself now&lt;/span&gt;&lt;br /&gt;This is the single most important update which broke a lot of stuff in MyMeeting. So now you cannot do things like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;mystuff-&gt;find(array('conditions'=&gt;array('updated'=&gt;'&lt;=!-now()))) &lt;/pre&gt;&lt;br /&gt;That won't work anymore. !- no longer stops the value from being put in quotes. Now you've got to do this way:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;mystuff-&gt;find(array('conditions'=&gt;array('updated &lt;= now()'))) &lt;/pre&gt;&lt;br /&gt;That would work. No need to asssign value to key and stuff. Just what is the query. Same thing that this won't work anymore:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;mystuff-&gt;find(array('conditions'=&gt;array('deleted'=&gt;'!=1')))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It now has to be:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;mystuff-&gt;find(array('conditions'=&gt;array('deleted != 1')))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Just as some example of how the new queries should be.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Unicode is broken in some of the older system and new cakePHP uses unicode in validation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This kinda caused me a lot of grief. Validation worked very well on my dev machine which ran on Ubuntu. But as soon as I moved it to production server (CentOS &amp;amp; Mandriva) it didn't work anymore. As it turned out that in the pcre library, unicode support is not enabled by default. To counter this I had to change back the regex not to use unicode and just use normal regex. So I changed the file cake/libs/validation.php in the function alphaNumeric the regex is from using unicode:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$_this-&gt;regex = '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/mu';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;to not use unicode:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$_this-&gt;regex = '/^[a-zA-Z0-9_-]+$/mu';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It now works on all systems but I've got to be more carefull now whenever I upgrade cakePHP core so that I do the necessary hack (this is a hack. A proper implementation would detect whether there is unicode support and use the approriate regex then)&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;Core now have contain. No more need for the Bindable behaviour to be added&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Using contain which comes with the core would better guarantee that it'd be properly supported in the future. The syntax is almost the same. So now whenever you need to restrict what models are queried or maybe even drop off all association so that only the specified model is queried, contain is the way to do it. How to drop off all of the associations? Like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;mymodel-&gt;find(array('contain'=&gt;false))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Of course you can put in conditions and stuff, but basically setting false to contain would query only the table for that model. Neat.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Unit tests rocks&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I can't say this enough. Unit test allows for very quick testing of whether things work or not. And actually it would (in the future) easily catch errors which might be caused by changes in the query syntax and stuff. To learn how to set up unit test you can go to &lt;a href="http://bakery.cakephp.org/articles/view/testing-models-with-cakephp-1-2-test-suite"&gt;http://bakery.cakephp.org/articles/view/testing-models-with-cakephp-1-2-test-suite&lt;/a&gt;. To access unit tests you need to enable debug in app/config/core.php. And then access the test page by going to http://location-of-app/test.php. Over there you'll see a whole lot of tests already provided to test cakePHP core functions. And then you can add new test cases for your app by adding the file model.test.php into app/tests/cases/model. You can add fixtures to your test by adding model_fixture.php to your app/tests/fixtures folder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-7437113600034699135?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/7437113600034699135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=7437113600034699135' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7437113600034699135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7437113600034699135'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/12/new-things-in-cakephp-core.html' title='New things in cakePHP core'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-6848897356951204425</id><published>2008-06-30T19:55:00.000-07:00</published><updated>2008-06-30T20:03:38.963-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='query'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='conditions'/><title type='text'>Using functions in cakephp queries</title><content type='html'>Sometimes you need to use functions in your queries for example using datediff. How would you do it in cakephp? Simply don't assign any value to the key and it will be inserted as it is. For example to get the query "where datediff(deadline,now())&lt;7" you'd do&lt;br /&gt;&lt;pre&gt;$this-&gt;Decision-&gt;find(array('datediff(deadline,now())&lt;7'));&lt;/pre&gt;&lt;br /&gt;Simple, efficent, nice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-6848897356951204425?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/6848897356951204425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=6848897356951204425' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6848897356951204425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6848897356951204425'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/06/using-functions-in-cakephp-queries.html' title='Using functions in cakephp queries'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-1201405759691514385</id><published>2008-06-30T19:28:00.000-07:00</published><updated>2008-06-30T19:32:20.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='query'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>The guts of a query</title><content type='html'>Sometimes to create more complex queries in cakephp you'd have to refer directly to the source code. If you want to know how do they change all of that array into the where clause of your query just search the &lt;a href="http://api.cakephp.org/"&gt;api&lt;/a&gt; for conditionKeysToString.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-1201405759691514385?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/1201405759691514385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=1201405759691514385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/1201405759691514385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/1201405759691514385'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/06/guts-of-query.html' title='The guts of a query'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-9062458856508304373</id><published>2008-05-12T01:28:00.000-07:00</published><updated>2008-05-12T01:30:21.753-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql function'/><title type='text'>Using mysql functions in cakephp</title><content type='html'>Sometimes it's just easier to use mysql functions in the conditions. But cakephp automatically quote them. To disable the automatic quoting for any field just prefix the variable with a -! for example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$notifications=$this-&gt;Notification-&gt;findAll(array('notification_date'=&gt;'&gt;= -!now()'));&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-9062458856508304373?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/9062458856508304373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=9062458856508304373' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9062458856508304373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9062458856508304373'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/05/using-mysql-functions-in-cakephp.html' title='Using mysql functions in cakephp'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-5706391125921245419</id><published>2008-04-24T23:57:00.000-07:00</published><updated>2008-04-25T00:06:27.394-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='routing'/><title type='text'>Advanced routing in CakePHP</title><content type='html'>Wow.. routing in Cakephp is pretty good. Works both ways. To learn more go to:&lt;br /&gt;&lt;a href="http://debuggable.com/posts/new-router-goodies:480f4dd6-4d40-4405-908d-4cd7cbdd56cb"&gt;http://debuggable.com/posts/new-router-goodies:480f4dd6-4d40-4405-908d-4cd7cbdd56cb&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The most important part for me in the post was the past variable. Finally I'd be able to pass variables to the function. So for something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Router::connect('/:committee/:controller/:action/:id',array(),array('pass'=&gt;array('committee','id')));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The empty array means you want to just pass to the default controller and action you keyed into the url. The pass array means you want to pass the committee as the first variable of the action and id as the second variable. Pretty cool stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-5706391125921245419?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/5706391125921245419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=5706391125921245419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5706391125921245419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5706391125921245419'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/04/advanced-routing-in-cakephp.html' title='Advanced routing in CakePHP'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-5927960917505389428</id><published>2008-04-23T02:45:00.000-07:00</published><updated>2008-04-23T02:55:33.307-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>I need to migrate</title><content type='html'>Fuh.. I need to get out of this country.. :P&lt;br /&gt;&lt;br /&gt;Anyway.. that may be a long time coming. But first here's a good reference on how to migrate databases using cakephp at:&lt;br /&gt;&lt;a href="http://cakebaker.42dh.com/2008/04/13/migrations-the-cakephp-way/"&gt;http://cakebaker.42dh.com/2008/04/13/migrations-the-cakephp-way/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To sum it up you have to follow these steps:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Update the tables in sql&lt;br /&gt;        You can use phpmyadmin, mysql console or anything you want&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Create/Update your models&lt;br /&gt;        Make sure your models are created for each table you add. Easy using `cake bake model`&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Update the schema&lt;br /&gt;        Run `cake schema generate`. This will create the app/config/sql/schema.php file. This file is needed for others to compare with.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Commit your changes and others update theirs&lt;br /&gt;        Use whatever you use, svn, cvs, git, mercurial. As long as everyone get the new version of app/config/sql/schema.php&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Update your database&lt;br /&gt;        Just run `cake schema run update`. And walah.. you've got your database all nice and update.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Have I said cakephp is cool.. Oh yeah, it sure is... :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-5927960917505389428?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/5927960917505389428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=5927960917505389428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5927960917505389428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5927960917505389428'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/04/i-need-to-migrate.html' title='I need to migrate'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-9116675494042524651</id><published>2008-04-02T11:25:00.000-07:00</published><updated>2008-04-02T11:32:30.947-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><category scheme='http://www.blogger.com/atom/ns#' term='component'/><title type='text'>Using components in shell class</title><content type='html'>One of the great things about cake is it's shell functions. It makes it easy to write shell scripts for your app. First step is to create the file cake/console/libs. Lets name this file myapp.php. Then inside you would do:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class MyappShell extends Shell {&lt;br /&gt;   function main(){&lt;br /&gt;        .....&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Do whatever you want inside that class. You can even define the $uses array in the class to use whatever models your app have. And if you want to use a certain component, lets say the Auth component, you'd do:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;App::import('Component','Auth');&lt;br /&gt;$this-&gt;Auth=&amp;amp; new AuthComponent(null);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then you can use stuff like $this-&gt;Auth-&gt;password and such. Great stuff this cakephp.. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-9116675494042524651?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/9116675494042524651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=9116675494042524651' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9116675494042524651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9116675494042524651'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/04/using-components-in-shell-class.html' title='Using components in shell class'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-9028747243335799467</id><published>2008-04-02T09:54:00.000-07:00</published><updated>2008-04-02T09:56:57.323-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='bake'/><title type='text'>Bake it quick</title><content type='html'>Even though I've been using cakephp for over 2 weeks already, but I've only just discovered that you can actually bake very quickly just by typing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;./cake bake all&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;in your cake/console directory. It will create your model, controls and views all in one shot. But only for one model. But it's much easier than how I usually do it (through the menus).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-9028747243335799467?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/9028747243335799467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=9028747243335799467' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9028747243335799467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9028747243335799467'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/04/bake-it-quick.html' title='Bake it quick'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-6130160046051447708</id><published>2008-03-30T01:37:00.000-07:00</published><updated>2009-04-24T18:19:08.911-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='Auth'/><category scheme='http://www.blogger.com/atom/ns#' term='component'/><title type='text'>Using proper Auth Component in Cakephp</title><content type='html'>A while back (when I had very little experience with cakephp), I wrote about how to go about setting user authentication in your cakephp. Basically you have to login to do anything at all in my whole web app.  So we manually set the user id and stuff in the sessions and check it every now and then. Now I'm more experienced and have finally been able to google my way to a better understanding of how it can be done using the auth component that comes with cakephp.&lt;br /&gt;&lt;br /&gt;First is that it is a component. And you will want it everywhere in your application. So where else do you write it but in your app/app_controller.php file.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var $components = array('Acl','Auth');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Make sure you add Acl before Auth because Auth uses some functions in Acl which is not initialized unless it is already loaded. So load Acl first.&lt;br /&gt;&lt;br /&gt;Okay, then you have to set up some settings for your Auth component. It is set in the beforeFilter function of your app_controller.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeFilter() {&lt;br /&gt;      $this-&gt;Auth-&gt;loginAction=array('controller'=&gt;'users','action'=&gt;'login');&lt;br /&gt;      $this-&gt;Auth-&gt;loginRedirect=array('controller'=&gt;'users','action'=&gt;'alert');&lt;br /&gt;      $this-&gt;Auth-&gt;logoutRedirect=array('controller'=&gt;'users','action'=&gt;'login');&lt;br /&gt;      $this-&gt;Auth-&gt;loginError=__('Invalid username or password',true);&lt;br /&gt;      $this-&gt;Auth-&gt;authorize='controller';&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Okay. Some explanation. loginAction is which page to display when your user will login. Of course it has to be a page with a form with the fields username and password. Then loginRedirect is the default page to go to if the users come directly to the login page. Let me explain. You see, when parts of your application is protected with this component, and the user has not logged in, the user will be redirected automatically to the login page to allow the user to login. If it is a successful login s/he will be directed back to the page s/he requested for before. Unless the user went directly to the login page. Because then the component don't know where to send the user. So we set it using loginRedirect. logoutRedirect is the page to send the user to once they have successfully logged out. In my case I'd send them straight back to the login page. loginError is of course the error message that will be flashed if the user didn't login successfully. And finally authorize will determine who will authorize the user. It can be set to 'controller', 'actions', 'crud', array('model'=&gt;'name') or 'object'. To learn more see &lt;a href="http://api.cakephp.org/1.2/class_auth_component.html#856e51220cac8fef9eef922a0b535146"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Then if you want your views to be able to know who is logged in you've got to send the data over. I do it in the beforeRender function like this.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeRender(){&lt;br /&gt;     if($this-&gt;Auth-&gt;user()){&lt;br /&gt;         $this-&gt;set('auth_user',$this-&gt;Auth-&gt;user());&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pretty straight forward. Previously I've set the controller to authorize the user access, so we will need the isAuthorized function defined in our controller. Define it in our app_controller like this.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function isAuthorized(){&lt;br /&gt;     return true;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then overwrite in your model controllers for more sophisticated authentication. Basically I've just set default is to allow access to the controller.&lt;br /&gt;&lt;br /&gt;Okay. That's it for the app_controller. Now for the user controller.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function login(){&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function logout(){&lt;br /&gt;      $this-&gt;Session-&gt;SetFlash(__('Successfully logged out',true));&lt;br /&gt;      $this-&gt;redirect($this-&gt;Auth-&gt;logout());&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Make sure the login view is created. But no other code is necessary for the login. And very litte required for the logout function. And basically that is it. Very cool. Of and one more thing. The auth component will actually hash the password with some other measures of security. So you have to make sure at least the first user uses the same password generated by $this-&gt;Auth-&gt;password('password') so that you can login. Or some other way to get the password in. I've read that when you save the user data the auth component will do it for you, haven't tested that yet. But sure to try soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-6130160046051447708?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/6130160046051447708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=6130160046051447708' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6130160046051447708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6130160046051447708'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/03/using-proper-auth-component-in-cakephp.html' title='Using proper Auth Component in Cakephp'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-7960450597706445678</id><published>2008-03-26T03:03:00.000-07:00</published><updated>2008-03-26T03:06:30.270-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='recursive'/><title type='text'>The use of recursive property</title><content type='html'>After much experimenting, I've finally found the reason for the recursive property. If you set it to 0 then it will not query into all the rest of the models it is bound with (you know has, belongsto and stuff like that). And so your query will be less.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-7960450597706445678?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/7960450597706445678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=7960450597706445678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7960450597706445678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7960450597706445678'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/03/use-of-recursive-property.html' title='The use of recursive property'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-4515837719105971302</id><published>2008-03-25T20:42:00.000-07:00</published><updated>2008-03-25T20:50:39.223-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><category scheme='http://www.blogger.com/atom/ns#' term='HABTM'/><title type='text'>Fixing habtm in cakephp</title><content type='html'>Okay... One of the cool things about cakephp is it's habtm (Has and belongs to many) relationship. It is great and works more the less out of the box if all your settings are correct (Hint: use cake bake to get it right). But I found some undefined behavior if you are editing a form with more than 1 habtm field. If you select the second item in the first list, it will also save the second item in your second list even if you did not select it. After much bashing my head over it, I finally tracked it all the way to the file cake/libs/model/models.php. It looks like the $newValues used at line 1301 is not unset for the second loop. So just add:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;unset($newValues);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Right after the insertMulti line. And it will be working alright.&lt;br /&gt;&lt;br /&gt;But there is another problem. If you use the 'multiple'=&gt;'checkbox' option in your form, you will get an error if you uncheck all the options. That is because it will not set the $value for line 1284. Add the whole block in an:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if(is_array($value)){&lt;br /&gt;....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And all will be okay. Hope that helps&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-4515837719105971302?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/4515837719105971302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=4515837719105971302' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4515837719105971302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4515837719105971302'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/03/fixing-habtm-in-cakephp.html' title='Fixing habtm in cakephp'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-8127558400798910737</id><published>2008-03-25T17:51:00.000-07:00</published><updated>2008-03-25T17:52:20.247-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><title type='text'>Optimize cakephp with cache</title><content type='html'>Wow.. Seems it is quite easy to do caching with cakephp. Just check out:&lt;br /&gt;&lt;a href="http://bakery.cakephp.org/articles/view/optimizing-your-cakephp-elements-and-views-with-caching"&gt;http://bakery.cakephp.org/articles/view/optimizing-your-cakephp-elements-and-views-with-caching&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope to be able to use it soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-8127558400798910737?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/8127558400798910737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=8127558400798910737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/8127558400798910737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/8127558400798910737'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/03/optimize-cakephp-with-cache.html' title='Optimize cakephp with cache'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-727551111662680335</id><published>2008-03-24T23:52:00.000-07:00</published><updated>2008-03-25T00:02:08.639-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='joomla'/><category scheme='http://www.blogger.com/atom/ns#' term='acl'/><title type='text'>Joomla: Hacking the ACL</title><content type='html'>I needed to allow managers and others to change their own password but only the back-end is accessible. I didn't want to enable login at the front end. But anything below administrator, not even the user manager menu comes out, so there is nothing to edit. Finally after much googling I found: &lt;a href="http://demo.joomlaworks.gr/content/view/23/32/"&gt;http://demo.joomlaworks.gr/content/view/23/32/&lt;/a&gt; which basically tells me that I can change the includes/gacl.class.php to hand hack the acl. By adding:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;_mos_add_acl( 'administration', 'manage', 'users', 'manager', 'components', 'com_users' );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I was able to show the user menu for managers and they can see the list of users. But they cannot edit anything. Cannot add anything. Cannot delete anything. So I finally checked directly into the file controlling the user data administrator/components/com_users/admin.users.php&lt;br /&gt;&lt;br /&gt;In the function checkUserPermission I changed it to:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if ( !$allowActionToMyself &amp;amp;&amp;amp; $id == $my-&gt;id ){&lt;br /&gt;                                $msg .= 'You cannot '. $actionName .' Yourself!';&lt;br /&gt;                        } else if (($id != $my-&gt;id &amp;amp;&amp;amp; $obj-&gt;gid == $my-&gt;gid &amp;amp;&amp;amp; !in_array($my-&gt;gid, array(24, 25))) || ($obj-&gt;gid &amp;amp;&amp;amp; !in_array($obj-&gt;gid,getGIDSChildren($my-&gt;gid)))) {&lt;br /&gt;                                $msg .= 'You cannot '. $actionName .' a `'. $this_group .'`. Only higher-level users have this power. ';&lt;br /&gt;                        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I added the $id!=$my-&gt;id part in the elseif. That would allow the action if the action is allowed to self (ie the $allowActionToMyself is set). Finally I was able to edit. But when I tried to save it didn't work. Finally I checked into the saveUser function and changed it to:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$msg = checkUserPermissions( array($userIdPosted), 'save', true );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Meaning that I allow user to save themselves. So now my managers can edit their own profile and only their profile. Turned out better than I thought.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-727551111662680335?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/727551111662680335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=727551111662680335' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/727551111662680335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/727551111662680335'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/03/joomla-hacking-acl.html' title='Joomla: Hacking the ACL'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-6972512609851351617</id><published>2008-03-05T18:14:00.000-08:00</published><updated>2008-03-05T18:16:35.271-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='HABTM'/><category scheme='http://www.blogger.com/atom/ns#' term='check boxes'/><title type='text'>Using checkboxes instead of selects in habtm</title><content type='html'>CakePHP is seriously cool. How easy is it to use check boxes rather than the default select box in a habtm field? Just this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;echo $form-&gt;input('FieldModel',array('multiple'=&gt;'checkbox'));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that's it!!! Sweet... :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-6972512609851351617?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/6972512609851351617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=6972512609851351617' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6972512609851351617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6972512609851351617'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/03/using-checkboxes-instead-of-selects-in.html' title='Using checkboxes instead of selects in habtm'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-3464597422013860255</id><published>2008-02-27T01:22:00.000-08:00</published><updated>2008-02-27T01:29:21.020-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='behavior'/><title type='text'>Finally got the behaviour working</title><content type='html'>Wow!! CakePHP is great!! Now I've even got my own behavior working. This is the latest models/behaviors/comment.php which I have come up with.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;class CommentBehavior extends ModelBehavior&lt;br /&gt;{&lt;br /&gt;    var $settings=array();&lt;br /&gt;    var $runtime=array();&lt;br /&gt;    var $Comment;&lt;br /&gt;&lt;br /&gt;    function __construct(){&lt;br /&gt;        $this-&gt;Comment=ClassRegistry::init('Comment','model');&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function setup(&amp;amp;$model,$config = array()){&lt;br /&gt;        $this-&gt;settings[$model-&gt;alias]['assocAlias'] = $model-&gt;alias.'Comment';&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function beforeFind(&amp;amp;$model, $query){&lt;br /&gt;        $commentcond['Comment.model']=$model-&gt;alias;&lt;br /&gt;        if(!empty($query['conditions']) &amp;amp;&amp;amp; is_array($query['conditions'])) {&lt;br /&gt;            foreach($query['conditions'] as $fieldName =&gt; $constraint) {&lt;br /&gt;                if(!strstr($fieldName,'Comment.')) {&lt;br /&gt;                    continue;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                $commentcond[$fieldName] = $constraint;&lt;br /&gt;                unset($query['conditions'][$fieldName]);   &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        $this-&gt;runtime[$model-&gt;alias]['query']['conditions'] = $commentcond;&lt;br /&gt;        return $query;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function afterFind(&amp;amp;$model,$results,$primary){&lt;br /&gt;        extract($this-&gt;settings[$model-&gt;alias]);&lt;br /&gt;        foreach($results as &amp;amp;$result){&lt;br /&gt;            if(!isset($result[$model-&gt;alias][$model-&gt;primaryKey])){&lt;br /&gt;                continue(1);&lt;br /&gt;            }&lt;br /&gt;            $commentcond=$this-&gt;runtime[$model-&gt;alias]['query']['conditions'];&lt;br /&gt;            $commentcond['Comment.foreign_key']=$result[$model-&gt;alias][$model-&gt;primaryKey];&lt;br /&gt;            $comment=$this-&gt;Comment-&gt;findAll($commentcond);&lt;br /&gt;            if(empty($comment)){&lt;br /&gt;                continue(1);&lt;br /&gt;            }&lt;br /&gt;            $result[$assocAlias]=$comment;&lt;br /&gt;        }&lt;br /&gt;        return $results;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function beforeSave(&amp;amp;$model)&lt;br /&gt;    {&lt;br /&gt;        extract($this-&gt;settings[$model-&gt;alias]);&lt;br /&gt;        $this-&gt;runtime[$model-&gt;alias]['beforeSave'][$assocAlias] = $model-&gt;data[$assocAlias];&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function afterSave(&amp;amp;$model,$created)&lt;br /&gt;    {&lt;br /&gt;        extract($this-&gt;settings[$model-&gt;alias]);&lt;br /&gt;        $data=$this-&gt;runtime[$model-&gt;alias]['beforeSave'];&lt;br /&gt;        unset($this-&gt;runtime[$model-&gt;alias]['beforeSave']);&lt;br /&gt;       &lt;br /&gt;        foreach($data[$assocAlias] as &amp;amp;$comment) {&lt;br /&gt;            if($created) {&lt;br /&gt;                $comment['foreign_key'] = $model-&gt;getLastInsertID();&lt;br /&gt;            } else {&lt;br /&gt;                $comment['foreign_key'] = $model-&gt;id;&lt;br /&gt;            }&lt;br /&gt;   &lt;br /&gt;            if(!isset($comment['id'])) {&lt;br /&gt;                $this-&gt;Comment-&gt;create();&lt;br /&gt;            }&lt;br /&gt;           &lt;br /&gt;            $comment['model'] = $model-&gt;alias;&lt;br /&gt;            $this-&gt;Comment-&gt;save($comment,false);&lt;br /&gt;        }&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Comment extends AppModel&lt;br /&gt;{&lt;br /&gt;    var $name="Comment";&lt;br /&gt;    var $useTable="comments";&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And so to use it in the the model declaration you have to have the line:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var $actsAs=array('Comment');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And that's all set. You will receive the Comment parts too if you do a findAll() on it. To save Comment you'd have to do something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$dcomment['Comment']['id']=1;&lt;br /&gt;$dcomment['Comment']['description']="is it have funny cartooniiist dileb";&lt;br /&gt;$this-&gt;data['MeetingComment'][]=$dcomment;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Saving that meeting would also save the meeting comment. Note the first line is if you are editing the comment. If you exclude it then you will actually save a new comment. Cool stuff. Now off to creating the controls for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-3464597422013860255?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/3464597422013860255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=3464597422013860255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/3464597422013860255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/3464597422013860255'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/finally-got-behaviour-working.html' title='Finally got the behaviour working'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-6592638519872236803</id><published>2008-02-27T00:14:00.000-08:00</published><updated>2008-02-27T00:22:09.160-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='behavior'/><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><title type='text'>Warning!!! The error is cached</title><content type='html'>I tried to create my own behavior in CakePHP today. Using ideas from the &lt;a href="http://bakery.cakephp.org/articles/view/attachments"&gt;attachments&lt;/a&gt; solution, my first step was just to try to read in data that I've already manually keyed into the database. Associate them with each other. This is what I have done so far (goes into models/behaviors/comment.php):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;class CommentBehavior extends ModelBehavior&lt;br /&gt;{&lt;br /&gt;    var $settings=array();&lt;br /&gt;    var $runtime=array();&lt;br /&gt;    var $Comment;&lt;br /&gt;&lt;br /&gt;    function __construct(){&lt;br /&gt;        $this-&gt;Comment=ClassRegistry::init('Comment','model');&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function setup(&amp;amp;$model,$config = array()){&lt;br /&gt;        $this-&gt;settings[$model-&gt;alias]['assocAlias'] = $model-&gt;alias.'Comment';&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function beforeFind(&amp;amp;$model, $query){&lt;br /&gt;        $commentcond['Comment.model']=$model-&gt;alias;&lt;br /&gt;        if(!empty($query['conditions']) &amp;amp;&amp;amp; is_array($query['conditions'])) {&lt;br /&gt;            foreach($query['conditions'] as $fieldName =&gt; $constraint) {&lt;br /&gt;                if(!strstr($fieldName,'Comment.')) {&lt;br /&gt;                    continue;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                $commentcond[$fieldName] = $constraint;&lt;br /&gt;                unset($query['conditions'][$fieldName]);   &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        $this-&gt;runtime[$model-&gt;alias]['query']['conditions'] = $commentcond;&lt;br /&gt;        return $query;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function afterFind(&amp;amp;$model,$results,$primary){&lt;br /&gt;        extract($this-&gt;settings[$model-&gt;alias]);&lt;br /&gt;        foreach($results as &amp;amp;$result){&lt;br /&gt;            if(!isset($result[$model-&gt;alias][$model-&gt;primaryKey])){&lt;br /&gt;                continue(1);&lt;br /&gt;            }&lt;br /&gt;            $commentcond=$this-&gt;runtime[$model-&gt;alias]['query']['conditions'];&lt;br /&gt;            $commentcond['Comment.foreign_key']=$result[$model-&gt;alias][$model-&gt;primaryKey];&lt;br /&gt;            $comment=$this-&gt;Comment-&gt;findAll($commentcond);&lt;br /&gt;            if(empty($comment)){&lt;br /&gt;                continue(1);&lt;br /&gt;            }&lt;br /&gt;            $result[$assocAlias]=$comment;&lt;br /&gt;        }&lt;br /&gt;        return $results;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Comment extends AppModel&lt;br /&gt;{&lt;br /&gt;    var $name="Comment";&lt;br /&gt;    var $useTable="comments";&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Quite straight forward I think. But earlier on I made a mistake and cakephp spit out a request address not found error. I cut down all the additional code until I got to the very basic which you see above and it still gives out that error. I was stumped. Well, a quick search into the cakephp google groups shows that there is caching for the models and so I deleted the content of tmp/cache/models. It works after that. Alhamdullillah.. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-6592638519872236803?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/6592638519872236803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=6592638519872236803' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6592638519872236803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6592638519872236803'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/warning-error-is-cached.html' title='Warning!!! The error is cached'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-1187270593259737332</id><published>2008-02-25T20:25:00.000-08:00</published><updated>2008-02-25T20:42:45.339-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='link'/><title type='text'>CakePHP $html-&gt;link Variables</title><content type='html'>You can send additional variables to the next page with additional keys in the array like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;echo $html-&gt;link(__('text to link',true),array('controller'=&gt;'dest_controller','action'=&gt;'dest_action','additional_variable'=&gt;'variable_data'));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And the data can be accessed in the controller with the $this-&gt;params['named'] variable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-1187270593259737332?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/1187270593259737332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=1187270593259737332' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/1187270593259737332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/1187270593259737332'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/cakephp-html-link-variables.html' title='CakePHP $html-&gt;link Variables'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-7579010869359236196</id><published>2008-02-25T15:25:00.000-08:00</published><updated>2008-02-25T15:46:31.513-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='find'/><title type='text'>What will you find?</title><content type='html'>Hmm... The lack of clear documentation is getting clearer and clearer as I find that I have to code dive more and more to learn how to use CakePHP. Latest one is how on earth do you use the find method?&lt;br /&gt;&lt;br /&gt;According to the &lt;a href="http://api.cakephp.org/1.2/libs_2model_2model_8php-source.html#l01667"&gt;api&lt;/a&gt;, the declaration is like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="fragment"&gt;function &lt;a class="code" href="http://api.cakephp.org/1.2/class_model.html#e60758f27fa8486a063b8cc424bad741"&gt;find&lt;/a&gt;($conditions = null, $fields = array(), &lt;a class="code" href="http://api.cakephp.org/1.2/class_model.html#8baeeecfcbacef043f6d3c272e0defdf"&gt;$order&lt;/a&gt; = null, &lt;a class="code" href="http://api.cakephp.org/1.2/class_model.html#21ff2f461a6032573d52bba2cd8ec296"&gt;$recursive&lt;/a&gt; = null) {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So it accepts conditions, then fields, order and recursive value. But if you had searched a little more on the internet before looking at the api you might have found some people did this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$model-&gt;find('list',array('conditions'=&gt;array('id'=&gt;1)));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And looking into the code you will find that if $conditions is a string and it is a valid find method then you are left with pretty much just two variables. $conditions become the type of find you want, $fields become an array of variables pertaining to the search which could have keys consisting of 'conditions' (like the example above), 'fields', 'limit', 'offset', 'order', 'page' and an array of 'joins'. The type (which we get from the variable $conditions) could either be 'count', 'first' or 'list'. The default (aka if you didn't set it in $conditions and it uses all the variables like the way they are named) is 'first'.&lt;br /&gt;&lt;br /&gt;The reason why I was diving into the code initially was I wanted to make a list for the select box option. I was pretty sure that cakephp could easily take care of that. And inside the code I see it. The 'list' find type is already suited for this and it uses $this-&gt;displayField to display the option to be selected by the user and $this-&gt;primaryKey for the value to put into that option. The $this-&gt;primaryKey seems to default to id which is already good enough but $this-&gt;displayField should really be set in your model so that it would be used automatically. Once it is set, you're good to go. Just:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;Model-&gt;find('list',array('conditions'=&gt;array('parent_id'=&gt;'1')))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And you would already have all the data you need for your select box. It's pretty convenient but to get there is the real challenge.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-7579010869359236196?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/7579010869359236196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=7579010869359236196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7579010869359236196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7579010869359236196'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/what-will-you-find.html' title='What will you find?'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-5022651251331705045</id><published>2008-02-21T00:00:00.000-08:00</published><updated>2008-02-21T00:28:23.543-08:00</updated><title type='text'>Fixup for the attach to anything plugin for cakephp</title><content type='html'>There is a great plugin for cakephp. It basically allows you to attach files to any models that you have. Quite useful if you have many models which needs attachments. It is at &lt;a href="http://bakery.cakephp.org/articles/view/attachments"&gt;http://bakery.cakephp.org/articles/view/attachments&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;This is a great piece of code. Got so much features already built in. Hats off to the developers and all the contributors.&lt;br /&gt;&lt;br /&gt;But there is a few things I would like to mention here on how to get it working. It took me a whole day just to figure it out.&lt;br /&gt;&lt;br /&gt;The first part is the database. The script included in the download is missing a the auto increment extra. So you should change the file in config/sql/attachments.php so that the line with:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;'id' =&gt; array('type'=&gt;'integer', 'null' =&gt; false, 'default' =&gt; NULL, 'key' =&gt; 'primary'),&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;is changed to:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;'id' =&gt; array('type'=&gt;'integer', 'null' =&gt; false, 'default' =&gt; NULL, 'key' =&gt; 'primary', 'extra' =&gt; 'auto_increment'),&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note the auto increment part at the end. Once that is done you can create it with bake. The command is just (running from your current cake root directory):&lt;br /&gt;cake/console/cake schema run create attachments&lt;br /&gt;&lt;br /&gt;That should set up your database if all your configuration is right.&lt;br /&gt;&lt;br /&gt;And then I find that I need to change the file models/behaviors/attachment.php. In there under the function setup I have to add:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;        if(!is_array($config)){&lt;br /&gt;            $config=$this-&gt;defaultSettings;&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Right at the beginning of the function so that there would be a default if there wasn't one passed by the user (And actually I don't have a clue how to pass one actually).&lt;br /&gt;&lt;br /&gt;And then in the same file under the beforeSave function I have to add the following code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;foreach($attachment as $key=&gt;$data){&lt;br /&gt;    if(is_array($data)){&lt;br /&gt;        foreach($data as $skey=&gt;$sdata){&lt;br /&gt;            $uh[$skey][$key]=$sdata;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}       &lt;br /&gt;$attachment=$uh;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;before line 365 just before the test:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if(isset($attachment['file'])) {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;because it seems the arrangments of the array is wrong for the Transfer object. But apart from that it works pretty well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-5022651251331705045?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/5022651251331705045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=5022651251331705045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5022651251331705045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5022651251331705045'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/fixup-for-attach-to-anything-plugin-for.html' title='Fixup for the attach to anything plugin for cakephp'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-3542498493455706529</id><published>2008-02-19T20:03:00.000-08:00</published><updated>2008-02-19T20:05:07.166-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='behavior'/><category scheme='http://www.blogger.com/atom/ns#' term='soft delete'/><title type='text'>A soft delete behaviour</title><content type='html'>Found this behavior here &lt;a href="http://bakery.cakephp.org/articles/view/soft-delete-behavior"&gt;http://bakery.cakephp.org/articles/view/soft-delete-behavior&lt;/a&gt; . This could potentially be very useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-3542498493455706529?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/3542498493455706529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=3542498493455706529' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/3542498493455706529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/3542498493455706529'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/soft-delete-behaviour.html' title='A soft delete behaviour'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-9104669211816086926</id><published>2008-02-18T21:12:00.000-08:00</published><updated>2008-02-18T21:15:33.731-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='internationalization'/><title type='text'>Internationalization with CakePHP</title><content type='html'>I just found this article &lt;a href="http://bakery.cakephp.org/articles/view/p28n-the-top-to-bottom-persistent-internationalization-tutorial"&gt;http://bakery.cakephp.org/articles/view/p28n-the-top-to-bottom-persistent-internationalization-tutorial&lt;/a&gt;, it looks like a great tutorial on internationalization with CakePHP. Hope to be able to use it soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-9104669211816086926?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/9104669211816086926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=9104669211816086926' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9104669211816086926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/9104669211816086926'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/internationalization-with-cakephp.html' title='Internationalization with CakePHP'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-2432824834325712948</id><published>2008-02-17T00:04:00.000-08:00</published><updated>2008-07-08T21:50:41.852-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='datepicker'/><title type='text'>Output helper javascript into headers properly</title><content type='html'>With some pointers taken from cakebaker at this article: &lt;a href="http://cakebaker.42dh.com/2007/09/28/how-to-write-and-test-your-own-head-helper/"&gt;http://cakebaker.42dh.com/2007/09/28/how-to-write-and-test-your-own-head-helper/&lt;/a&gt; , I was finally able to properly output the datepicker javascript into the header part of the file like it was supposed to. Basically the idea is get a reference to the view using the ClassRegistry::getObject method to get the view. And use the view's method addScript to add a script to the header part of the view. Here's the modified version of the datePicker helper.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt; * Autocomplete Helper&lt;br /&gt; *&lt;br /&gt; * @author  Nik Chankov&lt;br /&gt; * @website http://nik.chankov.net&lt;br /&gt; * @version 1.0.0&lt;br /&gt; *&lt;br /&gt; * @updated   2008-02-13&lt;br /&gt; * @author    Abdullah&lt;br /&gt; * @website   http://abdullahsolutions.com&lt;br /&gt; * @changes   Used helpers array. Also used beforeRender so that the javascripts and theme is automatically loaded&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;class DatePickerHelper extends FormHelper {&lt;br /&gt;&lt;br /&gt;    var $format = '%Y-%m-%d';&lt;br /&gt;    var $helpers = array('Javascript','Html');&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     *Setup the format if exist in Configure class&lt;br /&gt;     */&lt;br /&gt;    function _setup(){&lt;br /&gt;        $format = Configure::read('DatePicker.format');&lt;br /&gt;        if($format != null){&lt;br /&gt;            $this-&amp;gt;format = $format;&lt;br /&gt;        }&lt;br /&gt;        else{&lt;br /&gt;            $this-&amp;gt;format = '%Y-%m-%d';&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function beforeRender(){&lt;br /&gt;        $view = ClassRegistry::getObject('view');&lt;br /&gt;        if (is_object($view)) {&lt;br /&gt;            $view-&amp;gt;addScript($this-&amp;gt;Javascript-&amp;gt;link('jscalendar/calendar.js'));&lt;br /&gt;            $view-&amp;gt;addScript($this-&amp;gt;Javascript-&amp;gt;link('jscalendar/lang/calendar-en.js'));&lt;br /&gt;            $view-&amp;gt;addScript($this-&amp;gt;Javascript-&amp;gt;link('common.js'));&lt;br /&gt;            $view-&amp;gt;addScript($this-&amp;gt;Html-&amp;gt;css('../js/jscalendar/skins/aqua/theme'));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * The Main Function - picker&lt;br /&gt;     *&lt;br /&gt;     * @param string $field Name of the database field. Possible usage with Model.&lt;br /&gt;     * @param array $options Optional Array. Options are the same as in the usual text input field.&lt;br /&gt;     */   &lt;br /&gt;    function picker($fieldName, $options = array()) {&lt;br /&gt;        $this-&amp;gt;_setup();&lt;br /&gt;        $this-&amp;gt;setFormTag($fieldName);&lt;br /&gt;        $htmlAttributes = $this-&amp;gt;domId($options);       &lt;br /&gt;        $divOptions['class'] = 'date';&lt;br /&gt;        $options['type'] = 'text';&lt;br /&gt;        $options['div']['class'] = 'date';&lt;br /&gt;        $time='';&lt;br /&gt;        if(isset($options['showstime'])){&lt;br /&gt;            if($options['showstime']===true) {&lt;br /&gt;                $time=',&amp;quot;24&amp;quot;';&lt;br /&gt;                $this-&amp;gt;format.=&amp;quot; %k:%M&amp;quot;;&lt;br /&gt;            }&lt;br /&gt;            unset($options['showstime']);&lt;br /&gt;        }&lt;br /&gt;        $options['after'] = $this-&amp;gt;Html-&amp;gt;link($this-&amp;gt;Html-&amp;gt;image('../js/jscalendar/img.gif'), '#', array('onClick'=&amp;gt;&amp;quot;return showCalendar('&amp;quot;.$htmlAttributes['id'].&amp;quot;', '&amp;quot;.$this-&amp;gt;format.&amp;quot;'$time); return false;&amp;quot;), null, false);&lt;br /&gt;        $output = $this-&amp;gt;input($fieldName, $options);&lt;br /&gt;&lt;br /&gt;        return $output;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function flat($fieldName, $options = array()){&lt;br /&gt;        $this-&amp;gt;_setup();&lt;br /&gt;        $this-&amp;gt;setFormTag($fieldName);&lt;br /&gt;        $htmlAttributes = $this-&amp;gt;domId($options);       &lt;br /&gt;        $divOptions['class'] = 'date';&lt;br /&gt;        $options['type'] = 'hidden';&lt;br /&gt;        $options['div']['class'] = 'date';&lt;br /&gt;        $hoder = '&amp;lt;div id=&amp;quot;'.$htmlAttributes['id'].'_cal'.'&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;showFlatCalendar(&amp;quot;'.$htmlAttributes['id'].'&amp;quot;, &amp;quot;'.$htmlAttributes['id'].'_cal'.'&amp;quot;, &amp;quot;'.$this-&amp;gt;format.'&amp;quot;, function(cal, date){document.getElementById(\''.$htmlAttributes['id'].''.'\').value = date});&amp;lt;/script&amp;gt;';&lt;br /&gt;        $output = $this-&amp;gt;input($fieldName, $options).$hoder;&lt;br /&gt;&lt;br /&gt;        return $output;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we can output better pages with this helper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-2432824834325712948?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/2432824834325712948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=2432824834325712948' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/2432824834325712948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/2432824834325712948'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/output-helper-javascript-into-headers.html' title='Output helper javascript into headers properly'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-4706870171309760599</id><published>2008-02-15T15:48:00.000-08:00</published><updated>2008-02-15T15:50:08.423-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='resources'/><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>Ajax with Cakephp resources</title><content type='html'>Found a great blog which lists many ajax resources for cakephp at ht&lt;a href="http://ahsanity.wordpress.com/2007/02/23/get-started-with-ajax-in-cakephp/"&gt;tp://ahsanity.wordpress.com/2007/02/23/get-started-with-ajax-in-cakephp/&lt;/a&gt;. Have to dive into there someday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-4706870171309760599?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/4706870171309760599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=4706870171309760599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4706870171309760599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4706870171309760599'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/ajax-with-cakephp-resources.html' title='Ajax with Cakephp resources'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-7351279711737515441</id><published>2008-02-15T14:01:00.000-08:00</published><updated>2008-02-15T14:06:50.516-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='redirects problem'/><title type='text'>Login redirect causing problems</title><content type='html'>Okay... once in a while when I'm developing a cakephp application using the previously posted method of changing the app_controller.php to redirect if the user has not logged in causes some problems. Namely firefox will say that it has detected that we are being redirected in a way which will never finish. Solved it a few times but because I didn't write it down I had to solve it again. Apparently the problem is that there is some error with your application. Maybe a missing table or field in your database, maybe a mistaken setting. Whichever way it is you just switch off redirects for a while so that the problem will be properly displayed, fix the problem and enable redirects again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-7351279711737515441?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/7351279711737515441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=7351279711737515441' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7351279711737515441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/7351279711737515441'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/login-redirect-causing-problems.html' title='Login redirect causing problems'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-5733576822801739864</id><published>2008-02-14T02:14:00.000-08:00</published><updated>2008-02-14T02:15:42.679-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='model bindings'/><title type='text'>Bindable behaviours</title><content type='html'>Bindings seems to be very useful in cakephp. &lt;a href="http://bakery.cakephp.org/articles/view/bindable-behavior-control-your-model-bindings"&gt;http://bakery.cakephp.org/articles/view/bindable-behavior-control-your-model-bindings&lt;/a&gt; offers an interesting read on how to do it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-5733576822801739864?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/5733576822801739864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=5733576822801739864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5733576822801739864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/5733576822801739864'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/bindable-behaviours.html' title='Bindable behaviours'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-4459168726547172476</id><published>2008-02-14T02:01:00.000-08:00</published><updated>2008-02-14T02:04:50.521-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='HABTM'/><title type='text'>HABTM Add &amp; Delete Advanced Behaviour</title><content type='html'>HABTM is quite a hard concept to wrap your head around. And not knowing much about the black box that is cake make it a tad harder. But thanks to Brandon Parise from his post here: &lt;a href="http://bakery.cakephp.org/articles/view/add-delete-habtm-behavior"&gt;http://bakery.cakephp.org/articles/view/add-delete-habtm-behavior&lt;/a&gt;, you don't need to hack a automatic handler for deleting and adding HABTM items.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-4459168726547172476?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/4459168726547172476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=4459168726547172476' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4459168726547172476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4459168726547172476'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/habtm-add-delete-advanced-behaviour.html' title='HABTM Add &amp; Delete Advanced Behaviour'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-6360726872036818630</id><published>2008-02-12T23:12:00.001-08:00</published><updated>2008-02-12T23:22:01.750-08:00</updated><title type='text'>Using the Coolest DHTML/Javascript Calendar in CakePHP</title><content type='html'>The helpers in CakePHP are great but some things aren't all that great. One of them is the form date helper. It is really annoying to have to click on 3 select box for every date you want to key in. So finally I tried looking around and found &lt;a href="http://nik.chankov.net/2007/09/13/advanced-datepicker-helper-for-cakephp/"&gt;http://nik.chankov.net/2007/09/13/advanced-datepicker-helper-for-cakephp/&lt;/a&gt;. Followed the instruction on the page and it worked like a charm. Only problem is that apart from adding the helper in the controller, you also have to type in the lines to include the javascript in every view that uses it (that is at least the add and edit view). So I've changed the Helper a bit so that it would include the link automatically before it render.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt;* Autocomplete Helper&lt;br /&gt;*&lt;br /&gt;* @author  Nik Chankov&lt;br /&gt;* @website http://nik.chankov.net&lt;br /&gt;* @version 1.0.0&lt;br /&gt;*&lt;br /&gt;* @updated   2008-02-13&lt;br /&gt;* @author    Abdullah&lt;br /&gt;* @website   http://abdullahsolutions.com&lt;br /&gt;* @changes   Used helpers array. Also used beforeRender so that the javascripts and theme is automatically loaded&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;class DatePickerHelper extends FormHelper {&lt;br /&gt;   &lt;br /&gt;    var $format = '%Y-%m-%d';&lt;br /&gt;    var $helpers = array('Javascript','Html');&lt;br /&gt;   &lt;br /&gt;    /**&lt;br /&gt;     *Setup the format if exist in Configure class&lt;br /&gt;     */&lt;br /&gt;    function _setup(){&lt;br /&gt;        $format = Configure::read('DatePicker.format');&lt;br /&gt;        if($format != null){&lt;br /&gt;            $this-&gt;format = $format;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function beforeRender(){&lt;br /&gt;     echo $this-&gt;Javascript-&gt;link('jscalendar/calendar.js');&lt;br /&gt;     echo $this-&gt;Javascript-&gt;link('jscalendar/lang/calendar-en.js');&lt;br /&gt;     echo $this-&gt;Javascript-&gt;link('common.js');&lt;br /&gt;     echo $this-&gt;Html-&gt;css('../js/jscalendar/skins/aqua/theme');&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    /**&lt;br /&gt;    * The Main Function - picker&lt;br /&gt;    *&lt;br /&gt;    * @param string $field Name of the database field. Possible usage with Model.&lt;br /&gt;    * @param array $options Optional Array. Options are the same as in the usual text input field.&lt;br /&gt;    */   &lt;br /&gt;    function picker($fieldName, $options = array()) {&lt;br /&gt;        $this-&gt;_setup();&lt;br /&gt;        $this-&gt;setFormTag($fieldName);&lt;br /&gt;        $htmlAttributes = $this-&gt;domId($options);       &lt;br /&gt;        $divOptions['class'] = 'date';&lt;br /&gt;        $options['type'] = 'text';&lt;br /&gt;        $options['div']['class'] = 'date';&lt;br /&gt;        $options['after'] = $this-&gt;Html-&gt;link($this-&gt;Html-&gt;image('../js/jscalendar/img.gif'), '#', array('onClick'=&gt;"return showCalendar('".$htmlAttributes['id']."', '".$this-&gt;format."'); return false;"), null, false);&lt;br /&gt;       &lt;br /&gt;        $output = $this-&gt;input($fieldName, $options);&lt;br /&gt;       &lt;br /&gt;        return $output;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    function flat($fieldName, $options = array()){&lt;br /&gt;        $this-&gt;_setup();&lt;br /&gt;        $this-&gt;setFormTag($fieldName);&lt;br /&gt;        $htmlAttributes = $this-&gt;domId($options);       &lt;br /&gt;        $divOptions['class'] = 'date';&lt;br /&gt;        $options['type'] = 'hidden';&lt;br /&gt;        $options['div']['class'] = 'date';&lt;br /&gt;        $hoder = '&lt;div id="'.$htmlAttributes['id'].'_cal'.'"&gt;&lt;/div&gt;&lt;script type="text/javascript"&gt;showFlatCalendar("'.$htmlAttributes['id'].'", "'.$htmlAttributes['id'].'_cal'.'", "'.$this-&gt;format.'", function(cal, date){document.getElementById(\''.$htmlAttributes['id'].''.'\').value = date});&lt;/script&gt;';&lt;br /&gt;        $output = $this-&gt;input($fieldName, $options).$hoder;&lt;br /&gt;       &lt;br /&gt;        return $output;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-6360726872036818630?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/6360726872036818630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=6360726872036818630' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6360726872036818630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6360726872036818630'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/using-coolest-dhtmljavascript-calendar.html' title='Using the Coolest DHTML/Javascript Calendar in CakePHP'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-8925285654433610136</id><published>2008-02-12T19:33:00.000-08:00</published><updated>2008-02-12T19:48:08.921-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp login'/><title type='text'>Finally a working login in CakePHP</title><content type='html'>Waaah!!! It took so long for me to finally get this working right. I can hardly believe it. Based on the very helpful tutorial I've posted before, I finally got a you've got to login first before anything at all kind of website.&lt;br /&gt;&lt;br /&gt;I used the validateLogin function in the said tutorial in my User model and the login, logout function in my UsersController. Then I modified app_controller to have a beginFilter like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeFilter() {&lt;br /&gt;       if($this-&gt;Session-&gt;check('User') == false){&lt;br /&gt;           if($this-&gt;name!='Users' || ($this-&gt;action!='login' &amp;amp;&amp;amp; $this-&gt;action!='logout')){&lt;br /&gt;               $this-&gt;redirect(array('controller'=&gt;'users','action'=&gt;'login'));&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So I didn't change the beforeFilter in the UserController like the tutorial but in the app_controller. And based on the __validateLoginStatus function I changed a bit to check whether there is a valid user session first. If there isn't one then if they are trying to view other controllers (the name variable is the name of the current controller) other than Users or if they are even using users but doing other actions apart from login and logout then redirect to the users login page. Fuh.. finally...&lt;br /&gt;&lt;br /&gt;And just to mention a bit, if you want to check for the session in a view (maybe different menu for logged in user) then use $session directly as in:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if($session-&gt;check('User'))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And now the path is open to more development.. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-8925285654433610136?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/8925285654433610136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=8925285654433610136' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/8925285654433610136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/8925285654433610136'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/finally-working-login-in-cakephp.html' title='Finally a working login in CakePHP'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-995194719572717240</id><published>2008-02-11T01:08:00.000-08:00</published><updated>2008-02-11T01:09:43.992-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><title type='text'>Create a login in CakePHP</title><content type='html'>By refering to &lt;a href="http://bakery.cakephp.org/articles/view/simple-form-authentication-in-1-2-x-x"&gt;http://bakery.cakephp.org/articles/view/simple-form-authentication-in-1-2-x-x&lt;/a&gt;, I was able to do a basic login page in CakePHP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-995194719572717240?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/995194719572717240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=995194719572717240' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/995194719572717240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/995194719572717240'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/create-login-in-cakephp.html' title='Create a login in CakePHP'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-4321926011866397433</id><published>2008-02-11T00:11:00.000-08:00</published><updated>2008-02-11T00:16:20.352-08:00</updated><title type='text'>Update on rendering element in CakePHP</title><content type='html'>I am not sure whether I made a mistake in the previous post or something has changed in cake. Anyhow, I wasn't able to do a simple $this-&gt;renderElement call to render my elements. After a bit of testing and trying it out some more, it seems you've got to actually echo out the result. So in the end it had to be like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?php echo $this-&amp;gt;element('topbanner');&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice also that I'm just saying just element rather than renderElement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-4321926011866397433?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/4321926011866397433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=4321926011866397433' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4321926011866397433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4321926011866397433'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/02/update-on-rendering-element-in-cakephp.html' title='Update on rendering element in CakePHP'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-4158612037296842134</id><published>2008-01-30T17:07:00.000-08:00</published><updated>2008-01-30T17:14:42.550-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Rendering page elements in CakePHP</title><content type='html'>Most of the time, a web application will have some parts which are pretty constant no matter what you are viewing or editing. How to render these parts are not directly obvious since most of the CakePHP tutorials focus on developing the MVC parts of the application. After much code digging in some CakePHP applications, I've concluded that it is done using the renderElement function. You'll use it something like this in your app/views/layouts/default.ctp:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?php $this-&gt;renderElement('mainmenu'); ?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And then you'll have to create the file mainmenu .ctp in the app/views/elements directory. Piece of CakePHP eh.. ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-4158612037296842134?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/4158612037296842134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=4158612037296842134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4158612037296842134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/4158612037296842134'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/01/rendering-page-elements-in-cakephp.html' title='Rendering page elements in CakePHP'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-1598980722348773173</id><published>2008-01-08T05:06:00.000-08:00</published><updated>2008-01-08T05:28:09.484-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code igniter'/><category scheme='http://www.blogger.com/atom/ns#' term='cakephp'/><category scheme='http://www.blogger.com/atom/ns#' term='framework'/><category scheme='http://www.blogger.com/atom/ns#' term='template engine'/><category scheme='http://www.blogger.com/atom/ns#' term='smarty'/><title type='text'>Some nice frameworks</title><content type='html'>I have been coding raw php for quite some time now (coming up to 3 years already) and I didn't find any need to look to other things which was available for free on the web like a proper framework or even a template engine. But now I've pretty much run out of gas started looking for thing which could my life as a php developer much easier.&lt;br /&gt;&lt;br /&gt;The first thing I tried to look for a was better framework. Thanks to very excellent marketing done by the ruby on rails people, I found it's php counterpart, &lt;a href="http://www.cakephp.org/" target="_blank"&gt;CakePHP&lt;/a&gt;. I have not made any production system with it yet, but from my limited amount of experimentation it is an excellent implementation of MVC concept in PHP. I like being able to sculpt the view for the application without worrying that I might break any part of the application. I like the pretty urls we can use to determine what we want to serve our clients. I like the active record concept where it will fetch even the data in other tables connected to the item. Very nice.&lt;br /&gt;&lt;br /&gt;And one of my co-workers introduced me to his favorite framework, &lt;a href="http://codeigniter.com/" target="_blank"&gt;CodeIgniter&lt;/a&gt;. It has most of the things I like about CakePHP and on top of that it is quite raw as in you can even code directly just using some of its helpers rather than having to implement the whole framework. It is that easy to use. But then with parts and parcels like that it doesn't have the full active record concept of loading dynamically the data associated with the current data. But still it is an excellent framework.&lt;br /&gt;&lt;br /&gt;Apart from frameworks, I was also looking into a template engine to ease my coding if I ever have to code raw. And I found &lt;a href="http://www.smarty.net/" target="_blank"&gt;smarty&lt;/a&gt;. It made me fall in love with the idea of using templates for my projects as it's clear and unobtrusive syntax won my heart. But alas, it is only a template engine. It doesn't pretty up your urls, doesn't handle your data for you and all other things. So I might use it one day, but most probably only for small projects which wouldn't require a full blown framework like CakePHP and CodeIgniter. Who knows...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-1598980722348773173?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://php.abdullahsolutions.com/feeds/1598980722348773173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8740441542827453634&amp;postID=1598980722348773173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/1598980722348773173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/1598980722348773173'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/01/some-nice-frameworks.html' title='Some nice frameworks'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8740441542827453634.post-6642953392924876820</id><published>2008-01-04T08:55:00.000-08:00</published><updated>2008-01-04T08:57:34.907-08:00</updated><title type='text'>First post</title><content type='html'>It is customary....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hello, world!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8740441542827453634-6642953392924876820?l=php.abdullahsolutions.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6642953392924876820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8740441542827453634/posts/default/6642953392924876820'/><link rel='alternate' type='text/html' href='http://php.abdullahsolutions.com/2008/01/first-post.html' title='First post'/><author><name>Abdullah Zainul Abidin</name><uri>https://profiles.google.com/104618231658844927334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-V6ii0g6EFgs/AAAAAAAAAAI/AAAAAAAAAGA/d5d3IBVzT9M/s512-c/photo.jpg'/></author></entry></feed>
