Thursday, July 5, 2012

Using modules in Yii

What is modules?
Module is separate piece of application that can have Models, Controller,Views, modules are placed in protected/modules directory. We can define login system for modules.Module cannot be deployed alone it needs application to run.
  • Modules can be nested in unlimited levels
  • Modules may have separate login system

Application directory structure

 protected
   /commands
   /components
   /config
   /controllers
   /models
   /modules
       /admin       
       /user
       /agent

We have three modules placed under modules directory namely admin,user,agent. if we look in to the module directory structure we can find many files and folders similar to application.

   /modules
       /admin    
          AdminModule.php
          components/                
          controllers/                       
               DefaultController.php   
          extensions/                      
          models/                    
         views/                     
         layouts/               
         default/              
             index.php            


Why we have to use modules?
In large scale application we may divide our application in to many modules so that they can be resused later and it makes application maintenance easier.

Creating a Modules
Enable Gii in application config, open Gii generator using yourapplication/?r=gii/default/login in browser addresbar, then type your password,
'modules' => array(
        // uncomment the following to enable the Gii tool
        'gii' => array(
            'class' => 'system.gii.GiiModule',
            'password' => 'giitest',
        ),
         .......
click module generator enter your module name that's all yii will do the rest.
Gii module generator


Using Module
To use modules in our application, we have to configure it in application config file
'modules' => array(
        // uncomment the following to enable the Gii tool
        'gii' => array(
            'class' => 'system.gii.GiiModule',
            'password' => 'giitest',
        ),
        'user', //user module
        'admin', //admin module
        'agent', //agent module
    ),

Nested Module
Module can have any number of nested module.one module can contain another module previous module called parent module later module called child module so one can access child module action like. parentModuleID/childModuleID/controllerID/actionID
'modules'=>array(
    'module1'=>array(
        'modules'=>array(
            'module2',
            'module3'
        )
    )
)

 Sharing Models/Components/extensions to Modules

To share application's models/components/extensions to module, just import them using setImport function.

Here we are sharing models from user module, so admin and user model will use same model across application

class AdminModule extends CWebModule
{
 public function init()
 {
  // this method is called when the module is being created
  // you may place code here to customize the module or the application

  // import the module-level models and components
  $this->setImport(array(
   'admin.models.*',
   'admin.components.*',
   'user.models.Profile',      //sharing models from user module
   'user.models.TransactionHistory',
                        'agent.models.*',
  ));
               .....


Sharing Layouts to Modules

To share a main layout to module controller

class AdminController extends Controller
{ 
 public $layout='//layouts/admin';
...

the above statement uses admin template from protected/views/layouts/admin

// uses application views folder, refers to "protected/views/layouts"
/ uses module views folder refers to "protected/modules/module/views/layouts"

Creating Login system for Modules
Refer my previous article Module based login 


Pointing Subdomains to modules

Point sub-domain to module

This tips from the forum URL Subdomain to module

There is a feature called "Parameterizing Hostnames" (described on this pages). add the following lines to main.php

'components' => array(
   ...
   'urlManager' => array(
      'rules' => array(
         'http://customer.example.com' => 'customer/default/index',
         'http://customer.example.com/login' => 'customer/default/login',
      ),
   ),
   ...
),

So "customer/default/index" refers to the module "customer" with controller "default" and action "index".>

Getting action/controller/module name in Yii

Some times we need to know the current controller/module/action name in our application, Yii provides the default methods to accomplish the tasks.

To get a controller name
Yii::app()->controller->id //or
Yii::app()->getController()->getId()
$this->id  here $this refers to current controller 

To get method/action name
Yii::app()->controller->action->id
You can get action name in controller
$this->action->id

To get module name
Yii::app()->controller->module->id
$this->module->id

Tuesday, July 3, 2012

All about validation in Yii - PART1

Validation in YII (Server side & Client Side)- PART 1

Yii support server side validation &  client side validation and it has wide range of built in validators, here we are going to see the each and every points about validation features that Yii provide.

Declaring Validation Rules


We specify the validation rules in Model class through the rules() method which should return an array of rule configurations. validators are called in order if we specified more than one validator for attribute
rules() method is a default method that triggers yii validation by using rules() method while validate() called. validate() function triggered automatically while we call $model->save() orcall $model->validate().

Validation rule syntax


array('AttributeList', 'Validator', 'on'=>'ScenarioList'...), 
    

Here AttributeList defines the list of model attributes, if more than one attribute it should be separated by comma.
Validator defines type of validation to be done yii provides the built in validators for email, url and so on refer table 1 for built in validators.
ScenarioList tells on which scenario the validation rule should fire, more than one scenario will be separated by comma.

Adding validations to model


        public function rules(){
        return array('username','required');
        }
    

the above validation rule tells the yii to validate username fields to be mandatory through required validator. we apply same validation rule for  more than one field, by separating them with comma
        public function rules(){
        return array('username,password','required');
        }
    

in the above example we set username and password field to be mandatory and we can apply more than validation to same attribute
        public function rules(){
        return array(
        array('username,password','required');
        array('username','length','min'=>3, 'max'=>12);        
        }
        }    
    

Above example tells yii to validate username attribute length should have 3-12 and it is required.

Yii triggers validation when we call $model->validate(); or $model->save(); While saving records validation automatically called by default, if validation should be avoided in save methods $model->save(false); //which cancels validation

Clear steps

Model Finally model looks likes this
        class LoginForm extends CFormModel
        {
        public $username;
        public $password;        
        public function rules()
        {
        return array(
        array('username, password', 'required'),
        array('username','length','min'=>3, 'max'=>12);
        );
        }  
        }
    



Controller
$model = new Users();

Trigger Validation
$model->validate();

View
to get particular field validation error, Yii add these statements to view by default why we scaffolding our code.

<?php echo $form->error($model, 'username'); ?> 
To get error summary for all fields
<?php echo $form->errorSummary($model); ?>



Contd.. on PART II

Handle JSON Response in Yii

Convert array to json data
convert array data to json using json_encode() function use the below example, $this->layout=false makes yii to stop rendering layout for this action.

public function actionJsonTest(){
$this->layout=false;
$arr=array('Fruits'=>array('apples','orange'),'Vegetables'=>array('beans','carrot'));
header('Content-type: application/json');
echo json_encode($arr);
Yii::app()->end();
}


Convert model data to json 
convert your existing model data to json
  header('Content-type: application/json');
  $post = Post::model()->findByPK((int)$id);
  echo CJSON::encode($post);
  Yii::app()->end();


Convert model data with relations to json 
use this behaviour Converts Model Attributes and its Relations to a JSON  http://www.yiiframework.com/extension/ejsonbehavior/

Shopping cart in yii

Yii based shopping cart


Here is my compilation but i couldn't find any full fledged e-commerce framework. this will help some one to create complete e-commerce application.



yii-shop

Shopping cart component
Yii based ecommerce site but not open source
Shopping cart
Yii Cart
A tiny shopping cart script that supports batch products additions

Tuesday, June 26, 2012

Handling Scripts and CSS in Yii Framework

Handling Scripts and CSS in Yii Framework

Yii provide CClientScript to manage the scripts and css files in Yii.

Registering Core scripts that comes with Yii

To register the core jquery library that comes with yii, use the following methods.

Yii::app()->clientScript->registerCoreScript('jquery');
Yii::app()->clientScript->registerCoreScript( 'jquery.ui' );
//We need to pre-render the jquery.yiiactiveform.js on the view where we are going to place the AJAX functionality
Yii::app()->clientScript->registerCoreScript('yiiactiveform');

The above statement register the Jquery library and jquery ui, if YII_DEBUG is false then yii will register minimized version of Jquery & Jquery UI library.

To register inline scripts and css files
Yii::app()->clientScript->registerScript('unique scriptname','js code',position)

Yii::app()->clientScript->registerCss('unique css','csscode','media=>print/handheld/screen')

Script Positions

CClientScript::POS_HEAD : the script is inserted in the head section right before the title element. .
CClientScript::POS_BEGIN : the script is inserted at the beginning of the body section.
CClientScript::POS_END : the script is inserted at the end of the body section.
CClientScript::POS_LOAD : the script is inserted in the window.onload() function.
CClientScript::POS_READY : the script is inserted in the jQuery's ready function.

so if you use,
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . '/script/test.js',CClientScript::POS_END);
then the script will be inserted to the body section

To register external scripts and css files

Yii::app()->clientScript->registerCssFile($yourscript_asset. '/test.css');
Yii::app()->clientScript->registerScriptFile($yourscript_asset. '/test.js')

Publishing scripts to assets directory

Asset manager in brief

CAssetManager is a Web application component that manages private files (called assets) and makes them accessible by Web clients. It achieves this goal by copying assets to a Web-accessible directory and returns the corresponding URL for accessing them.
you can compress and minify and otherwise process your assets with the asset publishing system, and it makes it easier to host your JS and CSS on a CDN since it's separate from your codebase.With assets, a component can be used easily without worrying about what files to be copied to public directories and what their URLs are
Consider a scenario, if we have two scripts which is located in scripts/testscript, the directory has two files namely test.js and test.css. We are going to publish it to asset and then we consume that files from asset directory, here is the snippet
$yourscript_asset= Yii::app()->assetManager->publish(Yii::app()->basePath . '/scripts/testscript /');

//Register JS and CSS files        
Yii::app()->clientScript->registerCssFile($yourscript_asset. '/test.css');
Yii::app()->clientScript->registerScriptFile($yourscript_asset. '/test.js');

Tips

Load files from google server

Cleans all registered scripts before any script register

Cleans all registered scripts.
Yii::app()->getClientScript()->reset();

Prevent loading jquery files

Yii::app()->clientScript->scriptMap['jquery.js'] = false;
//or if more than one script to be prevent from registering
$cs=Yii::app()->clientScript;
$cs->scriptMap=array(
'jquery.js'=>false,
'jquery.ajaxqueue.js'=>false,
'jquery.metadata.js'=>false,
);

Avoiding scripts download on AJAX renderPartial request

Suppose we created a function to display the AJAX active form and its contents are returned by a call to a controller’s action that will partially render a view.
// Just before rendering the view that
// has our activeform
Yii::app()->clientScript->corePackages = array();
Now controller doesn't return script files.
It is very important that we set corePackages to array() instead of null, as setting it to null will make CClientScript to reload the packages.php file (located in framework/web/js/) and we won’t stop the duplication of the script.

Saturday, June 23, 2012

Joomla Security Fixes

Hosting security stuff

Turn off following settings in php.ini file



1.allow_url_fopen
allow_url_fopen allows PHP's functions such as file_get_contents() and the include and require statements can retrieve data from remote locations like an FTP or http protocol and could lead to code injection vulnerabilities,

You should disable allow_url_fopen in the php.ini file:

; Disable allow_url_fopen for security reasons
allow_url_fopen = 'off'

The setting can also be disabled in apache's httpd.conf file:
# Disable allow_url_fopen for security reasons
php_flag  allow_url_fopen  off

If you are using shared hosting use my php.ini file


2. display_errors setting
It should be turned off in production environment to hide annoying error messages.instead of showing erro messages we log them into to log file.

;in php.ini file
display_errors=off

log_errors =off

# Disable display_errors for security reasons
php_flag  display_errors  off
php_flag  log_errors  on


3.magic_quotes_gpc
When magic_quotes are on, all ' (single-quote), " (double quote), \ (backslash) and NULs are escaped with a backslash automatically. This is to prevent all sorts of injection security issues.

if input data contains single or multiple quotes, data automatically escaped with slashes so multiply the problem by repeatedly re-escaping the escaped stuff and you end up with strings like
<a href=\"\\&quot;\\\\&quot;\\\\\\\\&quot;\\... !!

;in php.ini file
magic_quotes_gpc=off

Joomla security stuff

1. Use latest Joomla security update
    Get latest joomla updates from here http://joomlacode.org/gf/project/joomla/frs/

2. All the sql injection takes place through the jos_users table , first off all change the databse prefix

    execute the following queries to change table prefix names

SELECT CONCAT('RENAME TABLE ', GROUP_CONCAT('`', TABLE_SCHEMA, '`.`', TABLE_NAME, '` TO `', TABLE_SCHEMA, '`.`yourprefix_', TABLE_NAME, '`')) AS q
FROM   `information_schema`.`Tables` WHERE TABLE_SCHEMA='yourdatabasename';

Change the prefix name value in configuration.php file also
var $dbprefix = 'yourprefix_';


3.Use only secure third party plugins and keep them updated

4.Use secure username and password for administrators
use strongpasswordgenerator.com or some other tool to generate strong password

5.Use an SEF component that makes your Joomla more secure
use .htaccess files provided with joomla package (just rename htaccess.txt to .htaccess)


6.Write-protect your Joomla configuration file (make unwriteable)
set 444 permission to configuration.php


7.Delete Joomla templates and unnecessary files/folders that you do not use




Sunday, June 17, 2012

Fixing The CSRF token could not be verified

"The CSRF token could not be verified", if you get this message while using YII Framework. the issue can happen in
1.You are not using CHtml Form widget
2.You are not using CActiveFormWidget
3.You are using cusom ajax handlers

If you are using CHtml Form widget or CActiveForm widget the Yii Framework automatically validate CSRF token, if we using custom form or custom jquery ajax methods we should pass YII_CSRF_TOKEN to POST request, this may solve the above issue


$csrfToken = Yii::app()->request->csrfToken; // 
will return the csrf token associated with the context, you can now use that csr token to pass in jquery ajax functions


to check csrfvalidation enabled in application use the following method to get status
if(Yii::app()->request->enableCsrfValidation) 

Getting CSRF Token from javascript
YII_CSRF_TOKEN=$('input[name="YII_CSRF_TOKEN"]').val();

open source projects built with yii

List of open source projects built with yii, this is the partial list, if you know others let me know.


Project
Description
Link
 Hamster  Forum software  https://github.com/samdark/hamster
 Celestic Open source project manager http://qbit.com.mx/labs/celestic/
Zurmo CRM
Customer Relationship Management – CRM
X2 Engine
Customer Relationship Management – CRM
Bugitor
Bug tracker application
Topics
Question and answer site like stackoverflow
Flexica CMS
Content Management System
Phundament CMS
Content Management System
Yii CMS - GXC-CMS

Content Management System
yay-cms
Content Management System

Web 2.0 CMS

Content Management System


Content Management System


Content Management System

YiiBackbone

blog web application
Simple Project Manager / Bug Tracker

Yeeki
Wiki application/module
Open Real Estate Used to built websites of real estate agencies and realtors. http://monoray.net/products/6-open-real-estate