Powered by Blogger.

Showing Static Pages in the Yii Framework

Let’s look at a different way of rendering view files: using static pages. The difference between a static page and a standard page in the site is that the static page does not change based upon any input. In other words, a dynamic page might display information based upon a provided model instance, but a static page just displays some hard-coded HTML (in theory).
This is an excerpt from Chapter 7, “Working with Controllers,” of “The Yii Book“.
If you only have a single static page to display, the easy solution is to treat it like any other view file, with a corresponding controller action:

<!-- # protected/controllers/views/some/about.php -->
<h1>About Us</h1>
<p>spam, spam, spam...</p>
And:
# protected/controllers/SomeController.php
public function actionAbout() {
    $this->render('about');
}
The combination of those two files means that the URL http://www.example.com/index.php/some/about will load that “about” page. As I said, this is a simple approach, and familiar, but less maintainable when you have more static pages.
An alternative and more professional solution is to register a “page” action associated with the CViewAction class. This is done via the controller’s actions() method:

# protected/controllers/SiteController.php
public function actions() {
    return array(
        'page' => array('class' => 'CViewAction')
    );
}
{TIP} You can have any controller display static pages, but it makes sense to do so using the “site” controller.
The CViewAction class defines an action for displaying a view based upon a parameter. By default, the determining parameter is $_GET['view']. This means that the URL http://www.example.com/index.php?r=site/page&view=about or, if you’ve modified your URLs, http://www.example.com/index.php/site/page/view/about, is a request to render the static about.php page.
{NOTE} You must also adjust your access rules to allow whatever users (likely everyone) to access the “page” action. Or, you can do what the “site” controller does: not implement access control at all.
By default, CViewAction will pull the static file from a pages subdirectory of the controller’s view folder. Thus, to complete this process, create your static files within the protected/views/site/pages directory.
If, for whatever reason, you want to change the name of the subdirectory from which the static files will be pulled, assign a new value to the basePath attribute:

# protected/controllers/SiteController.php
public function actions() {
    return array(
        'page' => array(
            'class' => 'CViewAction',
            'basePath' => 'static'
        )
    );
}
You can also create a nested directory structure. For example, say you wanted to have a series of static files about the company, stored within the protected/views/site/pages/company directory. To refer to those files, just prepend the value of $_GET['view'] with “company.”: /site/page/view/company.board would display the protected/views/site/pages/company/board.php page.
By default, if no $_GET['view'] value is provided, CViewAction will attempt to display an index.php static file. To change that, assign a new value to the defaultView property:

# protected/controllers/SiteController.php
public function actions() {
    return array(
        'page' => array(
            'class' => 'CViewAction',
            'defaultView' => 'about'
        )
    );
}
To change the layout used to encase the view, assign the alternative layout name to the layout attribute in that same array.

source  http://www.larryullman.com/2013/04/17/showing-static-pages-in-the-yii-framework/

Resize images using img extention in Yii

I was looking for extention to resize images , I found two (can be more)
1 img
2 image
I tried with first one got some errors(probabely you will not) so jumped to second one, it works. Now I'm gong to teach you how to work with img extention .
This extension is a module called image . we can save images sent by the view form. Also we can edit those images.


Fisrt of all we need to install the module download the extention here
Create new folder "modules" under "protected" folder(needn't if already exist) and create new folder "image" under created "modules" folder and extract extention files there.

Make other changes in main.php file as the extention page .
That code goes here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'import'=>array(
        .....
        'application.modules.image.components.*',
        'application.modules.image.models.Image',
),
'modules'=>array(
        .....
        'image'=>array(
                'createOnDemand'=>true, // requires apache mod_rewrite enabled
                'install'=>true, // allows you to run the installer
        ),
),
'components'=>array(
        .....
        'image'=>array(
                'class'=>'ImgManager',
                'versions'=>array(
                        'small'=>array('width'=>120,'height'=>120),
                        'medium'=>array('width'=>320,'height'=>320),
                        'large'=>array('width'=>640,'height'=>640),
                ),
        ),
),

Then run installer calling,
index.php/image/
or
index.php?r=image if your URL format is not set to 'path'
This module create a folder called files created by it self when installing it's the place save uploaded images(Actually when you call the save method) .But i changed this to my place .You can change it in

protected/modules/image/components/ImgManager.php file find $imagePath variable and changed it to your place

I changed it as 'protected/images/'

Also it use a database table to record few details about uploaded image.
In my view file image field's code is..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//The important part is going here..
   <div class="row">
       <?php echo $form->labelEx($model,'product_images'); ?>
       <?php $this->widget('CMultiFileUpload',array(
           'name'=>'product_images',
           'accept'=>'jpg|png',
           'max'=>5,
           'remove'=>Yii::t('ui','Remove'),
           'denied'=>'type is not allowed', //message that is displayed when a file type is not allowed
           'duplicate'=>'file appears twice', //message that is displayed when a file appears twice
           'htmlOptions'=>array('size'=>25),
       )); ?>
       <?php echo $form->error($model,'product_images'); ?>
   </div>

About this 'CMultiFileUpload' widget see
Yii multiple file upload post.
Then in my controller
Catch the image file with CUploadedFile::getInstancesByName() method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$primary_product_image = CUploadedFile::getInstancesByName('product_images');
foreach ($primary_product_image as $image => $pic) {
       $image_object=Yii::app()->image->save($pic,$pic->name,'original_images/');   // this image save in 'protected/images/original_images/'  folder.
                 
      $thumb=Yii::app()->image->loadThumb($image_object->id);
       $config=array('width'=>320,'height'=>160); 
       $options=new ImgOptions();
       $options=ImgOptions::create($config);
       $thumb->applyOptions($options);
       $thumb->save(Yii::getPathOfAlias('application').'/images/resized_images/'.'-'.$image_object->name.'-'.$image_object->id.'.'.$image_object->extension);
       
}

Tsis extension has many functionalities but here I tried to make one version(resized) with original image . But you can save many sizes with versioning functionality.


Yii multiple file upload

To upload multiple files, Yii has given a full functioning widget called “CMultiFileUploadhttp://www.yiiframework.com/doc/api/1.1/CMultiFileUpload
but the documentation about this isn't clear …
We can’t find there how to catch up uploaded files and how to save them a directory we need.
Let’s see how we do this..
My example is how to upload product images to my images directory created in my application path(in protected folder).
My form have many fields but here I consider about only file field called "Product images"(in my view file).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//The important part is going here..
   <div class="row">
       <?php echo $form->labelEx($model,'product_images'); ?>
       <?php $this->widget('CMultiFileUpload',array(
           'name'=>'product_images',
           'accept'=>'jpg|png',
           'max'=>5,
           'remove'=>Yii::t('ui','Remove'),
           'denied'=>'type is not allowed', //message that is displayed when a file type is not allowed
           'duplicate'=>'file appears twice', //message that is displayed when a file appears twice
           'htmlOptions'=>array('size'=>25),
       )); ?>
       <?php echo $form->error($model,'product_images'); ?>
   </div>

This widget send an array of uploaded files. Also the file count has limited to 5 here by 'max' option.
The widget has many options you can find all here http://www.yiiframework.com/doc/api/1.1/CMultiFileUpload.
The name of that array we define in ‘name’ option.We can use that name to catch files array at the controller.
We can catch it in the controller using
CUploadedFile::getInstancesByName() method

1
$product_images = CUploadedFile::getInstancesByName('product_images');
this is return an array of CUploadedFile instances
we can access each instance through foreach loop

1
2
3
4
5
foreach ($product_images as $image => $pic) {
     //we can save the current image at any where  
    $pic->saveAs(Yii::getPathOfAlias('application').'/images/'.$pic->name); //This file save to protected/images/ folder
    
}
That's it.
If you want to resize this image follow this post Edit images using img extention in Yii


Understanding Yii Active Record API

how to fetch and write data with Active Record

small tip

In these functions if having "All" part it returns an array of objects and then you should use foreach loop

foreach($objects as $object){

    echo $object->attribute ;

}

Functions don't have "All" part it returns an object and you can access as

$object->attribute

find

$model=Products::model()->find('category_id=:category_id',array(':category_id'=>4));

This returns one object so you can access results as

    echo $model->name;

findAll

$model=Products::model()->findAll('category_id=:category_id',array(':category_id'=>4));

This returns one an array of objects so you can access results as

    foreach($model as $product){

        echo $product->name;

    }

findByPk

$model=Products::model()->findByPk(1,array('condition'=>'category_id=:category_id','params'=>array(':category_id'=>1)));

This returns one object so you can access results as

    echo $model->name;

findAllByPks

$model=Products::model()->findAllByPk(array(2,3,10),array('condition'=>'category_id=:category_id','params'=>array(':category_id'=>0)));

This returns one an array of objects so you can access results as

    foreach($model as $product){

        echo $product->name;

    }
findByAttributes

$model=Products::model()->findByAttributes(array('id'=>1);

This returns an Product object so you can access results as

    echo $model->name;

findAllByAttributes

$model=Products::model()->findAllByAttributes(array('id'=>array(1,2,3,4));

This returns an array of product objects so you can access results as

    foreach($model as $product){

        echo $product->name;

    }


findBySql

$model=Products::model()->findBySql("select * from product where id=:id",array('id'=>10));

This returns an Product object so you can access results as

    echo $model->name;

findAllBySql

$model=Products::model()->findAllBySql("select * from product where category_id=:category_id",array('category_id'=>5));

This returns an array of product objects so you can access results as

    foreach($model as $product){

        echo $product->name;

    }

that's it !