Recent Blog Posts

RESTful PHP server API

By Ronald van Belzen | October 12, 2013

There are plenty of manuals on how to make your own RESTful PHP server on the web. One that I found particularly useful was Create a REST API with PHP. It explains the nuts and bolts of how to create a RESTful server with the use of PHP and in some aspects it goes beyond the example I am going to show here, which was inspired by that approach.

Even more useful I found the "RESTful Service Best Practices" manual that can be downloaded from http://www.restapitutorial.com/resources.html.

The index.php file

It is good practice to rewrite the request that needs to be handled by the index.php script. In this approach I placed the index.php file in its own subdirectory (I named that directory "api") together with the following .htaccess file:

RewriteEngine on 
RewriteRule ^images/.*$ - [L] 
RewriteRule ^js/*.js$ - [L] 
RewriteRule ^css/*.css$ - [L] 

# if a directory or a file exists, use it directly 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 

# otherwise forward it to index.php 
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

When you are not using an Apache server, or an alternative that can handle .htaccess, modern PHP offers a solution as I hinted at in a previous blog. I admit, the blog post does not explain how php.ini can mimic .htaccess functionality, but it can. Although, I have to admit, I have never experimented with that myself.

The rewrite rule in the above .htaccess file will cause requests like http://localhost/api/test to be rewritten to http://localhost/api/index.php/test. So let's start with the index.php that needs to handle this request.

Passing data to the CButtonColumn click event

By Ronald van Belzen | July 20, 2013

One of the limitations of the click event of an CButtonColumn is that it does not take data from the CGridView. But passing row specific data to a Javascript on clicking the button is precisely what is needed in many cases.

The simplest workaround is to use jQuery to deliver the required data:

$this->widget('zii.widgets.grid.CGridView', array( 

  // omitted parameters

  'columns'=>array( 

    // omitted columns 

    array( 
      'class'=>'CButtonColumn', 
      'template'=>'{view}', 
      'buttons' => array( 
        'view' => array( 
          'url'=>'$data->id', 
          'click'=>'js:function() { viewPost($(this).attr("href"));return false; }', 
        ), 
      ) 
    ), 
  ), 
));

The trick is that the data is passed to the url and $(this).attr("href") passes it to the function called by the click event. Of course, the click event should return false to prevent the web browser from visiting the url. All navigation (if any) should be triggered by the Javascript in this solution.

Adding Fancybox to an Yii application

By Ronald van Belzen | June 15, 2013

After showing how to add AD Gallery to an application I am showing here how to use Fancybox in an Yii application for the display of an image gallery. "FancyBox is a tool for displaying images, html content and multi-media in a Mac-style "lightbox" that floats overtop of web page." It is capable of showing much more then just images. In fact the Yii module Gii uses Fancybox to display the generated code in a lightbox. But in this example I am just going to show how to use Fancybox with images to show how it can be used to produce an image gallery.

As with AD Gallery Fancybox is not overly complicated, but it is different. In order not to repeat the former blog post too much I am adding pagination to the example, which is useful when using extremely large sets of images. The controller used in the previous example will be changed to look like this:

class OverviewController extends Controller { 
  const PAGE_SIZE = 50;

  // other action functions 

  public function actionView($id) { 
    $model=Gallery::model()->findByPk($id); 
    if($model===null) 
      throw new CHttpException(404,'The requested page does not exist.'); 

    $criteria = new CDbCriteria; 
    $criteria->condition = "gallery_id = $id"; 

    $count = GalleryImage::model()->count($criteria); 
    $pageCount = ceil($count/self::PAGE_SIZE); 
    $pager = new CPagination($pageCount); 
    $pager->pageSize=1; 

    $criteria->order = 'sort ASC'; 
    $criteria->limit = self::PAGE_SIZE; 
    $criteria->offset = self::PAGE_SIZE*$pager->currentPage; 
    $models = GalleryImage::model()->findAll($criteria); 
    $this->render('view', array( 
      'gallery'=>$model, 
      'models'=>$models, 
      'pager'=>$pager, 
    )); 
  } 
}

The class constant PAGE_SIZE represents the number of thumbnail images that will be displayed on a page. The variable $pageCount contains the number of pages that are needed for pagination and is passed to the CPagination class constructor. The page size for CPagination is set to 1, which is not related to the number of images on a page but chosen to make the offset calculation simpler.

Adding AD Gallery to an Yii application

By Ronald van Belzen | June 7, 2013

AD Gallery is "A highly customizable gallery/showcase plugin for jQuery". In other words it is a jQuery plugin to create an image gallery on a web page. As many lightbox and image gallery plugins, AD Gallery makes implementation relatively easy. For that reason the javascript part of the example shown below is the easiest part, while the rest is not overly complex either.

Still, to understand the script it is useful to know how it is called from the controller:

class OverviewController extends Controller { 
  // other action functions 

  public function actionView($id) { 
    $model=Gallery::model()->findByPk($id); 
    if($model===null) 
      throw new CHttpException(404,'The requested page does not exist.'); 
    $criteria = new CDbCriteria; 
    $criteria->condition = "gallery_id = $id"; 
    $criteria->order = 'sort ASC'; 
    $models = GalleryImage::model()->findAll($criteria); 
    $this->render('view', array( 
      'gallery'=>$model, 
      'models'=>$models, 
    ));
  } 
}

The model Gallery contains the information about different galleries. Most important attribute of this model is storage that contains the location of the directory in which the images are stored. The model GalleryImage links images to a gallery and contains the information about the image file names. The controller action renders the view view that shows the image gallery:

Multiple files upload in Yii - tabular input fields

By Ronald van Belzen | May 31, 2013

There are several ways to tackle the challenge of uploading multiple files in Yii. The differences are based upon the form field(s) being used. Here I will show an example of a tabular file input form. Other methods include the use of the CMultiFileUpload widget and the multiple attribute for the file input field introduced by HTML5.

When you have not read my previous blog post about single file upload, you should consider it when you run into problems. Also you should take into account the php.ini settings for max_file_uploads, post_max_size and upload_max_filesize.

To the model that will store the information about the image the field $images is added for the file upload:

class GalleryImage extends CActiveRecord { 
  public $images;

And to this class the validation rule is added for the new field:

  public function rules() { 
    return array( 
    // other rules 
    array('images', 'file', 'allowEmpty' => true, 'types' => 'gif,jpg,jpeg,png', 'maxSize' => 5242880, 'maxFiles' => 5, ), 
    // other rules ); 
  }

Next we create a form for the input of the files and their descriptions. To add a bit of complexity the images can be added to different galleries: