diff --git a/README.md b/README.md index 54bd499..9bd6480 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ DIRECTORY STRUCTURE ------------------- apps/ ready-to-use Web apps built on Yii 2 - bootstrap/ a simple app supporting user login and contact page + basic/ a simple app supporting user login and contact page build/ internally used build tools docs/ documentation yii/ framework source files diff --git a/apps/advanced/.gitignore b/apps/advanced/.gitignore new file mode 100644 index 0000000..b1cf719 --- /dev/null +++ b/apps/advanced/.gitignore @@ -0,0 +1 @@ +/yii \ No newline at end of file diff --git a/apps/bootstrap/LICENSE.md b/apps/advanced/LICENSE.md similarity index 100% rename from apps/bootstrap/LICENSE.md rename to apps/advanced/LICENSE.md diff --git a/apps/advanced/README.md b/apps/advanced/README.md new file mode 100644 index 0000000..a2bcdd4 --- /dev/null +++ b/apps/advanced/README.md @@ -0,0 +1,98 @@ +Yii 2 Advanced Application Template +=================================== + +**NOTE** Yii 2 and the relevant applications and extensions are still under heavy +development. We may make significant changes without prior notices. Please do not +use them for production. Please consider using [Yii v1.1](https://github.com/yiisoft/yii) +if you have a project to be deployed for production soon. + + +Thank you for using Yii 2 Advanced Application Template - an application template +that works out-of-box and can be easily customized to fit for your needs. + +Yii 2 Advanced Application Template is best suitable for large projects requiring frontend and backstage separation, +deployment in different environments, configuration nesting etc. + + +DIRECTORY STRUCTURE +------------------- + +``` +common + config/ contains shared configurations + models/ contains model classes used in both backstage and frontend +console + config/ contains console configurations + controllers/ contains console controllers (commands) + migrations/ contains database migrations + models/ contains console-specific model classes + runtime/ contains files generated during runtime +backstage + assets/ contains application assets such as JavaScript and CSS + config/ contains backstage configurations + controllers/ contains Web controller classes + models/ contains backstage-specific model classes + runtime/ contains files generated during runtime + views/ contains view files for the Web application + www/ contains the entry script and Web resources +frontend + assets/ contains application assets such as JavaScript and CSS + config/ contains frontend configurations + controllers/ contains Web controller classes + models/ contains frontend-specific model classes + runtime/ contains files generated during runtime + views/ contains view files for the Web application + www/ contains the entry script and Web resources +vendor/ contains dependent 3rd-party packages +environments/ contains environment-based overrides +``` + + + +REQUIREMENTS +------------ + +The minimum requirement by Yii is that your Web server supports PHP 5.3.?. + + +INSTALLATION +------------ + +### Install via Composer + +If you do not have [Composer](http://getcomposer.org/), you may download it from +[http://getcomposer.org/](http://getcomposer.org/) or run the following command on Linux/Unix/MacOS: + +~~~ +curl -s http://getcomposer.org/installer | php +~~~ + +You can then install the Bootstrap Application using the following command: + +~~~ +php composer.phar create-project --stability=dev yiisoft/yii2-app-advanced yii-advanced +~~~ + +Now you should be able to access: + +- the frontend using the URL `http://localhost/yii-advanced/frontend/www/` +- the backstage using the URL `http://localhost/yii-advanced/backstage/www/` + +assuming `yii-advanced` is directly under the document root of your Web server. + + +### Install from an Archive File + +This is not currently available. We will provide it when Yii 2 is formally released. + +GETTING STARTED +--------------- + +After template application and its dependencies are downloaded you need to initialize it and set some config values to +match your application requirements. + +1. Execute `install` command selecting `dev` as environment. +2. Set `id` value in `console/config/main.php`, `frontend/config/main.php`, `backstage/config/main.php`. +3. Create new database. It is assumed that MySQL InnoDB is used. If not, adjust `console/migrations/m130524_201442_init.php`. +4. In `common/config/params.php` set your database details in `components.db` values. + diff --git a/apps/bootstrap/assets/.gitignore b/apps/advanced/backstage/assets/.gitkeep similarity index 100% rename from apps/bootstrap/assets/.gitignore rename to apps/advanced/backstage/assets/.gitkeep diff --git a/apps/advanced/backstage/config/.gitignore b/apps/advanced/backstage/config/.gitignore new file mode 100644 index 0000000..20da318 --- /dev/null +++ b/apps/advanced/backstage/config/.gitignore @@ -0,0 +1,2 @@ +main-local.php +params-local.php \ No newline at end of file diff --git a/apps/bootstrap/config/assets.php b/apps/advanced/backstage/config/assets.php similarity index 100% rename from apps/bootstrap/config/assets.php rename to apps/advanced/backstage/config/assets.php diff --git a/apps/advanced/backstage/config/main.php b/apps/advanced/backstage/config/main.php new file mode 100644 index 0000000..4898bfd --- /dev/null +++ b/apps/advanced/backstage/config/main.php @@ -0,0 +1,40 @@ + 'change-me', + 'basePath' => dirname(__DIR__), + 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor', + 'preload' => array('log'), + 'controllerNamespace' => 'backstage\controllers', + 'modules' => array( + ), + 'components' => array( + 'db' => $params['components.db'], + 'cache' => $params['components.cache'], + 'user' => array( + 'class' => 'yii\web\User', + 'identityClass' => 'common\models\User', + ), + 'assetManager' => array( + 'bundles' => require(__DIR__ . '/assets.php'), + ), + 'log' => array( + 'class' => 'yii\logging\Router', + 'targets' => array( + array( + 'class' => 'yii\logging\FileTarget', + 'levels' => array('error', 'warning'), + ), + ), + ), + ), + 'params' => $params, +); diff --git a/apps/bootstrap/config/params.php b/apps/advanced/backstage/config/params.php similarity index 100% rename from apps/bootstrap/config/params.php rename to apps/advanced/backstage/config/params.php diff --git a/apps/advanced/backstage/controllers/SiteController.php b/apps/advanced/backstage/controllers/SiteController.php new file mode 100644 index 0000000..d40738a --- /dev/null +++ b/apps/advanced/backstage/controllers/SiteController.php @@ -0,0 +1,33 @@ +render('index'); + } + + public function actionLogin() + { + $model = new LoginForm(); + if ($this->populate($_POST, $model) && $model->login()) { + Yii::$app->response->redirect(array('site/index')); + } else { + echo $this->render('login', array( + 'model' => $model, + )); + } + } + + public function actionLogout() + { + Yii::$app->getUser()->logout(); + Yii::$app->getResponse()->redirect(array('site/index')); + } +} diff --git a/apps/bootstrap/runtime/.gitignore b/apps/advanced/backstage/models/.gitkeep similarity index 100% rename from apps/bootstrap/runtime/.gitignore rename to apps/advanced/backstage/models/.gitkeep diff --git a/apps/advanced/backstage/runtime/.gitignore b/apps/advanced/backstage/runtime/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/apps/advanced/backstage/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/apps/advanced/backstage/views/layouts/main.php b/apps/advanced/backstage/views/layouts/main.php new file mode 100644 index 0000000..44117f4 --- /dev/null +++ b/apps/advanced/backstage/views/layouts/main.php @@ -0,0 +1,64 @@ +registerAssetBundle('app'); +?> +beginPage(); ?> + + +
+ +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.
+ Get started with Yii +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.
+ + +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.
+ + +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.
+ + +Please fill out the following fields to login:
+ + array('class' => 'form-horizontal'))); ?> + field($model, 'username')->textInput(); ?> + field($model, 'password')->passwordInput(); ?> + field($model, 'rememberMe')->checkbox(); ?> +The path to yii framework seems to be incorrect.
'; + echo 'You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) .'.
'; + echo 'Please refer to the README on how to install Yii.
'; +} require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); $requirementsChecker = new YiiRequirementChecker(); diff --git a/apps/advanced/vendor/.gitignore b/apps/advanced/vendor/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/apps/advanced/vendor/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/apps/bootstrap/yii.bat b/apps/advanced/yii.bat similarity index 100% rename from apps/bootstrap/yii.bat rename to apps/advanced/yii.bat diff --git a/apps/basic/LICENSE.md b/apps/basic/LICENSE.md new file mode 100644 index 0000000..6edcc4f --- /dev/null +++ b/apps/basic/LICENSE.md @@ -0,0 +1,32 @@ +The Yii framework is free software. It is released under the terms of +the following BSD License. + +Copyright © 2008-2013 by Yii Software LLC (http://www.yiisoft.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Yii Software LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/apps/bootstrap/README.md b/apps/basic/README.md similarity index 72% rename from apps/bootstrap/README.md rename to apps/basic/README.md index a1376ba..5300448 100644 --- a/apps/bootstrap/README.md +++ b/apps/basic/README.md @@ -1,5 +1,5 @@ -Yii 2 Bootstrap Application -=========================== +Yii 2 Basic Application Template +================================ **NOTE** Yii 2 and the relevant applications and extensions are still under heavy development. We may make significant changes without prior notices. Please do not @@ -7,10 +7,10 @@ use them for production. Please consider using [Yii v1.1](https://github.com/yii if you have a project to be deployed for production soon. -Thank you for choosing Yii 2 - the new generation of high-performance PHP framework. +Thank you for using Yii 2 Basic Application Template - an application template +that works out-of-box and can be easily customized to fit for your needs. -The Yii 2 Bootstrap Application is a Web application template that you can easily customize -to fit for your needs. It is particularly suitable for small Websites which mainly contain +Yii 2 Basic Application Template is best suitable for small Websites which mainly contain a few informational pages. @@ -49,11 +49,11 @@ curl -s http://getcomposer.org/installer | php You can then install the Bootstrap Application using the following command: ~~~ -php composer.phar create-project --stability=dev yiisoft/yii2-bootstrap bootstrap +php composer.phar create-project --stability=dev yiisoft/yii2-app-basic yii-basic ~~~ -Now you should be able to access the Bootstrap Application using the URL `http://localhost/bootstrap/www/`, -assuming `bootstrap` is directly under the document root of your Web server. +Now you should be able to access the application using the URL `http://localhost/yii-basic/www/`, +assuming `yii-basic` is directly under the document root of your Web server. ### Install from an Archive File diff --git a/apps/bootstrap/www/assets/.gitignore b/apps/basic/assets/.gitkeep similarity index 100% rename from apps/bootstrap/www/assets/.gitignore rename to apps/basic/assets/.gitkeep diff --git a/apps/bootstrap/commands/HelloController.php b/apps/basic/commands/HelloController.php similarity index 100% rename from apps/bootstrap/commands/HelloController.php rename to apps/basic/commands/HelloController.php diff --git a/apps/bootstrap/composer.json b/apps/basic/composer.json similarity index 83% rename from apps/bootstrap/composer.json rename to apps/basic/composer.json index d44e35a..29b05d1 100644 --- a/apps/bootstrap/composer.json +++ b/apps/basic/composer.json @@ -1,7 +1,7 @@ { - "name": "yiisoft/yii2-bootstrap", - "description": "Yii 2 Bootstrap Application", - "keywords": ["yii", "framework", "bootstrap"], + "name": "yiisoft/yii2-app-basic", + "description": "Yii 2 Basic Application Template", + "keywords": ["yii", "framework", "basic", "application template"], "homepage": "http://www.yiiframework.com/", "type": "project", "license": "BSD-3-Clause", diff --git a/apps/basic/composer.lock b/apps/basic/composer.lock new file mode 100644 index 0000000..a66bbea --- /dev/null +++ b/apps/basic/composer.lock @@ -0,0 +1,164 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" + ], + "hash": "0411dbbd774aa1c89256c77c68023940", + "packages": [ + { + "name": "yiisoft/yii2", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-framework.git", + "reference": "15a8d0559260e39954a8eb6de0d28bfb7de95e7b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/15a8d0559260e39954a8eb6de0d28bfb7de95e7b", + "reference": "15a8d0559260e39954a8eb6de0d28bfb7de95e7b", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "lib-pcre": "*", + "php": ">=5.3.7" + }, + "suggest": { + "ezyang/htmlpurifier": "Required by HtmlPurifier.", + "michelf/php-markdown": "Required by Markdown.", + "smarty/smarty": "Required by SmartyViewRenderer.", + "twig/twig": "Required by TwigViewRenderer." + }, + "type": "library", + "autoload": { + "psr-0": { + "yii\\": "/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com", + "homepage": "http://www.yiiframework.com/", + "role": "Founder and project lead" + }, + { + "name": "Alexander Makarov", + "email": "sam@rmcreative.ru", + "homepage": "http://rmcreative.ru/", + "role": "Core framework development" + }, + { + "name": "Maurizio Domba", + "homepage": "http://mdomba.info/", + "role": "Core framework development" + }, + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "http://cebe.cc/", + "role": "Core framework development" + }, + { + "name": "Wei Zhuo", + "email": "weizhuo@gmail.com", + "role": "Project site maintenance and development" + }, + { + "name": "Sebastián Thierer", + "email": "sebas@artfos.com", + "role": "Component development" + }, + { + "name": "Jeffrey Winesett", + "email": "jefftulsa@gmail.com", + "role": "Documentation and marketing" + }, + { + "name": "Timur Ruziev", + "email": "resurtm@gmail.com", + "homepage": "http://resurtm.com/", + "role": "Core framework development" + }, + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com", + "role": "Core framework development" + } + ], + "description": "Yii2 Web Programming Framework", + "homepage": "http://www.yiiframework.com/", + "keywords": [ + "framework", + "yii" + ], + "time": "2013-05-25 20:59:05" + }, + { + "name": "yiisoft/yii2-composer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-composer.git", + "reference": "7ce4060faca940b836ab88de207638940a0a0568" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/7ce4060faca940b836ab88de207638940a0a0568", + "reference": "7ce4060faca940b836ab88de207638940a0a0568", + "shasum": "" + }, + "require": { + "yiisoft/yii2": "*" + }, + "type": "library", + "autoload": { + "psr-0": { + "yii\\composer": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com", + "homepage": "http://www.yiiframework.com/", + "role": "Founder and project lead" + } + ], + "description": "The composer integration for the Yii framework", + "keywords": [ + "composer", + "install", + "update", + "yii" + ], + "time": "2013-05-23 19:12:45" + } + ], + "packages-dev": [ + + ], + "aliases": [ + + ], + "minimum-stability": "dev", + "stability-flags": { + "yiisoft/yii2": 20, + "yiisoft/yii2-composer": 20 + }, + "platform": { + "php": ">=5.3.0" + }, + "platform-dev": [ + + ] +} diff --git a/apps/basic/config/assets.php b/apps/basic/config/assets.php new file mode 100644 index 0000000..ee0d610 --- /dev/null +++ b/apps/basic/config/assets.php @@ -0,0 +1,18 @@ + array( + 'basePath' => '@wwwroot', + 'baseUrl' => '@www', + 'css' => array( + 'css/site.css', + ), + 'js' => array( + + ), + 'depends' => array( + 'yii', + 'yii/bootstrap/responsive', + ), + ), +); diff --git a/apps/bootstrap/config/console.php b/apps/basic/config/console.php similarity index 88% rename from apps/bootstrap/config/console.php rename to apps/basic/config/console.php index df96023..bfb3ed7 100644 --- a/apps/bootstrap/config/console.php +++ b/apps/basic/config/console.php @@ -1,5 +1,5 @@ 'bootstrap-console', 'basePath' => dirname(__DIR__), @@ -22,5 +22,5 @@ return array( ), ), ), - 'params' => require(__DIR__ . '/params.php'), + 'params' => $params, ); diff --git a/apps/bootstrap/config/main.php b/apps/basic/config/main.php similarity index 92% rename from apps/bootstrap/config/main.php rename to apps/basic/config/main.php index b5980da..9adfba6 100644 --- a/apps/bootstrap/config/main.php +++ b/apps/basic/config/main.php @@ -1,5 +1,5 @@ 'bootstrap', 'basePath' => dirname(__DIR__), @@ -34,5 +34,5 @@ return array( ), ), ), - 'params' => require(__DIR__ . '/params.php'), + 'params' => $params, ); diff --git a/apps/basic/config/params.php b/apps/basic/config/params.php new file mode 100644 index 0000000..1e197d0 --- /dev/null +++ b/apps/basic/config/params.php @@ -0,0 +1,5 @@ + 'admin@example.com', +); \ No newline at end of file diff --git a/apps/bootstrap/controllers/SiteController.php b/apps/basic/controllers/SiteController.php similarity index 100% rename from apps/bootstrap/controllers/SiteController.php rename to apps/basic/controllers/SiteController.php diff --git a/apps/bootstrap/models/ContactForm.php b/apps/basic/models/ContactForm.php similarity index 100% rename from apps/bootstrap/models/ContactForm.php rename to apps/basic/models/ContactForm.php diff --git a/apps/bootstrap/models/LoginForm.php b/apps/basic/models/LoginForm.php similarity index 100% rename from apps/bootstrap/models/LoginForm.php rename to apps/basic/models/LoginForm.php diff --git a/apps/bootstrap/models/User.php b/apps/basic/models/User.php similarity index 100% rename from apps/bootstrap/models/User.php rename to apps/basic/models/User.php diff --git a/apps/basic/requirements.php b/apps/basic/requirements.php new file mode 100644 index 0000000..c9e6493 --- /dev/null +++ b/apps/basic/requirements.php @@ -0,0 +1,103 @@ +Error'; + echo 'The path to yii framework seems to be incorrect.
'; + echo 'You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) .'.
'; + echo 'Please refer to the README on how to install Yii.
'; +} + +require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); +$requirementsChecker = new YiiRequirementChecker(); + +/** + * Adjust requirements according to your application specifics. + */ +$requirements = array( + // Database : + array( + 'name' => 'PDO extension', + 'mandatory' => true, + 'condition' => extension_loaded('pdo'), + 'by' => 'All DB-related classes', + ), + array( + 'name' => 'PDO SQLite extension', + 'mandatory' => false, + 'condition' => extension_loaded('pdo_sqlite'), + 'by' => 'All DB-related classes', + 'memo' => 'Required for SQLite database.', + ), + array( + 'name' => 'PDO MySQL extension', + 'mandatory' => false, + 'condition' => extension_loaded('pdo_mysql'), + 'by' => 'All DB-related classes', + 'memo' => 'Required for MySQL database.', + ), + // Cache : + array( + 'name' => 'Memcache extension', + 'mandatory' => false, + 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), + 'by' => 'CMemCache', + 'memo' => extension_loaded('memcached') ? 'To use memcached set CMemCache::useMemcached totrue.' : ''
+ ),
+ array(
+ 'name' => 'APC extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('apc') || extension_loaded('apc'),
+ 'by' => 'CApcCache',
+ ),
+ // Additional PHP extensions :
+ array(
+ 'name' => 'Mcrypt extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('mcrypt'),
+ 'by' => 'CSecurityManager',
+ 'memo' => 'Required by encrypt and decrypt methods.'
+ ),
+ // PHP ini :
+ 'phpSafeMode' => array(
+ 'name' => 'PHP safe mode',
+ 'mandatory' => false,
+ 'condition' => $requirementsChecker->checkPhpIniOff("safe_mode"),
+ 'by' => 'File uploading and console command execution',
+ 'memo' => '"safe_mode" should be disabled at php.ini',
+ ),
+ 'phpExposePhp' => array(
+ 'name' => 'Expose PHP',
+ 'mandatory' => false,
+ 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"),
+ 'by' => 'Security reasons',
+ 'memo' => '"expose_php" should be disabled at php.ini',
+ ),
+ 'phpAllowUrlInclude' => array(
+ 'name' => 'PHP allow url include',
+ 'mandatory' => false,
+ 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"),
+ 'by' => 'Security reasons',
+ 'memo' => '"allow_url_include" should be disabled at php.ini',
+ ),
+ 'phpSmtp' => array(
+ 'name' => 'PHP mail SMTP',
+ 'mandatory' => false,
+ 'condition' => strlen(ini_get('SMTP'))>0,
+ 'by' => 'Email sending',
+ 'memo' => 'PHP mail SMTP server required',
+ ),
+);
+$requirementsChecker->checkYii()->check($requirements)->render();
diff --git a/apps/basic/runtime/.gitignore b/apps/basic/runtime/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/apps/basic/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/apps/basic/vendor/.gitignore b/apps/basic/vendor/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/apps/basic/vendor/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/apps/basic/views/layouts/main.php b/apps/basic/views/layouts/main.php
new file mode 100644
index 0000000..635e118
--- /dev/null
+++ b/apps/basic/views/layouts/main.php
@@ -0,0 +1,66 @@
+registerAssetBundle('app');
+?>
+beginPage(); ?>
+
+
+
+
+ + This is the About page. You may modify the following file to customize its content: +
+ +
+
diff --git a/apps/basic/views/site/contact.php b/apps/basic/views/site/contact.php
new file mode 100644
index 0000000..e740d0f
--- /dev/null
+++ b/apps/basic/views/site/contact.php
@@ -0,0 +1,46 @@
+title = 'Contact';
+$this->params['breadcrumbs'][] = $this->title;
+?>
++ If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. +
+ + array('class' => 'form-horizontal'), + 'fieldConfig' => array('inputOptions' => array('class' => 'input-xlarge')), +)); ?> + field($model, 'name')->textInput(); ?> + field($model, 'email')->textInput(); ?> + field($model, 'subject')->textInput(); ?> + field($model, 'body')->textArea(array('rows' => 6)); ?> + field($model, 'verifyCode'); + echo $field->begin() + . $field->label() + . Captcha::widget() + . Html::activeTextInput($model, 'verifyCode', array('class' => 'input-medium')) + . $field->error() + . $field->end(); + ?> +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.
+ Get started with Yii +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.
+ + +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.
+ + +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.
+ + +Please fill out the following fields to login:
+ + array('class' => 'form-horizontal'))); ?> + field($model, 'username')->textInput(); ?> + field($model, 'password')->passwordInput(); ?> + field($model, 'rememberMe')->checkbox(); ?> +' . $output . '
| #$n | ";
- echo ' ';
- if ($hasCode) {
- echo ' ';
- if ($hasCode) {
- $this->renderSourceCode($t['file'], $t['line'], $this->maxTraceSourceLines);
- }
- echo "+ - ';
- }
- echo ' ';
- if (isset($t['file'])) {
- echo $this->htmlEncode($t['file']) . '(' . $t['line'] . '): ';
- }
- if (!empty($t['class'])) {
- echo '' . $t['class'] . '' . $t['type'];
- }
- echo '' . $t['function'] . '';
- echo '(' . (empty($t['args']) ? '' : $this->htmlEncode($this->argumentsToString($t['args']))) . ')';
- echo ' |
- * function foo($source, $params) - *- * where $source parameter is the source file path, and the content returned - * by the function will be saved into the target file.
* text text background
@@ -450,7 +476,6 @@ class Console
*
* @param string $string String to convert
* @param bool $colored Should the string be colored?
- *
* @return string
*/
public static function renderColoredString($string, $colored = true)
@@ -508,22 +533,23 @@ class Console
}
/**
- * Escapes % so they don't get interpreted as color codes
- *
- * @param string $string String to escape
- *
- * @access public
- * @return string
- */
+ * Escapes % so they don't get interpreted as color codes when
+ * the string is parsed by [[renderColoredString]]
+ *
+ * @param string $string String to escape
+ *
+ * @access public
+ * @return string
+ */
public static function escape($string)
{
return str_replace('%', '%%', $string);
}
/**
- * Returns true if the stream supports colorization. ANSI colors is disabled if not supported by the stream.
+ * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream.
*
- * - windows without asicon
+ * - windows without ansicon
* - not tty consoles
*
* @param mixed $stream
@@ -532,7 +558,7 @@ class Console
public static function streamSupportsAnsiColors($stream)
{
return DIRECTORY_SEPARATOR == '\\'
- ? null !== getenv('ANSICON')
+ ? getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON'
: function_exists('posix_isatty') && @posix_isatty($stream);
}
@@ -542,18 +568,50 @@ class Console
*/
public static function isRunningOnWindows()
{
- return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
+ return DIRECTORY_SEPARATOR == '\\';
}
/**
* Usage: list($w, $h) = ConsoleHelper::getScreenSize();
*
- * @return array
+ * @param bool $refresh whether to force checking and not re-use cached size value.
+ * This is useful to detect changing window size while the application is running but may
+ * not get up to date values on every terminal.
+ * @return array|boolean An array of ($width, $height) or false when it was not able to determine size.
*/
- public static function getScreenSize()
+ public static function getScreenSize($refresh = false)
{
- // TODO implement
- return array(150, 50);
+ static $size;
+ if ($size !== null && !$refresh) {
+ return $size;
+ }
+
+ if (static::isRunningOnWindows()) {
+ $output = array();
+ exec('mode con', $output);
+ if(isset($output) && strpos($output[1], 'CON')!==false) {
+ return $size = array((int)preg_replace('~[^0-9]~', '', $output[3]), (int)preg_replace('~[^0-9]~', '', $output[4]));
+ }
+ } else {
+
+ // try stty if available
+ $stty = array();
+ if (exec('stty -a 2>&1', $stty) && preg_match('/rows\s+(\d+);\s*columns\s+(\d+);/mi', implode(' ', $stty), $matches)) {
+ return $size = array($matches[2], $matches[1]);
+ }
+
+ // fallback to tput, which may not be updated on terminal resize
+ if (($width = (int) exec('tput cols 2>&1')) > 0 && ($height = (int) exec('tput lines 2>&1')) > 0) {
+ return $size = array($width, $height);
+ }
+
+ // fallback to ENV variables, which may not be updated on terminal resize
+ if (($width = (int) getenv('COLUMNS')) > 0 && ($height = (int) getenv('LINES')) > 0) {
+ return $size = array($width, $height);
+ }
+ }
+
+ return $size = false;
}
/**
@@ -607,27 +665,23 @@ class Console
/**
* Prints text to STDOUT appended with a carriage return (PHP_EOL).
*
- * @param string $text
- * @param bool $raw
- *
+ * @param string $string
* @return mixed Number of bytes printed or bool false on error
*/
- public static function output($text = null)
+ public static function output($string = null)
{
- return static::stdout($text . PHP_EOL);
+ return static::stdout($string . PHP_EOL);
}
/**
* Prints text to STDERR appended with a carriage return (PHP_EOL).
*
- * @param string $text
- * @param bool $raw
- *
+ * @param string $string
* @return mixed Number of bytes printed or false on error
*/
- public static function error($text = null)
+ public static function error($string = null)
{
- return static::stderr($text . PHP_EOL);
+ return static::stderr($string . PHP_EOL);
}
/**
diff --git a/framework/yii/helpers/base/Purifier.php b/framework/yii/helpers/base/HtmlPurifier.php
similarity index 53%
rename from framework/yii/helpers/base/Purifier.php
rename to framework/yii/helpers/base/HtmlPurifier.php
index 2c5d334..799dabf 100644
--- a/framework/yii/helpers/base/Purifier.php
+++ b/framework/yii/helpers/base/HtmlPurifier.php
@@ -7,29 +7,22 @@
namespace yii\helpers\base;
/**
- * Purifier provides an ability to clean up HTML from any harmful code.
+ * HtmlPurifier is the concrete implementation of the [[yii\helpers\HtmlPurifier]] class.
*
- * Basic usage is the following:
- *
- * ```php
- * $my_html = Purifier::process($my_text);
- * ```
- *
- * If you want to configure it:
- *
- * ```php
- * $my_html = Purifier::process($my_text, array(
- * 'Attr.EnableID' => true,
- * ));
- * ```
- *
- * For more details please refer to HTMLPurifier documentation](http://htmlpurifier.org/).
+ * You should use [[yii\helpers\HtmlPurifier]] instead of this class in your application.
*
* @author Alexander Makarov
* @since 2.0
*/
-class Purifier
+class HtmlPurifier
{
+ /**
+ * Passes markup through HTMLPurifier making it safe to output to end user
+ *
+ * @param string $content
+ * @param array|null $config
+ * @return string
+ */
public static function process($content, $config = null)
{
$purifier=\HTMLPurifier::instance($config);
diff --git a/framework/yii/helpers/base/Markdown.php b/framework/yii/helpers/base/Markdown.php
index 2e14da5..3e69015 100644
--- a/framework/yii/helpers/base/Markdown.php
+++ b/framework/yii/helpers/base/Markdown.php
@@ -37,6 +37,13 @@ class Markdown
*/
protected static $markdown;
+ /**
+ * Converts markdown into HTML
+ *
+ * @param string $content
+ * @param array $config
+ * @return string
+ */
public static function process($content, $config = array())
{
if (static::$markdown === null) {
diff --git a/framework/yii/helpers/base/StringHelper.php b/framework/yii/helpers/base/StringHelper.php
index 5b854ac..5134bf6 100644
--- a/framework/yii/helpers/base/StringHelper.php
+++ b/framework/yii/helpers/base/StringHelper.php
@@ -18,20 +18,18 @@ class StringHelper
{
/**
* Returns the number of bytes in the given string.
- * This method ensures the string is treated as a byte array.
- * It will use `mb_strlen()` if it is available.
+ * This method ensures the string is treated as a byte array by using `mb_strlen()`.
* @param string $string the string being measured for length
* @return integer the number of bytes in the given string.
*/
public static function strlen($string)
{
- return function_exists('mb_strlen') ? mb_strlen($string, '8bit') : strlen($string);
+ return mb_strlen($string, '8bit');
}
/**
* Returns the portion of string specified by the start and length parameters.
- * This method ensures the string is treated as a byte array.
- * It will use `mb_substr()` if it is available.
+ * This method ensures the string is treated as a byte array by using `mb_substr()`.
* @param string $string the input string. Must be one character or longer.
* @param integer $start the starting position
* @param integer $length the desired portion length
@@ -40,15 +38,14 @@ class StringHelper
*/
public static function substr($string, $start, $length)
{
- return function_exists('mb_substr') ? mb_substr($string, $start, $length, '8bit') : substr($string, $start, $length);
+ return mb_substr($string, $start, $length, '8bit');
}
/**
* Returns the trailing name component of a path.
* This method does the same as the php function basename() except that it will
* always use \ and / as directory separators, independent of the operating system.
- * Note: basename() operates naively on the input string, and is not aware of the
- * actual filesystem, or path components such as "..".
+ * Note: this method is not aware of the actual filesystem, or path components such as "..".
* @param string $path A path string.
* @param string $suffix If the name component ends in suffix this will also be cut off.
* @return string the trailing name component of the given path.
diff --git a/framework/yii/i18n/GettextMessageSource.php b/framework/yii/i18n/GettextMessageSource.php
index 0eb7cb3..5e29487 100644
--- a/framework/yii/i18n/GettextMessageSource.php
+++ b/framework/yii/i18n/GettextMessageSource.php
@@ -31,6 +31,15 @@ class GettextMessageSource extends MessageSource
*/
public $useBigEndian = false;
+ /**
+ * Loads the message translation for the specified language and category.
+ * Child classes should override this method to return the message translations of
+ * the specified language and category.
+ * @param string $category the message category
+ * @param string $language the target language
+ * @return array the loaded messages. The keys are original messages, and the values
+ * are translated messages.
+ */
protected function loadMessages($category, $language)
{
$messageFile = Yii::getAlias($this->basePath) . '/' . $language . '/' . $this->catalog;
diff --git a/framework/yii/jui/Accordion.php b/framework/yii/jui/Accordion.php
index 6c5dd97..f36c981 100644
--- a/framework/yii/jui/Accordion.php
+++ b/framework/yii/jui/Accordion.php
@@ -8,7 +8,7 @@
namespace yii\jui;
use yii\base\InvalidConfigException;
-use yii\helpers\base\ArrayHelper;
+use yii\helpers\ArrayHelper;
use yii\helpers\Html;
/**
@@ -25,11 +25,27 @@ use yii\helpers\Html;
* ),
* array(
* 'header' => 'Section 2',
- * 'headerOptions' => array(...),
+ * 'headerOptions' => array(
+ * 'tag' => 'h3',
+ * ),
* 'content' => 'Sed non urna. Phasellus eu ligula. Vestibulum sit amet purus...',
- * 'options' => array(...),
+ * 'options' => array(
+ * 'tag' => 'div',
+ * ),
* ),
* ),
+ * 'options' => array(
+ * 'tag' => 'div',
+ * ),
+ * 'itemOptions' => array(
+ * 'tag' => 'div',
+ * ),
+ * 'headerOptions' => array(
+ * 'tag' => 'h3',
+ * ),
+ * 'clientOptions' => array(
+ * 'collapsible' => false,
+ * ),
* ));
* ```
*
@@ -40,23 +56,40 @@ use yii\helpers\Html;
class Accordion extends Widget
{
/**
- * @var array list of sections in the accordion widget. Each array element represents a single
- * section with the following structure:
+ * @var array the HTML attributes for the widget container tag. The following special options are recognized:
+ *
+ * - tag: string, defaults to "div", the tag name of the container tag of this widget
+ */
+ public $options = array();
+ /**
+ * @var array list of collapsible items. Each item can be an array of the following structure:
*
- * ```php
+ * ~~~
* array(
- * // required, the header (HTML) of the section
- * 'header' => 'Section label',
- * // required, the content (HTML) of the section
- * 'content' => 'Mauris mauris ante, blandit et, ultrices a, suscipit eget...',
- * // optional the HTML attributes of the section content container
- * 'options'=> array(...),
- * // optional the HTML attributes of the section header container
- * 'headerOptions'=> array(...),
+ * 'header' => 'Item header',
+ * 'content' => 'Item content',
+ * // the HTML attributes of the item header container tag. This will overwrite "headerOptions".
+ * 'headerOptions' => array(),
+ * // the HTML attributes of the item container tag. This will overwrite "itemOptions".
+ * 'options' => array(),
* )
- * ```
+ * ~~~
*/
public $items = array();
+ /**
+ * @var array list of HTML attributes for the item container tags. This will be overwritten
+ * by the "options" set in individual [[items]]. The following special options are recognized:
+ *
+ * - tag: string, defaults to "div", the tag name of the item container tags.
+ */
+ public $itemOptions = array();
+ /**
+ * @var array list of HTML attributes for the item header container tags. This will be overwritten
+ * by the "headerOptions" set in individual [[items]]. The following special options are recognized:
+ *
+ * - tag: string, defaults to "h3", the tag name of the item container tags.
+ */
+ public $headerOptions = array();
/**
@@ -64,20 +97,22 @@ class Accordion extends Widget
*/
public function run()
{
- echo Html::beginTag('div', $this->options) . "\n";
- echo $this->renderSections() . "\n";
- echo Html::endTag('div') . "\n";
+ $options = $this->options;
+ $tag = ArrayHelper::remove($options, 'tag', 'div');
+ echo Html::beginTag($tag, $options) . "\n";
+ echo $this->renderItems() . "\n";
+ echo Html::endTag($tag) . "\n";
$this->registerWidget('accordion');
}
/**
- * Renders collapsible sections as specified on [[items]].
+ * Renders collapsible items as specified on [[items]].
* @return string the rendering result.
* @throws InvalidConfigException.
*/
- protected function renderSections()
+ protected function renderItems()
{
- $sections = array();
+ $items = array();
foreach ($this->items as $item) {
if (!isset($item['header'])) {
throw new InvalidConfigException("The 'header' option is required.");
@@ -85,12 +120,14 @@ class Accordion extends Widget
if (!isset($item['content'])) {
throw new InvalidConfigException("The 'content' option is required.");
}
- $headerOptions = ArrayHelper::getValue($item, 'headerOptions', array());
- $sections[] = Html::tag('h3', $item['header'], $headerOptions);
- $options = ArrayHelper::getValue($item, 'options', array());
- $sections[] = Html::tag('div', $item['content'], $options);;
+ $headerOptions = array_merge($this->headerOptions, ArrayHelper::getValue($item, 'headerOptions', array()));
+ $headerTag = ArrayHelper::remove($headerOptions, 'tag', 'h3');
+ $items[] = Html::tag($headerTag, $item['header'], $headerOptions);
+ $options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', array()));
+ $tag = ArrayHelper::remove($options, 'tag', 'div');
+ $items[] = Html::tag($tag, $item['content'], $options);;
}
- return implode("\n", $sections);
+ return implode("\n", $items);
}
}
diff --git a/framework/yii/jui/AutoComplete.php b/framework/yii/jui/AutoComplete.php
index f5bbae9..44ca23d 100644
--- a/framework/yii/jui/AutoComplete.php
+++ b/framework/yii/jui/AutoComplete.php
@@ -8,8 +8,6 @@
namespace yii\jui;
use Yii;
-use yii\base\InvalidConfigException;
-use yii\base\Model;
use yii\helpers\Html;
/**
@@ -42,51 +40,27 @@ use yii\helpers\Html;
* @author Alexander Kochetov
* @since 2.0
*/
-class AutoComplete extends Widget
+class AutoComplete extends InputWidget
{
/**
- * @var \yii\base\Model the data model that this widget is associated with.
- */
- public $model;
- /**
- * @var string the model attribute that this widget is associated with.
- */
- public $attribute;
- /**
- * @var string the input name. This must be set if [[model]] and [[attribute]] are not set.
- */
- public $name;
- /**
- * @var string the input value.
- */
- public $value;
-
-
- /**
* Renders the widget.
*/
public function run()
{
- echo $this->renderField();
+ echo $this->renderWidget();
$this->registerWidget('autocomplete');
}
/**
- * Renders the AutoComplete field. If [[model]] has been specified then it will render an active field.
- * If [[model]] is null or not from an [[Model]] instance, then the field will be rendered according to
- * the [[name]] attribute.
+ * Renders the AutoComplete widget.
* @return string the rendering result.
- * @throws InvalidConfigException when none of the required attributes are set to render the textInput.
- * That is, if [[model]] and [[attribute]] are not set, then [[name]] is required.
*/
- public function renderField()
+ public function renderWidget()
{
- if ($this->model instanceof Model && $this->attribute !== null) {
+ if ($this->hasModel()) {
return Html::activeTextInput($this->model, $this->attribute, $this->options);
- } elseif ($this->name !== null) {
- return Html::textInput($this->name, $this->value, $this->options);
} else {
- throw new InvalidConfigException("Either 'name' or 'model' and 'attribute' properties must be specified.");
+ return Html::textInput($this->name, $this->value, $this->options);
}
}
}
diff --git a/framework/yii/jui/DatePicker.php b/framework/yii/jui/DatePicker.php
new file mode 100644
index 0000000..1138b73
--- /dev/null
+++ b/framework/yii/jui/DatePicker.php
@@ -0,0 +1,99 @@
+ 'ru',
+ * 'model' => $model,
+ * 'attribute' => 'country',
+ * 'clientOptions' => array(
+ * 'dateFormat' => 'yy-mm-dd',
+ * ),
+ * ));
+ * ```
+ *
+ * The following example will use the name property instead:
+ *
+ * ```php
+ * echo DatePicker::widget(array(
+ * 'language' => 'ru',
+ * 'name' => 'country',
+ * 'clientOptions' => array(
+ * 'dateFormat' => 'yy-mm-dd',
+ * ),
+ * ));
+ *```
+ *
+ * @see http://api.jqueryui.com/datepicker/
+ * @author Alexander Kochetov
+ * @since 2.0
+ */
+class DatePicker extends InputWidget
+{
+ /**
+ * @var string the locale ID (eg 'fr', 'de') for the language to be used by the date picker.
+ * If this property set to false, I18N will not be involved. That is, the date picker will show in English.
+ */
+ public $language = false;
+ /**
+ * @var boolean If true, shows the widget as an inline calendar and the input as a hidden field.
+ */
+ public $inline = false;
+
+
+ /**
+ * Renders the widget.
+ */
+ public function run()
+ {
+ echo $this->renderWidget() . "\n";
+ $this->registerWidget('datepicker');
+ if ($this->language !== false) {
+ $this->getView()->registerAssetBundle("yii/jui/datepicker/i18n/$this->language");
+ }
+ }
+
+ /**
+ * Renders the DatePicker widget.
+ * @return string the rendering result.
+ */
+ protected function renderWidget()
+ {
+ $contents = array();
+
+ if ($this->inline === false) {
+ if ($this->hasModel()) {
+ $contents[] = Html::activeTextInput($this->model, $this->attribute, $this->options);
+ } else {
+ $contents[] = Html::textInput($this->name, $this->value, $this->options);
+ }
+ } else {
+ if ($this->hasModel()) {
+ $contents[] = Html::activeHiddenInput($this->model, $this->attribute, $this->options);
+ $this->clientOptions['defaultDate'] = $this->model->{$this->attribute};
+ } else {
+ $contents[] = Html::hiddenInput($this->name, $this->value, $this->options);
+ $this->clientOptions['defaultDate'] = $this->value;
+ }
+ $this->clientOptions['altField'] = '#' . $this->options['id'];
+ $this->options['id'] .= '-container';
+ $contents[] = Html::tag('div', null, $this->options);
+ }
+
+ return implode("\n", $contents);
+ }
+}
diff --git a/framework/yii/jui/Dialog.php b/framework/yii/jui/Dialog.php
new file mode 100644
index 0000000..f4b3b12
--- /dev/null
+++ b/framework/yii/jui/Dialog.php
@@ -0,0 +1,52 @@
+ array(
+ * 'modal' => true,
+ * ),
+ * ));
+ *
+ * echo 'Dialog contents here...';
+ *
+ * Dialog::end();
+ * ```
+ *
+ * @see http://api.jqueryui.com/dialog/
+ * @author Alexander Kochetov
+ * @since 2.0
+ */
+class Dialog extends Widget
+{
+ /**
+ * Initializes the widget.
+ */
+ public function init()
+ {
+ parent::init();
+ echo Html::beginTag('div', $this->options) . "\n";
+ }
+
+ /**
+ * Renders the widget.
+ */
+ public function run()
+ {
+ echo Html::endTag('div') . "\n";
+ $this->registerWidget('dialog');
+ }
+}
diff --git a/framework/yii/jui/InputWidget.php b/framework/yii/jui/InputWidget.php
new file mode 100644
index 0000000..e100d6c
--- /dev/null
+++ b/framework/yii/jui/InputWidget.php
@@ -0,0 +1,59 @@
+
+ * @since 2.0
+ */
+class InputWidget extends Widget
+{
+ /**
+ * @var Model the data model that this widget is associated with.
+ */
+ public $model;
+ /**
+ * @var string the model attribute that this widget is associated with.
+ */
+ public $attribute;
+ /**
+ * @var string the input name. This must be set if [[model]] and [[attribute]] are not set.
+ */
+ public $name;
+ /**
+ * @var string the input value.
+ */
+ public $value;
+
+
+ /**
+ * Initializes the widget.
+ * If you override this method, make sure you call the parent implementation first.
+ */
+ public function init()
+ {
+ if (!$this->hasModel() && $this->name === null) {
+ throw new InvalidConfigException("Either 'name' or 'model' and 'attribute' properties must be specified.");
+ }
+ parent::init();
+ }
+
+ /**
+ * @return boolean whether this widget is associated with a data model.
+ */
+ protected function hasModel()
+ {
+ return $this->model instanceof Model && $this->attribute !== null;
+ }
+}
diff --git a/framework/yii/jui/Menu.php b/framework/yii/jui/Menu.php
index 0a84acf..d4e390c 100644
--- a/framework/yii/jui/Menu.php
+++ b/framework/yii/jui/Menu.php
@@ -8,7 +8,6 @@
namespace yii\jui;
use Yii;
-use yii\base\View;
use yii\helpers\Json;
diff --git a/framework/yii/jui/ProgressBar.php b/framework/yii/jui/ProgressBar.php
new file mode 100644
index 0000000..a7697e5
--- /dev/null
+++ b/framework/yii/jui/ProgressBar.php
@@ -0,0 +1,62 @@
+ array(
+ * 'value' => 75,
+ * ),
+ * ));
+ * ```
+ *
+ * The following example will show the content enclosed between the [[begin()]]
+ * and [[end()]] calls within the widget container:
+ *
+ * ~~~php
+ * ProgressBar::widget(array(
+ * 'clientOptions' => array(
+ * 'value' => 75,
+ * ),
+ * ));
+ *
+ * echo 'Loading...';
+ *
+ * ProgressBar::end();
+ * ~~~
+ * @see http://api.jqueryui.com/progressbar/
+ * @author Alexander Kochetov
+ * @since 2.0
+ */
+class ProgressBar extends Widget
+{
+ /**
+ * Initializes the widget.
+ */
+ public function init()
+ {
+ parent::init();
+ echo Html::beginTag('div', $this->options) . "\n";
+ }
+
+ /**
+ * Renders the widget.
+ */
+ public function run()
+ {
+ echo Html::endTag('div') . "\n";
+ $this->registerWidget('progressbar');
+ }
+}
diff --git a/framework/yii/jui/Sortable.php b/framework/yii/jui/Sortable.php
new file mode 100644
index 0000000..8524b5b
--- /dev/null
+++ b/framework/yii/jui/Sortable.php
@@ -0,0 +1,116 @@
+ array(
+ * 'Item 1',
+ * array(
+ * 'content' => 'Item2',
+ * ),
+ * array(
+ * 'content' => 'Item3',
+ * 'options' => array(
+ * 'tag' => 'li',
+ * ),
+ * ),
+ * ),
+ * 'options' => array(
+ * 'tag' => 'ul',
+ * ),
+ * 'itemOptions' => array(
+ * 'tag' => 'li',
+ * ),
+ * 'clientOptions' => array(
+ * 'cursor' => 'move',
+ * ),
+ * ));
+ * ```
+ *
+ * @see http://api.jqueryui.com/sortable/
+ * @author Alexander Kochetov
+ * @since 2.0
+ */
+class Sortable extends Widget
+{
+ /**
+ * @var array the HTML attributes for the widget container tag. The following special options are recognized:
+ *
+ * - tag: string, defaults to "ul", the tag name of the container tag of this widget
+ */
+ public $options = array();
+ /**
+ * @var array list of sortable items. Each item can be a string representing the item content
+ * or an array of the following structure:
+ *
+ * ~~~
+ * array(
+ * 'content' => 'item content',
+ * // the HTML attributes of the item container tag. This will overwrite "itemOptions".
+ * 'options' => array(),
+ * )
+ * ~~~
+ */
+ public $items = array();
+ /**
+ * @var array list of HTML attributes for the item container tags. This will be overwritten
+ * by the "options" set in individual [[items]]. The following special options are recognized:
+ *
+ * - tag: string, defaults to "li", the tag name of the item container tags.
+ */
+ public $itemOptions = array();
+
+
+ /**
+ * Renders the widget.
+ */
+ public function run()
+ {
+ $options = $this->options;
+ $tag = ArrayHelper::remove($options, 'tag', 'ul');
+ echo Html::beginTag($tag, $options) . "\n";
+ echo $this->renderItems() . "\n";
+ echo Html::endTag($tag) . "\n";
+ $this->registerWidget('sortable', false);
+ }
+
+ /**
+ * Renders sortable items as specified on [[items]].
+ * @return string the rendering result.
+ * @throws InvalidConfigException.
+ */
+ public function renderItems()
+ {
+ $items = array();
+ foreach ($this->items as $item) {
+ $options = $this->itemOptions;
+ $tag = ArrayHelper::remove($options, 'tag', 'li');
+ if (is_array($item)) {
+ if (!isset($item['content'])) {
+ throw new InvalidConfigException("The 'content' option is required.");
+ }
+ $options = array_merge($options, ArrayHelper::getValue($item, 'options', array()));
+ $tag = ArrayHelper::remove($options, 'tag', $tag);
+ $items[] = Html::tag($tag, $item['content'], $options);
+ } else {
+ $items[] = Html::tag($tag, $item, $options);
+ }
+ }
+ return implode("\n", $items);
+ }
+}
diff --git a/framework/yii/jui/Tabs.php b/framework/yii/jui/Tabs.php
index ca0b3da..052ffe7 100644
--- a/framework/yii/jui/Tabs.php
+++ b/framework/yii/jui/Tabs.php
@@ -8,7 +8,7 @@
namespace yii\jui;
use yii\base\InvalidConfigException;
-use yii\helpers\base\ArrayHelper;
+use yii\helpers\ArrayHelper;
use yii\helpers\Html;
/**
diff --git a/framework/yii/jui/Widget.php b/framework/yii/jui/Widget.php
index f6efd91..d34a8bd 100644
--- a/framework/yii/jui/Widget.php
+++ b/framework/yii/jui/Widget.php
@@ -8,7 +8,6 @@
namespace yii\jui;
use Yii;
-use yii\base\View;
use yii\helpers\Json;
@@ -59,13 +58,16 @@ class Widget extends \yii\base\Widget
/**
* Registers a specific jQuery UI widget and the related events
* @param string $name the name of the jQuery UI widget
+ * @param boolean $registerTheme whether register theme bundle
*/
- protected function registerWidget($name)
+ protected function registerWidget($name, $registerTheme = true)
{
$id = $this->options['id'];
$view = $this->getView();
$view->registerAssetBundle("yii/jui/$name");
- $view->registerAssetBundle(static::$theme . "/$name");
+ if ($registerTheme) {
+ $view->registerAssetBundle(static::$theme . "/$name");
+ }
if ($this->clientOptions !== false) {
$options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions);
diff --git a/framework/yii/jui/assets.php b/framework/yii/jui/assets.php
index 285026c..d2d8f7c 100644
--- a/framework/yii/jui/assets.php
+++ b/framework/yii/jui/assets.php
@@ -559,7 +559,7 @@ return array(
'js' => array(
'jquery.ui.dialog.js',
),
- 'depends' => array('yii/jui/core', 'yii/jui/widget', 'yii/jui/button', 'yii/jui/draggable', 'yii/jui/mouse', 'yii/jui/position', 'yii/jui/resizeable', 'yii/jui/effect/all'),
+ 'depends' => array('yii/jui/core', 'yii/jui/widget', 'yii/jui/button', 'yii/jui/draggable', 'yii/jui/mouse', 'yii/jui/position', 'yii/jui/resizable', 'yii/jui/effect/all'),
),
'yii/jui/draggable' => array(
'sourcePath' => __DIR__ . '/assets',
@@ -803,7 +803,7 @@ return array(
'css' => array(
'themes/base/jquery.ui.dialog.css',
),
- 'depends' => array('yii/jui/theme/base/core', 'yii/jui/theme/base/button', 'yii/jui/theme/base/resizeable'),
+ 'depends' => array('yii/jui/theme/base/core', 'yii/jui/theme/base/button', 'yii/jui/theme/base/resizable'),
),
'yii/jui/theme/base/menu' => array(
'sourcePath' => __DIR__ . '/assets',
diff --git a/framework/yii/rbac/DbManager.php b/framework/yii/rbac/DbManager.php
index 719ffa8..b7a5d4e 100644
--- a/framework/yii/rbac/DbManager.php
+++ b/framework/yii/rbac/DbManager.php
@@ -160,7 +160,8 @@ class DbManager extends Manager
throw new InvalidCallException("Cannot add '$childName' as a child of '$itemName'. A loop has been detected.");
}
$this->db->createCommand()
- ->insert($this->itemChildTable, array('parent' => $itemName, 'child' => $childName));
+ ->insert($this->itemChildTable, array('parent' => $itemName, 'child' => $childName))
+ ->execute();
return true;
} else {
throw new Exception("Either '$itemName' or '$childName' does not exist.");
@@ -177,7 +178,8 @@ class DbManager extends Manager
public function removeItemChild($itemName, $childName)
{
return $this->db->createCommand()
- ->delete($this->itemChildTable, array('parent' => $itemName, 'child' => $childName)) > 0;
+ ->delete($this->itemChildTable, array('parent' => $itemName, 'child' => $childName))
+ ->execute() > 0;
}
/**
@@ -248,7 +250,8 @@ class DbManager extends Manager
'item_name' => $itemName,
'biz_rule' => $bizRule,
'data' => serialize($data),
- ));
+ ))
+ ->execute();
return new Assignment(array(
'manager' => $this,
'userId' => $userId,
@@ -267,7 +270,8 @@ class DbManager extends Manager
public function revoke($userId, $itemName)
{
return $this->db->createCommand()
- ->delete($this->assignmentTable, array('user_id' => $userId, 'item_name' => $itemName)) > 0;
+ ->delete($this->assignmentTable, array('user_id' => $userId, 'item_name' => $itemName))
+ ->execute() > 0;
}
/**
@@ -276,7 +280,7 @@ class DbManager extends Manager
* @param string $itemName the item name
* @return boolean whether the item has been assigned to the user.
*/
- public function isAssigned($itemName, $userId)
+ public function isAssigned($userId, $itemName)
{
$query = new Query;
return $query->select(array('item_name'))
@@ -358,7 +362,8 @@ class DbManager extends Manager
), array(
'user_id' => $assignment->userId,
'item_name' => $assignment->itemName,
- ));
+ ))
+ ->execute();
}
/**
@@ -431,7 +436,8 @@ class DbManager extends Manager
'description' => $description,
'biz_rule' => $bizRule,
'data' => serialize($data),
- ));
+ ))
+ ->execute();
return new Item(array(
'manager' => $this,
'name' => $name,
@@ -451,12 +457,15 @@ class DbManager extends Manager
{
if ($this->usingSqlite()) {
$this->db->createCommand()
- ->delete($this->itemChildTable, array('or', 'parent=:name', 'child=:name'), array(':name' => $name));
+ ->delete($this->itemChildTable, array('or', 'parent=:name', 'child=:name'), array(':name' => $name))
+ ->execute();
$this->db->createCommand()
- ->delete($this->assignmentTable, array('item_name' => $name));
+ ->delete($this->assignmentTable, array('item_name' => $name))
+ ->execute();
}
return $this->db->createCommand()
- ->delete($this->itemTable, array('name' => $name)) > 0;
+ ->delete($this->itemTable, array('name' => $name))
+ ->execute() > 0;
}
/**
@@ -497,11 +506,14 @@ class DbManager extends Manager
{
if ($this->usingSqlite() && $oldName !== null && $item->getName() !== $oldName) {
$this->db->createCommand()
- ->update($this->itemChildTable, array('parent' => $item->getName()), array('parent' => $oldName));
+ ->update($this->itemChildTable, array('parent' => $item->getName()), array('parent' => $oldName))
+ ->execute();
$this->db->createCommand()
- ->update($this->itemChildTable, array('child' => $item->getName()), array('child' => $oldName));
+ ->update($this->itemChildTable, array('child' => $item->getName()), array('child' => $oldName))
+ ->execute();
$this->db->createCommand()
- ->update($this->assignmentTable, array('item_name' => $item->getName()), array('item_name' => $oldName));
+ ->update($this->assignmentTable, array('item_name' => $item->getName()), array('item_name' => $oldName))
+ ->execute();
}
$this->db->createCommand()
@@ -513,7 +525,8 @@ class DbManager extends Manager
'data' => serialize($item->data),
), array(
'name' => $oldName === null ? $item->getName() : $oldName,
- ));
+ ))
+ ->execute();
}
/**
@@ -529,8 +542,8 @@ class DbManager extends Manager
public function clearAll()
{
$this->clearAssignments();
- $this->db->createCommand()->delete($this->itemChildTable);
- $this->db->createCommand()->delete($this->itemTable);
+ $this->db->createCommand()->delete($this->itemChildTable)->execute();
+ $this->db->createCommand()->delete($this->itemTable)->execute();
}
/**
@@ -538,7 +551,7 @@ class DbManager extends Manager
*/
public function clearAssignments()
{
- $this->db->createCommand()->delete($this->assignmentTable);
+ $this->db->createCommand()->delete($this->assignmentTable)->execute();
}
/**
diff --git a/framework/yii/requirements/views/web/index.php b/framework/yii/requirements/views/web/index.php
index 6cd2594..1887f8b 100644
--- a/framework/yii/requirements/views/web/index.php
+++ b/framework/yii/requirements/views/web/index.php
@@ -56,8 +56,8 @@
-
-
+
+
@@ -79,4 +79,4 @@