Browse Source
			
			
			
			
				
		* 'master' of github.com:yiisoft/yii2: (87 commits) Added dirty attribute description. Fixed doc about renderers. Finished the initial draft of upgrading instructions Fix attaching behavior via config Changed default value of View::renderers. Fix attaching behavior via config Menu WIP upgrading instructions WIP Refactored Breadcrumbs. Fixes issue #54: Implemented Breadcrumbs. Added Breadcrumbs.php Fixes issue #134 Rollback word consistencty over entire codebase (ref. #139). Add ensureBehaviors() to detachBehavior*() Fixes issue #124. code reorganization fix. reorganized app code. removed app template from framework folder. Fixes issue #128. Fixes issue #124. Add Newlines ... Conflicts: tests/unit/framework/caching/ApcCacheTest.phptags/2.0.0-beta
				 209 changed files with 13359 additions and 10720 deletions
			
			
		@ -0,0 +1,14 @@
					 | 
				
			||||
language: php | 
				
			||||
 | 
				
			||||
php: | 
				
			||||
  - 5.3 | 
				
			||||
  - 5.4 | 
				
			||||
  - 5.5 | 
				
			||||
 | 
				
			||||
env: | 
				
			||||
  - DB=mysql | 
				
			||||
 | 
				
			||||
before_script: | 
				
			||||
  - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS yiitest;'; fi" | 
				
			||||
 | 
				
			||||
script: phpunit | 
				
			||||
@ -1,26 +0,0 @@
					 | 
				
			||||
<?php | 
				
			||||
/** | 
				
			||||
 * @var $this \yii\base\View | 
				
			||||
 * @var $content string | 
				
			||||
 */ | 
				
			||||
use yii\helpers\Html; | 
				
			||||
?> | 
				
			||||
<?php $this->beginPage(); ?> | 
				
			||||
<!DOCTYPE html> | 
				
			||||
<html lang="en"> | 
				
			||||
<head> | 
				
			||||
	<meta charset="utf-8" /> | 
				
			||||
	<title><?php echo Html::encode($this->title); ?></title>
 | 
				
			||||
	<?php echo Html::cssFile("css/bootstrap.min.css", array('media' => 'screen')); ?> | 
				
			||||
	<?php $this->head(); ?> | 
				
			||||
</head> | 
				
			||||
<body> | 
				
			||||
	<div class="container"> | 
				
			||||
		<h1>Welcome</h1> | 
				
			||||
		<?php $this->beginBody(); ?> | 
				
			||||
		<?php echo $content; ?> | 
				
			||||
		<?php $this->endBody(); ?> | 
				
			||||
	</div> | 
				
			||||
</body> | 
				
			||||
</html> | 
				
			||||
<?php $this->endPage(); ?> | 
				
			||||
@ -1,17 +0,0 @@
					 | 
				
			||||
<?php | 
				
			||||
/** @var $this \yii\base\View */ | 
				
			||||
 | 
				
			||||
use yii\helpers\Html; | 
				
			||||
 | 
				
			||||
$this->title = 'Hello World'; | 
				
			||||
 | 
				
			||||
$user = Yii::$app->getUser(); | 
				
			||||
if ($user->isGuest) { | 
				
			||||
	echo Html::a('login', array('login')); | 
				
			||||
} else { | 
				
			||||
	echo "You are logged in as " . $user->identity->username . "<br/>"; | 
				
			||||
	echo Html::a('logout', array('logout')); | 
				
			||||
} | 
				
			||||
?> | 
				
			||||
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,78 @@
					 | 
				
			||||
body { | 
				
			||||
	padding-top: 20px; | 
				
			||||
	padding-bottom: 60px; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/* Custom container */ | 
				
			||||
.container { | 
				
			||||
	margin: 0 auto; | 
				
			||||
	max-width: 1000px; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.container > hr { | 
				
			||||
	margin: 60px 0; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/* Main marketing message and sign up button */ | 
				
			||||
.jumbotron { | 
				
			||||
	margin: 80px 0; | 
				
			||||
	text-align: center; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.jumbotron h1 { | 
				
			||||
	font-size: 100px; | 
				
			||||
	line-height: 1; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.jumbotron .lead { | 
				
			||||
	font-size: 24px; | 
				
			||||
	line-height: 1.25; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.jumbotron .btn { | 
				
			||||
	font-size: 21px; | 
				
			||||
	padding: 14px 24px; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/* Supporting marketing content */ | 
				
			||||
.marketing { | 
				
			||||
	margin: 60px 0; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.marketing p + h4 { | 
				
			||||
	margin-top: 28px; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/* Customize the navbar links to be fill the entire space of the .navbar */ | 
				
			||||
.navbar .navbar-inner { | 
				
			||||
	padding: 0; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.navbar .nav { | 
				
			||||
	margin: 0; | 
				
			||||
	display: table; | 
				
			||||
	width: 100%; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.navbar .nav li { | 
				
			||||
	display: table-cell; | 
				
			||||
	width: 1%; | 
				
			||||
	float: none; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.navbar .nav li a { | 
				
			||||
	font-weight: bold; | 
				
			||||
	text-align: center; | 
				
			||||
	border-left: 1px solid rgba(255, 255, 255, .75); | 
				
			||||
	border-right: 1px solid rgba(0, 0, 0, .1); | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.navbar .nav li:first-child a { | 
				
			||||
	border-left: 0; | 
				
			||||
	border-radius: 3px 0 0 3px; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
.navbar .nav li:last-child a { | 
				
			||||
	border-right: 0; | 
				
			||||
	border-radius: 0 3px 3px 0; | 
				
			||||
} | 
				
			||||
| 
		 Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB  | 
| 
		 Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB  | 
@ -0,0 +1,19 @@
					 | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
return array( | 
				
			||||
	'app' => array( | 
				
			||||
		'basePath' => '@wwwroot', | 
				
			||||
		'baseUrl' => '@www', | 
				
			||||
		'css' => array( | 
				
			||||
			'css/bootstrap.min.css', | 
				
			||||
			'css/bootstrap-responsive.min.css', | 
				
			||||
			'css/site.css', | 
				
			||||
		), | 
				
			||||
		'js' => array( | 
				
			||||
 | 
				
			||||
		), | 
				
			||||
		'depends' => array( | 
				
			||||
			'yii', | 
				
			||||
		), | 
				
			||||
	), | 
				
			||||
); | 
				
			||||
@ -0,0 +1,63 @@
					 | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
namespace app\models; | 
				
			||||
 | 
				
			||||
use yii\base\Model; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * ContactForm is the model behind the contact form. | 
				
			||||
 */ | 
				
			||||
class ContactForm extends Model | 
				
			||||
{ | 
				
			||||
	public $name; | 
				
			||||
	public $email; | 
				
			||||
	public $subject; | 
				
			||||
	public $body; | 
				
			||||
	public $verifyCode; | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * @return array the validation rules. | 
				
			||||
	 */ | 
				
			||||
	public function rules() | 
				
			||||
	{ | 
				
			||||
		return array( | 
				
			||||
			// name, email, subject and body are required | 
				
			||||
			array('name, email, subject, body', 'required'), | 
				
			||||
			// email has to be a valid email address | 
				
			||||
			array('email', 'email'), | 
				
			||||
			// verifyCode needs to be entered correctly | 
				
			||||
			//array('verifyCode', 'captcha', 'allowEmpty' => !Captcha::checkRequirements()), | 
				
			||||
		); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * @return array customized attribute labels | 
				
			||||
	 */ | 
				
			||||
	public function attributeLabels() | 
				
			||||
	{ | 
				
			||||
		return array( | 
				
			||||
			'verifyCode' => 'Verification Code', | 
				
			||||
		); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Sends an email to the specified email address using the information collected by this model. | 
				
			||||
	 * @param string $email the target email address | 
				
			||||
	 * @return boolean whether the model passes validation | 
				
			||||
	 */ | 
				
			||||
	public function contact($email) | 
				
			||||
	{ | 
				
			||||
		if ($this->validate()) { | 
				
			||||
			$name = '=?UTF-8?B?' . base64_encode($this->name) . '?='; | 
				
			||||
			$subject = '=?UTF-8?B?' . base64_encode($this->subject) . '?='; | 
				
			||||
			$headers = "From: $name <{$this->email}>\r\n" . | 
				
			||||
				"Reply-To: {$this->email}\r\n" . | 
				
			||||
				"MIME-Version: 1.0\r\n" . | 
				
			||||
				"Content-type: text/plain; charset=UTF-8"; | 
				
			||||
			mail($email, $subject, $this->body, $headers); | 
				
			||||
			return true; | 
				
			||||
		} else { | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,60 @@
					 | 
				
			||||
<?php | 
				
			||||
/** | 
				
			||||
 * @var $this \yii\base\View | 
				
			||||
 * @var $content string | 
				
			||||
 */ | 
				
			||||
use yii\helpers\Html; | 
				
			||||
$this->registerAssetBundle('app'); | 
				
			||||
?> | 
				
			||||
<?php $this->beginPage(); ?> | 
				
			||||
<!DOCTYPE html> | 
				
			||||
<html lang="en"> | 
				
			||||
<head> | 
				
			||||
	<meta charset="utf-8"/> | 
				
			||||
	<title><?php echo Html::encode($this->title); ?></title>
 | 
				
			||||
	<?php $this->head(); ?> | 
				
			||||
</head> | 
				
			||||
<body> | 
				
			||||
<div class="container"> | 
				
			||||
	<?php $this->beginBody(); ?> | 
				
			||||
	<div class="masthead"> | 
				
			||||
		<h3 class="muted">My Company</h3> | 
				
			||||
 | 
				
			||||
		<div class="navbar"> | 
				
			||||
			<div class="navbar-inner"> | 
				
			||||
				<div class="container"> | 
				
			||||
					<ul class="nav"> | 
				
			||||
						<li><?php echo Html::a('Home', Yii::$app->homeUrl); ?></li>
 | 
				
			||||
						<li><?php echo Html::a('About', array('/site/about')); ?></li>
 | 
				
			||||
						<li><?php echo Html::a('Contact', array('/site/contact')); ?></li>
 | 
				
			||||
						<?php if (Yii::$app->user->isGuest): ?> | 
				
			||||
						<li><?php echo Html::a('Login', array('/site/login')); ?></li>
 | 
				
			||||
						<?php else: ?> | 
				
			||||
						<li><?php echo Html::a('Logout (' . Html::encode(Yii::$app->user->identity->username) . ')', array('/site/logout')); ?></li>
 | 
				
			||||
						<?php endif; ?> | 
				
			||||
					</ul> | 
				
			||||
				</div> | 
				
			||||
			</div> | 
				
			||||
		</div> | 
				
			||||
		<!-- /.navbar --> | 
				
			||||
	</div> | 
				
			||||
 | 
				
			||||
	<?php $this->widget('yii\widgets\Breadcrumbs', array( | 
				
			||||
		'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : array(), | 
				
			||||
	)); ?> | 
				
			||||
	<?php echo $content; ?> | 
				
			||||
 | 
				
			||||
	<hr> | 
				
			||||
 | 
				
			||||
	<div class="footer"> | 
				
			||||
		<p>© My Company <?php echo date('Y'); ?></p>
 | 
				
			||||
		<p> | 
				
			||||
			<?php echo Yii::powered(); ?> | 
				
			||||
			Template by <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a> | 
				
			||||
		</p> | 
				
			||||
	</div> | 
				
			||||
	<?php $this->endBody(); ?> | 
				
			||||
</div> | 
				
			||||
</body> | 
				
			||||
</html> | 
				
			||||
<?php $this->endPage(); ?> | 
				
			||||
@ -0,0 +1,16 @@
					 | 
				
			||||
<?php | 
				
			||||
use yii\helpers\Html; | 
				
			||||
/** | 
				
			||||
 * @var yii\base\View $this | 
				
			||||
 */ | 
				
			||||
$this->title = 'About'; | 
				
			||||
$this->params['breadcrumbs'][] = $this->title; | 
				
			||||
?> | 
				
			||||
<h1><?php echo Html::encode($this->title); ?></h1>
 | 
				
			||||
 | 
				
			||||
<p> | 
				
			||||
	This is the About page. You may modify the following file to customize its content: | 
				
			||||
</p> | 
				
			||||
 | 
				
			||||
<code><?php echo __FILE__; ?></code>
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,34 @@
					 | 
				
			||||
<?php | 
				
			||||
use yii\helpers\Html; | 
				
			||||
/** | 
				
			||||
 * @var yii\base\View $this | 
				
			||||
 * @var yii\widgets\ActiveForm $form | 
				
			||||
 * @var app\models\ContactForm $model | 
				
			||||
 */ | 
				
			||||
$this->title = 'Contact'; | 
				
			||||
$this->params['breadcrumbs'][] = $this->title; | 
				
			||||
?> | 
				
			||||
<h1><?php echo Html::encode($this->title); ?></h1>
 | 
				
			||||
 | 
				
			||||
<?php if(Yii::$app->session->hasFlash('contactFormSubmitted')): ?> | 
				
			||||
<div class="alert alert-success"> | 
				
			||||
	Thank you for contacting us. We will respond to you as soon as possible. | 
				
			||||
</div> | 
				
			||||
<?php return; endif; ?> | 
				
			||||
 | 
				
			||||
<p> | 
				
			||||
	If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. | 
				
			||||
</p> | 
				
			||||
 | 
				
			||||
<?php $form = $this->beginWidget('yii\widgets\ActiveForm', array( | 
				
			||||
	'options' => array('class' => 'form-horizontal'), | 
				
			||||
	'fieldConfig' => array('inputOptions' => array('class' => 'input-xlarge')), | 
				
			||||
)); ?> | 
				
			||||
	<?php echo $form->field($model, 'name')->textInput(); ?> | 
				
			||||
	<?php echo $form->field($model, 'email')->textInput(); ?> | 
				
			||||
	<?php echo $form->field($model, 'subject')->textInput(); ?> | 
				
			||||
	<?php echo $form->field($model, 'body')->textArea(array('rows' => 6)); ?> | 
				
			||||
	<div class="form-actions"> | 
				
			||||
		<?php echo Html::submitButton('Submit', null, null, array('class' => 'btn btn-primary')); ?> | 
				
			||||
	</div> | 
				
			||||
<?php $this->endWidget(); ?> | 
				
			||||
@ -0,0 +1,47 @@
					 | 
				
			||||
<?php | 
				
			||||
/** | 
				
			||||
 * @var yii\base\View $this | 
				
			||||
 */ | 
				
			||||
$this->title = 'Welcome'; | 
				
			||||
?> | 
				
			||||
<div class="jumbotron"> | 
				
			||||
	<h1>Welcome!</h1> | 
				
			||||
 | 
				
			||||
	<p class="lead">Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus | 
				
			||||
		commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p> | 
				
			||||
	<a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a> | 
				
			||||
</div> | 
				
			||||
 | 
				
			||||
<hr> | 
				
			||||
 | 
				
			||||
<!-- Example row of columns --> | 
				
			||||
<div class="row-fluid"> | 
				
			||||
	<div class="span4"> | 
				
			||||
		<h2>Heading</h2> | 
				
			||||
 | 
				
			||||
		<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris | 
				
			||||
			condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. | 
				
			||||
			Donec sed odio dui. </p> | 
				
			||||
 | 
				
			||||
		<p><a class="btn" href="#">View details »</a></p> | 
				
			||||
	</div> | 
				
			||||
	<div class="span4"> | 
				
			||||
		<h2>Heading</h2> | 
				
			||||
 | 
				
			||||
		<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris | 
				
			||||
			condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. | 
				
			||||
			Donec sed odio dui. </p> | 
				
			||||
 | 
				
			||||
		<p><a class="btn" href="#">View details »</a></p> | 
				
			||||
	</div> | 
				
			||||
	<div class="span4"> | 
				
			||||
		<h2>Heading</h2> | 
				
			||||
 | 
				
			||||
		<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta | 
				
			||||
			felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum | 
				
			||||
			massa.</p> | 
				
			||||
 | 
				
			||||
		<p><a class="btn" href="#">View details »</a></p> | 
				
			||||
	</div> | 
				
			||||
</div> | 
				
			||||
 | 
				
			||||
@ -0,0 +1,63 @@
					 | 
				
			||||
Bootstrap with Yii | 
				
			||||
================== | 
				
			||||
 | 
				
			||||
A ready-to-use Web application is distributed together with Yii. You may find | 
				
			||||
its source code under the `app` folder after you expand the Yii release file. | 
				
			||||
If you have installed Yii under a Web-accessible folder, you should be able to | 
				
			||||
access this application through the following URL: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
http://localhost/yii/apps/bootstrap/index.php | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
As you can see, the application has four pages: the homepage, the about page, | 
				
			||||
the contact page and the login page. The contact page displays a contact | 
				
			||||
form that users can fill in to submit their inquiries to the webmaster, | 
				
			||||
and the login page allows users to be authenticated before accessing privileged contents. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
The following diagram shows the directory structure of this application. | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
app/ | 
				
			||||
   index.php                 Web application entry script file | 
				
			||||
   index-test.php            entry script file for the functional tests | 
				
			||||
   assets/                   containing published resource files | 
				
			||||
   css/                      containing CSS files | 
				
			||||
   img/                      containing image files | 
				
			||||
   themes/                   containing application themes | 
				
			||||
   protected/                containing protected application files | 
				
			||||
      yiic                   yiic command line script for Unix/Linux | 
				
			||||
      yiic.bat               yiic command line script for Windows | 
				
			||||
      yiic.php               yiic command line PHP script | 
				
			||||
      commands/              containing customized 'yiic' commands | 
				
			||||
      components/            containing reusable user components | 
				
			||||
      config/                containing configuration files | 
				
			||||
         console.php         the console application configuration | 
				
			||||
         main.php            the Web application configuration | 
				
			||||
      controllers/           containing controller class files | 
				
			||||
         SiteController.php  the default controller class | 
				
			||||
      data/                  containing the sample database | 
				
			||||
         schema.mysql.sql    the DB schema for the sample MySQL database | 
				
			||||
         schema.sqlite.sql   the DB schema for the sample SQLite database | 
				
			||||
         bootstrap.db        the sample SQLite database file | 
				
			||||
      vendor/                containing third-party extensions and libraries | 
				
			||||
      messages/              containing translated messages | 
				
			||||
      models/                containing model class files | 
				
			||||
         User.php            the User model | 
				
			||||
         LoginForm.php       the form model for 'login' action | 
				
			||||
         ContactForm.php     the form model for 'contact' action | 
				
			||||
      runtime/               containing temporarily generated files | 
				
			||||
      views/                 containing controller view and layout files | 
				
			||||
         layouts/            containing layout view files | 
				
			||||
            main.php         the base layout shared by all pages | 
				
			||||
         site/               containing view files for the 'site' controller | 
				
			||||
            about.php        the view for the 'about' action | 
				
			||||
            contact.php      the view for the 'contact' action | 
				
			||||
            index.php        the view for the 'index' action | 
				
			||||
            login.php        the view for the 'login' action | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
TBD | 
				
			||||
@ -0,0 +1,30 @@
					 | 
				
			||||
* [Overview](overview.md) | 
				
			||||
* [Installation](installation.md) | 
				
			||||
* [Bootstrap with Yii](bootstrap.md) | 
				
			||||
* [MVC Overview](mvc.md) | 
				
			||||
* [Controller](controller.md) | 
				
			||||
* [Model](model.md) | 
				
			||||
* [View](view.md) | 
				
			||||
* [Application](application.md) | 
				
			||||
* [Form](form.md) | 
				
			||||
* [Data Validation](validation.md) | 
				
			||||
* [Database Access Objects](dao.md) | 
				
			||||
* [Query Builder](query-builder.md) | 
				
			||||
* [ActiveRecord](active-record.md) | 
				
			||||
* [Database Migration](migration.md) | 
				
			||||
* [Caching](caching.md) | 
				
			||||
* [Internationalization](i18n.md) | 
				
			||||
* [Extending Yii](extension.md) | 
				
			||||
* [Authentication](authentication.md) | 
				
			||||
* [Authorization](authorization.md) | 
				
			||||
* [Logging](logging.md) | 
				
			||||
* [URL Management](url.md) | 
				
			||||
* [Theming](theming.md) | 
				
			||||
* [Error Handling](error.md) | 
				
			||||
* [Template](template.md) | 
				
			||||
* [Console Application](console.md) | 
				
			||||
* [Security](security.md) | 
				
			||||
* [Performance Tuning](performance.md) | 
				
			||||
* [Testing](testing.md) | 
				
			||||
* [Automatic Code Generation](gii.md) | 
				
			||||
* [Upgrading from 1.1 to 2.0](upgrade-from-v1.md) | 
				
			||||
@ -0,0 +1,112 @@
					 | 
				
			||||
Installation | 
				
			||||
============ | 
				
			||||
 | 
				
			||||
Installation of Yii mainly involves the following two steps: | 
				
			||||
 | 
				
			||||
   1. Download Yii Framework from [yiiframework.com](http://www.yiiframework.com/). | 
				
			||||
   2. Unpack the Yii release file to a Web-accessible directory. | 
				
			||||
 | 
				
			||||
> Tip: Yii does not need to be installed under a Web-accessible directory. | 
				
			||||
A Yii application has one entry script which is usually the only file that | 
				
			||||
needs to be exposed to Web users. Other PHP scripts, including those from | 
				
			||||
Yii, should be protected from Web access; otherwise they might be exploited | 
				
			||||
by hackers. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Requirements | 
				
			||||
------------ | 
				
			||||
 | 
				
			||||
After installing Yii, you may want to verify that your server satisfies | 
				
			||||
Yii's requirements. You can do so by accessing the requirement checker | 
				
			||||
script via the following URL in a Web browser: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
http://hostname/path/to/yii/requirements/index.php | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
Yii requires PHP 5.3, so the server must have PHP 5.3 or above installed and | 
				
			||||
available to the web server. Yii has been tested with [Apache HTTP server](http://httpd.apache.org/) | 
				
			||||
on Windows and Linux. It may also run on other Web servers and platforms, | 
				
			||||
provided PHP 5.3 is supported. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Recommended Apache Configuration | 
				
			||||
-------------------------------- | 
				
			||||
 | 
				
			||||
Yii is ready to work with a default Apache web server configuration. | 
				
			||||
The `.htaccess` files in Yii framework and application folders deny | 
				
			||||
access to the restricted resources. To hide the bootstrap file (usually `index.php`) | 
				
			||||
in your URLs you can add `mod_rewrite` instructions to the `.htaccess` file | 
				
			||||
in your document root or to the virtual host configuration: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
RewriteEngine on | 
				
			||||
 | 
				
			||||
# if a directory or a file exists, use it directly | 
				
			||||
RewriteCond %{REQUEST_FILENAME} !-f | 
				
			||||
RewriteCond %{REQUEST_FILENAME} !-d | 
				
			||||
# otherwise forward it to index.php | 
				
			||||
RewriteRule . index.php | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Recommended Nginx Configuration | 
				
			||||
------------------------------- | 
				
			||||
 | 
				
			||||
You can use Yii with [Nginx](http://wiki.nginx.org/) and PHP with [FPM SAPI](http://php.net/install.fpm). | 
				
			||||
Here is a sample host configuration. It defines the bootstrap file and makes | 
				
			||||
Yii to catch all requests to nonexistent files, which allows us to have nice-looking URLs. | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
server { | 
				
			||||
    set $host_path "/www/mysite"; | 
				
			||||
    access_log  /www/mysite/log/access.log  main; | 
				
			||||
 | 
				
			||||
    server_name  mysite; | 
				
			||||
    root  $host_path/htdocs; | 
				
			||||
    set $yii_bootstrap "index.php"; | 
				
			||||
 | 
				
			||||
    charset utf-8; | 
				
			||||
 | 
				
			||||
    location / { | 
				
			||||
        index  index.html $yii_bootstrap; | 
				
			||||
        try_files $uri $uri/ /$yii_bootstrap?$args; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    location ~ ^/(protected|framework|themes/\w+/views) { | 
				
			||||
        deny  all; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    #avoid processing of calls to unexisting static files by yii | 
				
			||||
    location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { | 
				
			||||
        try_files $uri =404; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 | 
				
			||||
    # | 
				
			||||
    location ~ \.php { | 
				
			||||
        fastcgi_split_path_info  ^(.+\.php)(.*)$; | 
				
			||||
 | 
				
			||||
        #let yii catch the calls to unexising PHP files | 
				
			||||
        set $fsn /$yii_bootstrap; | 
				
			||||
        if (-f $document_root$fastcgi_script_name){ | 
				
			||||
            set $fsn $fastcgi_script_name; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        fastcgi_pass   127.0.0.1:9000; | 
				
			||||
        include fastcgi_params; | 
				
			||||
        fastcgi_param  SCRIPT_FILENAME  $document_root$fsn; | 
				
			||||
 | 
				
			||||
        #PATH_INFO and PATH_TRANSLATED can be omitted, but RFC 3875 specifies them for CGI | 
				
			||||
        fastcgi_param  PATH_INFO        $fastcgi_path_info; | 
				
			||||
        fastcgi_param  PATH_TRANSLATED  $document_root$fsn; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    location ~ /\.ht { | 
				
			||||
        deny  all; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
Using this configuration you can set `cgi.fix_pathinfo=0` in php.ini to avoid | 
				
			||||
many unnecessary system `stat()` calls. | 
				
			||||
@ -0,0 +1,319 @@
					 | 
				
			||||
Database Migration | 
				
			||||
================== | 
				
			||||
 | 
				
			||||
Like source code, the structure of a database is evolving as we develop and maintain | 
				
			||||
a database-driven application. For example, during development, we may want to | 
				
			||||
add a new table; or after the application is put into production, we may realize | 
				
			||||
the need of adding an index on a column. It is important to keep track of these | 
				
			||||
structural database changes (called **migration**) like we do with our source | 
				
			||||
code. If the source code and the database are out of sync, it is very likely | 
				
			||||
the whole system may break. For this reason, Yii provides a database migration | 
				
			||||
tool that can keep track of database migration history, apply new migrations, | 
				
			||||
or revert existing ones. | 
				
			||||
 | 
				
			||||
The following steps show how we can use database migration during development: | 
				
			||||
 | 
				
			||||
1. Tim creates a new migration (e.g. create a new table) | 
				
			||||
2. Tim commits the new migration into source control system (e.g. GIT, Mercurial) | 
				
			||||
3. Doug updates from source control system and receives the new migration | 
				
			||||
4. Doug applies the migration to his local development database | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Yii supports database migration via the `yiic migrate` command line tool. This | 
				
			||||
tool supports creating new migrations, applying/reverting/redoing migrations, and | 
				
			||||
showing migration history and new migrations. | 
				
			||||
 | 
				
			||||
Creating Migrations | 
				
			||||
------------------- | 
				
			||||
 | 
				
			||||
To create a new migration (e.g. create a news table), we run the following command: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/create <name> | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
The required `name` parameter specifies a very brief description of the migration | 
				
			||||
(e.g. `create_news_table`). As we will show in the following, the `name` parameter | 
				
			||||
is used as part of a PHP class name. Therefore, it should only contain letters, | 
				
			||||
digits and/or underscore characters. | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/create create_news_table | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
The above command will create under the `protected/migrations` directory a new | 
				
			||||
file named `m101129_185401_create_news_table.php` which contains the following | 
				
			||||
initial code: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
[php] | 
				
			||||
class m101129_185401_create_news_table extends \yii\db\Migration | 
				
			||||
{ | 
				
			||||
	public function up() | 
				
			||||
	{ | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public function down() | 
				
			||||
	{ | 
				
			||||
		echo "m101129_185401_create_news_table cannot be reverted.\n"; | 
				
			||||
		return false; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
Notice that the class name is the same as the file name which is of the pattern | 
				
			||||
`m<timestamp>_<name>`, where `<timestamp>` refers to the UTC timestamp (in the | 
				
			||||
format of `yymmdd_hhmmss`) when the migration is created, and `<name>` is taken | 
				
			||||
from the command's `name` parameter. | 
				
			||||
 | 
				
			||||
The `up()` method should contain the code implementing the actual database | 
				
			||||
migration, while the `down()` method may contain the code reverting what is | 
				
			||||
done in `up()`. | 
				
			||||
 | 
				
			||||
Sometimes, it is impossible to implement `down()`. For example, if we delete | 
				
			||||
table rows in `up()`, we will not be able to recover them in `down()`. In this | 
				
			||||
case, the migration is called irreversible, meaning we cannot roll back to | 
				
			||||
a previous state of the database. In the above generated code, the `down()` | 
				
			||||
method returns `false` to indicate that the migration cannot be reverted. | 
				
			||||
 | 
				
			||||
As an example, let's show the migration about creating a news table. | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
[php] | 
				
			||||
class m101129_185401_create_news_table extends \yii\db\Migration | 
				
			||||
{ | 
				
			||||
	public function up() | 
				
			||||
	{ | 
				
			||||
		$this->db->createCommand()->createTable('tbl_news, array( | 
				
			||||
			'id' => 'pk', | 
				
			||||
			'title' => 'string NOT NULL', | 
				
			||||
			'content' => 'text', | 
				
			||||
		))->execute(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public function down() | 
				
			||||
	{ | 
				
			||||
		$this->db->createCommand()->dropTable('tbl_news')->execute(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
The base class [\yii\db\Migration] exposes a database connection via `db` | 
				
			||||
property. You can use it for manipulating data and schema of a database. | 
				
			||||
 | 
				
			||||
Transactional Migrations | 
				
			||||
------------------------ | 
				
			||||
 | 
				
			||||
While performing complex DB migrations, we usually want to make sure that each | 
				
			||||
migration succeed or fail as a whole so that the database maintains the | 
				
			||||
consistency and integrity. In order to achieve this goal, we can exploit | 
				
			||||
DB transactions. | 
				
			||||
 | 
				
			||||
We could explicitly start a DB transaction and enclose the rest of the DB-related | 
				
			||||
code within the transaction, like the following: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
[php] | 
				
			||||
class m101129_185401_create_news_table extends \yii\db\Migration | 
				
			||||
{ | 
				
			||||
	public function up() | 
				
			||||
	{ | 
				
			||||
		$transaction=$this->getDbConnection()->beginTransaction(); | 
				
			||||
		try | 
				
			||||
		{ | 
				
			||||
			$this->db->createCommand()->createTable('tbl_news, array( | 
				
			||||
				'id' => 'pk', | 
				
			||||
				'title' => 'string NOT NULL', | 
				
			||||
				'content' => 'text', | 
				
			||||
			))->execute(); | 
				
			||||
			$transaction->commit(); | 
				
			||||
		} | 
				
			||||
		catch(Exception $e) | 
				
			||||
		{ | 
				
			||||
			echo "Exception: ".$e->getMessage()."\n"; | 
				
			||||
			$transaction->rollback(); | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// ...similar code for down() | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
> Note: Not all DBMS support transactions. And some DB queries cannot be put | 
				
			||||
> into a transaction. In this case, you will have to implement `up()` and | 
				
			||||
> `down()`, instead. And for MySQL, some SQL statements may cause | 
				
			||||
> [implicit commit](http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html). | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Applying Migrations | 
				
			||||
------------------- | 
				
			||||
 | 
				
			||||
To apply all available new migrations (i.e., make the local database up-to-date), | 
				
			||||
run the following command: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
The command will show the list of all new migrations. If you confirm to apply | 
				
			||||
the migrations, it will run the `up()` method in every new migration class, one | 
				
			||||
after another, in the order of the timestamp value in the class name. | 
				
			||||
 | 
				
			||||
After applying a migration, the migration tool will keep a record in a database | 
				
			||||
table named `tbl_migration`. This allows the tool to identify which migrations | 
				
			||||
have been applied and which are not. If the `tbl_migration` table does not exist, | 
				
			||||
the tool will automatically create it in the database specified by the `db` | 
				
			||||
application component. | 
				
			||||
 | 
				
			||||
Sometimes, we may only want to apply one or a few new migrations. We can use the | 
				
			||||
following command: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/up 3 | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
This command will apply the 3 new migrations. Changing the value 3 will allow | 
				
			||||
us to change the number of migrations to be applied. | 
				
			||||
 | 
				
			||||
We can also migrate the database to a specific version with the following command: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/to 101129_185401 | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
That is, we use the timestamp part of a migration name to specify the version | 
				
			||||
that we want to migrate the database to. If there are multiple migrations between | 
				
			||||
the last applied migration and the specified migration, all these migrations | 
				
			||||
will be applied. If the specified migration has been applied before, then all | 
				
			||||
migrations applied after it will be reverted (to be described in the next section). | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Reverting Migrations | 
				
			||||
-------------------- | 
				
			||||
 | 
				
			||||
To revert the last one or several applied migrations, we can use the following | 
				
			||||
command: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/down [step] | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
where the optional `step` parameter specifies how many migrations to be reverted | 
				
			||||
back. It defaults to 1, meaning reverting back the last applied migration. | 
				
			||||
 | 
				
			||||
As we described before, not all migrations can be reverted. Trying to revert | 
				
			||||
such migrations will throw an exception and stop the whole reverting process. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Redoing Migrations | 
				
			||||
------------------ | 
				
			||||
 | 
				
			||||
Redoing migrations means first reverting and then applying the specified migrations. | 
				
			||||
This can be done with the following command: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/redo [step] | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
where the optional `step` parameter specifies how many migrations to be redone. | 
				
			||||
It defaults to 1, meaning redoing the last migration. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Showing Migration Information | 
				
			||||
----------------------------- | 
				
			||||
 | 
				
			||||
Besides applying and reverting migrations, the migration tool can also display | 
				
			||||
the migration history and the new migrations to be applied. | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/history [limit] | 
				
			||||
yiic migrate/new [limit] | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
where the optional parameter `limit` specifies the number of migrations to be | 
				
			||||
displayed. If `limit` is not specified, all available migrations will be displayed. | 
				
			||||
 | 
				
			||||
The first command shows the migrations that have been applied, while the second | 
				
			||||
command shows the migrations that have not been applied. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Modifying Migration History | 
				
			||||
--------------------------- | 
				
			||||
 | 
				
			||||
Sometimes, we may want to modify the migration history to a specific migration | 
				
			||||
version without actually applying or reverting the relevant migrations. This | 
				
			||||
often happens when developing a new migration. We can use the following command | 
				
			||||
to achieve this goal. | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/mark 101129_185401 | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
This command is very similar to `yiic migrate/to` command, except that it only | 
				
			||||
modifies the migration history table to the specified version without applying | 
				
			||||
or reverting the migrations. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Customizing Migration Command | 
				
			||||
----------------------------- | 
				
			||||
 | 
				
			||||
There are several ways to customize the migration command. | 
				
			||||
 | 
				
			||||
### Use Command Line Options | 
				
			||||
 | 
				
			||||
The migration command comes with four options that can be specified in command | 
				
			||||
line: | 
				
			||||
 | 
				
			||||
* `interactive`: boolean, specifies whether to perform migrations in an | 
				
			||||
  interactive mode. Defaults to true, meaning the user will be prompted when | 
				
			||||
  performing a specific migration. You may set this to false should the | 
				
			||||
  migrations be done in a background process. | 
				
			||||
 | 
				
			||||
* `migrationPath`: string, specifies the directory storing all migration class | 
				
			||||
  files. This must be specified in terms of a path alias, and the corresponding | 
				
			||||
  directory must exist. If not specified, it will use the `migrations` | 
				
			||||
  sub-directory under the application base path. | 
				
			||||
 | 
				
			||||
* `migrationTable`: string, specifies the name of the database table for storing | 
				
			||||
  migration history information. It defaults to `tbl_migration`. The table | 
				
			||||
  structure is `version varchar(255) primary key, apply_time integer`. | 
				
			||||
 | 
				
			||||
* `connectionID`: string, specifies the ID of the database application component. | 
				
			||||
  Defaults to 'db'. | 
				
			||||
 | 
				
			||||
* `templateFile`: string, specifies the path of the file to be served as the code | 
				
			||||
  template for generating the migration classes. This must be specified in terms | 
				
			||||
  of a path alias (e.g. `application.migrations.template`). If not set, an | 
				
			||||
  internal template will be used. Inside the template, the token `{ClassName}` | 
				
			||||
  will be replaced with the actual migration class name. | 
				
			||||
 | 
				
			||||
To specify these options, execute the migrate command using the following format | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/up --option1=value1 --option2=value2 ... | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
For example, if we want to migrate for a `forum` module whose migration files | 
				
			||||
are located within the module's `migrations` directory, we can use the following | 
				
			||||
command: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
yiic migrate/up --migrationPath=ext.forum.migrations | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Configure Command Globally | 
				
			||||
 | 
				
			||||
While command line options allow us to configure the migration command | 
				
			||||
on-the-fly, sometimes we may want to configure the command once for all. | 
				
			||||
For example, we may want to use a different table to store the migration history, | 
				
			||||
or we may want to use a customized migration template. We can do so by modifying | 
				
			||||
the console application's configuration file like the following, | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
TBD | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Now if we run the `migrate` command, the above configurations will take effect | 
				
			||||
without requiring us to enter the command line options every time. | 
				
			||||
@ -0,0 +1,52 @@
					 | 
				
			||||
MVC Overview | 
				
			||||
============ | 
				
			||||
 | 
				
			||||
Yii implements the model-view-controller (MVC) design pattern, which is | 
				
			||||
widely adopted in Web programming. MVC aims to separate business logic from | 
				
			||||
user interface considerations, so that developers can more easily change | 
				
			||||
each part without affecting the other. In MVC, the model represents the | 
				
			||||
information (the data) and the business rules; the view contains elements | 
				
			||||
of the user interface such as text, form inputs; and the controller manages | 
				
			||||
the communication between the model and the view. | 
				
			||||
 | 
				
			||||
Besides implementing MVC, Yii also introduces a front-controller, called | 
				
			||||
`Application`, which encapsulates the execution context for the processing | 
				
			||||
of a request. Application collects information about a user request and | 
				
			||||
then dispatches it to an appropriate controller for further handling. | 
				
			||||
 | 
				
			||||
The following diagram shows the static structure of a Yii application: | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
A Typical Workflow | 
				
			||||
------------------ | 
				
			||||
 | 
				
			||||
The following diagram shows a typical workflow of a Yii application when | 
				
			||||
it is handling a user request: | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
   1. A user makes a request with the URL `http://www.example.com/index.php?r=post/show&id=1` | 
				
			||||
and the Web server handles the request by executing the bootstrap script `index.php`. | 
				
			||||
   2. The bootstrap script creates an [Application](/doc/guide/basics.application) | 
				
			||||
instance and runs it. | 
				
			||||
   3. The Application obtains detailed user request information from | 
				
			||||
an [application component](/doc/guide/basics.application#application-component) | 
				
			||||
named `request`. | 
				
			||||
   4. The application determines the requested [controller](/doc/guide/basics.controller) | 
				
			||||
and [action](/doc/guide/basics.controller#action) with the help | 
				
			||||
of an application component named `urlManager`. For this example, the controller | 
				
			||||
is `post`, which refers to the `PostController` class; and the action is `show`, | 
				
			||||
whose actual meaning is determined by the controller. | 
				
			||||
   5. The application creates an instance of the requested controller | 
				
			||||
to further handle the user request. The controller determines that the action | 
				
			||||
`show` refers to a method named `actionShow` in the controller class. It then | 
				
			||||
creates and executes filters (e.g. access control, benchmarking) associated | 
				
			||||
with this action. The action is executed if it is allowed by the filters. | 
				
			||||
   6. The action reads a `Post` [model](/doc/guide/basics.model) whose ID is `1` from the database. | 
				
			||||
   7. The action renders a [view](/doc/guide/basics.view) named `show` with the `Post` model. | 
				
			||||
   8. The view reads and displays the attributes of the `Post` model. | 
				
			||||
   9. The view executes some [widgets](/doc/guide/basics.view#widget). | 
				
			||||
   10. The view rendering result is embedded in a [layout](/doc/guide/basics.view#layout). | 
				
			||||
   11. The action completes the view rendering and displays the result to the user. | 
				
			||||
@ -0,0 +1,36 @@
					 | 
				
			||||
What is Yii | 
				
			||||
=========== | 
				
			||||
 | 
				
			||||
Yii is a high-performance, component-based PHP framework for developing | 
				
			||||
large-scale Web applications rapidly. It enables maximum reusability in Web | 
				
			||||
programming and can significantly accelerate your Web application development | 
				
			||||
process. The name Yii (pronounced `Yee` or `[ji:]`) is an acronym for | 
				
			||||
"**Yes It Is!**". | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Requirements | 
				
			||||
------------ | 
				
			||||
 | 
				
			||||
To run a Yii-powered Web application, you need a Web server that supports | 
				
			||||
PHP 5.3.?. | 
				
			||||
 | 
				
			||||
For developers who want to use Yii, understanding object-oriented | 
				
			||||
programming (OOP) is very helpful, because Yii is a pure OOP framework. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
What is Yii Best for? | 
				
			||||
--------------------- | 
				
			||||
 | 
				
			||||
Yii is a generic Web programming framework that can be used for developing | 
				
			||||
virtually any type of Web application.  Because it is light-weight and | 
				
			||||
equipped with sophisticated caching mechanisms, it is especially suited | 
				
			||||
to high-traffic applications, such as portals, forums, content | 
				
			||||
management systems (CMS), e-commerce systems, etc. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
How does Yii Compare with Other Frameworks? | 
				
			||||
------------------------------------------- | 
				
			||||
 | 
				
			||||
Like most PHP frameworks, Yii is an MVC (Model-View-Controller) framework. | 
				
			||||
 | 
				
			||||
TBD | 
				
			||||
@ -0,0 +1,181 @@
					 | 
				
			||||
Performance Tuning | 
				
			||||
================== | 
				
			||||
 | 
				
			||||
Application performance consists of two parts. First is the framework performance | 
				
			||||
and the second is the application itself. Yii has a pretty low performance impact | 
				
			||||
on your application out of the box and can be fine-tuned further for production | 
				
			||||
environment. As for the application, we'll provide some of the best practices | 
				
			||||
along with examples on how to apply them to Yii. | 
				
			||||
 | 
				
			||||
Preparing framework for production | 
				
			||||
---------------------------------- | 
				
			||||
 | 
				
			||||
### Disabling Debug Mode | 
				
			||||
 | 
				
			||||
First thing you should do before deploying your application to production environment | 
				
			||||
is to disable debug mode. A Yii application runs in debug mode if the constant | 
				
			||||
`YII_DEBUG` is defined as `true` in `index.php` so to disable debug the following | 
				
			||||
should be in your `index.php`: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
defined('YII_DEBUG') or define('YII_DEBUG', false); | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Debug mode is very useful during development stage, but it would impact performance | 
				
			||||
because some components cause extra burden in debug mode. For example, the message | 
				
			||||
logger may record additional debug information for every message being logged. | 
				
			||||
 | 
				
			||||
### Enabling PHP opcode cache | 
				
			||||
 | 
				
			||||
Enabling the PHP opcode cache improves any PHP application performance and lowers | 
				
			||||
memory usage significantly. Yii is no exception. It was tested with | 
				
			||||
[APC PHP extension](http://php.net/manual/en/book.apc.php) that caches | 
				
			||||
and optimizes PHP intermediate code and avoids the time spent in parsing PHP | 
				
			||||
scripts for every incoming request. | 
				
			||||
 | 
				
			||||
### Turning on ActiveRecord database schema caching | 
				
			||||
 | 
				
			||||
If the application is using Active Record, we should turn on the schema caching | 
				
			||||
to save the time of parsing database schema. This can be done by setting the | 
				
			||||
`Connection::enableSchemaCache` property to be `true` via application configuration | 
				
			||||
`protected/config/main.php`: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
return array( | 
				
			||||
	// ... | 
				
			||||
	'components' => array( | 
				
			||||
		// ... | 
				
			||||
		'db' => array( | 
				
			||||
			'class' => 'yii\db\Connection', | 
				
			||||
			'dsn' => 'mysql:host=localhost;dbname=mydatabase', | 
				
			||||
			'username' => 'root', | 
				
			||||
			'password' => '', | 
				
			||||
			'enableSchemaCache' => true, | 
				
			||||
 | 
				
			||||
			// Duration of schema cache. | 
				
			||||
			// 'schemaCacheDuration' => 3600, | 
				
			||||
 | 
				
			||||
			// Name of the cache component used. Default is 'cache'. | 
				
			||||
			//'schemaCache' => 'cache', | 
				
			||||
		), | 
				
			||||
		'cache' => array( | 
				
			||||
			'class' => 'yii\caching\FileCache', | 
				
			||||
		), | 
				
			||||
	), | 
				
			||||
); | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Note that `cache` application component should be configured. | 
				
			||||
 | 
				
			||||
### Combining and Minimizing Assets | 
				
			||||
 | 
				
			||||
TBD | 
				
			||||
 | 
				
			||||
### Using better storage for sessions | 
				
			||||
 | 
				
			||||
By default PHP uses files to handle sessions. It is OK for development and | 
				
			||||
small projects but when it comes to handling concurrent requests it's better to | 
				
			||||
switch to another storage such as database. You can do so by configuring your | 
				
			||||
application via `protected/config/main.php`: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
return array( | 
				
			||||
	// ... | 
				
			||||
	'components' => array( | 
				
			||||
		'session' => array( | 
				
			||||
			'class' => 'yii\web\DbSession', | 
				
			||||
 | 
				
			||||
			// Set the following if want to use DB component other than | 
				
			||||
			// default 'db'. | 
				
			||||
			// 'db' => 'mydb', | 
				
			||||
 | 
				
			||||
			// To override default session table set the following | 
				
			||||
			// 'sessionTable' => 'my_session', | 
				
			||||
		), | 
				
			||||
	), | 
				
			||||
); | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
You can use `CacheSession` to store sessions using cache. Note that some | 
				
			||||
cache storages such as memcached has no guaranteee that session data will not | 
				
			||||
be lost leading to unexpected logouts. | 
				
			||||
 | 
				
			||||
Improving application | 
				
			||||
--------------------- | 
				
			||||
 | 
				
			||||
### Using Serverside Caching Techniques | 
				
			||||
 | 
				
			||||
As described in the Caching section, Yii provides several caching solutions that | 
				
			||||
may improve the performance of a Web application significantly. If the generation | 
				
			||||
of some data takes long time, we can use the data caching approach to reduce the | 
				
			||||
data generation frequency; If a portion of page remains relatively static, we | 
				
			||||
can use the fragment caching approach to reduce its rendering frequency; | 
				
			||||
If a whole page remains relative static, we can use the page caching approach to | 
				
			||||
save the rendering cost for the whole page. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Leveraging HTTP to save procesing time and bandwidth | 
				
			||||
 | 
				
			||||
TBD | 
				
			||||
 | 
				
			||||
### Database Optimization | 
				
			||||
 | 
				
			||||
Fetching data from database is often the main performance bottleneck in | 
				
			||||
a Web application. Although using caching may alleviate the performance hit, | 
				
			||||
it does not fully solve the problem. When the database contains enormous data | 
				
			||||
and the cached data is invalid, fetching the latest data could be prohibitively | 
				
			||||
expensive without proper database and query design. | 
				
			||||
 | 
				
			||||
Design index wisely in a database. Indexing can make SELECT queries much faster, | 
				
			||||
but it may slow down INSERT, UPDATE or DELETE queries. | 
				
			||||
 | 
				
			||||
For complex queries, it is recommended to create a database view for it instead | 
				
			||||
of issuing the queries inside the PHP code and asking DBMS to parse them repetitively. | 
				
			||||
 | 
				
			||||
Do not overuse Active Record. Although Active Record is good at modelling data | 
				
			||||
in an OOP fashion, it actually degrades performance due to the fact that it needs | 
				
			||||
to create one or several objects to represent each row of query result. For data | 
				
			||||
intensive applications, using DAO or database APIs at lower level could be | 
				
			||||
a better choice. | 
				
			||||
 | 
				
			||||
Last but not least, use LIMIT in your SELECT queries. This avoids fetching | 
				
			||||
overwhelming data from database and exhausting the memory allocated to PHP. | 
				
			||||
 | 
				
			||||
### Using asArray | 
				
			||||
 | 
				
			||||
A good way to save memory and processing time on read-only pages is to use | 
				
			||||
ActiveRecord's `asArray` method. | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
class PostController extends Controller | 
				
			||||
{ | 
				
			||||
	public function actionIndex() | 
				
			||||
	{ | 
				
			||||
		$posts = Post::find()->orderBy('id DESC')->limit(100)->asArray()->all(); | 
				
			||||
		echo $this->render('index', array( | 
				
			||||
			'posts' => $posts, | 
				
			||||
		)); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
In the view you should access fields of each invidual record from `$posts` as array: | 
				
			||||
 | 
				
			||||
```php | 
				
			||||
foreach($posts as $post) { | 
				
			||||
	echo $post['title']."<br>"; | 
				
			||||
} | 
				
			||||
``` | 
				
			||||
 | 
				
			||||
Note that you can use array notation even if `asArray` wasn't specified and you're | 
				
			||||
working with AR objects. | 
				
			||||
 | 
				
			||||
### Processing data in background | 
				
			||||
 | 
				
			||||
In order to respond to user requests faster you can process heavy parts of the | 
				
			||||
request later if there's no need for immediate response. | 
				
			||||
 | 
				
			||||
- Cron jobs + console. | 
				
			||||
- queues + handlers. | 
				
			||||
 | 
				
			||||
TBD | 
				
			||||
@ -0,0 +1,8 @@
					 | 
				
			||||
The Definitive Guide to Yii 2.0 | 
				
			||||
=============================== | 
				
			||||
 | 
				
			||||
This tutorial is released under [the Terms of Yii Documentation](http://www.yiiframework.com/doc/terms/). | 
				
			||||
 | 
				
			||||
All Rights Reserved. | 
				
			||||
 | 
				
			||||
2008 (c) Yii Software LLC. | 
				
			||||
@ -0,0 +1,437 @@
					 | 
				
			||||
Upgrading from Yii 1.1 | 
				
			||||
====================== | 
				
			||||
 | 
				
			||||
In this chapter, we list the major changes introduced in Yii 2.0 since version 1.1. | 
				
			||||
We hope this list will make it easier for you to upgrade from Yii 1.1 and quickly | 
				
			||||
master Yii 2.0 based on your existing Yii knowledge. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Component and Object | 
				
			||||
-------------------- | 
				
			||||
 | 
				
			||||
Yii 2.0 breaks the `CComponent` class in 1.1 into two classes: `Object` and `Component`. | 
				
			||||
The `Object` class is a lightweight base class that allows defining class properties | 
				
			||||
via getters and setters. The `Component` class extends from `Object` and supports | 
				
			||||
the event feature and the behavior feature. | 
				
			||||
 | 
				
			||||
If your class does not need the event or behavior feature, you should consider using | 
				
			||||
`Object` as the based class. This is usually the case for classes that represent basic | 
				
			||||
data structures. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Object Configuration | 
				
			||||
-------------------- | 
				
			||||
 | 
				
			||||
The `Object` class introduces a uniform way of configuring objects. Any descendant class | 
				
			||||
of `Object` should declare its constructor (if needed) in the following way so that | 
				
			||||
it can be properly configured: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
class MyClass extends \yii\Object | 
				
			||||
{ | 
				
			||||
    public function __construct($param1, $param2, $config = array()) | 
				
			||||
    { | 
				
			||||
        // ... initialization before configuration is applied | 
				
			||||
 | 
				
			||||
        parent::__construct($config); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function init() | 
				
			||||
    { | 
				
			||||
        parent::init(); | 
				
			||||
 | 
				
			||||
        // ... initialization after configuration is applied | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
In the above, the last parameter of the constructor must take a configuration array | 
				
			||||
which contains name-value pairs for initializing the properties at the end of the constructor. | 
				
			||||
You can override the `init()` method to do initialization work that should be done after | 
				
			||||
the configuration is applied. | 
				
			||||
 | 
				
			||||
By following this convention, you will be able to create and configure a new object | 
				
			||||
using a configuration array like the following: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$object = Yii::createObject(array( | 
				
			||||
    'class' => 'MyClass', | 
				
			||||
    'property1' => 'abc', | 
				
			||||
    'property2' => 'cde', | 
				
			||||
), $param1, $param2); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Events | 
				
			||||
------ | 
				
			||||
 | 
				
			||||
There is no longer the need to define an `on`-method in order to define an event in Yii 2.0. | 
				
			||||
Instead, you can use whatever event names. To attach a handler to an event, you should | 
				
			||||
use the `on` method now: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$component->on($eventName, $handler); | 
				
			||||
// To detach the handler, use: | 
				
			||||
// $component->off($eventName, $handler); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
When you attach a handler, you can now associate it with some parameters which can be later | 
				
			||||
accessed via the event parameter by the handler: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$component->on($eventName, $handler, $params); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
Because of this change, you can now use "global" events. Simply trigger and attach handlers to | 
				
			||||
an event of the application instance: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
Yii::$app->on($eventName, $handler); | 
				
			||||
.... | 
				
			||||
// this will trigger the event and cause $handler to be invoked. | 
				
			||||
Yii::$app->trigger($eventName); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Path Alias | 
				
			||||
---------- | 
				
			||||
 | 
				
			||||
Yii 2.0 expands the usage of path aliases to both file/directory paths and URLs. An alias | 
				
			||||
must start with a `@` character so that it can be differentiated from file/directory paths and URLs. | 
				
			||||
For example, the alias `@yii` refers to the Yii installation directory. Path aliases are | 
				
			||||
supported in most places in the Yii core code. For example, `FileCache::cachePath` can take | 
				
			||||
both a path alias and a normal directory path. | 
				
			||||
 | 
				
			||||
Path alias is also closely related with class namespaces. It is recommended that a path | 
				
			||||
alias defined for each root namespace so that you can use Yii class autoloader without | 
				
			||||
any further configuration. For example, because `@yii` refers to the Yii installation directory, | 
				
			||||
a class like `yii\web\Request` can be autoloaded by Yii. If you use a third party library | 
				
			||||
such as Zend Framework, you may define a path alias `@Zend` which refers to its installation directory. | 
				
			||||
And Yii will be able to autoload any class in this library. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
View | 
				
			||||
---- | 
				
			||||
 | 
				
			||||
Yii 2.0 introduces a `View` class to represent the view part in the MVC pattern. | 
				
			||||
It can be configured globally through the "view" application component. It is also | 
				
			||||
accessible in any view file via `$this`. This is one of the biggest changes compared to 1.1: | 
				
			||||
**`$this` in a view file no longer refers to the controller or widget object.** | 
				
			||||
It refers to the view object that is used to render the view file. To access the controller | 
				
			||||
or the widget object, you have to use `$this->context` now. | 
				
			||||
 | 
				
			||||
Because you can access the view object through the "view" application component, | 
				
			||||
you can now render a view file like the following anywhere in your code, not necessarily | 
				
			||||
in controllers or widgets: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$content = Yii::$app->view->renderFile($viewFile, $params); | 
				
			||||
// You can also explicitly create a new View instance to do the rendering | 
				
			||||
// $view = new View; | 
				
			||||
// $view->renderFile($viewFile, $params); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
Also, there is no more `CClientScript` in Yii 2.0. The `View` class has taken over its role | 
				
			||||
with significant improvements. For more details, please see the "assets" subsection. | 
				
			||||
 | 
				
			||||
While Yii 2.0 continues to use PHP as its main template language, it comes with built-in | 
				
			||||
support for two popular template engines: Smarty and Twig. The Prado template engine is | 
				
			||||
no longer supported. To use these template engines, you just need to use `tpl` as the file | 
				
			||||
extension for your Smarty views, or `twig` for Twig views. You may also configure the  | 
				
			||||
`View::renderers` property to use other template engines. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Models | 
				
			||||
------ | 
				
			||||
 | 
				
			||||
A model is now associated with a form name returned its `formName()` method. This is | 
				
			||||
mainly used when using HTML forms to collect user inputs for a model. Previously in 1.1, | 
				
			||||
this is usually hardcoded as the class name of the model. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Yii 2.0 introduces a new method called `scenarios()` to declare which attributes require | 
				
			||||
validation under which scenario. Child classes should overwrite `scenarios()` to return | 
				
			||||
a list of scenarios and the corresponding attributes that need to be validated when | 
				
			||||
`validate()` is called. For example, | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
public function scenarios() | 
				
			||||
{ | 
				
			||||
    return array( | 
				
			||||
        'backend' => array('email', 'role'), | 
				
			||||
        'frontend' => array('email', '!name'), | 
				
			||||
    ); | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
This method also determines which attributes are safe and which are not. In particular, | 
				
			||||
given a scenario, if an attribute appears in the corresponding attribute list in `scenarios()` | 
				
			||||
and the name is not prefixed with `!`, it is considered *safe*. | 
				
			||||
 | 
				
			||||
Because of the above change, Yii 2.0 no longer has "safe" and "unsafe" validators. | 
				
			||||
 | 
				
			||||
If your model only has one scenario (very common), you do not have to overwrite `scenarios()`, | 
				
			||||
and everything will still work like the 1.1 way. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Controllers | 
				
			||||
----------- | 
				
			||||
 | 
				
			||||
The `render()` and `renderPartial()` methods now return the rendering results instead of directly | 
				
			||||
sending them out. You have to `echo` them explicitly, e.g., `echo $this->render(...);`. | 
				
			||||
 | 
				
			||||
A new method called `populate()` is introduced to simplify the data population from user inputs | 
				
			||||
to a model. For example, | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$post = new Post; | 
				
			||||
if ($this->populate($_POST, $model)) {...} | 
				
			||||
// which is equivalent to: | 
				
			||||
if (isset($_POST['Post'])) { | 
				
			||||
    $post->attributes = $_POST['Post']; | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Themes | 
				
			||||
------ | 
				
			||||
 | 
				
			||||
Theme works completely different in 2.0. It is now based on a path map to "translate" a source | 
				
			||||
view into a themed view. For example, if the path map for a theme is | 
				
			||||
`array('/www/views' => '/www/themes/basic')`, then the themed version for a view file | 
				
			||||
`/www/views/site/index.php` will be `/www/themes/basic/site/index.php`. | 
				
			||||
 | 
				
			||||
For this reason, theme can now be applied to any view file, even if a view rendered outside | 
				
			||||
of the context of a controller or a widget. | 
				
			||||
 | 
				
			||||
There is no more `CThemeManager`. Instead, `theme` is a configurable property of the "view" | 
				
			||||
application component. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Console Applications | 
				
			||||
-------------------- | 
				
			||||
 | 
				
			||||
Console applications are now composed by controllers, too, like Web applications. In fact, | 
				
			||||
console controllers and Web controllers share the same base controller class. | 
				
			||||
 | 
				
			||||
Each console controller is like `CConsoleCommand` in 1.1. It consists of one or several | 
				
			||||
actions. You use the `yiic <route>` command to execute a console command, where `<route>` | 
				
			||||
stands for a controller route (e.g. `sitemap/index`). Additional anonymous arguments | 
				
			||||
are passed as the parameters to the corresponding controller action method, and named arguments | 
				
			||||
are treated as global options declared in `globalOptions()`. | 
				
			||||
 | 
				
			||||
Yii 2.0 supports automatic generation of command help information from comment blocks. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
I18N | 
				
			||||
---- | 
				
			||||
 | 
				
			||||
Yii 2.0 removes date formatter and number formatter in favor of the PECL intl PHP module. | 
				
			||||
 | 
				
			||||
Message translation is still supported, but managed via the "i18n" application component. | 
				
			||||
The component manages a set of message sources, which allows you to use different message | 
				
			||||
sources based on message categories. For more information, see the class documentation for `I18N`. | 
				
			||||
 | 
				
			||||
The message translation method is changed by merging the message category into the message being | 
				
			||||
translated. For example, `Yii::t('yii|message to be translated')`. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Action Filters | 
				
			||||
-------------- | 
				
			||||
 | 
				
			||||
Action filters are implemented via behaviors now. You should extend from `ActionFilter` to | 
				
			||||
define a new filter. To use a filter, you should attach the filter class to the controller | 
				
			||||
as a behavior. For example, to use the `AccessControl` filter, you should have the following | 
				
			||||
code in a controller: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
public function behaviors() | 
				
			||||
{ | 
				
			||||
    return array( | 
				
			||||
        'access' => array( | 
				
			||||
            'class' => 'yii\web\AccessControl', | 
				
			||||
            'rules' => array( | 
				
			||||
                array('allow' => true, 'actions' => array('admin'), 'roles' => array('@')), | 
				
			||||
                array('allow' => false), | 
				
			||||
            ), | 
				
			||||
        ), | 
				
			||||
    ); | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Assets | 
				
			||||
------ | 
				
			||||
 | 
				
			||||
Yii 2.0 introduces a new concept called *asset bundle*. It is a bit similar to script | 
				
			||||
packages (managed by `CClientScript`) in 1.1, but with better support. | 
				
			||||
 | 
				
			||||
An asset bundle is a collection of asset files (e.g. JavaScript files, CSS files, image files, etc.) | 
				
			||||
under a directory. By registering an asset bundle via `View::registerAssetBundle()`, you | 
				
			||||
will be able to make the assets in that bundle accessible via Web, and the current page | 
				
			||||
will automatically contain references to the JavaScript and CSS files in that bundle. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Static Helpers | 
				
			||||
-------------- | 
				
			||||
 | 
				
			||||
Yii 2.0 introduces many commonly used static helper classes, such as `Html`, `ArrayHelper`, | 
				
			||||
`StringHelper`. These classes are designed to be easily extended. Note that static classes | 
				
			||||
are usually hard to be extended because of the fixed class name references. But Yii 2.0 | 
				
			||||
introduces the class map (via `Yii::$classMap`) to overcome this difficulty. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
`ActiveForm` | 
				
			||||
------------ | 
				
			||||
 | 
				
			||||
Yii 2.0 introduces the *field* concept for building a form using `ActiveForm`. A field | 
				
			||||
is a container consisting of a label, an input, and an error message. It is represented | 
				
			||||
as an `ActiveField` object. Using fields, you can build a form more cleanly than before: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
<?php $form = $this->beginWidget('yii\widgets\ActiveForm'); ?> | 
				
			||||
	<?php echo $form->field($model, 'username')->textInput(); ?> | 
				
			||||
	<?php echo $form->field($model, 'password')->passwordInput(); ?> | 
				
			||||
	<div class="form-actions"> | 
				
			||||
		<?php echo Html::submitButton('Login'); ?> | 
				
			||||
	</div> | 
				
			||||
<?php $this->endWidget(); ?> | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Query Builder | 
				
			||||
------------- | 
				
			||||
 | 
				
			||||
In 1.1, query building is scattered among several classes, including `CDbCommand`, | 
				
			||||
`CDbCriteria`, and `CDbCommandBuilder`. Yii 2.0 uses `Query` to represent a DB query | 
				
			||||
and `QueryBuilder` to generate SQL statements from query objects. For example, | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$query = new \yii\db\Query; | 
				
			||||
$query->select('id, name') | 
				
			||||
      ->from('tbl_user') | 
				
			||||
      ->limit(10); | 
				
			||||
 | 
				
			||||
$command = $query->createCommand(); | 
				
			||||
$sql = $command->sql; | 
				
			||||
$rows = $command->queryAll(); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
Best of all, such query building methods can be used together with `ActiveRecord`, | 
				
			||||
as explained in the next sub-section. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
ActiveRecord | 
				
			||||
------------ | 
				
			||||
 | 
				
			||||
ActiveRecord has undergone significant changes in Yii 2.0. The most important one | 
				
			||||
is about relational ActiveRecord query. In 1.1, you have to declare the relations | 
				
			||||
in the `relations()` method. In 2.0, this is done via getter methods that return | 
				
			||||
an `ActiveQuery` object. For example, the following method declares an "orders" relation: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
class Customer extends \yii\db\ActiveRecord | 
				
			||||
{ | 
				
			||||
	public function getOrders() | 
				
			||||
	{ | 
				
			||||
		return $this->hasMany('Order', array('customer_id' => 'id')); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
You can use `$customer->orders` to access the customer's orders. You can also | 
				
			||||
use `$customer->getOrders()->andWhere('status=1')->all()` to perform on-the-fly | 
				
			||||
relational query with customized query conditions. | 
				
			||||
 | 
				
			||||
When loading relational records in an eager way, Yii 2.0 does it differently from 1.1. | 
				
			||||
In particular, in 1.1 a JOIN query would be used to bring both the primary and the relational | 
				
			||||
records; while in 2.0, two SQL statements are executed without using JOIN: the first | 
				
			||||
statement brings back the primary records and the second brings back the relational records | 
				
			||||
by filtering with the primary keys of the primary records. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Yii 2.0 no longer uses the `model()` method when performing queries. Instead, you | 
				
			||||
use the `find()` method like the following: | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
// to retrieve all *active* customers and order them by their ID: | 
				
			||||
$customers = Customer::find() | 
				
			||||
	->where(array('status' => $active)) | 
				
			||||
	->orderBy('id') | 
				
			||||
	->all(); | 
				
			||||
// return the customer whose PK is 1 | 
				
			||||
$customer = Customer::find(1); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
The `find()` method returns an instance of `ActiveQuery` which is a subclass of `Query`. | 
				
			||||
Therefore, you can use all query methods of `Query`. | 
				
			||||
 | 
				
			||||
Instead of returning ActiveRecord objects, you may call `ActiveQuery::asArray()` to | 
				
			||||
return results in terms of arrays. This is more efficient and is especially useful | 
				
			||||
when you need to return large number of records. For example, | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$customers = Customer::find()->asArray()->all(); | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
By default, ActiveRecord now only saves dirty attributes. In 1.1, all attributes | 
				
			||||
would be saved to database when you call `save()`, regardless they are changed or not, | 
				
			||||
unless you explicitly list the attributes to save. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Auto-quoting Table and Column Names | 
				
			||||
------------------------------------ | 
				
			||||
 | 
				
			||||
Yii 2.0 supports automatic quoting of database table and column names. A name enclosed | 
				
			||||
within double curly brackets is treated as a table name, and a name enclosed within | 
				
			||||
double square brackets is treated as a column name. They will be quoted according to | 
				
			||||
the database driver being used. For example, | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
$command = $connection->createCommand('SELECT [[id]] FROM {{posts}}'); | 
				
			||||
echo $command->sql;  // MySQL: SELECT `id` FROM `posts` | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
This feature is especially useful if you are developing an application that supports | 
				
			||||
different DBMS. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
User and Identity | 
				
			||||
----------------- | 
				
			||||
 | 
				
			||||
The `CWebUser` class in 1.1 is now replaced by `\yii\Web\User`, and there is no more | 
				
			||||
`CUserIdentity` class. Instead, you should implement the `Identity` interface which | 
				
			||||
is much more straightforward to implement. The bootstrap application provides such an example. | 
				
			||||
 | 
				
			||||
 | 
				
			||||
URL Management | 
				
			||||
-------------- | 
				
			||||
 | 
				
			||||
URL management is similar to 1.1. A major enhancement is that it now supports optional | 
				
			||||
parameters. For example, if you have rule declared as follows, then it will match | 
				
			||||
both `post/popular` and `post/1/popular`. In 1.1, you would have to use two rules to achieve | 
				
			||||
the same goal. | 
				
			||||
 | 
				
			||||
~~~ | 
				
			||||
array( | 
				
			||||
	'pattern' => 'post/<page:\d+>/<tag>', | 
				
			||||
	'route' => 'post/index', | 
				
			||||
	'defaults' => array('page' => 1), | 
				
			||||
) | 
				
			||||
~~~ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
Response | 
				
			||||
-------- | 
				
			||||
 | 
				
			||||
Extensions | 
				
			||||
---------- | 
				
			||||
 | 
				
			||||
Integration with Composer | 
				
			||||
------------------------- | 
				
			||||
 | 
				
			||||
TBD | 
				
			||||
 | 
				
			||||
@ -1,17 +0,0 @@
					 | 
				
			||||
<?php | 
				
			||||
/** @var $controller \yii\console\controllers\AppController */ | 
				
			||||
$controller = $this; | 
				
			||||
 | 
				
			||||
return array( | 
				
			||||
	'default' => array( | 
				
			||||
		'index.php' => array( | 
				
			||||
			'handler' => function($source) use ($controller) { | 
				
			||||
				return $controller->replaceRelativePath($source, realpath(YII_PATH.'/yii.php'), 'yii'); | 
				
			||||
			}, | 
				
			||||
			'permissions' => 0777, | 
				
			||||
		), | 
				
			||||
		'protected/runtime' => array( | 
				
			||||
			'permissions' => 0755, | 
				
			||||
		), | 
				
			||||
	), | 
				
			||||
); | 
				
			||||
@ -1,10 +0,0 @@
					 | 
				
			||||
<?php | 
				
			||||
define('YII_DEBUG', true); | 
				
			||||
 | 
				
			||||
require __DIR__.'/../framework/yii.php'; | 
				
			||||
 | 
				
			||||
$config = require dirname(__DIR__).'/protected/config/main.php'; | 
				
			||||
$config['basePath'] = dirname(__DIR__).'/protected'; | 
				
			||||
 | 
				
			||||
$app = new \yii\web\Application($config); | 
				
			||||
$app->run(); | 
				
			||||
@ -1,20 +0,0 @@
					 | 
				
			||||
<?php | 
				
			||||
return array( | 
				
			||||
	'id' => 'webapp', | 
				
			||||
	'name' => 'My Web Application', | 
				
			||||
 | 
				
			||||
	'components' => array( | 
				
			||||
		// uncomment the following to use a MySQL database | 
				
			||||
		/* | 
				
			||||
		'db' => array( | 
				
			||||
			'class' => 'yii\db\Connection', | 
				
			||||
			'dsn' => 'mysql:host=localhost;dbname=testdrive', | 
				
			||||
			'username' => 'root', | 
				
			||||
			'password' => '', | 
				
			||||
		), | 
				
			||||
		*/ | 
				
			||||
		'cache' => array( | 
				
			||||
			'class' => 'yii\caching\DummyCache', | 
				
			||||
		), | 
				
			||||
	), | 
				
			||||
); | 
				
			||||
@ -1,15 +0,0 @@
					 | 
				
			||||
<?php | 
				
			||||
use \yii\web\Controller; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * SiteController | 
				
			||||
 */ | 
				
			||||
class SiteController extends Controller | 
				
			||||
{ | 
				
			||||
	public function actionIndex() | 
				
			||||
	{ | 
				
			||||
		echo $this->render('index', array( | 
				
			||||
			'name' => 'Qiang', | 
				
			||||
		)); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -1,17 +0,0 @@
					 | 
				
			||||
<?php use yii\helpers\Html as Html; ?> | 
				
			||||
<!doctype html> | 
				
			||||
<html lang="<?php \Yii::$app->language?>">
 | 
				
			||||
	<head> | 
				
			||||
		<meta charset="utf-8" /> | 
				
			||||
		<title><?php echo Html::encode($this->title)?></title>
 | 
				
			||||
	</head> | 
				
			||||
	<body> | 
				
			||||
		<h1><?php echo Html::encode($this->title)?></h1>
 | 
				
			||||
		<div class="content"> | 
				
			||||
			<?php echo $content?> | 
				
			||||
		</div> | 
				
			||||
		<div class="footer"> | 
				
			||||
			<?php echo \Yii::powered()?> | 
				
			||||
		</div> | 
				
			||||
	</body> | 
				
			||||
</html> | 
				
			||||
@ -1 +0,0 @@
					 | 
				
			||||
Hello, <?php echo $name?>!
 | 
				
			||||
@ -0,0 +1,45 @@
					 | 
				
			||||
<?php | 
				
			||||
/** | 
				
			||||
 * @link http://www.yiiframework.com/ | 
				
			||||
 * @copyright Copyright (c) 2008 Yii Software LLC | 
				
			||||
 * @license http://www.yiiframework.com/license/ | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
namespace yii\helpers; | 
				
			||||
 | 
				
			||||
use yii\base\Object; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * JsExpression marks a string as a JavaScript expression. | 
				
			||||
 * When using [[Json::encode()]] to encode a value, JsonExpression objects | 
				
			||||
 * will be specially handled and encoded as a JavaScript expression instead of a string. | 
				
			||||
 * @author Qiang Xue <qiang.xue@gmail.com> | 
				
			||||
 * @since 2.0 | 
				
			||||
 */ | 
				
			||||
class JsExpression extends Object | 
				
			||||
{ | 
				
			||||
	/** | 
				
			||||
	 * @var string the JavaScript expression represented by this object | 
				
			||||
	 */ | 
				
			||||
	public $expression; | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Constructor. | 
				
			||||
	 * @param string $expression the JavaScript expression represented by this object | 
				
			||||
	 * @param array $config additional configurations for this object | 
				
			||||
	 */ | 
				
			||||
	public function __construct($expression, $config = array()) | 
				
			||||
	{ | 
				
			||||
		$this->expression = $expression; | 
				
			||||
		parent::__construct($config); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * The PHP magic function converting an object into a string. | 
				
			||||
	 * @return string the JavaScript expression. | 
				
			||||
	 */ | 
				
			||||
	public function __toString() | 
				
			||||
	{ | 
				
			||||
		return $this->expression; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,18 @@
					 | 
				
			||||
<?php | 
				
			||||
/** | 
				
			||||
 * @link http://www.yiiframework.com/ | 
				
			||||
 * @copyright Copyright (c) 2008 Yii Software LLC | 
				
			||||
 * @license http://www.yiiframework.com/license/ | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
namespace yii\helpers; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * | 
				
			||||
 * @author Qiang Xue <qiang.xue@gmail.com> | 
				
			||||
 * @since 2.0 | 
				
			||||
 */ | 
				
			||||
class Json extends base\Json | 
				
			||||
{ | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,107 @@
					 | 
				
			||||
<?php | 
				
			||||
/** | 
				
			||||
 * @link http://www.yiiframework.com/ | 
				
			||||
 * @copyright Copyright (c) 2008 Yii Software LLC | 
				
			||||
 * @license http://www.yiiframework.com/license/ | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
namespace yii\helpers\base; | 
				
			||||
 | 
				
			||||
use yii\base\InvalidParamException; | 
				
			||||
use yii\helpers\JsExpression; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Json is a helper class providing JSON data encoding and decoding. | 
				
			||||
 * It enhances the PHP built-in functions `json_encode()` and `json_decode()` | 
				
			||||
 * by supporting encoding JavaScript expressions and throwing exceptions when decoding fails. | 
				
			||||
 * @author Qiang Xue <qiang.xue@gmail.com> | 
				
			||||
 * @since 2.0 | 
				
			||||
 */ | 
				
			||||
class Json | 
				
			||||
{ | 
				
			||||
	/** | 
				
			||||
	 * Encodes the given value into a JSON string. | 
				
			||||
	 * The method enhances `json_encode()` by supporting JavaScript expressions. | 
				
			||||
	 * In particular, the method will not encode a JavaScript expression that is | 
				
			||||
	 * represented in terms of a [[JsExpression]] object. | 
				
			||||
	 * @param mixed $value the data to be encoded | 
				
			||||
	 * @param integer $options the encoding options. For more details please refer to | 
				
			||||
	 * [[http://www.php.net/manual/en/function.json-encode.php]] | 
				
			||||
	 * @return string the encoding result | 
				
			||||
	 */ | 
				
			||||
	public static function encode($value, $options = 0) | 
				
			||||
	{ | 
				
			||||
		$expressions = array(); | 
				
			||||
		$value = static::processData($value, $expressions); | 
				
			||||
		$json = json_encode($value, $options); | 
				
			||||
		return $expressions === array() ? $json : strtr($json, $expressions); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Decodes the given JSON string into a PHP data structure. | 
				
			||||
	 * @param string $json the JSON string to be decoded | 
				
			||||
	 * @param boolean $asArray whether to return objects in terms of associative arrays. | 
				
			||||
	 * @return mixed the PHP data | 
				
			||||
	 * @throws InvalidParamException if there is any decoding error | 
				
			||||
	 */ | 
				
			||||
	public static function decode($json, $asArray = true) | 
				
			||||
	{ | 
				
			||||
		if (is_array($json)) { | 
				
			||||
			throw new InvalidParamException('Invalid JSON data.'); | 
				
			||||
		} | 
				
			||||
		$decode = json_decode((string)$json, $asArray); | 
				
			||||
		switch (json_last_error()) { | 
				
			||||
			case JSON_ERROR_NONE: | 
				
			||||
				break; | 
				
			||||
			case JSON_ERROR_DEPTH: | 
				
			||||
				throw new InvalidParamException('The maximum stack depth has been exceeded.'); | 
				
			||||
			case JSON_ERROR_CTRL_CHAR: | 
				
			||||
				throw new InvalidParamException('Control character error, possibly incorrectly encoded.'); | 
				
			||||
			case JSON_ERROR_SYNTAX: | 
				
			||||
				throw new InvalidParamException('Syntax error.'); | 
				
			||||
			case JSON_ERROR_STATE_MISMATCH: | 
				
			||||
				throw new InvalidParamException('Invalid or malformed JSON.'); | 
				
			||||
			case JSON_ERROR_UTF8: | 
				
			||||
				throw new InvalidParamException('Malformed UTF-8 characters, possibly incorrectly encoded.'); | 
				
			||||
			default: | 
				
			||||
				throw new InvalidParamException('Unknown JSON decoding error.'); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return $decode; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Pre-processes the data before sending it to `json_encode()`. | 
				
			||||
	 * @param mixed $data the data to be processed | 
				
			||||
	 * @param array $expressions collection of JavaScript expressions | 
				
			||||
	 * @return mixed the processed data | 
				
			||||
	 */ | 
				
			||||
	protected static function processData($data, &$expressions) | 
				
			||||
	{ | 
				
			||||
		if (is_array($data)) { | 
				
			||||
			foreach ($data as $key => $value) { | 
				
			||||
				if (is_array($value) || is_object($value)) { | 
				
			||||
					$data[$key] = static::processData($value, $expressions); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
			return $data; | 
				
			||||
		} elseif (is_object($data)) { | 
				
			||||
			if ($data instanceof JsExpression) { | 
				
			||||
				$token = '!{[' . count($expressions) . ']}!'; | 
				
			||||
				$expressions['"' . $token . '"'] = $data->expression; | 
				
			||||
				return $token; | 
				
			||||
			} | 
				
			||||
			$result = array(); | 
				
			||||
			foreach ($data as $key => $value) { | 
				
			||||
				if (is_array($value) || is_object($value)) { | 
				
			||||
					$result[$key] = static::processData($value, $expressions); | 
				
			||||
				} else { | 
				
			||||
					$result[$key] = $value; | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
			return $result; | 
				
			||||
		} else { | 
				
			||||
			return $data; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue