Yii fullcalendar integration in 3 steps

December 5, 2011 10 comments

FullCalendar is a jQuery plugin that provides a full-sized, drag & drop calendar. It uses AJAX to fetch events on-the-fly for each month and is easily configured to use your own feed format (an extension is provided for Google Calendar). Actually an extension for Yii already exists here, but it still doesn’t support live events so I decided (since I will obviously need them at one point) to use it directly, embedding a wee bit of PHP code in the Javascript.

Let’s get down to brass tacks:

This example will go around the ‘Event’ model, which for the sake of example has the time_created attribute, which will be used to show the all of the event entries in our calendar.

The first step would actually be to copy the fullcalendar plugin code into the ‘/external’ directory. Actual code for embedding the calendar is following below.

The controller for our ‘calendar’ page will be as simple as ‘index’ controller, providing only the search model to the page. You can add whatever filters you like in the model.

public function actionCalendar() {

  $model=new Event('search');
  $model->unsetAttributes();  // clear any default values
  if(isset($_GET['WorkOrder'])) {


And now to the actual view code:

<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/external/fullcalendar/fullcalendar/fullcalendar.css" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/external/fullcalendar/fullcalendar/fullcalendar.print.css" media="print" />
<script type="text/javascript" src="<?php echo Yii::app()->request->baseUrl; ?>/external/fullcalendar/fullcalendar/fullcalendar.min.js"></script>


<script type='text/javascript'>

$(document).ready(function() {

  header: {
    left: 'prev,next today',
    center: 'title',
    right: 'month,agendaWeek,agendaDay'
  editable: true,
  events: [

  foreach ($model->search()->getData() as $event) {
    $year_created = date("Y", strtotime($event->time_created));
    $month_created = date("m", strtotime($event->time_created)) - 1;
    $day_created = date("d", strtotime($event->time_created));
    $hour_created = date("H", strtotime($event->time_created));
    $min_created = date("i", strtotime($event->time_created));
    echo "{";
    echo "title: '" . $event->name .   "',";
    echo "start: new Date(" . $year_created . "," . $month_created . "," . $day_created . "," . $hour_created . "," . $min_created . "),";
    echo "allDay: false,";
    echo "url: '" . Yii::app()->createUrl("event/view", array("id"=>$event->id)) . "'";
    echo "},";


<style type='text/css'>
#calendar {
  width: 900px;
  margin: 0 auto;

<div id='calendar'></div>

Voila, a working calendar with entries of start dates for your events. This code will also add a clickable link on each calendar entry, which will lead user to the view page of the particular Event.

Categories: Javascript, PHP, Yii

Yii with DynaTree JQuery Plugin

October 4, 2011 14 comments

Just another Yii play-around. I recently discovered dynatree, a nice dynamic JQuery plugin for diplaying tree structures. You can check some live examples on this page. I mean sure CTreeView is nice but it fails to provide the checkboxes for eventual POST, as well as lazy loading for large trees and some other nice features the dynatree will give us. This example though, only explains how to simply get the data into the dynatree.

So I wanted to see it live, and since Yii is the most used framework I’m using right now I decided to mix the two. The best solution would be making the Yii extension for use of this plugin, but I decided to leave that for some less burdensome days.

The dynatree plugin works with Ajax support ofc, and takes the JSON wrapped structure to display the tree.

The code itself for dynatree which you put in a view is simple:

<script src="<?php echo Yii::app()->request->baseUrl; ?>/external/dynatree/jquery/jquery-ui.custom.js" type="text/javascript"></script>
<script src="<?php echo Yii::app()->request->baseUrl; ?>/external/dynatree/jquery/jquery.cookie.js" type="text/javascript"></script>
<link href="<?php echo Yii::app()->request->baseUrl; ?>/external/dynatree/src/skin/ui.dynatree.css" rel="stylesheet" type="text/css">
<script src="<?php echo Yii::app()->request->baseUrl; ?>/external/dynatree/src/jquery.dynatree.js" type="text/javascript"></script>

<script type="text/javascript">
     initAjax: {
       url: "<?php echo Yii::app()->request->baseUrl; ?>/index.php/agenda/loadDynaTree",
       data: {id: "<?php echo $model->id; ?>"}
     onActivate: function(node) {
     onDeactivate: function(node) {

<div id="tree"> </div>

Now all we have to do is pack the data with JSON in a controller and pass it through to the dynatree. But my problem was a specific one. The children of each node were one-to-many relations in Yii, but simple CJSON::encode($model) function is ignoring the relations (there are some hacks but not good enough). I had the depth of 5 one-to-many relations, in a simple Agenda implementation, where agenda has sessions, session has frames, frame has topics, and the topic has lecturers. So the controller action looked something like this:

public function actionLoadDynaTree($id) {
  $model = $this->loadModel($id);

  $data = array();
  $data['title'] = $model->title;
  $data['children'] = array();
  foreach ($model->agendaSessions as $session) {

    $session_children = array();
    foreach ($session->agendaFrames as $frame) {

      $frame_children = array();
      foreach ($frame->agendaTopics as $topic) {

        $topic_children = array();
        foreach ($topic->agendaLecturers as $lecturer) {
          $topic_children[] = array('title' => $lecturer->participants_name);

        $frame_children[] = array('title' => $topic->title, 'children' => $topic_children);

      $session_children[] = array('title' => $frame->title, 'children' => $frame_children);

    $data['children'][] = array('title' => $session->title, 'children' => $session_children);

  echo CJSON::encode($data);

There it is. A more dynamic solution and extension is under way, but I hope this will help you start up if you for any reason mix these two.

Categories: Javascript, PHP, Yii

PHP PDF generators compare review

Ok, so recently I had quite a number of requests from customers to do some back-end document generating out of some persistent info. They were of course satisfied with PDF format since all they actually needed was to store it and print it. Since I’m mostly tied up with PHP lately I knew I had to set up a standard for PDF generator library.

First thing that comes up on Google is of course the PHP embedded PDF support, but after a few tries you realise that you cannot do much with it rather then text print (with multiple fonts even, wow), image embedding and some table drawing (which wasn’t easy to begin with), so I turned my back to the custom libraries which some great guys from around the globe took time to write. Almost immediately I realised that those can be separated in two groups – those that support converting HTML to PDF and those who don’t. The ones that do were a good choice for me, as I believe would be for anyone, because they give you the possibility to view how your page will look without actually running the generator(not in all cases, as described below), which resulted in faster development. The ones which will be included in today’s review are:

1. ezPDF (http://www.ros.co.nz/pdf/)

2. TCPDF (http://www.tcpdf.org/)

3. FreePDF (http://www.fpdf.org/)

4. dompdf (http://code.google.com/p/dompdf/)

5. mPDF (http://www.mpdf1.com/mpdf/)

All of those have a list of features they support, but you shouldn’t always take those for granted. It happened to me more then once that some of those nifty features are buggy or don’t work at all. So, lets start, top first:

1. ezPDF – this library was the first one I ever used (don’t actually remember why), and after few days of complete torture, I realised it was a huge waste of time, it didn’t have the UTF-8 support at all, so I had to manually go around that lack of support, change the character codes in the moment of generating of PDF etc. It doesn’t have HTML support either (except veery few basic tags). The Y cursor which serves to know where the next element will be put vertically is also quite tricky because if some upper element will be empty, whole page is moved upwards. The obscure elements are also there for you to draw them around your PDF page like ellipses, curves et. Sky’s not so black though, because it has some nice features, like document lock, easy page numbering and linking.

2. TCPDF – this one is very mature one, 9 years in the making, and with constant support and new releases, it makes it one of the better choices that you can take. It’s under LGPL, and that’s always a plus. It has many nice features, like (especially useful to me) bar code support, truetype font support, automatic headers and footers insertion, HTML conversion etc. You can also very easy navigate around the page so I used this one for a long time before realising the power of creating HTML code first and then just converting it. The TCPDF has embedded support for HTML but it’s not actually usable. It doesn’t support most CSS properties, and working a page with div’s only proved near impossible; tables were more friendly but who uses tables any more, I’m not sure – I don’t. This prompted me to move a bit from a very powerful TCPDF …

3. FreePDF – besides the cool name, this one is pretty simple, without many features, rarely updated (quite old though) but very fast on the other side, so if you need to create many simple documents at once, this is the best choice. It doesn’t support HTML conversion and you have to navigate around the page with a (x,y) cursor.

4. dompdf – Once I wanted to use HTML for creating PDF’s, this one turned out at the top of the list. It’s pretty young, development is going quite fast ATM, current version is 0.6beta, there’s not so much documentation for it as for the above mentioned but the reference is quite good and quite enough. So, as I said, it was used for HTML conversion only, it worked quite well, with one big surprise that it doesn’t support floating elements (the developers are working on it as we speak because many people complained, so I guess it will be present soon) so you have to do workarounds like negative padding which is pain in the *** when you think about it. It’s also quite fast, generating quite complex documents with up to 5 pages in a matter of seconds. It also has some problems with certain fonts and in particular acute UTF-8 characters, although they claim that it fully supports this encoding.

5. mPDF – the last station. It had everything I ever wanted regarding HTML conversion (the things missing in both TCPDF and dompdf), UTF-8 support, easy font installing, password protection and complete CSS support. It also has a very good online documentation. One of the nicest features is the possibility to add templates from existing PDF’s, so it was very easy to reduce the amount of code in some cases. For those less attracted to designing their document with HTML though, this library is definitely not the choice…

Ok, there’s not even a ‘compare features’ table :), but I hope it serves you well if you’re ever stuck with this kind of decision.

Categories: PHP, Reviews

Yii autocomplete widget example

Yii is simple. Yii is nice. Yii is coder-friendly. No, this is not a commercial brake, just my 2 cents regarding recent framework switching from CodeIgniter and Zend. I’m not gonna delve deep into the features it has, instead I’ll describe one witch I liked really really much. It gave me the possibility to quickly give a client the sight for sore eyes regarding one-to-many or many-to-many form populating.

In this example I will describe one-to-many example and you can pick up the pieces for something more complicated.

Ok, so we have let’s say Hotel as a model and Hotel Offer as something that can relate to only one Hotel. On the Hotel Offer create/update interface we would want to allow client to select one of many Hotels in the system. So, the first approach was a drop down field but after populating the database with more then 10 hotels this was not a viable solution. Ergo, the first insight to CJuiAutoComplete was made. After some example scanning and some self-proclaimed coding I came to a solution which is presented below:


public function actionAutocomplete () {
  if (isset($_GET['term'])) {
    $criteria=new CDbCriteria;
    $criteria->alias = "hotels";
    $criteria->condition = "hotels.name like '" . $_GET['term'] . "%'";

    $dataProvider = new CActiveDataProvider(get_class(Hotel::model()), array(
    $hotels = $dataProvider->getData();

    $return_array = array();
    foreach($hotels as $hotel) {
      $return_array[] = array(

    echo CJSON::encode($return_array);

A condition parameter of the CDbCriteria class can be tweaked if maybe I would want to include all results which include the letters type in the resulting auto complete drop down, not just those beginning with. Also don’t forget to add ‘autocomplete’ action to the ACL rules in the accessRules method.

Now we need to prepare the Hotel Offer. CJuiAutoComplete widget has one downside and that’s that it has to use the existing attribute of the model. Now, I haven’t find a way to specify the attribute as a relational field to some other model, so we have to add a hotels_name field in the HotelOffer model.


class HotelOffer extends CActiveRecord {
  public $hotels_name;


  public function afterFind() {
$this->hotels_name = $this->hotel->name;

Now, all we need is to put the widget into the Hotel Offer form and we’re done for the day 🙂


  <?php echo $form->label($model,Yii::t('messages','Hotel Name')); ?>
  <?php echo $form->hiddenField($model,'hotels_id',array()); ?>
  <?php $this->widget('zii.widgets.jui.CJuiAutoComplete',
               'select'=>"js:function(hotel, ui) {
    )); ?>
Categories: Coding, PHP, Yii

Javascript array definition problem on Internet Explorer 6 (and 7)

Long were the hours spent on making some piece(es) of code compatible on multiple browsers we have nowadays. But one of the largest frustrations happened to me a few days back when somethings like this presented me with an error in client’s browser:

myArray = {

While I would say, since this is completely valid in PHP which I’m using for the last 6 years, that nothing is wrong here (also Firefox, Epiphany and IE8 support my claim), IE7 told me to go fudge myself. What I missed was that those Microsoft’s older browsers didn’t like the ‘comma’ at the last row of the array definition.

So the correct would be:

myArray = {

But this eventually led to some other copy-paste mistakes later, but more about that some other time.