| Size: 1752 Comment:  | Size: 12320 Comment:  | 
| Deletions are marked like this. | Additions are marked like this. | 
| Line 31: | Line 31: | 
| Require local | Require all granted AllowOverride all | 
| Line 63: | Line 64: | 
| == Validation rules ActiveRecord CModel == http://www.yiiframework.com/doc/guide/1.1/en/form.model#declaring-validation-rules We specify the validation rules in the rules() method which should return an array of rule configurations. || '''Alias''' || '''Class''' || ||boolean || CBooleanValidator || ||captcha || CCaptchaValidator || ||compare || CCompareValidator || ||email || CEmailValidator || ||date || CDateValidator || ||default || CDefaultValueValidator || ||exist || CExistValidator || ||file || CFileValidator || ||filter || CFilterValidator || ||in || CRangeValidator || ||length || CStringValidator || ||match || CRegularExpressionValidator || ||numerical || CNumberValidator || ||required || CRequiredValidator || ||type || CTypeValidator || ||unique || CUniqueValidator || ||url || CUrlValidator || {{{#!highlight php public function rules() { return array( array('username, password', 'required'), array('rememberMe', 'boolean'), array('password', 'authenticate'), ); } }}} == Relations ActiveRecord == http://www.yiiframework.com/doc/guide/1.1/en/database.arr#declaring-relationship Override the relations() method of CActiveRecord. Types relationship: * self::BELONGS_TO * self::HAS_MANY * self::HAS_ONE * self::MANY_MANY {{{#!highlight php public function relations() { return array( 'posts'=>array(self::HAS_MANY, 'Post', 'author_id'), 'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'), ); } }}} == ActiveResource extension == Adapted from http://www.yiiframework.com/extension/activeresource Steps: * Get source code from https://github.com/Haensel/ActiveResource/ * Add the extension to Yii by placing it in your application's extension folder (for example '/protected/extensions') * Edit your applications main.php config file and add 'application.extensions.EActiveResource.*' to your import definitions * Add the configuration for your resources to the main config {{{ 'activeresource'=>array( 'class'=>'EActiveResourceConnection', 'site'=>'http://api.aRESTservice.com', 'contentType'=>'application/json', 'acceptType'=>'application/json', 'queryCacheId'=>'SomeCacheComponent' ) }}} * Create a class extending EActiveResource like this (don't forget the model() method!): ActiveResource implementation: {{{#!highlight php class Person extends EActiveResource { /* The id that uniquely identifies a person. This attribute is not defined * as a property * because we don't want to send it back to the service like a name, surname or * gender etc. */ public $id; public static function model($className=__CLASS__) { return parent::model($className); } /* Define the resource property of this class */ public function rest() { return CMap::mergeArray( parent::rest(), array( 'resource'=>'people', ) ); } /* Let's define some properties and their datatypes*/ public function properties() { return array( 'name'=>array('type'=>'string'), 'surname'=>array('type'=>'string'), 'gender'=>array('type'=>'string'), 'age'=>array('type'=>'integer'), 'married'=>array('type'=>'boolean'), 'salary'=>array('type'=>'double'), ); } /* Define rules as usual */ public function rules() { return array( array('name,surname,gender,age,married,salary','safe'), array('age','numerical','integerOnly'=>true), array('married','boolean'), array('salary','numerical') ); } /* Add some custom labels for forms etc. */ public function attributeLabels() { return array( 'name'=>'First name', 'surname'=>'Last name', 'salary'=>'Your monthly salary', ); } } }}} Sample usage: {{{ /* GET to http://api.example.com/person/1 and populates a single Person model*/ $person=Person::model()->findById(1); /* GET to http://api.example.com/person and populating Person models */ $persons=Person::model()->findAll(); /* create a resource*/ $person=new Person; $person->name='A name'; $person->age=21; $person->save(); POST request. Returns false if the model doesn't validate /* Updating a resource (sending a PUT request) $person=Person::model()->findById(1); $person->name='Another name'; $person->save(); //PUT request. Returns false if the model doesn't validate //or short version Person::model()->updateById(1,array('name'=>'Another name')); /* DELETE a resource */ $person=Person::model()->findById(1); $person->destroy(); //DELETE to http://api.example.com/person/1 //or short version Person::model()->deleteById(1); //setting attributes $person->attributes=$_POST['Person']; if($person->save()) echo 'yipiie'; //model validated and was saved/updated }}} Other methods for EActiveResource: * public function init() * public function setAttribute($name,$value) * public function getAttributesToSend($attributes=null) * protected function beforeSave() * public function sendRequest($uri,$method,$params,$data) == Trace == Yii:trace(string $msg, string $category='application') == Sample controller actions Blog demo == Path: http://localhostyii/demos/blog/site/ {{{#!highlight php public function actionRxvalue() { $m = new Tag(); $m->name=$_GET['value']; $m->save(); header('Content-type: application/json'); echo( json_encode( array('value'=>$_GET['value']) ) ); } public function actionDelvalue() { $m = Tag::model()->find('id=:id' , array(':id' => $_GET['value'] ) ); $m->delete(); header('Content-type: application/json'); echo( json_encode( array('value'=>$_GET['value']) ) ); } }}} Javascript AJAX calls {{{#!highlight javascript $(document).ready(function(){ $('#addTag').click(function(){ console.log('Clicked'); $.ajax({ url: '/demos/blog/site/rxvalue', data: {'value':$('#tag').val() }, success: rxSuccess }); } ); $('.delTag').click( delTag ); } ); function delTag(){ $.ajax({ url: '/demos/blog/site/delvalue', data: {'value': $(this).attr('id') }, success: delSuccess }); return false; } function rxSuccess(data){ $('#listx').append('<li>' + data.value + '</li>'); console.log(data); } function delSuccess(data){ console.log('Delete !' + data.value ); $('li#' + data.value ).remove(); } }}} == CGridView + CArrayDataProvider with pagination, sort and filtering == views/site/test.php: {{{ <h1>Test 1234</h1> <?php $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider'=>$dp, 'enableSorting'=>true, 'columns'=>array('id','name' ) , 'filter'=>Tag::model() , )) ; ?> }}} models/Tag.php: {{{ public function search(){ if( isset( $_GET[get_class($this)] ) ){ Yii::app()->session['filterId']= trim($_GET[get_class($this)]['id']); Yii::app()->session['filterName']= trim($_GET[get_class($this)]['name']); } $posts = $this->findAll(); // filtering $filtered = array(); $filterId= Yii::app()->session['filterId']; $filterName= Yii::app()->session['filterName']; foreach($posts as $p){ if( strlen($filterId) >0 ){ if(strpos($p->id , $filterId ) !==false) $filtered[]=$p; } if( strlen( $filterName ) >0 ){ if(strpos($p->name, $filterName ) !==false) $filtered[]=$p; } } if( strlen(Yii::app()->session['filterId'])==0 && strlen(Yii::app()->session['filterName'])==0 ) { $filtered=$posts; } $dataProvider=new CArrayDataProvider( $filtered, array( 'pagination'=>array( 'pageSize'=>4, ) , 'id'=>'id', 'sort'=>array('attributes'=>array('id','name') , 'multiSort'=>false ) ) ); return $dataProvider; } }}} controllers/SiteController.php: {{{ public function actionTest() { syslog(LOG_INFO,'actionTest called'); $dp = Tag::model()->search(); $this->render('test', array( 'dp'=>$dp ) ); } }}} == $this in a view == In a view, $this refers to the controller that called render to that view. Get absolute URL inside a view {{{#!highlight php echo( $this->createAbsoluteUrl($this->getRoute() ) ); }}} == Register Javascript file == {{{#!highlight php Yii::app()->getClientScript()->registerScriptFile( Yii::app()->baseUrl . '/js/test.js' ); }}} == Save state in components == http://www.yiiframework.com/doc/api/1.1/CHtml#statefulForm-detail Generates a stateful form tag. A stateful form tag is similar to form except that it renders an additional hidden field for storing persistent page states. You should use this method to generate a form tag if you want to access persistent page states when the form is submitted. == Widget == Widget definition in components/MyWidget.php {{{ <?php class MyWidget extends CWidget { public $titley; public function init() { // this method is called by CController::beginWidget() } public function run() { // this method is called by CController::endWidget() $this->render('mywidget' , array( 'titlexxx'=>$this->titley ) ); } } ?> }}} View in components/views/mywidget.php {{{ <h1> My widget <?php echo( $titlexxx ); ?> !!!! </h1> }}} Invocation in other view {{{ <?php $this->widget('MyWidget', array('titley'=>' extra text') ); ?> }}} | 
Yii
Yii is a high-performance PHP framework best for developing Web 2.0 applications.
Slackware installation
http://www.yiiframework.com/doc/guide/1.1/en/topics.url#hiding-x-23x
- cd ~/Downloads
- wget https://github.com/yiisoft/yii/releases/download/1.1.15/yii-1.1.15.022a51.tar.gz 
- cp yii-1.1.15.022a51.tar.gz /vars/www/htdocs
- cd /vars/www/htdocs
- tar xvzf yii-1.1.15.022a51.tar.gz
- cd yii-1.1.15.022a51
- chown apache * -R
- chmod 755 /etc/rc.d/rc.httpd
- vim /etc/httpd/httpd.conf
<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so
Include /etc/httpd/mod_php.conf  # enable the php module- vim /etc/httpd/vhosts.conf
<VirtualHost *:80>
    ServerName localhostyii
    DocumentRoot "/var/www/htdocs/yii-1.1.15.022a51"
    <Directory "/var/www/htdocs/yii-1.1.15.022a51">
      Require all granted
      AllowOverride all
    </Directory>
</VirtualHost>- vim /etc/hosts
127.0.0.1 localhostyii
- vim /etc/httpd/php.ini
date.timezone="Europe/Lisbon"
- vim /var/www/htdocs/yii-1.1.15.022a51/demos/blog/.htaccess
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
RewriteBase /demos/blog
# 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- vim blog/protected/config/main.php
                'urlManager'=>array(
                        'showScriptName'=>false,- /etc/rc.d/rc.httpd start
Validation rules ActiveRecord CModel
http://www.yiiframework.com/doc/guide/1.1/en/form.model#declaring-validation-rules
We specify the validation rules in the rules() method which should return an array of rule configurations.
| Alias | Class | 
| boolean | CBooleanValidator | 
| captcha | CCaptchaValidator | 
| compare | CCompareValidator | 
| CEmailValidator | |
| date | CDateValidator | 
| default | CDefaultValueValidator | 
| exist | CExistValidator | 
| file | CFileValidator | 
| filter | CFilterValidator | 
| in | CRangeValidator | 
| length | CStringValidator | 
| match | CRegularExpressionValidator | 
| numerical | CNumberValidator | 
| required | CRequiredValidator | 
| type | CTypeValidator | 
| unique | CUniqueValidator | 
| url | CUrlValidator | 
Relations ActiveRecord
http://www.yiiframework.com/doc/guide/1.1/en/database.arr#declaring-relationship
Override the relations() method of CActiveRecord.
Types relationship:
- self::BELONGS_TO
- self::HAS_MANY
- self::HAS_ONE
- self::MANY_MANY
ActiveResource extension
Adapted from http://www.yiiframework.com/extension/activeresource
Steps:
- Get source code from https://github.com/Haensel/ActiveResource/ 
- Add the extension to Yii by placing it in your application's extension folder (for example '/protected/extensions')
- Edit your applications main.php config file and add 'application.extensions.EActiveResource.*' to your import definitions
- Add the configuration for your resources to the main config
'activeresource'=>array(
    'class'=>'EActiveResourceConnection',
    'site'=>'http://api.aRESTservice.com',
    'contentType'=>'application/json',
    'acceptType'=>'application/json',
    'queryCacheId'=>'SomeCacheComponent'
)- Create a class extending EActiveResource like this (don't forget the model() method!):
ActiveResource implementation:
   1 class Person extends EActiveResource
   2      {
   3      /* The id that uniquely identifies a person. This attribute is not defined
   4       * as a property      
   5       * because we don't want to send it back to the service like a name, surname or    
   6       * gender etc.
   7       */
   8      public $id;
   9  
  10      public static function model($className=__CLASS__)
  11      {
  12          return parent::model($className);
  13      }
  14  
  15      /* Define the resource property of this class */
  16      public function rest()
  17      {
  18          return CMap::mergeArray(
  19          parent::rest(),
  20          array(
  21         'resource'=>'people',
  22              )
  23     );
  24      }
  25  
  26      /* Let's define some properties and their datatypes*/
  27      public function properties()
  28      {
  29          return array(
  30              'name'=>array('type'=>'string'),
  31              'surname'=>array('type'=>'string'),
  32              'gender'=>array('type'=>'string'),
  33              'age'=>array('type'=>'integer'),
  34              'married'=>array('type'=>'boolean'),
  35              'salary'=>array('type'=>'double'),
  36          );
  37      }
  38  
  39      /* Define rules as usual */
  40      public function rules()
  41      {
  42          return array(
  43              array('name,surname,gender,age,married,salary','safe'),
  44              array('age','numerical','integerOnly'=>true),
  45              array('married','boolean'),
  46              array('salary','numerical')
  47          );
  48      }
  49  
  50      /* Add some custom labels for forms etc. */
  51      public function attributeLabels()
  52      {
  53          return array(
  54              'name'=>'First name',
  55              'surname'=>'Last name',
  56              'salary'=>'Your monthly salary',
  57          );
  58      }
  59  }
Sample usage:
/* GET to http://api.example.com/person/1 and populates a single Person model*/
    $person=Person::model()->findById(1);
 
    /* GET to http://api.example.com/person and populating Person models */
    $persons=Person::model()->findAll();
 
    /* create a resource*/
    $person=new Person;
    $person->name='A name';
    $person->age=21;
    $person->save(); POST request. Returns false if the model doesn't validate
 
    /* Updating a resource (sending a PUT request)
    $person=Person::model()->findById(1);
    $person->name='Another name';
    $person->save(); //PUT request. Returns false if the model doesn't validate
 
    //or short version
    Person::model()->updateById(1,array('name'=>'Another name'));
 
    /* DELETE a resource */
    $person=Person::model()->findById(1);
    $person->destroy(); //DELETE to http://api.example.com/person/1
 
    //or short version
    Person::model()->deleteById(1);
 
    //setting attributes
    $person->attributes=$_POST['Person'];
    if($person->save())
        echo 'yipiie'; //model validated and was saved/updatedOther methods for EActiveResource:
- public function init()
- public function setAttribute($name,$value)
- public function getAttributesToSend($attributes=null)
- protected function beforeSave()
- public function sendRequest($uri,$method,$params,$data)
Trace
Yii:trace(string $msg, string $category='application')
Sample controller actions Blog demo
Path: http://localhostyii/demos/blog/site/
   1   public function actionRxvalue()
   2         {
   3           $m = new Tag();
   4           $m->name=$_GET['value'];
   5           $m->save();
   6           header('Content-type: application/json');
   7           echo( json_encode( array('value'=>$_GET['value']) )  );
   8         }
   9 
  10         public function actionDelvalue()
  11         {
  12           $m = Tag::model()->find('id=:id' , array(':id' => $_GET['value'] )  );
  13           $m->delete();
  14           header('Content-type: application/json');
  15           echo( json_encode( array('value'=>$_GET['value']) )  );
  16         }
Javascript AJAX calls
   1 $(document).ready(function(){
   2   $('#addTag').click(function(){ 
   3        console.log('Clicked');  
   4        $.ajax({
   5          url: '/demos/blog/site/rxvalue',
   6          data: {'value':$('#tag').val() },
   7          success: rxSuccess   
   8        });
   9     } );
  10   $('.delTag').click( delTag  );
  11 } );
  12 
  13 function delTag(){
  14   $.ajax({
  15          url: '/demos/blog/site/delvalue',
  16          data: {'value':  $(this).attr('id')   },
  17          success: delSuccess   
  18        });
  19   return false;
  20 }
  21 
  22 function rxSuccess(data){
  23   $('#listx').append('<li>' + data.value + '</li>');    
  24   console.log(data);
  25 }
  26 
  27 function delSuccess(data){
  28   console.log('Delete !' + data.value  ); 
  29   $('li#' +  data.value  ).remove();
  30 }
CGridView + CArrayDataProvider with pagination, sort and filtering
views/site/test.php:
<h1>Test 1234</h1>
<?php
 $this->widget('zii.widgets.grid.CGridView', 
     array( 'dataProvider'=>$dp, 
            'enableSorting'=>true,
            'columns'=>array('id','name' ) ,
            'filter'=>Tag::model() ,   
 )) ;
?>models/Tag.php:
        public function search(){
           if( isset( $_GET[get_class($this)] )  ){
               Yii::app()->session['filterId']= trim($_GET[get_class($this)]['id']);
               Yii::app()->session['filterName']= trim($_GET[get_class($this)]['name']);
           }
           $posts = $this->findAll();
           // filtering
           $filtered = array();
           $filterId= Yii::app()->session['filterId'];
           $filterName= Yii::app()->session['filterName'];
           foreach($posts as $p){
             if(  strlen($filterId)   >0 ){
                 if(strpos($p->id ,  $filterId  ) !==false) $filtered[]=$p;
             }
             if(  strlen(  $filterName )  >0 ){
                 if(strpos($p->name,  $filterName  ) !==false) $filtered[]=$p;
             }
           }
           if( strlen(Yii::app()->session['filterId'])==0 && strlen(Yii::app()->session['filterName'])==0 ) {
              $filtered=$posts;
           }
           $dataProvider=new CArrayDataProvider(  $filtered, 
                       array(  'pagination'=>array( 'pageSize'=>4, ) , 
                               'id'=>'id', 
                               'sort'=>array('attributes'=>array('id','name') , 'multiSort'=>false ) 
                       ) );
           return $dataProvider; 
        }controllers/SiteController.php:
        public function actionTest()
        {
                syslog(LOG_INFO,'actionTest called'); 
                $dp = Tag::model()->search();
                $this->render('test', array(  'dp'=>$dp   ) );
        }
$this in a view
In a view, $this refers to the controller that called render to that view.
Get absolute URL inside a view
   1 echo( $this->createAbsoluteUrl($this->getRoute() ) );
Register Javascript file
   1 Yii::app()->getClientScript()->registerScriptFile( Yii::app()->baseUrl . '/js/test.js' );
Save state in components
http://www.yiiframework.com/doc/api/1.1/CHtml#statefulForm-detail
Generates a stateful form tag. A stateful form tag is similar to form except that it renders an additional hidden field for storing persistent page states. You should use this method to generate a form tag if you want to access persistent page states when the form is submitted.
Widget
Widget definition in components/MyWidget.php
<?php
class MyWidget extends CWidget
{
    public $titley;
    public function init()
    {
        // this method is called by CController::beginWidget()
    }
 
    public function run()
    {
        // this method is called by CController::endWidget()
        $this->render('mywidget' , array( 'titlexxx'=>$this->titley  )  );
    }
}
?>View in components/views/mywidget.php
<h1> My widget <?php echo( $titlexxx ); ?> !!!! </h1>
Invocation in other view
<?php
  $this->widget('MyWidget', array('titley'=>' extra text') );
?>