Posts tagged Yii

Yii Framework

How to use a Widget as an Action Provider

2

Yii FrameworkAt the Yii forum there a good question about this matter, and most of us where curious on how this feature actually works.

As usual in the API docs it was clearly written but sometimes the text just sounds like a test for a car driver license. Nevertheless, after creating a test scenario, I found the solution and this is article is to show you exactly how this is done.

Why would I need an action provider?

Well, imagine you have lots of general actions that could be shared among controllers. It is true that by setting the actions() function to point to the external CAction classes files but just imagine that those functions are encapsulated by just a class (a widget in this case) and you just need a line of code to import all of its actions.

First Step: Create your Action

For the sake of the article we creating an action named getData that supposed to be shared among the whole project and saved with the name getData.php on our protected/components/actions folder.

<?php
class getData extends CAction{
	public function run(){
		echo 'HELLO WORLD';
	}
}

Second Step: configure the Widget

To transform a Widget into an action provider is quite easy (once you know of course). The only thing we need to do is to set the static method actions(). As you will see on the following code, we name the action as GetData and that is the action that will be called in our route. We are going to save the following widget in our protected/components/ folder with the name testProvider.php.

class testProvider extends CWidget{
	public static function actions(){
		return array(
                   // naming the action and pointing to the location
                   // where the external action class is
		   'GetData'=>'application.components.actions.getData',
		);
	}
}

Step 3: Configure our Controller

Finally we set our controller’s actions() function to point to our actions provider.

// This function is in this example
// on SiteController
public function actions()
{
        return array(
        // test. is the prefix we are going to use
        // for all action within the actionProvider class
        // we point to the location where the provider
        // is
	'test.'=>'application.components.testProvider',
	);
}

Now we can call the action as controllerID/actionPrefix.actionID

index.php?site/test.GetData


Agile Web Application Development with Yii 1.1 and PHP5



Tweet this!Tweet this!
Yii Framework

Yii News: Query Caching

5

Yii FrameworkStarting from version 1.1.7 Yii Framework will include a really great feature: query caching. This new feature is built on top of data caching, query caching stores the result of a DB query in cache and may thus save the DB query execution time if the same query is requested in future, as the result can be directly served from the cache -After this, I truly would like to see some proper benchmarks versus other frameworks out there on query requests.

Using Query Caching with DAO

We need to use CDbConnection::cache() method in order to perform DB queries. The following example specifies that the query results should remain valid in cache for 1000 seconds. If we execute the same lines of code within the next 100 seconds one more time, the query results will be returned from cache without executing the SQL statement again.

$sql = 'SELECT * FROM tbl_post LIMIT 20';
$rows = Yii::app()->db->cache(1000)->createCommand($sql)->queryAll();

We can also specify a cache dependency for the cached query result so if there is any changes to the table, then we can invalidate the query results. In the next code, we create a dependency which checks the maximum `update_time` of all records in a table. If the value has any change, it means the table data is changed and we should invalidate the query cache.

$sql = 'SELECT * FROM tbl_post LIMIT 20';
$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post');
$rows = Yii::app()->db->cache(1000, $dependency)->createCommand($sql)->queryAll();

Using Query Caching with CActiveRecord

This new feature can also be used with CActiveRecord

$posts = Post::model()->cache(1000)->findAll();
// query caching can also be used with relations
$posts = Post::model()->cache(1000)->with('author')->findAll();

If you wish to have a look at this cool feature, go and grab the SVN repository on google: http://code.google.com/p/yii/source/checkout



Tweet this!Tweet this!
Sidebar marker event trigger

A sidebar marker trigger with EGMap 2.0

0


Introduction

This is another article from a feature requested by a EGMap Yii Extension User. He proposed me when the following will be incorporated to the library: http://gmaps-samples-v3.googlecode.com/svn/trunk/sidebar/random-markers.html.

I am going to demonstrate that the extension is already capable of creating that without the need of more ‘library tweaking’.

HTML and Styling

First of all we are going to write the CSS and the HTML that will ‘mimic’ the example provided in the previous link. As you are going to see, there is also a JavaScript helper function that will handle the creation of LI elements (as in the example).

<style>
#sideContainer {
    list-style-type: none;
    padding: 0;
    margin: 0 10px 0 0;
    float: left;
    border: 1px solid #676767;
    background-color: #eee;
    overflow: auto;
  }
  #sideContainer li {
    font-size: 0.9em;
    border-bottom: 1px solid #aaa;
    padding: 5px;
  }
  #mapContainer {
    float: left;
    width: 500px;
    height: 400px;
  }
 </style>
</head>
<script>
// global marker counter
var n = 1;
function generateListElement( marker ){
    var ul = document.getElementById('sideContainer');
    var li = document.createElement('li');
    var aSel = document.createElement('a');
    aSel.href = 'javascript:void(0);';
    aSel.innerHTML = 'Open Marker #' + n++;
    aSel.onclick = function(){ google.maps.event.trigger(marker, 'click')};
    li.appendChild(aSel);
    ul.appendChild(li);
}
</script>
<body>
<!-- the side menu container -->
<ul id="sideContainer" style></ul>
<!-- we are going to render the map here -->
<div id="mapContainer"></div>

Creating the Map

For the sake of this example, we are going to create just one EGMapInfoWindow object and two markers. The most important thing is to demonstrate how to use callbackTriggers with EGMap 2.0. As you will now see, it is pretty easy to do.

// array holding a reference to all the markers
// that will be rendered to the Map
$markers = array();
$gMap = new EGMap();
$gMap->zoom = 10;
$gMap->setCenter('39.721089311812094', '2.91165944519042');
// Create GMapInfoWindow
$info_window_b = new EGMapInfoWindow('Hey! I am a marker with label!');
// Create 1st marker
$marker = new EGMapMarker(39.721089311812094, 2.91165944519042, array('title' => 'Marker With Label'));
// attach info window
$marker->addHtmlInfoWindow($info_window_b);
// add to map
$gMap->addMarker($marker);
// add to array
$markers[] = $marker;
// repeat process with second
$marker = new EGMapMarker(39.721089311812094, 2.81165944519042, array('title' => 'Marker With Label'));
$marker->addHtmlInfoWindow($info_window_b);
$gMap->addMarker($marker);
$markers[] = $marker;
// tell the map we want to render it
// to a specific layer
$gMap->appendMapTo('#mapContainer');
// initialize the afterInit array that
// will hold after map initialization
// script code
$afterInit = array();
//
// loop through markers and
// call global function to generate
// the element that will hold the
// callback trigger event
foreach($markers as $marker){
	$afterInit[] = 'generateListElement('.$marker->getJsName().');'.PHP_EOL;
}
// now render map and pass the afterInit code
$gMap->renderMap($afterInit);

Final Words

The above code is very simplistic, if we were to render lots of markers to the map, a better approach would be to make that on a loop and even more, create a couple of functions to simplify the creation of the markers.

Hope this example helps you guys to better understand the flexibility of this extension. Thanks all for using it.



Tweet this!Tweet this!
Reverse-geolocator-EGMap-Yii

A Reverse Geolocator Tool with EGMap 2.0 Extension

1

I have been requested to create an article about a reverse geolocator tool, that is a tool to find out the latitude and longitude of a location, to include on our CMS, and here it is.

Styling, Javascript and HTML

First of all, we are going to write the HTML that will work with this example, it won’t styled as the example picture displayed, which is the tool I created for a project I am working now, but don’t you worry as this article will provide you with the scripts and routines to create your own.

Write the following style on the HEAD section of your HTML page:

<style>
  div#map {
    position: relative;
  }
  div#crosshair {
    position: absolute;
/*
     the top will be half of the width of the map
     less 50% of its size more or less
     to center the image correctly on the map
*/
    top: 192px;
    height: 19px;
    width: 19px;
    left: 50%;
    margin-left: -8px;
    display: block;
/* we are going to borrow a crosshair gif from google */
    background: url(http://gmaps-samples-v3.googlecode.com/svn/trunk/geocoder/crosshair.gif);
    background-position: center center;
    background-repeat: no-repeat;
}
</style>

Now, some Javascript functions that will allow us to get the information from the map

<script type="text/javascript">
  //
  // function to get the latitude and longitude
  // and place them on the test fields
  function setLatLngToClass(){
	if(document.getElementById('test_latitude'))
	 	document.getElementById('test_latitude').value = map.getCenter().lat();
	if(document.getElementById('test_longitude'))
		document.getElementById('test_longitude').value = map.getCenter().lng();
  }
  //
  // function to get Centered Latitude and Longitude points
  function getCenterLatLngText() {
    return '(' + map.getCenter().lat() +', '+ map.getCenter().lng() +')';
  }
  //
  // function to call when the center of the map
  // has changed. Center information will be
  // collected and displayed on the document
  // elements
  function centerChanged() {
    centerChangedLast = new Date();
    var latlng = getCenterLatLngText();
    document.getElementById('latlng').innerHTML = latlng;
    document.getElementById('formatedAddress').innerHTML = '';
    currentReverseGeocodeResponse = null;
  }
  //
  // Collects reverse center location
  function reverseGeocode() {
    reverseGeocodedLast = new Date();
    geocoder.geocode({latLng:map.getCenter()},reverseGeocodeResult);
  }
  //
  // Displays collected reverse geocoded results
  // and displays them on document elements
  function reverseGeocodeResult(results, status) {
    currentReverseGeocodeResponse = results;
    if(status == 'OK') {
      if(results.length == 0) {
        document.getElementById('formatedAddress').innerHTML = 'None';
      } else {
        document.getElementById('formatedAddress').innerHTML = results[0].formatted_address;
      }
    } else {
      document.getElementById('formatedAddress').innerHTML = 'Error';
    }
  }
  //
  // geocodes the address inserted
  function geocode() {
    var address = document.getElementById("address").value;
    geocoder.geocode({
      'address': address,
      'partialmatch': true}, geocodeResult);
  }
  function geocodeResult(results, status) {
    if (status == 'OK' && results.length > 0) {
      map.fitBounds(results[0].geometry.viewport);
    } else {
      alert("Geocode was not successful for the following reason: " + status);
    }
  }
 //
 // adds marker to the center of the map
  function addMarkerAtCenter() {
    var marker = new google.maps.Marker({
        position: map.getCenter(),
        map: map
    });
    var text = 'Lat/Lng: ' + getCenterLatLngText();
    if(currentReverseGeocodeResponse) {
      var addr = '';
      if(currentReverseGeocodeResponse.size == 0) {
        addr = 'None';
      } else {
        addr = currentReverseGeocodeResponse[0].formatted_address;
      }
      text = text + '<br>' + 'address: <br>' + addr;
    }
    var infowindow = new google.maps.InfoWindow({ content: text });
    google.maps.event.addListener(marker, 'click', function() {
      infowindow.open(map,marker);
    });
  }
</script>

Our HTML on this example will be the following one:

<body style="background:white">
<div class="form">
Find by address:
 <input type="text" id="address" style="width:300px"/>
 <button type="button" class="small"onclick="geocode()">Go to Address</button>
  <ul>
     <li>Lat/Lng:&nbsp;<span id="latlng"></span></li>
     <li>Address:&nbsp;<span id="formatedAddress"></span></li>
     <li>Zoom Level:&nbsp;<span id="zoom_level"><?php echo $zoom;?></span></li>
 </ul>
</div>
<div id="map">
    <div id="map_canvas" style="width:100%; height:400px"></div>
    <div id="crosshair"></div>
</div>
<div style="overflow:hidden;width:100%;text-align:right">
<button type="button" class="small" onclick="setLatLngToClass()">Set Latitude & Longitude</button>
<button type="button" class="small" onclick="addMarkerAtCenter()">Add Marker at Center</button>
</div>
<hr>
Latitude: <input id="test_latitude" value=""/> Longitude: <input id="test_longitude" value=""/>
</hr>
</body>

Using EGMap 2.0 Extension

Finally, we are going to use EGMap 2.0 extension to automate the rest of the tasks to render our map.

Yii::import('ext.gmaps.*');
// center the map
// wherever you want
$latitude = 39.72098197183251;
$longitude = 2.9115524999999964;
$zoom = 8;
$gMap = new EGMap();
$gMap->setJsName('map');
$gMap->width = '100%';
$gMap->height = '400';
$gMap->setCenter($latitude, $longitude);
$gMap->zoom = 8;
$gMap->addGlobalVariable('geocoder');
$gMap->addGlobalVariable('centerChangedLast');
$gMap->addGlobalVariable('reverseGeocodedLast');
$gMap->addGlobalVariable('currentReversGeocodeResponse');
$gMap->addEvent(
     new EGMapEvent(
             'zoom_changed',
             'document.getElementById("zoom_level").innerHTML = map.getZoom();'));
$gMap->addEvent(new EGMapEvent('center_changed','centerChanged',false));
$gEvent = new EGMapEvent('dblclick','map.setZoom(map.getZoom() +1)');
$gMap->appendMapTo('#map_canvas');
$gMap->renderMap(array(
    'geocoder = new google.maps.Geocoder();',
    $gEvent->getDomEventJs('crosshair'),
    'reverseGeocodedLast= new Date();',
    'centerChagedLast = new Date();',
    'setInterval(function(){
        if((new Date()).getSeconds() - centerChangedLast.getSeconds() > 1) {
        if(reverseGeocodedLast.getTime() < centerChangedLast.getTime())
          reverseGeocode();
      }
    },1000);',
    'centerChanged();'
));

Important

If you are going to run this example, please be aware that in order to display it properly in a controller, all of the above have to be the content of a layout, otherwise, if you are using renderPartial (that you can), make sure you force to true the parameter ‘processOutput’ of the mentioned function (ie $this->renderPartial(‘view’,null,false,true) )



Tweet this!Tweet this!
Yii Framework

EFeed Universal RSS Feed Writer For Yii

0

Yii Framework

Introduction

Required for one of my projects, I decided to develop my own Yii extension to create RSS Feeds. I knew there is already one but I wanted something easier to use than that. This is why I came up with EFeed Extension. This extension supports RSS 1.0, RSS 2.0, and ATOM 1.0 standards.

How to Use

I assume that you have downloaded the extension and place it on your protected/extensions folder.

RSS 1.0 Example

Yii::import('ext.feed.*');
// specify feed type
$feed = new EFeed(EFeed::RSS1);
$feed->title = 'Testing the RSS 1 EFeed class';
$feed->link = 'http://www.ramirezcobos.com';
$feed->description = 'This is test of creating a RSS 1.0 feed by Universal Feed Writer';
$feed->RSS1ChannelAbout = 'http://www.ramirezcobos.com/about';
// create our item
$item = $feed->createNewItem();
$item->title = 'The first feed';
$item->link = 'http://www.yiiframework.com';
$item->date = time();
$item->description = 'Amaz-ii-ng <b>Yii Framework</b>';
$item->addTag('dc:subject', 'Subject Testing');
 // add it to the feed
$feed->addItem($item);
$feed->generateFeed();

As you can see in the example above, we just need to create items and add them to the feed. The example could be easily modified to add items extracted from a database and add them to the Feed in a loop.

RSS 2.0 Example

Yii::import('ext.feed.*');
// RSS 2.0 is the default type
$feed = new EFeed();
$feed->title= 'Testing RSS 2.0 EFeed class';
$feed->description = 'This is test of creating a RSS 2.0 Feed';
$feed->setImage(
'Testing the EFeed class',
'http://www.ramirezcobos.com',
'http://www.yiiframework.com/forum/uploads/profile/photo-7106.jpg');
$feed->addChannelTag('language', 'en-us');
$feed->addChannelTag('pubDate', date(DATE_RSS, time()));
$item = $feed->createNewItem();
$item->title = "first Feed";
$item->link = "http://www.yahoo.com";
$item->date = time();
$item->description = 'This is test of adding ' .
          'CDATA Encoded description <b>EFeed Extension</b>';
// this is just a test!!
$item->setEncloser(
      'http://www.tester.com',
     '1283629', 'audio/mpeg');
$item->addTag(
     'author',
     'thisisnot@myemail.com (Antonio Ramirez)');
$item->addTag(
     'guid',
     'http://www.ramirezcobos.com',
     array('isPermaLink'=>'true'));
$feed->addItem($item);
$feed->generateFeed();

ATOM 1.0 Example

Yii::import('ext.feed.*');
$feed = new EFeed(EFeed::ATOM);
// IMPORTANT : No need to add id for feed or channel.
// It will be automatically created from link.
$feed->title = 'Testing the ATOM RSS EFeed class';
$feed->link = 'http://www.ramirezcobos.com';
$feed->addChannelTag('updated', date(DATE_ATOM, time()));
$feed->addChannelTag('author', array('name'=>'Antonio Ramirez Cobos'));
$item = $feed->createNewItem();
$item->title = 'The first Feed';
$item->link  = 'http://www.ramirezcobos.com';
// we can also insert well formatted date strings
$item->date ='2010/24/12';
$item->description = 'Test of CDATA Encoded description <b>EFeed Extension</b>';
$feed->addItem($item);
$feed->generateFeed();

Download

To download the extension go to Yii’s extension repository. Hope this little piece of code can help your project needs somehow.

Tweet this!Tweet this!
Yii Framework

Paths, Paths, Yii Paths!

8

Yii Framework

Introduction

When we start learning something and we go through some parts, we completely forget about what was a small issue in our way to get where we are. I started talking about things that can be hard to understand if the initial concepts are not well understood. For this reason, even though for some this small tutorials are too basic, I would like to post them every now and then to help newcomers to better understand the basic concepts of the articles.

Paths

Before, you continue with this article, I assume that you have read the fundamentals of Path Aliasing and Namespaces from the Definitive Guide of Yii

We are going to talk about paths and before we start, we should first explain how Yii creates its folder structure after you use its yiic tool. This is how it looks and the definitions of the folders (assuming you have created an application called testweb):

testweb/             containing your web
   assets/           containing published resource files
   css/              containing CSS files
   images/           containing image files
   themes/           containing application themes
   protected/        containing protected application files
      commands/      containing customized 'yiic' commands
         shell/      containing customized 'yiic shell' commands
      components/    containing reusable user components authentication
      config/        containing configuration files
      controllers/   containing controller class files
      data/          containing the sample database
      extensions/    containing third-party extensions
      messages/      containing translated messages
      models/        containing model class files
      runtime/       containing temporarily generated files
      tests/         containing test scripts
      views/         containing controller view and layout files
         layouts/    containing layout view files
         site/       containing view files for the 'site' controller
            pages/   containing "static" pages

Quite impressive, Yii MVC folder structure is very well created and for simple projects, we probably don’t need to change it, but if we wish to do it, or we create some widgets or portlets or components or whatever, and those need to access different folder locations in our application, Yii paths related functions come to resue:

  1. getPathOfAlias
  2. setPathOfAlias
  3. import

So, tell me, how do they work

A path alias is ‘nickname’ that we give to a folder in our Web project. Yii comes with five of them already established.

  • system: refers to the Yii framework directory;
  • zii: refers to the Zii library directory;
  • application: refers to the application’s base directory;
  • webroot: refers to the directory containing the entry script file. This alias has been available since version 1.0.3.
  • ext: refers to the directory containing all third-party extensions. This alias has been available since version 1.0.8.

So, in our example above, these are the correspondent translations:

Yii::getPathOfAlias(‘webroot.images’) is equal to the translated images folder path on your computer or server (ie. windows: C:\mywebserverpath\testweb\images, linux: /usr/web/www/testweb/images). I do use this feature to save images or folders on a folder  when I develop CMS for my clients. Here is an example:

$picture_file = CUploadedFile::getInstanceByName('Filedata');
//...
//... some validation code here
//...
// create a picture name
$picture_name = Picture::createPictureName($picture_file->name);
// saving file
// 'othersubfolder' is just an imaginary subfolder under images
$picture_file->saveAs(
          Yii::getPathOfAlias('webroot.images.othersubfolder') .
          DIRECTORY_SEPARATOR .
         $picture_name );

Now, lets imagine that I wish to create a new folder 2010 for my application and it is located very far down on the folder structure and I wish to access it in order to save documents there. Here is the example:

testweb/
   assets/
   css/
   docs/
      clients/
         2010/
           January/

To make our life easier, we are going to use Yii::setPathOfAlias to provide an alias to the 2010 folder. For the sake of the example we are going to configure it in our index.php file after the creation of our Application:

defined('DS') or define('DS',DIRECTORY_SEPARATOR);
Yii::createWebApplication($config)-&gt;run();
Yii::setPathOfAlias('2010',
           dirname($_SERVER['SCRIPT_FILENAME']).DS.
           'docs'.DS.
           'clients'.DS.'2010');
// Now we can access the folder to read and/or write like this:
$pathToDocs = Yii::getPathOfAlias('2010');

Remember, than setPathOfAlias doesn’t normalizes the path and getPathOfAlias do not check for the existence of the folder just check if the alias exist. We need to put special attention to them.

And what about import?

I wouldn’t explain it better than Yii:

Using aliases, it is very convenient to include the definition of a class. For example, if we want to include theCController class, we can call the following:

Yii::import('system.web.CController');

The import method differs from include and require in that it is more efficient. The class definition being imported is actually not included until it is referenced for the first time (implemented via PHP autoloading mechanism). Importing the same namespace multiple times is also much faster than include_once and require_once.

We can also use the following syntax to import a whole directory so that the class files under the directory can be automatically included when needed.

Yii::import('system.web.*');

Besides import, aliases are also used in many other places to refer to classes. For example, an alias can be passed to Yii::createComponent() to create an instance of the corresponding class, even if the class file was not included previously.

Further Reading

We have covered just a small portion of the great funcionality of Yii. I highly recommend you to also look at the following path related functions:

  • getBasePath -Returns the root path of the application. Your root URL.
  • setBasePath -Sets the root directory of the application. This method can only be invoked at the begin of the constructor.
  • getExtensionPath – Returns the root directory that holds all third-party extensions.
  • setExtensionPath – Sets the root directory that holds all third-party extensions.
  • setRuntimePath – Sets the directory that stores runtime files.
  • getRuntimePath – Returns the root directory that stores runtime files
  • getLocaleDataPath – Returns the directory that contains the locale data. It defaults to ‘framework/i18n/data’.
  • setLocaleDataPath – Sets the directory that contains the locale data.

Hope this helps new comers to better understand the concepts working with path Yii way.



Tweet this!Tweet this!
EGMap Example 1

EGMap Google Maps Extension for Yii

10

Yii Framework

Introduction

I had to develop a Google maps extension for my current personal project and I did some research in order not to re-invent the wheel.

The best of them all was a Symphony plugin developed by Fabrice Bernhard. I didn’t want to create a wrapper so I decided to modify its code -in some cases rewriting the whole class, in order to create a full Extension built with Yii.

The features of this extension are very large to explain, therefore I will concentrate my next posts to fully explain by example the wonders of this extension.

Requirements

Developed with latest stable version of Yii (1.5)

Usage

Unzip its contents and place the gmaps folder into your protected/extensions folder.

A Reallly Easy Example

Displaying a Marker with an Info window.

Note: This example was written in a view file.

    // import the library
    Yii::import('ext.gmaps.*');
    $gMap = new EGMap();
    $gMap->setZoom(13);
    $gMap->setCenter(39.721089311812094, 2.91165944519042);
    // Create GMapInfoWindow
    $info_window = new EGMapInfoWindow('<div>I was living here as a kid!</div>');
    // Create marker
    $marker = new EGMapMarker(39.721089311812094, 2.91165944519042, array('title' => '"My Town"'));
    $marker->addHtmlInfoWindow($info_window);
    $gMap->addMarker($marker);
    $gMap->renderMap();

Result

 

Resources

Download the Extension
Bug Reports & Positive Feedback



Tweet this!Tweet this!
Yii Framework

How to maintain pages on CGridView

2

Yii Framework

Introduction

Lots of Yii forum members have ask how to return to current navigated page on a CGridView after a user has clicked the update or create button. Meaning that if I am in page number 4 of our Grid and we have clicked on the ‘edit’ button, how, and after I clicked the submit button return to the page number 4 as our Grid was?

Through this small tutorial on how to get current page parameter, you will learn how to do exactly that. At least I hope so.

Bit of analysis

If you check at the parameters of the Yii pagination classes you will see that the parameter name of the pagination is on the format of: Modelname_page. So, if we are at our NewsController admin page, we will surely see the pagination as URL?&News_page=2 for example.  Now that we know that we are going to tweak a bit our code to accomplish what we want.

Modifying CButtonColumn

CButtonColumn is the class that takes care of the rendering of our edition buttons (view, update, delete), we are going to modify its buttons URL. How to do it? Well, as I always said, it is really good to look at the guts of Yii framework; if we check the CButtonColumn class code we will see that this class has three properties that we can set: viewButtonUrl, updateButtonUrl and deleteButtonUrl. A closer look to these variables we see:

public $viewButtonUrl='Yii::app()->controller->createUrl("view",array("id"=>$data->primaryKey))';
public $updateButtonUrl='Yii::app()->controller->createUrl("update",array("id"=>$data->primaryKey))';
public $deleteButtonUrl='Yii::app()->controller->createUrl("delete",array("id"=>$data->primaryKey))';

These variables have PHP code that is afterwards evaluated in a very smart way. So, as you probably know by now, we need to modify that code in the view where we render the grid to include our new links, the ones that will include the current page parameter for our Grid.

// setting up the class
$buttons = array('class'=>'CButtonColumn');
// do we have a News_page parameter?
$page = Yii::app()->getRequest()->getParam('News_page',false);
// if yes, modify the link
// IMPORTANT
// for this example I assume that you have
// and update, view and delete actions!
if( $page ){
	foreach(array('view','update','delete') as $id){
		$buttons[$id.'ButtonUrl'] = 'Yii::app()->controller->createUrl("'.$id.'",array("id"=>$data->primaryKey,"News_page"=>'.$page.'));';
	}
}
$this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'news-grid',
	'dataProvider'=>$model->search(),
	'filter'=>$model,
	'columns'=>array(
		array(
		'name'=>'id',
		'filter'=>false
		),
		'title',
		'sender',
		array(
			'name'=>'datetime_sent',
			'type'=>'datetime',
			'filter'=>false,
		),
		// HERE WE PLACE OUR NEW BUTTONS
		$buttons,
	),
));

Exercise

Now our edition buttons will hold also the current page parameter of our News model. That means that when we render the corresponding views for viewing, editing or even calling actionDelete of our controller, we will also render that parameter.

I think that it could be a good exercise for you to find out how deal with that parameter to return to the page you were after editing your model. I will give you two quick tips:

On my _Form.php view

if(getParam('Brand_page')){
	echo CHtml::hiddenField('Brand_page',getParam('Brand_page'));
}

On my actionUpdate in NewsController

public function actionUpdate($id)
{
	$model=$this->loadModel($id);
	if(isset($_POST['News']))
	{
		$model->attributes=$_POST['News'];
                $page = Yii::app()->getRequest()->getParam('News_page',false);
                $params = $page? array('News_page'=>$page) : array();
		if($model->save()){
                        // redirecting to admin.php view where our grid is
			$route = $this->createUrl('admin',$params);
			$this->redirect($route,true);
		}
	}
	$this->renderPartial('_form',array(
		'model'=>$model,
	));
}

Further Reading

Quick tip about pagination params

Using CButtonColumn to customize buttons in CGridView



Tweet this!Tweet this!
Home Page

Real Estate Colonia San Pedro

10

Real Estate Web Application fully developed with Yii Framework.

To visit the site: http://www.mallorcacolonia.com/

Website Features

Web Panel Features

  • The webpanel allows to manage:
  • Web Translations
  • Property Types
  • Properties (Sale, Rent, Inactive) – Gallery – Property Owners
  • Zones
  • Site Languages
  • Inbox

Backend Gallery



Tweet this!Tweet this!
Yii Framework

Yii Learning Guide

2

Yii FrameworkI am a ‘plugged’ person, means that I am constantly connected to the net and being a member of a certain number of social networks and tools (I maybe a weirdo but *no facebook* account) and I am very surprised of the amount of people that are highly interested on Yii and asks information on what is the best way to learn the framework. In order to solve those doubts I would like to put my two cents on this matter by sharing with you what was my learning curve with Yii -this way I do not need to post in every social network I am involved with.

For this post I assume that you know PHP (beginner, intermediate) and some DB skills for whatever the DB Engine you prefer to work with (MySQL, Oracle, etc…)

Yii Learning Guide

When you first arrive to Yii’s website, even though is an amazingly easy to navigate and use Website, you will obviously feel lost and won’t know where to start working with, and this is the most important steps of them all: download and READ its Definitive Guide to Yii. Do not worry if you do not understand some concepts, but you need to read it all, do not let any episode without a look as you will soon understand everything and will get ‘hooked’ by the easiness and magic of Yii. If you prefer not to download it, an online version of the guide is also available. If you are new to MVC, then I also recommend the visit to Larry Ullman’s Learning Yii Series blog.

After the guide, you will have tons of questions to solve and, even though will become a great tool in the future, do not jump immediately on the forum to drop them all. You need to get your hands on a practical example and for that, the demo application of The Yii Blog Tutorial is the perfect playground. It is highly recommended that you have your preferred PHP editor with two projects open: one that is the full demo blog application that comes with the Yii Framework download package, and the practical project that you will create following the tutorial. There are a couple of lines of code that you need to discover in the builded demo application and there are not in the tutorial.

There is also a book, “Agile Web Application Development with Yii1.1 and PHP5“, that takes you step-by-step through the process of using a test-driven development (TDD) approach to develop a real world Web application with Yii, from initial concept through production-readiness. This is another good practical tutorial to follow. If you do buy the book, then I recommend you to subscribe to Yii’s forum and follow this discussion: http://www.yiiframework.com/forum/index.php?/topic/11920-identified-issues/.

If you have reached this far on the article and follow the above steps then you are already amazed of Yii’s power and probably started your first real-world project with the Framework. Real issues and challenges will arise, it is time to find out about Yii’s amazing network of people, register and subscribe to Yii’s forum. Ask and you will be answered, people are so helpful and polite, it is just unreal the response time of this community. If you prefer  to get immediate help, then use Yii’s live IRC chat.

Don’t think that your learning curve has stopped here, to be ‘plugged’ to the network is highly recommended, so ‘plug’ your self to the Wiki. Its articles are written by other fellow programmers, it is a programmers-to-programmers experience, and due to the nature of the people that are part of this network, the Wiki grows day-by-day. This is the reason that I am subscribed to its RSS. You can also stay up to date by following any of the next social networks accounts: TwitterFacebook or LinkedIn

Once you know the ins and outs of the Framework, one great learning resource are the Extensions written by other programmers. Use them in order to easy your tasks and solve your problems but also read at its guts, its code behind. You will be surprised on how much you can learn from that. If you do not understand something within that code, have *always* a browser window or a tab opened with Yii’s Class Reference.

If you are comfortable with PHP, then I also recommend that you look at the code of the Framework. For example, if you wish to display a radio button using CHtml::radioButton look at the function itself too. Lots of forum questions wouldn’t be posted if they follow this simple advice.

Final Words

There are other resources to take into account (resources directly extracted from Yii’s site):

Cheat Sheets

The Yii cheat sheet, created by Sebastián Thierer. This presents commonly used Yii classes, methods and properties in a single printable sheet.

Yii 1.1 validator cheatsheet: created by schmunk. This summarizes all of Yii’s built-in validators in a single printable sheet.

Yii Playground

The Yii Playground is a community-contributed demo application that uses the PHP Yii Framework to show some features of the framework by explicit example. It is great place to see how some of the features work, and learn the code behind them.

Radio Podcasts

Yii Radio Podcasts, created by Imre Mehesz, covers hot topics and recent activities about the Yii framework.

Blogroll

The community-driven wiki page Yii Related Sites is collecting links to sites with useful tips and tutorials related to the Yii Framework.

The most important thing is that, once you get your hands on this amazing framework you get actively involved in the community (Forum, Wiki, Extensions), and share your projects so others can look at Yii’s real power and provide you with positive feedbacks.

I truly hope this article provides you with an easy guidance to get into Yii’s framework.



Tweet this!Tweet this!
Go to Top