Recent Blog Posts

Single file upload in Yii

By Ronald van Belzen | May 24, 2013

When uploading files in Yii the first choice to be made is to either use an existing model or create a new model. The existing model can be of the type CActiveRecord. The new model is usually of the type CFormModel. The reason for the choice for a class inheriting from CFormModel is that the uploaded file is usually not saved in a database table and therefore no CActiveRecord is required.

That does not mean that a model based upon CActiveRecord cannot be used. When the meta data of an uploaded file is saved in a database table it even makes perfect sense to use that model for the file upload.

In this example an image is uploaded to serve as logo for one of the blogs.The image will be saved in the file system. The name of the image is saved in the database table field "logo". To the existing Blog model the variable "$filename" is added to be used in the upload form:

class Blog extends CActiveRecord { 
  public $filename;

The validation of the uploaded image will also be done by the model. To the function "rules()" the validation rule for "filename" is added:

public function rules() { 
  return array( 
    // other rules 
    array('filename', 'file', 'allowEmpty' => true,'maxSize' => 102400, 'types' => 'jpg, jpeg, png'), 
    // other rules 
  ); 
}

The form that is used to create and update the database table already exists. This CActiveForm is adapted to be able to handle file uploads by adding the following "htmlOptions" property:

<?php $form=$this->beginWidget('CActiveForm', array( 
  'id'=>'blog-form', 
  'enableAjaxValidation'=>false, 
  'htmlOptions'=>array('enctype'=>'multipart/form-data'), 
)); ?>

This adds the mandatory attribute enctype="multipart/form-data" for file upload to the html form.
NOTE: The default method POST must be used and Ajax validation needs to be disabled.

Next the field for the file upload needs to be added to the form:

Gzip compression for PHP

By Ronald van Belzen | May 14, 2013

One way to use gzip compression when requested by the client is by setting

zlib.output_compression = On

in your php.ini.

When you do not have access to the webserver there is also the option to use the above setting in a ".user.ini" file in the root of your website. Search the phpinfo() for the "user_ini.filename" setting just in case the default filename has been set to something else.

This use of ".user.ini" file is supported since PHP 5.3.0.

Spam control by IP blocking in Yii

By Ronald van Belzen | May 4, 2013

Any interactive website needs to take into account that that interactivity will be abused. The most common form of abuse is spam. Even when you control the user input by moderation there comes a time that you need to structure the control of user input. One way of getting control over input from abusive users is by using IP blocking.

The approach I will describe here will require that your application registers the IP address in all the database tables that store user input. As an example I will use a "blog_comment" table.

The stategy that will be followed is that upon creation of a comment (INSERT) the IP address will be checked against a database table containing the IP addresses that need to be blocked.

The moment to determine the IP address of a user and store it in the table "blog_comment" is during validation in the function "rules()":

    return array( 
      // ... other rules 
      array('ip', 'default', 'value'=>Yii::app()->request->userHostAddress), 
      // ... other rules 
    );

We start by creating the database table that will contain the IP addresses that need to be blocked.

CREATE TABLE `ipaddress` ( 
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT , 
  `ip` VARCHAR(39) NULL , 
  `address` VARCHAR(255) NULL , 
  `source` TINYINT NULL DEFAULT 0 , 
  `count` INT NULL DEFAULT 0 , 
  `create_time` TIMESTAMP NULL , 
  `update_time` TIMESTAMP NULL , 
  PRIMARY KEY (`id`) , 
  UNIQUE INDEX `ip_UNIQUE` (`ip` ASC) );

The only mandatory field in that table will be "ip". The other fields are for extra functionality that can be used for maintaining the IP addresses. The field "source" can be used to distinguish manual input from automated input of IP addresses. The field "count" can be used to count the number of times an IP address has been checked.The field "update_time" is used to check when an IP address was last checked.

We use Gii to create a model from this table and use the Crud Generator. Next we improve the views that the Crud Generator has made, but I leave it to you to do that. In this blog post we concentrate on the model Ipaddress to which we add the following function:

Retrieving all controller actions in an application

By Ronald van Belzen | May 3, 2013

Well not all actions, the method does not incorporate the CController actions() function to retrieve the external action classes of a controller, but these can be added quite easy for each controller found.

The method does not bother to search for nested modules either, but when you have them in your application you can add a search for them to the method.