Friday, November 30, 2012

Creating a Drop Down List using Constants

In designing databases often time we will use integers to represent data such as 'status' for example rather than actually storing "Created/In Progress/Completed". This is fine however when it comes to entering data into your view you have to know that 1 = In Progress, 0 = Created. It would be easier if you could have a drop down list. With Yii it is not difficult to achieve just that.

The first thing you need to do is create these constants in the Model. Let us assume we have a model called 'Job'. In the Job model create the constants you require.

class Job extends CActiveRecord
{
const STATUS_CREATED=0;
const STATUS_PROGRESS=1;
const STATUS_COMPLETED=2;

You now need to create a function to get the constants and again create this function in your model.

public function getStatus()
{
return array (
self::STATUS_CREATED=>'Created',
self::STATUS_PROGRESS=>'In Progress',
self::STATUS_COMPLETED=>'Completed',
);
}
All that is required now is to create a drop down list in your view. To do this you can take advantage of Yii's build in dropDownList.
<div class="wide form">
.......

<div class="row">
<?php echo $form->labelEx($model,'status'); ?>
<?php echo $form->dropDownList($model, 'status', $model->getStatus()); ?>
<?php echo $form->error($model,'status'); ?>
</div>
If you open up the form you will notice that there is a drop down list populated by Created/In Progress/Completed. When you save the form the value of 0,1 or 2 is written to the database.
You can take this a step further. Continuing with the example of a model called Job you should be able to list a specific job in your view and instead of the Status displaying a value of 0, 1 or 2 you can output the corresponding text. The way to do this is to create an additional function inside the Job model.

public function getActiveStatusText ()
{
$activeStatus=$this->getActiveStatus();
return isset($activeStatus[$this->status]) ? $activeStatus[$this->status] : "unkown status({$this->status})";
}
Then to use this in your view (e.g. CDetailView or Bootstraps TbDetailView)

<?php $this->widget('bootstrap.widgets.TbDetailView', array(
'type'=>'striped bordered condensed',
'data'=>$model,
'attributes'=>array(
'job_name',
'username',
array(
'name'=>'status',
'value'=>CHtml::encode($model->getActiveStatusText()),
),
),
)); ?>

That's all there is to it. There are other methods for creating this functionality however I find this the easiest and quickest to implement.

References:

  1. Understanding Virtual Attributes and get/set methods 
  2. Managing constants easily



Thursday, November 29, 2012

Debugging variables in Yii 

It was quite a while before I started to use this feature and now I would not be without it. As your application becomes more complex it is often necessary to see that your variables and query results are what they should be. You can even see what errors may be occurring and this is invaluable.

The first thing you need to do is configure your main configuration file. You will find this under  "Protected/config/main.php". In "main.php" you need to find a parameter called 'log' and here we use a class called "CWebLogRoute". To configure CWebLogRoute add the following
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CWebLogRoute',
'levels'=>'trace',
'categories'=>'vardump',
'showInFireBug'=>true,
),
),
),
As you can see the output is written to FireBug which is an essential tool not only for Yii but for general web development. This will also work with Chrome Developer tools  - to use it in Chrome simply click anywhere on the page and select Inspect Element and go to the Console.

To write the value of a variable to the Console in Yii all you need to do is add the following to your controller or view.
$test = array(1,2,3,4);
echo Yii::trace(CVarDumper::dumpAsString($test),'vardump');
I found this particularly useful when writing code to write data to the database. You can see if your code is successful by using:

echo Yii::trace(CVarDumper::dumpAsString($model->save()),'vardump');
If the data is written successfully to your database this will return 'true' in the console. If it returns 'false' and you are not sure why then output the errors.

echo Yii::trace(CVarDumper::dumpAsString($model->errors)),'vardump');
CWebLogRoute is absolutely invaluable in debugging Yii applications.

References:

  1. http://www.yiiframework.com/doc/api/1.1/CWebLogRoute
  2. How to log and debug variables using CWebLogRoute 

How to do a count of records in Yii

Incorporating a database into your website is a fairly standard requirement and Yii makes if easy. One really important section of the "Definitive Guide to Yii" is "Working with Databases" and I would encourage you to read this. Some of the syntax can be a little confusing and often time I found if I could see an example then it is relatively straight forward to extrapolate. Hopefully the example to follow may help you understand some of the syntax.

If you need to count how many records in your database match specific criteria then this is relatively simple to do.  Lets assume we have a table called 'job'  and a column called 'zipcode' and we want to count how many rows in the table have a zipcode = 4000. First you need to define the count property in your Model class before you can access or use the variable in your controller.


class Job extends CActiveRecord
{
//count for number of zips
public $zipcount;

Now in your controller you need to create the query and one way is create an instance of  CDbCriteria If your not confident with Object Oriented programming creating an instance just means we use the 'new' keyword to create an object.



$criteria = new CDbCriteria;
$criteria->select = 'zipcode, COUNT(zipcode) as zipcount';
$criteria->condition='zipcode=4000';
$myquery=Job::model()->find($criteria);

Notice the 'as zipcount'. This alias 'zipcount' must be the same as the variable name you declared in your model. Now to access this 'zipcount' variable in your controller all you need to use is: $myquery->zipcount

Sometimes there may be a more complex query and CDbCriteria is perfect. Lets assume in the Job table we want to know how many 'doctors' live in this zip code and lets assume that the column 'job_id' holds this value. Lets assume for a doctor, job_id=1. So to count how many doctors live in the zip code of 4000 we would use.


$criteria = new CDbCriteria;
$criteria->select = 'job_id, COUNT(job_id) as zipcount';
$criteria->condition='job_id=:jobId and zipcode=4000';
$criteria->params=array(':jobId'=>1);
$myquery=Job::model()->find($criteria);
I used  'params'  just for the purpose of example as it displays the syntax you need to use. It is useful when you do not have a hard-coded value but rather a variable. For example say the variable '$jobtype' holds a job description value you would use 'params' as
$criteria->condition='job_id=:jobId and zipcode=4000';
$criteria->params=array(':jobId'=>$jobtype);


That is the basic requirements if you need to do a count in the database. CDbCriteria allows you to create very complex queries and I would encourage you to have a read of the Yii Documentation for more information.

References:

  1. http://www.yiiframework.com/forum/index.php/topic/7996-how-to-get-record-count/page__p__40356__hl__count+record+#entry40356
  2. http://www.yiiframework.com/doc/guide/1.1/en/database.ar


Thursday, November 22, 2012

Yii - My Journey


When I was asked to write a web application I looked at the various frameworks around for PHP and decided to use Yii. This is relatively new framework compared to other more mature frameworks however it has a very active user base.

Starting off with any framework can be a very steep learning curve and choosing one is almost just as hard. I had some slight experience with the ZEND Framework however I found it very overwhelming. There is a mountain of documentation however getting started with this Framework I found difficult. I had to write a lot of code to do something simple. I played with CakePHP a few years ago and I found it to be really rigid. If you wanted to deviate from the Cake conventions then you pay the price. I had no experience with Code Igniter however after reading an article by SHELDMANDU I decided to give Yii a try.

Now don't be fooled. If you are not experienced with PHP and have little Object Oriented Programming experience then Yii is not going to be a breeze however even for a novice PHP developer you can get a lot done in a short amount of time with very little effort. 

Yii is based on the Model View Controller architecture. Now there is no point me explaining this when there is so much written about it however for a good overview have a look at the Yii website. In a nutshell the MVC architecture separates the data and logic into the Model, the View contains the actual layout and forms and the Controller acts as a conduit between the Model and the View. It is really worth understanding this concept.

So how do you get started using the Yii Framework. In my opinion you can read and read (and read) however until you start writing the code you do not learn anything. I would recommend that you go to the Yii website and download Yii then in my opinion head on over to Larry Ullman's website and do the 8 part tutorial called "Introduction to the Yii Framework". It is the best (in my opinion) beginners tutorial that covers everything from how to install the framework to writing a basic Employee/Department application. Larry Ullman writes in easy to understand language and does not leave out big chunks of information that you have to figure out for yourself like some other tutorials. This 8 part tutorial will allow you to develop a small application quickly and you will be on your way to using the Yii Framework.

Where do you go from there? I would recommend you write an application for yourself. Think of an application you would like to develop and jump in feet first. You can read the "Definitive Guide to Yii" and I would recommend at some stage you do however it still comes back to the fact (or opinion) that writing code is the only way to learn. The Yii forums are really worth using when you get stuck (and you will) because the user base is very active and more experienced Yii users are very happy to help and give advice. Every time I had a problem I could either find the answer in the forum or someone brighter than me would solve my problem. Do not be afraid to ask for help.

Where is this blog going to go->I found that the same questions seem to get asked over and over (maybe in a different way but the concept is usually the same) so I thought I would post the problems I had when I first started in the hope that it will help others. It is a real shift from writing desktop applications to web applications and hopefully this blog will help people starting out with the Yii Framework.