diff --git a/CHANGELOG b/CHANGELOG
index 0cc617c4c..51408ea4d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,12 +10,17 @@ Version 1.0.3 to be released
----------------------------
- Bug #127: CUploadedFile is using an undefined variable (Qiang)
- Bug #132: CMysqlSchema has a typo (Qiang)
+- Bug #133: CSort should properly quote the columns to be sorted (Qiang)
+- Bug #135: CSort::link() does not work well with labels with special chars (Qiang)
+- Bug #145: When layout property of CController is false, main layout is still applied (Qiang)
- Bug: CHttpRequest.hostInfo may give wrong port number (Qiang)
- Bug: CHtml::activeListBox does not work when multiple selection is needed (Qiang)
- Bug: Inconsistency in timezone of log messages for different log routes (Qiang)
- Bug: Script file registered for POS_BEGIN is rendered twice (Qiang)
- New #117: Added count() support to relational AR (Qiang)
- New #136: Added support to CWebUser to allow directly accessing persistent properties (Qiang)
+- New #137: yiic model command should only set a column as required when it does not have default value (Qiang)
+- New #138: Added support to specify additional attributes for OPTION tags (Qiang)
- New: Upgraded jquery to 1.3.1 (Qiang)
- New: Upgraded jquery star rating to 2.61 (Qiang)
- New: Added skeleton application and refactored 'yiic webapp' command (Qiang)
diff --git a/README b/README
index 6400a90e3..939166304 100644
--- a/README
+++ b/README
@@ -1,19 +1,18 @@
-
- Yii Web Programming Framework
- =============================
+Yii Web Programming Framework
+=============================
Thank you for choosing Yii - a high-performance component-based PHP framework.
INSTALLATION
------------
+
Please make sure the release file is unpacked under a Web-accessible
directory. You shall see the following files and directories:
demos/ demos
framework/ framework source files
requirements/ requirement checker
- testdrive/ a skeleton Yii application
CHANGELOG describing changes in every Yii release
LICENSE license of Yii
README this file
@@ -22,6 +21,7 @@ directory. You shall see the following files and directories:
REQUIREMENTS
------------
+
The minimum requirement by Yii is that your Web server supports
PHP 5.1.0 or above. Yii has been tested with Apache HTTP server
on Windows and Linux operating systems.
@@ -34,8 +34,19 @@ the requirements by Yii, assuming "YiiPath" is where Yii is installed:
QUICK START
-----------
-Yii comes with a skeleton application located under the directory
-"testdrive". It is a good starting point for your application.
+
+Yii comes with a command line tool called "yiic" that can create
+a skeleton Yii application for you to start with.
+
+On command line, type in the following commands:
+
+ $ cd YiiPath/framework (Linux)
+ cd YiiPath\framework (Windows)
+
+ $ ./yiic webapp ../testdrive (Linux)
+ yiic webapp ..\testdrive (Windows)
+
+The new Yii application will be created at "YiiPath/testdrive".
You can access it with the following URL:
http://hostname/YiiPath/testdrive/index.php
@@ -43,6 +54,7 @@ You can access it with the following URL:
WHAT's NEXT
-----------
+
Please visit the project website for tutorials, class reference
and join discussions with other Yii users.
diff --git a/docs/blog/comment.create.txt b/docs/blog/comment.create.txt
index 4da86bc5e..865ede61d 100644
--- a/docs/blog/comment.create.txt
+++ b/docs/blog/comment.create.txt
@@ -59,7 +59,8 @@ protected function newComment($post)
$comment->validate('insert');
else if(isset($_POST['submitComment']) && $comment->save())
{
- Yii::app()->user->setFlash('commentSubmitted','Thank you...'); $this->refresh();
+ Yii::app()->user->setFlash('commentSubmitted','Thank you...');
+ $this->refresh();
}
}
return $comment;
diff --git a/docs/blog/final.url.txt b/docs/blog/final.url.txt
index bd9b08cd8..e81da44e3 100644
--- a/docs/blog/final.url.txt
+++ b/docs/blog/final.url.txt
@@ -7,7 +7,7 @@ The URLs linking various pages of our blog application currently look ugly. For
/index.php?r=post/show&id=1
~~~
-In this section, we describe how to beautifying these URLs and make them SEO-friendly. We goal is to be able to use the following URLs in the application:
+In this section, we describe how to beautifying these URLs and make them SEO-friendly. Our goal is to be able to use the following URLs in the application:
* `/index.php/tag/yii`: leads to the page showing a list of posts with tag `yii`;
* `/index.php/posts`: leads to the page showing the latest posts;
diff --git a/docs/blog/post.model.txt b/docs/blog/post.model.txt
index 2f16aad74..21f9472e9 100644
--- a/docs/blog/post.model.txt
+++ b/docs/blog/post.model.txt
@@ -31,7 +31,7 @@ public function rules()
}
~~~
-In the above, we specify that the `title`, `length` and `max` attributes are required; the length of `title` should not exceed 128; the `status` attribute value should be 0 (draft), 1 (published) or 2 (archived); and the `tags` attribute should only contain word characters and commas. All other attributes (e.g. `id`, `createTime`) will not be validated because their values do not come from user input.
+In the above, we specify that the `title`, `content` and `status` attributes are required; the length of `title` should not exceed 128; the `status` attribute value should be 0 (draft), 1 (published) or 2 (archived); and the `tags` attribute should only contain word characters and commas. All other attributes (e.g. `id`, `createTime`) will not be validated because their values do not come from user input.
After making these changes, we can visit the post creation page again to verify that the new validation rules are taking effect.
diff --git a/docs/blog/prototype.auth.txt b/docs/blog/prototype.auth.txt
index 30d45fc32..0829dde38 100644
--- a/docs/blog/prototype.auth.txt
+++ b/docs/blog/prototype.auth.txt
@@ -79,6 +79,6 @@ switch($identity->errorCode)
> Info: People often get confused about identity and the `user` application component. The former represents a way of performing authentication, while the latter is used to represent the information related with the current user. An application can only have one `user` component, but it can have one or several identity classes, depending on what kind of authentication it supports. Once authenticated, an identity instance may pass its state information to the `user` component so that they are globally accessible via `user`.
-To test the modified `UserIdentity` class, we can browse the URL `http://www.example.com/blog/index.php` and try logging in with the username and password that we store in the `User` table. If we use the database provided by the [blog demo](http://www.yiiframework.com/demos/blog/], we should be able to login with username `demo` and password `demo`. Note that this blog system does not provide the user management feature. As a result, a user cannot change his account or create a new one through the Web interface. The user management feature may be considered as a future enhancement to the blog application.
+To test the modified `UserIdentity` class, we can browse the URL `http://www.example.com/blog/index.php` and try logging in with the username and password that we store in the `User` table. If we use the database provided by the [blog demo](http://www.yiiframework.com/demos/blog/), we should be able to login with username `demo` and password `demo`. Note that this blog system does not provide the user management feature. As a result, a user cannot change his account or create a new one through the Web interface. The user management feature may be considered as a future enhancement to the blog application.
$Id$
\ No newline at end of file
diff --git a/docs/blog/toc.txt b/docs/blog/toc.txt
index 6b487d587..70c100bb1 100644
--- a/docs/blog/toc.txt
+++ b/docs/blog/toc.txt
@@ -21,7 +21,7 @@
- [Creating and Displaying Comments](comment.create)
- [Managing Comments](comment.admin)
-* Porlets
+* Portlets
- [Establishing Portlet Architecture](portlet.base)
- [Creating User Menu Portlet](portlet.menu)
- [Creating Login Portlet](portlet.login)
diff --git a/docs/guide/quickstart.first-app.txt b/docs/guide/quickstart.first-app.txt
index 22d61bf68..966a50f41 100644
--- a/docs/guide/quickstart.first-app.txt
+++ b/docs/guide/quickstart.first-app.txt
@@ -26,9 +26,6 @@ This will create a skeleton Yii application under the directory
`WebRoot/testdrive`. The application has a directory structure that is
is needed by most Yii applications.
-> Tip: Starting from version 1.0.3, a testdrive application is included
-> directly under the directory `YiiRoot/testdrive`.
-
Without writing a single line of code, we can test drive our first Yii
application by accessing the following URL in a Web browser:
diff --git a/framework/cli/commands/WebAppCommand.php b/framework/cli/commands/WebAppCommand.php
index 68614dea1..b821202da 100644
--- a/framework/cli/commands/WebAppCommand.php
+++ b/framework/cli/commands/WebAppCommand.php
@@ -54,7 +54,7 @@ EOD;
echo "Create a Web application under '$path'? [Yes|No] ";
if(!strncasecmp(trim(fgets(STDIN)),'y',1))
{
- $sourceDir=realpath(dirname(__FILE__).'/../../../testdrive');
+ $sourceDir=realpath(dirname(__FILE__).'/../views/webapp');
if($sourceDir===false)
die('Unable to locate the source directory.');
$list=$this->buildFileList($sourceDir,$path);
diff --git a/framework/cli/commands/shell/ModelCommand.php b/framework/cli/commands/shell/ModelCommand.php
index 29d7e84ac..5ae695edd 100644
--- a/framework/cli/commands/shell/ModelCommand.php
+++ b/framework/cli/commands/shell/ModelCommand.php
@@ -101,7 +101,7 @@ EOD;
{
if($column->isPrimaryKey && $table->sequenceName!==null || $column->isForeignKey)
continue;
- if(!$column->allowNull)
+ if(!$column->allowNull && $column->defaultValue!==null)
$required[]=$column->name;
if($column->type==='integer')
$integers[]=$column->name;
diff --git a/framework/cli/views/shell/crud/controller.php b/framework/cli/views/shell/crud/controller.php
index 210d46b7c..cd26417e4 100644
--- a/framework/cli/views/shell/crud/controller.php
+++ b/framework/cli/views/shell/crud/controller.php
@@ -113,7 +113,7 @@ class {ClassName} extends CController
{
$criteria=new CDbCriteria;
- $pages=new CPagination({ModelClass}::model()->count());
+ $pages=new CPagination({ModelClass}::model()->count($criteria));
$pages->pageSize=self::PAGE_SIZE;
$pages->applyLimit($criteria);
@@ -134,7 +134,7 @@ class {ClassName} extends CController
$criteria=new CDbCriteria;
- $pages=new CPagination({ModelClass}::model()->count());
+ $pages=new CPagination({ModelClass}::model()->count($criteria));
$pages->pageSize=self::PAGE_SIZE;
$pages->applyLimit($criteria);
diff --git a/testdrive/assets/.yii b/framework/cli/views/webapp/assets/.yii
similarity index 100%
rename from testdrive/assets/.yii
rename to framework/cli/views/webapp/assets/.yii
diff --git a/testdrive/css/bg.gif b/framework/cli/views/webapp/css/bg.gif
similarity index 100%
rename from testdrive/css/bg.gif
rename to framework/cli/views/webapp/css/bg.gif
diff --git a/testdrive/css/form.css b/framework/cli/views/webapp/css/form.css
similarity index 100%
rename from testdrive/css/form.css
rename to framework/cli/views/webapp/css/form.css
diff --git a/testdrive/css/main.css b/framework/cli/views/webapp/css/main.css
similarity index 100%
rename from testdrive/css/main.css
rename to framework/cli/views/webapp/css/main.css
diff --git a/testdrive/images/.yii b/framework/cli/views/webapp/images/.yii
similarity index 100%
rename from testdrive/images/.yii
rename to framework/cli/views/webapp/images/.yii
diff --git a/testdrive/index.php b/framework/cli/views/webapp/index.php
similarity index 100%
rename from testdrive/index.php
rename to framework/cli/views/webapp/index.php
diff --git a/testdrive/protected/.htaccess b/framework/cli/views/webapp/protected/.htaccess
similarity index 100%
rename from testdrive/protected/.htaccess
rename to framework/cli/views/webapp/protected/.htaccess
diff --git a/testdrive/protected/commands/shell/.yii b/framework/cli/views/webapp/protected/commands/shell/.yii
similarity index 100%
rename from testdrive/protected/commands/shell/.yii
rename to framework/cli/views/webapp/protected/commands/shell/.yii
diff --git a/testdrive/protected/components/MainMenu.php b/framework/cli/views/webapp/protected/components/MainMenu.php
similarity index 100%
rename from testdrive/protected/components/MainMenu.php
rename to framework/cli/views/webapp/protected/components/MainMenu.php
diff --git a/testdrive/protected/components/UserIdentity.php b/framework/cli/views/webapp/protected/components/UserIdentity.php
similarity index 100%
rename from testdrive/protected/components/UserIdentity.php
rename to framework/cli/views/webapp/protected/components/UserIdentity.php
diff --git a/testdrive/protected/components/views/mainMenu.php b/framework/cli/views/webapp/protected/components/views/mainMenu.php
similarity index 100%
rename from testdrive/protected/components/views/mainMenu.php
rename to framework/cli/views/webapp/protected/components/views/mainMenu.php
diff --git a/testdrive/protected/config/console.php b/framework/cli/views/webapp/protected/config/console.php
similarity index 100%
rename from testdrive/protected/config/console.php
rename to framework/cli/views/webapp/protected/config/console.php
diff --git a/testdrive/protected/config/main.php b/framework/cli/views/webapp/protected/config/main.php
similarity index 100%
rename from testdrive/protected/config/main.php
rename to framework/cli/views/webapp/protected/config/main.php
diff --git a/testdrive/protected/controllers/SiteController.php b/framework/cli/views/webapp/protected/controllers/SiteController.php
similarity index 100%
rename from testdrive/protected/controllers/SiteController.php
rename to framework/cli/views/webapp/protected/controllers/SiteController.php
diff --git a/testdrive/protected/extensions/.yii b/framework/cli/views/webapp/protected/extensions/.yii
similarity index 100%
rename from testdrive/protected/extensions/.yii
rename to framework/cli/views/webapp/protected/extensions/.yii
diff --git a/testdrive/protected/messages/.yii b/framework/cli/views/webapp/protected/messages/.yii
similarity index 100%
rename from testdrive/protected/messages/.yii
rename to framework/cli/views/webapp/protected/messages/.yii
diff --git a/testdrive/protected/models/ContactForm.php b/framework/cli/views/webapp/protected/models/ContactForm.php
similarity index 100%
rename from testdrive/protected/models/ContactForm.php
rename to framework/cli/views/webapp/protected/models/ContactForm.php
diff --git a/testdrive/protected/models/LoginForm.php b/framework/cli/views/webapp/protected/models/LoginForm.php
similarity index 100%
rename from testdrive/protected/models/LoginForm.php
rename to framework/cli/views/webapp/protected/models/LoginForm.php
diff --git a/testdrive/protected/runtime/.yii b/framework/cli/views/webapp/protected/runtime/.yii
similarity index 100%
rename from testdrive/protected/runtime/.yii
rename to framework/cli/views/webapp/protected/runtime/.yii
diff --git a/testdrive/protected/views/layouts/main.php b/framework/cli/views/webapp/protected/views/layouts/main.php
similarity index 100%
rename from testdrive/protected/views/layouts/main.php
rename to framework/cli/views/webapp/protected/views/layouts/main.php
diff --git a/testdrive/protected/views/site/contact.php b/framework/cli/views/webapp/protected/views/site/contact.php
similarity index 100%
rename from testdrive/protected/views/site/contact.php
rename to framework/cli/views/webapp/protected/views/site/contact.php
diff --git a/testdrive/protected/views/site/index.php b/framework/cli/views/webapp/protected/views/site/index.php
similarity index 100%
rename from testdrive/protected/views/site/index.php
rename to framework/cli/views/webapp/protected/views/site/index.php
diff --git a/testdrive/protected/views/site/login.php b/framework/cli/views/webapp/protected/views/site/login.php
similarity index 100%
rename from testdrive/protected/views/site/login.php
rename to framework/cli/views/webapp/protected/views/site/login.php
diff --git a/testdrive/protected/views/system/.yii b/framework/cli/views/webapp/protected/views/system/.yii
similarity index 100%
rename from testdrive/protected/views/system/.yii
rename to framework/cli/views/webapp/protected/views/system/.yii
diff --git a/testdrive/protected/yiic b/framework/cli/views/webapp/protected/yiic
similarity index 100%
rename from testdrive/protected/yiic
rename to framework/cli/views/webapp/protected/yiic
diff --git a/testdrive/protected/yiic.bat b/framework/cli/views/webapp/protected/yiic.bat
similarity index 100%
rename from testdrive/protected/yiic.bat
rename to framework/cli/views/webapp/protected/yiic.bat
diff --git a/testdrive/protected/yiic.php b/framework/cli/views/webapp/protected/yiic.php
similarity index 100%
rename from testdrive/protected/yiic.php
rename to framework/cli/views/webapp/protected/yiic.php
diff --git a/testdrive/themes/classic/views/.htaccess b/framework/cli/views/webapp/themes/classic/views/.htaccess
similarity index 100%
rename from testdrive/themes/classic/views/.htaccess
rename to framework/cli/views/webapp/themes/classic/views/.htaccess
diff --git a/testdrive/themes/classic/views/layouts/.yii b/framework/cli/views/webapp/themes/classic/views/layouts/.yii
similarity index 100%
rename from testdrive/themes/classic/views/layouts/.yii
rename to framework/cli/views/webapp/themes/classic/views/layouts/.yii
diff --git a/testdrive/themes/classic/views/site/.yii b/framework/cli/views/webapp/themes/classic/views/site/.yii
similarity index 100%
rename from testdrive/themes/classic/views/site/.yii
rename to framework/cli/views/webapp/themes/classic/views/site/.yii
diff --git a/testdrive/themes/classic/views/system/.yii b/framework/cli/views/webapp/themes/classic/views/system/.yii
similarity index 100%
rename from testdrive/themes/classic/views/system/.yii
rename to framework/cli/views/webapp/themes/classic/views/system/.yii
diff --git a/framework/web/CController.php b/framework/web/CController.php
index ea739f756..6ca69c426 100644
--- a/framework/web/CController.php
+++ b/framework/web/CController.php
@@ -70,9 +70,9 @@ class CController extends CBaseController
const STATE_INPUT_NAME='YII_PAGE_STATE';
/**
- * @var mixed the name of the layout to be applied to this controller's views.
+ * @var string the name of the layout to be applied to this controller's views.
* Defaults to null, meaning the {@link CWebApplication::layout application layout}
- * is used. If false, no layout will be applied.
+ * is used. If it is an empty string, no layout will be applied.
*/
public $layout;
/**
@@ -509,7 +509,7 @@ class CController extends CBaseController
{
$output=$this->renderPartial($view,$data,true);
- if(($layout=$this->layout)==null)
+ if(($layout=$this->layout)===null)
$layout=Yii::app()->layout;
if(!empty($layout) && ($layoutFile=$this->getLayoutFile($layout))!==false)
@@ -533,7 +533,7 @@ class CController extends CBaseController
*/
public function renderText($text,$return=false)
{
- if(($layout=$this->layout)==null)
+ if(($layout=$this->layout)===null)
$layout=Yii::app()->layout;
if(!empty($layout) && ($layoutFile=$this->getLayoutFile($layout))!==false)
diff --git a/framework/web/CSort.php b/framework/web/CSort.php
index dede97245..827973c4c 100644
--- a/framework/web/CSort.php
+++ b/framework/web/CSort.php
@@ -122,9 +122,16 @@ class CSort extends CComponent
$order=$this->defaultOrder;
else
{
+ $schema=CActiveRecord::model($this->modelClass)->getDbConnection()->getSchema();
$orders=array();
foreach($directions as $attribute=>$descending)
+ {
+ if(($pos=strpos($attribute,'.'))!==false)
+ $attribute=$schema->quoteTableName(substr($attribute,0,$pos)).'.'.$schema->quoteColumnName(substr($attribute,$pos+1));
+ else
+ $attribute=$schema->quoteColumnName($attribute);
$orders[]=$descending?$attribute.' DESC':$attribute;
+ }
$order=implode(', ',$orders);
}
@@ -280,6 +287,6 @@ class CSort extends CComponent
*/
protected function createLink($attribute,$label,$url,$htmlOptions)
{
- return CHtml::link(CHtml::encode($label),$url,$htmlOptions);
+ return CHtml::link($label,$url,$htmlOptions);
}
}
\ No newline at end of file
diff --git a/framework/web/helpers/CHtml.php b/framework/web/helpers/CHtml.php
index c8aa4840e..86a588be0 100644
--- a/framework/web/helpers/CHtml.php
+++ b/framework/web/helpers/CHtml.php
@@ -546,7 +546,9 @@ class CHtml
* Generates a drop down list.
* @param string the input name
* @param string the selected value
- * @param array data for generating the list options (value=>display)
+ * @param array data for generating the list options (value=>display).
+ * You may use {@link listData} to generate this data.
+ * Please refer to {@link listOptions} on how this data is used to generate the list options.
* @param array additional HTML attributes. Besides normal HTML attributes, a few special
* attributes are also recognized (see {@link clientChange} for more details.)
* @return string the generated drop down list
@@ -569,6 +571,8 @@ class CHtml
* @param string the input name
* @param string the selected value
* @param array data for generating the list options (value=>display)
+ * You may use {@link listData} to generate this data.
+ * Please refer to {@link listOptions} on how this data is used to generate the list options.
* @param array additional HTML attributes. Besides normal HTML attributes, a few special
* attributes are also recognized (see {@link clientChange} for more details.)
* @return string the generated list box
@@ -1024,6 +1028,8 @@ class CHtml
* @param CModel the data model
* @param string the attribute
* @param array data for generating the list options (value=>display)
+ * You may use {@link listData} to generate this data.
+ * Please refer to {@link listOptions} on how this data is used to generate the list options.
* @param array additional HTML attributes. Besides normal HTML attributes, a few special
* attributes are also recognized (see {@link clientChange} for more details.)
* @return string the generated drop down list
@@ -1054,6 +1060,8 @@ class CHtml
* @param CModel the data model
* @param string the attribute
* @param array data for generating the list options (value=>display)
+ * You may use {@link listData} to generate this data.
+ * Please refer to {@link listOptions} on how this data is used to generate the list options.
* @param array additional HTML attributes. Besides normal HTML attributes, a few special
* attributes are also recognized (see {@link clientChange} for more details.)
* @return string the generated list box
@@ -1288,10 +1296,21 @@ class CHtml
*
*
prompt: string, specifies the prompt text shown as the first list option. Its value is empty.
*
empty: string, specifies the text corresponding to empty selection. Its value is empty.
+ *
options: array, specifies additional attributes for each OPTION tag.
+ * The array keys must be the option values, and the array values are the extra
+ * OPTION tag attributes in the name-value pairs. For example,
+ *