CakePHP - Some controller functions

CakePHP No Comments »

Interacting with your views:

set($variable, $value);
string $variable;
mixed $value;

The principal use of this function is to extract data from a controller and transfer it to a view.
It can be used to transfer single values, whole arrays and so on etc. The moment you utilize set(), the variable can be accessed in your view: doing set(name, john) in your controller makes the variable name available in the view.

validateErrors() - displays the number of all the errors produced by an unsuccessful save.
validate() - this function is used to validate a model data respecting the rules of validation defined in to the model.

render($action, $layout, $file) - this function may not always be needed because render is called by default when every controller action ends, so the view specific to your action is rendered. On the other side, you can call this function to render the view anywhere in the controller code.

CakePHP - About Controllers

CakePHP No Comments »

The role of a controller is that of administering the logic for a special section of your application. In general controllers are utilized in administering the logic for only one model. To take as an example if you were to make up a website that directs a rental-library, you could use a BooksController and a RentalController to administer both your rentals and your books.
Note that in Cake Controller names are only plural.

The controllers of your application are classes that extends the Cake ApplicationController class, which also extends a core Controller class. Controllers may comprise many kinds of actions: functions that are utilized in your web application to show off data in views.

ApplicationController class can be described in /app/appController.php and it may include methods that are distributed among controllers. It itself extends the Controller class which is a standardized in Cake Library.

A controller has an action as it’s single functionality. The Dispatcher directs it automatically if any incoming page request details in routes configuration. Going back to our example with the rental-library, our BooksController is supposed to include the view(), rent(), and search() actions.
The controller should be situated in /app/controllers/bookscontroller.php and include:

PHP:
  1. class BooksController extends AppController{
  2.   function view($id)
  3.   {
  4.     //logic here...
  5.   }
  6.   function rent($customer_id, $video_id)
  7.   {
  8.     //logic here...
  9.   }
  10.   function search($query)
  11.   {
  12.     //logic here...
  13.   }
  14. }

You should be capable to access these actions using the example URLs:
http://www.yourwebsite.com/books/view/Tom-Sawyer
http://www.yourwebsite.com/books/rent/12332/B-213ed
http://www.yourwebsite.com/books/search/Mark+Twain

The data displayed on this pages can be easily formated from the views area, for example for the rent() action we will have: /app/views/books/rent/index.thtml and so on.

CakePHP: upload and resize images

CakePHP 15 Comments »

I searched on Google for a code example of how to upload and resize an image using CakePHP and I didn't get to much results on this, so I decided to make it on my own way. First of all I created the /foto/ directory in the webroot (app/webroot) and inside it other 2 directories, one for the uploaded image /big/ (this is the big version of the image) and one for the image that will be resized /small/ (this can be the thumbnail), be sure that they have write permissions.

Now create a component called image.php and inside it you will have the code that will handle getting the file extension and resizing the uploaded image (app/controllers/components/image.php):

PHP:
  1. class ImageComponent extends Object
  2. {
  3.    function resize_img($imgname,$size)
  4.    {
  5.       //Header("Content-Type: image/jpeg");
  6.       $img_src = ImageCreateFromjpeg ($imgname);
  7.       $true_width = imagesx($img_src);
  8.       $true_height = imagesy($img_src);
  9.  
  10.       if ($true_width>=$true_height)
  11.       {
  12.         $width=$size;
  13.         $height = ($width/$true_width)*$true_height;
  14.       }
  15.       else
  16.       {
  17.        // $height=$size;
  18.        $width=$size;
  19.        $height = ($width/$true_width)*$true_height;
  20.        // $width = ($height/$true_height)*$true_width;
  21.       }
  22.         $img_des = ImageCreateTrueColor($width,$height);
  23.         imagecopyresampled ($img_des, $img_src, 0, 0, 0, 0, $width, $height, $true_width, $true_height);
  24.         return $img_des;
  25.     }
  26.  
  27.     function getFileExtension($str) {
  28.  
  29.         $i = strrpos($str,".");
  30.         if (!$i) { return ""; }
  31.         $l = strlen($str) - $i;
  32.         $ext = substr($str,$i+1,$l);
  33.         return $ext;
  34.     }
  35. }

Now let's see the view that will show the input type file element and the form (app/views/controller_name/upload.thtml):

PHP:
  1. <form method="post" enctype="multipart/form-data" action="<?php echo $this->webroot;?>images/add">
  2.     <p>
  3.        <p>Image: &nbsp; &nbsp; &nbsp; &nbsp; <?php echo $html->file('Image/name1', array('size' => '40'))?>
  4.     </p>
  5.     <p>
  6.         <?php echo $html->submit('Upload image'); ?>
  7.     </p>
  8. </form>


At the end comes the last part and the "hardest", when comes to write the controller code (app/controllers/images_controller.php):

PHP:
  1. class ImagesController extends AppController {
  2. var $components = array("Image"); // here is the image component that we described above
  3.  
  4. function add(){
  5.  
  6. if (strlen($this->data['Image']['name1']['name'])>4){
  7.  
  8.                    $error = 0;
  9.                    $uploaddir1 = "foto/big"; // the /big/ directory
  10.                    $uploaddir2 = "foto/small"; // the /small/ directory with resized images
  11.                    $filetype = $this->Image->getFileExtension($this->data['Image']['name1']['name']);
  12.                    $filetype = strtolower($filetype);
  13.  
  14.                    if (($filetype != "jpeg")  && ($filetype != "jpg"))
  15.                    {
  16.                     // verify the extension
  17.                     $error=1;
  18.                    }
  19.                    else
  20.                    {
  21.                     $imgsize = GetImageSize($this->data['Image']['name1']['tmp_name']); // image size
  22.                    }
  23.                    if (($imgsize[0]> 800) || ($imgsize[1]> 600)){
  24.                      // verify to see if the image exceds 800 x 600 px
  25.                      unlink($this->data['Image']['name1']['name']); // delete the image in case is to big
  26.                      $error=1;
  27.                     }
  28.                     if ($error==0){
  29.  
  30.                       // here is generated an unic id for the image name
  31.                       $stamp = strtotime ("now");
  32.                       $orderid = $stamp;
  33.                       $orderid = str_replace(".", "", $orderid);
  34.                       $id_unic = $orderid;
  35.                       $temp = $id_unic;
  36.                       settype($temp,"string");
  37.                       $temp.= ".";
  38.                       $temp.=$filetype;
  39.                       $newfile = $uploaddir1 . "/$temp";
  40.                     if (is_uploaded_file($this->data['Image']['name1']['tmp_name']))
  41.                     {
  42.                         if (!copy($this->data['Image']['name1']['tmp_name'],"$newfile"))
  43.                         {
  44.                             print "Error Uploading File1.";
  45.                             exit();
  46.                         }
  47.                     }
  48.                     $newfile2 = $uploaddir2 . "/$temp";
  49.  
  50.                      $picture_location=$newfile;
  51.                      $size=110; // the size for the resized image
  52.                      $img_des= $this->Image->resize_img($picture_location, $size); //here resizing
  53.                      imagejpeg($img_des,$newfile2,80);
  54.  
  55.                      // here you can have some code for example to insert in the database
  56.                      // Image uploaded
  57.                    }
  58.               }else{
  59.                       // Image not uploaded
  60.               }
  61.      }
  62. }

This is all.
This script above need to have GD installed on the server.

CakePHP, Simple Contact Form, email sending

CakePHP 12 Comments »

In this post a I will show an example of a simple contact form which sends an email to a specified address, done using CakePHP.
The form has 3 fields: name, email address and message.
Firs of all let's see the "view" for the form displaying. It looks like this (app/views/controller_name/contact.thtml):

PHP:
  1. <?php if (isset($succes)){?> // $succes is the variable which is verified to see if email was sent
  2.      <p>The message has been sent.
  3.      <br />Thank you!
  4.      </p> // Message displayed if success
  5. <?php }else{?>
  6.      <form method="post" enctype="multipart/form-data" action=”<?php echo $this->webroot;?>controllername/contact/”>
  7.      </form>
  8.  
  9. <?php if (isset($erroare)){?> // Verify if is an error and then display error message
  10.       <p>Please complete all fields!</p>
  11. <?}?>
  12.  
  13. <p>
  14.     Name: &nbsp;&nbsp;&nbsp;&nbsp;<?php echo $html->input(’Page/name’, array(’size’ => ‘25))?>
  15. </p>
  16.  
  17. <p>
  18.     Email: &nbsp;&nbsp;&nbsp;&nbsp;<?php echo $html->input(’Page/email’, array(’size’ => ‘25))?>
  19. </p>
  20.  
  21. <p>
  22.    Message: &nbsp; &nbsp; &nbsp; <?php echo $html->textarea(’Page/message’, array(’cols’ => ‘40′, ‘rows’ => ‘10))?>
  23. </p>
  24.  
  25. <p>
  26.    <?php echo $html->submit(’Send email’)?>
  27. </p>
  28. <p>
  29.    All fields have to be completed!
  30. </p>
  31. </form>
  32.  
  33. <?php }?>

Now we need a small component to verify the email address to be a valid one and also to contain the code necessary for the email sending. The component (app/controllers/components/email.php) is looking like this:

PHP:
  1. <?php
  2.  
  3. class EmailComponent extends Object
  4. {
  5.  
  6.     function email($email, $name, $message)
  7.     {
  8.       $f_mail = "name@domain.com";
  9.       $f_name = "WebMaster domain.com";
  10.       $f_message ="\nName : $name";   // start building the message
  11.       $f_message .="\n\nE-mail : $email";
  12.       $f_message .="\n\nMessage \n : $message";
  13.  
  14.       $headers = "From: www.domain.com <administrator@domain.com>\n";
  15.       $headers .= "X-Sender: <admin @domain.com>\n";
  16.       $headers .= "X-Mailer: PHP\n";
  17.       $headers .="Reply-To:$f_mail\n\n";
  18.      
  19.       $subject = "Message from your website domain.com";
  20.      
  21.       mail("$f_mail", "$subject", "$f_message",$headers); // send the email
  22.  
  23.     }
  24.  
  25.  
  26.     function validMail($email) // this function checks to see if the email supplied by the visitor is a valid one
  27.     {
  28.         $pattern="^[-_.[:alnum:]]+@((([[:alnum:]]|[[:alnum:]][[:alnum:]-]*[[:alnum:]])\.)+(ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|com|coop|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|info|int|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mil|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
  29. // the regex for an email addres
  30.      
  31.      if(eregi($pattern, $email))
  32.         $ll=1;
  33.      else
  34.         $ll=0;
  35.      return $ll;
  36.     }
  37. }
  38.  
  39. ?>

And now becomes the logic part, the controller (app/controllers/controller_name.php):

PHP:
  1. <?php
  2.  
  3. class NameController extends AppController {
  4.  
  5.     var $uses = null;
  6.     var $components = array('Email');
  7.  
  8.     function contact(){
  9.  
  10.         $this->pageTitle = 'Contact';
  11.  
  12.         if (!empty($this->data))
  13.         {
  14.  
  15.           $email = $this->data['Page']['email'];
  16.           $name = $this->data['Page']['name'];
  17.           $message = $this->data['Page']['message'];
  18.  
  19.           $error = 0;
  20.  
  21.            // start filter vars
  22.           if(strlen(trim($email))<3)
  23.           {
  24.             $error=1;
  25.           }
  26.  
  27.           if(strlen(trim($message))<4)
  28.           {
  29.             $error=1;
  30.           }
  31.  
  32.          // verify email address
  33.           if( (strlen(trim($email))<3)||($this->Email->validMail($email)==0))
  34.           {
  35.             $error=1;
  36.           }
  37.  
  38.           if ($error==0)
  39.           {
  40.  
  41.             $this->Email->email($email, $name, $message)//here is the email sent
  42.             $this->set('succes', 'The message was sent <br />Thank you!');
  43.             // setting "succes" variable for displaying if email was sent.
  44.  
  45.           }else
  46.           {
  47.             $this->set('error', 'Please complete all fields');
  48.             // this is in case of error
  49.           }
  50.  
  51.       }else{
  52.        
  53.       }
  54.  
  55.   }
  56.  
  57. }?>

 

HasOne association type

CakePHP 2 Comments »

A powerful feature in Cake is the relational data association provided by the model definition. There are four types of associations:
- hasOne
- hasMany
- belongsTo
- hasAndbelongsToMany

After we define the association between 2 models Cake will automatically fetch the data between the “glued” models. For example if the Car model is related to the Image model and is using a hasOne association type when we will retrieve the data using findAll for example in a controller there will be retrived both Car and Image records: $this->Car->findAll()
To use this types of relations correctly is indicated to use naming conventions like:

- Foreign Keys: singular-model-name_id. For example, a foreign key in the "images" table pointing back to the Car a given Image belongs to would be named "car_id".
- Tables name should be at plural
- Model names should be singular form of the tables names.

Example of association and querying data with hasOne between two models Car model and Image model in this cases:

Location: app/models/car.php

PHP:
  1. class Car extends AppModel
  2.   {
  3.     var $name = 'Car';
  4.     var $hasOne = array(Image' =>               
  5.        array('className' => 'Image',
  6.        'conditions' => '',
  7.        'order' => '',
  8.        'dependent' => true,
  9.        'foreignKey' => 'car_id'
  10.        )
  11. // the hasOne array is what Cake is using to create the association between this 2 models
  12.     );
  13.   }

When we will retrieve data using find() or findAll() calls upon Car model we should see our associated Image model data as well.

PHP:
  1. $car = $this->Car->read(null, '20');
  2. print_r($car);
  3.  //will  output:
  4.    (
  5.    [Car] => Array
  6.         (
  7.          [id] => 20
  8.          [name] => Ferrari
  9.          [model] => Testarosa
  10.          [year] => 1977
  11.          [status] => sold
  12.           )
  13.          [Image] => Array
  14.          (
  15.          [id] => 34
  16.          [title] => sqwertmnx312.jpg
  17.          [width] => 200
  18.          [height] = 150
  19.          )
  20.   )

 

Saving data in CakePHP

CakePHP 2 Comments »

To save in your model using CakePHP you only have to supply that data to a specific model using the save() method.
The data needs to be in the following form:

PHP:
  1. (
  2.     [ModelName] => Array
  3.         (
  4.             [yourfieldname] => 'value'
  5.             [anotherfieldname] => 'value'
  6.         )
  7. )

To post data in this form to a controller for example is very easy using HTML helpers that are implemented in Cake. Everything we need to care about is that form elements are looking like: data[Modelname][fieldname] .

For example to acces a certain variable in a controller we will use;

PHP:
  1. $name_var = $this->data[‘Modelname’][‘formvariable’];

The input form in the view will look something like this:

PHP:
  1. $html->input('Modelname/formvariable')

In a form construction using helpers is best to respect the model structure using to give names to form elements the same names like fields we want to fill in the database.
Using this convention data sent from forms will be formatted automatically and will look putted in $this->data within you controller, so saving data becomes very easy.

Example of saving data:

PHP:
  1. function add() // action add
  2.     {
  3.         if (!empty($this->data))   // checking to see if $this->data is not empty
  4.         {
  5.             if ($this->Car->save($this->data)) // is data is saved returns true
  6.             {
  7.                 $this->flash('Your post has been saved.','/posts'); //displaying message with link
  8.             }