Tuesday, 19 August 2014

Simple CakePHP captcha component for CakePHP 2.x

Here is the latest CakePHP Captcha component for CakePHP Version 2.x. Compatible up to CakePHP version 2.5.3.
NOTE:For best Image Captcha results this component requires GD and Freetype support enabled. Please check your phpinfo() to know whether your server supports this (See image below). Contact your hosting provider if any of these libraries is not enabled.
gd-free-type-enabled
Captcha-Component-for-CakePHP-2.x
Update – Sep 25, 2013
§  Supports Image and Simple Math captcha
§  Works without GD Truetype font support (NOT RECOMMENDED though)
§  Default and Random themes for Image Captcha
§  Checks for missing font file
Updated on – Sep 19, 2013
§  Had been reported of issues related to missing font file so i have updated the controller function to detect the existence of font file. Dies with error on missing font file. So don’t forget to upload attached font file. If you wanted to use a different font upload it to webroot folder and change settings['font'] parameter
Updated on – April 12, 2013
§  Random captcha images are possible. Set “theme”=>”random” in $settings variable of CaptchaComponent.php or in Controller when loading captcha component.
§  Can’t Read? Reload is possible now. A working piece of jQuery code is included in view fileadd.ctp. Be sure to include jquery library, such ashttps://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js to make Reloading of captcha working
How to make it working
Download attached zip file and extract. Copy all files placed in app folder to their corresponding locations.
I created “SignupsController” controller and Signup.php model for demonstration purpose. Create a function similar to the following in your controller.
function captcha() {
 $this->autoRender = false;
 $this->layout='ajax';
 if(!isset($this->Captcha)) { //if Component was not loaded through $components array()
 $this->Captcha = $this->Components->load('Captcha', array(
 'width' => 150,
 'height' => 50,
 'theme' => 'random', //possible values : default, random ; No value means 'default'
 )); //load it
 }
 $this->Captcha->create();
 }
Call the captcha action from within your form tag in the view file, as below:
echo $this->Session->flash();
echo $this->Form->create("Signups");
$this->Captcha->render($captchaSettings);
echo $this->Form->submit(__(' Submit ',true));
echo $this->Form->end();
And you are done! The captcha image should look like Cakephp Captcha COmponent
This component includes a model file i.e. Model/Signup.php file to demonstrate the use of model validation for captcha input by user. The validation works just like any other custom model validation in CakePHP.


Friday, 15 August 2014

HTML5 Input Types

HTML5 New Input Types

HTML5 has several new input types for forms. These new features allow better input control and validation.
This chapter covers the new input types:
  • color
  • date
  • datetime
  • datetime-local
  • email
  • month
  • number
  • range
  • search
  • tel
  • time
  • url
  • week
Note:
Not all browsers support all the new input types. However, you can already start using them; If they are not supported, they will behave as regular text fields.

Input Type: color

The color type is used for input fields that should contain a color.
<!DOCTYPE html>
<html>
<body>

<form action="demo_form.asp">
  Select your favorite color: <input type="color" name="favcolor"><br>
  <input type="submit">
</form>

</body>
</html>

Output:

Select your favorite color: 

Input Type: date

The date type allows the user to select a date.
<!DOCTYPE html>
<html>
<body>

<form action="demo_form.asp">
  Birthday: <input type="date" name="bday">
  <input type="submit">
</form>

</body>
</html>

Output:
Birthday:  

Input Type: email

The email type is used for input fields that should contain an e-mail address.
Define a field for an e-mail address (will be automatically validated when submitted):
<!DOCTYPE html>
<html>
<body>

<form action="demo_form.asp">
  E-mail: <input type="email" name="email">
  <input type="submit">
</form>

<p><b>Note:</b> type="email" is not supported in Internet Explorer 9 and earlier versions.</p>

</body>
</html>

Output:
E-mail:  
Note: type="email" is not supported in Internet Explorer 9 and earlier versions.

CakePHP Pagination Change Label

Here we can change the displayed label for CakePHP Pagination:

Say, we want to sort results by user_id.

This is how it is done by default:

<?php echo $paginator->sort('user_id');?> 


And to change the displayed label:
 <?php echo $paginator->sort('User', 'user_id');?> 

Here User is the label which will be displayed.
user_id is the field to be sorted.

How to Generate Options for HTML Select Tags in CakePHP

How to generate options for HTML Select Tags in CakePHP?

As such

  1. You can retrieve options from a Model (Database Table).
  2. Or, you can specify options for select tag in view files.
Just keep in mind CakePHP does not support ENUM type field. So, you may not use 'ENUM' datatype in table fields.

To retrieve options from Database Table

Say, you have two Models (tables) - Order and Size; 

Fields in 'sizes' table:
id, size
And fields in 'orders' table:
id, quantity, size_id

In your OrdersController file (/app/controllers/orders_controller.php)
$sizes = $this->Order->Size->find('all');
$this->set('sizes',$sizes);

Now in your view file: (/app/views/orders/add.ctp)

echo $form->create('Order');
echo $form->input('quantity');
echo $form->input('size_id');
echo $form->end('Submit');

And done.

Note the use of variable names. 
It is important to name the variables as per this convention. It will display all sizes available in database when you are adding a new order. To retrieve size field in table 'sizes', you need to specify variable name 'sizes' (note plural form) in your respective controller/action.  Now when you refer to 'size_id' in view file - cake will create a select tag on the fly with options retrieved from database.  

OK. It was pretty simple.

Now, how to display options for HTML Select Tag without any database table:

In this case, we have, say, only 'orders' table with following fields
id, quantity, size

In your view file (/app/views/orders/add.ctp), specify - 

$form->create('Order');
$form->input('quantity');
$sizes = array('s'=>'Small', 'm'=>'Medium', 'l'=>'Large');
echo $form->input('size', array('options'=>$sizes, 'default'=>'m'));
$form->end('submit');

That's it.

CakePHP - Edit a Record in Database

So, the keen readers may guess what we need to do to edit a record in our 'posts' table.
Step:
1. Open posts_controller.php (found under '/app/controllers' folder).
2. Copy-paster the function edit() to edit record.


function edit($id = null) 
{   $this->Post->id = $id; 
  if (empty($this->data)) { 
  $this->data = $this->Post->read(); 
}
 else {  
if ($this->Post->save($this->data)) {

   $this->Session->setFlash('Your post has been updated.');
   $this->redirect(array('action' => 'index')); 
  }  
}  


}
As such, this function edit() is self-explanatory. If you read it carefully, the function edit() expects '$id' value.
$this=>data contains form submitted data. If it is empty ($this=>data will obviously be empty the first time you try to edit a record), the function $this->Post->read() reads the record from database and stores it at $this->data variable to display the same via edit form. If some data has been submitted, the function $this->Post->save($this->data); tries to save that data by updating the respective record.

Now we need to create a form (Cake calls it 'view') to edit record.
Step:
1. Create a new file.
2. Copy-paste following code:
<h1>Edit Post</h1>
<?php  
echo $form->create('Post', array('action' => 'edit'));  
echo $form->input('title');  
echo $form->input('body', array('rows' => '3'));  
echo $form->input('id', array('type'=>'hidden'));   
echo $form->end('Save Post');  
?>
3. Save this file as 'app/views/posts/edit.ctp'

Now we need to add a link to our index.ctp file to display edit option.

Step:
1. Open index.ctp (found under '/app/views/posts' folder)
2. Add the following line just below the line we have added to show 'delete' option.
<?php echo $html->link('Edit', array('action'=>'edit', 'id'=>$post['Post']['id']));?>
3. Save that file.

Now point your browser to:
http://caketest.local/posts

You can see the 'Edit' option.
Now if you follow 'Edit' link, you can see the form with respective record.
Here is a screenshot:

  

CakePHP - Delete a Record from Database

If you are following me, you must have learnt how to add a new record to a table.
Let us learn how to delete record.
Steps required:
1. Open file posts_controller.php (Found under '/app/controllers' folder)
2. Add following lines (This is the function to delete record).

function delete($id) {
$this->Post->delete($id);
$this->Session->setFlash('The post with id: '.$id.' has been deleted.');
$this->redirect(array('action'=>'index'));
}
As you can see, $this->Post->delete($id) statement tells Cake (short-form of CakePHP) to delete the record with id = '$id' from posts table.

This is all we need to do in the PostsController (posts_controller.php).

Now let's edit index.ctp file under '/app/views/posts' folder to show 'Delete' option.
Step:
Open the file '/app/views/posts/index.ctp'
Copy the following code and paste it:


<h1>Blog posts</h1>
  <table>
  <tr>
  <th>Id</th>
  <th>Title</th>
  <th>Actions</th>
  <th>Created</th>
  </tr>
 <!-- Here is where we loop through our $posts array, printing out post info -->
<?php foreach ($posts as $post): ?>
  <tr>
  <td><?php echo $post['Post']['id']; ?></td>
  <td>
  <?php echo $html->link($post['Post']['title'], 
  "/posts/view/".$post['Post']['id']); ?>
  </td>
  <td>
  <?php echo $html->link('Delete', array('action' => 'delete', 'id' => $post['Post']['id']), null, 'Are you sure?' )?>
  </td>
  <td><?php echo $post['Post']['created']; ?></td>
  </tr>
  <?php endforeach; ?>
</table>

..............................................................
Save the file. 
Now point your browser to:
http://caketest.local/posts
You can see the screen-shot with DELETE option:

If you follow 'Delete' link, Cake will display a message - 'Are you sure?'
If you confirm delete, the selected record gets deleted.

Now, take a close look at the use of $html->link(); function.

We have learnt already that this function creates a link . This $html->link() function is very versatile like most other functions of CakePHP. 
You can create a link simply by specifying 
$html->link('Link Text','Link Url', array('class'=>'link-class-name'), 'Confirmation Msg [Optional]' );

Here we have created a link in a more sophisticated way. Instead of using link url directly, we have used Cake's powerful link generation feature.
We have used an array() instead of a direct link url.
array('action' => 'delete', 'id' => $post['Post']['id']
Note: we have used 'action'=>'delete' and 'id'=>$post['Post']['id'];
Now Cake will create a link like this one on the fly:
http://caketest.local/posts/delete/2

While going through the CakePHP book I have also noticed that in that array() part, you can actually specify the Controllers also.
array('controller'=>'posts','action' => 'delete', 'id' => $post['Post']['id']) 
Cake will create the same link - http://caketest.local/posts/delete/2 -  without getting confused.
But by default Cake can assume the name of the Controllers in question. So, you may not specify it separately.
That's it.

In my next post, I'll show how to edit record with Cake.