Archive for the ‘cakephp’ Category

Implementing softdelete with cakephp

Softdeleting in terms of database generally means marking the record as delete rather than physically removing the record from the db. It is specifically useful in cases like CRMs where we want to retain the data for future reference in the database. There are a few behaviors to implement Softdelete behavior in cakephp. We researched on them and finally decided to use cakesyrup’s softdeleteable behavior. Another good option is to use CakeDC Utils SoftDelete Behavior but at the time of this writing the behavior required quite a few changes for it to be used effectively. How to Use Softdeleteable in a cakephp application
  • Download the behavior from the sourceforge on the above said link and copy it to app/Model/Behavior
  • Add the behavior to the $actsAs member of the model that needs to be softdeleted:
    class User extends AppModel {
    var $actsAs = array('SoftDeletable');
    }
    
  • By Default it works on two fields in a table named deleted, delete_date, but if you want to use the different fields from your table, you can configure that in the options to the Softdeletable behavior:
    var $actsAs = array('SoftDelete'=> array('field' => '0'));
    
  • Thats it. Now whenever you perform a delete action on certain model, then it won’t delete that record permanently instead will set deleted as 1 hence it won’t be resulting in the finder queries that you shoot for the model. Enjoy retaining your records from deleting permanently !!

Simple Acl controlled Application with cakephp

What is ACL? ACL or Access Control List is a common means to control access to applications or sites at a granular level. The basic premise is simple; you have ‘whos’ and ‘whats’. The combination determines who can access what. Why ACL? Unless you want access all or nothing, you need to consider ACLs. An ACL specifies which users or system processes are granted access to objects, as well as what operations are allowed on given objects. Requirements:
  • A running web server (eg:Apache )
  • A database server (eg:MySQL)
  • Basic PHP knowledge
Steps to Implement ACL:
  • Get a fresh copy of CakePhP
  • To get a fresh download, visit the CakePhP project at Cake forge: http://github.com/cakephp/cakephp/downloads and download the stable release.
  • Configure database.php and core.php.
  • Once you’ve got a fresh copy of cake setup your database.php configure file, and change the value of Security. Salt in your app/config/core.php.
  • Create Database and tables.
  • We will build a simple database schema to build our application on. Execute the following SQL statements into your database.
CREATE TABLE users (
 id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 username VARCHAR(255) NOT NULL UNIQUE,
 password CHAR(40) NOT NULL,
 group_id INT(11) NOT NULL,
 created DATETIME,
 modified DATETIME
 );
CREATE TABLE groups (
 id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 name VARCHAR(100) NOT NULL,
 created DATETIME,
 modified DATETIME
 );
CREATE TABLE posts (
 id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 user_id INT(11) NOT NULL,
 title VARCHAR(255) NOT NULL,
 body TEXT,
 created DATETIME,
 modified DATETIME
 );
Create models, controllers, and views: These are the tables we will be using to build the rest of our application. Once we have the table structure in the database we can start cooking. Use cake bake to quickly create your models, controllers, and views. Implement Auth: In App Controller add the following
class AppController extends Controller {
var $components = array('Acl', 'Auth', 'Session');
var $helpers = array('Html', 'Form', 'Session');
function beforeFilter() {
//Configure AuthComponent
$this->Auth->authorize = 'actions';
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'logout');
$this->Auth->loginRedirect = array('controller' => 'posts', 'action' => 'add');
}
}
Initialize the Db Acl tables (create your ACL database tables) Before we create any users or groups we will want to connect them to the Acl. However, we do not have any Acl tables at this time and if you try to view any pages right now, you will get a missing table error (“Error: Database table acos for model Aco was not found.”). To remove these errors we need to run a schema file. In a shell run the following: style=”text-align: justify;”>cake schema create DbAcl This schema will prompt you to drop and create the tables. Say yes to dropping and creating the tables. Acts as a Requester For Auth and Acl to work properly we need to associate our users and groups to rows in the Acl tables. In order to do this we will use the AclBehavior. The AclBehavior allows for the automatic connection of models with the Acl tables. Its use requires an implementation of parent Node () on your model. In User model we will add the following.
">var $name = 'User';
var $belongsTo = array('Group');
var $actsAs = array('Acl' => array('type' => 'requester'));
function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['group_id'])) {
$groupId = $this->data['User']['group_id'];
} else {
$groupId = $this->field('group_id');
}
if (!$groupId) {
return null;
} else {
return array('Group' => array('id' => $groupId));
Then in Group Model add the following:
var $actsAs = array('Acl' => array('type' => 'requester'));
function parentNode() {
return null;
}
The controllers and models are now prepped for adding some initial data and Group and User models are bound to the Acl table. So add some groups and users using the baked forms by browsing to: //example.com/groups/add and: //example.com/users/add. We have made the following groups:
  • administrators
  • managers
  • users
Create ACOs (Access Control Objects): Now that we have our users and groups (arose), we can begin inputting our existing controllers into the Acl and setting permissions for our groups and users, as well as enabling login / logout.

Our ARO are automatically creating them when new users and groups are created. What about a way to auto-generate ACOs from our controllers and their actions? Well unfortunately there is no magic way in CakePhP core to accomplish this. The core classes offer a few ways to manually create ACO’s though. You can create ACO objects from the Acl shell or you can use the AclComponent. Creating Acos from the shell looks like: cake acl create aco root controllers While using the AclComponent it would look like:

$this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'controllers'));
$this->Acl->Aco->save();
Both of these examples would create our ‘root’ or top level ACO which is going to be called ‘controllers’. The purpose of this root node is to make it easy to allow/deny access on a global application scope, and allow the use of the Acl for purposes not related to controllers/actions such as checking model record permissions. Add action path to AppController As we will be using a global root ACO we need to make a small modification to our AuthComponent configuration. AuthComponent needs to know about the existence of this root node, so that when making ACL checks it can use the correct node path when looking up controllers/actions. In AppController add the following to the before Filter:$this->Auth->actionPath = ‘controllers/'; Setting Permissions
style="text-align: justify;">In Controller add a function to allow and deny access
style="text-align: justify;">$this->Acl->allow($aroAlias, $acoAlias);
eg: -$group =& $this->User->Group;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Posts/add');
Or in cmd:
grant   [] or all
Use this command to grant ACL permissions. Once executed, the ARO
specified (and its children, if any) will have ALLOW access to the
specified ACO action (and the ACO's children, if any).
For more detailed parameter usage info,
see help for the 'create' command.
deny   []or all
Use this command to deny ACL permissions. Once executed, the ARO
specified (and its children, if any) will have DENY access to the
specified ACO action (and the ACO's children, if any).
For more detailed parameter usage info,
see help for the 'create' command.

All done You should now have an application controlled by Auth and Acl.


Generating UUID with cakephp

Most of the Database implementations use auto increment integers as primary keys, but in some cases we might need a random string like UUID as primary key. UUID is a 32 byte string separated by four hyphens, for a total of 36 characters. For example: 550e8400-e29b-41d4-a716-446655440000 One of the major advantages of using UUID is that it can be generated in parallel without communication between clustered DB servers. These are unique, not only within a single table, but also across tables and databases. With this, I hope you might have got some idea about UUID, let us now talk about how to implement it in our database in cake PhP projects. In Cake php’s uuid implementation is based on RFC 4122 standard. It is basically splitted as:
  • time_low
  • time_mid
  • PHP process ID
  • node
Time_low and Time_mid constitute the Timestamp value which is of 60 bit . The node field consists of an IEEE 802 MAC address, usually the host address or the host name. Implementation: It is very easy all you need is to specify your primary key as a CHAR (36) or BINARY (36) and CakePhP will automatically generate them for you, when new records are created. Or alternatively you can use the String class which includes convenience methods for creating and manipulating strings and is normally accessed statically. For example: – $uuid = String::uuid (); It will assign a unique id to $uuid which you can use in your project.

CakePHP User Authentication with Auth Component

When we talk about user authentication, it means there are two type of pages. One that a user can access only after logging in such as posting comments and other where user is allowed to access without any prior login such as products browsing page, etc. User Authentication makes sure that if a user tries to access a page which application denies free access, it redirects the user to logging page and after a successful login brings back to the requested page. Cake provides a very simple and handy User authentication module called Auth component to do this. How does it work: Auth component catches the request before it reaches before filter of the controller and checks if the page is allowed to be displayed Requirements: A users table with username and password as fields. These are the defaults by cake standard. These variables can be defined in before filter of controller. How to do it: 1. Add the Auth to your component lists for the controller in question. I prefer to do it in App controller as usually Auth is required through out the application.
var $components = array('Auth');
2. Define Login/Logout action in users_controller.php
function login()
{
}

function logout(){
	$this->Session->setFlash('Logout');
	$this->redirect($this->Auth->logout());
}
3. A login view for the user in app/views/users/login.ctp
<?php
    echo $form->create('User', array('action' => 'login'));
    echo $form->input('username');
    echo $form->input('password');
    echo $form->end('Login');
?>
4. Settings in Before filter in the controller where Auth is defined in list of components. App_controller for me.
function beforeFilter(){
	// loginAction defines the action which should be used to login. By default users/login
	$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');

	// loginRedirect defines the action called after user is logged in first time.
	$this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'display', 'home');

	// Allows the display action to be accessed without user login.
	$this->Auth->allow('display');
	$this->Auth->authorize = 'controller';
}
5. Defining Auth->allows and Denys By default Auth restricts access to every action except the login and logout methods. You need to define individual in your controller which action to allow. It might be cumbersome to define each action in this list. so the magic word is ‘*’
$this->Auth->allow('*'); // allows all the actions in the controller under auth allow.
6. Accessing Authorized user in controllers. Auth stores all the information in session and can be retrieved via:
$this->Auth->user(); // returns the User record information at the time of logging in
$this->Auth->user('id'); // when passed a field, this function returns the field value instead of whole array.
Pitfalls: The biggest pitfall of using the Auth comes in the redirect. When a user fills a form and the action is in denied list, user will be redirected to the login page followed by the action page. By then, all the information of form is lost as Auth DOES NOT retrieve form or POST data. Reference: Cakephp Book

Code Generation with Bake all in CakePHP

Each MVC module contains a Model, a Controller and multiple views for each table in the application. It can be a big pain to write all the controllers, models and views for your application from scratch and define the relationships. Not only it’s time consuming, banal, it is prone to errors in defining relationships and constraints. To make life easy its time to use Cake’s scaffolding console for code generation, known as Bake. Launching Bake: For Baking, we will have to use PHP executable. Rather than typing PHP path each time, I prefer to include php executable path to the environment variable paths, for comfort rather than necessity. For windows, it’s accessible via -> Right click on “My Computer”->Properties. -> Go to “Advanced“ tab. Click on environment variables. -> Go to system variable path and edit it. -> Add PHP path (Mine is xampp E:/xampp/php) and cake console (E:/xampp/htdocs/cake/console) paths, separated by semicolons. You might need to restart system after adding these paths. Sometimes the bake command doesnt work on windows even after changing environment variables. Make sure you use the correct forward slash for this when giving path for console and php. Sample Path post editing should look like C:Documents and SettingsEnbake>path PATH=C:WINDOWSsystem32;C:WINDOWS;C:WINDOWSSystem32Wbem;C:Program FilesTortoiseSVNbin;E:/xampp/htdocs/campaign3/cake/console;E:/xampp/php;

Sample PATH variable

Time for pre heat Go to the app folder of your application through console. Type “cake bake”. This will give you following screen.  We have two options here:
  1. If your database.php is updated with connectivity settings, this will pick existing tables and give you option to bake them. Cakephp Bake Console
  2. But if DB information is missing in databse.php, we can configure it using ‘D’ as an option to bake. It will prompt us for all the settings and create necessary models, views & controllers.
Super Bake : bake all If you are sure about your DB and don’t want to go individual on baking separately for MVC, you can avail option of bake all. Instead of models this time it will ask you for each entity and on pressing the number it will create models, controllers and views. Hope baking will be as simple as walking through the cake & will save you precious time in coding skeleton for controllers, models and views. Especially when doing a feasibility study or brief demo to the client on the app. Optional Enhancements: Over 1.2 the recent released 1.3 bake has had a significant jump, and a number of features and enhancements have been added.
  • New tasks (FixtureTask and TestTask) are added to the main bake menu
  • TemplateTask has been added for use in the shells.
  • All the different bake tasks now can use connections other than default for baking. Using the -connection parameter.
  • Multiple validations on models has been added.
  • Self Associated models using parent_id are now detected. For example if your model is named Thread, a ParentThread and ChildThread association will be created.
  • Baked Tests include as many fixtures as they know about, including plugin detection (plugin detection does not work on PHP4).
Happy Baking !!!

Useful cakephp resources

As we moved forward developing newer and better applications in cakephp, we came across many great resources for cakephp. I will try enlisting a few of them here(not in any specific order) and will keep adding to them as I come across any. If you know of any great resource, please enlist that in the comment and I will add it here to the post. 1. Official CakePHP website: The number one source for CakePHP manuals, blogs, API’s, articles and tutorials is Official CakePHP website. 2. Donutczar.com: It provides great information and examples on Helpers in CakePHP 1.2, a really good source for people who want a hand’s on and visual explanation. 3. cakebaker.42dh.com: It provides new and brilliant ideas for CakePHP applications and offers easy to understand and user-friendly tutorials. 4. ThinkingPHP: ThinkingPHP is an all-round PHP information site. It also has a very helpful and detailed area dedicated to CakePHP. ThinkingPHP also monitors other popular CakePHP blogs and provides all the information in a common and easy to manage area. 5. Rolsoft.wordpress.com: The RolSoft Blog is an oldie, but a goodie! It has articles on integrating AJAX, speeding up SQL queries in CakePHP and much more. Most of the content is outdated, but it still serves to point people in the right direction and to offer food for thought. 6. Mariano Iglesias: This blog has buckets of information, everything from CakeFest information, CakePHP tips, framework write-ups and more. 7. CakePHP Google Group: This is the official Google Code group for CakePHP and it has a large member base. The community is very active and can be really helpful if you get stuck somewhere. 8. Tim Trice: This is a great blog that concentrates on articles aimed at the CakePHP beginner. Here, articles ranging from “What CakePHP can do” extend to extending the CakePHP Blog tutorial. 9. CakePHP.nu: Another little CakePHP blog that had a couple of articles that really stood out to me. It is relatively new so there isn’t a great deal of content, but its more like quality over quantity. 10. In the Kitchen with CakePHP: This isn’t really a “site” as such but I thought it was worth a mention. “In the Kitchen with CakePHP” is a great tutorial for beginners who need a start to finish walkthrough of CakePHP and its features; it is also useful to have a read before selecting CakePHP as your framework of choice as it goes over many of the key features. 11. Andy Dawson’s Blog : Andy Dawson(ad7six) is a geek who has contributed several modules(components, behaviors, helpers or even modifying the core code) to cakephp core. If you are using cakephp, then you are most probably using one of his contributions. His blog is a great source of cakephp related information and a great guide to handling complex and simple problems with caekphp. 12. Debuggable Blog : Debuggable is a company focussed on writing cakephp and jquery applications. Felix Geisendörfer and Tim Koschützki founded debuggable. The Company’s blog is a great set of articles on the solution of real time problems in cakephp.

iPad in cakefest is now confirmed !!!

Yes, You heard it right. Graham Weldon (AKA: Predominant) put an end to the rumors regarding the giving away of an iPad in cakeFest 2010. In a mail sent to pretty active cakephp community on google groups, Graham said : “While we had hoped to keep this information under wraps until the event was underway, however we are required to address to rumours. CakeFest 2010 will indeed involve the giveaway of an Apple iPad device. This will be a random pool from the attendee! Thats right, just by having purchased a ticket, you will be eligible to win an Apple iPad on the conference days. The winner is required to be onsite at the announcement to collect the iPad, or another winner will be randomly selected from the pool of attendees.” Also, just for reminder the early bird ticketing for cakefest 2010 ends on 24th July. So in case you plan to attend the cakefest, its your chance to grab the tickets now at a much cheaper rate. Go Cake, go !!!

mysql COLUMN_UPDATED() and bitwise operations

Sometimes to achieve a certain functionality, you need to determine the columns that were updated after the mysql update query. I will try to explain how to achieve this in this particular article. The article contains the reference to cakephp constructs because i happened to use this in a cakephp application. Handling Bits in General: Let me discuss about the basics of how we can do bitwise operations in php(The code contains references to cakephp constructs but the logic remains the same).
  • Depending on the number of bits that need to be used declare an attribute of type INT.
  • Tiny – 8bits, Small- 16 bits, Med – 24  bits or Int – 32 bits
  • smallint $status = 0;
  • Declare each flag that needs to be used as following in model in powers of 2.
<code><em>class</em><em> Node </em><em>extends</em><em> AppModel {</em></code>

<em>const</em><em> flag1 =1;//00000001 </em>

<em>const</em><em> flag2 =2;//00000010</em>

<em>const</em><em> flag3 =4;//00000100</em>

<em>const</em><em> flag4 =8;//00001000</em>

<em>}
  • Check if a particular flag is set:  if($status & Node::flag2) { echo “flag 2 is set”;}
  • Set a flag: $status |= Node::flag3;
  • Unset a flag: $status = $status &~ Node::flag3;
  • Check how many flags are set:
<em>function </em><em>get_count($status){</em>

<em> $i=0;</em>

<em> while ($status){ $i++ ; $status &= ($status - 1) ; }</em>

<em> return $i; </em>

<em> }
MySql – COLUMNS_UPDATED() Mysql columns_updated works on the similar logic as explained above. COLUMNS_UPDATED() returns a varbinary bit pattern that indicates the columns in a table or view that were inserted or updated. COLUMNS_UPDATED is used anywhere inside the body of a Transact-SQL INSERT or UPDATE trigger to test whether the trigger should execute certain actions. COLUMNS_UPDATED returns one or more bytes that are ordered from left to right, with the least significant bit in each byte being the rightmost. The rightmost bit of the leftmost byte represents the first column in the table; the next bit to the left represents the second column, and so on. COLUMNS_UPDATED returns multiple bytes if the table on which the trigger is created contains more than eight columns, with the least significant byte being the leftmost. COLUMNS_UPDATED returns TRUE for all columns in INSERT actions because the columns have either explicit values or implicit (NULL) values inserted. To test for updates or inserts to specific columns, follow the syntax with a bitwise operator and an integer bitmask of the columns being tested. For example, table t1 contains columns C1, C2, C3, C4, and C5. To verify that columns C2, C3, and C4 are all updated (with table t1 having an UPDATE trigger), follow the syntax with & 14(bitwise and operation). To test whether only column C2 is updated, specify & 2. Hope this helps someone !!

How to setup home page in cakephp application

There are two possibilities which you might think before setting the home page of your application (aka setting the root of your application). 1. Static Home Page : In this case you can change the content you would like to add to your home page in the following file in your cakephp framework  “APP/views/pages/home.ctp”. (.ctp aka cake template) Now if this simply does not work for you much and you want your home page to be fancy. You can change its Layout and create a file if its not already present in “APP/views/layouts/default.ctp”. If you want to do more fancy stuff like changing the icon or adding a style sheet,  you can do it easily with Nifty HTMLHelper.
echo $this->Html->meta('icon');
echo $this->Html->css('cake.generic');
cake.generic is the default Style Sheet present in “APP/webroot/css/cake.generic.css”. You can add your own Style Sheet in the css directory and make the respective change of the name in default.ctp Now if you have many layouts in your application and your home page uses a layout called homepage.ctp, you will have to specify a property in the respective controller “APP/controllers/pages_controller.php” as follows:
$this->layout = ‘homepage’;
2. Dynamic Home Page : On the other hand, if you don’t want to be stuck with home.ctp as your default main page. All you need to do is simply designate a new root (/) route. Let’s take an example… I have a users Controller (users_controller.php), which has an action called signup() and also It pulls data from various User model methods and utilizes some features of the App Controller. And i would prefer that page (summary) to be my new “home”. So, rather than dealing with Pages Controller, I simply replace the default route (in app/config/routes.php) with
Router::connect('/', array('controller' => 'users', 'action' => 'signup'));
I hope that this gives clear enough an idea of how to setup the home page in the cakephp application. Please feel free to leave any  comments  or doubts that you  might have and I would be more than happy to answer.