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 @@