YII webapp customising from ground up


A)) config/main.php

1. name your webapp

‘name’=’my webapp’

2.  enable gii

‘gii’=>array(
‘class’=>’system.gii.GiiModule’,
‘password’=>’password’,
// If removed, Gii defaults to localhost only. Edit carefully to taste.
‘ipFilters’=>array(‘127.0.0.1′,’::1′),
),

),

3. create your database scheme

4.  beautify url

‘urlManager’=>array(
‘urlFormat’=>’path’,
‘rules’=>array(
‘<controller:\w+>/<id:\d+>’=>'<controller>/view’,
‘<controller:\w+>/<action:\w+>/<id:\d+>’=>'<controller>/<action>’,
‘<controller:\w+>/<action:\w+>’=>'<controller>/<action>’,
),
),

5. enable mysql or point to sqldatabase

‘db’=>array(
‘connectionString’ => ‘mysql:host=localhost;dbname=mywebapp’,
’emulatePrepare’ => true,
‘username’ => ‘root’,
‘password’ => ‘password’,
‘charset’ => ‘utf8’,
),

6. set admin email

‘params’=>array(
// this is used in contact page
‘adminEmail’=>’xxxxx@gmail.com’,
),

 

7. show log messages in the webpage

/ uncomment the following to show log messages on web pages
//
array(
‘class’=>’CWebLogRoute’,
),

componenets/UserIdentity.php

7.  change default passwords

public function authenticate()
{
$users=array(
// username => password
‘demo’=>’demo’,
‘admin’=>’admin’,
);

BB) Download mbmenu plugi

views/layouts/main.php

1. change menus

<?php $this->widget(‘application.extensions.mbmenu.MbMenu’,array(
‘items’=>array(
array(‘label’=>’Home’, ‘url’=>array(‘/site/index’)),
array(‘label’=>’Menu 1’, ‘url’=>array(‘/menu1l’),
‘items’=>array(
array(‘label’=>’sub menu 1’, ‘url’=>array(‘/item11’)),
array(‘label’=>’sub menu 2’, ‘url’=>array(‘/item12)),
),
),

2. change footer

<div id=”footer”>
Copyright &copy; <?php echo date(‘Y’); ?> by my company – All Rights Reserved.<br/>
</div><!– footer –>

CC)  YII-booster plugin

config/main.php

Yii::setPathOfAlias(‘booster’, dirname(__FILE__) . DIRECTORY_SEPARATOR . ‘../extensions/yii-booster’);

// preloading ‘log’ component
‘preload’=>array(‘log’,’booster’),

‘components’=>array(

…………………..

‘booster’=> array(
‘class’ =>’booster.components.Booster’,
‘responsiveCss’=>true,
),

………………………….

Advertisements

Using Google Transliterate API with YII


Using Google Transliterate API is straight forward. However to meet the goals of the small project (Webapp for food Catering company) I need to overcome following challenges.

Want to change id of text box (Tablename_fieldname) at will

Google text box id defaults to transliterateTextarea. I was not able to figure out how to change the YII $form object which enforces id of format Tablename_fieldname. I figured out its far more easier to change in the javascript of google to the id which YII requires.

 

change from

control.makeTransliteratable(['transliterateTextarea']);

to

var ids = ["Dish_dish", "Dish_dish2"]

control.makeTransliteratable(ids);

This brings us to the next challenge. I have to add one line for every field attribute I want to transliterate in the main site template page.

Load Google Transliterate API only in the views and not in every page

Handling related models in YII forms


Many AWBs can be carried in one Trip. One AWB can be carried across Many Trips. We will use MySQL for the database. Below is the schema. tbl_tripAWB is the junction table.

CREATE TABLE tbl_trip(

id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,

truckId TINYINT UNSIGNED NOT NULL,

departureDate DATETIME NOT NULL,

tripOrigin MEDIUMINT UNSIGNED NOT NULL,

tripDestination MEDIUMINT UNSIGNED NOT NULL,

arrivalDate DATETIME NOT NULL,

tripFor BOOLEAN NOT NULL DEFAULT 0,

tripStatus VARCHAR(125),

trip TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,

INDEX (truckId),

INDEX (tripOrigin),

INDEX (tripDestination)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE tbl_awb(

id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,

awbPrefix VARCHAR(3) NOT NULL,

awbNumber VARCHAR(8) NOT NULL,

awbAirport MEDIUMINT UNSIGNED NOT NULL,

awbCarrier TINYINT UNSIGNED NOT NULL,

awbPieces TINYINT UNSIGNED NOT NULL,

awbWeight MEDIUMINT UNSIGNED NOT NULL,

awb TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,

INDEX (awbAirport),

INDEX (awbCarrier)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE tbl_tripAwb(

id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,

trip INTEGER UNSIGNED NOT NULL,

awb INTEGER UNSIGNED NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE tbl_tripAwb

ADD CONSTRAINT FOREIGN KEY (trip) REFERENCES tbl_trip (id) ON UPDATE CASCADE,

ADD CONSTRAINT FOREIGN KEY (awb) REFERENCES tbl_awb (id) ON UPDATE CASCADE;

Update Trip form to display the list box with multi select containing AWBs.

labelEx($model,’tripAwbs’); ?>
dropDownList($model, ‘tripAwbs’, CHtml::listData(Awb::model()->findAll(), ‘id’, ‘awbNumber’, ‘awbPrefix’),array(‘multiple’=>’multiple’, ‘size’=>5)
); ?>
error($model,’tripAwbs’); ?>

Yii automatically created the below relationship


'tripAwbs' => array(self::HAS_MANY, 'TripAwb', 'trip'),

In order for the creation of a new Trip to work, you’ll need to update the Controller to handle the tripAwbs. Within the actionCreate() method (of TripController), after the Trip has been saved, loop through each AWB and add that record to tbl_tripAwb. The beginning of actionCreate() would look like:

if(isset($_POST['Trip']))
{
$model->attributes=$_POST['Trip'];
if($model->save()) {
foreach ($_POST['Trip']['tripAwbs'] as $awb) {
$tripAwb = new TripAwb;
$tripAwb->trip = $model->id;
$tripAwb->awb = $awb;
if (!$tripAwb->save()) print_r($tripAwb->errors);
// $this->redirect(array('view','id'=>$model->id));
}}
}

The form has already been created and populated, but to get it to indicate existing selections, we need to pass along the tbl_tripAwb values. You might think that you can just fetch all the tbl_tripAwb records where id equals the Model’s id (in other words, perform a with(‘tripAwb’)-> retrieval), but you can’t. For the drop-down menu in the form to preselect the right values, the form needs to access an array of values, not an array of objects. To achieve that, add some code to the loadModel() method of the TripController. This method is called for the update, delete, and view actions and just returns a single Model. The Model is loaded using:


public function loadModel($id)
{

$model=Trip::model()->findByPk($id);

// added for update by karthick
$criteria=new CDbCriteria;
$criteria->condition=’trip=:trip’;
$criteria->select = ‘awb’;
$criteria->params=array(‘:trip’=>$_GET[‘id’]);
$tripAwbs = TripAwb::model()->findAll($criteria);

$Awbs = array();
foreach ($tripAwbs as $awb) {
$Awbs[] = $awb->awb;
}

$model->tripAwbs = $Awbs;

if($model===null)
throw new CHttpException(404,’The requested page does not exist.’);
return $model;
}

Then update the tbl_tripAwb when the form is submitted (and the post is updated). The easiest way to handle all possibilities is to clear out the existing values (for this trip) in tbl_tripAWb, and then add them new. To do that, in actionUpdate() of the TripController, you would have:


if(isset($_POST['Trip']))
{
$model->attributes=$_POST['Trip'];
if($model->save()) {
$criteria=new CDbCriteria;
$criteria->condition='trip=:trip';
$criteria->params=array(':trip'=>$model->id);
tripAwb::model()->deleteAll($criteria);

// repeat of for each loop found in actionCreate()

foreach ($_POST[‘Trip’][‘tripAwbs’] as $awb) {
$tripAwb = new TripAwb;
$tripAwb->trip = $model->id;
$tripAwb->awb = $awb;
if (!$tripAwb->save()) print_r($tripAwb->errors);
}

$this->redirect(array(‘view’,’id’=>$model->id));
}

}

First Step before Creating a Webapp with YII


  1. Install LAMP Server
  2. Install PHPunit
  3. % sudo pear channel-discover pear.phpunit.de
    % sudo pear install phpunit/PHPUnit

  4. Install Selenium
  5. Download Selenium Remote Control (Selenium RC) zip file from http://seleniumhq.org/download/.
    Run Server from shell

    % java -jar selenium-server.jar

  6. Running the Functional Tests
  7. Before we can run this functional test, we need to make a couple of configuration changes to our application. First we need to alter protected/tests/WebTestCase. php to properly define our test URL that Selenium will attempt to open when it runs
    the tests. Open up that file and make sure the TEST_BASE_URL definition matches the URL to your webapp

    define(‘TEST_BASE_URL’,’http://localhost/webapp/index-test.php/&#8217;);

    The file protected/tests/phpunit.xml houses some configuration settings for Selenium Server. It is configured to use IE as the primary browser. We can remove the following highlighted line of code to ensure only Firefox will be used when running Selenium:

    name=”Internet Explorer” browser=”*iexplore”

    Now, as long as you have installed PHPUnitand have ensured that Selenium Server is running, and then we can navigate to our tests folder at the command prompt and run this functional test:

    % cd protected/tests/
    % phpunit functional/SiteTest.php

    What should happen is that you will see your browser being automatically invoked, as the Selenium Server platform is using the browser to access the end-user functionality of the site that we configured in the WebTestCase.php file. As it runs through the test methods, it actually automates the behavior of a real user of the site.

  8. Configure Gedit for PHP
  9. Install Netbeans
  10. SVN update the latest YII
  11. install the webapp in the webroot
  12. Testing the DB Connection
  13. we know we add our unit tests under protected/tests/unit/. Let’s create a simple database connectivity test file under this folder called DbTest.php. Create this new file with the following contents:

    class DbTest extends CTestCase
    {
    public function testConnection()
    {
    $this->assertTrue(true);
    }
    }

    Here we have added a fairly trivial test. The assertTrue() method, which is part of phpUnit, is an assertion that will pass if the argument passed to it is true, and it will fail if it is false. So, in this case, it will pass if true is true. Of course it is, so this test will pass. We are doing this to make sure our new application is working as expected for testing. Navigate to the tests folder and execute this new test:

    % cd /WebRoot/trackstar/protected/tests
    % phpunit unit/DbTest.php

    Change the trivial assertEquals(true) statement in the testConnection() test method to:

    $this->assertNotEquals(NULL, Yii::app()->db);

    And rerun the test:

  14. Configuring YII to use MySQL
  15. To customize our application configuration, we normally provide a configuration file
    to initialize its property values when the application instance is being created. The
    main application configuration file is located in /protected/config/main.php.