diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d908ff0..b092468 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,4 +3,5 @@ Contributing to Yii2 - [Report an issue](docs/internals/report-an-issue.md) - [Translate documentation or messages](docs/internals/translation-workflow.md) -- [Contribute to the core code or fix bugs](docs/internals/getting-started.md) +- [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/) +- [Contribute to the core code or fix bugs](docs/internals/git-workflow.md) diff --git a/README.md b/README.md index a8dd733..8e6cf20 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,8 @@ DIRECTORY STRUCTURE ------------------- ``` -apps/ ready-to-use application templates - advanced/ a template suitable for building sophisticated Web applications - basic/ a template suitable for building simple Web applications - benchmark/ an application demonstrating the performance of Yii build/ internally used build tools docs/ documentation -extensions/ extensions framework/ core framework code tests/ tests of the core framework code ``` @@ -47,7 +42,7 @@ Yii 2.0 has a [Definitive Guide](http://www.yiiframework.com/doc-2.0/guide-index a [Class Reference](http://www.yiiframework.com/doc-2.0/index.html) which cover every detail of Yii. There is also a [PDF version](http://stuff.cebe.cc/yii2-guide.pdf) of the Definitive Guide -and a [Definitive Guide Mirror](http://stuff.cebe.cc/yii2docs/) which update every 15 minutes. +and a [Definitive Guide Mirror](http://stuff.cebe.cc/yii2docs/) which is updated every 15 minutes. For 1.1 users, you may refer to [Upgrading from Yii 1.1](docs/guide/intro-upgrade-from-v1.md) to have a general idea of what has changed in 2.0. @@ -60,11 +55,8 @@ HOW TO PARTICIPATE You may participate in the following ways: -* [Report issues](https://github.com/yiisoft/yii2/issues) -* [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-design-discussions-for-yii-20/) -* Fix issues, develop features, write/polish documentation - - Before you start, please adopt an existing issue (labelled with "ready for adoption") or start a new one to avoid duplicated efforts. - - Please submit a merge request after you finish development. - -In order to make it easier we've prepared [special `yii2-dev` Composer package](https://github.com/yiisoft/yii2/blob/master/docs/internals/getting-started.md). +- [Report an issue](docs/internals/report-an-issue.md) +- [Translate documentation or messages](docs/internals/translation-workflow.md) +- [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/) +- [Contribute to the core code or fix bugs](docs/internals/git-workflow.md) diff --git a/apps/advanced/.bowerrc b/apps/advanced/.bowerrc deleted file mode 100644 index 1669168..0000000 --- a/apps/advanced/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory" : "vendor/bower" -} diff --git a/apps/advanced/.gitignore b/apps/advanced/.gitignore deleted file mode 100644 index 346d3b2..0000000 --- a/apps/advanced/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# yii console command -/yii - -# phpstorm project files -.idea - -# netbeans project files -nbproject - -# zend studio for eclipse project files -.buildpath -.project -.settings - -# windows thumbnail cache -Thumbs.db - -# composer vendor dir -/vendor - -# composer itself is not needed -composer.phar - -# Mac DS_Store Files -.DS_Store - -# phpunit itself is not needed -phpunit.phar -# local phpunit config -/phpunit.xml diff --git a/apps/advanced/LICENSE.md b/apps/advanced/LICENSE.md deleted file mode 100644 index e98f03d..0000000 --- a/apps/advanced/LICENSE.md +++ /dev/null @@ -1,32 +0,0 @@ -The Yii framework is free software. It is released under the terms of -the following BSD License. - -Copyright © 2008 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. diff --git a/apps/advanced/README.md b/apps/advanced/README.md deleted file mode 100644 index 549e378..0000000 --- a/apps/advanced/README.md +++ /dev/null @@ -1,97 +0,0 @@ -Yii 2 Advanced Application Template -=================================== - -Yii 2 Advanced Application Template is a skeleton Yii 2 application best for -developing complex Web applications with multiple tiers. - -The template includes three tiers: front end, back end, and console, each of which -is a separate Yii application. - -The template is designed to work in a team development environment. It supports -deploying the application in different environments. - - -DIRECTORY STRUCTURE -------------------- - -``` -common - config/ contains shared configurations - mail/ contains view files for e-mails - models/ contains model classes used in both backend 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 -backend - assets/ contains application assets such as JavaScript and CSS - config/ contains backend configurations - controllers/ contains Web controller classes - models/ contains backend-specific model classes - runtime/ contains files generated during runtime - views/ contains view files for the Web application - web/ 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 - web/ contains the entry script and Web resources - widgets/ contains frontend widgets -vendor/ contains dependent 3rd-party packages -environments/ contains environment-based overrides -tests contains various tests for the advanced application - codeception/ contains tests developed with Codeception PHP Testing Framework -``` - - -REQUIREMENTS ------------- - -The minimum requirement by this application template that your Web server supports PHP 5.4.0. - - -INSTALLATION ------------- - -### Install from an Archive File - -Extract the archive file downloaded from [yiiframework.com](http://www.yiiframework.com/download/) to -a directory named `advanced` that is directly under the Web root. - -Then follow the instructions given in "GETTING STARTED". - - -### Install via Composer - -If you do not have [Composer](http://getcomposer.org/), you may install it by following the instructions -at [getcomposer.org](http://getcomposer.org/doc/00-intro.md#installation-nix). - -You can then install the application using the following command: - -~~~ -php composer.phar global require "fxp/composer-asset-plugin:1.0.0-beta4" -php composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-advanced advanced -~~~ - - -GETTING STARTED ---------------- - -After you install the application, you have to conduct the following steps to initialize -the installed application. You only need to do these once for all. - -1. Run command `init` to initialize the application with a specific environment. -2. Create a new database and adjust the `components['db']` configuration in `common/config/main-local.php` accordingly. -3. Apply migrations with console command `yii migrate`. This will create tables needed for the application to work. -4. Set document roots of your Web server: - -- for frontend `/path/to/yii-application/frontend/web/` and using the URL `http://frontend/` -- for backend `/path/to/yii-application/backend/web/` and using the URL `http://backend/` - -To login into the application, you need to first sign up, with any of your email address, username and password. -Then, you can login into the application with same email address and password at any time. diff --git a/apps/advanced/backend/assets/AppAsset.php b/apps/advanced/backend/assets/AppAsset.php deleted file mode 100644 index c262142..0000000 --- a/apps/advanced/backend/assets/AppAsset.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @since 2.0 - */ -class AppAsset extends AssetBundle -{ - public $basePath = '@webroot'; - public $baseUrl = '@web'; - public $css = [ - 'css/site.css', - ]; - public $js = [ - ]; - public $depends = [ - 'yii\web\YiiAsset', - 'yii\bootstrap\BootstrapAsset', - ]; -} diff --git a/apps/advanced/backend/config/.gitignore b/apps/advanced/backend/config/.gitignore deleted file mode 100644 index 20da318..0000000 --- a/apps/advanced/backend/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -main-local.php -params-local.php \ No newline at end of file diff --git a/apps/advanced/backend/config/bootstrap.php b/apps/advanced/backend/config/bootstrap.php deleted file mode 100644 index b3d9bbc..0000000 --- a/apps/advanced/backend/config/bootstrap.php +++ /dev/null @@ -1 +0,0 @@ - 'app-backend', - 'basePath' => dirname(__DIR__), - 'controllerNamespace' => 'backend\controllers', - 'bootstrap' => ['log'], - 'modules' => [], - 'components' => [ - 'user' => [ - 'identityClass' => 'common\models\User', - 'enableAutoLogin' => true, - ], - 'log' => [ - 'traceLevel' => YII_DEBUG ? 3 : 0, - 'targets' => [ - [ - 'class' => 'yii\log\FileTarget', - 'levels' => ['error', 'warning'], - ], - ], - ], - 'errorHandler' => [ - 'errorAction' => 'site/error', - ], - ], - 'params' => $params, -]; diff --git a/apps/advanced/backend/config/params.php b/apps/advanced/backend/config/params.php deleted file mode 100644 index 7f754b9..0000000 --- a/apps/advanced/backend/config/params.php +++ /dev/null @@ -1,4 +0,0 @@ - 'admin@example.com', -]; diff --git a/apps/advanced/backend/controllers/SiteController.php b/apps/advanced/backend/controllers/SiteController.php deleted file mode 100644 index db3259a..0000000 --- a/apps/advanced/backend/controllers/SiteController.php +++ /dev/null @@ -1,83 +0,0 @@ - [ - 'class' => AccessControl::className(), - 'rules' => [ - [ - 'actions' => ['login', 'error'], - 'allow' => true, - ], - [ - 'actions' => ['logout', 'index'], - 'allow' => true, - 'roles' => ['@'], - ], - ], - ], - 'verbs' => [ - 'class' => VerbFilter::className(), - 'actions' => [ - 'logout' => ['post'], - ], - ], - ]; - } - - /** - * @inheritdoc - */ - public function actions() - { - return [ - 'error' => [ - 'class' => 'yii\web\ErrorAction', - ], - ]; - } - - public function actionIndex() - { - return $this->render('index'); - } - - public function actionLogin() - { - if (!\Yii::$app->user->isGuest) { - return $this->goHome(); - } - - $model = new LoginForm(); - if ($model->load(Yii::$app->request->post()) && $model->login()) { - return $this->goBack(); - } else { - return $this->render('login', [ - 'model' => $model, - ]); - } - } - - public function actionLogout() - { - Yii::$app->user->logout(); - - return $this->goHome(); - } -} diff --git a/apps/advanced/backend/models/.gitkeep b/apps/advanced/backend/models/.gitkeep deleted file mode 100644 index 72e8ffc..0000000 --- a/apps/advanced/backend/models/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/apps/advanced/backend/views/layouts/main.php b/apps/advanced/backend/views/layouts/main.php deleted file mode 100644 index e3f294f..0000000 --- a/apps/advanced/backend/views/layouts/main.php +++ /dev/null @@ -1,71 +0,0 @@ - -beginPage() ?> - - - - - - - <?= Html::encode($this->title) ?> - head() ?> - - - beginBody() ?> -
- 'My Company', - 'brandUrl' => Yii::$app->homeUrl, - 'options' => [ - 'class' => 'navbar-inverse navbar-fixed-top', - ], - ]); - $menuItems = [ - ['label' => 'Home', 'url' => ['/site/index']], - ]; - if (Yii::$app->user->isGuest) { - $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']]; - } else { - $menuItems[] = [ - 'label' => 'Logout (' . Yii::$app->user->identity->username . ')', - 'url' => ['/site/logout'], - 'linkOptions' => ['data-method' => 'post'] - ]; - } - echo Nav::widget([ - 'options' => ['class' => 'navbar-nav navbar-right'], - 'items' => $menuItems, - ]); - NavBar::end(); - ?> - -
- isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], - ]) ?> - -
-
- - - - endBody() ?> - - -endPage() ?> diff --git a/apps/advanced/backend/views/site/error.php b/apps/advanced/backend/views/site/error.php deleted file mode 100644 index b9812c4..0000000 --- a/apps/advanced/backend/views/site/error.php +++ /dev/null @@ -1,27 +0,0 @@ -title = $name; -?> -
- -

title) ?>

- -
- -
- -

- The above error occurred while the Web server was processing your request. -

-

- Please contact us if you think this is a server error. Thank you. -

- -
diff --git a/apps/advanced/backend/views/site/index.php b/apps/advanced/backend/views/site/index.php deleted file mode 100644 index 0159bef..0000000 --- a/apps/advanced/backend/views/site/index.php +++ /dev/null @@ -1,52 +0,0 @@ -title = 'My Yii Application'; -?> -
- -
-

Congratulations!

- -

You have successfully created your Yii-powered application.

- -

Get started with Yii

-
- -
- -
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Documentation »

-
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Forum »

-
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Extensions »

-
-
- -
-
diff --git a/apps/advanced/backend/views/site/login.php b/apps/advanced/backend/views/site/login.php deleted file mode 100644 index a4041a9..0000000 --- a/apps/advanced/backend/views/site/login.php +++ /dev/null @@ -1,29 +0,0 @@ -title = 'Login'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

Please fill out the following fields to login:

- -
-
- 'login-form']); ?> - field($model, 'username') ?> - field($model, 'password')->passwordInput() ?> - field($model, 'rememberMe')->checkbox() ?> -
- 'btn btn-primary', 'name' => 'login-button']) ?> -
- -
-
-
diff --git a/apps/advanced/backend/web/.gitignore b/apps/advanced/backend/web/.gitignore deleted file mode 100644 index 25c74e6..0000000 --- a/apps/advanced/backend/web/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/index.php -/index-test.php diff --git a/apps/advanced/backend/web/assets/.gitignore b/apps/advanced/backend/web/assets/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/apps/advanced/backend/web/assets/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/apps/advanced/backend/web/css/site.css b/apps/advanced/backend/web/css/site.css deleted file mode 100644 index 698be70..0000000 --- a/apps/advanced/backend/web/css/site.css +++ /dev/null @@ -1,91 +0,0 @@ -html, -body { - height: 100%; -} - -.wrap { - min-height: 100%; - height: auto; - margin: 0 auto -60px; - padding: 0 0 60px; -} - -.wrap > .container { - padding: 70px 15px 20px; -} - -.footer { - height: 60px; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - padding-top: 20px; -} - -.jumbotron { - text-align: center; - background-color: transparent; -} - -.jumbotron .btn { - font-size: 21px; - padding: 14px 24px; -} - -.not-set { - color: #c55; - font-style: italic; -} - -/* add sorting icons to gridview sort links */ -a.asc:after, a.desc:after { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: normal; - line-height: 1; - padding-left: 5px; -} - -a.asc:after { - content: /*"\e113"*/ "\e151"; -} - -a.desc:after { - content: /*"\e114"*/ "\e152"; -} - -.sort-numerical a.asc:after { - content: "\e153"; -} - -.sort-numerical a.desc:after { - content: "\e154"; -} - -.sort-ordinal a.asc:after { - content: "\e155"; -} - -.sort-ordinal a.desc:after { - content: "\e156"; -} - -.grid-view th { - white-space: nowrap; -} - -.hint-block { - display: block; - margin-top: 5px; - color: #999; -} - -.error-summary { - color: #a94442; - background: #fdf7f7; - border-left: 3px solid #eed3d7; - padding: 10px 20px; - margin: 0 0 15px 0; -} diff --git a/apps/advanced/backend/web/favicon.ico b/apps/advanced/backend/web/favicon.ico deleted file mode 100644 index 580ed73..0000000 Binary files a/apps/advanced/backend/web/favicon.ico and /dev/null differ diff --git a/apps/advanced/backend/web/robots.txt b/apps/advanced/backend/web/robots.txt deleted file mode 100644 index c6742d8..0000000 --- a/apps/advanced/backend/web/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-Agent: * -Disallow: / diff --git a/apps/advanced/common/config/.gitignore b/apps/advanced/common/config/.gitignore deleted file mode 100644 index 97c0f01..0000000 --- a/apps/advanced/common/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -main-local.php -params-local.php diff --git a/apps/advanced/common/config/bootstrap.php b/apps/advanced/common/config/bootstrap.php deleted file mode 100644 index ecc13e5..0000000 --- a/apps/advanced/common/config/bootstrap.php +++ /dev/null @@ -1,5 +0,0 @@ - dirname(dirname(__DIR__)) . '/vendor', - 'components' => [ - 'cache' => [ - 'class' => 'yii\caching\FileCache', - ], - ], -]; diff --git a/apps/advanced/common/config/params.php b/apps/advanced/common/config/params.php deleted file mode 100644 index 4ec9ba6..0000000 --- a/apps/advanced/common/config/params.php +++ /dev/null @@ -1,6 +0,0 @@ - 'admin@example.com', - 'supportEmail' => 'support@example.com', - 'user.passwordResetTokenExpire' => 3600, -]; diff --git a/apps/advanced/common/mail/layouts/html.php b/apps/advanced/common/mail/layouts/html.php deleted file mode 100644 index bddbc61..0000000 --- a/apps/advanced/common/mail/layouts/html.php +++ /dev/null @@ -1,22 +0,0 @@ - -beginPage() ?> - - - - - <?= Html::encode($this->title) ?> - head() ?> - - - beginBody() ?> - - endBody() ?> - - -endPage() ?> diff --git a/apps/advanced/common/mail/passwordResetToken.php b/apps/advanced/common/mail/passwordResetToken.php deleted file mode 100644 index 4093dc9..0000000 --- a/apps/advanced/common/mail/passwordResetToken.php +++ /dev/null @@ -1,14 +0,0 @@ -urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]); -?> - -Hello username) ?>, - -Follow the link below to reset your password: - - diff --git a/apps/advanced/common/models/LoginForm.php b/apps/advanced/common/models/LoginForm.php deleted file mode 100644 index 6ec31f2..0000000 --- a/apps/advanced/common/models/LoginForm.php +++ /dev/null @@ -1,78 +0,0 @@ -hasErrors()) { - $user = $this->getUser(); - if (!$user || !$user->validatePassword($this->password)) { - $this->addError($attribute, 'Incorrect username or password.'); - } - } - } - - /** - * Logs in a user using the provided username and password. - * - * @return boolean whether the user is logged in successfully - */ - public function login() - { - if ($this->validate()) { - return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); - } else { - return false; - } - } - - /** - * Finds user by [[username]] - * - * @return User|null - */ - public function getUser() - { - if ($this->_user === false) { - $this->_user = User::findByUsername($this->username); - } - - return $this->_user; - } -} diff --git a/apps/advanced/common/models/User.php b/apps/advanced/common/models/User.php deleted file mode 100644 index ace9324..0000000 --- a/apps/advanced/common/models/User.php +++ /dev/null @@ -1,193 +0,0 @@ - self::STATUS_ACTIVE], - ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]], - - ['role', 'default', 'value' => self::ROLE_USER], - ['role', 'in', 'range' => [self::ROLE_USER]], - ]; - } - - /** - * @inheritdoc - */ - public static function findIdentity($id) - { - return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); - } - - /** - * @inheritdoc - */ - public static function findIdentityByAccessToken($token, $type = null) - { - throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); - } - - /** - * Finds user by username - * - * @param string $username - * @return static|null - */ - public static function findByUsername($username) - { - return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); - } - - /** - * Finds user by password reset token - * - * @param string $token password reset token - * @return static|null - */ - public static function findByPasswordResetToken($token) - { - if (!static::isPasswordResetTokenValid($token)) { - return null; - } - - return static::findOne([ - 'password_reset_token' => $token, - 'status' => self::STATUS_ACTIVE, - ]); - } - - /** - * Finds out if password reset token is valid - * - * @param string $token password reset token - * @return boolean - */ - public static function isPasswordResetTokenValid($token) - { - if (empty($token)) { - return false; - } - $expire = Yii::$app->params['user.passwordResetTokenExpire']; - $parts = explode('_', $token); - $timestamp = (int) end($parts); - return $timestamp + $expire >= time(); - } - - /** - * @inheritdoc - */ - public function getId() - { - return $this->getPrimaryKey(); - } - - /** - * @inheritdoc - */ - public function getAuthKey() - { - return $this->auth_key; - } - - /** - * @inheritdoc - */ - public function validateAuthKey($authKey) - { - return $this->getAuthKey() === $authKey; - } - - /** - * Validates password - * - * @param string $password password to validate - * @return boolean if password provided is valid for current user - */ - public function validatePassword($password) - { - return Yii::$app->security->validatePassword($password, $this->password_hash); - } - - /** - * Generates password hash from password and sets it to the model - * - * @param string $password - */ - public function setPassword($password) - { - $this->password_hash = Yii::$app->security->generatePasswordHash($password); - } - - /** - * Generates "remember me" authentication key - */ - public function generateAuthKey() - { - $this->auth_key = Yii::$app->security->generateRandomString(); - } - - /** - * Generates new password reset token - */ - public function generatePasswordResetToken() - { - $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); - } - - /** - * Removes password reset token - */ - public function removePasswordResetToken() - { - $this->password_reset_token = null; - } -} diff --git a/apps/advanced/composer.json b/apps/advanced/composer.json deleted file mode 100644 index fd1c589..0000000 --- a/apps/advanced/composer.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "yiisoft/yii2-app-advanced", - "description": "Yii 2 Advanced Application Template", - "keywords": ["yii2", "framework", "advanced", "application template"], - "homepage": "http://www.yiiframework.com/", - "type": "project", - "license": "BSD-3-Clause", - "support": { - "issues": "https://github.com/yiisoft/yii2/issues?state=open", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", - "source": "https://github.com/yiisoft/yii2" - }, - "minimum-stability": "stable", - "require": { - "php": ">=5.4.0", - "yiisoft/yii2": "*", - "yiisoft/yii2-bootstrap": "*", - "yiisoft/yii2-swiftmailer": "*" - }, - "require-dev": { - "yiisoft/yii2-codeception": "*", - "yiisoft/yii2-debug": "*", - "yiisoft/yii2-gii": "*", - "yiisoft/yii2-faker": "*" - }, - "config": { - "process-timeout": 1800 - }, - "extra": { - "asset-installer-paths": { - "npm-asset-library": "vendor/npm", - "bower-asset-library": "vendor/bower" - } - } -} diff --git a/apps/advanced/console/config/.gitignore b/apps/advanced/console/config/.gitignore deleted file mode 100644 index 20da318..0000000 --- a/apps/advanced/console/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -main-local.php -params-local.php \ No newline at end of file diff --git a/apps/advanced/console/config/bootstrap.php b/apps/advanced/console/config/bootstrap.php deleted file mode 100644 index b3d9bbc..0000000 --- a/apps/advanced/console/config/bootstrap.php +++ /dev/null @@ -1 +0,0 @@ - 'app-console', - 'basePath' => dirname(__DIR__), - 'bootstrap' => ['log', 'gii'], - 'controllerNamespace' => 'console\controllers', - 'modules' => [ - 'gii' => 'yii\gii\Module', - ], - 'components' => [ - 'log' => [ - 'targets' => [ - [ - 'class' => 'yii\log\FileTarget', - 'levels' => ['error', 'warning'], - ], - ], - ], - ], - 'params' => $params, -]; diff --git a/apps/advanced/console/config/params.php b/apps/advanced/console/config/params.php deleted file mode 100644 index 7f754b9..0000000 --- a/apps/advanced/console/config/params.php +++ /dev/null @@ -1,4 +0,0 @@ - 'admin@example.com', -]; diff --git a/apps/advanced/console/controllers/.gitkeep b/apps/advanced/console/controllers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/advanced/console/migrations/m130524_201442_init.php b/apps/advanced/console/migrations/m130524_201442_init.php deleted file mode 100644 index 5119f33..0000000 --- a/apps/advanced/console/migrations/m130524_201442_init.php +++ /dev/null @@ -1,35 +0,0 @@ -db->driverName === 'mysql') { - // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci - $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; - } - - $this->createTable('{{%user}}', [ - 'id' => Schema::TYPE_PK, - 'username' => Schema::TYPE_STRING . ' NOT NULL', - 'auth_key' => Schema::TYPE_STRING . '(32) NOT NULL', - 'password_hash' => Schema::TYPE_STRING . ' NOT NULL', - 'password_reset_token' => Schema::TYPE_STRING, - 'email' => Schema::TYPE_STRING . ' NOT NULL', - 'role' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 10', - - 'status' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 10', - 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', - 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', - ], $tableOptions); - } - - public function down() - { - $this->dropTable('{{%user}}'); - } -} diff --git a/apps/advanced/console/models/.gitkeep b/apps/advanced/console/models/.gitkeep deleted file mode 100644 index 72e8ffc..0000000 --- a/apps/advanced/console/models/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/apps/advanced/console/runtime/.gitignore b/apps/advanced/console/runtime/.gitignore deleted file mode 100644 index c96a04f..0000000 --- a/apps/advanced/console/runtime/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/apps/advanced/environments/dev/backend/config/main-local.php b/apps/advanced/environments/dev/backend/config/main-local.php deleted file mode 100644 index d9e3809..0000000 --- a/apps/advanced/environments/dev/backend/config/main-local.php +++ /dev/null @@ -1,21 +0,0 @@ - [ - 'request' => [ - // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation - 'cookieValidationKey' => '', - ], - ], -]; - -if (!YII_ENV_TEST) { - // configuration adjustments for 'dev' environment - $config['bootstrap'][] = 'debug'; - $config['modules']['debug'] = 'yii\debug\Module'; - - $config['bootstrap'][] = 'gii'; - $config['modules']['gii'] = 'yii\gii\Module'; -} - -return $config; diff --git a/apps/advanced/environments/dev/backend/config/params-local.php b/apps/advanced/environments/dev/backend/config/params-local.php deleted file mode 100644 index d0b9c34..0000000 --- a/apps/advanced/environments/dev/backend/config/params-local.php +++ /dev/null @@ -1,3 +0,0 @@ -run(); diff --git a/apps/advanced/environments/dev/backend/web/index.php b/apps/advanced/environments/dev/backend/web/index.php deleted file mode 100644 index 6038167..0000000 --- a/apps/advanced/environments/dev/backend/web/index.php +++ /dev/null @@ -1,18 +0,0 @@ -run(); diff --git a/apps/advanced/environments/dev/common/config/main-local.php b/apps/advanced/environments/dev/common/config/main-local.php deleted file mode 100644 index 43db30e..0000000 --- a/apps/advanced/environments/dev/common/config/main-local.php +++ /dev/null @@ -1,20 +0,0 @@ - [ - 'db' => [ - 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2advanced', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', - ], - 'mailer' => [ - 'class' => 'yii\swiftmailer\Mailer', - 'viewPath' => '@common/mail', - // send all mails to a file by default. You have to set - // 'useFileTransport' to false and configure a transport - // for the mailer to send real emails. - 'useFileTransport' => true, - ], - ], -]; diff --git a/apps/advanced/environments/dev/common/config/params-local.php b/apps/advanced/environments/dev/common/config/params-local.php deleted file mode 100644 index d0b9c34..0000000 --- a/apps/advanced/environments/dev/common/config/params-local.php +++ /dev/null @@ -1,3 +0,0 @@ - [ - 'request' => [ - // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation - 'cookieValidationKey' => '', - ], - ], -]; - -if (!YII_ENV_TEST) { - // configuration adjustments for 'dev' environment - $config['bootstrap'][] = 'debug'; - $config['modules']['debug'] = 'yii\debug\Module'; - - $config['bootstrap'][] = 'gii'; - $config['modules']['gii'] = 'yii\gii\Module'; -} - -return $config; diff --git a/apps/advanced/environments/dev/frontend/config/params-local.php b/apps/advanced/environments/dev/frontend/config/params-local.php deleted file mode 100644 index d0b9c34..0000000 --- a/apps/advanced/environments/dev/frontend/config/params-local.php +++ /dev/null @@ -1,3 +0,0 @@ -run(); diff --git a/apps/advanced/environments/dev/frontend/web/index.php b/apps/advanced/environments/dev/frontend/web/index.php deleted file mode 100644 index 6038167..0000000 --- a/apps/advanced/environments/dev/frontend/web/index.php +++ /dev/null @@ -1,18 +0,0 @@ -run(); diff --git a/apps/advanced/environments/dev/yii b/apps/advanced/environments/dev/yii deleted file mode 100644 index 8cc5827..0000000 --- a/apps/advanced/environments/dev/yii +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env php -run(); -exit($exitCode); diff --git a/apps/advanced/environments/index.php b/apps/advanced/environments/index.php deleted file mode 100644 index 5bb0acf..0000000 --- a/apps/advanced/environments/index.php +++ /dev/null @@ -1,61 +0,0 @@ - [ - * 'path' => 'directory storing the local files', - * 'setWritable' => [ - * // list of directories that should be set writable - * ], - * 'setExecutable' => [ - * // list of directories that should be set executable - * ], - * 'setCookieValidationKey' => [ - * // list of config files that need to be inserted with automatically generated cookie validation keys - * ], - * 'createSymlink' => [ - * // list of symlinks to be created. Keys are symlinks, and values are the targets. - * ], - * ], - * ]; - * ``` - */ -return [ - 'Development' => [ - 'path' => 'dev', - 'setWritable' => [ - 'backend/runtime', - 'backend/web/assets', - 'frontend/runtime', - 'frontend/web/assets', - ], - 'setExecutable' => [ - 'yii', - ], - 'setCookieValidationKey' => [ - 'backend/config/main-local.php', - 'frontend/config/main-local.php', - ], - ], - 'Production' => [ - 'path' => 'prod', - 'setWritable' => [ - 'backend/runtime', - 'backend/web/assets', - 'frontend/runtime', - 'frontend/web/assets', - ], - 'setExecutable' => [ - 'yii', - ], - 'setCookieValidationKey' => [ - 'backend/config/main-local.php', - 'frontend/config/main-local.php', - ], - ], -]; diff --git a/apps/advanced/environments/prod/backend/config/main-local.php b/apps/advanced/environments/prod/backend/config/main-local.php deleted file mode 100644 index af46ba3..0000000 --- a/apps/advanced/environments/prod/backend/config/main-local.php +++ /dev/null @@ -1,9 +0,0 @@ - [ - 'request' => [ - // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation - 'cookieValidationKey' => '', - ], - ], -]; diff --git a/apps/advanced/environments/prod/backend/config/params-local.php b/apps/advanced/environments/prod/backend/config/params-local.php deleted file mode 100644 index d0b9c34..0000000 --- a/apps/advanced/environments/prod/backend/config/params-local.php +++ /dev/null @@ -1,3 +0,0 @@ -run(); diff --git a/apps/advanced/environments/prod/common/config/main-local.php b/apps/advanced/environments/prod/common/config/main-local.php deleted file mode 100644 index 84c4d9f..0000000 --- a/apps/advanced/environments/prod/common/config/main-local.php +++ /dev/null @@ -1,16 +0,0 @@ - [ - 'db' => [ - 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2advanced', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', - ], - 'mailer' => [ - 'class' => 'yii\swiftmailer\Mailer', - 'viewPath' => '@common/mail', - ], - ], -]; diff --git a/apps/advanced/environments/prod/common/config/params-local.php b/apps/advanced/environments/prod/common/config/params-local.php deleted file mode 100644 index d0b9c34..0000000 --- a/apps/advanced/environments/prod/common/config/params-local.php +++ /dev/null @@ -1,3 +0,0 @@ - [ - 'request' => [ - // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation - 'cookieValidationKey' => '', - ], - ], -]; diff --git a/apps/advanced/environments/prod/frontend/config/params-local.php b/apps/advanced/environments/prod/frontend/config/params-local.php deleted file mode 100644 index d0b9c34..0000000 --- a/apps/advanced/environments/prod/frontend/config/params-local.php +++ /dev/null @@ -1,3 +0,0 @@ -run(); diff --git a/apps/advanced/environments/prod/yii b/apps/advanced/environments/prod/yii deleted file mode 100644 index c8b6f3f..0000000 --- a/apps/advanced/environments/prod/yii +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env php -run(); -exit($exitCode); diff --git a/apps/advanced/frontend/assets/AppAsset.php b/apps/advanced/frontend/assets/AppAsset.php deleted file mode 100644 index 995e3dc..0000000 --- a/apps/advanced/frontend/assets/AppAsset.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @since 2.0 - */ -class AppAsset extends AssetBundle -{ - public $basePath = '@webroot'; - public $baseUrl = '@web'; - public $css = [ - 'css/site.css', - ]; - public $js = [ - ]; - public $depends = [ - 'yii\web\YiiAsset', - 'yii\bootstrap\BootstrapAsset', - ]; -} diff --git a/apps/advanced/frontend/config/.gitignore b/apps/advanced/frontend/config/.gitignore deleted file mode 100644 index 20da318..0000000 --- a/apps/advanced/frontend/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -main-local.php -params-local.php \ No newline at end of file diff --git a/apps/advanced/frontend/config/bootstrap.php b/apps/advanced/frontend/config/bootstrap.php deleted file mode 100644 index b3d9bbc..0000000 --- a/apps/advanced/frontend/config/bootstrap.php +++ /dev/null @@ -1 +0,0 @@ - 'app-frontend', - 'basePath' => dirname(__DIR__), - 'bootstrap' => ['log'], - 'controllerNamespace' => 'frontend\controllers', - 'components' => [ - 'user' => [ - 'identityClass' => 'common\models\User', - 'enableAutoLogin' => true, - ], - 'log' => [ - 'traceLevel' => YII_DEBUG ? 3 : 0, - 'targets' => [ - [ - 'class' => 'yii\log\FileTarget', - 'levels' => ['error', 'warning'], - ], - ], - ], - 'errorHandler' => [ - 'errorAction' => 'site/error', - ], - ], - 'params' => $params, -]; diff --git a/apps/advanced/frontend/config/params.php b/apps/advanced/frontend/config/params.php deleted file mode 100644 index 7f754b9..0000000 --- a/apps/advanced/frontend/config/params.php +++ /dev/null @@ -1,4 +0,0 @@ - 'admin@example.com', -]; diff --git a/apps/advanced/frontend/controllers/SiteController.php b/apps/advanced/frontend/controllers/SiteController.php deleted file mode 100644 index c160a45..0000000 --- a/apps/advanced/frontend/controllers/SiteController.php +++ /dev/null @@ -1,171 +0,0 @@ - [ - 'class' => AccessControl::className(), - 'only' => ['logout', 'signup'], - 'rules' => [ - [ - 'actions' => ['signup'], - 'allow' => true, - 'roles' => ['?'], - ], - [ - 'actions' => ['logout'], - 'allow' => true, - 'roles' => ['@'], - ], - ], - ], - 'verbs' => [ - 'class' => VerbFilter::className(), - 'actions' => [ - 'logout' => ['post'], - ], - ], - ]; - } - - /** - * @inheritdoc - */ - public function actions() - { - return [ - 'error' => [ - 'class' => 'yii\web\ErrorAction', - ], - 'captcha' => [ - 'class' => 'yii\captcha\CaptchaAction', - 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, - ], - ]; - } - - public function actionIndex() - { - return $this->render('index'); - } - - public function actionLogin() - { - if (!\Yii::$app->user->isGuest) { - return $this->goHome(); - } - - $model = new LoginForm(); - if ($model->load(Yii::$app->request->post()) && $model->login()) { - return $this->goBack(); - } else { - return $this->render('login', [ - 'model' => $model, - ]); - } - } - - public function actionLogout() - { - Yii::$app->user->logout(); - - return $this->goHome(); - } - - public function actionContact() - { - $model = new ContactForm(); - if ($model->load(Yii::$app->request->post()) && $model->validate()) { - if ($model->sendEmail(Yii::$app->params['adminEmail'])) { - Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.'); - } else { - Yii::$app->session->setFlash('error', 'There was an error sending email.'); - } - - return $this->refresh(); - } else { - return $this->render('contact', [ - 'model' => $model, - ]); - } - } - - public function actionAbout() - { - return $this->render('about'); - } - - public function actionSignup() - { - $model = new SignupForm(); - if ($model->load(Yii::$app->request->post())) { - if ($user = $model->signup()) { - if (Yii::$app->getUser()->login($user)) { - return $this->goHome(); - } - } - } - - return $this->render('signup', [ - 'model' => $model, - ]); - } - - public function actionRequestPasswordReset() - { - $model = new PasswordResetRequestForm(); - if ($model->load(Yii::$app->request->post()) && $model->validate()) { - if ($model->sendEmail()) { - Yii::$app->getSession()->setFlash('success', 'Check your email for further instructions.'); - - return $this->goHome(); - } else { - Yii::$app->getSession()->setFlash('error', 'Sorry, we are unable to reset password for email provided.'); - } - } - - return $this->render('requestPasswordResetToken', [ - 'model' => $model, - ]); - } - - public function actionResetPassword($token) - { - try { - $model = new ResetPasswordForm($token); - } catch (InvalidParamException $e) { - throw new BadRequestHttpException($e->getMessage()); - } - - if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { - Yii::$app->getSession()->setFlash('success', 'New password was saved.'); - - return $this->goHome(); - } - - return $this->render('resetPassword', [ - 'model' => $model, - ]); - } -} diff --git a/apps/advanced/frontend/models/ContactForm.php b/apps/advanced/frontend/models/ContactForm.php deleted file mode 100644 index 613abb5..0000000 --- a/apps/advanced/frontend/models/ContactForm.php +++ /dev/null @@ -1,59 +0,0 @@ - 'Verification Code', - ]; - } - - /** - * Sends an email to the specified email address using the information collected by this model. - * - * @param string $email the target email address - * @return boolean whether the email was sent - */ - public function sendEmail($email) - { - return Yii::$app->mailer->compose() - ->setTo($email) - ->setFrom([$this->email => $this->name]) - ->setSubject($this->subject) - ->setTextBody($this->body) - ->send(); - } -} diff --git a/apps/advanced/frontend/models/PasswordResetRequestForm.php b/apps/advanced/frontend/models/PasswordResetRequestForm.php deleted file mode 100644 index df01013..0000000 --- a/apps/advanced/frontend/models/PasswordResetRequestForm.php +++ /dev/null @@ -1,60 +0,0 @@ - 'trim'], - ['email', 'required'], - ['email', 'email'], - ['email', 'exist', - 'targetClass' => '\common\models\User', - 'filter' => ['status' => User::STATUS_ACTIVE], - 'message' => 'There is no user with such email.' - ], - ]; - } - - /** - * Sends an email with a link, for resetting the password. - * - * @return boolean whether the email was send - */ - public function sendEmail() - { - /* @var $user User */ - $user = User::findOne([ - 'status' => User::STATUS_ACTIVE, - 'email' => $this->email, - ]); - - if ($user) { - if (!User::isPasswordResetTokenValid($user->password_reset_token)) { - $user->generatePasswordResetToken(); - } - - if ($user->save()) { - return \Yii::$app->mailer->compose('passwordResetToken', ['user' => $user]) - ->setFrom([\Yii::$app->params['supportEmail'] => \Yii::$app->name . ' robot']) - ->setTo($this->email) - ->setSubject('Password reset for ' . \Yii::$app->name) - ->send(); - } - } - - return false; - } -} diff --git a/apps/advanced/frontend/models/ResetPasswordForm.php b/apps/advanced/frontend/models/ResetPasswordForm.php deleted file mode 100644 index 5ed3d2e..0000000 --- a/apps/advanced/frontend/models/ResetPasswordForm.php +++ /dev/null @@ -1,65 +0,0 @@ -_user = User::findByPasswordResetToken($token); - if (!$this->_user) { - throw new InvalidParamException('Wrong password reset token.'); - } - parent::__construct($config); - } - - /** - * @inheritdoc - */ - public function rules() - { - return [ - ['password', 'required'], - ['password', 'string', 'min' => 6], - ]; - } - - /** - * Resets password. - * - * @return boolean if password was reset. - */ - public function resetPassword() - { - $user = $this->_user; - $user->password = $this->password; - $user->removePasswordResetToken(); - - return $user->save(); - } -} diff --git a/apps/advanced/frontend/models/SignupForm.php b/apps/advanced/frontend/models/SignupForm.php deleted file mode 100644 index 17bcdeb..0000000 --- a/apps/advanced/frontend/models/SignupForm.php +++ /dev/null @@ -1,57 +0,0 @@ - 'trim'], - ['username', 'required'], - ['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'], - ['username', 'string', 'min' => 2, 'max' => 255], - - ['email', 'filter', 'filter' => 'trim'], - ['email', 'required'], - ['email', 'email'], - ['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'], - - ['password', 'required'], - ['password', 'string', 'min' => 6], - ]; - } - - /** - * Signs user up. - * - * @return User|null the saved model or null if saving fails - */ - public function signup() - { - if ($this->validate()) { - $user = new User(); - $user->username = $this->username; - $user->email = $this->email; - $user->setPassword($this->password); - $user->generateAuthKey(); - $user->save(); - return $user; - } - - return null; - } -} diff --git a/apps/advanced/frontend/runtime/.gitignore b/apps/advanced/frontend/runtime/.gitignore deleted file mode 100644 index c96a04f..0000000 --- a/apps/advanced/frontend/runtime/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/apps/advanced/frontend/views/layouts/main.php b/apps/advanced/frontend/views/layouts/main.php deleted file mode 100644 index d4e68e6..0000000 --- a/apps/advanced/frontend/views/layouts/main.php +++ /dev/null @@ -1,76 +0,0 @@ - -beginPage() ?> - - - - - - - <?= Html::encode($this->title) ?> - head() ?> - - - beginBody() ?> -
- 'My Company', - 'brandUrl' => Yii::$app->homeUrl, - 'options' => [ - 'class' => 'navbar-inverse navbar-fixed-top', - ], - ]); - $menuItems = [ - ['label' => 'Home', 'url' => ['/site/index']], - ['label' => 'About', 'url' => ['/site/about']], - ['label' => 'Contact', 'url' => ['/site/contact']], - ]; - if (Yii::$app->user->isGuest) { - $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']]; - $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']]; - } else { - $menuItems[] = [ - 'label' => 'Logout (' . Yii::$app->user->identity->username . ')', - 'url' => ['/site/logout'], - 'linkOptions' => ['data-method' => 'post'] - ]; - } - echo Nav::widget([ - 'options' => ['class' => 'navbar-nav navbar-right'], - 'items' => $menuItems, - ]); - NavBar::end(); - ?> - -
- isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], - ]) ?> - - -
-
- - - - endBody() ?> - - -endPage() ?> diff --git a/apps/advanced/frontend/views/site/about.php b/apps/advanced/frontend/views/site/about.php deleted file mode 100644 index 813ed30..0000000 --- a/apps/advanced/frontend/views/site/about.php +++ /dev/null @@ -1,14 +0,0 @@ -title = 'About'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

This is the About page. You may modify the following file to customize its content:

- - -
diff --git a/apps/advanced/frontend/views/site/contact.php b/apps/advanced/frontend/views/site/contact.php deleted file mode 100644 index 60bddd3..0000000 --- a/apps/advanced/frontend/views/site/contact.php +++ /dev/null @@ -1,37 +0,0 @@ -title = 'Contact'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

- If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. -

- -
-
- 'contact-form']); ?> - field($model, 'name') ?> - field($model, 'email') ?> - field($model, 'subject') ?> - field($model, 'body')->textArea(['rows' => 6]) ?> - field($model, 'verifyCode')->widget(Captcha::className(), [ - 'template' => '
{image}
{input}
', - ]) ?> -
- 'btn btn-primary', 'name' => 'contact-button']) ?> -
- -
-
- -
diff --git a/apps/advanced/frontend/views/site/error.php b/apps/advanced/frontend/views/site/error.php deleted file mode 100644 index b9812c4..0000000 --- a/apps/advanced/frontend/views/site/error.php +++ /dev/null @@ -1,27 +0,0 @@ -title = $name; -?> -
- -

title) ?>

- -
- -
- -

- The above error occurred while the Web server was processing your request. -

-

- Please contact us if you think this is a server error. Thank you. -

- -
diff --git a/apps/advanced/frontend/views/site/index.php b/apps/advanced/frontend/views/site/index.php deleted file mode 100644 index a00ee4d..0000000 --- a/apps/advanced/frontend/views/site/index.php +++ /dev/null @@ -1,51 +0,0 @@ -title = 'My Yii Application'; -?> -
- -
-

Congratulations!

- -

You have successfully created your Yii-powered application.

- -

Get started with Yii

-
- -
- -
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Documentation »

-
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Forum »

-
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Extensions »

-
-
- -
-
diff --git a/apps/advanced/frontend/views/site/login.php b/apps/advanced/frontend/views/site/login.php deleted file mode 100644 index 647e04b..0000000 --- a/apps/advanced/frontend/views/site/login.php +++ /dev/null @@ -1,32 +0,0 @@ -title = 'Login'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

Please fill out the following fields to login:

- -
-
- 'login-form']); ?> - field($model, 'username') ?> - field($model, 'password')->passwordInput() ?> - field($model, 'rememberMe')->checkbox() ?> -
- If you forgot your password you can . -
-
- 'btn btn-primary', 'name' => 'login-button']) ?> -
- -
-
-
diff --git a/apps/advanced/frontend/views/site/requestPasswordResetToken.php b/apps/advanced/frontend/views/site/requestPasswordResetToken.php deleted file mode 100644 index fa5055c..0000000 --- a/apps/advanced/frontend/views/site/requestPasswordResetToken.php +++ /dev/null @@ -1,27 +0,0 @@ -title = 'Request password reset'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

Please fill out your email. A link to reset password will be sent there.

- -
-
- 'request-password-reset-form']); ?> - field($model, 'email') ?> -
- 'btn btn-primary']) ?> -
- -
-
-
diff --git a/apps/advanced/frontend/views/site/resetPassword.php b/apps/advanced/frontend/views/site/resetPassword.php deleted file mode 100644 index 45461d0..0000000 --- a/apps/advanced/frontend/views/site/resetPassword.php +++ /dev/null @@ -1,27 +0,0 @@ -title = 'Reset password'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

Please choose your new password:

- -
-
- 'reset-password-form']); ?> - field($model, 'password')->passwordInput() ?> -
- 'btn btn-primary']) ?> -
- -
-
-
diff --git a/apps/advanced/frontend/views/site/signup.php b/apps/advanced/frontend/views/site/signup.php deleted file mode 100644 index cdf0143..0000000 --- a/apps/advanced/frontend/views/site/signup.php +++ /dev/null @@ -1,29 +0,0 @@ -title = 'Signup'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

Please fill out the following fields to signup:

- -
-
- 'form-signup']); ?> - field($model, 'username') ?> - field($model, 'email') ?> - field($model, 'password')->passwordInput() ?> -
- 'btn btn-primary', 'name' => 'signup-button']) ?> -
- -
-
-
diff --git a/apps/advanced/frontend/web/.gitignore b/apps/advanced/frontend/web/.gitignore deleted file mode 100644 index 25c74e6..0000000 --- a/apps/advanced/frontend/web/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/index.php -/index-test.php diff --git a/apps/advanced/frontend/web/assets/.gitignore b/apps/advanced/frontend/web/assets/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/apps/advanced/frontend/web/assets/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/apps/advanced/frontend/web/css/site.css b/apps/advanced/frontend/web/css/site.css deleted file mode 100644 index 698be70..0000000 --- a/apps/advanced/frontend/web/css/site.css +++ /dev/null @@ -1,91 +0,0 @@ -html, -body { - height: 100%; -} - -.wrap { - min-height: 100%; - height: auto; - margin: 0 auto -60px; - padding: 0 0 60px; -} - -.wrap > .container { - padding: 70px 15px 20px; -} - -.footer { - height: 60px; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - padding-top: 20px; -} - -.jumbotron { - text-align: center; - background-color: transparent; -} - -.jumbotron .btn { - font-size: 21px; - padding: 14px 24px; -} - -.not-set { - color: #c55; - font-style: italic; -} - -/* add sorting icons to gridview sort links */ -a.asc:after, a.desc:after { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: normal; - line-height: 1; - padding-left: 5px; -} - -a.asc:after { - content: /*"\e113"*/ "\e151"; -} - -a.desc:after { - content: /*"\e114"*/ "\e152"; -} - -.sort-numerical a.asc:after { - content: "\e153"; -} - -.sort-numerical a.desc:after { - content: "\e154"; -} - -.sort-ordinal a.asc:after { - content: "\e155"; -} - -.sort-ordinal a.desc:after { - content: "\e156"; -} - -.grid-view th { - white-space: nowrap; -} - -.hint-block { - display: block; - margin-top: 5px; - color: #999; -} - -.error-summary { - color: #a94442; - background: #fdf7f7; - border-left: 3px solid #eed3d7; - padding: 10px 20px; - margin: 0 0 15px 0; -} diff --git a/apps/advanced/frontend/web/favicon.ico b/apps/advanced/frontend/web/favicon.ico deleted file mode 100644 index 580ed73..0000000 Binary files a/apps/advanced/frontend/web/favicon.ico and /dev/null differ diff --git a/apps/advanced/frontend/web/robots.txt b/apps/advanced/frontend/web/robots.txt deleted file mode 100644 index 6f27bb6..0000000 --- a/apps/advanced/frontend/web/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: \ No newline at end of file diff --git a/apps/advanced/frontend/widgets/Alert.php b/apps/advanced/frontend/widgets/Alert.php deleted file mode 100644 index fa755da..0000000 --- a/apps/advanced/frontend/widgets/Alert.php +++ /dev/null @@ -1,79 +0,0 @@ -getSession()->setFlash('error', 'This is the message'); - * \Yii::$app->getSession()->setFlash('success', 'This is the message'); - * \Yii::$app->getSession()->setFlash('info', 'This is the message'); - * ``` - * - * Multiple messages could be set as follows: - * - * ```php - * \Yii::$app->getSession()->setFlash('error', ['Error 1', 'Error 2']); - * ``` - * - * @author Kartik Visweswaran - * @author Alexander Makarov - */ -class Alert extends \yii\bootstrap\Widget -{ - /** - * @var array the alert types configuration for the flash messages. - * This array is setup as $key => $value, where: - * - $key is the name of the session flash variable - * - $value is the bootstrap alert type (i.e. danger, success, info, warning) - */ - public $alertTypes = [ - 'error' => 'alert-danger', - 'danger' => 'alert-danger', - 'success' => 'alert-success', - 'info' => 'alert-info', - 'warning' => 'alert-warning' - ]; - - /** - * @var array the options for rendering the close button tag. - */ - public $closeButton = []; - - public function init() - { - parent::init(); - - $session = \Yii::$app->getSession(); - $flashes = $session->getAllFlashes(); - $appendCss = isset($this->options['class']) ? ' ' . $this->options['class'] : ''; - - foreach ($flashes as $type => $data) { - if (isset($this->alertTypes[$type])) { - $data = (array) $data; - foreach ($data as $message) { - /* initialize css class for each alert box */ - $this->options['class'] = $this->alertTypes[$type] . $appendCss; - - /* assign unique id to each alert box */ - $this->options['id'] = $this->getId() . '-' . $type; - - echo \yii\bootstrap\Alert::widget([ - 'body' => $message, - 'closeButton' => $this->closeButton, - 'options' => $this->options, - ]); - } - - $session->removeFlash($type); - } - } - } -} diff --git a/apps/advanced/init b/apps/advanced/init deleted file mode 100755 index e6278db..0000000 --- a/apps/advanced/init +++ /dev/null @@ -1,205 +0,0 @@ -#!/usr/bin/env php - - * - * @link http://www.yiiframework.com/ - * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ - */ - -if (!extension_loaded('mcrypt')) { - die('The mcrypt PHP extension is required by Yii2.'); -} - -$params = getParams(); -$root = str_replace('\\', '/', __DIR__); -$envs = require("$root/environments/index.php"); -$envNames = array_keys($envs); - -echo "Yii Application Initialization Tool v1.0\n\n"; - -$envName = null; -if (empty($params['env']) || $params['env'] === '1') { - echo "Which environment do you want the application to be initialized in?\n\n"; - foreach ($envNames as $i => $name) { - echo " [$i] $name\n"; - } - echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] '; - $answer = trim(fgets(STDIN)); - - if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) { - echo "\n Quit initialization.\n"; - exit(0); - } - - if (isset($envNames[$answer])) { - $envName = $envNames[$answer]; - } -} else { - $envName = $params['env']; -} - -if (!in_array($envName, $envNames)) { - $envsList = implode(', ', $envNames); - echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n"; - exit(2); -} - -$env = $envs[$envName]; - -if (empty($params['env'])) { - echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] "; - $answer = trim(fgets(STDIN)); - if (strncasecmp($answer, 'y', 1)) { - echo "\n Quit initialization.\n"; - exit(0); - } -} - -echo "\n Start initialization ...\n\n"; -$files = getFileList("$root/environments/{$env['path']}"); -$all = false; -foreach ($files as $file) { - if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) { - break; - } -} - -$callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable']; -foreach ($callbacks as $callback) { - if (!empty($env[$callback])) { - $callback($root, $env[$callback]); - } -} - -echo "\n ... initialization completed.\n\n"; - -function getFileList($root, $basePath = '') -{ - $files = []; - $handle = opendir($root); - while (($path = readdir($handle)) !== false) { - if ($path === '.svn' || $path === '.' || $path === '..') { - continue; - } - $fullPath = "$root/$path"; - $relativePath = $basePath === '' ? $path : "$basePath/$path"; - if (is_dir($fullPath)) { - $files = array_merge($files, getFileList($fullPath, $relativePath)); - } else { - $files[] = $relativePath; - } - } - closedir($handle); - return $files; -} - -function copyFile($root, $source, $target, &$all, $params) -{ - if (!is_file($root . '/' . $source)) { - echo " skip $target ($source not exist)\n"; - return true; - } - if (is_file($root . '/' . $target)) { - if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) { - echo " unchanged $target\n"; - return true; - } - if ($all) { - echo " overwrite $target\n"; - } else { - echo " exist $target\n"; - echo " ...overwrite? [Yes|No|All|Quit] "; - - - $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN)); - if (!strncasecmp($answer, 'q', 1)) { - return false; - } else { - if (!strncasecmp($answer, 'y', 1)) { - echo " overwrite $target\n"; - } else { - if (!strncasecmp($answer, 'a', 1)) { - echo " overwrite $target\n"; - $all = true; - } else { - echo " skip $target\n"; - return true; - } - } - } - } - file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); - return true; - } - echo " generate $target\n"; - @mkdir(dirname($root . '/' . $target), 0777, true); - file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); - return true; -} - -function getParams() -{ - $rawParams = []; - if (isset($_SERVER['argv'])) { - $rawParams = $_SERVER['argv']; - array_shift($rawParams); - } - - $params = []; - foreach ($rawParams as $param) { - if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) { - $name = $matches[1]; - $params[$name] = isset($matches[3]) ? $matches[3] : true; - } else { - $params[] = $param; - } - } - return $params; -} - -function setWritable($root, $paths) -{ - foreach ($paths as $writable) { - echo " chmod 0777 $writable\n"; - @chmod("$root/$writable", 0777); - } -} - -function setExecutable($root, $paths) -{ - foreach ($paths as $executable) { - echo " chmod 0755 $executable\n"; - @chmod("$root/$executable", 0755); - } -} - -function setCookieValidationKey($root, $paths) -{ - foreach ($paths as $file) { - echo " generate cookie validation key in $file\n"; - $file = $root . '/' . $file; - $length = 32; - $bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); - $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.'); - $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file)); - file_put_contents($file, $content); - } -} - -function createSymlink($links) -{ - foreach ($links as $link => $target) { - echo " symlink $target as $link\n"; - if (!is_link($link)) { - symlink($target, $link); - } - } -} diff --git a/apps/advanced/init.bat b/apps/advanced/init.bat deleted file mode 100644 index e50c242..0000000 --- a/apps/advanced/init.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -rem ------------------------------------------------------------- -rem Yii command line init script for Windows. -rem -rem @author Qiang Xue -rem @link http://www.yiiframework.com/ -rem @copyright Copyright (c) 2008 Yii Software LLC -rem @license http://www.yiiframework.com/license/ -rem ------------------------------------------------------------- - -@setlocal - -set YII_PATH=%~dp0 - -if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe - -"%PHP_COMMAND%" "%YII_PATH%init" %* - -@endlocal diff --git a/apps/advanced/requirements.php b/apps/advanced/requirements.php deleted file mode 100644 index a560dc3..0000000 --- a/apps/advanced/requirements.php +++ /dev/null @@ -1,139 +0,0 @@ -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(); - -$gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; -$gdOK = $imagickOK = false; - -if (extension_loaded('imagick')) { - $imagick = new Imagick(); - $imagickFormats = $imagick->queryFormats('PNG'); - if (in_array('PNG', $imagickFormats)) { - $imagickOK = true; - } else { - $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; - } -} - -if (extension_loaded('gd')) { - $gdInfo = gd_info(); - if (!empty($gdInfo['FreeType Support'])) { - $gdOK = true; - } else { - $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; - } -} - -/** - * 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.', - ), - array( - 'name' => 'PDO PostgreSQL extension', - 'mandatory' => false, - 'condition' => extension_loaded('pdo_pgsql'), - 'by' => 'All DB-related classes', - 'memo' => 'Required for PostgreSQL database.', - ), - // Cache : - array( - 'name' => 'Memcache extension', - 'mandatory' => false, - 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), - 'by' => 'MemCache', - 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : '' - ), - array( - 'name' => 'APC extension', - 'mandatory' => false, - 'condition' => extension_loaded('apc'), - 'by' => 'ApcCache', - ), - // CAPTCHA: - array( - 'name' => 'GD PHP extension with FreeType support', - 'mandatory' => false, - 'condition' => $gdOK, - 'by' => 'Captcha', - 'memo' => $gdMemo, - ), - array( - 'name' => 'ImageMagick PHP extension with PNG support', - 'mandatory' => false, - 'condition' => $imagickOK, - 'by' => 'Captcha', - 'memo' => $imagickMemo, - ), - // 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/advanced/tests/README.md b/apps/advanced/tests/README.md deleted file mode 100644 index ad7f016..0000000 --- a/apps/advanced/tests/README.md +++ /dev/null @@ -1,58 +0,0 @@ -This directory contains various tests for the advanced applications. - -Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/). - -After creating and setting up the advanced application, follow these steps to prepare for the tests: - -1. Install Codeception if it's not yet installed: - - ``` - composer global require "codeception/codeception=2.0.*" "codeception/specify=*" "codeception/verify=*" - ``` - - If you've never used Composer for global packages run `composer global status`. It should output: - - ``` - Changed current directory to - ``` - - Then add `/vendor/bin` to you `PATH` environment variable. Now you're able to use `codecept` from command - line globally. - -2. Install faker extension by running the following from template root directory where `composer.json` is: - - ``` - composer require --dev yiisoft/yii2-faker:* - ``` - -3. Create `yii2_advanced_tests` database then update it by applying migrations: - - ``` - codeception/bin/yii migrate - ``` - -4. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in - webserver. In the root directory where `common`, `frontend` etc. are execute the following: - - ``` - php -S localhost:8080 - ``` - -5. Now you can run the tests with the following commands, assuming you are in the `tests/codeception` directory: - - ``` - # frontend tests - cd frontend - codecept build - codecept run - - # backend tests - - cd backend - codecept build - codecept run - - # etc. - ``` - - If you already have run `codecept build` for each application, you can skip that step and run all tests by a single `codecept run`. diff --git a/apps/advanced/tests/codeception.yml b/apps/advanced/tests/codeception.yml deleted file mode 100644 index 1a793ed..0000000 --- a/apps/advanced/tests/codeception.yml +++ /dev/null @@ -1,11 +0,0 @@ -include: - - codeception/common - - codeception/console - - codeception/backend - - codeception/frontend - -paths: - log: codeception/_output - -settings: - colors: true diff --git a/apps/advanced/tests/codeception/_output/.gitignore b/apps/advanced/tests/codeception/_output/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/apps/advanced/tests/codeception/_output/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/apps/advanced/tests/codeception/backend/.gitignore b/apps/advanced/tests/codeception/backend/.gitignore deleted file mode 100644 index 985dbb4..0000000 --- a/apps/advanced/tests/codeception/backend/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# these files are auto generated by codeception build -/unit/UnitTester.php -/functional/FunctionalTester.php -/acceptance/AcceptanceTester.php diff --git a/apps/advanced/tests/codeception/backend/_bootstrap.php b/apps/advanced/tests/codeception/backend/_bootstrap.php deleted file mode 100644 index a28a3d2..0000000 --- a/apps/advanced/tests/codeception/backend/_bootstrap.php +++ /dev/null @@ -1,23 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -$I->expectTo('see that user is logged'); -$I->seeLink('Logout (erau)'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); -/** Uncomment if using WebDriver - * $I->click('Logout (erau)'); - * $I->dontSeeLink('Logout (erau)'); - * $I->seeLink('Login'); - */ diff --git a/apps/advanced/tests/codeception/backend/acceptance/_bootstrap.php b/apps/advanced/tests/codeception/backend/acceptance/_bootstrap.php deleted file mode 100644 index 411855e..0000000 --- a/apps/advanced/tests/codeception/backend/acceptance/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -$I->expectTo('see that user is logged'); -$I->seeLink('Logout (erau)'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); diff --git a/apps/advanced/tests/codeception/backend/functional/_bootstrap.php b/apps/advanced/tests/codeception/backend/functional/_bootstrap.php deleted file mode 100644 index 94f3fbd..0000000 --- a/apps/advanced/tests/codeception/backend/functional/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ - [ - 'fixture' => [ - 'class' => 'yii\faker\FixtureController', - 'fixtureDataPath' => '@tests/codeception/common/fixtures/data', - 'templatePath' => '@tests/codeception/common/templates/fixtures', - 'namespace' => 'tests\codeception\common\fixtures', - ], - ], - ] -); - -$application = new yii\console\Application($config); -$exitCode = $application->run(); -exit($exitCode); diff --git a/apps/advanced/tests/codeception/bin/yii.bat b/apps/advanced/tests/codeception/bin/yii.bat deleted file mode 100644 index d516b3a..0000000 --- a/apps/advanced/tests/codeception/bin/yii.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -rem ------------------------------------------------------------- -rem Yii command line bootstrap script for Windows. -rem -rem @author Qiang Xue -rem @link http://www.yiiframework.com/ -rem @copyright Copyright (c) 2008 Yii Software LLC -rem @license http://www.yiiframework.com/license/ -rem ------------------------------------------------------------- - -@setlocal - -set YII_PATH=%~dp0 - -if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe - -"%PHP_COMMAND%" "%YII_PATH%yii" %* - -@endlocal diff --git a/apps/advanced/tests/codeception/common/.gitignore b/apps/advanced/tests/codeception/common/.gitignore deleted file mode 100644 index 985dbb4..0000000 --- a/apps/advanced/tests/codeception/common/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# these files are auto generated by codeception build -/unit/UnitTester.php -/functional/FunctionalTester.php -/acceptance/AcceptanceTester.php diff --git a/apps/advanced/tests/codeception/common/_bootstrap.php b/apps/advanced/tests/codeception/common/_bootstrap.php deleted file mode 100644 index cea3ee5..0000000 --- a/apps/advanced/tests/codeception/common/_bootstrap.php +++ /dev/null @@ -1,15 +0,0 @@ -actor->fillField('input[name="LoginForm[username]"]', $username); - $this->actor->fillField('input[name="LoginForm[password]"]', $password); - $this->actor->click('login-button'); - } -} diff --git a/apps/advanced/tests/codeception/common/_support/FixtureHelper.php b/apps/advanced/tests/codeception/common/_support/FixtureHelper.php deleted file mode 100644 index cc2a311..0000000 --- a/apps/advanced/tests/codeception/common/_support/FixtureHelper.php +++ /dev/null @@ -1,60 +0,0 @@ -loadFixtures(); - } - - /** - * Method is called after all suite tests run - */ - public function _afterSuite() - { - $this->unloadFixtures(); - } - - /** - * @inheritdoc - */ - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/common/fixtures/data/init_login.php', - ], - ]; - } -} diff --git a/apps/advanced/tests/codeception/common/codeception.yml b/apps/advanced/tests/codeception/common/codeception.yml deleted file mode 100644 index e8a3407..0000000 --- a/apps/advanced/tests/codeception/common/codeception.yml +++ /dev/null @@ -1,13 +0,0 @@ -namespace: tests\codeception\common -actor: Tester -paths: - tests: . - log: _output - data: _data - helpers: _support -settings: - bootstrap: _bootstrap.php - suite_class: \PHPUnit_Framework_TestSuite - colors: true - memory_limit: 1024M - log: true diff --git a/apps/advanced/tests/codeception/common/fixtures/UserFixture.php b/apps/advanced/tests/codeception/common/fixtures/UserFixture.php deleted file mode 100644 index 7153c8c..0000000 --- a/apps/advanced/tests/codeception/common/fixtures/UserFixture.php +++ /dev/null @@ -1,13 +0,0 @@ - 'erau', - 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI', - // password_0 - 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne', - 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490', - 'created_at' => '1392559490', - 'updated_at' => '1392559490', - 'email' => 'sfriesen@jenkins.info', - ], -]; diff --git a/apps/advanced/tests/codeception/common/templates/fixtures/user.php b/apps/advanced/tests/codeception/common/templates/fixtures/user.php deleted file mode 100644 index d3f83b5..0000000 --- a/apps/advanced/tests/codeception/common/templates/fixtures/user.php +++ /dev/null @@ -1,17 +0,0 @@ -getSecurity(); - -return [ - 'username' => $faker->userName, - 'email' => $faker->email, - 'auth_key' => $security->generateRandomString(), - 'password_hash' => $security->generatePasswordHash('password_' . $index), - 'password_reset_token' => $security->generateRandomString() . '_' . time(), - 'created_at' => time(), - 'updated_at' => time(), -]; diff --git a/apps/advanced/tests/codeception/common/unit.suite.yml b/apps/advanced/tests/codeception/common/unit.suite.yml deleted file mode 100644 index a0582a5..0000000 --- a/apps/advanced/tests/codeception/common/unit.suite.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Codeception Test Suite Configuration - -# suite for unit (internal) tests. -# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. - -class_name: UnitTester diff --git a/apps/advanced/tests/codeception/common/unit/DbTestCase.php b/apps/advanced/tests/codeception/common/unit/DbTestCase.php deleted file mode 100644 index 2159a69..0000000 --- a/apps/advanced/tests/codeception/common/unit/DbTestCase.php +++ /dev/null @@ -1,11 +0,0 @@ - 'bayer.hudson', - 'auth_key' => 'HP187Mvq7Mmm3CTU80dLkGmni_FUH_lR', - //password_0 - 'password_hash' => '$2y$13$EjaPFBnZOQsHdGuHI.xvhuDp1fHpo8hKRSk6yshqa9c5EG8s3C3lO', - 'password_reset_token' => 'ExzkCOaYc1L8IOBs4wdTGGbgNiG3Wz1I_1402312317', - 'created_at' => '1402312317', - 'updated_at' => '1402312317', - 'email' => 'nicole.paucek@schultz.info', - ], -]; diff --git a/apps/advanced/tests/codeception/common/unit/models/LoginFormTest.php b/apps/advanced/tests/codeception/common/unit/models/LoginFormTest.php deleted file mode 100644 index 7fd64f6..0000000 --- a/apps/advanced/tests/codeception/common/unit/models/LoginFormTest.php +++ /dev/null @@ -1,94 +0,0 @@ - [ - 'user' => [ - 'class' => 'yii\web\User', - 'identityClass' => 'common\models\User', - ], - ], - ]); - } - - protected function tearDown() - { - Yii::$app->user->logout(); - parent::tearDown(); - } - - public function testLoginNoUser() - { - $model = new LoginForm([ - 'username' => 'not_existing_username', - 'password' => 'not_existing_password', - ]); - - $this->specify('user should not be able to login, when there is no identity', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('user should not be logged in', Yii::$app->user->isGuest)->true(); - }); - } - - public function testLoginWrongPassword() - { - $model = new LoginForm([ - 'username' => 'bayer.hudson', - 'password' => 'wrong_password', - ]); - - $this->specify('user should not be able to login with wrong password', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('error message should be set', $model->errors)->hasKey('password'); - expect('user should not be logged in', Yii::$app->user->isGuest)->true(); - }); - } - - public function testLoginCorrect() - { - - $model = new LoginForm([ - 'username' => 'bayer.hudson', - 'password' => 'password_0', - ]); - - $this->specify('user should be able to login with correct credentials', function () use ($model) { - expect('model should login user', $model->login())->true(); - expect('error message should not be set', $model->errors)->hasntKey('password'); - expect('user should be logged in', Yii::$app->user->isGuest)->false(); - }); - } - - /** - * @inheritdoc - */ - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/common/unit/fixtures/data/models/user.php' - ], - ]; - } - -} diff --git a/apps/advanced/tests/codeception/config/acceptance.php b/apps/advanced/tests/codeception/config/acceptance.php deleted file mode 100644 index 9318da5..0000000 --- a/apps/advanced/tests/codeception/config/acceptance.php +++ /dev/null @@ -1,7 +0,0 @@ - 'app-common', - 'basePath' => dirname(__DIR__), - ] -); diff --git a/apps/advanced/tests/codeception/config/config.php b/apps/advanced/tests/codeception/config/config.php deleted file mode 100644 index 59e485a..0000000 --- a/apps/advanced/tests/codeception/config/config.php +++ /dev/null @@ -1,17 +0,0 @@ - [ - 'db' => [ - 'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests', - ], - 'mailer' => [ - 'useFileTransport' => true, - ], - 'urlManager' => [ - 'showScriptName' => true, - ], - ], -]; diff --git a/apps/advanced/tests/codeception/config/console/unit.php b/apps/advanced/tests/codeception/config/console/unit.php deleted file mode 100644 index 4d3aeb0..0000000 --- a/apps/advanced/tests/codeception/config/console/unit.php +++ /dev/null @@ -1,14 +0,0 @@ - [ - 'request' => [ - // it's not recommended to run functional tests with CSRF validation enabled - 'enableCsrfValidation' => false, - // but if you absolutely need it set cookie domain to localhost - /* - 'csrfCookie' => [ - 'domain' => 'localhost', - ], - */ - ], - ], -]; \ No newline at end of file diff --git a/apps/advanced/tests/codeception/config/unit.php b/apps/advanced/tests/codeception/config/unit.php deleted file mode 100644 index 6bd08d3..0000000 --- a/apps/advanced/tests/codeception/config/unit.php +++ /dev/null @@ -1,7 +0,0 @@ - $value) { - $inputType = $field === 'body' ? 'textarea' : 'input'; - $this->actor->fillField($inputType . '[name="ContactForm[' . $field . ']"]', $value); - } - $this->actor->click('contact-button'); - } -} diff --git a/apps/advanced/tests/codeception/frontend/_pages/SignupPage.php b/apps/advanced/tests/codeception/frontend/_pages/SignupPage.php deleted file mode 100644 index 0e1cefa..0000000 --- a/apps/advanced/tests/codeception/frontend/_pages/SignupPage.php +++ /dev/null @@ -1,27 +0,0 @@ - $value) { - $inputType = $field === 'body' ? 'textarea' : 'input'; - $this->actor->fillField($inputType . '[name="SignupForm[' . $field . ']"]', $value); - } - $this->actor->click('signup-button'); - } -} diff --git a/apps/advanced/tests/codeception/frontend/acceptance.suite.yml b/apps/advanced/tests/codeception/frontend/acceptance.suite.yml deleted file mode 100644 index 1828a04..0000000 --- a/apps/advanced/tests/codeception/frontend/acceptance.suite.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Codeception Test Suite Configuration - -# suite for acceptance tests. -# perform tests in browser using the Selenium-like tools. -# powered by Mink (http://mink.behat.org). -# (tip: that's what your customer will see). -# (tip: test your ajax and javascript by one of Mink drivers). - -# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. - -class_name: AcceptanceTester -modules: - enabled: - - PhpBrowser - - tests\codeception\common\_support\FixtureHelper -# you can use WebDriver instead of PhpBrowser to test javascript and ajax. -# This will require you to install selenium. See http://codeception.com/docs/04-AcceptanceTests#Selenium -# "restart" option is used by the WebDriver to start each time per test-file new session and cookies, -# it is useful if you want to login in your app in each test. -# - WebDriver - config: - PhpBrowser: -# PLEASE ADJUST IT TO THE ACTUAL ENTRY POINT WITHOUT PATH INFO - url: http://localhost:8080 -# WebDriver: -# url: http://localhost:8080 -# browser: firefox -# restart: true diff --git a/apps/advanced/tests/codeception/frontend/acceptance/AboutCept.php b/apps/advanced/tests/codeception/frontend/acceptance/AboutCept.php deleted file mode 100644 index 7f7f97e..0000000 --- a/apps/advanced/tests/codeception/frontend/acceptance/AboutCept.php +++ /dev/null @@ -1,8 +0,0 @@ -wantTo('ensure that about works'); -AboutPage::openBy($I); -$I->see('About', 'h1'); diff --git a/apps/advanced/tests/codeception/frontend/acceptance/ContactCept.php b/apps/advanced/tests/codeception/frontend/acceptance/ContactCept.php deleted file mode 100644 index c537fd4..0000000 --- a/apps/advanced/tests/codeception/frontend/acceptance/ContactCept.php +++ /dev/null @@ -1,45 +0,0 @@ -wantTo('ensure that contact works'); - -$contactPage = ContactPage::openBy($I); - -$I->see('Contact', 'h1'); - -$I->amGoingTo('submit contact form with no data'); -$contactPage->submit([]); -$I->expectTo('see validations errors'); -$I->see('Contact', 'h1'); -$I->see('Name cannot be blank', '.help-block'); -$I->see('Email cannot be blank', '.help-block'); -$I->see('Subject cannot be blank', '.help-block'); -$I->see('Body cannot be blank', '.help-block'); -$I->see('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with not correct email'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester.email', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->expectTo('see that email adress is wrong'); -$I->dontSee('Name cannot be blank', '.help-block'); -$I->see('Email is not a valid email address.', '.help-block'); -$I->dontSee('Subject cannot be blank', '.help-block'); -$I->dontSee('Body cannot be blank', '.help-block'); -$I->dontSee('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with correct data'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester@example.com', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); diff --git a/apps/advanced/tests/codeception/frontend/acceptance/HomeCept.php b/apps/advanced/tests/codeception/frontend/acceptance/HomeCept.php deleted file mode 100644 index 5cf8379..0000000 --- a/apps/advanced/tests/codeception/frontend/acceptance/HomeCept.php +++ /dev/null @@ -1,10 +0,0 @@ -wantTo('ensure that home page works'); -$I->amOnPage(Yii::$app->homeUrl); -$I->see('My Company'); -$I->seeLink('About'); -$I->click('About'); -$I->see('This is the About page.'); diff --git a/apps/advanced/tests/codeception/frontend/acceptance/LoginCept.php b/apps/advanced/tests/codeception/frontend/acceptance/LoginCept.php deleted file mode 100644 index e4363a8..0000000 --- a/apps/advanced/tests/codeception/frontend/acceptance/LoginCept.php +++ /dev/null @@ -1,32 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -$I->expectTo('see that user is logged'); -$I->seeLink('Logout (erau)'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); -/** Uncomment if using WebDriver - * $I->click('Logout (erau)'); - * $I->dontSeeLink('Logout (erau)'); - * $I->seeLink('Login'); - */ diff --git a/apps/advanced/tests/codeception/frontend/acceptance/SignupCest.php b/apps/advanced/tests/codeception/frontend/acceptance/SignupCest.php deleted file mode 100644 index ab4b7bb..0000000 --- a/apps/advanced/tests/codeception/frontend/acceptance/SignupCest.php +++ /dev/null @@ -1,82 +0,0 @@ - 'tester.email@example.com', - 'username' => 'tester', - ]); - } - - /** - * This method is called when test fails. - * @param \Codeception\Event\FailEvent $event - */ - public function _fail($event) - { - } - - /** - * @param \codeception_frontend\AcceptanceTester $I - * @param \Codeception\Scenario $scenario - */ - public function testUserSignup($I, $scenario) - { - $I->wantTo('ensure that signup works'); - - $signupPage = SignupPage::openBy($I); - $I->see('Signup', 'h1'); - $I->see('Please fill out the following fields to signup:'); - - $I->amGoingTo('submit signup form with no data'); - - $signupPage->submit([]); - - $I->expectTo('see validation errors'); - $I->see('Username cannot be blank.', '.help-block'); - $I->see('Email cannot be blank.', '.help-block'); - $I->see('Password cannot be blank.', '.help-block'); - - $I->amGoingTo('submit signup form with not correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that email address is wrong'); - $I->dontSee('Username cannot be blank.', '.help-block'); - $I->dontSee('Password cannot be blank.', '.help-block'); - $I->see('Email is not a valid email address.', '.help-block'); - - $I->amGoingTo('submit signup form with correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email@example.com', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that user logged in'); - $I->seeLink('Logout (tester)'); - } -} diff --git a/apps/advanced/tests/codeception/frontend/acceptance/_bootstrap.php b/apps/advanced/tests/codeception/frontend/acceptance/_bootstrap.php deleted file mode 100644 index b0a40ef..0000000 --- a/apps/advanced/tests/codeception/frontend/acceptance/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ -wantTo('ensure that about works'); -AboutPage::openBy($I); -$I->see('About', 'h1'); diff --git a/apps/advanced/tests/codeception/frontend/functional/ContactCept.php b/apps/advanced/tests/codeception/frontend/functional/ContactCept.php deleted file mode 100644 index 1aaac3f..0000000 --- a/apps/advanced/tests/codeception/frontend/functional/ContactCept.php +++ /dev/null @@ -1,45 +0,0 @@ -wantTo('ensure that contact works'); - -$contactPage = ContactPage::openBy($I); - -$I->see('Contact', 'h1'); - -$I->amGoingTo('submit contact form with no data'); -$contactPage->submit([]); -$I->expectTo('see validations errors'); -$I->see('Contact', 'h1'); -$I->see('Name cannot be blank', '.help-block'); -$I->see('Email cannot be blank', '.help-block'); -$I->see('Subject cannot be blank', '.help-block'); -$I->see('Body cannot be blank', '.help-block'); -$I->see('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with not correct email'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester.email', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->expectTo('see that email adress is wrong'); -$I->dontSee('Name cannot be blank', '.help-block'); -$I->see('Email is not a valid email address.', '.help-block'); -$I->dontSee('Subject cannot be blank', '.help-block'); -$I->dontSee('Body cannot be blank', '.help-block'); -$I->dontSee('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with correct data'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester@example.com', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); diff --git a/apps/advanced/tests/codeception/frontend/functional/HomeCept.php b/apps/advanced/tests/codeception/frontend/functional/HomeCept.php deleted file mode 100644 index 0f5b2ff..0000000 --- a/apps/advanced/tests/codeception/frontend/functional/HomeCept.php +++ /dev/null @@ -1,9 +0,0 @@ -wantTo('ensure that home page works'); -$I->amOnPage(Yii::$app->homeUrl); -$I->see('My Company'); -$I->seeLink('About'); -$I->click('About'); -$I->see('This is the About page.'); diff --git a/apps/advanced/tests/codeception/frontend/functional/LoginCept.php b/apps/advanced/tests/codeception/frontend/functional/LoginCept.php deleted file mode 100644 index 0fb3477..0000000 --- a/apps/advanced/tests/codeception/frontend/functional/LoginCept.php +++ /dev/null @@ -1,27 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -$I->expectTo('see that user is logged'); -$I->seeLink('Logout (erau)'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); diff --git a/apps/advanced/tests/codeception/frontend/functional/SignupCest.php b/apps/advanced/tests/codeception/frontend/functional/SignupCest.php deleted file mode 100644 index 525b037..0000000 --- a/apps/advanced/tests/codeception/frontend/functional/SignupCest.php +++ /dev/null @@ -1,90 +0,0 @@ - 'tester.email@example.com', - 'username' => 'tester', - ]); - } - - /** - * This method is called when test fails. - * @param \Codeception\Event\FailEvent $event - */ - public function _fail($event) - { - - } - - /** - * - * @param \codeception_frontend\FunctionalTester $I - * @param \Codeception\Scenario $scenario - */ - public function testUserSignup($I, $scenario) - { - $I->wantTo('ensure that signup works'); - - $signupPage = SignupPage::openBy($I); - $I->see('Signup', 'h1'); - $I->see('Please fill out the following fields to signup:'); - - $I->amGoingTo('submit signup form with no data'); - - $signupPage->submit([]); - - $I->expectTo('see validation errors'); - $I->see('Username cannot be blank.', '.help-block'); - $I->see('Email cannot be blank.', '.help-block'); - $I->see('Password cannot be blank.', '.help-block'); - - $I->amGoingTo('submit signup form with not correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that email address is wrong'); - $I->dontSee('Username cannot be blank.', '.help-block'); - $I->dontSee('Password cannot be blank.', '.help-block'); - $I->see('Email is not a valid email address.', '.help-block'); - - $I->amGoingTo('submit signup form with correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email@example.com', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that user is created'); - $I->seeRecord('common\models\User', [ - 'username' => 'tester', - 'email' => 'tester.email@example.com', - ]); - - $I->expectTo('see that user logged in'); - $I->seeLink('Logout (tester)'); - } -} diff --git a/apps/advanced/tests/codeception/frontend/functional/_bootstrap.php b/apps/advanced/tests/codeception/frontend/functional/_bootstrap.php deleted file mode 100644 index 1abc491..0000000 --- a/apps/advanced/tests/codeception/frontend/functional/_bootstrap.php +++ /dev/null @@ -1,3 +0,0 @@ - 'okirlin', - 'auth_key' => 'iwTNae9t34OmnK6l4vT4IeaTk-YWI2Rv', - 'password_hash' => '$2y$13$CXT0Rkle1EMJ/c1l5bylL.EylfmQ39O5JlHJVFpNn618OUS1HwaIi', - 'password_reset_token' => 't5GU9NwpuGYSfb7FEZMAxqtuz2PkEvv_' . time(), - 'created_at' => '1391885313', - 'updated_at' => '1391885313', - 'email' => 'brady.renner@rutherford.com', - ], - [ - 'username' => 'troy.becker', - 'auth_key' => 'EdKfXrx88weFMV0vIxuTMWKgfK2tS3Lp', - 'password_hash' => '$2y$13$g5nv41Px7VBqhS3hVsVN2.MKfgT3jFdkXEsMC4rQJLfaMa7VaJqL2', - 'password_reset_token' => '4BSNyiZNAuxjs5Mty990c47sVrgllIi_' . time(), - 'created_at' => '1391885313', - 'updated_at' => '1391885313', - 'email' => 'nicolas.dianna@hotmail.com', - 'status' => '0', - ], -]; diff --git a/apps/advanced/tests/codeception/frontend/unit/models/ContactFormTest.php b/apps/advanced/tests/codeception/frontend/unit/models/ContactFormTest.php deleted file mode 100644 index 9aaf595..0000000 --- a/apps/advanced/tests/codeception/frontend/unit/models/ContactFormTest.php +++ /dev/null @@ -1,59 +0,0 @@ -mailer->fileTransportCallback = function ($mailer, $message) { - return 'testing_message.eml'; - }; - } - - protected function tearDown() - { - unlink($this->getMessageFile()); - parent::tearDown(); - } - - public function testContact() - { - $model = new ContactForm(); - - $model->attributes = [ - 'name' => 'Tester', - 'email' => 'tester@example.com', - 'subject' => 'very important letter subject', - 'body' => 'body of current message', - ]; - - $model->sendEmail('admin@example.com'); - - $this->specify('email should be send', function () { - expect('email file should exist', file_exists($this->getMessageFile()))->true(); - }); - - $this->specify('message should contain correct data', function () use ($model) { - $emailMessage = file_get_contents($this->getMessageFile()); - - expect('email should contain user name', $emailMessage)->contains($model->name); - expect('email should contain sender email', $emailMessage)->contains($model->email); - expect('email should contain subject', $emailMessage)->contains($model->subject); - expect('email should contain body', $emailMessage)->contains($model->body); - }); - } - - private function getMessageFile() - { - return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml'; - } -} diff --git a/apps/advanced/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php b/apps/advanced/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php deleted file mode 100644 index ec65a0e..0000000 --- a/apps/advanced/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php +++ /dev/null @@ -1,88 +0,0 @@ -mailer->fileTransportCallback = function ($mailer, $message) { - return 'testing_message.eml'; - }; - } - - protected function tearDown() - { - @unlink($this->getMessageFile()); - - parent::tearDown(); - } - - public function testSendEmailWrongUser() - { - $this->specify('no user with such email, message should not be send', function () { - - $model = new PasswordResetRequestForm(); - $model->email = 'not-existing-email@example.com'; - - expect('email not send', $model->sendEmail())->false(); - - }); - - $this->specify('user is not active, message should not be send', function () { - - $model = new PasswordResetRequestForm(); - $model->email = $this->user[1]['email']; - - expect('email not send', $model->sendEmail())->false(); - - }); - } - - public function testSendEmailCorrectUser() - { - $model = new PasswordResetRequestForm(); - $model->email = $this->user[0]['email']; - $user = User::findOne(['password_reset_token' => $this->user[0]['password_reset_token']]); - - expect('email sent', $model->sendEmail())->true(); - expect('user has valid token', $user->password_reset_token)->notNull(); - - $this->specify('message has correct format', function () use ($model) { - - expect('message file exists', file_exists($this->getMessageFile()))->true(); - - $message = file_get_contents($this->getMessageFile()); - expect('message "from" is correct', $message)->contains(Yii::$app->params['supportEmail']); - expect('message "to" is correct', $message)->contains($model->email); - - }); - } - - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php' - ], - ]; - } - - private function getMessageFile() - { - return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml'; - } - -} diff --git a/apps/advanced/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php b/apps/advanced/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php deleted file mode 100644 index a2f5012..0000000 --- a/apps/advanced/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php +++ /dev/null @@ -1,44 +0,0 @@ -user[0]['password_reset_token']); - expect('password should be resetted', $form->resetPassword())->true(); - } - - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php' - ], - ]; - } - -} diff --git a/apps/advanced/tests/codeception/frontend/unit/models/SignupFormTest.php b/apps/advanced/tests/codeception/frontend/unit/models/SignupFormTest.php deleted file mode 100644 index 4d869f1..0000000 --- a/apps/advanced/tests/codeception/frontend/unit/models/SignupFormTest.php +++ /dev/null @@ -1,53 +0,0 @@ - 'some_username', - 'email' => 'some_email@example.com', - 'password' => 'some_password', - ]); - - $user = $model->signup(); - - $this->assertInstanceOf('common\models\User', $user, 'user should be valid'); - - expect('username should be correct', $user->username)->equals('some_username'); - expect('email should be correct', $user->email)->equals('some_email@example.com'); - expect('password should be correct', $user->validatePassword('some_password'))->true(); - } - - public function testNotCorrectSignup() - { - $model = new SignupForm([ - 'username' => 'troy.becker', - 'email' => 'nicolas.dianna@hotmail.com', - 'password' => 'some_password', - ]); - - expect('username and email are in use, user should not be created', $model->signup())->null(); - } - - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php', - ], - ]; - } - -} diff --git a/apps/advanced/yii.bat b/apps/advanced/yii.bat deleted file mode 100644 index d516b3a..0000000 --- a/apps/advanced/yii.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -rem ------------------------------------------------------------- -rem Yii command line bootstrap script for Windows. -rem -rem @author Qiang Xue -rem @link http://www.yiiframework.com/ -rem @copyright Copyright (c) 2008 Yii Software LLC -rem @license http://www.yiiframework.com/license/ -rem ------------------------------------------------------------- - -@setlocal - -set YII_PATH=%~dp0 - -if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe - -"%PHP_COMMAND%" "%YII_PATH%yii" %* - -@endlocal diff --git a/apps/basic/.bowerrc b/apps/basic/.bowerrc deleted file mode 100644 index 1669168..0000000 --- a/apps/basic/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory" : "vendor/bower" -} diff --git a/apps/basic/.gitignore b/apps/basic/.gitignore deleted file mode 100644 index 45bf7bf..0000000 --- a/apps/basic/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# phpstorm project files -.idea - -# netbeans project files -nbproject - -# zend studio for eclipse project files -.buildpath -.project -.settings - -# windows thumbnail cache -Thumbs.db - -# composer vendor dir -/vendor - -# composer itself is not needed -composer.phar - -# Mac DS_Store Files -.DS_Store - -# phpunit itself is not needed -phpunit.phar -# local phpunit config -/phpunit.xml diff --git a/apps/basic/LICENSE.md b/apps/basic/LICENSE.md deleted file mode 100644 index e98f03d..0000000 --- a/apps/basic/LICENSE.md +++ /dev/null @@ -1,32 +0,0 @@ -The Yii framework is free software. It is released under the terms of -the following BSD License. - -Copyright © 2008 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. diff --git a/apps/basic/README.md b/apps/basic/README.md deleted file mode 100644 index 36df778..0000000 --- a/apps/basic/README.md +++ /dev/null @@ -1,89 +0,0 @@ -Yii 2 Basic Application Template -================================ - -Yii 2 Basic Application Template is a skeleton Yii 2 application best for -rapidly creating small projects. - -The template contains the basic features including user login/logout and a contact page. -It includes all commonly used configurations that would allow you to focus on adding new -features to your application. - - -DIRECTORY STRUCTURE -------------------- - - assets/ contains assets definition - commands/ contains console commands (controllers) - config/ contains application configurations - controllers/ contains Web controller classes - mail/ contains view files for e-mails - models/ contains model classes - runtime/ contains files generated during runtime - tests/ contains various tests for the basic application - vendor/ contains dependent 3rd-party packages - views/ contains view files for the Web application - web/ contains the entry script and Web resources - - - -REQUIREMENTS ------------- - -The minimum requirement by this application template that your Web server supports PHP 5.4.0. - - -INSTALLATION ------------- - -### Install from an Archive File - -Extract the archive file downloaded from [yiiframework.com](http://www.yiiframework.com/download/) to -a directory named `basic` that is directly under the Web root. - -You can then access the application through the following URL: - -~~~ -http://localhost/basic/web/ -~~~ - - -### Install via Composer - -If you do not have [Composer](http://getcomposer.org/), you may install it by following the instructions -at [getcomposer.org](http://getcomposer.org/doc/00-intro.md#installation-nix). - -You can then install this application template using the following command: - -~~~ -php composer.phar global require "fxp/composer-asset-plugin:1.0.0-beta4" -php composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic -~~~ - -Now you should be able to access the application through the following URL, assuming `basic` is the directory -directly under the Web root. - -~~~ -http://localhost/basic/web/ -~~~ - - -CONFIGURATION -------------- - -### Database - -Edit the file `config/db.php` with real data, for example: - -```php -return [ - 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2basic', - 'username' => 'root', - 'password' => '1234', - 'charset' => 'utf8', -]; -``` - -**NOTE:** Yii won't create the database for you, this has to be done manually before you can access it. - -Also check and edit the other files in the `config/` directory to customize your application. diff --git a/apps/basic/assets/AppAsset.php b/apps/basic/assets/AppAsset.php deleted file mode 100644 index 0e495a8..0000000 --- a/apps/basic/assets/AppAsset.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @since 2.0 - */ -class AppAsset extends AssetBundle -{ - public $basePath = '@webroot'; - public $baseUrl = '@web'; - public $css = [ - 'css/site.css', - ]; - public $js = [ - ]; - public $depends = [ - 'yii\web\YiiAsset', - 'yii\bootstrap\BootstrapAsset', - ]; -} diff --git a/apps/basic/commands/HelloController.php b/apps/basic/commands/HelloController.php deleted file mode 100644 index 86ab8b8..0000000 --- a/apps/basic/commands/HelloController.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @since 2.0 - */ -class HelloController extends Controller -{ - /** - * This command echoes what you have entered as the message. - * @param string $message the message to be echoed. - */ - public function actionIndex($message = 'hello world') - { - echo $message . "\n"; - } -} diff --git a/apps/basic/composer.json b/apps/basic/composer.json deleted file mode 100644 index faf0732..0000000 --- a/apps/basic/composer.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "yiisoft/yii2-app-basic", - "description": "Yii 2 Basic Application Template", - "keywords": ["yii2", "framework", "basic", "application template"], - "homepage": "http://www.yiiframework.com/", - "type": "project", - "license": "BSD-3-Clause", - "support": { - "issues": "https://github.com/yiisoft/yii2/issues?state=open", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", - "source": "https://github.com/yiisoft/yii2" - }, - "minimum-stability": "stable", - "require": { - "php": ">=5.4.0", - "yiisoft/yii2": "*", - "yiisoft/yii2-bootstrap": "*", - "yiisoft/yii2-swiftmailer": "*" - }, - "require-dev": { - "yiisoft/yii2-codeception": "*", - "yiisoft/yii2-debug": "*", - "yiisoft/yii2-gii": "*", - "yiisoft/yii2-faker": "*" - }, - "config": { - "process-timeout": 1800 - }, - "scripts": { - "post-create-project-cmd": [ - "yii\\composer\\Installer::postCreateProject" - ] - }, - "extra": { - "yii\\composer\\Installer::postCreateProject": { - "setPermission": [ - { - "runtime": "0777", - "web/assets": "0777", - "yii": "0755" - } - ], - "generateCookieValidationKey": [ - "config/web.php" - ] - }, - "asset-installer-paths": { - "npm-asset-library": "vendor/npm", - "bower-asset-library": "vendor/bower" - } - } -} diff --git a/apps/basic/config/console.php b/apps/basic/config/console.php deleted file mode 100644 index 31ed9c7..0000000 --- a/apps/basic/config/console.php +++ /dev/null @@ -1,31 +0,0 @@ - 'basic-console', - 'basePath' => dirname(__DIR__), - 'bootstrap' => ['log', 'gii'], - 'controllerNamespace' => 'app\commands', - 'modules' => [ - 'gii' => 'yii\gii\Module', - ], - 'components' => [ - 'cache' => [ - 'class' => 'yii\caching\FileCache', - ], - 'log' => [ - 'targets' => [ - [ - 'class' => 'yii\log\FileTarget', - 'levels' => ['error', 'warning'], - ], - ], - ], - 'db' => $db, - ], - 'params' => $params, -]; diff --git a/apps/basic/config/db.php b/apps/basic/config/db.php deleted file mode 100644 index c4c1252..0000000 --- a/apps/basic/config/db.php +++ /dev/null @@ -1,9 +0,0 @@ - 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2basic', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', -]; diff --git a/apps/basic/config/params.php b/apps/basic/config/params.php deleted file mode 100644 index 6ebf279..0000000 --- a/apps/basic/config/params.php +++ /dev/null @@ -1,5 +0,0 @@ - 'admin@example.com', -]; diff --git a/apps/basic/config/web.php b/apps/basic/config/web.php deleted file mode 100644 index 1632a5a..0000000 --- a/apps/basic/config/web.php +++ /dev/null @@ -1,54 +0,0 @@ - 'basic', - 'basePath' => dirname(__DIR__), - 'bootstrap' => ['log'], - 'components' => [ - 'request' => [ - // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation - 'cookieValidationKey' => '', - ], - 'cache' => [ - 'class' => 'yii\caching\FileCache', - ], - 'user' => [ - 'identityClass' => 'app\models\User', - 'enableAutoLogin' => true, - ], - 'errorHandler' => [ - 'errorAction' => 'site/error', - ], - 'mailer' => [ - 'class' => 'yii\swiftmailer\Mailer', - // send all mails to a file by default. You have to set - // 'useFileTransport' to false and configure a transport - // for the mailer to send real emails. - 'useFileTransport' => true, - ], - 'log' => [ - 'traceLevel' => YII_DEBUG ? 3 : 0, - 'targets' => [ - [ - 'class' => 'yii\log\FileTarget', - 'levels' => ['error', 'warning'], - ], - ], - ], - 'db' => require(__DIR__ . '/db.php'), - ], - 'params' => $params, -]; - -if (YII_ENV_DEV) { - // configuration adjustments for 'dev' environment - $config['bootstrap'][] = 'debug'; - $config['modules']['debug'] = 'yii\debug\Module'; - - $config['bootstrap'][] = 'gii'; - $config['modules']['gii'] = 'yii\gii\Module'; -} - -return $config; diff --git a/apps/basic/controllers/SiteController.php b/apps/basic/controllers/SiteController.php deleted file mode 100644 index f959941..0000000 --- a/apps/basic/controllers/SiteController.php +++ /dev/null @@ -1,96 +0,0 @@ - [ - 'class' => AccessControl::className(), - 'only' => ['logout'], - 'rules' => [ - [ - 'actions' => ['logout'], - 'allow' => true, - 'roles' => ['@'], - ], - ], - ], - 'verbs' => [ - 'class' => VerbFilter::className(), - 'actions' => [ - 'logout' => ['post'], - ], - ], - ]; - } - - public function actions() - { - return [ - 'error' => [ - 'class' => 'yii\web\ErrorAction', - ], - 'captcha' => [ - 'class' => 'yii\captcha\CaptchaAction', - 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, - ], - ]; - } - - public function actionIndex() - { - return $this->render('index'); - } - - public function actionLogin() - { - if (!\Yii::$app->user->isGuest) { - return $this->goHome(); - } - - $model = new LoginForm(); - if ($model->load(Yii::$app->request->post()) && $model->login()) { - return $this->goBack(); - } else { - return $this->render('login', [ - 'model' => $model, - ]); - } - } - - public function actionLogout() - { - Yii::$app->user->logout(); - - return $this->goHome(); - } - - public function actionContact() - { - $model = new ContactForm(); - if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) { - Yii::$app->session->setFlash('contactFormSubmitted'); - - return $this->refresh(); - } else { - return $this->render('contact', [ - 'model' => $model, - ]); - } - } - - public function actionAbout() - { - return $this->render('about'); - } -} diff --git a/apps/basic/mail/layouts/html.php b/apps/basic/mail/layouts/html.php deleted file mode 100644 index bddbc61..0000000 --- a/apps/basic/mail/layouts/html.php +++ /dev/null @@ -1,22 +0,0 @@ - -beginPage() ?> - - - - - <?= Html::encode($this->title) ?> - head() ?> - - - beginBody() ?> - - endBody() ?> - - -endPage() ?> diff --git a/apps/basic/models/ContactForm.php b/apps/basic/models/ContactForm.php deleted file mode 100644 index d4052ee..0000000 --- a/apps/basic/models/ContactForm.php +++ /dev/null @@ -1,64 +0,0 @@ - 'Verification Code', - ]; - } - - /** - * Sends an email to the specified email address using the information collected by this model. - * @param string $email the target email address - * @return boolean whether the model passes validation - */ - public function contact($email) - { - if ($this->validate()) { - Yii::$app->mailer->compose() - ->setTo($email) - ->setFrom([$this->email => $this->name]) - ->setSubject($this->subject) - ->setTextBody($this->body) - ->send(); - - return true; - } else { - return false; - } - } -} diff --git a/apps/basic/models/LoginForm.php b/apps/basic/models/LoginForm.php deleted file mode 100644 index 7bd44d4..0000000 --- a/apps/basic/models/LoginForm.php +++ /dev/null @@ -1,79 +0,0 @@ -hasErrors()) { - $user = $this->getUser(); - - if (!$user || !$user->validatePassword($this->password)) { - $this->addError($attribute, 'Incorrect username or password.'); - } - } - } - - /** - * Logs in a user using the provided username and password. - * @return boolean whether the user is logged in successfully - */ - public function login() - { - if ($this->validate()) { - return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0); - } else { - return false; - } - } - - /** - * Finds user by [[username]] - * - * @return User|null - */ - public function getUser() - { - if ($this->_user === false) { - $this->_user = User::findByUsername($this->username); - } - - return $this->_user; - } -} diff --git a/apps/basic/models/User.php b/apps/basic/models/User.php deleted file mode 100644 index cbfb9fe..0000000 --- a/apps/basic/models/User.php +++ /dev/null @@ -1,103 +0,0 @@ - [ - 'id' => '100', - 'username' => 'admin', - 'password' => 'admin', - 'authKey' => 'test100key', - 'accessToken' => '100-token', - ], - '101' => [ - 'id' => '101', - 'username' => 'demo', - 'password' => 'demo', - 'authKey' => 'test101key', - 'accessToken' => '101-token', - ], - ]; - - /** - * @inheritdoc - */ - public static function findIdentity($id) - { - return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; - } - - /** - * @inheritdoc - */ - public static function findIdentityByAccessToken($token, $type = null) - { - foreach (self::$users as $user) { - if ($user['accessToken'] === $token) { - return new static($user); - } - } - - return null; - } - - /** - * Finds user by username - * - * @param string $username - * @return static|null - */ - public static function findByUsername($username) - { - foreach (self::$users as $user) { - if (strcasecmp($user['username'], $username) === 0) { - return new static($user); - } - } - - return null; - } - - /** - * @inheritdoc - */ - public function getId() - { - return $this->id; - } - - /** - * @inheritdoc - */ - public function getAuthKey() - { - return $this->authKey; - } - - /** - * @inheritdoc - */ - public function validateAuthKey($authKey) - { - return $this->authKey === $authKey; - } - - /** - * Validates password - * - * @param string $password password to validate - * @return boolean if password provided is valid for current user - */ - public function validatePassword($password) - { - return $this->password === $password; - } -} diff --git a/apps/basic/requirements.php b/apps/basic/requirements.php deleted file mode 100644 index 4da0631..0000000 --- a/apps/basic/requirements.php +++ /dev/null @@ -1,139 +0,0 @@ -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(); - -$gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; -$gdOK = $imagickOK = false; - -if (extension_loaded('imagick')) { - $imagick = new Imagick(); - $imagickFormats = $imagick->queryFormats('PNG'); - if (in_array('PNG', $imagickFormats)) { - $imagickOK = true; - } else { - $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; - } -} - -if (extension_loaded('gd')) { - $gdInfo = gd_info(); - if (!empty($gdInfo['FreeType Support'])) { - $gdOK = true; - } else { - $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; - } -} - -/** - * 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.', - ), - array( - 'name' => 'PDO PostgreSQL extension', - 'mandatory' => false, - 'condition' => extension_loaded('pdo_pgsql'), - 'by' => 'All DB-related classes', - 'memo' => 'Required for PostgreSQL database.', - ), - // Cache : - array( - 'name' => 'Memcache extension', - 'mandatory' => false, - 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), - 'by' => 'MemCache', - 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : '' - ), - array( - 'name' => 'APC extension', - 'mandatory' => false, - 'condition' => extension_loaded('apc'), - 'by' => 'ApcCache', - ), - // CAPTCHA: - array( - 'name' => 'GD PHP extension with FreeType support', - 'mandatory' => false, - 'condition' => $gdOK, - 'by' => 'Captcha', - 'memo' => $gdMemo, - ), - array( - 'name' => 'ImageMagick PHP extension with PNG support', - 'mandatory' => false, - 'condition' => $imagickOK, - 'by' => 'Captcha', - 'memo' => $imagickMemo, - ), - // 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 deleted file mode 100644 index c96a04f..0000000 --- a/apps/basic/runtime/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/apps/basic/tests/README.md b/apps/basic/tests/README.md deleted file mode 100644 index f14db26..0000000 --- a/apps/basic/tests/README.md +++ /dev/null @@ -1,63 +0,0 @@ -This directory contains various tests for the basic application. - -Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/). - -After creating the basic application, follow these steps to prepare for the tests: - -1. Install Codeception if it's not yet installed: - -``` -composer global require "codeception/codeception=2.0.*" -composer global require "codeception/specify=*" -composer global require "codeception/verify=*" -``` - -If you've never used Composer for global packages run `composer global status`. It should output: - -``` -Changed current directory to -``` - -Then add `/vendor/bin` to you `PATH` environment variable. Now we're able to use `codecept` from command -line globally. - -2. Install faker extension by running the following from template root directory where `composer.json` is: - -``` -composer require --dev yiisoft/yii2-faker:* -``` - -3. Create `yii2_basic_tests` database and update it by applying migrations: - -``` -codeception/bin/yii migrate -``` - -4. Build the test suites: - -``` -codecept build -``` - -5. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in -webserver. In the `web` directory execute the following: - -``` -php -S localhost:8080 -``` - -6. Now you can run the tests with the following commands: - -``` -# run all available tests -codecept run -# run acceptance tests -codecept run acceptance -# run functional tests -codecept run functional -# run unit tests -codecept run unit -``` - -Please refer to [Codeception tutorial](http://codeception.com/docs/01-Introduction) for -more details about writing and running acceptance, functional and unit tests. diff --git a/apps/basic/tests/codeception.yml b/apps/basic/tests/codeception.yml deleted file mode 100644 index 0a45a0c..0000000 --- a/apps/basic/tests/codeception.yml +++ /dev/null @@ -1,16 +0,0 @@ -actor: Tester -paths: - tests: codeception - log: codeception/_output - data: codeception/_data - helpers: codeception/_support -settings: - bootstrap: _bootstrap.php - suite_class: \PHPUnit_Framework_TestSuite - memory_limit: 1024M - log: true - colors: true -config: - # the entry script URL (with host info) for functional and acceptance tests - # PLEASE ADJUST IT TO THE ACTUAL ENTRY SCRIPT URL - test_entry_url: http://localhost:8080/index-test.php \ No newline at end of file diff --git a/apps/basic/tests/codeception/.gitignore b/apps/basic/tests/codeception/.gitignore deleted file mode 100644 index 985dbb4..0000000 --- a/apps/basic/tests/codeception/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# these files are auto generated by codeception build -/unit/UnitTester.php -/functional/FunctionalTester.php -/acceptance/AcceptanceTester.php diff --git a/apps/basic/tests/codeception/_bootstrap.php b/apps/basic/tests/codeception/_bootstrap.php deleted file mode 100644 index 755029e..0000000 --- a/apps/basic/tests/codeception/_bootstrap.php +++ /dev/null @@ -1,16 +0,0 @@ - $value) { - $inputType = $field === 'body' ? 'textarea' : 'input'; - $this->actor->fillField($inputType . '[name="ContactForm[' . $field . ']"]', $value); - } - $this->actor->click('contact-button'); - } -} diff --git a/apps/basic/tests/codeception/_pages/LoginPage.php b/apps/basic/tests/codeception/_pages/LoginPage.php deleted file mode 100644 index c3a2ef2..0000000 --- a/apps/basic/tests/codeception/_pages/LoginPage.php +++ /dev/null @@ -1,25 +0,0 @@ -actor->fillField('input[name="LoginForm[username]"]', $username); - $this->actor->fillField('input[name="LoginForm[password]"]', $password); - $this->actor->click('login-button'); - } -} diff --git a/apps/basic/tests/codeception/acceptance.suite.yml b/apps/basic/tests/codeception/acceptance.suite.yml deleted file mode 100644 index 1781b00..0000000 --- a/apps/basic/tests/codeception/acceptance.suite.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Codeception Test Suite Configuration - -# suite for acceptance tests. -# perform tests in browser using the Selenium-like tools. -# powered by Mink (http://mink.behat.org). -# (tip: that's what your customer will see). -# (tip: test your ajax and javascript by one of Mink drivers). - -# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. - -class_name: AcceptanceTester -modules: - enabled: - - PhpBrowser -# you can use WebDriver instead of PhpBrowser to test javascript and ajax. -# This will require you to install selenium. See http://codeception.com/docs/04-AcceptanceTests#Selenium -# "restart" option is used by the WebDriver to start each time per test-file new session and cookies, -# it is useful if you want to login in your app in each test. -# - WebDriver - config: - PhpBrowser: -# PLEASE ADJUST IT TO THE ACTUAL ENTRY POINT WITHOUT PATH INFO - url: http://localhost:8080 -# WebDriver: -# url: http://localhost:8080 -# browser: firefox -# restart: true diff --git a/apps/basic/tests/codeception/acceptance/AboutCept.php b/apps/basic/tests/codeception/acceptance/AboutCept.php deleted file mode 100644 index 1ef220e..0000000 --- a/apps/basic/tests/codeception/acceptance/AboutCept.php +++ /dev/null @@ -1,8 +0,0 @@ -wantTo('ensure that about works'); -AboutPage::openBy($I); -$I->see('About', 'h1'); diff --git a/apps/basic/tests/codeception/acceptance/ContactCept.php b/apps/basic/tests/codeception/acceptance/ContactCept.php deleted file mode 100644 index 98ba2ef..0000000 --- a/apps/basic/tests/codeception/acceptance/ContactCept.php +++ /dev/null @@ -1,49 +0,0 @@ -wantTo('ensure that contact works'); - -$contactPage = ContactPage::openBy($I); - -$I->see('Contact', 'h1'); - -$I->amGoingTo('submit contact form with no data'); -$contactPage->submit([]); -$I->expectTo('see validations errors'); -$I->see('Contact', 'h1'); -$I->see('Name cannot be blank'); -$I->see('Email cannot be blank'); -$I->see('Subject cannot be blank'); -$I->see('Body cannot be blank'); -$I->see('The verification code is incorrect'); - -$I->amGoingTo('submit contact form with not correct email'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester.email', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->expectTo('see that email adress is wrong'); -$I->dontSee('Name cannot be blank', '.help-inline'); -$I->see('Email is not a valid email address.'); -$I->dontSee('Subject cannot be blank', '.help-inline'); -$I->dontSee('Body cannot be blank', '.help-inline'); -$I->dontSee('The verification code is incorrect', '.help-inline'); - -$I->amGoingTo('submit contact form with correct data'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester@example.com', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->dontSeeElement('#contact-form'); -$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); diff --git a/apps/basic/tests/codeception/acceptance/HomeCept.php b/apps/basic/tests/codeception/acceptance/HomeCept.php deleted file mode 100644 index 369ab7f..0000000 --- a/apps/basic/tests/codeception/acceptance/HomeCept.php +++ /dev/null @@ -1,9 +0,0 @@ -wantTo('ensure that home page works'); -$I->amOnPage(Yii::$app->homeUrl); -$I->see('My Company'); -$I->seeLink('About'); -$I->click('About'); -$I->see('This is the About page.'); diff --git a/apps/basic/tests/codeception/acceptance/LoginCept.php b/apps/basic/tests/codeception/acceptance/LoginCept.php deleted file mode 100644 index 4f022e1..0000000 --- a/apps/basic/tests/codeception/acceptance/LoginCept.php +++ /dev/null @@ -1,32 +0,0 @@ -wantTo('ensure that login works'); - -$loginPage = LoginPage::openBy($I); - -$I->see('Login', 'h1'); - -$I->amGoingTo('try to login with empty credentials'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.'); -$I->see('Password cannot be blank.'); - -$I->amGoingTo('try to login with wrong credentials'); -$loginPage->login('admin', 'wrong'); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('admin', 'admin'); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->expectTo('see user info'); -$I->see('Logout (admin)'); diff --git a/apps/basic/tests/codeception/acceptance/_bootstrap.php b/apps/basic/tests/codeception/acceptance/_bootstrap.php deleted file mode 100644 index 36f9f1d..0000000 --- a/apps/basic/tests/codeception/acceptance/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ - [ - 'fixture' => [ - 'class' => 'yii\faker\FixtureController', - 'fixtureDataPath' => '@tests/codeception/fixtures', - 'templatePath' => '@tests/codeception/templates', - 'namespace' => 'tests\codeception\fixtures', - ], - ], - ] -); - -$application = new yii\console\Application($config); -$exitCode = $application->run(); -exit($exitCode); diff --git a/apps/basic/tests/codeception/bin/yii.bat b/apps/basic/tests/codeception/bin/yii.bat deleted file mode 100644 index d516b3a..0000000 --- a/apps/basic/tests/codeception/bin/yii.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -rem ------------------------------------------------------------- -rem Yii command line bootstrap script for Windows. -rem -rem @author Qiang Xue -rem @link http://www.yiiframework.com/ -rem @copyright Copyright (c) 2008 Yii Software LLC -rem @license http://www.yiiframework.com/license/ -rem ------------------------------------------------------------- - -@setlocal - -set YII_PATH=%~dp0 - -if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe - -"%PHP_COMMAND%" "%YII_PATH%yii" %* - -@endlocal diff --git a/apps/basic/tests/codeception/config/acceptance.php b/apps/basic/tests/codeception/config/acceptance.php deleted file mode 100644 index c688575..0000000 --- a/apps/basic/tests/codeception/config/acceptance.php +++ /dev/null @@ -1,11 +0,0 @@ - [ - 'db' => [ - 'dsn' => 'mysql:host=localhost;dbname=yii2_basic_tests', - ], - 'mailer' => [ - 'useFileTransport' => true, - ], - 'urlManager' => [ - 'showScriptName' => true, - ], - ], -]; diff --git a/apps/basic/tests/codeception/config/functional.php b/apps/basic/tests/codeception/config/functional.php deleted file mode 100644 index 6d22bd9..0000000 --- a/apps/basic/tests/codeception/config/functional.php +++ /dev/null @@ -1,25 +0,0 @@ - [ - 'request' => [ - // it's not recommended to run functional tests with CSRF validation enabled - 'enableCsrfValidation' => false, - // but if you absolutely need it set cookie domain to localhost - /* - 'csrfCookie' => [ - 'domain' => 'localhost', - ], - */ - ], - ], - ] -); diff --git a/apps/basic/tests/codeception/config/unit.php b/apps/basic/tests/codeception/config/unit.php deleted file mode 100644 index 5bab5ea..0000000 --- a/apps/basic/tests/codeception/config/unit.php +++ /dev/null @@ -1,11 +0,0 @@ -wantTo('ensure that about works'); -AboutPage::openBy($I); -$I->see('About', 'h1'); diff --git a/apps/basic/tests/codeception/functional/ContactCept.php b/apps/basic/tests/codeception/functional/ContactCept.php deleted file mode 100644 index 4760405..0000000 --- a/apps/basic/tests/codeception/functional/ContactCept.php +++ /dev/null @@ -1,46 +0,0 @@ -wantTo('ensure that contact works'); - -$contactPage = ContactPage::openBy($I); - -$I->see('Contact', 'h1'); - -$I->amGoingTo('submit contact form with no data'); -$contactPage->submit([]); -$I->expectTo('see validations errors'); -$I->see('Contact', 'h1'); -$I->see('Name cannot be blank'); -$I->see('Email cannot be blank'); -$I->see('Subject cannot be blank'); -$I->see('Body cannot be blank'); -$I->see('The verification code is incorrect'); - -$I->amGoingTo('submit contact form with not correct email'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester.email', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->expectTo('see that email adress is wrong'); -$I->dontSee('Name cannot be blank', '.help-inline'); -$I->see('Email is not a valid email address.'); -$I->dontSee('Subject cannot be blank', '.help-inline'); -$I->dontSee('Body cannot be blank', '.help-inline'); -$I->dontSee('The verification code is incorrect', '.help-inline'); - -$I->amGoingTo('submit contact form with correct data'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester@example.com', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->dontSeeElement('#contact-form'); -$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); diff --git a/apps/basic/tests/codeception/functional/HomeCept.php b/apps/basic/tests/codeception/functional/HomeCept.php deleted file mode 100644 index 80aa551..0000000 --- a/apps/basic/tests/codeception/functional/HomeCept.php +++ /dev/null @@ -1,9 +0,0 @@ -wantTo('ensure that home page works'); -$I->amOnPage(Yii::$app->homeUrl); -$I->see('My Company'); -$I->seeLink('About'); -$I->click('About'); -$I->see('This is the About page.'); diff --git a/apps/basic/tests/codeception/functional/LoginCept.php b/apps/basic/tests/codeception/functional/LoginCept.php deleted file mode 100644 index 991d27c..0000000 --- a/apps/basic/tests/codeception/functional/LoginCept.php +++ /dev/null @@ -1,26 +0,0 @@ -wantTo('ensure that login works'); - -$loginPage = LoginPage::openBy($I); - -$I->see('Login', 'h1'); - -$I->amGoingTo('try to login with empty credentials'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.'); -$I->see('Password cannot be blank.'); - -$I->amGoingTo('try to login with wrong credentials'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('admin', 'admin'); -$I->expectTo('see user info'); -$I->see('Logout (admin)'); diff --git a/apps/basic/tests/codeception/functional/_bootstrap.php b/apps/basic/tests/codeception/functional/_bootstrap.php deleted file mode 100644 index 8aac091..0000000 --- a/apps/basic/tests/codeception/functional/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ -mailer->fileTransportCallback = function ($mailer, $message) { - return 'testing_message.eml'; - }; - } - - protected function tearDown() - { - unlink($this->getMessageFile()); - parent::tearDown(); - } - - public function testContact() - { - $model = $this->getMock('app\models\ContactForm', ['validate']); - $model->expects($this->once())->method('validate')->will($this->returnValue(true)); - - $model->attributes = [ - 'name' => 'Tester', - 'email' => 'tester@example.com', - 'subject' => 'very important letter subject', - 'body' => 'body of current message', - ]; - - $model->contact('admin@example.com'); - - $this->specify('email should be send', function () { - expect('email file should exist', file_exists($this->getMessageFile()))->true(); - }); - - $this->specify('message should contain correct data', function () use ($model) { - $emailMessage = file_get_contents($this->getMessageFile()); - - expect('email should contain user name', $emailMessage)->contains($model->name); - expect('email should contain sender email', $emailMessage)->contains($model->email); - expect('email should contain subject', $emailMessage)->contains($model->subject); - expect('email should contain body', $emailMessage)->contains($model->body); - }); - } - - private function getMessageFile() - { - return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml'; - } - -} diff --git a/apps/basic/tests/codeception/unit/models/LoginFormTest.php b/apps/basic/tests/codeception/unit/models/LoginFormTest.php deleted file mode 100644 index c7f971a..0000000 --- a/apps/basic/tests/codeception/unit/models/LoginFormTest.php +++ /dev/null @@ -1,61 +0,0 @@ -user->logout(); - parent::tearDown(); - } - - public function testLoginNoUser() - { - $model = new LoginForm([ - 'username' => 'not_existing_username', - 'password' => 'not_existing_password', - ]); - - $this->specify('user should not be able to login, when there is no identity', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('user should not be logged in', Yii::$app->user->isGuest)->true(); - }); - } - - public function testLoginWrongPassword() - { - $model = new LoginForm([ - 'username' => 'demo', - 'password' => 'wrong_password', - ]); - - $this->specify('user should not be able to login with wrong password', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('error message should be set', $model->errors)->hasKey('password'); - expect('user should not be logged in', Yii::$app->user->isGuest)->true(); - }); - } - - public function testLoginCorrect() - { - $model = new LoginForm([ - 'username' => 'demo', - 'password' => 'demo', - ]); - - $this->specify('user should be able to login with correct credentials', function () use ($model) { - expect('model should login user', $model->login())->true(); - expect('error message should not be set', $model->errors)->hasntKey('password'); - expect('user should be logged in', Yii::$app->user->isGuest)->false(); - }); - } - -} diff --git a/apps/basic/tests/codeception/unit/models/UserTest.php b/apps/basic/tests/codeception/unit/models/UserTest.php deleted file mode 100644 index f4f4f4b..0000000 --- a/apps/basic/tests/codeception/unit/models/UserTest.php +++ /dev/null @@ -1,17 +0,0 @@ -loadFixtures(['user']); - } - - // TODO add test methods here -} diff --git a/apps/basic/tests/codeception/unit/templates/fixtures/.gitkeep b/apps/basic/tests/codeception/unit/templates/fixtures/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/basic/views/layouts/main.php b/apps/basic/views/layouts/main.php deleted file mode 100644 index b9dcfb9..0000000 --- a/apps/basic/views/layouts/main.php +++ /dev/null @@ -1,69 +0,0 @@ - -beginPage() ?> - - - - - - - <?= Html::encode($this->title) ?> - head() ?> - - - -beginBody() ?> -
- 'My Company', - 'brandUrl' => Yii::$app->homeUrl, - 'options' => [ - 'class' => 'navbar-inverse navbar-fixed-top', - ], - ]); - echo Nav::widget([ - 'options' => ['class' => 'navbar-nav navbar-right'], - 'items' => [ - ['label' => 'Home', 'url' => ['/site/index']], - ['label' => 'About', 'url' => ['/site/about']], - ['label' => 'Contact', 'url' => ['/site/contact']], - Yii::$app->user->isGuest ? - ['label' => 'Login', 'url' => ['/site/login']] : - ['label' => 'Logout (' . Yii::$app->user->identity->username . ')', - 'url' => ['/site/logout'], - 'linkOptions' => ['data-method' => 'post']], - ], - ]); - NavBar::end(); - ?> - -
- isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], - ]) ?> - -
-
- -
-
-

© My Company

-

-
-
- -endBody() ?> - - -endPage() ?> diff --git a/apps/basic/views/site/about.php b/apps/basic/views/site/about.php deleted file mode 100644 index 13d85a6..0000000 --- a/apps/basic/views/site/about.php +++ /dev/null @@ -1,16 +0,0 @@ -title = 'About'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- -

- 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 deleted file mode 100644 index e964a34..0000000 --- a/apps/basic/views/site/contact.php +++ /dev/null @@ -1,57 +0,0 @@ -title = 'Contact'; -$this->params['breadcrumbs'][] = $this->title; -?> -
-

title) ?>

- - session->hasFlash('contactFormSubmitted')): ?> - -
- Thank you for contacting us. We will respond to you as soon as possible. -
- -

- Note that if you turn on the Yii debugger, you should be able - to view the mail message on the mail panel of the debugger. - mailer->useFileTransport): ?> - Because the application is in development mode, the email is not sent but saved as - a file under mailer->fileTransportPath) ?>. - Please configure the useFileTransport property of the mail - application component to be false to enable email sending. - -

- - - -

- If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. -

- -
-
- 'contact-form']); ?> - field($model, 'name') ?> - field($model, 'email') ?> - field($model, 'subject') ?> - field($model, 'body')->textArea(['rows' => 6]) ?> - field($model, 'verifyCode')->widget(Captcha::className(), [ - 'template' => '
{image}
{input}
', - ]) ?> -
- 'btn btn-primary', 'name' => 'contact-button']) ?> -
- -
-
- - -
diff --git a/apps/basic/views/site/error.php b/apps/basic/views/site/error.php deleted file mode 100644 index b9812c4..0000000 --- a/apps/basic/views/site/error.php +++ /dev/null @@ -1,27 +0,0 @@ -title = $name; -?> -
- -

title) ?>

- -
- -
- -

- The above error occurred while the Web server was processing your request. -

-

- Please contact us if you think this is a server error. Thank you. -

- -
diff --git a/apps/basic/views/site/index.php b/apps/basic/views/site/index.php deleted file mode 100644 index a00ee4d..0000000 --- a/apps/basic/views/site/index.php +++ /dev/null @@ -1,51 +0,0 @@ -title = 'My Yii Application'; -?> -
- -
-

Congratulations!

- -

You have successfully created your Yii-powered application.

- -

Get started with Yii

-
- -
- -
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Documentation »

-
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Forum »

-
-
-

Heading

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip - ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu - fugiat nulla pariatur.

- -

Yii Extensions »

-
-
- -
-
diff --git a/apps/basic/views/site/login.php b/apps/basic/views/site/login.php deleted file mode 100644 index 916be98..0000000 --- a/apps/basic/views/site/login.php +++ /dev/null @@ -1,46 +0,0 @@ -title = 'Login'; -$this->params['breadcrumbs'][] = $this->title; -?> - diff --git a/apps/basic/web/assets/.gitignore b/apps/basic/web/assets/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/apps/basic/web/assets/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/apps/basic/web/css/site.css b/apps/basic/web/css/site.css deleted file mode 100644 index 698be70..0000000 --- a/apps/basic/web/css/site.css +++ /dev/null @@ -1,91 +0,0 @@ -html, -body { - height: 100%; -} - -.wrap { - min-height: 100%; - height: auto; - margin: 0 auto -60px; - padding: 0 0 60px; -} - -.wrap > .container { - padding: 70px 15px 20px; -} - -.footer { - height: 60px; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - padding-top: 20px; -} - -.jumbotron { - text-align: center; - background-color: transparent; -} - -.jumbotron .btn { - font-size: 21px; - padding: 14px 24px; -} - -.not-set { - color: #c55; - font-style: italic; -} - -/* add sorting icons to gridview sort links */ -a.asc:after, a.desc:after { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: normal; - line-height: 1; - padding-left: 5px; -} - -a.asc:after { - content: /*"\e113"*/ "\e151"; -} - -a.desc:after { - content: /*"\e114"*/ "\e152"; -} - -.sort-numerical a.asc:after { - content: "\e153"; -} - -.sort-numerical a.desc:after { - content: "\e154"; -} - -.sort-ordinal a.asc:after { - content: "\e155"; -} - -.sort-ordinal a.desc:after { - content: "\e156"; -} - -.grid-view th { - white-space: nowrap; -} - -.hint-block { - display: block; - margin-top: 5px; - color: #999; -} - -.error-summary { - color: #a94442; - background: #fdf7f7; - border-left: 3px solid #eed3d7; - padding: 10px 20px; - margin: 0 0 15px 0; -} diff --git a/apps/basic/web/favicon.ico b/apps/basic/web/favicon.ico deleted file mode 100644 index 580ed73..0000000 Binary files a/apps/basic/web/favicon.ico and /dev/null differ diff --git a/apps/basic/web/index-test.php b/apps/basic/web/index-test.php deleted file mode 100644 index 32b4ce3..0000000 --- a/apps/basic/web/index-test.php +++ /dev/null @@ -1,16 +0,0 @@ -run(); diff --git a/apps/basic/web/index.php b/apps/basic/web/index.php deleted file mode 100644 index d1e070a..0000000 --- a/apps/basic/web/index.php +++ /dev/null @@ -1,12 +0,0 @@ -run(); diff --git a/apps/basic/web/robots.txt b/apps/basic/web/robots.txt deleted file mode 100644 index 6f27bb6..0000000 --- a/apps/basic/web/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: \ No newline at end of file diff --git a/apps/basic/yii b/apps/basic/yii deleted file mode 100755 index b032ebd..0000000 --- a/apps/basic/yii +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env php -run(); -exit($exitCode); diff --git a/apps/basic/yii.bat b/apps/basic/yii.bat deleted file mode 100644 index d516b3a..0000000 --- a/apps/basic/yii.bat +++ /dev/null @@ -1,20 +0,0 @@ -@echo off - -rem ------------------------------------------------------------- -rem Yii command line bootstrap script for Windows. -rem -rem @author Qiang Xue -rem @link http://www.yiiframework.com/ -rem @copyright Copyright (c) 2008 Yii Software LLC -rem @license http://www.yiiframework.com/license/ -rem ------------------------------------------------------------- - -@setlocal - -set YII_PATH=%~dp0 - -if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe - -"%PHP_COMMAND%" "%YII_PATH%yii" %* - -@endlocal diff --git a/apps/benchmark/LICENSE.md b/apps/benchmark/LICENSE.md deleted file mode 100644 index e98f03d..0000000 --- a/apps/benchmark/LICENSE.md +++ /dev/null @@ -1,32 +0,0 @@ -The Yii framework is free software. It is released under the terms of -the following BSD License. - -Copyright © 2008 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. diff --git a/apps/benchmark/README.md b/apps/benchmark/README.md deleted file mode 100644 index 27f598a..0000000 --- a/apps/benchmark/README.md +++ /dev/null @@ -1,58 +0,0 @@ -Yii 2 Benchmark Application -=========================== - -**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. - - -Yii 2 Benchmark Application is an application built to demonstrate the minimal overhead -introduced by the Yii framework. The application contains a single page which only renders -the "hello world" string. - -The application attempts to simulate the scenario in which you can achieve the best performance -when using Yii. It does so by assuming that both of the main application configuration and the page -content are cached in memory, and the application enables pretty URLs. - - -DIRECTORY STRUCTURE -------------------- - - protected/ contains application source code - controllers/ contains Web controller classes - index.php the entry script - - -REQUIREMENTS ------------- - -The minimum requirement by Yii is that your Web server supports PHP 5.4.0. - - -INSTALLATION ------------- - -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 --prefer-dist --stability=dev yiisoft/yii2-app-benchmark yii-benchmark -~~~ - -Now you should be able to access the benchmark page using the URL - -~~~ -http://localhost/yii-benchmark/index.php/site/hello -~~~ - -In the above, we assume `yii-benchmark` is directly under the document root of your Web server. - -Note that in order to install some dependencies you must have `php_openssl` extension enabled. - diff --git a/apps/benchmark/composer.json b/apps/benchmark/composer.json deleted file mode 100644 index 81f3eed..0000000 --- a/apps/benchmark/composer.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "yiisoft/yii2-app-benchmark", - "description": "Yii 2 Benchmark Application", - "keywords": ["yii2", "framework", "benchmark", "application"], - "homepage": "http://www.yiiframework.com/", - "type": "project", - "license": "BSD-3-Clause", - "support": { - "issues": "https://github.com/yiisoft/yii2/issues?state=open", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", - "source": "https://github.com/yiisoft/yii2" - }, - "config": { - "vendor-dir": "protected/vendor" - }, - "minimum-stability": "stable", - "require": { - "php": ">=5.4.0", - "yiisoft/yii2": "*" - } -} diff --git a/apps/benchmark/index.php b/apps/benchmark/index.php deleted file mode 100644 index c278f1d..0000000 --- a/apps/benchmark/index.php +++ /dev/null @@ -1,18 +0,0 @@ - 'benchmark', - 'basePath' => __DIR__ . '/protected', - 'components' => [ - 'urlManager' => [ - 'enablePrettyUrl' => true, - ], - ], -]; - -$application = new yii\web\Application($config); -$application->run(); diff --git a/apps/benchmark/protected/.htaccess b/apps/benchmark/protected/.htaccess deleted file mode 100644 index 8d2f256..0000000 --- a/apps/benchmark/protected/.htaccess +++ /dev/null @@ -1 +0,0 @@ -deny from all diff --git a/apps/benchmark/protected/controllers/SiteController.php b/apps/benchmark/protected/controllers/SiteController.php deleted file mode 100644 index 9b08da8..0000000 --- a/apps/benchmark/protected/controllers/SiteController.php +++ /dev/null @@ -1,15 +0,0 @@ - - * @since 2.0 - */ -class AppController extends Controller -{ - public $defaultAction = 'link'; - - /** - * Properly removes symlinked directory under Windows, MacOS and Linux - * - * @param string $file path to symlink - */ - protected function unlink($file) - { - if (is_dir($file) && DIRECTORY_SEPARATOR === '\\') { - rmdir($file); - } else { - unlink($file); - } - } - - /** - * This command runs the following shell commands in the dev repo root: - * - * - Run `composer update` - * - `rm -rf apps/basic/vendor/yiisoft/yii2` - * - `rm -rf apps/basic/vendor/yiisoft/yii2-*` - * - * And replaces them with symbolic links to the extensions and framework path in the dev repo. - * @param string $app the application name `basic` or `advanced`. - */ - public function actionLink($app) - { - // root of the dev repo - $base = dirname(dirname(__DIR__)); - $appDir = "$base/apps/$app"; - - // cleanup - if (is_link($link = "$appDir/vendor/yiisoft/yii2")) { - $this->stdout("Removing symlink $link.\n"); - $this->unlink($link); - } - $extensions = $this->findDirs("$appDir/vendor/yiisoft"); - foreach($extensions as $ext) { - if (is_link($link = "$appDir/vendor/yiisoft/yii2-$ext")) { - $this->stdout("Removing symlink $link.\n"); - $this->unlink($link); - } - } - - // composer update - chdir($appDir); - passthru('composer update --prefer-dist'); - - // link directories - if (is_dir($link = "$appDir/vendor/yiisoft/yii2")) { - $this->stdout("Removing dir $link.\n"); - FileHelper::removeDirectory($link); - $this->stdout("Creating symlink for $link.\n"); - symlink("$base/framework", $link); - } - $extensions = $this->findDirs("$appDir/vendor/yiisoft"); - foreach($extensions as $ext) { - if (is_dir($link = "$appDir/vendor/yiisoft/yii2-$ext")) { - $this->stdout("Removing dir $link.\n"); - FileHelper::removeDirectory($link); - $this->stdout("Creating symlink for $link.\n"); - symlink("$base/extensions/$ext", $link); - } - } - - $this->stdout("done.\n"); - } - - /** - * Finds linkable applications - * - * @param string $dir directory to search in - * @return array list of applications command can link - */ - protected function findDirs($dir) - { - $list = []; - $handle = @opendir($dir); - if ($handle === false) { - return []; - } - while (($file = readdir($handle)) !== false) { - if ($file === '.' || $file === '..') { - continue; - } - $path = $dir . DIRECTORY_SEPARATOR . $file; - if (is_dir($path) && preg_match('/^yii2-(.*)$/', $file, $matches)) { - $list[] = $matches[1]; - } - } - closedir($handle); - - foreach($list as $i => $e) { - if ($e == 'composer') { // skip composer to not break composer update - unset($list[$i]); - } - } - - return $list; - } -} diff --git a/build/controllers/ClassmapController.php b/build/controllers/ClassmapController.php index e88bdb0..a88e6cd 100644 --- a/build/controllers/ClassmapController.php +++ b/build/controllers/ClassmapController.php @@ -51,6 +51,7 @@ class ClassmapController extends Controller '/Yii.php', '/BaseYii.php', '/console/', + '/requirements/', ], ]; $files = FileHelper::findFiles($root, $options); diff --git a/build/controllers/DevController.php b/build/controllers/DevController.php new file mode 100644 index 0000000..092adaf --- /dev/null +++ b/build/controllers/DevController.php @@ -0,0 +1,325 @@ + + * @since 2.0 + */ +class DevController extends Controller +{ + public $defaultAction = 'all'; + + public $apps = [ + 'basic' => 'git@github.com:yiisoft/yii2-app-basic.git', + 'advanced' => 'git@github.com:yiisoft/yii2-app-advanced.git', + 'benchmark' => 'git@github.com:yiisoft/yii2-app-benchmark.git', + ]; + + public $extensions = [ + 'apidoc' => 'git@github.com:yiisoft/yii2-apidoc.git', + 'authclient' => 'git@github.com:yiisoft/yii2-authclient.git', + 'bootstrap' => 'git@github.com:yiisoft/yii2-bootstrap.git', + 'codeception' => 'git@github.com:yiisoft/yii2-codeception.git', + 'composer' => 'git@github.com:yiisoft/yii2-composer.git', + 'debug' => 'git@github.com:yiisoft/yii2-debug.git', + 'elasticsearch' => 'git@github.com:yiisoft/yii2-elasticsearch.git', + 'faker' => 'git@github.com:yiisoft/yii2-faker.git', + 'gii' => 'git@github.com:yiisoft/yii2-gii.git', + 'imagine' => 'git@github.com:yiisoft/yii2-imagine.git', + 'jui' => 'git@github.com:yiisoft/yii2-jui.git', + 'mongodb' => 'git@github.com:yiisoft/yii2-mongodb.git', + 'redis' => 'git@github.com:yiisoft/yii2-redis.git', + 'smarty' => 'git@github.com:yiisoft/yii2-smarty.git', + 'sphinx' => 'git@github.com:yiisoft/yii2-sphinx.git', + 'swiftmailer' => 'git@github.com:yiisoft/yii2-swiftmailer.git', + 'twig' => 'git@github.com:yiisoft/yii2-twig.git', + ]; + + + /** + * Install all extensions and advanced + basic app + */ + public function actionAll() + { + if (!$this->confirm('Install all applications and all extensions now?')) { + return 1; + } + + foreach($this->extensions as $ext => $repo) { + $ret = $this->actionExt($ext, $repo); + if ($ret !== 0) { + return $ret; + } + } + + foreach($this->apps as $app => $repo) { + $ret = $this->actionApp($app, $repo); + if ($ret !== 0) { + return $ret; + } + } + + return 0; + } + + /** + * Runs a command in all extension and application directories + * + * Can be used to run e.g. `git pull`. + * + * ./build/build dev/run git pull + * + * @param string $command the command to run + */ + public function actionRun($command) + { + $command = implode(' ', func_get_args()); + + // root of the dev repo + $base = dirname(dirname(__DIR__)); + $dirs = $this->listSubDirs("$base/extensions"); + $dirs = array_merge($dirs, $this->listSubDirs("$base/apps")); + asort($dirs); + + $oldcwd = getcwd(); + foreach($dirs as $dir) { + $displayDir = substr($dir, strlen($base)); + $this->stdout("Running '$command' in $displayDir...\n", Console::BOLD); + chdir($dir); + passthru($command); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + } + chdir($oldcwd); + } + + /** + * This command installs a project template in the `apps` directory and links the framework and extensions + * + * It basically runs the following commands in the dev repo root: + * + * - Run `composer update` + * - `rm -rf apps/basic/vendor/yiisoft/yii2` + * - `rm -rf apps/basic/vendor/yiisoft/yii2-*` + * + * And replaces them with symbolic links to the extensions and framework path in the dev repo. + * + * Extensions required by the application are automatically installed using the `ext` action. + * + * @param string $app the application name e.g. `basic` or `advanced`. + * @param string $repo url of the git repo to clone if it does not already exist. + * @return int return code + */ + public function actionApp($app, $repo = null) + { + // root of the dev repo + $base = dirname(dirname(__DIR__)); + $appDir = "$base/apps/$app"; + + if (!file_exists($appDir)) { + if (empty($repo)) { + if (isset($this->apps[$app])) { + $repo = $this->apps[$app]; + } else { + $this->stderr("Repo argument is required for app '$app'.\n", Console::FG_RED); + return 1; + } + } + + $this->stdout("cloning application repo '$app' from '$repo'...\n", Console::BOLD); + passthru('git clone ' . escapeshellarg($repo) . ' ' . $appDir); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + } + + // cleanup + $this->stdout("cleaning up application '$app' vendor directory...\n", Console::BOLD); + $this->cleanupVendorDir($appDir); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + + // composer update + $this->stdout("updating composer for app '$app'...\n", Console::BOLD); + chdir($appDir); + passthru('composer update --prefer-dist'); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + + // link directories + $this->stdout("linking framework and extensions to '$app' app vendor dir...\n", Console::BOLD); + $this->linkFrameworkAndExtensions($appDir, $base); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + + return 0; + } + + /** + * This command installs an extension in the `extensions` directory and links the framework and other extensions + * + * @param string $extension the application name e.g. `basic` or `advanced`. + * @param string $repo url of the git repo to clone if it does not already exist. + */ + public function actionExt($extension, $repo = null) + { + // root of the dev repo + $base = dirname(dirname(__DIR__)); + $extensionDir = "$base/extensions/$extension"; + + if (!file_exists($extensionDir)) { + if (empty($repo)) { + if (isset($this->extensions[$extension])) { + $repo = $this->extensions[$extension]; + } else { + $this->stderr("Repo argument is required for extension '$extension'.\n", Console::FG_RED); + return 1; + } + } + + $this->stdout("cloning extension repo '$extension' from '$repo'...\n", Console::BOLD); + passthru('git clone ' . escapeshellarg($repo) . ' ' . $extensionDir); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + } + + // cleanup + $this->stdout("cleaning up extension '$extension' vendor directory...\n", Console::BOLD); + $this->cleanupVendorDir($extensionDir); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + + // composer update + $this->stdout("updating composer for extension '$extension'...\n", Console::BOLD); + chdir($extensionDir); + passthru('composer update --prefer-dist'); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + + // link directories + $this->stdout("linking framework and extensions to '$extension' vendor dir...\n", Console::BOLD); + $this->linkFrameworkAndExtensions($extensionDir, $base); + $this->stdout("done.\n", Console::BOLD, Console::FG_GREEN); + + return 0; + } + + + protected function cleanupVendorDir($dir) + { + if (is_link($link = "$dir/vendor/yiisoft/yii2")) { + $this->stdout("Removing symlink $link.\n"); + $this->unlink($link); + } + $extensions = $this->findDirs("$dir/vendor/yiisoft"); + foreach($extensions as $ext) { + if (is_link($link = "$dir/vendor/yiisoft/yii2-$ext")) { + $this->stdout("Removing symlink $link.\n"); + $this->unlink($link); + } + } + } + + protected function linkFrameworkAndExtensions($dir, $base) + { + if (is_dir($link = "$dir/vendor/yiisoft/yii2")) { + $this->stdout("Removing dir $link.\n"); + FileHelper::removeDirectory($link); + $this->stdout("Creating symlink for $link.\n"); + symlink("$base/framework", $link); + } + $extensions = $this->findDirs("$dir/vendor/yiisoft"); + foreach($extensions as $ext) { + if (is_dir($link = "$dir/vendor/yiisoft/yii2-$ext")) { + $this->stdout("Removing dir $link.\n"); + FileHelper::removeDirectory($link); + $this->stdout("Creating symlink for $link.\n"); + if (!file_exists("$base/extensions/$ext")) { + $ret = $this->actionExt($ext); + if ($ret !== 0) { + return $ret; + } + } + symlink("$base/extensions/$ext", $link); + } + } + } + + /** + * Properly removes symlinked directory under Windows, MacOS and Linux + * + * @param string $file path to symlink + */ + protected function unlink($file) + { + if (is_dir($file) && DIRECTORY_SEPARATOR === '\\') { + rmdir($file); + } else { + unlink($file); + } + } + + protected function listSubDirs($dir) + { + $list = []; + $handle = opendir($dir); + if ($handle === false) { + throw new InvalidParamException("Unable to open directory: $dir"); + } + while (($file = readdir($handle)) !== false) { + if ($file === '.' || $file === '..') { + continue; + } + // ignore hidden directories + if ($file[0] === '.') { + continue; + } + if (is_dir("$dir/$file")) { + $list[] = "$dir/$file"; + } + } + closedir($handle); + return $list; + } + + /** + * Finds linkable applications + * + * @param string $dir directory to search in + * @return array list of applications command can link + */ + protected function findDirs($dir) + { + $list = []; + $handle = @opendir($dir); + if ($handle === false) { + return []; + } + while (($file = readdir($handle)) !== false) { + if ($file === '.' || $file === '..') { + continue; + } + $path = $dir . DIRECTORY_SEPARATOR . $file; + if (is_dir($path) && preg_match('/^yii2-(.*)$/', $file, $matches)) { + $list[] = $matches[1]; + } + } + closedir($handle); + + foreach($list as $i => $e) { + if ($e == 'composer') { // skip composer to not break composer update + unset($list[$i]); + } + } + + return $list; + } +} diff --git a/composer.json b/composer.json index 58b87a6..688e17c 100644 --- a/composer.json +++ b/composer.json @@ -53,22 +53,6 @@ }, "minimum-stability": "dev", "replace": { - "yiisoft/yii2-apidoc": "self.version", - "yiisoft/yii2-authclient": "self.version", - "yiisoft/yii2-bootstrap": "self.version", - "yiisoft/yii2-codeception": "self.version", - "yiisoft/yii2-debug": "self.version", - "yiisoft/yii2-elasticsearch": "self.version", - "yiisoft/yii2-faker": "self.version", - "yiisoft/yii2-imagine": "self.version", - "yiisoft/yii2-gii": "self.version", - "yiisoft/yii2-jui": "self.version", - "yiisoft/yii2-mongodb": "self.version", - "yiisoft/yii2-redis": "self.version", - "yiisoft/yii2-smarty": "self.version", - "yiisoft/yii2-swiftmailer": "self.version", - "yiisoft/yii2-sphinx": "self.version", - "yiisoft/yii2-twig": "self.version", "yiisoft/yii2": "self.version" }, "require": { @@ -77,7 +61,7 @@ "lib-pcre": "*", "yiisoft/yii2-composer": "*", "ezyang/htmlpurifier": "4.6.*", - "cebe/markdown": "~1.0.0", + "cebe/markdown": "~1.0.0 | ~1.1.0", "bower-asset/jquery": "2.1.*@stable | 1.11.*@stable", "bower-asset/jquery.inputmask": "3.1.*", "bower-asset/punycode": "1.3.*", @@ -87,7 +71,7 @@ "bower-asset/typeahead.js": "0.10.*" }, "require-dev": { - "phpunit/phpunit": "3.7.*", + "phpunit/phpunit": "~4.5", "twig/twig": "*", "smarty/smarty": "~3.1", "imagine/imagine": "0.5.*", @@ -111,23 +95,7 @@ }, "autoload": { "psr-4": { - "yii\\": "framework/", - "yii\\apidoc\\": "extensions/apidoc/", - "yii\\authclient\\": "extensions/authclient/", - "yii\\bootstrap\\": "extensions/bootstrap/", - "yii\\codeception\\": "extensions/codeception/", - "yii\\debug\\": "extensions/debug/", - "yii\\elasticsearch\\": "extensions/elasticsearch/", - "yii\\faker\\": "extensions/faker/", - "yii\\gii\\": "extensions/gii/", - "yii\\imagine\\": "extensions/imagine/", - "yii\\jui\\": "extensions/jui/", - "yii\\mongodb\\": "extensions/mongodb/", - "yii\\redis\\": "extensions/redis/", - "yii\\smarty\\": "extensions/smarty/", - "yii\\swiftmailer\\": "extensions/swiftmailer/", - "yii\\sphinx\\": "extensions/sphinx/", - "yii\\twig\\": "extensions/twig/" + "yii\\": "framework/" } }, "bin": [ diff --git a/composer.lock b/composer.lock index ae8bcbf..8cccc8a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "c3090fa59c9356e92b35f8b13b0348de", + "hash": "6f81c77925e8946ece8cd3a4d536f88c", "packages": [ { "name": "bower-asset/bootstrap", - "version": "v3.3.1", + "version": "v3.3.4", "source": { "type": "git", "url": "https://github.com/twbs/bootstrap.git", - "reference": "9a7e365c2c4360335d25246dac11afb1f577210a" + "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twbs/bootstrap/zipball/9a7e365c2c4360335d25246dac11afb1f577210a", - "reference": "9a7e365c2c4360335d25246dac11afb1f577210a", + "url": "https://api.github.com/repos/twbs/bootstrap/zipball/a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f", + "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f", "shasum": "" }, "require": { @@ -32,7 +32,8 @@ "dist/fonts/glyphicons-halflings-regular.eot", "dist/fonts/glyphicons-halflings-regular.svg", "dist/fonts/glyphicons-halflings-regular.ttf", - "dist/fonts/glyphicons-halflings-regular.woff" + "dist/fonts/glyphicons-halflings-regular.woff", + "dist/fonts/glyphicons-halflings-regular.woff2" ], "bower-asset-ignore": [ "/.*", @@ -59,23 +60,23 @@ }, { "name": "bower-asset/jquery", - "version": "2.1.1", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/jquery/jquery.git", - "reference": "4dec426aa2a6cbabb1b064319ba7c272d594a688" + "reference": "8f2a9d9272d6ed7f32d3a484740ab342c02541e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jquery/jquery/zipball/4dec426aa2a6cbabb1b064319ba7c272d594a688", - "reference": "4dec426aa2a6cbabb1b064319ba7c272d594a688", + "url": "https://api.github.com/repos/jquery/jquery/zipball/8f2a9d9272d6ed7f32d3a484740ab342c02541e0", + "reference": "8f2a9d9272d6ed7f32d3a484740ab342c02541e0", "shasum": "" }, "require-dev": { "bower-asset/qunit": "1.14.0", "bower-asset/requirejs": "2.1.10", "bower-asset/sinon": "1.8.1", - "bower-asset/sizzle": "1.10.19" + "bower-asset/sizzle": "2.1.1-patch2" }, "type": "bower-asset-library", "extra": { @@ -102,16 +103,16 @@ }, { "name": "bower-asset/jquery-ui", - "version": "1.11.2", + "version": "1.11.4", "source": { "type": "git", "url": "https://github.com/components/jqueryui.git", - "reference": "396781474d936959061271505f506b78398fe6a2" + "reference": "c34f8dbf3ba57b3784b93f26119f436c0e8288e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/components/jqueryui/zipball/396781474d936959061271505f506b78398fe6a2", - "reference": "396781474d936959061271505f506b78398fe6a2", + "url": "https://api.github.com/repos/components/jqueryui/zipball/c34f8dbf3ba57b3784b93f26119f436c0e8288e1", + "reference": "c34f8dbf3ba57b3784b93f26119f436c0e8288e1", "shasum": "" }, "require": { @@ -127,16 +128,16 @@ }, { "name": "bower-asset/jquery.inputmask", - "version": "3.1.38", + "version": "3.1.61", "source": { "type": "git", "url": "https://github.com/RobinHerbots/jquery.inputmask.git", - "reference": "464cddbdea65411896468f40321e68abcc75a34c" + "reference": "f2c086411d2557fc485c47afb3cecfa6c1de9ee2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/464cddbdea65411896468f40321e68abcc75a34c", - "reference": "464cddbdea65411896468f40321e68abcc75a34c", + "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/f2c086411d2557fc485c47afb3cecfa6c1de9ee2", + "reference": "f2c086411d2557fc485c47afb3cecfa6c1de9ee2", "shasum": "" }, "require": { @@ -172,7 +173,7 @@ "form", "input", "inputmask", - "jQuery", + "jquery", "mask", "plugins" ] @@ -234,16 +235,16 @@ }, { "name": "bower-asset/yii2-pjax", - "version": "v2.0.1", + "version": "v2.0.4", "source": { "type": "git", "url": "https://github.com/yiisoft/jquery-pjax.git", - "reference": "f07ce95f6098c0bd5421789a20789f39a19be73b" + "reference": "3f20897307cca046fca5323b318475ae9dac0ca0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/f07ce95f6098c0bd5421789a20789f39a19be73b", - "reference": "f07ce95f6098c0bd5421789a20789f39a19be73b", + "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/3f20897307cca046fca5323b318475ae9dac0ca0", + "reference": "3f20897307cca046fca5323b318475ae9dac0ca0", "shasum": "" }, "require": { @@ -254,9 +255,16 @@ "bower-asset-main": "./jquery.pjax.js", "bower-asset-ignore": [ ".travis.yml", + "Gemfile", + "Gemfile.lock", + "vendor/", + "script/", "test/" ] - } + }, + "license": [ + "MIT" + ] }, { "name": "cebe/markdown", @@ -264,12 +272,12 @@ "source": { "type": "git", "url": "https://github.com/cebe/markdown.git", - "reference": "77ba2daada49fc851b397028d26fb2078ec4a3cf" + "reference": "e14d3da8f84eefa3792fd22b5b5ecba9c98d2e18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cebe/markdown/zipball/77ba2daada49fc851b397028d26fb2078ec4a3cf", - "reference": "77ba2daada49fc851b397028d26fb2078ec4a3cf", + "url": "https://api.github.com/repos/cebe/markdown/zipball/e14d3da8f84eefa3792fd22b5b5ecba9c98d2e18", + "reference": "e14d3da8f84eefa3792fd22b5b5ecba9c98d2e18", "shasum": "" }, "require": { @@ -279,7 +287,7 @@ "require-dev": { "cebe/indent": "*", "facebook/xhprof": "*@dev", - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "4.1.*" }, "bin": [ "bin/markdown" @@ -287,7 +295,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -316,7 +324,7 @@ "markdown", "markdown-extra" ], - "time": "2014-11-07 12:53:11" + "time": "2015-03-20 11:07:08" }, { "name": "ezyang/htmlpurifier", @@ -362,53 +370,6 @@ "html" ], "time": "2013-11-30 08:25:19" - }, - { - "name": "yiisoft/yii2-composer", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/yiisoft/yii2-composer.git", - "reference": "0ed315f4b450604d5c2fa5fcacaf27fdde73d062" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/0ed315f4b450604d5c2fa5fcacaf27fdde73d062", - "reference": "0ed315f4b450604d5c2fa5fcacaf27fdde73d062", - "shasum": "" - }, - "require": { - "composer-plugin-api": "1.0.0" - }, - "type": "composer-plugin", - "extra": { - "class": "yii\\composer\\Plugin", - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "yii\\composer\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Qiang Xue", - "email": "qiang.xue@gmail.com" - } - ], - "description": "The composer plugin for Yii extension installer", - "keywords": [ - "composer", - "extension installer", - "yii2" - ], - "time": "2014-11-07 16:17:16" } ], "packages-dev": [ @@ -446,17 +407,71 @@ "time": "2014-05-23 14:40:08" }, { + "name": "doctrine/instantiator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "3d9669e597439e8d205baf315efb757038fb4dea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/3d9669e597439e8d205baf315efb757038fb4dea", + "reference": "3d9669e597439e8d205baf315efb757038fb4dea", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-01-16 19:29:51" + }, + { "name": "fzaninotto/faker", "version": "dev-master", "source": { "type": "git", "url": "https://github.com/fzaninotto/Faker.git", - "reference": "44eae4deeb065454e68b3c9911181285f01003c6" + "reference": "81f8e9439d0041866849c05d334584ea31c7b05e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/44eae4deeb065454e68b3c9911181285f01003c6", - "reference": "44eae4deeb065454e68b3c9911181285f01003c6", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/81f8e9439d0041866849c05d334584ea31c7b05e", + "reference": "81f8e9439d0041866849c05d334584ea31c7b05e", "shasum": "" }, "require": { @@ -466,6 +481,9 @@ "phpunit/phpunit": "~4.0", "squizlabs/php_codesniffer": "~1.5" }, + "suggest": { + "ext-intl": "*" + }, "type": "library", "extra": { "branch-alias": { @@ -492,7 +510,7 @@ "faker", "fixtures" ], - "time": "2014-11-12 17:27:49" + "time": "2015-03-18 16:46:58" }, { "name": "imagine/imagine", @@ -552,47 +570,158 @@ "time": "2014-06-13 10:54:04" }, { + "name": "phpdocumentor/reflection-docblock", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d1da796ba5565789a623052eb9f2cf59d57fec60" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d1da796ba5565789a623052eb9f2cf59d57fec60", + "reference": "d1da796ba5565789a623052eb9f2cf59d57fec60", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0", + "league/commonmark": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-27 09:28:18" + }, + { + "name": "phpspec/prophecy", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "07606749da971eda75434814a313ed0ce6790f6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/07606749da971eda75434814a313ed0ce6790f6a", + "reference": "07606749da971eda75434814a313ed0ce6790f6a", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2015-03-20 17:41:29" + }, + { "name": "phpunit/php-code-coverage", - "version": "1.2.x-dev", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b" + "reference": "4676604b851bfc6fc02bf3394bf350c727bcebf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", - "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4676604b851bfc6fc02bf3394bf350c727bcebf4", + "reference": "4676604b851bfc6fc02bf3394bf350c727bcebf4", "shasum": "" }, "require": { "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.0@stable", - "phpunit/php-text-template": ">=1.2.0@stable", - "phpunit/php-token-stream": ">=1.1.3,<1.3.0" + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "~1.0", + "sebastian/version": "~1.0" }, "require-dev": { - "phpunit/phpunit": "3.7.*@dev" + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" }, "suggest": { "ext-dom": "*", - "ext-xdebug": ">=2.0.5" + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ - "PHP/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -610,7 +739,7 @@ "testing", "xunit" ], - "time": "2014-09-02 10:13:14" + "time": "2015-03-19 05:49:08" }, { "name": "phpunit/php-file-iterator", @@ -747,45 +876,44 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.2.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=5.3.3" }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.4-dev" } }, "autoload": { "classmap": [ - "PHP/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], "description": "Wrapper around PHP's tokenizer extension.", @@ -793,62 +921,61 @@ "keywords": [ "tokenizer" ], - "time": "2014-03-03 05:10:30" + "time": "2015-01-17 09:51:32" }, { "name": "phpunit/phpunit", - "version": "3.7.x-dev", + "version": "4.5.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6" + "reference": "10f6685ca2cf5d8662b43a225ab853699821690b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/38709dc22d519a3d1be46849868aa2ddf822bcf6", - "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/10f6685ca2cf5d8662b43a225ab853699821690b", + "reference": "10f6685ca2cf5d8662b43a225ab853699821690b", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-dom": "*", "ext-json": "*", "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", - "phpunit/php-code-coverage": "~1.2", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.1", - "phpunit/php-timer": "~1.0", - "phpunit/phpunit-mock-objects": "~1.2", + "phpspec/prophecy": "~1.3.1", + "phpunit/php-code-coverage": "~2.0,>=2.0.11", + "phpunit/php-file-iterator": "~1.3.2", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.2", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", "symfony/yaml": "~2.0" }, - "require-dev": { - "pear-pear.php.net/pear": "1.9.4" - }, "suggest": { "phpunit/php-invoker": "~1.1" }, "bin": [ - "composer/bin/phpunit" + "phpunit" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.7.x-dev" + "dev-master": "4.5.x-dev" } }, "autoload": { "classmap": [ - "PHPUnit/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], "license": [ "BSD-3-Clause" ], @@ -860,34 +987,35 @@ } ], "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", + "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], - "time": "2014-10-17 09:04:17" + "time": "2015-03-02 06:58:30" }, { "name": "phpunit/phpunit-mock-objects", - "version": "1.2.x-dev", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "c39c4511c3b007539eb170c32cbc2af49a07351a" + "reference": "55484334fb4c306ed24bfc3bdb0874685c29036f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c39c4511c3b007539eb170c32cbc2af49a07351a", - "reference": "c39c4511c3b007539eb170c32cbc2af49a07351a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/55484334fb4c306ed24bfc3bdb0874685c29036f", + "reference": "55484334fb4c306ed24bfc3bdb0874685c29036f", "shasum": "" }, "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", "php": ">=5.3.3", - "phpunit/php-text-template": ">=1.1.1@stable" + "phpunit/php-text-template": "~1.2" }, "require-dev": { - "phpunit/phpunit": "3.7.*@dev" + "phpunit/phpunit": "4.4.*@dev" }, "suggest": { "ext-soap": "*" @@ -895,18 +1023,15 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.4.x-dev" } }, "autoload": { "classmap": [ - "PHPUnit/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -923,7 +1048,378 @@ "mock", "xunit" ], - "time": "2014-02-16 12:43:56" + "time": "2015-03-18 09:04:51" + }, + { + "name": "sebastian/comparator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-01-29 16:28:08" + }, + { + "name": "sebastian/diff", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-02-22 15:13:53" + }, + { + "name": "sebastian/environment", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", + "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2015-01-01 10:01:08" + }, + { + "name": "sebastian/exporter", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "84839970d05254c73cde183a721c7af13aede943" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", + "reference": "84839970d05254c73cde183a721c7af13aede943", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2015-01-27 07:23:06" + }, + { + "name": "sebastian/global-state", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "007c441df427cf0e175372fcbb9d196bce7eb743" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/007c441df427cf0e175372fcbb9d196bce7eb743", + "reference": "007c441df427cf0e175372fcbb9d196bce7eb743", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-01-20 04:09:31" + }, + { + "name": "sebastian/recursion-context", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-01-24 09:48:32" + }, + { + "name": "sebastian/version", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2014-12-15 14:25:24" }, { "name": "smarty/smarty", @@ -931,12 +1427,12 @@ "source": { "type": "git", "url": "https://github.com/smarty-php/smarty.git", - "reference": "de7310b702a2024f60c0af384b6617d0c5f406bb" + "reference": "443ae8c2167add9c7e605f115955816efeb86f1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smarty-php/smarty/zipball/de7310b702a2024f60c0af384b6617d0c5f406bb", - "reference": "de7310b702a2024f60c0af384b6617d0c5f406bb", + "url": "https://api.github.com/repos/smarty-php/smarty/zipball/443ae8c2167add9c7e605f115955816efeb86f1e", + "reference": "443ae8c2167add9c7e605f115955816efeb86f1e", "shasum": "" }, "require": { @@ -978,20 +1474,20 @@ "keywords": [ "templating" ], - "time": "2014-11-13 18:52:41" + "time": "2015-03-22 23:39:22" }, { "name": "swiftmailer/swiftmailer", - "version": "dev-master", + "version": "5.x-dev", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "d0f361d88e5de851bbb8c542d3b6aa46d61a9ffc" + "reference": "048be6f7c19944d604e321347990543bc2bbe10b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d0f361d88e5de851bbb8c542d3b6aa46d61a9ffc", - "reference": "d0f361d88e5de851bbb8c542d3b6aa46d61a9ffc", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/048be6f7c19944d604e321347990543bc2bbe10b", + "reference": "048be6f7c19944d604e321347990543bc2bbe10b", "shasum": "" }, "require": { @@ -1003,7 +1499,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3-dev" + "dev-master": "5.4-dev" } }, "autoload": { @@ -1030,7 +1526,7 @@ "mail", "mailer" ], - "time": "2014-10-30 13:41:35" + "time": "2015-03-14 06:07:26" }, { "name": "symfony/yaml", @@ -1039,16 +1535,19 @@ "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "75deb1b183d2bbf12f4b54c644c0caafca338fbe" + "reference": "bc2504716cb3f7704dfff5d5dcb88df43282f414" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/75deb1b183d2bbf12f4b54c644c0caafca338fbe", - "reference": "75deb1b183d2bbf12f4b54c644c0caafca338fbe", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/bc2504716cb3f7704dfff5d5dcb88df43282f414", + "reference": "bc2504716cb3f7704dfff5d5dcb88df43282f414", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0.0" }, "type": "library", "extra": { @@ -1077,29 +1576,29 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2014-11-20 13:24:30" + "time": "2015-03-22 16:57:18" }, { "name": "twig/twig", - "version": "dev-master", + "version": "1.x-dev", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "efed4fa3b10f8ad6f856d817f4e4a6d9ac527915" + "reference": "7ee4aec238949225a25f174318dc84167e5f360d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/efed4fa3b10f8ad6f856d817f4e4a6d9ac527915", - "reference": "efed4fa3b10f8ad6f856d817f4e4a6d9ac527915", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/7ee4aec238949225a25f174318dc84167e5f360d", + "reference": "7ee4aec238949225a25f174318dc84167e5f360d", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">=5.2.7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.16-dev" + "dev-master": "1.18-dev" } }, "autoload": { @@ -1134,7 +1633,7 @@ "keywords": [ "templating" ], - "time": "2014-11-20 10:35:14" + "time": "2015-03-17 17:21:28" } ], "aliases": [], @@ -1143,6 +1642,7 @@ "bower-asset/jquery-ui": 0 }, "prefer-stable": false, + "prefer-lowest": false, "platform": { "php": ">=5.4.0", "ext-mbstring": "*", diff --git a/docs/guide-es/README.md b/docs/guide-es/README.md index 334142d..bef9ef1 100644 --- a/docs/guide-es/README.md +++ b/docs/guide-es/README.md @@ -74,13 +74,13 @@ Conceptos clave Trabajar con bases de datos --------------------------- -* [Objeto de acceso a datos](db-dao.md) - Conexión a una base de datos, consultas básicas, transacciones y +* [Objeto de acceso a datos](db-dao.md) - Conexión a una base de datos, consultas básicas, transacciones y manipulación de esquemas -* **TBD** [Constructor de consultas](db-query-builder.md) - Consulta de la base de datos utilizando una simple capa de +* [Constructor de consultas](db-query-builder.md) - Consulta de la base de datos utilizando una simple capa de abstracción -* **TBD** [Active Record](db-active-record.md) - ORM Active Record, recuperación y manipulación de registros y +* **TBD** [Active Record](db-active-record.md) - ORM Active Record, recuperación y manipulación de registros y definición de relaciones -* **TBD** [Migraciones](db-migrations.md) - Control de versiones de bases de datos en el entorno de desarrollo en +* **TBD** [Migraciones](db-migrations.md) - Control de versiones de bases de datos en el entorno de desarrollo en equipo * **TBD** [Sphinx](db-sphinx.md) * **TBD** [Redis](db-redis.md) @@ -94,6 +94,7 @@ Obtener datos de los usuarios * **TBD** [Crear formularios](input-forms.md) * **TBD** [Validar datos](input-validation.md) * **TBD** [Subir archivos](input-file-upload.md) +* **TBD** [Recogida de tabular input](input-tabular-input.md) * **TBD** [Obtener datos para múltiples modelos](input-multiple-models.md) @@ -106,7 +107,7 @@ Visualizar datos * **TBD** [Proveedores de datos](output-data-providers.md) * **TBD** [Widgets de datos](output-data-widgets.md) * **TBD** [Trabajar con scripts de cliente](output-client-scripts.md) -* **TBD** [Utilización de temas](output-theming.md) +* [Temas](output-theming.md) Seguridad @@ -168,7 +169,7 @@ Temas especiales * **TBD** [Plantilla aplicación avanzada](tutorial-advanced-app.md) * **TBD** [Creación de una aplicación desde cero](tutorial-start-from-scratch.md) * **TBD** [Comandos de consola](tutorial-console.md) -* **TBD** [Validadores de base](tutorial-core-validators.md) +* [Validadores del núcleo](tutorial-core-validators.md) * **TBD** [Internacionalización](tutorial-i18n.md) * **TBD** [Envío de correos electrónicos](tutorial-mailing.md) * **TBD** [Mejora del rendimiento](tutorial-performance-tuning.md) @@ -180,14 +181,14 @@ Temas especiales Widgets ------- -* GridView: link to demo page -* ListView: link to demo page -* DetailView: link to demo page -* ActiveForm: link to demo page -* Pjax: link to demo page -* Menu: link to demo page -* LinkPager: link to demo page -* LinkSorter: link to demo page +* GridView: **TBD** link to demo page +* ListView: **TBD** link to demo page +* DetailView: **TBD** link to demo page +* ActiveForm: **TBD** link to demo page +* Pjax: **TBD** link to demo page +* Menu: **TBD** link to demo page +* LinkPager: **TBD** link to demo page +* LinkSorter: **TBD** link to demo page * **TBD** [Bootstrap Widgets](bootstrap-widgets.md) * **TBD** [Jquery UI Widgets](jui-widgets.md) @@ -195,8 +196,7 @@ Widgets Clases auxiliares ----------------- -* **TBD** [Información general](helper-overview.md) -* **TBD** [ArrayHelper](helper-array.md) -* **TBD** [Html](helper-html.md) +* [Información general](helper-overview.md) +* [ArrayHelper](helper-array.md) +* [Html](helper-html.md) * [Url](helper-url.md) -* **TBD** [Security](helper-security.md) diff --git a/docs/guide-es/caching-data.md b/docs/guide-es/caching-data.md index 85a1080..20c8073 100644 --- a/docs/guide-es/caching-data.md +++ b/docs/guide-es/caching-data.md @@ -1,7 +1,7 @@ Almacenamiento de Datos en Caché ================================ -El almacenamiento de datos en caché trata del almacenamiento de alguna variable PHP en caché y recuperarla más tarde del mismo. También es la base de algunas de las características avanzadas de almacenamiento en caché, tales como [el almacenamiento en caché de consultas a la base de datos](#query-caching) y [el almacenamiento en caché de contenido](caching-content.md). +El almacenamiento de datos en caché trata del almacenamiento de alguna variable PHP en caché y recuperarla más tarde del mismo. También es la base de algunas de las características avanzadas de almacenamiento en caché, tales como [el almacenamiento en caché de consultas a la base de datos](#query-caching) y [el almacenamiento en caché de contenido](caching-page.md). El siguiente código muestra el típico patrón de uso para el almacenamiento en caché, donde la variable `$cache` se refiere al [componente caché](#cache-components): @@ -11,7 +11,8 @@ $data = $cache->get($key); if ($data === false) { - // $data no ha sido encontrada en caché, calcularla desde cero + // $data no ha sido encontrada en la caché, calcularla desde cero + // guardar $data en caché para así recuperarla la próxima vez $cache->set($key, $data); } @@ -19,12 +20,13 @@ if ($data === false) { // $data está disponible aquí ``` -## Componentes de Caché + +## Componentes de Caché El almacenamiento de datos en caché depende de los llamados *cache components* (componentes de caché) los cuales representan diferentes tipos de almacenamiento en caché, como por ejemplo en memoria, en archivos o en base de datos. -Los Componentes de Caché están normalmente registrados como componentes de la aplicación para que de esta forma puedan +Los Componentes de Caché están normalmente registrados como [componentes de la aplicación](structure-application-components.md) para que de esta forma puedan ser configurados y accesibles globalmente. El siguiente código muestra cómo configurar el componente de aplicación `cache` para usar [memcached](http://memcached.org/) con dos servidores caché: @@ -62,9 +64,10 @@ el código que utiliza la caché. Por ejemplo, podrías modificar la configuraci ], ``` -> Nota: Puedes registrar múltiples componentes de aplicación de caché. El componente llamado `cache` es usado por defecto por muchas clases caché-dependiente (ej. [[yii\web\UrlManager]]). +> Consejo: Puedes registrar múltiples componentes de aplicación de caché. El componente llamado `cache` es usado por defecto por muchas clases caché-dependiente (ej. [[yii\web\UrlManager]]). -### Almacenamientos de Caché Soportados + +### Almacenamientos de Caché Soportados Yii proporciona varios componentes de caché que pueden almacenar datos en diferentes medios. A continuación se muestra un listado con los componentes de caché disponibles: @@ -79,9 +82,10 @@ se muestra un listado con los componentes de caché disponibles: * [[yii\caching\XCache]]: utiliza la extensión de PHP [XCache](http://xcache.lighttpd.net/). * [[yii\caching\ZendDataCache]]: utiliza [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) como el medio fundamental de caché. -> Nota: Puedes utilizar diferentes tipos de almacenamiento de caché en la misma aplicación. Una estrategia común es la de usar almacenamiento de caché en memoria para almacenar datos que son pequeños pero que son utilizados constantemente (ej. datos estadísticos), y utilizar el almacenamiento de caché en archivos o en base de datos para guardar datos que son grandes y utilizados con menor frecuencia (ej. contenido de página). +> Consejo: Puedes utilizar diferentes tipos de almacenamiento de caché en la misma aplicación. Una estrategia común es la de usar almacenamiento de caché en memoria para almacenar datos que son pequeños pero que son utilizados constantemente (ej. datos estadísticos), y utilizar el almacenamiento de caché en archivos o en base de datos para guardar datos que son grandes y utilizados con menor frecuencia (ej. contenido de página). + -## API de Caché +## API de Caché Todos los componentes de almacenamiento de caché provienen de la misma clase "padre" [[yii\caching\Cache]] y por lo tanto soportan la siguiente API: @@ -96,6 +100,10 @@ Todos los componentes de almacenamiento de caché provienen de la misma clase "p * [[yii\caching\Cache::delete()|delete()]]: elimina un elemento de datos identificado por una clave de la caché. * [[yii\caching\Cache::flush()|flush()]]: elimina todos los elementos de datos de la cache. +> Nota: No Almacenes el valor boolean `false` en caché directamente porque el método [[yii\caching\Cache::get()|get()]] devuelve +el valor `false` para indicar que el dato no ha sido encontrado en la caché. Puedes poner `false` dentro de un array y cachear +este array para evitar este problema. + Algunos sistemas de almacenamiento de caché, como por ejemplo MemCache, APC, pueden recuperar múltiples valores almacenados en modo de lote (batch), lo que puede reducir considerablemente la sobrecarga que implica la recuperación de datos almacenados en la caché. Las API [[yii\caching\Cache::mget()|mget()]] y [[yii\caching\Cache::madd()|madd()]] se proporcionan para utilizar esta característica. En el caso de que el sistema de memoria caché no lo soportara, ésta sería simulada. @@ -107,7 +115,8 @@ $cache['var1'] = $value1; // equivalente a: $cache->set('var1', $value1); $value2 = $cache['var2']; // equivalente a: $value2 = $cache->get('var2'); ``` -### Claves de Caché + +### Claves de Caché Cada elemento de datos almacenado en caché se identifica por una clave. Cuando se almacena un elemento de datos en la memoria caché, se debe especificar una clave. Más tarde, cuando se recupera el elemento de datos de la memoria caché, se debe proporcionar la clave correspondiente. @@ -139,7 +148,8 @@ Cuando en un mismo almacenamiento en caché es utilizado por diferentes aplicaci Para garantizar la interoperabilidad, deberían utilizarse sólo caracteres alfanuméricos. -### Caducidad de Caché + +### Caducidad de Caché Un elemento de datos almacenado en la memoria caché permanecerá en ella para siempre, a menos que sea removida de alguna manera debido a alguna directiva de caché (ej. el espacio de almacenamiento en caché está lleno y los datos más antiguos se eliminan). Para cambiar este comportamiento, podrías proporcionar un parámetro de caducidad al llamar [[yii\caching\Cache::set()|set()]] para guardar el elemento de datos. El parámetro nos indica por cuántos segundos el elemento se mantendrá válido en memoria caché. Cuando llames [[yii\caching\Cache::get()|get()]] para recuperar el elemento, si el tiempo de caducidad ha pasado, el método devolverá `false`, indicando que el elemento de datos no ha sido encontrado en la memoria caché. Por ejemplo, @@ -155,9 +165,10 @@ if ($data === false) { } ``` -### Dependencias de Caché -Además de configurar el tiempo de expiración, los datos almacenados en caché pueden también ser invalidados conforme a algunos cambios en la caché de dependencias. Por ejemplo, [[yii\caching\FileDependency]] representa la dependencia del tiempo de modificación del archivo. Cuando esta dependencia cambia, significa que el archivo correspondiente ha cambiado. Como resultado, cualquier contenido anticuado que sea encontrado en la caché debería ser invalidado y la llamada a [[yii\caching\Cache::get()|get()]] debería devolver `null`. +### Dependencias de Caché + +Además de configurar el tiempo de caducidad, los datos almacenados en caché pueden también ser invalidados conforme a algunos cambios en la caché de dependencias. Por ejemplo, [[yii\caching\FileDependency]] representa la dependencia del tiempo de modificación del archivo. Cuando esta dependencia cambia, significa que el archivo correspondiente ha cambiado. Como resultado, cualquier contenido anticuado que sea encontrado en la caché debería ser invalidado y la llamada a [[yii\caching\Cache::get()|get()]] debería retornar falso. Una dependencia es representada como una instancia de [[yii\caching\Dependency]] o su clase hija. Cuando llamas [[yii\caching\Cache::set()|set()]] para almacenar un elemento de datos en la caché, puedes pasar el objeto de dependencia asociado. Por ejemplo, @@ -185,12 +196,12 @@ Aquí abajo se muestra un sumario de las dependencias disponibles: con el mismo nombre del grupo a la vez llamando a [[yii\caching\TagDependency::invalidate()]]. -## Consultas en Caché +## Consultas en Caché Las consultas en caché es una característica especial de caché construido sobre el almacenamiento de caché de datos. Se proporciona para almacenar en caché el resultado de consultas a la base de datos. -Las consultas en caché requieren una [[yii\db\Connection|conexión a BD]] y un componente de aplicación caché válido. El uso básico de las consultas en memoria caché es el siguiente, asumiendo que `db` es una instancia de [[yii\db\Connection]]: +Las consultas en caché requieren una [[yii\db\Connection|DB connection]] y un componente de aplicación caché válido. El uso básico de las consultas en memoria caché es el siguiente, asumiendo que `db` es una instancia de [[yii\db\Connection]]: ```php $result = $db->cache(function ($db) { @@ -202,11 +213,18 @@ $result = $db->cache(function ($db) { }); ``` -El almacenamiento en caché de consultas se puede usar para [DAO](db-dao.md), así como para [ActiveRecord](db-active-record.md). +El cacheo de consultas puede ser usado tanto para [DAO](db-dao.md) como para [ActiveRecord](db-active-record.md): + +```php +$result = Customer::getDb()->cache(function ($db) { + return Customer::find()->where(['id' => 1])->one(); +}); +``` > Nota: Algunos DBMS (ej. [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) también soporta el almacenamiento en caché desde el mismo servidor de la BD. Puedes optar por utilizar cualquiera de los mecanismos de memoria caché. El almacenamiento en caché de consultas previamente descrito tiene la ventaja que de que se puede especificar dependencias de caché de una forma flexible y son potencialmente mucho más eficientes. -### Configuraciones + +### Configuraciones Las consultas en caché tienen tres opciones configurables globales a través de [[yii\db\Connection]]: @@ -217,7 +235,7 @@ Las consultas en caché tienen tres opciones configurables globales a través de Por defecto es `'cache'`. El almacenamiento en caché de consultas se habilita sólo si hay un componente de la aplicación de caché válida. -### Usos +### Usos Puedes usar [[yii\db\Connection::cache()]] si tienes multiples consultas SQL que necesitas a aprovechar el cacheo de consultas. El uso es de la siguiente manera, @@ -279,7 +297,8 @@ $result = $db->cache(function ($db) { }); ``` -### Limitaciones + +### Limitaciones El almacenamiento en caché de consultas no funciona con los resultados de consulta que contienen controladores de recursos. Por ejemplo, cuando se utiliza el tipo de columna `BLOB` en algunos DBMS, el resultado de la consulta devolverá un recurso para manejar los datos de la columna. diff --git a/docs/guide-es/caching-fragment.md b/docs/guide-es/caching-fragment.md index 68bab36..3d8cd17 100644 --- a/docs/guide-es/caching-fragment.md +++ b/docs/guide-es/caching-fragment.md @@ -28,14 +28,14 @@ Como en la [caché de datos](caching-data.md), un `$id` (clave) único es necesa caché. -## Opciones de Caché +## Opciones de Caché Puedes especificar opciones adicionales para la caché de fragmentos pasando el array de opciones como segundo parametro del método [[yii\base\View::beginCache()|beginCache()]]. Entre bastidores, este array de opciones se utiliza para configurar el widget [[yii\widgets\FragmentCache]] que es en realidad el que implementa la funcionalidad de la caché de fragmentos. -### Duración +### Duración Quizás la opción más utilizada en la caché de fragmentos es [[yii\widgets\FragmentCache::duration|duración]]. Ésta especifica cuántos segundos el contenido puede permanecer como válido en la memoria caché. El siguiente código almacena @@ -53,7 +53,7 @@ if ($this->beginCache($id, ['duration' => 3600])) { Si la opción no está activada, se tomará el valor por defecto 60, lo que significa que el contenido almacenado en caché expirará en 60 segundos. -### Dependencias +### Dependencias Como en la [caché de datos](caching-data.md#cache-dependencies), el fragmento de contenido que está siendo almacenado en caché también puede tener dependencias. Por ejemplo, el contenido de un artículo que se muestre depende de si el mensaje se @@ -78,7 +78,7 @@ if ($this->beginCache($id, ['dependency' => $dependency])) { ``` -### Variaciones +### Variaciones El contenido almacenado en caché puede variar de acuerdo a ciertos parámetros. Por ejemplo, para una aplicación Web que soporte multiples idiomas, la misma pieza del código de la vista puede generar el contenido almacenado en caché @@ -99,7 +99,7 @@ if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) { ``` -### Alternando el Almacenamiento en Caché +### Alternando el Almacenamiento en Caché Puede que a veces quieras habilitar la caché de fragmentos únicamente cuando ciertas condiciones se cumplan. Por ejemplo, para una página que muestra un formulario, tal vez quieras guardarlo en la caché cuando es inicialmente solicitado (a @@ -117,7 +117,7 @@ if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) { ``` -## Almacenamiento en Caché Anidada +## Almacenamiento en Caché Anidada El almacenamiento en caché de fragmentos se puede anidar. Es decir, un fragmento de caché puede ser encerrado dentro de otro fragmento que también se almacena en caché. Por ejemplo, los comentarios se almacenan en una caché de fragmento @@ -151,7 +151,7 @@ dependencias de las cachés anidadas, de lo contrario los fragmentos internos qu manteniendo en el fragmento externo. -## Contenido Dinámico +## Contenido Dinámico Cuando se usa la caché de fragmentos, podrías encontrarte en la situación que un fragmento grande de contenido es relavitamente estático excepto en uno u otro lugar. Por ejemplo, la cabeza de una página (header) puede que muestre el diff --git a/docs/guide-es/caching-http.md b/docs/guide-es/caching-http.md index 25f0486..391da78 100644 --- a/docs/guide-es/caching-http.md +++ b/docs/guide-es/caching-http.md @@ -15,7 +15,7 @@ consultas: * [[yii\filters\HttpCache::cacheControlHeader|Cache-Control]] -## La Cabecera `Last-Modified` +## La Cabecera `Last-Modified` La cabecera `Last-Modified` usa un sello de tiempo para indicar si la página ha sido modificada desde que el cliente la almacena en la caché. @@ -59,7 +59,7 @@ regenerar la página, y el navegador usará la versión caché del lado del clie lado del servidor y la transmisión del contenido de la página son ambos omitidos. -## La Cabecera `ETag` +## La Cabecera `ETag` La cabecera "Entity Tag" (o para abreviar `ETag`) usa un hash para representar el contenido de una página. Si la página ha sido cambiada, el hash también cambiará. Al comparar el hash guardado en el lado del cliente con el hash generado en @@ -113,7 +113,7 @@ expresión sencilla para invalidar la caché si la página ha sido modificada. > Nota: En cumplimiento con [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4), `HttpCache` enviará ambas cabeceras `ETag` y `Last-Modified` si ambas están configuradas. Y si el clientes envía tanto la cabecera `If-None-Match` como la cabecera `If-Modified-Since`, solo la primera será respetada. -## La Cabecera `Cache-Control` +## La Cabecera `Cache-Control` La cabecera `Cache-Control` especifica la directiva general de la caché para páginas. Puedes enviarla configurando la propiedad [[yii\filters\HttpCache::cacheControlHeader]] con el valor de la cabecera. Por defecto, la siguiente cabecera @@ -123,7 +123,7 @@ será enviada: Cache-Control: public, max-age=3600 ``` -## Limitador de la Sesión de Caché +## Limitador de la Sesión de Caché Cuando una página utiliza la sesión, PHP enviará automáticamente cabeceras HTTP relacionadas con la caché tal y como se especifican en `session.cache_limiter` de la configuración INI de PHP. Estas cabeceras pueden interferir o deshabilitar @@ -134,7 +134,7 @@ automáticamente el envío de estas cabeceras. Si deseas modificar este comporta para una mejor explicación sobre esos valores. -## Implicaciones SEO +## Implicaciones SEO Los robots de motores de búsqueda tienden a respetar las cabeceras de caché. Dado que algunos `crawlers` tienen limitado el número de páginas que pueden rastrear por dominios dentro de un cierto período de tiempo, la introducción de cabeceras diff --git a/docs/guide-es/concept-aliases.md b/docs/guide-es/concept-aliases.md index 0e42141..ecaee1a 100644 --- a/docs/guide-es/concept-aliases.md +++ b/docs/guide-es/concept-aliases.md @@ -6,7 +6,7 @@ en tu código. Un alias debe comenzar con un cáracter `@` para que así pueda s Por ejemplo, el alias `@yii` representa la ruta de instalación de la librería Yii, mientras que `@web` representa la URL base la aplicación que actualmente se está ejecutando. -Definiendo Alias +Definiendo Alias ---------------- Puedes llamar a [[Yii::setAlias()]] para definir un alias para una determinada ruta de archivo o URL. Por ejemplo, @@ -48,7 +48,7 @@ return [ ``` -Resolución de Alias +Resolución de Alias ------------------- Puedes llamar [[Yii::getAlias()]] para resolver un alias de raíz en la ruta o URL que representa. El mismo método puede @@ -80,7 +80,7 @@ Yii::getAlias('@foo/bar/file.php'); // muestra: /path2/bar/file.php Si `@foo/bar` no está definido como un alias de raíz, la última declaración mostraría `/path/to/foo/bar/file.php`. -Usando Alias +Usando Alias ------------ Los alias son utilizados en muchos lugares en Yii sin necesidad de llamar [[Yii::getAlias()]] para convertirlos en rutas/URLs. @@ -97,29 +97,31 @@ $cache = new FileCache([ Por favor, presta atención a la documentación API para ver si una propiedad o el parámetro de un método soporta alias. -Alias Predefinidos + +Alias Predefinidos ------------------ Yii predefine un conjunto de alias para aliviar la necesidad de hacer referencia a rutas de archivo o URLs que son utilizadas regularmente. La siguiente es la lista de alias predefinidos por Yii: -- `@yii`: el directorio donde el archivo `BaseYii.php` se encuentra (también llamado el directorio de la libreria). +- `@yii`: el directorio donde el archivo `BaseYii.php` se encuentra (también llamado el directorio del framework). - `@app`: la [[yii\base\Application::basePath|ruta base]] de la aplicación que se está ejecutando actualmente. -- `@runtime`: la [[yii\base\Application::runtimePath|ruta de ejecución]] (carpeta `runtime) de la aplicación que se ` - está ejecutando actualmente. -- `@vendor`: el [[yii\base\Application::vendorPath|directorio vendor de Composer]. +- `@runtime`: la [[yii\base\Application::runtimePath|ruta de ejecución]] de la aplicación en ejecución. Por defecto `@app/runtime`. - `@webroot`: el directorio raíz Web de la aplicación Web se está ejecutando actualmente. -- `@web`: la URL base de la aplicación web se ejecuta actualmente. +- `@web`: la URL base de la aplicación web se ejecuta actualmente. Tiene el mismo valor que [[yii\web\Request::baseUrl]]. +- `@vendor`: el [[yii\base\Application::vendorPath|directorio vendor de Composer]. Por defecto `@app/vendor`. +- `@bower`, el directorio raíz que contiene [paquetes bower](http://bower.io/). Por defecto `@vendor/bower`. +- `@npm`, el directorio raíz que contiene [paquetes npm](https://www.npmjs.org/). Por defecto `@vendor/npm`. El alias `@yii` se define cuando incluyes el archivo `Yii.php` en tu [script de entrada](structure-entry-scripts.md), mientras que el resto de los alias están definidos en el constructor de la aplicación cuando se aplica la [configuración](concept-configurations.md) de la aplicación. -Alias en Extensiones +Alias en Extensiones -------------------- -Un alias se define automaticamente por cada [extension](structure-extensions.md) que ha sido instalada a través de Composer. +Un alias se define automaticamente por cada [extensión](structure-extensions.md) que ha sido instalada a través de Composer. El alias es nombrado tras el `namespace` de raíz de la extensión instalada tal y como está declarada en su archivo `composer.json`, y representa el directorio raíz de la extensión. Por ejemplo, si instalas la extensión `yiisoft/yii2-jui`, tendrás automaticamente definido el alias `@yii/jui` durante la etapa [bootstrapping](runtime-bootstrapping.md) de la aplicación: diff --git a/docs/guide-es/concept-autoloading.md b/docs/guide-es/concept-autoloading.md index b7d01ca..900ad25 100644 --- a/docs/guide-es/concept-autoloading.md +++ b/docs/guide-es/concept-autoloading.md @@ -1,7 +1,7 @@ Autocarga de clases =================== -Yii depende del [mecanismo de autocarga de clases](http://www.php.net/manual/en/language.oop5.autoload.php) para localizar +Yii depende del [mecanismo de autocarga de clases](http://www.php.net/manual/es/language.oop5.autoload.php) para localizar e incluir los archivos de las clases requiridas. Proporciona un cargador de clases de alto rendimiento que cumple con el [estandard PSR-4](https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md). El cargador se instala cuando incluyes el archivo `Yii.php`. @@ -10,7 +10,7 @@ El cargador se instala cuando incluyes el archivo `Yii.php`. ten en cuenta que el contenido que describimos aquí también se aplica a la autocarga de interfaces y rasgos (Traits). -Usando el Autocargador de Yii +Usando el Autocargador de Yii ----------------------------- Para utilizar el cargador automático de clases de Yii, deberías seguir dos reglas básicas cuando desarrolles y nombres tus @@ -40,7 +40,7 @@ poner las clases `front-end` bajo el espacio de nombres `frontend` mientras que `backend`. Esto permitirá que estas clases sean automaticamente cargadas por el autocargador de Yii. -Mapa de Clases +Mapa de Clases -------------- El autocargador de clases de Yii soporta el *mapa de clases*, que mapea nombres de clases to sus correpondientes rutas de @@ -59,7 +59,7 @@ clases en el proceso [bootstrapping](runtime-bootstrapping.md) de la aplicación antes de que tus clases sean usadas. -Usando otros Autocargadores +Usando otros Autocargadores --------------------------- Debido a que Yii incluye Composer como un gestor de dependencias y extensions, es recomendado que también instales el @@ -85,7 +85,7 @@ ser autocargables. incluirlo en tu [script de entrada](structure-entry-scripts.md). -Carga Automática de Clases de Extensiones +Carga Automática de Clases de Extensiones ----------------------------------------- El autocargador de Yii es capaz de autocargar clases de [extensiones](structure-extensions.md). El único requirimiento es diff --git a/docs/guide-es/concept-behaviors.md b/docs/guide-es/concept-behaviors.md index 4a6ff48..fbbbf16 100644 --- a/docs/guide-es/concept-behaviors.md +++ b/docs/guide-es/concept-behaviors.md @@ -10,58 +10,99 @@ comportamiento puede responder a [eventos](concept-events.md) disparados por el o adaptar a la ejecución normal del código del componente. -Usando comportamientos ----------------------- +Definiendo comportamientos +-------------------------- -Para poder utilizar un comportamiento, primero tienes que unirlo a un [[yii\base\Component|componente]]. Describiremos cómo -puedes vincular un comportamiento en la próxima sub-sección. +Para definir un comportamiento, se debe crear una clase que exiende [[yii\base\Behavior]], o se extiende una clase hija. Por ejemplo: -Una vez que el comportamiento ha sido vinculado a un componente, su uso es sencillo. +```php +namespace app\components; -Puedes usar a una variable *pública* o a una [propiedad](concept-properties.md) definida por un `getter` y/o un `setter` -del comportamiento a través del componente con el que se ha vinculado, como por ejemplo, +use yii\base\Behavior; -```php -// "prop1" es una propiedad definida en la clase comportamiento -echo $component->prop1; -$component->prop1 = $value; -``` +class MyBehavior extends Behavior +{ + public $prop1; -También puedes llamar métodos *públicos* del comportamiento de una forma similar, + private $_prop2; -```php -// bar() es un método público definido dentro de la clase comportamiento -$component->bar(); + public function getProp2() + { + return $this->_prop2; + } + + public function setProp2($value) + { + $this->_prop2 = $value; + } + + public function foo() + { + // ... + } +} ``` +El código anterior define la clase de comportamiento (behavior) app\components\MyBehavior`, con dos propiedades -- +`prop1` y `prop2`--y un método `foo()`. Tenga en cuenta que la propiedad `prop2` +se define a través de la getter `getProp2()` y el setter `setProp2()`. Este caso es porque [[yii\base\Behavior]] extiende [[yii\base\Object]] y por lo tanto se apoya en la definición de [propiedades](concept-properties.md) via getters y setters. -Como puedes ver, aunque `$component` no tiene definida `prop1` y `bar()`, pueden ser usadas como si fueran parte -definida del componente. +Debido a que esta clase es un comportamiento, cuando está unido a un componente, el componente también tienen la propiedad `prop1` y `prop2` y el método `foo()`. -Si dos comportamientos definen la misma propiedad o método y ambos están vinculados con el mismo componente, el -comportamiento que ha sido vinculado primero tendrá preferencia cuando se esté accediendo a la propiedad o método. +> Consejo: Dentro de un comportamiento, puede acceder al componente que el comportamiento está unido a través de la propiedad [[yii\base\Behavior::owner]]. -Un comportamiento puede estar asociado con un nombre cuando se une a un componente. Si este es el caso, es posible -acceder al objeto de comportamiento mediante el nombre, como se muestra a continuación, + +Gestión de eventos de componentes +--------------------------------- + +Si un comportamiento necesita responder a los acontecimientos desencadenados por el componente al que está unido, se debe reemplazar el método [[yii\base\Behavior::events()]]. Por ejemplo: ```php -$behavior = $component->getBehavior('myBehavior'); +namespace app\components; + +use yii\db\ActiveRecord; +use yii\base\Behavior; + +class MyBehavior extends Behavior +{ + // ... + + public function events() + { + return [ + ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate', + ]; + } + + public function beforeValidate($event) + { + // ... + } +} ``` -También puedes acceder a todos los comportamientos vinculados al componente: +El método [[yii\base\Behavior::events()|events()]] debe devolver una lista de eventos y sus correspondientes controladores. +El ejemplo anterior declara que el evento [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]] existe y esta exists y define su controlador, `beforeValidate()`. Al especificar un controlador de eventos, puede utilizar uno de los siguientes formatos: + +* una cadena que se refiere al nombre de un método de la clase del comportamiento, como el ejemplo anterior +* un arreglo de objeto o nombre de clase, y un nombre de método como una cadena (sin paréntesis), ej., `[$object, 'methodName']`; +* una función anónima + +La firma de un controlador de eventos debe ser la siguiente, donde `$ event` refiere al parámetro de evento. Por favor, consulte la sección [Eventos](concept-events.md) para más detalles sobre los eventos. ```php -$behaviors = $component->getBehaviors(); +function ($event) { +} ``` -Vinculando Comportamientos +Vinculando Comportamientos -------------------------- Puedes vincular un comportamiento a un [[yii\base\Component|componente]] ya sea estática o dinámicamente. La primera forma es la más comúnmente utilizada en la práctica. -Para unir un comportamiento estáticamente, reemplaza el método [[yii\base\Component::behaviors()|behaviors()]] de la -clase componente que se está conectando. Por ejemplo, +Para unir un comportamiento estáticamente, reemplaza el método [[yii\base\Component::behaviors()|behaviors()]] dde la clase de componente a la que se une el comportamiento. El método [[yii\base\Component::behaviors()|behaviors()]] debe devolver una lista de comportamiento [configuraciones](concept-configurations.md). +Cada configuración de comportamiento puede ser un nombre de clase de comportamiento o un arreglo de configuración: ```php namespace app\models; @@ -74,20 +115,20 @@ class User extends ActiveRecord public function behaviors() { return [ - // comportamiento anónimo, sólo el nombre de la clase del comportamiento + // anonymous behavior, behavior class name only MyBehavior::className(), - // comportamiento nombrado, sólo el nombre de la clase del comportamiento + // named behavior, behavior class name only 'myBehavior2' => MyBehavior::className(), - // comportamiento anónimo, matriz de configuración + // anonymous behavior, configuration array [ 'class' => MyBehavior::className(), 'prop1' => 'value1', 'prop2' => 'value2', ], - // comportamiento nombrado, matriz de configuración + // named behavior, configuration array 'myBehavior4' => [ 'class' => MyBehavior::className(), 'prop1' => 'value1', @@ -98,17 +139,13 @@ class User extends ActiveRecord } ``` -El método [[yii\base\Component::behaviors()|behaviors()]] tiene que devolver la lista de los comportamientos -[configuraciones](concept-configurations.md). -Cada configuración de un comportamiento puede ser el nombre de la clase o una matriz de configuración. - Puedes asociciar un nombre a un comportamiento especificándolo en la clave de la matriz correspondiente a la configuración del comportamiento. En este caso, el comportamiento puede ser llamado un *comportamiento nombrado* (named behavior). En el ejemplo anterior, hay dos tipos de comportamientos nombrados: `myBehavior2` y `myBehavior4`. Si un comportamiento no está asociado con un nombre, se le llama *comportamiento anónimo* (anonymous behavior). Para vincular un comportamiento dinámicamente, llama al método [[yii\base\Component::attachBehavior()]] desde el componente al -que se le va a unir el comportamiento. Por ejemplo, +que se le va a unir el comportamiento: ```php use app\components\MyBehavior; @@ -126,19 +163,16 @@ $component->attachBehavior('myBehavior3', [ 'prop2' => 'value2', ]); ``` - -You may attach multiple behaviors at once by using the [[yii\base\Component::attachBehaviors()]] method. -For example, +Puede vincular múltiples comportamientos a la vez mediante el uso del método [[yii\base\Component::attachBehaviors()]]. Por ejemplo, ```php $component->attachBehaviors([ - 'myBehavior1' => new MyBehavior, // a named behavior - MyBehavior::className(), // an anonymous behavior + 'myBehavior1' => new MyBehavior, // un comportamiento nombrado + MyBehavior::className(), // un comportamiento anónimo ]); ``` -También puedes asociar comportamientos a traves de [configuraciones](concept-configurations.md) compor el siguiente -ejemplo. Para más detalles, por favor visita la sección [Configuraciones](concept-configurations.md#configuration-format). +También puedes asociar comportamientos a traves de [configuraciones](concept-configurations.md) como el siguiente: ```php [ @@ -152,121 +186,73 @@ ejemplo. Para más detalles, por favor visita la sección [Configuraciones](conc ] ``` +Para más detalles, por favor visita la sección [Configuraciones](concept-configurations.md#configuration-format). -Desasociar Comportamientos --------------------------- -Para desasociar un comportamiento, puedes llamar el método [[yii\base\Component::detachBehavior()]] con el nombre con el -que se le asoció: +Usando comportamientos +---------------------- -```php -$component->detachBehavior('myBehavior1'); -``` +Para poder utilizar un comportamiento, primero tienes que unirlo a un [[yii\base\Component|componente]] según las instrucciones anteriores. Una vez que un comportamiento ha sido vinculado a un componente, su uso es sencillo. -También puedes desvincular *todos* los comportamientos: +Puedes usar a una variable *pública* o a una [propiedad](concept-properties.md) definida por un `getter` y/o un `setter` +del comportamiento a través del componente con el que se ha vinculado: ```php -$component->detachBehaviors(); +// "prop1" es una propiedad definida en la clase comportamiento +echo $component->prop1; +$component->prop1 = $value; ``` - -Definiendo Comportamientos --------------------------- - -Para definir un comportamiento, crea una clase extendendiéndola de [[yii\base\Behavior]] o una de sus clases "hija". Por ejemplo, +También puedes llamar métodos *públicos* del comportamiento de una forma similar: ```php -namespace app\components; - -use yii\base\Model; -use yii\base\Behavior; - -class MyBehavior extends Behavior -{ - public $prop1; +// foo() es un método público definido dentro de la clase comportamiento +$component->foo(); +``` - private $_prop2; +Como puedes ver, aunque `$component` no tiene definida `prop1` y `bar()`, que se pueden utilizar como si son parte +de la definición de componentes debido al comportamiento vinculado. - public function getProp2() - { - return $this->_prop2; - } +Si dos comportamientos definen la misma propiedad o método y ambos están vinculados con el mismo componente, el +comportamiento que ha sido vinculado *primero* tendrá preferencia cuando se esté accediendo a la propiedad o método. - public function setProp2($value) - { - $this->_prop2 = $value; - } +Un comportamiento puede estar asociado con un nombre cuando se une a un componente. Si este es el caso, es posible +acceder al objeto de comportamiento mediante el nombre, como se muestra a continuación, - public function foo() - { - // ... - } -} +```php +$behavior = $component->getBehavior('myBehavior'); ``` -El código anterior define la clase del comportamiento `app\components\MyBehavior` que provee dos propiedades `prop1` y -`prop2`, y un método `foo()` al componente con el que está asociado. - -The above code defines the behavior class `app\components\MyBehavior` which will provide two properties -`prop1` and `prop2`, and one method `foo()` to the component it is attached to. Fíjese que la propiedad `prop2` esta -definida a través del getter `getProp2()` y el setter `setProp2()`. Esto es debido a que [[yii\base\Object]] es una -clase "ancestro" (o padre) de [[yii\base\Behavior]], la cual soporta la definición de [propiedades](concept-properties.md) por -getters/setters. - -En un comportamiento, puedes acceder al componente al que está vinculado a través de la propiedad [[yii\base\Behavior::owner]]. - -Si un omportamiento necesita responder a los eventos que han sido disparados desde el componente al qu están asociados, -debería sobreescribir el método [[yii\base\Behavior::events()]]. Por ejemplo, +También puedes acceder a todos los comportamientos vinculados al componente: ```php -namespace app\components; +$behaviors = $component->getBehaviors(); +``` -use yii\db\ActiveRecord; -use yii\base\Behavior; -class MyBehavior extends Behavior -{ - // ... +Desasociar Comportamientos +-------------------------- - public function events() - { - return [ - ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate', - ]; - } +Para desasociar un comportamiento, puedes llamar el método [[yii\base\Component::detachBehavior()]] con el nombre con el +que se le asoció: - public function beforeValidate($event) - { - // ... - } -} +```php +$component->detachBehavior('myBehavior1'); ``` -El método [[yii\base\Behavior::events()|events()]] tiene que devolver un listado de eventos y sus correspondientes -controladores (handlers). El código anterior declara el evento [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]] -con su controlador `beforeValidate()`. Cuando se especifica un controlador de evento, pudes utilizar uno de los siguientes -formatos: - -* una cadena que se refiere al nombre de un método de la clase comportamiento, como el ejemplo anterior; -* una matriz con un objeto o nombre de la clase, y el nombre de un método, por ejemplo, `[$object, 'nombreMétodo']`; -* una función anónima. - -El formato de un controlador de eventos tendría que ser como se describe a continuación, donde `$event` se refiere al -parámetro `evento`. Por favor, visita la sección [Eventos](concept-events.md) para obtener más información acerca de -eventos. +También puedes desvincular *todos* los comportamientos: ```php -function ($event) { -} +$component->detachBehaviors(); ``` -Utilizando `TimestampBehavior` +Utilizando `TimestampBehavior` ----------------------------- -Para terminar, vamos a echar un vistazo a [[yii\behaviors\TimestampBehavior]] - un comportamiento que soporta de forma -automática la actualización de atributos `timestamp` (sellos de tiempo) de un [[yii\db\ActiveRecord|Registro Activo]] -(Active Record) cuando éste está siendo guardado. +Para terminar, vamos a echar un vistazo a [[yii\behaviors\TimestampBehavior]]. Este comportamiento soporta de forma +automática la actualización de atributos timestamp de un modelo [[yii\db\ActiveRecord|Registro Activo]] +(Active Record) en cualquier momento donde se guarda el modelo (ej., en la inserción o actualización). Primero, vincula este comportamiento a la clase [[yii\db\ActiveRecord|Active Record]] que desees utilizar. @@ -300,7 +286,7 @@ La configuración del comportamiento anterior especifica que * cuando el registro está siendo insertado, el comportamiento debe asignar el sello de tiempo actual a los atributos `created_at` y `updated_at`; * cuando el registro está siendo actualizado, el comportamiento debe asignar el sello de tiempo actual al atributo - `updated_at. + `updated_at`. Ahora si tienes un objeto `User` e intentas guardarlo, descubrirás que sus campos `created_at` y `updated_at` están automáticamente actualizados con el sello de tiempo actual: @@ -313,26 +299,25 @@ echo $user->created_at; // muestra el sello tiempo actual (timestamp) ``` El comportamiento [[yii\behaviors\TimestampBehavior|TimestampBehavior]] también ofrece un método muy útil llamado -[[yii\behaviors\TimestampBehavior::touch()|touch()]], que asigna el sello de tiempo actual a un atributo especificado y -lo guarda automáticamente en la base de datos: +[[yii\behaviors\TimestampBehavior::touch()|touch()]], que asigna el sello de tiempo actual a un atributo especificado y lo guarda automáticamente en la base de datos: ```php $user->touch('login_time'); ``` -Comparación con Traits +Comparación con Traits ---------------------- Mientras que los comportamientos son similares a [traits](http://www.php.net/traits) en cuanto que ambos "inyectan" sus métodos y propiedades a la clase primaria, son diferentes en muchos aspectos. Tal y como se describe abajo, los dos -tienen sus ventajas y desventajas. Son much mejor descritos como complementos y no como reemplazos entre sí. +tienen sus ventajas y desventajas. Son más como complementos el uno al otro en lugar de alternativas. -### Las Ventajas de los Comportamientos +### Razones para utilizar comportamientos -Las clases de comportamientos (Behaviors), como todas las clases, soportan herencias. Traits, por otro lado, pueden ser -considerados como un copia-y-pega de PHP. Los Traits no soportan la herencia de clases. +Las clases de comportamientos, como todas las clases, soportan herencias. Traits, por otro lado, pueden ser +considerados como un copia-y-pega de PHP. Ellos no soportan la herencia de clases. Los comportamientos pueden ser asociados y desasociados a un componente dinámicamente sin necesidad de que la clase del componente sea modificada. Para usar un trait, debes modificar la clase que la usa. @@ -343,14 +328,13 @@ Los comportamientos pueden personalizar la ejecución de un componente al respon Cuando hay un conflicto de nombre entre los diferentes comportamientos vinculados a un mismo componente, el conflicto es automáticamente resuelto respetando al que ha sido asociado primero. -El conflicto de nombres en traits requiere que manualmente sean resueltos cambiando el nombre de las propiedades o métodos -afectados. +El conflicto de nombres en traits requiere que manualmente sean resueltos cambiando el nombre de las propiedades o métodos afectados. -### Las Ventajas de los Traits +### Razones para utilizar los Traits Los Traits son mucho más eficientes que los comportamientos debido a que los últimos son objetos que consumen tiempo y memoria. -Los IDEs (Programas de desarrollo) trabajan mucho mejor con traits ya que forman parte del lenguaje PHP. +Los IDEs (Programas de desarrollo) son más amigables con traits ya que son una construcción del lenguaje nativo. diff --git a/docs/guide-es/concept-components.md b/docs/guide-es/concept-components.md index 4ce239a..b00ca26 100644 --- a/docs/guide-es/concept-components.md +++ b/docs/guide-es/concept-components.md @@ -29,9 +29,9 @@ Si tus componentes no necesitan estas dos características, deberías considerar Cuando extiendes tu clase de [[yii\base\Component]] o [[yii\base\Object]], se recomienda que sigas las siguientes convenciones: -- Si sobrescribes el constructor, especifica un parámetro `$config` como el *último* parámetro del constructor, y después pasa este parámetro al constructor de la clase "padre". -- Siempre llama al constructor del "padre" al *final* de su propio constructor. -- Si sobrescribes el método [[yii\base\Object::init()]], asegúrate de que llamas a la implementación de la clase "padre" *al principio* de tu método `init`. +- Si sobrescribes el constructor, especifica un parámetro `$config` como el *último* parámetro del constructor, y después pasa este parámetro al constructor padre. +- Siempre llama al constructor padre al *final* de su propio constructor. +- Si sobrescribes el método [[yii\base\Object::init()]], asegúrese de llamar la implementación padre de `init` * al principio * de su método` init`. Por ejemplo: diff --git a/docs/guide-es/concept-configurations.md b/docs/guide-es/concept-configurations.md index 15068f5..a59447f 100644 --- a/docs/guide-es/concept-configurations.md +++ b/docs/guide-es/concept-configurations.md @@ -26,7 +26,7 @@ Yii::configure($object, $config); Tenga en cuenta que en este caso, la matriz de configuración no debe contener un elemento `class`. -## Formato de Configuración +## Formato de Configuración El formato de una configuración se puede describir formalmente como: @@ -63,14 +63,14 @@ A continuación se muestra un ejemplo de una configuración con los valores de p ``` -## Usando Configuraciones +## Usando Configuraciones Las configuraciones se utilizan en muchos lugares en Yii. Al comienzo de esta sección, hemos demostrado cómo crear un objeto según una configuración mediante el uso de [[Yii::CreateObject()]]. En este apartado, vamos a describir configuraciones de aplicaciones y configuraciones widget - dos principales usos de configuraciones. -### Configuraciones de aplicación +### Configuraciones de aplicación -Configuración para una [aplicación](structure-applications.md) es probablemente una de las configuraciones más complejas. Esto se debe a que la clase [[yii\web\Application|application]] tiene un montón de propiedades y eventos configurables. Más importante aún, su propiedad [[yii\web\Application::components|components]] que puede recibir una gran variedad de configuraciones para crear componentes que se registran a través de la aplicación. Lo siguiente es un resumen del archivo de configuración de la aplicación para la [plantilla básica de la aplicación](start-installation.md). +Configuración para una [aplicación](structure-applications.md) es probablemente una de las configuraciones más complejas. Esto se debe a que la clase [[yii\web\Application|aplicación]] tiene un montón de propiedades y eventos configurables. Más importante aún, su propiedad [[yii\web\Application::components|componentes]] que puede recibir una gran variedad de configuraciones para crear componentes que se registran a través de la aplicación. Lo siguiente es un resumen del archivo de configuración de la aplicación para la [plantilla básica de la aplicación](start-installation.md). ```php $config = [ @@ -113,7 +113,7 @@ La configuración no tiene una clave `class`. Esto es porque se utiliza como sig Para más detalles sobre la configuración de la propiedad `components` de una aplicación se puede encontrar en la sección [Aplicación](structure-applications.md) y la sección [Localizador de Servicio](concept-service-locator.md). -### Configuración Widget +### Configuración Widget Cuando se utiliza [widgets](structure-widgets.md), a menudo es necesario utilizar las configuraciones para personalizar las propiedades de widgets. Tanto los metodos [[yii\base\Widget::widget()]] y [[yii\base\Widget::begin()]] pueden usarse para crear un widget. Toman un arreglo de configuración, como el siguiente, @@ -135,9 +135,9 @@ El código anterior crea un widget `Menu` e inicializa su propiedad `activeItems Tenga en cuenta que debido a que el nombre de la clase ya está dado, la matriz de configuración no deben tener la clave `class`. -## Archivos de Configuración +## Archivos de Configuración -Cuando una configuración es muy compleja, una práctica común es almacenarla en uno o múltiples archivos PHP, conocidos como *Los archivos de configuración*. Un archivo de configuración devuelve un array de PHP que representa la configuración. Por ejemplo, es posible mantener una configuración de la aplicación en un archivo llamado `web.php`, como el siguiente, +Cuando una configuración es muy compleja, una práctica común es almacenarla en uno o múltiples archivos PHP, conocidos como *archivos de configuración*. Un archivo de configuración devuelve un array de PHP que representa la configuración. Por ejemplo, es posible mantener una configuración de la aplicación en un archivo llamado `web.php`, como el siguiente, ```php return [ @@ -185,7 +185,7 @@ $config = require('path/to/web.php'); ``` -## Configuraciones por Defecto +## Configuraciones por Defecto El método [[Yii::createObject()]] es implementado en base a [contenedor de inyección de dependencia](concept-di-container.md). Le permite especificar un conjunto de los llamados *configuraciones predeterminadas* que se aplicarán a todos los casos de las clases especificadas cuando se crean utilizando [[Yii::createObject()]]. Las configuraciones por defecto se puede especificar llamando `Yii::$container->set()` en el código [bootstrapping](runtime-bootstrapping.md). @@ -199,7 +199,7 @@ Por ejemplo, si desea personalizar [[yii\widgets\LinkPager]] para que TODO enlac Sin utilizar las configuraciones predeterminadas, usted tendría que configurar `maxButtonCount` en cada lugar en el que utiliza enlace paginador. -## Constantes de Entorno +## Constantes de Entorno Las configuraciones a menudo varían de acuerdo al entorno en que se ejecuta una aplicación. Por ejemplo, en el entorno de desarrollo, es posible que desee utilizar una base de datos llamada `mydb_dev`, mientras que en servidor de producción es posible que desee utilizar la base de datos `mydb_prod`. Para facilitar la conmutación de entornos, Yii proporciona una constante llamado `YII_ENV` que se puede definir en el [script de entrada](structure-entry-scripts.md) de su aplicación. Por ejemplo, @@ -209,7 +209,8 @@ defined('YII_ENV') or define('YII_ENV', 'dev'); Usted puede definir `YII_ENV` como uno de los valores siguientes: -- `prod`: entorno de producción. La constante `YII_ENV_PROD` evaluará como verdadero. Este es el valor por defecto de `YII_ENV` si no lo define. +- `prod`: entorno de producción. La constante `YII_ENV_PROD` evaluará como verdadero. +Este es el valor por defecto de `YII_ENV` si no esta definida. - `dev`: entorno de desarrollo. La constante `YII_ENV_DEV` evaluará como verdadero. - `test`: entorno de pruebas. La constante `YII_ENV_TEST` evaluará como verdadero. diff --git a/docs/guide-es/concept-di-container.md b/docs/guide-es/concept-di-container.md index 5e643fb..80eea95 100644 --- a/docs/guide-es/concept-di-container.md +++ b/docs/guide-es/concept-di-container.md @@ -6,7 +6,7 @@ objetos dependientes. El [articulo de Martin](http://martinfowler.com/articles/i explicación de porque son útiles los contenedores de ID. A continuación explicaremos como usar el contenedor de ID que proporciona Yii. -Inyección de Dependencias +Inyección de Dependencias ------------------------- Yii proporciona la función de contenedor de ID mediante la clase [[yii\di\Container]]. Soporta los siguientes tipos @@ -16,7 +16,7 @@ de ID: * Inyección de setters y propiedades; * Inyección de [llamadas de retorno PHP](http://php.net/manual/es/language.types.callable.php); -### Inyección de Constructores +### Inyección de Constructores El contenedor de ID soporta inyección de constructores con la ayuda de los indicios (hint) de tipo para los parámetros del constructor. Los indicios de tipo le proporcionan información al contenedor para saber cuáles son las clases o @@ -37,7 +37,7 @@ $bar = new Bar; $foo = new Foo($bar); ``` -### Inyección de Setters y Propiedades +### Inyección de Setters y Propiedades La inyección de setters y propiedades se admite a través de [configuraciones](concept-configurations.md). Cuando se registra una dependencia o se crea un nuevo objeto, se puede proporcionar una configuración que usará el contenedor @@ -69,7 +69,7 @@ $container->get('Foo', [], [ ]); ``` -### Inyección de Llamadas de retorno PHP +### Inyección de Llamadas de retorno PHP En este caso, el contenedor usará una llamada de retorno PHP registrada para construir una nueva instancia de una clase. La llamada de retorno se responsabiliza de que dependencias debe inyectar al nuevo objeto creado. Por ejemplo, @@ -82,7 +82,7 @@ $container->set('Foo', function () { $foo = $container->get('Foo'); ``` -Registro de dependencias +Registro de dependencias ------------------------ Se puede usar [[yii\di\Container::set()]] para registrar dependencias. El registro requiere un nombre de dependencia @@ -150,7 +150,7 @@ $container->setSingleton('yii\db\Connection', [ ]); ``` -Resolución de Dependencias +Resolución de Dependencias -------------------------- Una ves se hayan registrado las dependencias, se puede usar el contenedor de ID para crear nuevos objetos, y el @@ -238,7 +238,7 @@ $finder = new UserFinder($db); $lister = new UserLister($finder); ``` -Uso Practico +Uso Practico ------------ Yii crea un contenedor de ID cuando se incluye el archivo `Yii.php` en el @@ -300,7 +300,7 @@ instanciada. Esto se debe a que necesitamos indicar al contenedor de ID como tra Ahora si se accede al contenedor nuevamente, se creará una instancia de `app\components\BookingService` y se inyectará a como tercer parámetro al constructor del controlador. -Cuando Registrar Dependencias +Cuando Registrar Dependencias ----------------------------- El registro de dependencias debe hacerse lo antes posible debido a que las dependencias se necesitan cuando se crean @@ -311,7 +311,7 @@ nuevos objetos. A continuación se listan practicas recomendadas: * Siendo desarrolladores de una [extension](structure-extensions.md) redistribuible, podemos registrar dependencias en la clase de boostraping de la extensión. -Resumen +Resumen ------- Tanto la inyección de dependencias como el [localizador de servicios](concept-service-locator.md) son patrones de diff --git a/docs/guide-es/concept-events.md b/docs/guide-es/concept-events.md index b02ec88..741cc5d 100644 --- a/docs/guide-es/concept-events.md +++ b/docs/guide-es/concept-events.md @@ -1,27 +1,27 @@ Eventos ======= -Los eventos permiten inyectar código dentro de otro código existente en ciertos puntos de ejecución. Se pueden adjuntar -código personalizado a un evento, cuando se lance (triggered), el código se ejecutará automáticamente. Por ejemplo, un -objeto `mailer` puede lanzar el evento `messageSent` cuando se envía un mensaje correctamente. Si se quiere rastrear +Los eventos permiten inyectar código dentro de otro código existente en ciertos puntos de ejecución. Se pueden adjuntar +código personalizado a un evento, cuando se lance (triggered), el código se ejecutará automáticamente. Por ejemplo, un +objeto mailer puede lanzar el evento `messageSent` cuando se envía un mensaje correctamente. Si se quiere rastrear el correcto envío del mensaje, se puede, simplemente, añadir un código de seguimiento al evento `messageSent`. -Yii introduce una clase base [[yii\base\Component]] para soportar eventos. Si una clase necesita lanzar un evento, +Yii introduce una clase base [[yii\base\Component]] para soportar eventos. Si una clase necesita lanzar un evento, este debe extender a [[yii\base\Component]] o a una clase hija. -Gestor de Eventos +Gestor de Eventos ----------------- -Un gestor de eventos es una -[llamada de retorno PHP (PHP callback)](http://php.net/manual/es/language.types.callable.php) que se ejecuta cuando se +Un gestor de eventos es una +[llamada de retorno PHP (PHP callback)](http://php.net/manual/es/language.types.callable.php) que se ejecuta cuando se lanza el evento al que corresponde. Se puede usar cualquier llamada de retorno de las enumeradas a continuación: -- una función de PHP global especificada como una cadena de texto (sin paréntesis), p. ej. `'trim'`; -- un método de objeto especificado como un array de un objeto y un nombre de método como una cadena de texto - (sin paréntesis), p. ej. `[$object, 'methodNAme']`; -- un método de clase estático especificado como un array de un nombre de clase y un método como una cadena de texto - (sin paréntesis), p. ej. `[$class, 'methodName']`; -- una función anónima, p. ej. `function ($event) { ... }`. +- una función de PHP global especificada como una cadena de texto (sin paréntesis), ej. `'trim'`; +- un método de objeto especificado como un array de un objeto y un nombre de método como una cadena de texto + (sin paréntesis), ej. `[$object, 'methodNAme']`; +- un método de clase estático especificado como un array de un nombre de clase y un método como una cadena de texto + (sin paréntesis), ej. `[$class, 'methodName']`; +- una función anónima, ej. `function ($event) { ... }`. La firma de un gestor de eventos es: @@ -31,15 +31,16 @@ function ($event) { } ``` -Un gestor de eventos puede obtener la siguiente información acerca de un evento ya sucedido mediante el parámetro +Un gestor de eventos puede obtener la siguiente información acerca de un evento ya sucedido mediante el parámetro `$event`: -- [[yii\base\Event::name|event name]] -- [[yii\base\Event::sender|event sender]]: el objeto desde el que se ha ejecutado `trigger()` -- [[yii\base\Event::data|custom data]]: los datos que se proporcionan al adjuntar el gestor de eventos +- [[yii\base\Event::name|nombre del evento]] +- [[yii\base\Event::sender|evento enviando]]: el objeto desde el que se ha ejecutado `trigger()` +- [[yii\base\Event::data|custom data]]: los datos que se proporcionan al adjuntar el gestor de eventos (se explicará más adelante) -Añadir Gestores de Eventos + +Añadir Gestores de Eventos -------------------------- Se puede añadir un gestor a un evento llamando al método [[yii\base\Component::on()]]. Por ejemplo: @@ -62,16 +63,16 @@ $foo->on(Foo::EVENT_HELLO, function ($event) { }); ``` -También se pueden adjuntar gestores de eventos mediante [configuraciones](concept-configurations.md). Se pueden +También se pueden adjuntar gestores de eventos mediante [configuraciones](concept-configurations.md). Se pueden encontrar más de talles en la sección [Configuraciones](concept-configurations.md#configuration-format). -Cuando se adjunta un gestor de eventos, se pueden proporcionar datos adicionales como tercer parámetro de -[[yii\base\Component::on()]]. El gestor podrá acceder a los datos cuando se lance el evento y se ejecute el gestor. +Cuando se adjunta un gestor de eventos, se pueden proporcionar datos adicionales como tercer parámetro de +[[yii\base\Component::on()]]. El gestor podrá acceder a los datos cuando se lance el evento y se ejecute el gestor. Por ejemplo: -```php +```php // El siguiente código muestra "abc" cuando se lanza el evento -// ya que $event->data contiene los datos enviados en el tercer parámetro de "on" +// ya que $event->data contiene los datos enviados en el tercer parámetro de "on" $foo->on(Foo::EVENT_HELLO, 'function_name', 'abc'); function function_name($event) { @@ -82,8 +83,8 @@ function function_name($event) { Ordenación de Gestores de Eventos --------------------------------- -Se puede adjuntar uno o más gestores a un único evento. Cuando se lanza un evento, se ejecutarán los gestores adjuntos -en el orden que se hayan añadido al evento. Si un gestor necesita parar la invocación de los gestores que le siguen, +Se puede adjuntar uno o más gestores a un único evento. Cuando se lanza un evento, se ejecutarán los gestores adjuntos +en el orden que se hayan añadido al evento. Si un gestor necesita parar la invocación de los gestores que le siguen, se puede establecer la propiedad [[yii\base\Event::handled]] del parámetro `$event` para que sea `true`: ```php @@ -92,10 +93,10 @@ $foo->on(Foo::EVENT_HELLO, function ($event) { }); ``` -De forma predeterminada, cada nuevo gestor añadido se pone a la cola de la lista de gestores del evento. Por lo tanto, -el gestor se ejecutará en el último lugar cuando se lance el evento. Para insertar un nuevo gestor al principio de la -cola de gestores para que sea ejecutado primero, se debe llamar a [[yii\base\Component::on()]], pasando al cuarto -parámetro `$append` el valor `false`: +De forma predeterminada, cada nuevo gestor añadido se pone a la cola de la lista de gestores del evento. Por lo tanto, +el gestor se ejecutará en el último lugar cuando se lance el evento. Para insertar un nuevo gestor al principio de la +cola de gestores para que sea ejecutado primero, se debe llamar a [[yii\base\Component::on()]], pasando al cuarto +parámetro `$append` el valor false: ```php $foo->on(Foo::EVENT_HELLO, function ($event) { @@ -103,11 +104,11 @@ $foo->on(Foo::EVENT_HELLO, function ($event) { }, $data, false); ``` -Lanzamiento de Eventos +Lanzamiento de Eventos ---------------------- -Los eventos se lanzan llamando al método [[yii\base\Component::trigger()]]. El método requiere un *nombre de evento*, -y de forma opcional un objeto de evento que describa los parámetros que se enviarán a los gestores de eventos. Por +Los eventos se lanzan llamando al método [[yii\base\Component::trigger()]]. El método requiere un *nombre de evento*, +y de forma opcional un objeto de evento que describa los parámetros que se enviarán a los gestores de eventos. Por ejemplo: ```php @@ -129,16 +130,16 @@ class Foo extends Component Con el código anterior, cada llamada a `bar()` lanzará un evento llamado `hello` -> Consejo: Se recomienda usar las constantes de clase para representar nombres de eventos. En el anterior ejemplo, la - constante `EVENT_HELLO` representa el evento `hello`. Este enfoque proporciona tres beneficios. Primero, previene - errores tipográficos. Segundo, puede hacer que los IDEs reconozcan los eventos en las funciones de auto-completado. +> Consejo: Se recomienda usar las constantes de clase para representar nombres de eventos. En el anterior ejemplo, la + constante `EVENT_HELLO` representa el evento `hello`. Este enfoque proporciona tres beneficios. Primero, previene + errores tipográficos. Segundo, puede hacer que los IDEs reconozcan los eventos en las funciones de auto-completado. Tercero, se puede ver que eventos soporta una clase simplemente revisando la declaración de constantes. -A veces cuando se lanza un evento se puede querer pasar información adicional al gestor de eventos. Por ejemplo, un -`mailer` puede querer enviar la información del mensaje para que los gestores del evento `messageSent` para que los -gestores puedan saber las particularidades del mensaje enviado. Para hacerlo, se puede proporcionar un objeto de tipo -evento como segundo parámetro al método [[yii\base\Component::trigger()]]. El objeto de tipo evento debe ser una -instancia de la clase [[yii\base\Event]] o de sus hijas. Por ejemplo: +A veces cuando se lanza un evento se puede querer pasar información adicional al gestor de eventos. Por ejemplo, un +mailer puede querer enviar la información del mensaje para que los gestores del evento `messageSent` para que los +gestores puedan saber las particularidades del mensaje enviado. Para hacerlo, se puede proporcionar un objeto de tipo +evento como segundo parámetro al método [[yii\base\Component::trigger()]]. El objeto de tipo evento debe ser una +instancia de la clase [[yii\base\Event]] o de su clase hija. Por ejemplo: ```php namespace app\components; @@ -168,7 +169,7 @@ class Mailer extends Component Cuando se lanza el método [[yii\base\Component::trigger()]], se ejecutarán todos los gestores adjuntos al evento. -Desadjuntar Gestores de Evento +Desadjuntar Gestores de Evento ------------------------------ Para desadjuntar un gestor de un evento, se puede ejecutar el método [[yii\base\Component::off()]]. Por ejemplo: @@ -187,28 +188,28 @@ $foo->off(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']); $foo->off(Foo::EVENT_HELLO, $anonymousFunction); ``` -Tenga en cuenta que en general no se debe intentar desadjuntar las funciones anónimas a no ser que se almacene donde -se ha adjuntado al evento. En el anterior ejemplo, se asume que la función anónima se almacena como variable +Tenga en cuenta que en general no se debe intentar desadjuntar las funciones anónimas a no ser que se almacene donde +se ha adjuntado al evento. En el anterior ejemplo, se asume que la función anónima se almacena como variable `$anonymousFunction`. -Para desadjuntar TODOS los gestores de un evento, se puede llamar [[yii\base\Component::off()]] sin el segundo +Para desadjuntar TODOS los gestores de un evento, se puede llamar [[yii\base\Component::off()]] sin el segundo parámetro: ```php $foo->off(Foo::EVENT_HELLO); ``` -Nivel de Clase (Class-Level) Gestores de Eventos +Nivel de Clase (Class-Level) Gestores de Eventos ------------------------------------------------ -En las subsecciones anteriores se ha descrito como adjuntar un gestor a un evento a *nivel de instancia*. A veces, se -puede querer que un gestor responda todos los eventos de *todos* las instancias de una clase en lugar de una instancia -especifica. En lugar de adjuntar un gestor de eventos a una instancia, se puede adjuntar un gestor a *nivel de clase* +En las subsecciones anteriores se ha descrito como adjuntar un gestor a un evento a *nivel de instancia*. A veces, se +puede querer que un gestor responda todos los eventos de *todos* las instancias de una clase en lugar de una instancia +especifica. En lugar de adjuntar un gestor de eventos a una instancia, se puede adjuntar un gestor a *nivel de clase* llamando al método estático [[yii\base\Event::on()]]. -Por ejemplo, un objeto de tipo [Active Record](db-active-record.md) lanzará un evento -[[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]] cada vez que inserte un nuevo registro en la base -de datos. Para poder registrar las inserciones efectuadas por *todos* los objetos +Por ejemplo, un objeto de tipo [Active Record](db-active-record.md) lanzará un evento +[[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]] cada vez que inserte un nuevo registro en la base +de datos. Para poder registrar las inserciones efectuadas por *todos* los objetos [Active Record](db-active-record.md), se puede usar el siguiente código: ```php @@ -221,15 +222,15 @@ Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function }); ``` -Se invocará al gestor de eventos cada vez que una instancia de [[yii\db\ActiveRecord|ActiveRecord]], o de uno de sus -clases hijas, lance un evento de tipo [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]]. Se puede +Se invocará al gestor de eventos cada vez que una instancia de [[yii\db\ActiveRecord|ActiveRecord]], o de uno de sus +clases hijas, lance un evento de tipo [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]]. Se puede obtener el objeto que ha lanzado el evento mediante `$event->sender` en el gestor. -Cuando un objeto lanza un evento, primero llamará los gestores a nivel de instancia, y a continuación los gestores a +Cuando un objeto lanza un evento, primero llamará los gestores a nivel de instancia, y a continuación los gestores a nivel de clase. -Se puede lanzar un evento de tipo *nivel de clase* llamando al método estático [[yii\base\Event::trigger()]]. Un -evento de nivel de clase no se asocia a un objeto en particular. Como resultado, esto provocará solamente la +Se puede lanzar un evento de tipo *nivel de clase* llamando al método estático [[yii\base\Event::trigger()]]. Un +evento de nivel de clase no se asocia a un objeto en particular. Como resultado, esto provocará solamente la invocación de los gestores de eventos a nivel de clase. ```php @@ -242,11 +243,11 @@ Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { Event::trigger(Foo::className(), Foo::EVENT_HELLO); ``` -Tenga en cuenta que en este caso, el `$event->sender` hace referencia al nombre de la clase que lanza el evento en +Tenga en cuenta que en este caso, el `$event->sender` hace referencia al nombre de la clase que lanza el evento en lugar de a la instancia del objeto. -> Nota: Debido a que los gestores a nivel de clase responderán a los eventos lanzados por cualquier instancia de la -clase, o cualquier clase hija, se debe usar con cuidado, especialmente en las clases de bajo nivel (low-level), tales +> Nota: Debido a que los gestores a nivel de clase responderán a los eventos lanzados por cualquier instancia de la +clase, o cualquier clase hija, se debe usar con cuidado, especialmente en las clases de bajo nivel (low-level), tales como [[yii\base\Object]]. Para desadjuntar un gestor de eventos a nivel de clase, se tiene que llamar a [[yii\base\Event::off()]]. Por ejemplo: @@ -259,15 +260,15 @@ Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); Event::off(Foo::className(), Foo::EVENT_HELLO); ``` -Eventos Globales +Eventos Globales ---------------- -Yii soporta los llamados *eventos globales*, que en realidad es un truco basado en el gestor de eventos descrito -anteriormente. El evento global requiere un Singleton globalmente accesible, tal como la instancia de +Yii soporta los llamados *eventos globales*, que en realidad es un truco basado en el gestor de eventos descrito +anteriormente. El evento global requiere un Singleton globalmente accesible, tal como la instancia de [aplicación](structure-applications.md) en si misma. -Para crear un evento global, un evento remitente (event sender) llama al método `trigger()` del Singleton para lanzar -el evento, en lugar de llamar al propio método `trigger()` del remitente. De forma similar, los gestores de eventos se +Para crear un evento global, un evento remitente (event sender) llama al método `trigger()` del Singleton para lanzar +el evento, en lugar de llamar al propio método `trigger()` del remitente. De forma similar, los gestores de eventos se adjuntan al evento del Singleton. Por ejemplo: ```php @@ -282,10 +283,10 @@ Yii::$app->on('bar', function ($event) { Yii::$app->trigger('bar', new Event(['sender' => new Foo])); ``` -Un beneficio de usar eventos globales es que no se necesita un objeto cuando se adjuntan gestores a un evento para que -sean lanzados por el objeto. En su lugar, los gestores adjuntos y el lanzamiento de eventos se efectúan en el -Singleton (p. ej. la instancia de la aplicación). +Un beneficio de usar eventos globales es que no se necesita un objeto cuando se adjuntan gestores a un evento para que +sean lanzados por el objeto. En su lugar, los gestores adjuntos y el lanzamiento de eventos se efectúan en el +Singleton (ej. la instancia de la aplicación). -Sin embargo, debido a que los `namespaces` de los eventos globales son compartidos por todas partes, se les deben -asignar nombres bien pensados, como puede ser la introducción de algún `namespace` -(p. ej. "frontend.mail.sent", "backend.mail.sent"). +Sin embargo, debido a que los `namespaces` de los eventos globales son compartidos por todas partes, se les deben +asignar nombres bien pensados, como puede ser la introducción de algún `namespace` +(ej. "frontend.mail.sent", "backend.mail.sent"). diff --git a/docs/guide-es/concept-properties.md b/docs/guide-es/concept-properties.md index 0e7d96b..82ba186 100644 --- a/docs/guide-es/concept-properties.md +++ b/docs/guide-es/concept-properties.md @@ -1,32 +1,32 @@ Propiedades =========== -En PHP, las variables miembro de clases también llamadas *propiedades*, son parte de la definición de la clase, y se -usan para representar el estado de una instancia de la clase (p. ej. para diferenciar una instancia de clase de otra). -A la práctica, a menudo, se puede querer gestionar la lectura o escritura de las propiedades de algunos momentos. Por -ejemplo, se puede querer eliminar los espacios en blanco (trim) de una cadena de texto cada vez que esta se asigne a +En PHP, las variables miembro de clases también llamadas *propiedades*, son parte de la definición de la clase, y se +usan para representar el estado de una instancia de la clase (ej. para diferenciar una instancia de clase de otra). +A la práctica, a menudo, se puede querer gestionar la lectura o escritura de las propiedades de algunos momentos. Por +ejemplo, se puede querer eliminar los espacios en blanco (trim) de una cadena de texto cada vez que esta se asigne a una propiedad de tipo `label`. Se *podría* usar el siguiente código para realizar esta tarea: ```php $object->label = trim($label); ``` -La desventaja del código anterior es que se tendría que ejecutar `trim()` en todas las partes del código que pudieran -establecer la propiedad `label`. Si en el futuro, la propiedad `label` tiene que seguir otro funcionamiento, como por -ejemplo que la primera letra tiene que estar en mayúsculas, se tendrán que modificar todas las secciones de código que -asignen el valor a la propiedad `label`. La repetición de código conlleva a bugs, y es una practica que se tiene que +La desventaja del código anterior es que se tendría que ejecutar `trim()` en todas las partes del código que pudieran +establecer la propiedad `label`. Si en el futuro, la propiedad `label` tiene que seguir otro funcionamiento, como por +ejemplo que la primera letra tiene que estar en mayúsculas, se tendrán que modificar todas las secciones de código que +asignen el valor a la propiedad `label`. La repetición de código conlleva a bugs, y es una practica que se tiene que evitar en la medida de lo posible. -Para solventar este problema, Yii introduce la clase base llamada [[yii\base\Object]] que da soporte a la definición -de propiedades basada en los métodos de clase *getter* y *setter*. Si una clase necesita más funcionalidad, debe +Para solventar este problema, Yii introduce la clase base llamada [[yii\base\Object]] que da soporte a la definición +de propiedades basada en los métodos de clase *getter* y *setter*. Si una clase necesita más funcionalidad, debe extender a la clase [[yii\base\Object]] o a alguna de sus hijas. -> Información: Casi todas las clases del núcleo (core) en el framework Yii extienden a [[yii\base\Object]] o a una de - sus clases hijas. Esto significa que siempre que se encuentre un getter o un setter en una clase del núcleo, se +> Información: Casi todas las clases del núcleo (core) en el framework Yii extienden a [[yii\base\Object]] o a una de + sus clases hijas. Esto significa que siempre que se encuentre un getter o un setter en una clase del núcleo, se puede utilizar como una propiedad. -Un método getter es un método cuyo nombre empieza por la palabra `get`: un metodo setter empieza por `set`. El nombre -añadido detrás del prefijo `get` o `set` define el nombre de la propiedad. Por ejemplo, un getter `getLabel()` y/o un +Un método getter es un método cuyo nombre empieza por la palabra `get`: un metodo setter empieza por `set`. El nombre +añadido detrás del prefijo `get` o `set` define el nombre de la propiedad. Por ejemplo, un getter `getLabel()` y/o un setter `setLabel()` definen la propiedad `label`, como se muestra a continuación: ```php @@ -50,11 +50,11 @@ class Foo extends Object } ``` -(Para ser claros, los métodos getter y setter crean la propiedad `label`, que en este caso hace una referencia interna +(Para ser claros, los métodos getter y setter crean la propiedad `label`, que en este caso hace una referencia interna al nombre de atributo privado `_label`.) -Las propiedades definidas por los getter y los setters se pueden usar como variables de clase miembro. La principal -diferencia radica en que cuando esta propiedad se lea, se ejecutará su correspondiente método getter; cuando se asigne +Las propiedades definidas por los getter y los setters se pueden usar como variables de clase miembro. La principal +diferencia radica en que cuando esta propiedad se lea, se ejecutará su correspondiente método getter; cuando se asigne un valor a la propiedad, se ejecutará el correspondiente método setter. Por ejemplo: ```php @@ -65,24 +65,24 @@ $label = $object->label; $object->label = 'abc'; ``` -Una propiedad definida por un getter sin un setter es de tipo *sólo lectura*. Si se intenta asignar un valor a esta -propiedad se producirá una excepción de tipo [[yii\base\InvalidCallException|InvalidCallException]]. Del mismo modo -que una propiedad definida con un setter pero sin getter será de tipo *sólo escritura*, cualquier intento de lectura +Una propiedad definida por un getter sin un setter es de tipo *sólo lectura*. Si se intenta asignar un valor a esta +propiedad se producirá una excepción de tipo [[yii\base\InvalidCallException|InvalidCallException]]. Del mismo modo +que una propiedad definida con un setter pero sin getter será de tipo *sólo escritura*, cualquier intento de lectura de esta propiedad producirá una excepción. No es común tener variables de tipo sólo escritura. Hay varias reglas especiales y limitaciones en las propiedades definidas mediante getters y setters: -* Los nombres de estas propiedades son *case-insensitive*. Por ejemplo, `$object->label` y `$object->Label` son la +* Los nombres de estas propiedades son *case-insensitive*. Por ejemplo, `$object->label` y `$object->Label` son la misma. Esto se debe a que los nombres de los métodos en PHP son case-insensitive. -* Si el nombre de una propiedad de este tipo es igual al de una variable miembro de la clase, la segunda tendrá - prioridad. Por ejemplo, si la anterior clase `Foo` tiene la variable miembro `label`, entonces la asignación +* Si el nombre de una propiedad de este tipo es igual al de una variable miembro de la clase, la segunda tendrá + prioridad. Por ejemplo, si la anterior clase `Foo` tiene la variable miembro `label`, entonces la asignación `$object->label = 'abc'` afectará a la *variable miembro* 'label'; no se ejecutará el método setter `setLabel()`. -* Estas variables no soportan la visibilidad. No hay diferencia en definir los métodos getter o setter en una +* Estas variables no soportan la visibilidad. No hay diferencia en definir los métodos getter o setter en una propiedad public, protected, o private. -* Las propiedades sólo se pueden definir por getters y setters *no estáticos*. Los métodos estáticos no se tratarán de +* Las propiedades sólo se pueden definir por getters y setters *no estáticos*. Los métodos estáticos no se tratarán de la misma manera. -Volviendo de nuevo al problema descrito al principio de la guía, en lugar de ejecutar `trim()` cada vez que se asigne -un valor a `label`, ahora `trim()` sólo necesita ser invocado dentro del setter `setLabel()`. I si se tiene que añadir +Volviendo de nuevo al problema descrito al principio de la guía, en lugar de ejecutar `trim()` cada vez que se asigne +un valor a `label`, ahora `trim()` sólo necesita ser invocado dentro del setter `setLabel()`. I si se tiene que añadir un nuevo requerimiento, para que `label` empiece con una letra mayúscula, se puede modificar rápidamente el método ` setLabel()` sin tener que modificar más secciones de código. El cambio afectará a cada asignación de `label`. \ No newline at end of file diff --git a/docs/guide-es/db-dao.md b/docs/guide-es/db-dao.md index a3611d2..40e1cf7 100644 --- a/docs/guide-es/db-dao.md +++ b/docs/guide-es/db-dao.md @@ -1,33 +1,41 @@ Objetos de Acceso a Bases de Datos ================================== -> Nota: Esta sección está en desarrollo. +Construido sobre [PDO](http://php.net/manual/es/book.pdo.php), Yii DAO (Objetos de Acceso a Bases de Datos) proporciona una +API orientada a objetos para el acceso a bases de datos relacionales. Es el fundamento para otros métodos de acceso a bases de datos +más avanzados, incluyendo el [constructor de consultas](db-query-builder.md) y [active record](db-active-record.md). -Yii incluye una capa de acceso a bases de datos basado en el [PDO](http://php.net/manual/es/book.pdo.php) de PHP. La -interfaz de objetos de acceso a bases de datos (DAO) proporciona una API uniforme y soluciona algunas inconsistencias -que existen entre diferentes aplicaciones de bases de datos. Mientras el Active Record proporciona interacciones con -los modelos, y el Constructor de Consultas (Query Builder) ayuda en la composición de consultas dinámicas, DAO es una -manera simple y eficiente para ejecutar SQL en la base de datos. Por lo general, se usará DAO cuando la ejecución de -la consulta sea muy costosa y/o no se requieran modelos de aplicación y sus correspondientes lógicas de negocio. +Al utilizar Yii DAO, principalmente vas a tratar con SQLs planos y arrays PHP. Como resultado, esta es la manera más eficiente +de acceder a las bases de datos. Sin embargo, como la sintaxis puede variar para las diferentes bases de datos, utilizando +Yii DAO también significa que tienes que tienes que tomar un esfuerzo adicional para crear una aplicación de database-agnostic. -De forma predeterminada, Yii soporta los siguientes DBMS (Sistemas de Gestión de Base de Datos): +Yii DAO soporta las siguientes bases de datos: - [MySQL](http://www.mysql.com/) - [MariaDB](https://mariadb.com/) - [SQLite](http://sqlite.org/) - [PostgreSQL](http://www.postgresql.org/) -- [CUBRID](http://www.cubrid.org/): versión 9.3 o superior. (Tenga en cuenta que debido al - [bug](http://jira.cubrid.org/browse/APIS-658) en la extensión PDO de cubrid, los valores entrecomillados no - funcionarán, por lo que se necesita CUBRID 9.3 tanto para el cliente como para el servidor) +- [CUBRID](http://www.cubrid.org/): versión 9.3 o superior. - [Oracle](http://www.oracle.com/us/products/database/overview/index.html) -- [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): versión 2005 o superior. +- [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): versión 2008 o superior. -Configuración -------------- +## Creando Conexiones DB -Para empezar a interaccionar con la base de datos (usando DAO o de otra forma), se tiene que configurar el componente -de conexión a la base de datos de la aplicación. El DSN (Nombre de Origen de Datos) configura que aplicación de BBDD y -que BBDD especifica debe conectar la aplicación: +Para acceder a una base de datos, primero necesitas conectarte a tu bases de datos mediante la creación +de una instancia de [yii\db\Connection]]: + +```php +$db = new yii\db\Connection([ + 'dsn' => 'mysql:host=localhost;dbname=example', + 'username' => 'root', + 'password' => '', + 'charset' => 'utf8', +]); +``` + +Debido a una conexión DB a menudo necesita ser accedido en diferentes lugares, una práctica común es +configurarlo en términos de un [componente de aplicación](structure-application-components.md) como +se muestra a continuación: ```php return [ @@ -36,14 +44,7 @@ return [ // ... 'db' => [ 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=mydatabase', // MySQL, MariaDB - //'dsn' => 'sqlite:/path/to/database/file', // SQLite - //'dsn' => 'pgsql:host=localhost;port=5432;dbname=mydatabase', // PostgreSQL - //'dsn' => 'cubrid:dbname=demodb;host=localhost;port=33000', // CUBRID - //'dsn' => 'sqlsrv:Server=localhost;Database=mydatabase', // MS SQL Server, sqlsrv driver - //'dsn' => 'dblib:host=localhost;dbname=mydatabase', // MS SQL Server, dblib driver - //'dsn' => 'mssql:host=localhost;dbname=mydatabase', // MS SQL Server, mssql driver - //'dsn' => 'oci:dbname=//localhost:1521/mydatabase', // Oracle + 'dsn' => 'mysql:host=localhost;dbname=example', 'username' => 'root', 'password' => '', 'charset' => 'utf8', @@ -53,12 +54,25 @@ return [ ]; ``` -Se puede encontrar más información del formato de la cadena DSN en el -[manual de PHP](http://php.net/manual/es/pdo.construct.php). Además se puede encontrar el listado completo de -propiedades que se pueden configurar en la clase en [[yii\db\Connection]]. +Puedes acceder a la conexión DB mediante la expresión `Yii::$app->db`. + +> Consejo: Puedes configurar múltiples componentes de aplicación DB si tu aplicación necesita acceder a múltiples bases de datos. -Hay que tener en cuenta que si se conecta a una base de datos mediante ODBC, se debe configurar la propiedad -[[yii\db\Connection::driverName]] para que Yii sepa el tipo de bases de datos actual. Por ejemplo, +Cuando configuras una conexión DB, deberías siempre especificar el Nombre de Origen de Datos (DSN) mediante la +propiedad [[yii\db\Connection::dsn|dsn]]. El formato del DSN varia para cada diferente base de datos. Por favor consulte el +[manual de PHP](http://www.php.net/manual/es/function.PDO-construct.php) para más detalles. Abajo están algunos ejemplos: + +* MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` +* SQLite: `sqlite:/path/to/database/file` +* PostgreSQL: `pgsql:host=localhost;port=5432;dbname=mydatabase` +* CUBRID: `cubrid:dbname=demodb;host=localhost;port=33000` +* MS SQL Server (mediante sqlsrv driver): `sqlsrv:Server=localhost;Database=mydatabase` +* MS SQL Server (mediante dblib driver): `dblib:host=localhost;dbname=mydatabase` +* MS SQL Server (mediante mssql driver): `mssql:host=localhost;dbname=mydatabase` +* Oracle: `oci:dbname=//localhost:1521/mydatabase` + +Nota que si estás conectándote con una base de datos mediante ODBC, deberías configurar la propiedad [[yii\db\Connection::driverName]] +para que Yii pueda conocer el tipo de base de datos actual. Por ejemplo, ```php 'db' => [ @@ -70,53 +84,53 @@ Hay que tener en cuenta que si se conecta a una base de datos mediante ODBC, se ], ``` -Se puede acceder a la conexión `db` primaria mediante la expresión `\Yii::$app->db`. También se pueden configurar -múltiples conexiones de BBDD en una única aplicación. Simplemente asignándoles diferentes IDs en la configuración de -la aplicación: +Además de la propiedad [[yii\db\Connection::dsn|dsn]], a menudo es necesario configurar el [[yii\db\Connection::username|username]] +y [[yii\db\Connection::password|password]]. Por favor consulta [[yii\db\Connection]] para ver la lista completa de propiedades configurables. -```php -return [ - // ... - 'components' => [ - // ... - 'db' => [ - 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=mydatabase', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', - ], - 'secondDb' => [ - 'class' => 'yii\db\Connection', - 'dsn' => 'sqlite:/path/to/database/file', - ], - ], - // ... -]; -``` +> Información: Cuando se crea una instancia de conexión DB, la conexión actual a la base de datos no se establece hasta que + ejecutes el primer SQL o llames explícitamente al método [[yii\db\Connection::open()|open()]]. -Ahora se pueden usar las dos conexiones a la base de datos al mismo tiempo si es necesario: -```php -$primaryConnection = \Yii::$app->db; -$secondaryConnection = \Yii::$app->secondDb; -``` +## Ejecutando Consultas SQL + +Una vez tienes instanciada una conexión a la base de datos, se pueden ejecutar consultas SQL tomando +los siguientes pasos: -Si no se quiere definir la conexión como un [componente de aplicación](structure-application-components.md), se puede -instanciar directamente: +1. Crea un [[yii\db\Command]] con SQL plano; +2. Vincula parámetros (opcional); +3. Llama a uno de los métodos de ejecución SQL con [[yii\db\Command]]. + +El siguiente ejemplo muestra varias maneras de obtener datos de una base de datos: ```php -$connection = new \yii\db\Connection([ - 'dsn' => $dsn, - 'username' => $username, - 'password' => $password, -]); -$connection->open(); +$db = new yii\db\Connection(...); + +// retorna un conjunto de filas. Cada fila es un array asociativo de columnas de nombres y valores. +// un array vacío es retornado si no hay resultados +$posts = $db->createCommand('SELECT * FROM post') + ->queryAll(); + +// retorna una sola fila (la primera fila) +// false es retornado si no hay resultados +$post = $db->createCommand('SELECT * FROM post WHERE id=1') + ->queryOne(); + +// retorna una sola columna (la primera columna) +// un array vacío es retornado si no hay resultados +$titles = $db->createCommand('SELECT title FROM post') + ->queryColumn(); + +// retorna un escalar +// false es retornado si no hay resultados +$count = $db->createCommand('SELECT COUNT(*) FROM post') + ->queryScalar(); ``` -> Tip: Si se necesita ejecutar una consulta SQL inmediatamente después de establecer la conexión - (p. ej. para establecer la zona horaria (timezone) o juego de caracteres), se puede añadir el siguiente código en el - archivo de configuración de la aplicación: +> Nota: Para preservar la precisión, los datos obtenidos de las bases de datos son todos representados como cadenas, incluso si el tipo de columna correspondiente +a la base de datos es numérico. + +> Consejo: Si necesitas ejecutar una consulta SQL inmediatamente después de establecer una conexión (ej., para establecer una zona horaria o un conjunto de caracteres), +> puedes hacerlo con el evento [[yii\db\Connection::EVENT_AFTER_OPEN]]. Por ejemplo, > ```php return [ @@ -127,6 +141,7 @@ return [ 'class' => 'yii\db\Connection', // ... 'on afterOpen' => function($event) { + // $event->sender se refiere a la conexión DB $event->sender->createCommand("SET time_zone = 'UTC'")->execute(); } ], @@ -135,101 +150,141 @@ return [ ]; ``` -Ejecución de Consultas SQL Basicas ----------------------------------- - -Una vez instanciada una conexión a la base de datos, se pueden ejecutar consultas SQL usando [[yii\db\Command]]. -### Ejecutando Consultas SELECT +### Parámetros Vinculados (Binding Parameters) -Cuando la consulta que tiene que ser ejecutada devuelve un conjunto de filas, se usará `queryAll`: +Cuando creamos un comando DB para un SQL con parámetros, nosotros deberíamos casi siempre aprovechar el uso de los parámetros vinculados +para prevenir los ataques de inyección de SQL. Por ejemplo, ```php -$command = $connection->createCommand('SELECT * FROM post'); -$posts = $command->queryAll(); +$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status') + ->bindValue(':id', $_GET['id']) + ->bindValue(':status', 1) + ->queryOne(); ``` -Cuando la consulta que se ejecute devuelva una única fila, se usará `queryOne`: +En la sentencia SQL, puedes incrustar uno o múltiples parámetros placeholders (ej. `:id` en el ejemplo anterior). Un parámetro +placeholder debería ser una cadena que empiece con dos puntos. A continuación puedes llamar a uno de los siguientes métodos para +unir los valores de los parámetros vinculados: + +* [[yii\db\Command::bindValue()|bindValue()]]: une un solo parámetro +* [[yii\db\Command::bindValues()|bindValues()]]: une múltiples parámetros en una sola llamada +* [[yii\db\Command::bindParam()|bindParam()]]: similar a [[yii\db\Command::bindValue()|bindValue()]] pero también + soporta las referencias de parámetros vinculados. + +El siguiente ejemplo muestra formas alternativas de vincular parámetros: ```php -$command = $connection->createCommand('SELECT * FROM post WHERE id=1'); -$post = $command->queryOne(); +$params = [':id' => $_GET['id'], ':status' => 1]; + +$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status') + ->bindValues($params) + ->queryOne(); + +$post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status', $params) + ->queryOne(); ``` -Cuando la consulta devuelva múltiples filas pero solo una columna, se usará `queryColumn`: +La vinculación parámetros es implementada mediante [sentencias preparadas (prepared statements)](http://php.net/manual/es/mysqli.quickstart.prepared-statements.php). +Además de prevenir ataques de inyección de SQL, también puede mejorar el rendimiento preparando una sola vez una sentencia SQL y ejecutándola múltiples veces con diferentes +parámetros. Por ejemplo, ```php -$command = $connection->createCommand('SELECT title FROM post'); -$titles = $command->queryColumn(); +$command = $db->createCommand('SELECT * FROM post WHERE id=:id'); + +$post1 = $command->bindValue(':id', 1)->queryOne(); +$post2 = $command->bindValue(':id', 2)->queryOne(); ``` -Cuando la consulta solo devuelva un valor escalar, se usará `queryScalar`: +Porque [[yii\db\Command::bindParam()|bindParam()]] soporta parámetros vinculados por referencias, el código de arriba también +puede ser escrito como lo siguiente: ```php -$command = $connection->createCommand('SELECT COUNT(*) FROM post'); -$postCount = $command->queryScalar(); +$command = $db->createCommand('SELECT * FROM post WHERE id=:id') + ->bindParam(':id', $id); + +$id = 1; +$post1 = $command->queryOne(); + +$id = 2; +$post2 = $command->queryOne(); ``` -### Ejecución de Consultas que No Devuelvan Valores +Observe que vincula el placeholder a la variable `$id` antes de la ejecución, y entonces cambia el valor de esa variable +antes de cada subsiguiente ejecución (esto se hace a menudo con bucles). Ejecutando consultas de esta manera puede ser +bastante más eficiente que ejecutar una nueva consulta para cada valor diferente del parámetro. + + +### Ejecutando Consultas Non-SELECT -Si el SQL ejecutado no devuelve ningún dato, por ejemplo, INSER, UPDATE, y DELETE, se puede usar el método `execute`: +El método `queryXyz()` introducidos en las secciones previas todos tratan con consultas SELECT los cuales recogen los +datos de la base de datos. Para las consultas que no devuelven datos, deberías llamar a el método [[yii\db\Command::execute()]] +en su lugar. Por ejemplo, ```php -$command = $connection->createCommand('UPDATE post SET status=1 WHERE id=1'); -$command->execute(); +$db->createCommand('UPDATE post SET status=1 WHERE id=1') + ->execute(); ``` -De forma alternativa, se pueden usar los métodos `insert`, `update`, y `delete`. Estos métodos se encargarán de -gestionar entrecomillar adecuadamente el nombre de la tabla y de las columnas que se usen en la consulta, y solo se -tendrá que proporcionar los valores necesarios. +El método [[yii\db\Command::execute()]] retorna el número de filas afectadas por la ejecución SQL. -[[Se tiene que poner el enlace de documentación aquí.]] +Para consultas INSERT, UPDATE y DELETE, en vez de escribir SQLs planos, puedes llamar a [[yii\db\Command::insert()|insert()]], +[[yii\db\Command::update()|update()]], [[yii\db\Command::delete()|delete()]], respectivamente, construyen los correspondientes +SQLs. Estos métodos entrecomillan adecuadamente las tablas y los nombres de columnas y los valores de los parámetros vinculados. +Por ejemplo, ```php -// INSERT -$connection->createCommand()->insert('user', [ +// INSERT (table name, column values) +$db->createCommand()->insert('user', [ 'name' => 'Sam', 'age' => 30, ])->execute(); -// insertar múltiples filas a la vez -$connection->createCommand()->batchInsert('user', ['name', 'age'], [ +// UPDATE (table name, column values, condition) +$db->createCommand()->update('user', ['status' => 1], 'age > 30')->execute(); + +// DELETE (table name, condition) +$db->createCommand()->delete('user', 'status = 0')->execute(); +``` + +Puedes también llamar a [[yii\db\Command::batchInsert()|batchInsert()]] para insertar múltiples filas de una sola vez, +que es mucho más eficiente que insertar una fila de cada vez: + +```php +// table name, column names, column values +$db->createCommand()->batchInsert('user', ['name', 'age'], [ ['Tom', 30], ['Jane', 20], ['Linda', 25], ])->execute(); +``` -// UPDATE -$connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute(); -// DELETE -$connection->createCommand()->delete('user', 'status = 0')->execute(); -``` +## Entrecomillado de Tablas y Nombres de Columna -Entrecomillado de Nombre de Tablas y Columnas ---------------------------------------------- +Al escribir código de database-agnostic, entrecomillar correctamente los nombres de las tablas y las columnas es a menudo +un dolor de cabeza porque las diferentes bases de datos tienen diferentes reglas para entrecomillar los nombres. Para +solventar este problema, puedes usar la siguiente sintaxis de entrecomillado introducido por Yii: -Para hacer que los nombres de columnas y tablas sean seguros para usarse en consultas, se puede utilizar Yii -adecuadamente para que los entrecomille: +* `[[column name]]`: encierra con dobles corchetes el nombre de una columna que debe ser entrecomillado; +* `{{table name}}`: encierra con dobles llaves el nombre de una tabla que debe ser entrecomillado. + +Yii DAO automáticamente convertirá tales construcciones en un SQL con los correspondientes entrecomillados de los nombres de las columnas o tablas. +Por ejemplo, ```php -$sql = "SELECT COUNT([[$column]]) FROM {{table}}"; -$rowCount = $connection->createCommand($sql)->queryScalar(); +// ejecuta esta SQL para MySQL: SELECT COUNT(`id`) FROM `employee` +$count = $db->createCommand("SELECT COUNT([[id]]) FROM {{employee}}") + ->queryScalar(); ``` -En el código anterior, se convertirá `[[$column]]` a un nombre de columna debidamente entrecomillado, mientras que se -convertirá `{{table}}` a un nombre de tabla debidamente entrecomillado. -Hay una variante especial de esta sintaxis especifica para que los nombres de tablas: `{{%Y}}` añade automáticamente -el prefijo de la tabla de la aplicación para proporcionar un valor, si se ha establecido un prefijo de tabla: +### Usadno Prefijos de Tabla -```php -$sql = "SELECT COUNT([[$column]]) FROM {{%table}}"; -$rowCount = $connection->createCommand($sql)->queryScalar(); -``` +Si la mayoría de tus tablas de BD utilizan algún prefijo común en sus tablas, puedes usar la función de prefijo de tabla soportado +por Yii DAO. -El código anterior dará como resultado una consulta de selección de la tabla `tbl_table`, si se tiene el prefijo de -tabla configurado como el siguiente: +Primero, especifica el prefijo de tabla mediante la propiedad [[yii\db\Connection::tablePrefix]]: ```php return [ @@ -244,152 +299,151 @@ return [ ]; ``` -La alternativa es entrecomillar los nombres de tabla y columna manualmente usando -[[yii\db\Connection::quoteTableName()]] y [[yii\db\Connection::quoteColumnName()]]: +Luego en tu código, siempre que lo necesites para hacer referencia a una tabla cuyo nombre tiene un prefijo, utiliza la sintaxis +`{{%table name}}`. El carácter porcentaje se sustituye con el prefijo de la tabla que has especificado en la configuración de +la conexión DB. Por ejemplo, ```php -$column = $connection->quoteColumnName($column); -$table = $connection->quoteTableName($table); -$sql = "SELECT COUNT($column) FROM $table"; -$rowCount = $connection->createCommand($sql)->queryScalar(); +// ejecuta esta SQL para MySQL: SELECT COUNT(`id`) FROM `tbl_employee` +$count = $db->createCommand("SELECT COUNT([[id]]) FROM {{%employee}}") + ->queryScalar(); ``` -Uso de Sentencias Preparadas ----------------------------- -Para pasar parámetros seguros a las consultas, se deben usar las sentencias preparadas. Primero, se tiene que crear un -*parámetro de substitución* (placeholder) en una consulta (usando la sintaxis `:placeholder`). Después intercambiar el -parámetro de substitución por una variable y ejecutar la consulta: +## Realización de Transacciones -```php -$command = $connection->createCommand('SELECT * FROM post WHERE id=:id'); -$command->bindValue(':id', $_GET['id']); -$post = $command->queryOne(); -``` +Cuando se ejecutan múltiples consultas relacionadas en una secuencia, puede que se tengan que envolver en una +transacción para asegurar la integridad de los datos y la consistencia de tu base de datos. Si cualquiera de las consultas +falla, la base de datos debe ser revertida al estado anterior como si ninguna de estas consultas se haya ejecutado. -Otra finalidad de las sentencias preparadas (aparte de mejorar la seguridad) es la habilidad de ejecutar una consulta -múltiples veces mientras que sólo se ha preparado una vez: +El siguiente código muestra una manera típica de usar transacciones: ```php -$command = $connection->createCommand('DELETE FROM post WHERE id=:id'); -$command->bindParam(':id', $id); - -$id = 1; -$command->execute(); - -$id = 2; -$command->execute(); +$db->transaction(function($db) { + $db->createCommand($sql1)->execute(); + $db->createCommand($sql2)->execute(); + // ... ejecutando otras sentencias SQL +}); ``` -Tenga en cuenta que se efectúa la asignación del parámetro de substitución antes de su ejecución, y después se cambia -el valor antes de la siguiente ejecución (normalmente se ejecuta en bucles). La ejecución de consultas con este -método, puede ser mucho más eficiente que la ejecución de una consulta cada vez. - -Realización de Transacciones ----------------------------- - -Cuando se ejecutan múltiples, consultas relacionadas en una secuencia, puede que se tengan que envolver en una -transacción para proteger la integridad de los datos. Las transacciones permiten escribir una serie de consultas de -forma que o todas se ejecutan correctamente o no tendrán ningún efecto. Yii proporciona una interfaz sencilla para -trabajar con transacciones en casos simples pero también para el uso avanzado cuando tengan que definir los niveles de -aislamiento. - -El siguiente código muestra un patrón simple que debe seguir todo código que utilice consultas transaccionales: +El código de arriba es equivalente a lo siguiente: ```php -$transaction = $connection->beginTransaction(); +$transaction = $db->beginTransaction(); + try { - $connection->createCommand($sql1)->execute(); - $connection->createCommand($sql2)->execute(); - // ... executing other SQL statements ... + $db->createCommand($sql1)->execute(); + $db->createCommand($sql2)->execute(); + // ... ejecutando otras sentencias SQL + $transaction->commit(); + } catch(\Exception $e) { + $transaction->rollBack(); + throw $e; } ``` -La primera linea empieza una nueva transacción usando el método -[[yii\db\Connection::beginTransaction()|beginTransaction()]] del objeto de conexión a la base de datos. La transacción -en si misma se representa con el objeto [[yii\db\Transaction]] almacenado en `$transaction`. Nosotros encapsulamos la -ejecución de todas las consultas en un bloque try-catch para poder gestionar los errores. Llamamos a -[[yii\db\Transaction::commit()|commit()]] cuando todo es correcto para efectuar la transacción y si sucede algún error -ejecutamos [[yii\db\Transaction::rollBack()|rollBack()]]. Esto revertirá el efecto de todas las consultas que se hayan -ejecutado dentro de la transacción. Se usa `throw $e` para relanzar la excepción en caso de que nosotros no podamos -gestionar el error y se delega a otro código del gestor de errores de Yii. +Al llamar al método [[yii\db\Connection::beginTransaction()|beginTransaction()]], se inicia una nueva transacción. +La transacción se representa como un objeto [[yii\db\Transaction]] almacenado en la variable `$transaction`. Luego, +las consultas que se ejecutan están encerrados en un bloque `try...catch...`. Si todas las consultas son ejecutadas satisfactoriamente, +el método [[yii\db\Transaction::commit()|commit()]] es llamado para confirmar la transacción. De lo contrario, una excepción +se disparará y se capturará, y el método [[yii\db\Transaction::rollBack()|rollBack()]] es llamado para revertir +los cambios hechos por las consultas antes de que fallara la consulta en la transacción. -Es posible anidar múltiples transacciones si es necesario: -```php -// transacción exterior -$transaction1 = $connection->beginTransaction(); -try { - $connection->createCommand($sql1)->execute(); +### Especificando los Niveles de Aislamiento - // transacción interior - $transaction2 = $connection->beginTransaction(); - try { - $connection->createCommand($sql2)->execute(); - $transaction2->commit(); - } catch (Exception $e) { - $transaction2->rollBack(); - } +Yii también soporta la configuración de [niveles de aislamiento] para tus transacciones. Por defecto, cuando comienza una nueva transacción, +utilizará el nivel de aislamiento definido por tu sistema de base de datos. Se puede sobrescribir el nivel de aislamiento por defecto de la +siguiente manera, - $transaction1->commit(); -} catch (Exception $e) { - $transaction1->rollBack(); -} -``` +```php +$isolationLevel = \yii\db\Transaction::REPEATABLE_READ; -Tenga en cuanta que el DBMS debe soportar Puntos de Registro (Savepoints) para que funcionen correctamente. El código -anterior, trabajará con cualquier DBMS pero las sólo se garantizarán las transacciones que se ejecuten bajo un DBMS -que las soporte. +$db->transaction(function ($db) { + .... +}, $isolationLevel); -Yii también soporta la configuración de [niveles de aislamiento] en las transacciones. Cuando empiece una transacción -se ejecutará con el nivel predeterminado de aislamiento definido por la base de datos. Se puede especificar un nivel -de aislamiento especifico cuando se empieza una transacción: +// or alternatively -```php -$transaction = $connection->beginTransaction(\yii\db\Transaction::REPEATABLE_READ); +$transaction = $db->beginTransaction($isolationLevel); ``` Yii proporciona cuatro constantes para los niveles de aislamiento más comunes: -- [[\yii\db\Transaction::READ_UNCOMMITTED]] - el nivel más bajo, pueden ocurrir lecturas Dirty, lecturas +- [[\yii\db\Transaction::READ_UNCOMMITTED]] - el nivel más bajo, pueden ocurrir lecturas Dirty, lecturas Non-repeatable y Phantoms. - [[\yii\db\Transaction::READ_COMMITTED]] - evita lecturas Dirty. - [[\yii\db\Transaction::REPEATABLE_READ]] - evita lecturas Dirty y lecturas Non-repeatable. - [[\yii\db\Transaction::SERIALIZABLE]] - el nivel más fuerte, evita todos los problemas nombrados anteriormente. -Se pueden usar las constantes descritas anteriormente aunque también se pueden usar cadenas de texto que representen -la sintaxis que puede ser utilizada en el DBMS seguido de `SET TRANSACTION ISOLATION LEVEL`. Para postgres podría -utilizarse, por ejemplo, `SERIALIZABLE READ ONLY DEFERRABLE`. +Además de usar las constantes de arriba para especificar los niveles de aislamiento, puedes también usar cadenas con +una sintaxis valida soportada por el DBMS que estés usando. Por ejemplo, en PostgreSQL, puedes utilizar `SERIALIZABLE READ ONLY DEFERRABLE`. -Tenga en cuenta que algunos DBMS permiten configuraciones de niveles de aislamiento solo a nivel de conexión y por -consiguiente las transacciones pueden obtener el mismo nivel de aislamiento incluso si no se especifica ninguno. -Cuando se usa esta característica, se puede tener que establecer el nivel de aislamiento explícitamente para evitar -conflictos de configuración. En este momento se ven afectados los DBMS MSSQL y SQLite. +Tenga en cuenta que algunos DBMS permiten configuraciones de niveles de aislamiento solo a nivel de conexión. Las transacciones subsiguientes +recibirá el mismo nivel de aislamiento , incluso si no se especifica ninguna. Al utilizar esta característica +es posible que necesites ajustar el nivel de aislamiento para todas las transacciones de forma explícitamente para evitar conflictos +en las configuraciones. +En el momento de escribir esto, solo MSSQL y SQLite serán afectadas. -> NOTA: SQLite solo soporta dos niveles de aislamiento, por lo que solo se puede usar `READ UNCOMMITTED` y +> Nota: SQLite solo soporta dos niveles de aislamiento, por lo que solo se puede usar `READ UNCOMMITTED` y `SERIALIZABLE`. El uso de otros niveles causará el lanzamiento de una excepción. -> Nota: PostgreSQL no permite configurar el nivel de aislamiento antes que la transacción empiece por lo que no se - puede especificar el nivel de aislamiento directamente cuando empieza la transacción. Se tiene que ejecutar +> Nota: PostgreSQL no permite configurar el nivel de aislamiento antes que la transacción empiece por lo que no se + puede especificar el nivel de aislamiento directamente cuando empieza la transacción. Se tiene que llamar a [[yii\db\Transaction::setIsolationLevel()]] después de que la transacción haya empezado. [isolation levels]: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels -Replicas y División Lectura-Escritura -------------------------------------- -Muchos DBMS soportan -[replicación de bases de datos](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) para tener -una mejor disponibilidad de la base de datos y un mejor tiempo de respuesta del servidor. Con la replicación de bases -de datos, los datos están replicados en los llamados *servidores maestros* (master servers) y *servidores esclavos* -(slave servers). Todas las escrituras y actualizaciones deben hacerse en el servidor maestro mientras que las lecturas +### Transacciones Anidadas + +Si tu DBMS soporta Savepoint, puedes anidar múltiples transacciones como a continuación: + +```php +$db->transaction(function ($db) { + // outer transaction + + $db->transaction(function ($db) { + // inner transaction + }); +}); +``` + +O alternativamente, + +```php +$outerTransaction = $db->beginTransaction(); +try { + $db->createCommand($sql1)->execute(); + + $innerTransaction = $db->beginTransaction(); + try { + $db->createCommand($sql2)->execute(); + $innerTransaction->commit(); + } catch (Exception $e) { + $innerTransaction->rollBack(); + } + + $outerTransaction->commit(); +} catch (Exception $e) { + $outerTransaction->rollBack(); +} +``` + + +## Replicación y División Lectura-Escritura + +Muchos DBMS soportan [replicación de bases de datos](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) para tener +una mejor disponibilidad de la base de datos y un mejor tiempo de respuesta del servidor. Con la replicación de bases +de datos, los datos están replicados en los llamados *servidores maestros* (master servers) y *servidores esclavos* +(slave servers). Todas las escrituras y actualizaciones deben hacerse en el servidor maestro, mientras que las lecturas se efectuarán en los servidores esclavos. -Para aprovechar las ventajas de la replicación de BBDD y lograr una división de lecuta-escritura, se puede configurar +Para aprovechar las ventajas de la replicación de la base de datos y lograr una división de lecuta-escritura, se puede configurar el componente [[yii\db\Connection]] como se muestra a continuación: ```php @@ -406,7 +460,7 @@ el componente [[yii\db\Connection]] como se muestra a continuación: 'username' => 'slave', 'password' => '', 'attributes' => [ - // use a smaller connection timeout + // utiliza un tiempo de espera de conexión más pequeña PDO::ATTR_TIMEOUT => 10, ], ], @@ -421,8 +475,8 @@ el componente [[yii\db\Connection]] como se muestra a continuación: ] ``` -La configuración anterior especifica una configuración con un único maestro y múltiples esclavos. Uno de los esclavos -se conectará y se usará para ejecutar consultas de lectura mientras que el maestro se usara para realizar consultas de +La configuración anterior especifica una configuración con un único maestro y múltiples esclavos. Uno de los esclavos +se conectará y se usará para ejecutar consultas de lectura, mientras que el maestro se usará para realizar consultas de escritura. De este modo la división de lectura-escritura se logra automáticamente con esta configuración, Por ejemplo, ```php @@ -436,22 +490,21 @@ $rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll(); $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute(); ``` -> Información: Las consultas realizadas ejecutando [[yii\db\Command::execute()]] se consideran consultas de escritura, - mientras que todas las demás se ejecutan mediante alguno de los métodos "query" de [[yii\db\Command]] son consultas +> Información: Las consultas realizadas llamando a [[yii\db\Command::execute()]] se consideran consultas de escritura, + mientras que todas las demás se ejecutan mediante alguno de los métodos "query" de [[yii\db\Command]] son consultas de lectura. Se puede obtener la conexión de esclavo activa mediante `$db->slave`. -El componente `Connection` soporta el balanceo de carga y la conmutación de errores entre esclavos. Cuando se realiza -una consulta de lectura por primera vez, el componente `Connection` elegirá un esclavo aleatorio e intentará realizar -una conexión a este. Si está "muerto", se intentara con otro. Si no está disponible ningún esclavo, se conectará al -maestro. Configurando una [[yii\db\Connection::serverStatusCache|server status cache]], se recordarán los servidores -"muertos" por lo que no se intentará volver a conectar a ellos durante +El componente `Connection` soporta el balanceo de carga y la conmutación de errores entre esclavos. Cuando se realiza +una consulta de lectura por primera vez, el componente `Connection` elegirá un esclavo aleatorio e intentará realizar +una conexión a este. Si el esclavo se encuentra "muerto", se intentará con otro. Si no está disponible ningún esclavo, se conectará al maestro. Configurando una [[yii\db\Connection::serverStatusCache|server status cache]], se recordarán los servidores +"muertos" por lo que no se intentará volver a conectar a ellos durante [[yii\db\Connection::serverRetryInterval|certain period of time]]. -> Información: En la configuración anterior, se especifica un tiempo de espera (timeout) de conexión de 10 segundos - para cada esclavo. Esto significa que si no se puede conectar a un esclavo en 10 segundos, este será considerado +> Información: En la configuración anterior, se especifica un tiempo de espera (timeout) de conexión de 10 segundos + para cada esclavo. Esto significa que si no se puede conectar a un esclavo en 10 segundos, este será considerado como "muerto". Se puede ajustar el parámetro basado en el entorno actual. -También se pueden configurar múltiples parámetros para múltiples esclavos. Por ejemplo, +También se pueden configurar múltiples maestros con múltiples esclavos. Por ejemplo, ```php [ @@ -462,7 +515,7 @@ También se pueden configurar múltiples parámetros para múltiples esclavos. P 'username' => 'master', 'password' => '', 'attributes' => [ - // use a smaller connection timeout + // utilizar un tiempo de espera de conexión más pequeña PDO::ATTR_TIMEOUT => 10, ], ], @@ -478,7 +531,7 @@ También se pueden configurar múltiples parámetros para múltiples esclavos. P 'username' => 'slave', 'password' => '', 'attributes' => [ - // use a smaller connection timeout + // utilizar un tiempo de espera de conexión más pequeña PDO::ATTR_TIMEOUT => 10, ], ], @@ -493,16 +546,16 @@ También se pueden configurar múltiples parámetros para múltiples esclavos. P ] ``` -La configuración anterior especifica dos maestros y cuatro esclavos. El componente `Connection` también da soporte al -balanceo de carga y la conmutación de errores entre maestros igual que hace con los esclavos. La diferencia es que +La configuración anterior especifica dos maestros y cuatro esclavos. El componente `Connection` también da soporte al +balanceo de carga y la conmutación de errores entre maestros igual que hace con los esclavos. La diferencia es que cuando no se encuentra ningún maestro disponible se lanza una excepción. -> Nota: cuando se usa la propiedad [[yii\db\Connection::masters|masters]] para configurar uno o múltiples maestros, se - ignorarán todas las otras propiedades que especifiquen una conexión de base de datos - (p. ej. `dsn`, `username`, `password`), junto con el mismo objeto `Connection`. +> Nota: cuando se usa la propiedad [[yii\db\Connection::masters|masters]] para configurar uno o múltiples maestros, se + ignorarán todas las otras propiedades que especifiquen una conexión de base de datos + (ej. `dsn`, `username`, `password`), junto con el mismo objeto `Connection`. -Las conexiones usan la conexión de maestro de forma predeterminada. Y todas las operaciones de BBDD que estén dentro -de una transacción, usaran la conexión de maestro. Por ejemplo, +Por defecto. las transacciones usan la conexión del maestro. Y dentro de una transacción, todas las operaciones de DB usarán +la conexión del maestro. Por ejemplo, ```php // la transacción empieza con la conexión al maestro @@ -520,14 +573,14 @@ try { } ``` -Si se quiere empezar la conexión con una conexión a un esclavo, se debe hacer explícitamente como se muestra a +Si se quiere empezar la transacción con una conexión a un esclavo, se debe hacer explícitamente como se muestra a continuación: ```php $transaction = $db->slave->beginTransaction(); ``` -A veces, se puede querer forzar el uso de una conexión maestra para realizar una consulta de lectura. Se puede lograr +A veces, se puede querer forzar el uso de una conexión maestra para realizar una consulta de lectura. Se puede lograr usando el método `useMaster()`: ```php @@ -536,48 +589,48 @@ $rows = $db->useMaster(function ($db) { }); ``` -También se puede utilizar directamente estableciendo `$db->enableSlaves` a `false` para que se redirijan todas las -consultas a la conexión de maestro. +También se puede utilizar directamente estableciendo `$db->enableSlaves` a `false` para que se redirijan todas las +consultas a la conexión del maestro. -Trabajar con Esquemas de Bases de Datos ---------------------------------------- +## Trabajando con Esquemas de Bases de Datos -### Obtención de la información del esquema +Yii DAO proporciona todo un conjunto de métodos que permites manipular el esquema de tu base de datos, tal como +crear nuevas tablas, borrar una columna de una tabla, etc. Estos métodos son listados a continuación: -Se puede obtener una instancia de [[yii\db\Schema]] como se muestra a continuación: +* [[yii\db\Command::createTable()|createTable()]]: crea una tabla +* [[yii\db\Command::renameTable()|renameTable()]]: renombra una tabla +* [[yii\db\Command::dropTable()|dropTable()]]: remueve una tabla +* [[yii\db\Command::truncateTable()|truncateTable()]]: remueve todas las filas de una tabla +* [[yii\db\Command::addColumn()|addColumn()]]: añade una columna +* [[yii\db\Command::renameColumn()|renameColumn()]]: renombra una columna +* [[yii\db\Command::dropColumn()|dropColumn()]]: remueve una columna +* [[yii\db\Command::alterColumn()|alterColumn()]]: altera una columna +* [[yii\db\Command::addPrimaryKey()|addPrimaryKey()]]: añade una clave primaria +* [[yii\db\Command::dropPrimaryKey()|dropPrimaryKey()]]: remueve una clave primaria +* [[yii\db\Command::addForeignKey()|addForeignKey()]]: añade una clave ajena +* [[yii\db\Command::dropForeignKey()|dropForeignKey()]]: remueve una clave ajena +* [[yii\db\Command::createIndex()|createIndex()]]: crea un indice +* [[yii\db\Command::dropIndex()|dropIndex()]]: remueve un indice -```php -$schema = $connection->getSchema(); -``` - -Contiene una serie de métodos que permiten obtener información varia acerca de la base de datos: - -```php -$tables = $schema->getTableNames(); -``` - -Para hacer referencia al esquema entero, se puede revisar [[yii\db\Schema]]. - -### Modificación de esquemas - -Aparte de consultas SQL basicas, [[yii\db\Command]] contiene un conjunto de métodos que permiten modificar el esquema -de la base de datos: - -- createTable, renameTable, dropTable, truncateTable -- addColumn, renameColumn, dropColumn, alterColumn -- addPrimaryKey, dropPrimaryKey -- addForeignKey, dropForeignKey -- createIndex, dropIndex - -Que pueden usarse como se muestra a continuación: +Estos métodos puedes ser usados como se muestra a continuación: ```php // CREATE TABLE -$connection->createCommand()->createTable('post', [ +$db->createCommand()->createTable('post', [ 'id' => 'pk', 'title' => 'string', 'text' => 'text', ]); ``` -Para la referencia completa, se puede revisar [[yii\db\Command]]. +También puedes recuperar la información de definición de una tabla a través +del método [[yii\db\Connection::getTableSchema()|getTableSchema()]] de una conexión DB. Por ejemplo, + +```php +$table = $db->getTableSchema('post'); +``` + +El método retorna un objeto [[yii\db\TableSchema]] que contiene la información sobre las columnas de las tablas, +claves primarias, claves ajenas, etc. Toda esta información principalmente es utilizada por el +[constructor de consultas](db-query-builder.md) y [active record](db-active-record.md) para ayudar a +escribir código database-agnostic. diff --git a/docs/guide-es/db-query-builder.md b/docs/guide-es/db-query-builder.md new file mode 100644 index 0000000..a7670ff --- /dev/null +++ b/docs/guide-es/db-query-builder.md @@ -0,0 +1,470 @@ +Constructor de Consultas +======================== + +> Nota: Esta sección está en desarrollo. + +Yii proporciona una capa de acceso básico a bases de datos como se describe en la sección +[Objetos de Acceso a Bases de Datos](db-dao.md). La capa de acceso a bases de datos proporciona un método de bajo +nivel (low-level) para interaccionar con la base de datos. Aunque a veces puede ser útil la escritura de sentencias +SQLs puras, en otras situaciones puede ser pesado y propenso a errores. Otra manera de tratar con bases de datos puede +ser el uso de Constructores de Consultas (Query Builder). El Constructor de Consultas proporciona un medio orientado a +objetos para generar las consultas que se ejecutarán. + +Un uso típico de Constructor de Consultas puede ser el siguiente: + +```php +$rows = (new \yii\db\Query()) + ->select('id, name') + ->from('user') + ->limit(10) + ->all(); + +// que es equivalente al siguiente código: + +$query = (new \yii\db\Query()) + ->select('id, name') + ->from('user') + ->limit(10); + +// Crear un comando. Se puede obtener la consulta SQL actual utilizando $command->sql +$command = $query->createCommand(); + +// Ejecutar el comando: +$rows = $command->queryAll(); +``` + +Métodos de Consulta +------------------- + +Como se puede observar, primero se debe tratar con [[yii\db\Query]]. En realidad, `Query` sólo se encarga de +representar diversa información de la consulta. La lógica para generar la consulta se efectúa mediante +[[yii\db\QueryBuilder]] cuando se llama al método `createCommand()`, y la ejecución de la consulta la efectúa +[[yii\db\Command]]. + +Se ha establecido, por convenio, que [[yii\db\Query]] proporcione un conjunto de métodos de consulta comunes que +construirán la consulta, la ejecutarán, y devolverán el resultado. Por ejemplo: + +- [[yii\db\Query::all()|all()]]: construye la consulta, la ejecuta y devuelve todos los resultados en formato de array. +- [[yii\db\Query::one()|one()]]: devuelve la primera fila del resultado. +- [[yii\db\Query::column()|column()]]: devuelve la primera columna del resultado. +- [[yii\db\Query::scalar()|scalar()]]: devuelve la primera columna en la primera fila del resultado. +- [[yii\db\Query::exists()|exists()]]: devuelve un valor indicando si la el resultado devuelve algo. +- [[yii\db\Query::count()|count()]]: devuelve el resultado de la consulta `COUNT`. Otros métodos similares incluidos + son `sum($q)`, `average($q)`, `max($q)`, `min($q)`, que soportan las llamadas funciones de agregación. El parámetro + `$q` es obligatorio en estos métodos y puede ser el nombre de la columna o expresión. + +Construcción de Consultas +------------------------- + +A continuación se explicará como construir una sentencia SQL que incluya varias clausulas. Para simplificarlo, usamos +`$query` para representar el objeto [[yii\db\Query]]: + +### `SELECT` + +Para formar una consulta `SELECT` básica, se necesita especificar que columnas y de que tablas se seleccionarán: + +```php +$query->select('id, name') + ->from('user'); +``` + +Las opciones de select se pueden especificar como una cadena de texto (string) separada por comas o como un array. La +sintaxis del array es especialmente útil cuando se forma la selección dinámicamente. + +```php +$query->select(['id', 'name']) + ->from('user'); +``` + +> Información: Se debe usar siempre el formato array si la clausula `SELECT` contiene expresiones SQL. Esto se debe a + que una expresión SQL como `CONCAT(first_name, last_name) AS full_name` puede contener comas. Si se junta con otra + cadena de texto de otra columna, puede ser que la expresión se divida en varias partes por comas, esto puede + conllevar a errores. + +Cuando se especifican columnas, se pueden incluir los prefijos de las tablas o alias de columnas, ej. `user.id`, +`user.id AS user_id`. Si se usa un array para especificar las columnas, también se pueden usar las claves del array +para especificar los alias de columna, ej. `['user_id' => 'user.id', 'user_name' => 'user.name']`. + +A partir de la versión 2.0.1, también se pueden seleccionar subconsultas como columnas. Por ejemplo: + +```php +$subQuery = (new Query)->select('COUNT(*)')->from('user'); +$query = (new Query)->select(['id', 'count' => $subQuery])->from('post'); +// $query representa la siguiente sentencia SQL: +// SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post` +``` + +Para seleccionar filas distintas, se puede llamar a `distinct()`, como se muestra a continuación: + +```php +$query->select('user_id')->distinct()->from('post'); +``` + +### `FROM` + +Para especificar de que tabla(s) se quieren seleccionar los datos, se llama a `from()`: + +```php +$query->select('*')->from('user'); +``` + +Se pueden especificar múltiples tablas usando una cadena de texto separado por comas o un array. Los nombres de tablas +pueden contener prefijos de esquema (ej. `'public.user'`) y/o alias de tablas (ej. `'user u'). El método +entrecomillara automáticamente los nombres de tablas a menos que contengan algún paréntesis (que significa que se +proporciona la tabla como una subconsulta o una expresión de BD). Por ejemplo: + +```php +$query->select('u.*, p.*')->from(['user u', 'post p']); +``` + +Cuando se especifican las tablas como un array, también se pueden usar las claves de los arrays como alias de tablas +(si una tabla no necesita alias, no se usa una clave en formato texto). Por ejemplo: + +```php +$query->select('u.*, p.*')->from(['u' => 'user', 'p' => 'post']); +``` + +Se puede especificar una subconsulta usando un objeto `Query`. En este caso, la clave del array correspondiente se +usará como alias para la subconsulta. + +```php +$subQuery = (new Query())->select('id')->from('user')->where('status=1'); +$query->select('*')->from(['u' => $subQuery]); +``` + +### `WHERE` + +Habitualmente se seleccionan los datos basándose en ciertos criterios. El Constructor de Consultas tiene algunos +métodos útiles para especificarlos, el más poderoso de estos es `where`, y se puede usar de múltiples formas. + +La manera más simple para aplicar una condición es usar una cadena de texto: + +```php +$query->where('status=:status', [':status' => $status]); +``` + +Cuando se usan cadenas de texto, hay que asegurarse que se unen los parámetros de la consulta, no crear una consulta +mediante concatenación de cadenas de texto. El enfoque anterior es seguro, el que se muestra a continuación, no lo es: + +```php +$query->where("status=$status"); // Peligroso! +``` + +En lugar de enlazar los valores de estado inmediatamente, se puede hacer usando `params` o `addParams`: + +```php +$query->where('status=:status'); +$query->addParams([':status' => $status]); +``` + +Se pueden establecer múltiples condiciones en `where` usando el *formato hash*. + +```php +$query->where([ + 'status' => 10, + 'type' => 2, + 'id' => [4, 8, 15, 16, 23, 42], +]); +``` + +El código generará la el siguiente SQL: + +```sql +WHERE (`status` = 10) AND (`type` = 2) AND (`id` IN (4, 8, 15, 16, 23, 42)) +``` + +El valor NULO es un valor especial en las bases de datos, y el Constructor de Consultas lo gestiona inteligentemente. +Este código: + +```php +$query->where(['status' => null]); +``` + +da como resultado la siguiente cláusula WHERE: + +```sql +WHERE (`status` IS NULL) +``` + +También se pueden crear subconsultas con objetos de tipo `Query` como en el siguiente ejemplo: + +```php +$userQuery = (new Query)->select('id')->from('user'); +$query->where(['id' => $userQuery]); +``` + +que generará el siguiente código SQL: + +```sql +WHERE `id` IN (SELECT `id` FROM `user`) +``` + +Otra manera de usar el método es el formato de operando que es `[operator, operand1, operand2, ...]`. + +El operando puede ser uno de los siguientes (ver también [[yii\db\QueryInterface::where()]]): + +- `and`: los operandos deben concatenerase usando `AND`. por ejemplo, `['and', 'id=1', 'id=2']` generará + `id=1 AND id=2`. Si el operando es un array, se convertirá en una cadena de texto usando las reglas aquí descritas. + Por ejemplo, `['and', 'type=1', ['or', 'id=1', 'id=2']]` generará `type=1 AND (id=1 OR id=2)`. El método no + ejecutará ningún filtrado ni entrecomillado. + +- `or`: similar al operando `and` exceptuando que los operando son concatenados usando `OR`. + +- `between`: el operando 1 debe ser el nombre de columna, y los operandos 2 y 3 deben ser los valores iniciales y + finales del rango en el que se encuentra la columna. Por ejemplo, `['between', 'id', 1, 10]` generará + `id BETWEEN 1 AND 10`. + +- `not between`: similar a `between` exceptuando que `BETWEEN` se reemplaza por `NOT BETWEEN` en la condición + generada. + +- `in`: el operando 1 debe ser una columna o una expresión de BD. El operando 2 puede ser un array o un objeto de tipo + `Query`. Generará una condición `IN`. Si el operando 2 es un array, representará el rango de valores que puede + albergar la columna o la expresión de BD; Si el operando 2 es un objeto de tipo `Query`, se generará una subconsulta + y se usará como rango de la columna o de la expresión de BD. Por ejemplo, `['in', 'id', [1, 2, 3]]` generará + `id IN (1, 2, 3)`. El método entrecomillará adecuadamente el nombre de columna y filtrará los valores del rango. El + operando `in` también soporta columnas compuestas. En este caso, el operando 1 debe se un array de columnas, + mientras que el operando 2 debe ser un array de arrays o un objeto de tipo `Query` que represente el rango de las + columnas. + +- `not in`: similar que el operando `in` exceptuando que `IN` se reemplaza por `NOT IN` en la condición generada. + +- `like`: el operando 1 debe ser una columna o una expresión de BD, y el operando 2 debe ser una cadena de texto o un + array que represente los valores a los que tienen que asemejarse la columna o la expresión de BD.Por ejemplo, + `['like', 'name', 'tester']` generará `name LIKE '%tester%'`. Cuando se da el valor rango como un array, se + generarán múltiples predicados `LIKE` y se concatenaran usando `AND`. Por ejemplo, + `['like', 'name', ['test', 'sample']]` generará `name LIKE '%test%' AND name LIKE '%sample%'`. También se puede + proporcionar un tercer operando opcional para especificar como deben filtrarse los caracteres especiales en los + valores. El operando debe se un array que mapeen los caracteres especiales a sus caracteres filtrados asociados. Si + no se proporciona este operando, se aplicará el mapeo de filtrado predeterminado. Se puede usar `false` o un array + vacío para indicar que los valores ya están filtrados y no se necesita aplicar ningún filtro. Hay que tener en + cuenta que cuando se usa un el mapeo de filtrado (o no se especifica el tercer operando), los valores se encerraran + automáticamente entre un par de caracteres de porcentaje. + +> Nota: Cuando se usa PostgreSQL también se puede usar +[`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) en lugar de `like` para +filtrar resultados insensibles a mayúsculas (case-insensitive). + +- `or like`: similar al operando `like` exceptuando que se usa `OR` para concatenar los predicados `LIKE` cuando haya + un segundo operando en un array. + +- `not like`: similar al operando `like` exceptuando que se usa `LIKE` en lugar de `NOT LIKE` en las condiciones + generadas. + +- `or not like`: similar al operando `not like` exceptuando que se usa `OR` para concatenar los predicados `NOT LIKE`. + +- `exists`: requiere un operando que debe ser una instancia de [[yii\db\Query]] que represente la subconsulta. Esto + generará una expresión `EXISTS (sub-query)`. + +- `not exists`: similar al operando `exists` y genera una expresión `NOT EXISTS (sub-query)`. + +Adicionalmente se puede especificar cualquier cosa como operando: + +```php +$query->select('id') + ->from('user') + ->where(['>=', 'id', 10]); +``` + +Cuyo resultado será: + +```sql +SELECT id FROM user WHERE id >= 10; +``` + +Si se construyen partes de una condición dinámicamente, es muy convenientes usar `andWhere()` y `orWhere()`: + +```php +$status = 10; +$search = 'yii'; + +$query->where(['status' => $status]); +if (!empty($search)) { + $query->andWhere(['like', 'title', $search]); +} +``` + +En el caso que `$search` no este vacío, se generará el siguiente código SQL: + +```sql +WHERE (`status` = 10) AND (`title` LIKE '%yii%') +``` + +#### Construcción de Condiciones de Filtro + +Cuando se generan condiciones de filtro basadas en datos recibidos de usuarios (inputs), a menudo se quieren gestionar +de forma especial las "datos vacíos" para ignorarlos en los filtros. Por ejemplo, teniendo un formulario HTML que +obtiene el nombre de usuario y la dirección de correo electrónico. Si el usuario solo rellena el campo de nombre de +usuario, se puede querer generar una consulta para saber si el nombre de usuario recibido es valido. Se puede usar +`filterWhere()` para conseguirlo: + +```php +// $username y $email son campos de formulario rellenados por usuarios +$query->filterWhere([ + 'username' => $username, + 'email' => $email, +]); +``` + +El método `filterWhere()` es muy similar al método `where()`. La principal diferencia es que el `filterWhere()` +eliminará los valores vacíos de las condiciones proporcionadas. Por lo tanto si `$email` es "vació", la consulta +resultante será `...WHERE username=:username`; y si tanto `$username` como `$email` son "vacías", la consulta no +tendrá `WHERE`. + +Decimos que un valor es *vacío* si es nulo, una cadena de texto vacía, una cadena de texto que consista en espacios en +blanco o un array vacío. + +También se pueden usar `andFilterWhere()` y `orFilterWhere()` para añadir más condiciones de filtro. + +### `ORDER BY` + +Se pueden usar `orderBy` y `addOrderBy` para ordenar resultados: + +```php +$query->orderBy([ + 'id' => SORT_ASC, + 'name' => SORT_DESC, +]); +``` + +Aquí estamos ordenando por `id` ascendente y después por `name` descendente. + +### `GROUP BY` and `HAVING` + +Para añadir `GROUP BY` al SQL generado se puede usar el siguiente código: + +```php +$query->groupBy('id, status'); +``` + +Si se quieren añadir otro campo después de usar `groupBy`: + +```php +$query->addGroupBy(['created_at', 'updated_at']); +``` + +Para añadir la condición `HAVING` se pueden usar los métodos `having` y `andHaving` y `orHaving`. Los parámetros para +ellos son similares a los del grupo de métodos `where`: + +```php +$query->having(['status' => $status]); +``` + +### `LIMIT` and `OFFSET` + +Para limitar el resultado a 10 filas se puede usar `limit`: + +```php +$query->limit(10); +``` + +Para saltarse las 100 primeras filas, se puede usar: + +```php +$query->offset(100); +``` + +### `JOIN` + +Las clausulas `JOIN` se generan en el Constructor de Consultas usando el método join aplicable: + +- `innerJoin()` +- `leftJoin()` +- `rightJoin()` + +Este left join selecciona los datos desde dos tablas relacionadas en una consulta: + +```php +$query->select(['user.name AS author', 'post.title as title']) + ->from('user') + ->leftJoin('post', 'post.user_id = user.id'); +``` + +En el código, el primer parámetro del método `leftjoin` especifica la tabla a la que aplicar el join. El segundo +parámetro, define la condición del join. + +Si la aplicación de bases de datos soporta otros tipos de joins, se pueden usar mediante el método `join` genérico: + +```php +$query->join('FULL OUTER JOIN', 'post', 'post.user_id = user.id'); +``` + +El primer argumento es el tipo de join a realizar. El segundo es la tabla a la que aplicar el join, y el tercero es la condición: + +Como en `FROM`, también se pueden efectuar joins con subconsultas. Para hacerlo, se debe especificar la subconsulta +como un array que tiene que contener un elemento. El valor del array tiene que ser un objeto de tipo `Query` que +represente la subconsulta, mientras que la clave del array es el alias de la subconsulta. Por ejemplo: + +```php +$query->leftJoin(['u' => $subQuery], 'u.id=author_id'); +``` + +### `UNION` + +En SQL `UNION` agrega resultados de una consulta a otra consulta. Las columnas devueltas por ambas consultas deben +coincidir. En Yii para construirla, primero se pueden formar dos objetos de tipo query y después usar el método +`union`: + +```php +$query = new Query(); +$query->select("id, category_id as type, name")->from('post')->limit(10); + +$anotherQuery = new Query(); +$anotherQuery->select('id, type, name')->from('user')->limit(10); + +$query->union($anotherQuery); +``` + +Consulta por Lotes +--------------- + +Cuando se trabaja con grandes cantidades de datos, los métodos como [[yii\db\Query::all()]] no son adecuados ya que +requieren la carga de todos los datos en memoria. Para mantener los requerimientos de memoria reducidos, Yii +proporciona soporte a las llamadas consultas por lotes (batch query). Una consulta por lotes usa un cursor de datos y +recupera los datos en bloques. + +Las consultas por lotes se pueden usar del siguiente modo: + +```php +use yii\db\Query; + +$query = (new Query()) + ->from('user') + ->orderBy('id'); + +foreach ($query->batch() as $users) { + // $users is an array of 100 or fewer rows from the user table +} + +// o si se quieren iterar las filas una a una +foreach ($query->each() as $user) { + // $user representa uno fila de datos de la tabla user +} +``` + +Los métodos [[yii\db\Query::batch()]] y [[yii\db\Query::each()]] devuelven un objeto [[yii\db\BatchQueryResult]] que +implementa una interfaz `Iterator` y así se puede usar en el constructor `foreach`. Durante la primera iteración, se +efectúa una consulta SQL a la base de datos. Desde entonces, los datos se recuperan por lotes en las iteraciones. El +tamaño predeterminado de los lotes es 100, que significa que se recuperan 100 filas de datos en cada lote. Se puede +modificar el tamaño de los lotes pasando pasando un primer parámetro a los métodos `batch()` o `each()`. + +En comparación con [[yii\db\Query::all()]], las consultas por lotes sólo cargan 100 filas de datos en memoria cada +vez. Si el procesan los datos y después se descartan inmediatamente, las consultas por lotes, pueden ayudar a mantener +el uso de memora bajo un limite. + +Si se especifica que el resultado de la consulta tiene que ser indexado por alguna columna mediante +[[yii\db\Query::indexBy()]], las consultas por lotes seguirán manteniendo el indice adecuado. Por ejemplo, + +```php +use yii\db\Query; + +$query = (new Query()) + ->from('user') + ->indexBy('username'); + +foreach ($query->batch() as $users) { + // $users esta indexado en la columna "username" +} + +foreach ($query->each() as $username => $user) { +} +``` \ No newline at end of file diff --git a/docs/guide-es/helper-array.md b/docs/guide-es/helper-array.md new file mode 100644 index 0000000..0bfb01c --- /dev/null +++ b/docs/guide-es/helper-array.md @@ -0,0 +1,304 @@ +ArrayHelper +=========== + +Adicionalmente al [rico conjunto de funciones para arrays de PHP](http://php.net/manual/es/book.array.php) Yii array helper proporciona +métodos estáticos adicionales permitiendo trabajar con arrays de manera más eficiente. + + +## Devolviendo Valores + +Recuperar valores de un array, un objeto o una estructura compleja usando PHP estándar es bastante +repetitivo. Tienes que comprobar primero si una clave existe con `isset`, después devolver el valor si existe, si no, +devolver un valor por defecto: + +```php +class User +{ + public $name = 'Alex'; +} + +$array = [ + 'foo' => [ + 'bar' => new User(), + ] +]; + +$value = isset($array['foo']['bar']->name) ? $array['foo']['bar']->name : null; +``` + +Yii proviene de un método muy conveniente para hacerlo: + +```php +$value = ArrayHelper::getValue($array, 'foo.bar.name'); +``` + +El primer argumento del método es de donde vamos a obtener el valor. El segundo argumento especifica como devolver el dato. Puede ser +de la siguiente manera: + +- Nombre de la clave del array o de la propiedad del objeto para recuperar el valor. +- Conjunto de puntos separados por las claves del array o los nombres de las propiedades del objeto. Esto se ha usado en el ejemplo anterior. +- Un callback que devuelve un valor. + +El callback se debería usar de la siguiente manera: + +```php +$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) { + return $user->firstName . ' ' . $user->lastName; +}); +``` + +El tercer argumento opcional es el valor por defecto el cual es `null` si no se especifica. Podría ser utilizado de la siguiente manera: + +```php +$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown'); +``` + +En caso de que quieras coger un valor y luego removerlo inmediatamente del array puedes usar el método `remove`: + +```php +$array = ['type' => 'A', 'options' => [1, 2]]; +$type = ArrayHelper::remove($array, 'type'); +``` + +Después de ejecutar el código el `$array` contendrá `['options' => [1, 2]]` y `$type` debe ser `A`. Tenga en cuenta que a diferencia del método +`getValue`, `remove` solo soporta nombres clave simples. + + +## Comprobando la Existencia de Claves + +`ArrayHelper::keyExists` funciona de la misma manera que [array_key_exists](http://php.net/manual/es/function.array-key-exists.php) +excepto que también soporta case-insensitive para la comparación de claves. Por ejemplo, + +```php +$data1 = [ + 'userName' => 'Alex', +]; + +$data2 = [ + 'username' => 'Carsten', +]; + +if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) { + echo "Please provide username."; +} +``` + +## Recuperando Columnas + +A menudo necesitas obtener unos valores de una columna de las filas de datos u objetos de un array. Un ejemplo común es obtener una lista de IDs. + +```php +$data = [ + ['id' => '123', 'data' => 'abc'], + ['id' => '345', 'data' => 'def'], +]; +$ids = ArrayHelper::getColumn($array, 'id'); +``` + +El resultado será `['123', '345']`. + +Si se requieren transformaciones adicionales o la manera de obtener el valor es complejo, se podría especificar como segundo argumento +una función anónima : + +```php +$result = ArrayHelper::getColumn($array, function ($element) { + return $element['id']; +}); +``` + + +## Re-indexar Arrays + +Con el fin de indexar un array según una clave especificada, se puede usar el método `index`. La entrada del array debe ser +multidimensional o un array de objetos. La clave puede ser un nombre clave del sub-array, un nombre de una propiedad del objeto, o +una función anónima que retorne el valor de la clave dado el elemento del array. + +Si el valor de la clave es null, el correspondiente elemento del array será desechado y no se pondrá en el resultado. Por ejemplo, + +```php +$array = [ + ['id' => '123', 'data' => 'abc'], + ['id' => '345', 'data' => 'def'], +]; +$result = ArrayHelper::index($array, 'id'); +// el resultado es: +// [ +// '123' => ['id' => '123', 'data' => 'abc'], +// '345' => ['id' => '345', 'data' => 'def'], +// ] + +// usando función anónima +$result = ArrayHelper::index($array, function ($element) { + return $element['id']; +}); +``` + + +## Construyendo Mapas (Maps) + +Con el fin de construir un mapa (pareja clave-valor) de un array multidimensional o un array de objetos puedes usar el método `map`. +Los parámetros `$from` y `$to` especifican los nombres de las claves o los nombres de las propiedades que serán configuradas en el mapa. Opcionalmente, se puede +agrupar en el mapa de acuerdo al campo de agrupamiento `$group`. Por ejemplo, + +```php +$array = [ + ['id' => '123', 'name' => 'aaa', 'class' => 'x'], + ['id' => '124', 'name' => 'bbb', 'class' => 'x'], + ['id' => '345', 'name' => 'ccc', 'class' => 'y'], +); + +$result = ArrayHelper::map($array, 'id', 'name'); +// el resultado es: +// [ +// '123' => 'aaa', +// '124' => 'bbb', +// '345' => 'ccc', +// ] + +$result = ArrayHelper::map($array, 'id', 'name', 'class'); +// el resultado es: +// [ +// 'x' => [ +// '123' => 'aaa', +// '124' => 'bbb', +// ], +// 'y' => [ +// '345' => 'ccc', +// ], +// ] +``` + + +## Ordenamiento Multidimensional + +El método `multisort` ayuda a ordenar un array de objetos o arrays anidados por una o varias claves. Por ejemplo, + +```php +$data = [ + ['age' => 30, 'name' => 'Alexander'], + ['age' => 30, 'name' => 'Brian'], + ['age' => 19, 'name' => 'Barney'], +]; +ArrayHelper::multisort($data, ['age', 'name'], [SORT_ASC, SORT_DESC]); +``` + +Después del ordenado obtendremos lo siguiente en `$data`: + +```php +[ + ['age' => 19, 'name' => 'Barney'], + ['age' => 30, 'name' => 'Brian'], + ['age' => 30, 'name' => 'Alexander'], +]; +``` + +El segundo argumento que especifica las claves para ordenar puede ser una cadena si se trata de una clave, un array en caso de que tenga múltiples claves +o una función anónima como la siguiente + +```php +ArrayHelper::multisort($data, function($item) { + return isset($item['age']) ? ['age', 'name'] : 'name'; +}); +``` + +El tercer argumento es la dirección. En caso de ordenar por una clave podría ser `SORT_ASC` o +`SORT_DESC`. Si ordenas por múltiples valores puedes ordenar cada valor diferentemente proporcionando un array de +direcciones de ordenación. + +El último argumento es un PHP sort flag que toma los mismos valores que los pasados a +PHP [sort()](http://php.net/manual/es/function.sort.php). + + +## Detectando Tipos de Array + +Es muy útil saber si un array es indexado o asociativo. He aquí un ejemplo: + +```php +// sin claves especificadas +$indexed = ['Qiang', 'Paul']; +echo ArrayHelper::isIndexed($indexed); + +// todas las claves son strings +$associative = ['framework' => 'Yii', 'version' => '2.0']; +echo ArrayHelper::isAssociative($associative); +``` + + +## Codificación y Decodificación de Valores HTML + +Con el fin de codificar o decodificar caracteres especiales en un array de strings con entidades HTML puedes usar lo siguiente: + +```php +$encoded = ArrayHelper::htmlEncode($data); +$decoded = ArrayHelper::htmlDecode($data); +``` + +Solo los valores se codifican por defecto. Pasando como segundo argumento `false` puedes codificar un array de claves también. +La codificación utilizará el charset de la aplicación y podría ser cambiado pasandole un tercer argumento. + + +## Fusionando Arrays + +```php + /** + * Merges two or more arrays into one recursively. + * If each array has an element with the same string key value, the latter + * will overwrite the former (different from array_merge_recursive). + * Recursive merging will be conducted if both arrays have an element of array + * type and are having the same key. + * For integer-keyed elements, the elements from the latter array will + * be appended to the former array. + * @param array $a array to be merged to + * @param array $b array to be merged from. You can specify additional + * arrays via third argument, fourth argument etc. + * @return array the merged array (the original arrays are not changed.) + */ + public static function merge($a, $b) +``` + + +## Convirtiendo Objetos a Arrays + +A menudo necesitas convertir un objeto o un array de objetos a un array. El caso más común es convertir los modelos de +active record con el fin de servir los arrays de datos vía API REST o utilizarlos de otra manera. El siguiente código +se podría utilizar para hacerlo: + +```php +$posts = Post::find()->limit(10)->all(); +$data = ArrayHelper::toArray($post, [ + 'app\models\Post' => [ + 'id', + 'title', + // el nombre de la clave del resultado del array => nombre de la propiedad + 'createTime' => 'created_at', + // el nombre de la clave del resultado del array => función anónima + 'length' => function ($post) { + return strlen($post->content); + }, + ], +]); +``` + +El primer argumento contiene el dato que queremos convertir. En nuestro caso queremos convertir un modelo AR `Post`. + +El segundo argumento es el mapeo de conversión por clase. Estamos configurando un mapeo para el modelo `Post`. +Cada array de mapeo contiene un conjunto de mapeos. Cada mapeo podría ser: + +- Un campo nombre para incluir como está. +- Un par clave-valor del array deseado con un nombre clave y el nombre de la columna del modelo que tomará el valor. +- Un par clave-valor del array deseado con un nombre clave y una función anónima que retorne el valor. + +El resultado de la conversión anterior será: + + +```php +[ + 'id' => 123, + 'title' => 'test', + 'createTime' => '2013-01-01 12:00AM', + 'length' => 301, +] +``` + +Es posible proporcionar una manera predeterminada de convertir un objeto a un array para una clase especifica +mediante la implementación de la interfaz [[yii\base\Arrayable|Arrayable]] en esa clase. diff --git a/docs/guide-es/helper-html.md b/docs/guide-es/helper-html.md new file mode 100644 index 0000000..e2cf2bb --- /dev/null +++ b/docs/guide-es/helper-html.md @@ -0,0 +1,377 @@ +Clase auxiliar Html (Html helper) +================================= + +Todas las aplicaciones web generan grandes cantidades de marcado HTML (HTML markup). Si el marcado es estático, se +puede realizar de forma efectiva +[mezclando PHP y HTML en un mismo archivo](http://php.net/manual/es/language.basic-syntax.phpmode.php) pero cuando se +generan dinámicamente empieza a complicarse su gestión sin ayuda extra. Yii ofrece esta ayuda en forma de una clase auxiliar Html +que proporciona un conjunto de métodos estáticos para gestionar las etiquetas HTML más comúnmente usadas, sus opciones y contenidos. + +> Nota: Si el marcado es casi estático, es preferible usar HTML directamente. No es necesario encapsularlo todo con +llamadas a la clase auxiliar Html. + +## Lo fundamental + + +Teniendo en cuenta que la construcción de HTML dinámico mediante la concatenación de cadenas de texto se complica +rápidamente, Yii proporciona un conjunto de métodos para manipular las opciones de etiquetas y la construcción de las +mismas basadas en estas opciones. + +### Generación de etiquetas + +El código de generación de etiquetas es similar al siguiente: + +```php +name), ['class' => 'username']) ?> +``` + +El primer argumento es el nombre de la etiqueta. El segundo es el contenido que se ubicará entre la etiqueta de +apertura y la de cierre. Hay que tener en cuenta que estamos usando `Html::encode`. Esto es debido a que el contenido +no se codifica automáticamente para permitir usar HTML cuando se necesite. La tercera opción es un array de opciones +HTML o, en otras palabras, los atributos de las etiquetas. En este array la clave representa el nombre del atributo +como podría ser `class`, `href` o `target` y el valor es su valor. + +El código anterior generará el siguiente HTML: + +```html +

samdark

+``` + +Si se necesita solo la apertura o el cierre de una etiqueta, se pueden usar los métodos `Html::beginTag()` y +`Html::endTag()`. + +Las opciones se usan en muchos métodos de la clase auxiliar Html y en varios widgets. En todos estos casos hay cierta +gestión adicional que se debe conocer: + +- Si un valor es `null`, el correspondiente atributo no se renderizará. +- Los atributos cuyos valores son de tipo booleano serán tratados como + [atributos booleanos](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes). +- Los valores de los atributos se codificarán en HTML usando [[yii\helpers\Html::encode()|Html::encode()]]. +- El atributo "data" puede recibir un array. En este caso, se "expandirá" y se renderizará una lista de atributos + `data` ej. `'data' => ['id' => 1, 'name' => 'yii']` se convierte en `data-id="1" data-name="yii"`. +- El atributo "data" puede recibir un JSON. Se gestionará de la misma manera que un array ej. + `'data' => ['params' => ['id' => 1, 'name' => 'yii'], 'status' => 'ok']` se convierte en + `data-params='{"id":1,"name":"yii"}' data-status="ok"`. + +### Formación de clases y estilos dinámicamente + +Cuando se construyen opciones para etiquetas HTML, a menudo nos encontramos con valores predeterminados que hay que +modificar. Para añadir o eliminar clases CSS se puede usar el siguiente ejemplo: + +```php +$options = ['class' => 'btn btn-default']; + +if ($type === 'success') { + Html::removeCssClass($options, 'btn-default'); + Html::addCssClass($options, 'btn-success'); +} + +echo Html::tag('div', 'Pwede na', $options); + +// cuando $type sea 'success' se renderizará +//
Pwede na
+``` + +Para hacer lo mismo con los estilos para el atributo `style`: + +```php +$options = ['style' => ['width' => '100px', 'height' => '100px']]; + +// devuelve style="width: 100px; height: 200px; position: absolute;" +Html::addCssStyle($options, 'height: 200px; positon: absolute;'); + +// devuelve style="position: absolute;" +Html::removeCssStyle($options, ['width', 'height']); +``` + +Cuando se usa [[yii\helpers\Html::addCssStyle()|addCssStyle()]] se puede especificar si un array de pares clave-valor +corresponde a nombres y valores de la propiedad CSS correspondiente o a una cadena de texto como por ejemplo +`width: 100px; height: 200px;`. Estos formatos se pueden "hacer" y "deshacer" usando +[[yii\helpers\Html::cssStyleFromArray()|cssStyleFromArray()]] y +[[yii\helpers\Html::cssStyleToArray()|cssStyleToArray()]]. El método +[[yii\helpers\Html::removeCssStyle()|removeCssStyle()]] acepta un array de propiedades que se eliminarán. Si sólo se +eliminara una propiedad, se puede especificar como una cadena de texto. + +## Codificación y Decodificación del contenido + + +Para que el contenido se muestre correctamente y de forma segura con caracteres especiales HTML el contenido debe ser +codificado. En PHP esto se hace con [htmlspecialchars](http://www.php.net/manual/es/function.htmlspecialchars.php) y +[htmlspecialchars_decode](http://www.php.net/manual/es/function.htmlspecialchars-decode.php). El problema con el uso +de estos métodos directamente es que se tiene que especificar la codificación y opciones extra cada vez. Ya que las +opciones siempre son las mismas y la codificación debe coincidir con la de la aplicación para prevenir problemas de +seguridad, Yii proporciona dos métodos simples y compactos: + +```php +$userName = Html::encode($user->name); +echo $userName; + +$decodedUserName = Html::decode($userName); +``` + +## Formularios + + +El trato con el marcado de formularios es una tarea repetitiva y propensa a errores. Por esto hay un grupo de métodos +para ayudar a gestionarlos. + +> Nota: hay que considerar la opción de usar [[yii\widgets\ActiveForm|ActiveForm]] en caso de que se gestionen +formularios que requieran validaciones. + +### Creando formularios + +Se puede abrir un formulario con el método [[yii\helpers\Html::beginForm()|beginForm()]] como se muestra a +continuación: + +```php + $id], 'post', ['enctype' => 'multipart/form-data']) ?> +``` + +El primer argumento es la URL a la que se enviarán los datos del formulario. Se puede especificar en formato de ruta +de Yii con los parámetros aceptados por [[yii\helpers\Url::to()|Url::to()]]. El segundo es el método que se usará. +`post` es el método predeterminado. El tercero es un array de opciones para la etiqueta `form`. En este caso cambiamos +el método de codificación del formulario de `data` en una petición POST a `multipart/form-data`. Esto se requiere +cuando se quieren subir archivos. + +El cierre de la etiqueta `form` es simple: + +```php + +``` + +### Botones + +Para generar botones se puede usar el siguiente código: + +```php + 'teaser']) ?> + 'submit']) ?> + 'reset']) ?> +``` + +El primer argumento para los tres métodos es el título del botón y el segundo son las opciones. El título no está +codificado pero si se usan datos recibidos por el usuario, deben codificarse mediante +[[yii\helpers\Html::encode()|Html::encode()]]. + +### Inputs + +Hay dos grupos en los métodos input. Unos empiezan con `active` y se llaman inputs activos y los otros no empiezan +así. Los inputs activos obtienen datos del modelo y del atributo especificado y los datos de los inputs normales se +especifica directamente. + +Los métodos más genéricos son: + +```php +type, input name, input value, options +name, ['class' => $username]) ?> + +type, model, model attribute name, options + $username]) ?> +``` + +Si se conoce el tipo de input de antemano, es conveniente usar los atajos de los métodos: + +- [[yii\helpers\Html::buttonInput()]] +- [[yii\helpers\Html::submitInput()]] +- [[yii\helpers\Html::resetInput()]] +- [[yii\helpers\Html::textInput()]], [[yii\helpers\Html::activeTextInput()]] +- [[yii\helpers\Html::hiddenInput()]], [[yii\helpers\Html::activeHiddenInput()]] +- [[yii\helpers\Html::passwordInput()]] / [[yii\helpers\Html::activePasswordInput()]] +- [[yii\helpers\Html::fileInput()]], [[yii\helpers\Html::activeFileInput()]] +- [[yii\helpers\Html::textarea()]], [[yii\helpers\Html::activeTextarea()]] + +Los botones de opción (Radios) y las casillas de verificación (checkboxes) se especifican de forma un poco diferente: + +```php + 'I agree']); + 'agreement']) + + 'I agree']); + 'agreement']) +``` + +Las listas desplegables (dropdown list) se pueden renderizar como se muestra a continuación: + +```php + + + + + +``` + +El primer argumento es el nombre del input, el segundo es el valor seleccionado actualmente y el tercero es el array +de pares clave-valor donde la clave es la lista de valores y el valor del array es la lista a mostrar. + +Si se quiere habilitar la selección múltiple, se puede usar la lista seleccionable (checkbox list): + +```php + + +``` + +Si no, se puede usar la lista de opciones (radio list): + +```php + + +``` + +### Etiquetas y Errores + +De forma parecida que en los inputs hay dos métodos para generar etiquetas. El activo que obtiene los datos del modelo y +el no-activo que acepta los datos directamente: + +```php + 'label username']) ?> + 'label username']) +``` + +Para mostrar los errores del formulario de un modelo o modelos a modo de resumen puedes usar: + +```php + 'errors']) ?> +``` + +Para mostrar un error individual: + +```php + 'error']) ?> +``` + +### Input Names y Values + +Existen métodos para obtener names, IDs y values para los campos de entrada (inputs) basados en el modelo. Estos se +usan principalmente internamente pero a veces pueden resultar prácticos: + +```php +// Post[title] +echo Html::getInputName($post, 'title'); + +// post-title +echo Html::getInputId($post, 'title'); + +// mi primer post +echo Html::getAttributeValue($post, 'title'); + +// $post->authors[0] +echo Html::getAttributeValue($post, '[0]authors[0]'); +``` + +En el ejemplo anterior, el primer argumento es el modelo y el segundo es un atributo de expresión. En su forma más +simple es su nombre de atributo pero podría ser un nombre de atributo prefijado y/o añadido como sufijo con los +indices de un array, esto se usa principalmente para mostrar inputs en formatos de tablas: + +- `[0]content` se usa en campos de entrada de datos en formato de tablas para representar el atributo "content" para + el primer modelo del input en formato de tabla; +- `dates[0]` representa el primer elemento del array del atributo "dates"; +- `[0]dates[0]` representa el primer elemento del array del atributo "dates" para el primer modelo en formato de tabla. + +Para obtener el nombre de atributo sin sufijos o prefijos se puede usar el siguiente código: + +```php +// dates +echo Html::getAttributeName('dates[0]'); +``` + +## Estilos y scripts + + +Existen dos métodos para generar etiquetas que envuelvan estilos y scripts incrustados (embebbed): + +```php + + +Genera + + + + true]); + +Genera + + +``` + +Si se quiere enlazar un estilo externo desde un archivo CSS: + +```php + 'IE 5']) ?> + +genera + + +``` + +El primer argumento es la URL. El segundo es un array de opciones. Adicionalmente, para regular las opciones se puede +especificar: + +- `condition` para envolver `` por lo que el sólo se + incluirá si el navegador no soporta JavaScript o si lo ha deshabilitado el usuario. + +Para enlazar un archivo JavaScript: + +```php + +``` + +Es igual que con las CSS, el primer argumento especifica el enlace al fichero que se quiere incluir. Las opciones se +pueden pasar como segundo argumento. En las opciones se puede especificar `condition` del mismo modo que se puede usar +para `cssFile`. + +## Enlaces + + +Existe un método para generar hipervínculos a conveniencia: + +```php + $id], ['class' => 'profile-link']) ?> +``` + +El primer argumento es el título. No está codificado por lo que si se usan datos enviados por el usuario se tienen que +codificar usando `Html::encode()`. El segundo argumento es el que se introducirá en `href` de la etiqueta ` +``` + +## Imagenes + + +Para generar una etiqueta de tipo imagen se puede usar el siguiente ejemplo: + +```php + 'My logo']) ?> + +genera + +My logo +``` + +Aparte de los [alias](concept-aliases.md) el primer argumento puede aceptar rutas, parámetros y URLs. Del mismo modo +que [Url::to()](helper-url.md). + +## Listas + + +Las listas desordenadas se puede generar como se muestra a continuación: + +```php + function($item, $index) { + return Html::tag( + 'li', + $this->render('post', ['item' => $item]), + ['class' => 'post'] + ); +}]) ?> +``` + +Para generar listas ordenadas se puede usar `Html::ol()` en su lugar. diff --git a/docs/guide-es/helper-overview.md b/docs/guide-es/helper-overview.md new file mode 100644 index 0000000..3bf4354 --- /dev/null +++ b/docs/guide-es/helper-overview.md @@ -0,0 +1,79 @@ +Helpers +======= + +> Nota: Esta sección está en desarrollo. + +Yii ofrece muchas clases que ayudan a simplificar las tareas comunes de codificación, como manipulación de string o array, +generación de código HTML, y más. Estas clases helper están organizadas bajo el namespace `yii\helpers` y +son todo clases estáticas (lo que significa que sólo contienen propiedades y métodos estáticos y no deben ser instanciadas). + +Puedes usar una clase helper directamente llamando a uno de sus métodos estáticos, como a continuación: + +```php +use yii\helpers\Html; + +echo Html::encode('Test > test'); +``` + +> Nota: Para soportar la [personalización de clases helper](#customizing-helper-classes), Yii separa cada clase helper del núcleo + en dos clases: una clase base (ej. `BaseArrayHelper`) y una clase concreta (ej. `ArrayHelper`). + Cuando uses un helper, deberías sólo usar la versión concreta y nunca usar la clase base. + + +Clases Helper del núcleo +------------------------ + +Las siguientes clases helper del núcleo son proporcionadas en los releases de Yii: + +- [ArrayHelper](helper-array.md) +- Console +- FileHelper +- [Html](helper-html.md) +- HtmlPurifier +- Image +- Inflector +- Json +- Markdown +- Security +- StringHelper +- [Url](helper-url.md) +- VarDumper + + +Personalizando Las Clases Helper +-------------------------------- + +Para personalizar una clase helper del núcleo (ej. [[yii\helpers\ArrayHelper]]), deberías crear una nueva clase extendiendo +de los helpers correspondientes a la clase base (ej. [[yii\helpers\BaseArrayHelper]]), incluyendo su namespace. Esta clase +será creada para remplazar la implementación original del framework. + +El siguiente ejemplo muestra como personalizar el método [[yii\helpers\ArrayHelper::merge()|merge()]] de la clase +[[yii\helpers\ArrayHelper]]: + +```php + 42]); ``` -Se puede especificar la ruta como una cadena de texto, p. ej. `site/index`. También se puede usar un array si se +Se puede especificar la ruta como una cadena de texto, ej. `site/index`. También se puede usar un array si se quieren especificar parámetros para la URL que se esta generando. El formato del array debe ser: ```php @@ -53,14 +53,14 @@ Si se quiere crear una URL con un enlace, se puede usar el formato de array con ['site/index', 'param1' => 'value1', '#' => 'name'] ``` -Una ruta puede ser absoluta o relativa. Una ruta absoluta tiene una barra al principio (p. ej. `/site/index`), -mientras que una ruta relativa no la tiene (p. ej. `site/index` o `index`). Una ruta relativa se convertirá en una +Una ruta puede ser absoluta o relativa. Una ruta absoluta tiene una barra al principio (ej. `/site/index`), +mientras que una ruta relativa no la tiene (ej. `site/index` o `index`). Una ruta relativa se convertirá en una ruta absoluta siguiendo las siguientes normas: - Si la ruta es una cadena vacía, se usará la [[\yii\web\Controller::route|route]] actual; -- Si la ruta no contiene barras (p. ej. `index`), se considerará que es el ID de una acción del controlador actual y +- Si la ruta no contiene barras (ej. `index`), se considerará que es el ID de una acción del controlador actual y se antepondrá con [[\yii\web\Controller::uniqueId]]; -- Si la ruta no tiene barra inicial (p. ej. `site/index`), se considerará que es una ruta relativa del modulo actual y +- Si la ruta no tiene barra inicial (ej. `site/index`), se considerará que es una ruta relativa del modulo actual y se le antepondrá el [[\yii\base\Module::uniqueId|uniqueId]] del modulo. A continuación se muestran varios ejemplos del uso de este método: @@ -79,21 +79,21 @@ echo Url::toRoute('site/index', true); echo Url::toRoute('site/index', 'https'); ``` -El otro método `Url::to()` es muy similar a [[toRoute()]]. La única diferencia es que este método requiere que la ruta +El otro método `Url::to()` es muy similar a [[toRoute()]]. La única diferencia es que este método requiere que la ruta especificada sea un array. Si se pasa una cadena de texto, se tratara como una URL. El primer argumento puede ser: -- un array: se llamará a [[toRoute()]] para generar la URL. Por ejemplo: `['site/index']`, - `['post/index', 'page' => 2]`. Se puede revisar [[toRoute()]] para obtener más detalles acerca de como especificar +- un array: se llamará a [[toRoute()]] para generar la URL. Por ejemplo: `['site/index']`, + `['post/index', 'page' => 2]`. Se puede revisar [[toRoute()]] para obtener más detalles acerca de como especificar una ruta. -- una cadena que empiece por `@`: se tratará como un alias, y se devolverá la cadena correspondiente asociada a este +- una cadena que empiece por `@`: se tratará como un alias, y se devolverá la cadena correspondiente asociada a este alias. - una cadena vacía: se devolverá la URL de la petición actual; - una cadena de texto: se devolverá sin alteraciones. -Cuando se especifique `$schema` (tanto una cadena de text como `true`), se devolverá una URL con información del host -(obtenida mediante [[\yii\web\UrlManager::hostInfo]]). Si `$url` ya es una URL absoluta, su esquema se reemplazará con +Cuando se especifique `$schema` (tanto una cadena de text como `true`), se devolverá una URL con información del host +(obtenida mediante [[\yii\web\UrlManager::hostInfo]]). Si `$url` ya es una URL absoluta, su esquema se reemplazará con el especificado. A continuación se muestran algunos ejemplos de uso: @@ -124,7 +124,7 @@ echo Url::to('@web/images/logo.gif', 'https'); Recordar la URL para utilizarla más adelante -------------------------------------------- -Hay casos en que se necesita recordar la URL y después usarla durante el procesamiento de una de las peticiones +Hay casos en que se necesita recordar la URL y después usarla durante el procesamiento de una de las peticiones secuenciales. Se puede logar de la siguiente manera: ```php @@ -148,7 +148,7 @@ $productUrl = Url::previous('product'); Reconocer la relatividad de URLs -------------------------------- -Para descubrir si una URL es relativa, es decir, que no contenga información del host, se puede utilizar el siguiente +Para descubrir si una URL es relativa, es decir, que no contenga información del host, se puede utilizar el siguiente código: ```php diff --git a/docs/guide-es/images/start-gii-crud-preview.png b/docs/guide-es/images/start-gii-crud-preview.png new file mode 100644 index 0000000..85c2355 Binary files /dev/null and b/docs/guide-es/images/start-gii-crud-preview.png differ diff --git a/docs/guide-es/images/start-gii-crud.png b/docs/guide-es/images/start-gii-crud.png index a3aa21b..77c1ada 100644 Binary files a/docs/guide-es/images/start-gii-crud.png and b/docs/guide-es/images/start-gii-crud.png differ diff --git a/docs/guide-es/intro-upgrade-from-v1.md b/docs/guide-es/intro-upgrade-from-v1.md index 8d9bb8b..bcb4df3 100644 --- a/docs/guide-es/intro-upgrade-from-v1.md +++ b/docs/guide-es/intro-upgrade-from-v1.md @@ -6,7 +6,7 @@ en su segunda versión. Como resultado, actualizar desde la versión 1.1 no es tan trivial como actualizar entre versiones menores. En esta guía encontrarás las diferencias más grandes entre estas dos versiones. -Si no has utilizado Yii 1.1 antes, puedes saltar con seguridad esta sección e ir directamente a "[Comenzando con Yii](start-installation.md)". +Si no has utilizado Yii 1.1 antes, puedes saltarte con seguridad esta sección e ir directamente a "[Comenzando con Yii](start-installation.md)". Es importante anotar que Yii 2.0 introduce más características de las que van a ser cubiertas en este resumen. Es altamente recomendado que leas a través de toda la guía definitiva para aprender acerca de todas ellas. Hay muchas posibilidades de que algo que hayas desarrollado anteriormente para extender Yii, sea ahora parte del núcleo de la librería. @@ -18,7 +18,7 @@ Instalación Yii 2.0 adopta íntegramente [Composer](https://getcomposer.org/), el administrador de paquetes de facto de PHP. Tanto la instalación del núcleo del framework como las extensiones se manejan a través de Composer. Por favor consulta la sección [Comenzando con la Aplicación Básica](start-installation.md) para aprender a instalar Yii 2.0. Si quieres crear extensiones -o transformar extensiones de Yii 1.1 para que sean compatibles con Yii 2.0, consulta la sección [Creando Extensiones](extend-creating-extensions.md) de la guía. +o transformar extensiones de Yii 1.1 para que sean compatibles con Yii 2.0, consulta la sección [Creando Extensiones](structure-extensions.md#creating-extensions) de la guía. Requerimientos de PHP @@ -30,13 +30,13 @@ Abajo hay un resumen de los mayores cambios en relación a PHP: - [Namespaces](http://php.net/manual/es/language.namespaces.php). - [Funciones anónimas](http://php.net/manual/es/functions.anonymous.php). -- Sintáxis cortas de Arrays `[...elementos...]` es utilizado en vez de `array(...elementos...)`. +- La sintaxis corta de Arrays `[...elementos...]` es utilizada en vez de `array(...elementos...)`. - Etiquetas cortas de `echo`. Ahora en las vistas se usa `on($eventName, $handler); Hay muchas mejoras en lo que respecta a eventos. Para más detalles, consulta la sección [Eventos](concept-events.md). -Path Alias ----------- +Alias +----- -Yii 2.0 extiende el uso de path alias tanto para archivos/directorios como URLs. Yii 2.0 ahora requiere que cada +Yii 2.0 extiende el uso de alias tanto para archivos/directorios como URLs. Yii 2.0 ahora requiere que cada alias comience con el carácter `@`, para diferenciarlos de rutas o URLs normales. -Por ejemplo, el alias `@yii` corresponde al directorio donde Yii se encuentra instalado. Los path alias +Por ejemplo, el alias `@yii` corresponde al directorio donde Yii se encuentra instalado. Los alias están soportados en la mayor parte del núcleo. Por ejemplo, [[yii\caching\FileCache::cachePath]] puede tomar tanto una ruta de directorios normal como un alias. -Un path alias está relacionado de cerca con un namespace. Se recomienda definir un path alias +Un alias está estrechamente relacionado con un namespace de la clase. Se recomienda definir un alias por cada namespace raíz, y así poder utilizar el autolader de Yii sin otra configuración. Por ejemplo, debido a que `@yii` se refiere al directorio de instalación, una clase como `yii\web\Request` puede ser auto-cargada. Si estás utilizando una librería de terceros, -como Zend Framework, puedes definir un path alias `@Zend` que se refiera al directorio de instalación +como Zend Framework, puedes definir un alias `@Zend` que se refiera al directorio de instalación de ese framework. Una vez realizado esto, Yii será capaz de auto-cargar cualquier clase de Zend Framework también. -Se puede encontrar más detalles del tema en la sección [Path Alias](concept-aliases.md). +Se puede encontrar más detalles del tema en la sección [Alias](concept-aliases.md). Vistas ------ -El cambio más significativo con respecto a las vistas en Yii 2 es que la variable especial `$this` (dentro de una vista) +El cambio más significativo con respecto a las vistas en Yii 2 es que la variable especial `$this` dentro de una vista ya no se refiere al controlador o widget actual. En vez de eso, `$this` ahora se refiere al objeto de la *vista*, un concepto nuevo introducido en Yii 2.0. -El objeto *vista* es del tipo [[yii\web\View]], que representa la parte de las vistas en el patrón MVC. -of the MVC pattern. Si quieres acceder al controlador o al widget correspondiente desde la propia vista, +El objeto *vista* es del tipo [[yii\web\View]], que representa la parte de las vistas en el patrón MVC. Si +quieres acceder al controlador o al widget correspondiente desde la propia vista, puedes utilizar `$this->context`. Para renderizar una vista parcial (partial) dentro de otra vista, se utiliza `$this->render()`, no `$this->renderPartial()`. @@ -179,10 +179,10 @@ Modelos ------- Yii 2.0 utiliza [[yii\base\Model]] como modelo base, algo similar a `CModel` en 1.1. -La clase `CFormModel` ha sido descartada por completo. Ahora, en Yii 2 debes extender [[yii\base\Model]] para crear clases de modelos. +La clase `CFormModel` ha sido descartada por completo. Ahora, en Yii 2 debes extender de [[yii\base\Model]] para crear clases de modelos basados en formularios. Yii 2.0 introduce un nuevo método llamado [[yii\base\Model::scenarios()|scenarios()]] para declarar escenarios soportados, -y para indicar bajo qué escenario un atributo necesita ser validado, puede ser considerado seguro o no, etc. Por ejemplo: +y para indicar bajo que escenario un atributo necesita ser validado, puede ser considerado seguro o no, etc. Por ejemplo: ```php public function scenarios() @@ -204,7 +204,7 @@ Ten en cuenta que dada la introducción de [[yii\base\Model::scenarios()|scenari En la mayoría de los casos, no necesitas sobrescribir [[yii\base\Model::scenarios()|scenarios()]] si el método [[yii\base\Model::rules()|rules()]] especifica completamente los escenarios que existirán, y si no hay necesidad de declarar atributos inseguros (`unsafe`). -Para aprender más detalles de modelos, consulta la sección [Modelos](basic-models.md). +Para aprender más detalles de modelos, consulta la sección [Modelos](structure-models.md). Controladores @@ -228,7 +228,7 @@ public function actionView($id) } ``` -Por favor, consulta la sección [Controllers](structure-controllers.md) para más detalles acerca de los controladores. +Por favor, consulta la sección [Controladores](structure-controllers.md) para más detalles acerca de los controladores. Widgets @@ -236,7 +236,7 @@ Widgets Yii 2.0 utiliza [[yii\base\Widget]] como clase base de los widgets, similar a `CWidget` en Yii 1.1. -Para obtener mejor soporte del framework en IDEs, Yii 2.0 introduce una nueva sintáxis para utilizar widgets. +Para obtener mejor soporte del framework en IDEs, Yii 2.0 introduce una nueva sintaxis para utilizar widgets. Los métodos estáticos [[yii\base\Widget::begin()|begin()]], [[yii\base\Widget::end()|end()]], y [[yii\base\Widget::widget()|widget()]] fueron incorporados, y deben utilizarse así: @@ -259,19 +259,19 @@ ActiveForm::end(); Consulta la sección [Widgets](structure-widgets.md) para más detalles. -Themes +Temas ------ -Los themes funcionan completamente diferente en Yii 2.0. Ahora están basados en un mecanismo de mapeo de rutas, -que mapea la ruta de un archivo vista de origen a uno con un theme aplicado. Por ejemplo, si el path map de un theme es -`['/web/views' => '/web/themes/basic']`, entonces la versión con el theme aplicado del archivo -`/web/views/site/index.php` será `/web/themes/basic/site/index.php`. Por esta razón, ahora los themes pueden ser -aplicados a cualquier archivo de vista, incluso una vista renderizada fuera del contexto de un controlador o widget. +Los temas funcionan completamente diferente en Yii 2.0. Ahora están basados en un mecanismo de mapeo de rutas, +que mapea la ruta de un archivo de la vista de origen a uno con un tema aplicado. Por ejemplo, si el mapeo de ruta de un tema es +`['/web/views' => '/web/themes/basic']`, entonces la versión con el tema aplicado del archivo +`/web/views/site/index.php` será `/web/themes/basic/site/index.php`. Por esta razón, ahora los temas pueden ser +aplicados a cualquier archivo de la vista, incluso una vista renderizada fuera del contexto de un controlador o widget. Además, el componente `CThemeManager` ya no existe. En cambio, `theme` es una propiedad configurable del componente `view` de la aplicación. -Consulta la sección [Utilizando Themes](tutorial-theming.md) para más detalles. +Consulta la sección [Temas](output-theming.md) para más detalles. Aplicaciones de Consola @@ -304,7 +304,7 @@ Por favor, consulta la sección [Internacionalización](tutorial-i18n.md) para m Filtros de Acciones ------------------- -En Yii 2.0, los filtros de acciones son implementados a través de comportamientos (behaviors). Para definir un +Los filtros de acciones son implementados a través de comportamientos. Para definir un nuevo filtro personalizado, se debe extender de [[yii\base\ActionFilter]]. Para utilizar el filtro, conecta la clase del filtro al controlador como un comportamiento. Por ejemplo, para utilizar el filtro [[yii\filters\AccessControl]], deberías tener el siguiente código en el controlador: @@ -331,13 +331,13 @@ Assets Yii 2.0 introduce un nuevo concepto llamado *asset bundle* que reemplaza el concepto de script package encontrado en Yii 1.1. -Un asset bundle es una colección de assets (ej. archivos JavaScript, archivos CSS, imágenes, etc.) dentro de un directorio. -Cada asset bundle está representada por una clase que extiende de [[yii\web\AssetBundle]]. +Un asset bundle es una colección de archivos assets (ej. archivos JavaScript, archivos CSS, imágenes, etc.) dentro de un directorio. +Cada asset bundle está representado por una clase que extiende de [[yii\web\AssetBundle]]. Al registrar un asset bundle a través de [[yii\web\AssetBundle::register()]], haces que los assets de dicho bundle sean accesibles vía Web. A diferencia de Yii 1, la página que registra el bundle contendrá automáticamente las referencias a los archivos JavaScript y CSS especificados en el bundle. -Por favor, consulta la sección [Manejando Assets](output-assets.md) para más detalles. +Por favor, consulta la sección [Manejando Assets](structure-assets.md) para más detalles. Helpers @@ -356,10 +356,10 @@ Por favor, consulta la sección [Información General de Helpers](helper-overvie Formularios ----------- -Yii 2.0 introduce el concepto de *campo* (field) para construir formularios utilizando [[yii\widgets\ActiveForm]]. Un campo (field) +Yii 2.0 introduce el concepto de *campo* (field) para construir formularios utilizando [[yii\widgets\ActiveForm]]. Un campo es un contenedor que consiste en una etiqueta, un input, un mensaje de error y/o texto de ayuda. Un campo es representado como un objeto [[yii\widgets\ActiveField|ActiveField]]. -Utilizando estos campos, puedes crear formularios más claramente que antes: +Utilizando estos campos, puedes crear formularios más legibles que antes: ```php @@ -374,12 +374,12 @@ Utilizando estos campos, puedes crear formularios más claramente que antes: Por favor, consulta la sección [Creando Formularios](input-forms.md) para más detalles. -Query Builder -------------- +Constructor de Consultas +------------------------ En Yii 1.1, la generación de consultas a la base de datos estaba dividida en varias clases, incluyendo `CDbCommand`, `CDbCriteria`, y `CDbCommandBuilder`. Yii 2.0 representa una consulta a la base de datos en términos de un objeto [[yii\db\Query|Query]] -que puede ser convertido en una declaración SQL con la ayuda de [[yii\db\QueryBuilder|QueryBuilder]] detrás de escena. +que puede ser convertido en una declaración SQL con la ayuda de [[yii\db\QueryBuilder|QueryBuilder]] detrás de la escena. Por ejemplo: ```php @@ -395,7 +395,7 @@ $rows = $command->queryAll(); Lo mejor de todo, dichos métodos de generación de consultas pueden ser también utilizados mientras se trabaja con [Active Record](db-active-record.md). -Consulta la sección [Query Builder](db-query-builder.md) para más detalles. +Consulta la sección [Constructor de Consultas](db-query-builder.md) para más detalles. Active Record @@ -409,7 +409,7 @@ y por lo tanto hereda todos los métodos de generación de consultas. Para comenzar a generar una consulta, llamas al método [[yii\db\ActiveRecord::find()]]: ```php -// Para traer todos los clientes *activos* y ordenarlos por su ID: +// Recibe todos los clientes *activos* y ordenados por su ID: $customers = Customer::find() ->where(['status' => $active]) ->orderBy('id') @@ -431,27 +431,27 @@ class Customer extends \yii\db\ActiveRecord ``` Ahora puedes utilizar `$customer->orders` para acceder a las órdenes de la tabla relacionada. También puedes utilizar el siguiente -código para realizar una consulta 'al-vuelo' relacionada con una condición personalizada: +código para realizar una consulta relacional 'al-vuelo' con una condición personalizada: ```php $orders = $customer->getOrders()->andWhere('status=1')->all(); ``` -Cuando se utiliza la carga temprana de la relación, Yii 2.0 lo hace diferente de 1.1. En particular, en 1.1 una declaración JOIN +Cuando se utiliza la carga temprana (eager loading) de la relación, Yii 2.0 lo hace diferente de 1.1. En particular, en 1.1 una declaración JOIN sería creada para seleccionar tanto los registros de la tabla primaria como los relacionados. En Yii 2.0, dos declaraciones SQL son ejecutadas -sin utilizar un JOIN: la primera traer todos los modelos primarios, mientras que la segunda trae los registros relacionados +sin utilizar un JOIN: la primera trae todos los modelos primarios, mientras que la segunda trae los registros relacionados utilizando como condición la clave primaria de los primarios. En vez de devolver objetos [[yii\db\ActiveRecord|ActiveRecord]], puedes conectar el método [[yii\db\ActiveQuery::asArray()|asArray()]] mientras generas una consulta que devuelve un gran número de registros. Esto causará que el resultado de la consulta sea devuelto como -matrices (arrays), lo que puede reducir significativamente la necesidad de tiempo de CPU y memoria si el número de registros es grande. +arrays, lo que puede reducir significativamente la necesidad de tiempo de CPU y memoria si el número de registros es grande. Por ejemplo: ```php $customers = Customer::find()->asArray()->all(); ``` -Otro cambio es que ya no puedes definir valores por defecto a los atributos a través de propiedades publicas. +Otro cambio es que ya no puedes definir valores por defecto a los atributos a través de propiedades públicas. Si lo necesitaras, debes definirlo en el método `init` de la clase del registro en cuestión. ```php @@ -469,21 +469,51 @@ Hay muchos otros cambios y mejoras con respecto a ActiveRecord. Por favor, consu la sección [Active Record](db-active-record.md) para más detalles. +Active Record Behaviors +----------------------- + +En 2.0, hemos eliminado la clase del comportamiento base `CActiveRecordBehavior`. Si desea crear un comportamiento Active Record, usted tendrá que extender directamente de `yii\base\Behavior`. Si la clase de comportamiento debe responder a algunos eventos propios, usted tiene que sobrescribir los métodos `events()` como se muestra a continuación, + +```php +namespace app\components; + +use yii\db\ActiveRecord; +use yii\base\Behavior; + +class MyBehavior extends Behavior +{ + // ... + + public function events() + { + return [ + ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate', + ]; + } + + public function beforeValidate($event) + { + // ... + } +} +``` + + User e IdentityInterface ------------------------ La clase `CWebUser` de 1.1 es reemplazada por [[yii\web\User]], y la clase `CUserIdentity` ha dejado de existir. -En cambio, ahora debes implementar [[yii\web\IdentityInterface]] lo que es mucho más directo para usar. -El template de Aplicación Avanzada provee un ejemplo así. +En cambio, ahora debes implementar [[yii\web\IdentityInterface]] el cual es mucho más directo de usar. +La plantilla de Aplicación Avanzada provee un ejemplo así. -Consulta las secciones [Autenticación](security-authentication.md), [Autorización](security-authorization.md), y [Template de Aplicación Avanzanda](tutorial-advanced-app.md) para más detalles. +Consulta las secciones [Autenticación](security-authentication.md), [Autorización](security-authorization.md), y [Plantilla de Aplicación Avanzada](tutorial-advanced-app.md) para más detalles. Manejo de URLs -------------- El manejo de URLs en Yii 2 es similar al de 1.1. Una mejora mayor es que el manejador actual ahora soporta parámetros opcionales. -Por ejemplo, si tienes una regla declarada como a continuación, entonces coincidirá tanto con `post/popular` como `post/1/popular`. +Por ejemplo, si tienes una regla declarada como a continuación, entonces coincidirá tanto con `post/popular` como con `post/1/popular`. En 1.1, tendrías que haber creado dos reglas diferentes para obtener el mismo resultado ```php @@ -494,11 +524,11 @@ En 1.1, tendrías que haber creado dos reglas diferentes para obtener el mismo r ] ``` -Por favor, consulta la sección [Documentación del Manejo de URLs](url.md) para más detalles. +Por favor, consulta la sección [Documentación del Manejo de URLs](runtime-routing.md) para más detalles. Utilizando Yii 1.1 y 2.x juntos ------------------------------- Si tienes código en Yii 1.1 que quisieras utilizar junto con Yii 2.0, por favor consulta -la sección [Using Yii 1.1 and 2.0 Together](extend-using-v1-v2.md). +la sección [Utilizando Yii 1.1 y 2.0 juntos](tutorial-yii-integration.md). diff --git a/docs/guide-es/intro-yii.md b/docs/guide-es/intro-yii.md index 453eb4b..495aba0 100644 --- a/docs/guide-es/intro-yii.md +++ b/docs/guide-es/intro-yii.md @@ -1,50 +1,52 @@ ¿Qué es Yii? ============ -Yii es un marco de programación del lenguaje PHP de alto rendimiento, basado en componentes para desarrollar aplicaciones web -modernas en poco tiempo. El nombre Yii significa "simple y evolutivo" en chino; también se puede considerar como un acrónimo +Yii es un framework de PHP de alto rendimiento, basado en componentes para desarrollar aplicaciones web +modernas en poco tiempo. El nombre Yii significa "simple y evolutivo" en chino. También se puede considerar como un acrónimo de _**Yes It Is**_ (que en inglés significa _**Sí, eso es**_)! ¿En qué es mejor Yii? ----------------------- -Yii es un marco genérico de programación web, lo que significa que se puede utilizar para desarrollar todo tipo de aplicaciones web en PHP. -Debido a su arquitectura basada en componentes y a su sofisticada compatibilidad de caché, es especialmente apropiado para el desarrollo -de aplicaciones de gran envergadura, como portales, foros, sistemas de gestión de contenidos (CMS), proyectos de comercio electrónico, +Yii es un framework genérico de programación web, lo que significa que se puede utilizar para desarrollar todo tipo de aplicaciones web en PHP. +Debido a su arquitectura basada en componentes y a su sofisticada compatibilidad de caché, es especialmente apropiado para el desarrollo +de aplicaciones de gran envergadura, como portales, foros, sistemas de gestión de contenidos (CMS), proyectos de comercio electrónico, servicios web compatibles con la arquitectura REST y muchas más. -¿Cómo se compara Yii con otros marcos? +¿Cómo se compara Yii con otros frameworks? -------------------------------------- -- Como la mayoría de los marcos de PHP, Yii implementa el patrón de diseño MVC (Modelo-Vista-Controlador) y promueve la organización de código basada en este patrón. +Si estás familiarizado con otros framework, puedes apreciar como se compara Yii con ellos: + +- Como la mayoría de los framework de PHP, Yii implementa el patrón de diseño MVC (Modelo-Vista-Controlador) y promueve la organización de código basada en este patrón. - La filosofía de Yii consiste en escribir el código de manera simple y elegante, sin sobrediseñar nunca por el mero hecho de seguir un patrón de diseño determinado. -- Yii es un marco completo que provee muchas características probadas y listas para usar, como los constructores de consultas y la clase ActiveRecord para las bases de datos relacionales y NoSQL, la compatibilidad con la arquitectura REST para desarrollar API, la compatibilidad de caché en varios niveles y muchas más. -- Yii es extremadamente extensible; se puede personalizar o reemplazar prácticamente cualquier pieza de código de base, como se puede también aprovechar su sólida arquitectura de extensiones para utilizar o desarrollar extensiones distribuibles. +- Yii es un framework completo que provee muchas características probadas y listas para usar, como los constructores de consultas y la clase ActiveRecord para las bases de datos relacionales y NoSQL, la compatibilidad con la arquitectura REST para desarrollar API, la compatibilidad de caché en varios niveles y muchas más. +- Yii es extremadamente extensible. Puedes personalizar o reemplazar prácticamente cualquier pieza de código de base, como se puede también aprovechar su sólida arquitectura de extensiones para utilizar o desarrollar extensiones distribuibles. - El alto rendimiento es siempre la meta principal de Yii. -Detrás de Yii hay un [sólido equipo de desarrollo][], así como una gran comunidad en la que numerosos profesionales contribuyen constantemente a su desarrollo. -El equipo de desarrollo de Yii se mantiene atento a las últimas tendencias de desarrollo web, así como a las mejores prácticas y características de otros marcos y proyectos. -Las buenas prácticas más relevantes de otros proyectos se incorporan regularmente a la base del marco y se exponen a través de interfaces simples y elegantes. +Yii no es un proyecto de un sola persona, detrás de Yii hay un [sólido equipo de desarrollo][about_yii], así como una gran comunidad en la que numerosos profesionales contribuyen constantemente a su desarrollo. +El equipo de desarrollo de Yii se mantiene atento a las últimas tendencias de desarrollo web, así como a las mejores prácticas y características de otros frameworks y proyectos. +Las buenas prácticas y características más relevantes de otros proyectos se incorporan regularmente a la base del framework y se exponen a través de interfaces simples y elegantes. -[sólido equipo de desarrollo]: http://www.yiiframework.com/about/ +[about_yii]: http://www.yiiframework.com/about/ Versiones de Yii ---------------- -Actualmente existen dos versiones principales de Yii: la versión 1.1 y la versión 2.0. Para la versión 1.1, que es de la generación anterior, actualmente solo se ofrece mantenimiento. -La versión 2.0 está completamente reescrita y adopta las últimas tecnologías y protocolos, incluidos Composer, PSR, espacio de nombres, rasgos, etc. -Esta versión representa la última generación del marco y su desarrollo recibirá nuestro principal esfuerzo en los próximos años. -Esta guía está basada principalmente en la versión 2.0 del marco. +Actualmente existen dos versiones principales de Yii: la versión 1.1 y la versión 2.0. Para la versión 1.1, que es de la generación anterior, actualmente solo se ofrece mantenimiento. +La versión 2.0 está completamente reescrita y adopta las últimas tecnologías y protocolos, incluidos Composer, PSR, namespaces, traits, etc. +La versión 2.0 representa la actual generación del framework y su desarrollo recibirá el principal esfuerzo en los próximos años. +Esta guía está basada principalmente en la versión 2.0. del framework. Requisitos ----------- -Yii 2.0 requiere PHP 5.4.0 o una versión posterior. Se pueden encontrar requisitos más detallados de características individuales -ejecutando el programa de comprobación incluido en cada lanzamiento de Yii. +Yii 2.0 requiere PHP 5.4.0 o una versión posterior. Se pueden encontrar requisitos más detallados de características individuales +ejecutando el script de comprobación incluido en cada release de Yii. -Para utilizar Yii se requieren conocimientos básicos de programación orientada a objetos (POO), porque el marco Yii se basa íntegramente en esta tecnología. -Yii 2.0 hace uso también de las últimas características de PHP, como [espacios de nombres](http://www.php.net/manual/en/language.namespaces.php) -y [rasgos](http://www.php.net/manual/en/language.oop5.traits.php). Comprender estos conceptos ayuda a entender Yii 2.0. +Para utilizar Yii se requieren conocimientos básicos de programación orientada a objetos (POO), porque el framework Yii se basa íntegramente en esta tecnología. +Yii 2.0 hace uso también de las últimas características de PHP, como [namespaces](http://www.php.net/manual/es/language.namespaces.php) +y [traits](http://www.php.net/manual/es/language.oop5.traits.php). Comprender estos conceptos te ayudará a entender mejor Yii 2.0. diff --git a/docs/guide-es/output-theming.md b/docs/guide-es/output-theming.md new file mode 100644 index 0000000..18a7d45 --- /dev/null +++ b/docs/guide-es/output-theming.md @@ -0,0 +1,99 @@ +Temas +===== + +> Nota: Esta sección está en desarrollo. + +Un tema (theme) es un directorio de archivos y de vistas (views) y layouts. Cada archivo de este directorio +sobrescribe el archivo correspondiente de una aplicación cuando se renderiza. Una única aplicación puede usar +múltiples temas para que pueden proporcionar experiencias totalmente diferentes. Solo se puede haber un único tema +activo. + +> Nota: Los temas no están destinados a ser redistribuidos ya que están demasiado ligados a la aplicación. Si se + quiere redistribuir una apariencia personalizada, se puede considerar la opción de + [asset bundles](structure-assets.md) de archivos CSS y Javascript. + +Configuración de un Tema +------------------------ + +La configuración de un tema se especifica a través del componente `view` de la aplicación. Para establecer que un tema +trabaje con vistas de aplicación básicas, la configuración de la aplicación debe contener lo siguiente: + +```php +'components' => [ + 'view' => [ + 'theme' => [ + 'pathMap' => ['@app/views' => '@app/themes/basic'], + 'baseUrl' => '@web/themes/basic', + ], + ], +], +``` + +En el ejemplo anterior, el `pathMap` define un mapa (map) de las rutas a las que se aplicará el tema mientras que +`baseUrl` define la URL base para los recursos a los que hacen referencia los archivos del tema. + +En nuestro caso `pathMap` es `['@app/views' => '@app/themes/basic']`. Esto significa que cada vista de `@app/views` +primero se buscará en `@app/themes/basic` y si existe, se usará la vista del directorio del tema en lugar de la vista +original. + +Por ejemplo, con la configuración anterior, la versión del tema para la vista `@app/views/site/index.php` será +`@app/themes/basic/site/index.php`. Básicamente se reemplaza `@app/views` en `@app/views/site/index.php` por +`@app/themes/basic`. + +### Temas para Módulos + +Para utilizar temas en los módulos, el `pathMap` debe ser similar al siguiente: + +```php +'components' => [ + 'view' => [ + 'theme' => [ + 'pathMap' => [ + '@app/views' => '@app/themes/basic', + '@app/modules' => '@app/themes/basic/modules', // <-- !!! + ], + ], + ], +], +``` + +Esto permite aplicar el tema a `@app/modules/blog/views/comment/index.php` con la vista +`@app/themes/basic/modules/blog/views/comment/index.php`. + +### Temas para Widgets + +Para utilizar un tema en una vista que se encuentre en `@app/widgets/currency/views/index.php`, se debe aplicar la +siguiente configuración para el componente vista, tema: + +```php +'components' => [ + 'view' => [ + 'theme' => [ + 'pathMap' => ['@app/widgets' => '@app/themes/basic/widgets'], + ], + ], +], +``` + +Con la configuración anterior, se puede crear una versión de la vista `@app/widgets/currency/index.php` para que se +aplique el tema en `@app/themes/basic/widgets/currency/index.php`. + +Uso de Multiples Rutas +---------------------- + +Es posible mapear una única ruta a múltiples rutas de temas. Por ejemplo: + +```php +'pathMap' => [ + '@app/views' => [ + '@app/themes/christmas', + '@app/themes/basic', + ], +] +``` + +En este caso, primero se buscara la vista en `@app/themes/christmas/site/index.php`, si no se encuentra, se intentará +en `@app/themes/basic/site/index.php`. Si la vista no se encuentra en ninguna de rutas especificadas, se usará la +vista de aplicación. + +Esta capacidad es especialmente útil si se quieren sobrescribir algunas rutas temporal o condicionalmente. \ No newline at end of file diff --git a/docs/guide-es/rest-authentication.md b/docs/guide-es/rest-authentication.md index ce046ff..d97036e 100644 --- a/docs/guide-es/rest-authentication.md +++ b/docs/guide-es/rest-authentication.md @@ -111,7 +111,7 @@ y entonces ejecutar la acción. La identidad del usuario autenticado puede ser r Si la autenticación falla, una respuesta con estado HTTP 401 será devuelta junto con otras cabeceras apropiadas (tal como la cabecera para autenticación básica HTTP `WWW-Authenticate`). -## Autorización +## Autorización Después de que un usuario se ha autenticado, probablementer querrás comprobar si él o ella tiene los permisos para realizar la acción solicitada. Este proceso es llamado *autorización (authorization)* y está cubierto en detalle en la [Sección de Autorización](security-authorization.md). diff --git a/docs/guide-es/rest-controllers.md b/docs/guide-es/rest-controllers.md index b16c9f8..1177cda 100644 --- a/docs/guide-es/rest-controllers.md +++ b/docs/guide-es/rest-controllers.md @@ -25,7 +25,7 @@ algunas de las cuales se describen en detalle en las siguientes secciones: * La autorización del usuario de acuerdo a la acción y recurso solicitado. -## Creando Clases de Controlador +## Creando Clases de Controlador Al crear una nueva clase de controlador, una convención para nombrar la clase del controlador es utilizar el nombre del tipo de recurso en singular. Por ejemplo, para servir información de usuario, @@ -45,7 +45,7 @@ public function actionView($id) ``` -## Filtros +## Filtros La mayoría de las características API REST son proporcionadas por [[yii\rest\Controller]] son implementadas en los términos de [filtros](structure-filters.md). En particular, los siguientes filtros se ejecutarán en el orden en que aparecen: @@ -76,14 +76,14 @@ public function behaviors() ``` -## Extendiendo `ActiveController` +## Extendiendo `ActiveController` Si tu clase controlador extiende de [[yii\rest\ActiveController]], debe establecer su propiedad [[yii\rest\ActiveController::modelClass||modelClass]] con el nombre de la clase del recurso que planeas servir a través de este controlador. La clase debe extender de [[yii\db\ActiveRecord]]. -### Personalizando Acciones +### Personalizando Acciones Por defecto, [[yii\rest\ActiveController]] provee de las siguientes acciones: @@ -120,7 +120,7 @@ public function prepareDataProvider() Por favor, consulta las referencias de clases de acciones individuales para aprender las opciones de configuración disponibles para cada una. -### Realizando Comprobación de Acceso +### Realizando Comprobación de Acceso Al exponer los recursos a través de RESTful APIs, a menudo es necesario comprobar si el usuario actual tiene permiso para acceder y manipular el/los recurso solicitado/s. Con [[yii\rest\ActiveController]], esto puede lograrse diff --git a/docs/guide-es/rest-error-handling.md b/docs/guide-es/rest-error-handling.md index a8b1dda..092a6ab 100644 --- a/docs/guide-es/rest-error-handling.md +++ b/docs/guide-es/rest-error-handling.md @@ -40,7 +40,7 @@ La siguiente lista sumariza los códigos de estado HTTP que son usados por el fr * `500`: Error interno del servidor. Esto puede estar causado por errores internos del programa. -## Personalizando la Respuesta al Error +## Personalizando la Respuesta al Error A veces puedes querer personalizar el formato de la respuesta del error por defecto . Por ejemplo, en lugar de depender del uso de diferentes estados HTTP para indicar los diferentes errores, puedes querer usar siempre el estado HTTP 200 diff --git a/docs/guide-es/rest-quick-start.md b/docs/guide-es/rest-quick-start.md index c4f385c..836292f 100644 --- a/docs/guide-es/rest-quick-start.md +++ b/docs/guide-es/rest-quick-start.md @@ -23,7 +23,7 @@ Supongamos que deseas exponer los datos de los usuarios vía APIs RESTful. Los d y ya tienes creado la clase [[yii\db\ActiveRecord|ActiveRecord]] `app\models\User` para acceder a los datos del usuario. -## Creando un controlador +## Creando un controlador Primero, crea una clase controladora `app\controllers\UserController` como la siguiente, @@ -42,7 +42,7 @@ La clase controladora extiende de [[yii\rest\ActiveController]]. Especificado po como `app\models\User`, el controlador sabe que modelo puede ser usado para recoger y manipular sus datos. -## Configurando las reglas de las URL +## Configurando las reglas de las URL A continuación, modifica la configuración del componente `urlManager` en la configuración de tu aplicación: @@ -61,7 +61,7 @@ La configuración anterior principalmente añade una regla URL para el controlad que los datos de user pueden ser accedidos y manipulados con URLs amigables y verbos HTTP significativos. -## Habilitando entradas JSON +## Habilitando entradas JSON Para permitir que la API acepte datos de entrada con formato JSON, configura la propiedad [[yii\web\Request::$parsers|parsers]] del componente de aplicación `request` para usar [[yii\web\JsonParser]] para entradas JSON: @@ -78,7 +78,7 @@ del componente de aplicación `request` para usar [[yii\web\JsonParser]] para en `application/x-www-form-urlencoded` y `multipart/form-data` como formatos de entrada. -## Probándolo +## Probándolo Con la mínima cantidad de esfuerzo, tienes ya finalizado tu tarea de crear las APIs RESTful para acceder a los datos de user. Las APIs que tienes creado incluyen: @@ -188,7 +188,7 @@ Por ejemplo, la URL `http://localhost/users?fields=id,email` sólo devolverá lo > Puedes y deberías filtrar estos campos como se describe en la sección [Response Formatting](rest-response-formatting.md). -## Resumen +## Resumen Utilizando el framework Yii API RESTful, implementa un punto final API en términos de una acción de un controlador, y utiliza un controlador para organizar las acciones que implementan los puntos finales para un sólo tipo de recurso. diff --git a/docs/guide-es/rest-resources.md b/docs/guide-es/rest-resources.md index a0785ce..3d8979e 100644 --- a/docs/guide-es/rest-resources.md +++ b/docs/guide-es/rest-resources.md @@ -12,7 +12,7 @@ Mientras que no hay restricción a cómo representar un recurso, en YII usualmen En esta sección, vamos principalmente a describir como la clase con recursos que extiende de [[yii\base\Model]] (o sus clases hijas) puede especificar qué datos puede ser devueltos vía las APIs RESTful. Si la clase de los recursos no extiende de [[yii\base\Model]], entonces todas las variables públicas miembro serán devueltas. -## Campos (fields) +## Campos (fields) Cuando incluimos un recurso en una respuesta de la API RESTful, el recurso necesita ser serializado en una cadena. Yii divide este proceso en dos pasos. Primero, el recurso es convertido en un array por [[yii\rest\Serializer]]. @@ -37,7 +37,7 @@ http://localhost/users?fields=id,email&expand=profile ``` -### Sobreescribiendo `fields()` +### Sobreescribiendo `fields()` Por defecto, [[yii\base\Model::fields()]] devuelve todos los atributos de los modelos como si fueran campos, mientras [[yii\db\ActiveRecord::fields()]] sólo devuelve los atributos que tengan datos en la base de datos. @@ -79,7 +79,7 @@ public function fields() > quitar `auth_key`, `password_hash` y `password_reset_token`. -### Sobreescribiendo `extraFields()` +### Sobreescribiendo `extraFields()` Por defecto, [[yii\base\Model::extraFields()]] no devuelve nada, mientras que [[yii\db\ActiveRecord::extraFields()]] devuelve los nombres de las relaciones que tienen datos (populated) obtenidos de la base de datos. @@ -114,7 +114,7 @@ la petición `http://localhost/users?fields=id,email&expand=profile` puede devol ``` -## Enlaces (Links) +## Enlaces (Links) [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), es una abreviación de Hipermedia es el Motor del Estado de la Aplicación (Hypermedia as the Engine of Application State), promueve que las APIs RESTfull devuelvan información que permita a los clientes descubrir las acciones que soportan los recursos devueltos. El sentido de HATEOAS es devolver un conjunto de hiperenlaces con relación a la información, cuando los datos de los recursos son servidos por las APIs. @@ -145,14 +145,16 @@ Cuando un objeto `User` es devuelto en una respuesta, puede contener un elemento "id": 100, "email": "user@example.com", // ... - "_links" => [ - "self": "https://example.com/users/100" - ] + "_links" => { + "self": { + "href": "https://example.com/users/100" + } + } } ``` -## Colecciones +## Colecciones Los objetos de los recursos pueden ser agrupados en *collections*. Cada colección contiene una lista de recursos objeto del mismo tipo. diff --git a/docs/guide-es/rest-response-formatting.md b/docs/guide-es/rest-response-formatting.md index f60db36..2b8826a 100644 --- a/docs/guide-es/rest-response-formatting.md +++ b/docs/guide-es/rest-response-formatting.md @@ -13,7 +13,7 @@ con el formato de la respuesta: componente de la aplicación [[yii\web\Response::formatters|response]]. -## Negociación de contenido (Content Negotiation) +## Negociación de contenido (Content Negotiation) Yii soporta la negociación de contenido a través del filtro [[yii\filters\ContentNegotiator]]. La clase de controlador base del API RESTful [[yii\rest\Controller]] está equipada con este filtro bajo el nombre `contentNegotiator`. @@ -81,7 +81,7 @@ Las claves de la propiedad `formats` son los tipos MIME soportados, mientras que los cuales deben ser soportados en [[yii\web\Response::formatters]]. -## Serialización de Datos +## Serialización de Datos Como hemos descrito antes, [[yii\rest\Serializer]] es la pieza central responsable de convertir objetos recurso o colecciones en arrays. Reconoce objetos tanto implementando [[yii\base\ArrayableInterface]] @@ -136,9 +136,15 @@ Content-Type: application/json; charset=UTF-8 ... ], "_links": { - "self": "http://localhost/users?page=1", - "next": "http://localhost/users?page=2", - "last": "http://localhost/users?page=50" + "self": { + "href": "http://localhost/users?page=1" + }, + "next": { + "href": "http://localhost/users?page=2" + }, + "last": { + "href": "http://localhost/users?page=50" + } }, "_meta": { "totalCount": 1000, diff --git a/docs/guide-es/runtime-handling-errors.md b/docs/guide-es/runtime-handling-errors.md index c07f137..e7cfb15 100644 --- a/docs/guide-es/runtime-handling-errors.md +++ b/docs/guide-es/runtime-handling-errors.md @@ -1,24 +1,24 @@ Gestión de Errores ================== -Yii incluye un [[yii\web\ErrorHandler|error handler]] que permite una gestión de errores mucho más práctica que +Yii incluye un [[yii\web\ErrorHandler|error handler]] que permite una gestión de errores mucho más práctica que anteriormente. En particular, el gestor de errores de Yii hace lo siguiente para mejorar la gestión de errores: -* Todos los errores no fatales (p. ej. advertencias (warning), avisos (notices)) se convierten en excepciones +* Todos los errores no fatales (ej. advertencias (warning), avisos (notices)) se convierten en excepciones capturables. -* Las excepciones y los errores fatales de PHP se muestran con una pila de llamadas (call stack) de información +* Las excepciones y los errores fatales de PHP se muestran con una pila de llamadas (call stack) de información detallada y lineas de código fuente. * Soporta el uso de [acciones de controlador](structure-controllers.md#actions) dedicadas para mostrar errores. * Soporta diferentes formatos de respuesta (response) de errores. -El [[yii\web\ErrorHandler|error handler]] esta habilitado de forma predeterminada. Se puede deshabilitar definiendo la -constante `YII_ENABLE_ERROR_HANDLER` con valor false en el +El [[yii\web\ErrorHandler|error handler]] esta habilitado de forma predeterminada. Se puede deshabilitar definiendo la +constante `YII_ENABLE_ERROR_HANDLER` con valor false en el [script de entrada (entry script)](structure-entry-scripts.md) de la aplicación. -## Uso del Gestor de Errores +## Uso del Gestor de Errores -El [[yii\web\ErrorHandler|error handler]] se registra como un -[componente de aplicación](structure-application-components.md) llamado `errorHandler`. Se puede configurar en la +El [[yii\web\ErrorHandler|error handler]] se registra como un +[componente de aplicación](structure-application-components.md) llamado `errorHandler`. Se puede configurar en la configuración de la aplicación como en el siguiente ejemplo: ```php @@ -31,10 +31,10 @@ return [ ]; ``` -Con la anterior configuración, el numero del lineas de código fuente que se mostrará en las páginas de excepciones +Con la anterior configuración, el numero del lineas de código fuente que se mostrará en las páginas de excepciones será como máximo de 20. -Como se ha mencionado, el gestor de errores convierte todos los errores de PHP no fatales en excepciones capturables. +Como se ha mencionado, el gestor de errores convierte todos los errores de PHP no fatales en excepciones capturables. Esto significa que se puede usar el siguiente código para tratar los errores PHP: ```php @@ -50,9 +50,9 @@ try { // la ejecución continua ... ``` -Si se quiere mostrar una página de error que muestra al usuario que su petición no es válida o no es la esperada, se -puede simplemente lanzar una excepción de tipo [[yii\web\HttpException|HTTP exception]], como podría ser -[[yii\web\NotFoundHttpException]]. El gestor de errores establecerá correctamente el código de estado HTTP de la +Si se quiere mostrar una página de error que muestra al usuario que su petición no es válida o no es la esperada, se +puede simplemente lanzar una excepción de tipo [[yii\web\HttpException|HTTP exception]], como podría ser +[[yii\web\NotFoundHttpException]]. El gestor de errores establecerá correctamente el código de estado HTTP de la respuesta y usará la vista de error apropiada para mostrar el mensaje. ```php @@ -61,34 +61,34 @@ use yii\web\NotFoundHttpException; throw new NotFoundHttpException(); ``` -## Personalizar la Visualización de Errores +## Personalizar la Visualización de Errores -El [[yii\web\ErrorHandler|error handler]] ajusta la visualización del error conforme al valor de la constante -`YII_DEBUG`. Cuando `YII_DEBUG` es `true` (es decir, en modo depuración (debug)), el gestor de errores mostrara las -excepciones con una pila detallada de información y con lineas de código fuente para ayudar a depurar. Y cuando la -variable `YII_DEBUG` es `false`, solo se mostrará el mensaje de error para prevenir la revelación de información +El [[yii\web\ErrorHandler|error handler]] ajusta la visualización del error conforme al valor de la constante +`YII_DEBUG`. Cuando `YII_DEBUG` es `true` (es decir, en modo depuración (debug)), el gestor de errores mostrara las +excepciones con una pila detallada de información y con lineas de código fuente para ayudar a depurar. Y cuando la +variable `YII_DEBUG` es `false`, solo se mostrará el mensaje de error para prevenir la revelación de información sensible de la aplicación. -> Información: Si una excepción es descendiente de [[yii\base\UserException]], no se mostrará la pila de llamadas - independientemente del valor de `YII_DEBUG`. Esto es debido a que se considera que estas excepciones se deben a +> Información: Si una excepción es descendiente de [[yii\base\UserException]], no se mostrará la pila de llamadas + independientemente del valor de `YII_DEBUG`. Esto es debido a que se considera que estas excepciones se deben a errores cometidos por los usuarios y los desarrolladores no necesitan corregirlas. -De forma predeterminada, el [[yii\web\ErrorHandler|error handler]] muestra los errores usando dos +De forma predeterminada, el [[yii\web\ErrorHandler|error handler]] muestra los errores usando dos [vistas](structure-views.md): -* `@yii/views/errorHandler/error.php`: se usa cuando deben mostrarse los errores SIN la información de la pila de +* `@yii/views/errorHandler/error.php`: se usa cuando deben mostrarse los errores SIN la información de la pila de llamadas. Cuando `YII_DEBUG` es falos, este es el único error que se mostrara. -* `@yii/views/errorHandler/exception.php`: se usa cuando los errores deben mostrarse CON la información de la pila de +* `@yii/views/errorHandler/exception.php`: se usa cuando los errores deben mostrarse CON la información de la pila de llamadas. -Se pueden configurar las propiedades [[yii\web\ErrorHandler::errorView|errorView]] y -[[yii\web\ErrorHandler::exceptionView|exceptionView]] el gestor de errores para usar nuestros propias vistas para +Se pueden configurar las propiedades [[yii\web\ErrorHandler::errorView|errorView]] y +[[yii\web\ErrorHandler::exceptionView|exceptionView]] el gestor de errores para usar nuestros propias vistas para personalizar la visualización de los errores. -### Uso de Acciones de Error +### Uso de Acciones de Error -Una mejor manera de personalizar la visualización de errores es usar un [acción](structure-controllers.md) de error -dedicada. Para hacerlo, primero se debe configurar la propiedad [[yii\web\ErrorHandler::errorAction|errorAction]] del +Una mejor manera de personalizar la visualización de errores es usar un [acción](structure-controllers.md) de error +dedicada. Para hacerlo, primero se debe configurar la propiedad [[yii\web\ErrorHandler::errorAction|errorAction]] del componente `errorHandler` como en el siguiente ejemplo: ```php @@ -101,8 +101,8 @@ return [ ]; ``` -La propiedad [[yii\web\ErrorHandler::errorAction|errorAction]] vincula una [ruta](structure-controllers.md#routes) a -una acción. La configuración anterior declara que cuando un error tiene que mostrarse sin la pila de información de +La propiedad [[yii\web\ErrorHandler::errorAction|errorAction]] vincula una [ruta](structure-controllers.md#routes) a +una acción. La configuración anterior declara que cuando un error tiene que mostrarse sin la pila de información de llamadas, se debe ejecutar la acción `site/error`. Se puede crear una acción `site/error` como se hace a continuación, @@ -126,10 +126,10 @@ class SiteController extends Controller } ``` -El código anterior define la acción `error` usando la clase [[yii\web\ErrorAction]] que renderiza un error usando la +El código anterior define la acción `error` usando la clase [[yii\web\ErrorAction]] que renderiza un error usando la vista llamada `error`. -Además, usando [[yii\web\ErrorAction]], también se puede definir la acción `error` usando un método de acción como en +Además, usando [[yii\web\ErrorAction]], también se puede definir la acción `error` usando un método de acción como en el siguiente ejemplo, ```php @@ -142,24 +142,24 @@ public function actionError() } ``` -Ahora se debe crear un archivo de vista ubicado en `views/sites/error.php`. En este archivo de vista, se puede acceder +Ahora se debe crear un archivo de vista ubicado en `views/sites/error.php`. En este archivo de vista, se puede acceder a las siguientes variables si se define el error como un [[yii\web\ErrorAction]]: * `name`: el nombre del error; * `message`: el mensaje del error; -* `exception`: el objeto de excepción a través del cual se puede obtener más información útil, tal como el código de +* `exception`: el objeto de excepción a través del cual se puede obtener más información útil, tal como el código de estado HTTP, el código de error, la pila de llamadas del error, etc. -> Información: Tanto la [plantilla de aplicación básica](start-installation.md) como la +> Información: Tanto la [plantilla de aplicación básica](start-installation.md) como la [plantilla de aplicación avanzada](tutorial-advanced-app.md), ya incorporan la acción de error y la vista de error. -### Personalizar el Formato de Respuesta de Error +### Personalizar el Formato de Respuesta de Error -El gestor de errores muestra los errores de siguiente la configuración del formato de las -[respuestas](runtime-responses.md). Si el [[yii\web\Response::format response format]] es `html`, se usará la vista de -error o excepción para mostrar los errores tal y como se ha descrito en la anterior subsección. Para otros tipos de -formatos de respuesta, el gestor de errores asignara la representación del array de la excepción a la propiedad -[[yii\web\Response::data]] que posteriormente podrá convertirse al formato deseado. Por ejemplo, si el formato de +El gestor de errores muestra los errores de siguiente la configuración del formato de las +[respuestas](runtime-responses.md). Si el [[yii\web\Response::format response format]] es `html`, se usará la vista de +error o excepción para mostrar los errores tal y como se ha descrito en la anterior subsección. Para otros tipos de +formatos de respuesta, el gestor de errores asignara la representación del array de la excepción a la propiedad +[[yii\web\Response::data]] que posteriormente podrá convertirse al formato deseado. Por ejemplo, si el formato de respuesta es `json`, obtendremos la siguiente respuesta: ``` @@ -177,7 +177,7 @@ Content-Type: application/json; charset=UTF-8 } ``` -Se puede personalizar el formato de respuestas de error respondiendo al evento `beforeSend` del componente `response` +Se puede personalizar el formato de respuestas de error respondiendo al evento `beforeSend` del componente `response` en la configuración de la aplicación: ```php diff --git a/docs/guide-es/runtime-logging.md b/docs/guide-es/runtime-logging.md index a644fef..505caf0 100644 --- a/docs/guide-es/runtime-logging.md +++ b/docs/guide-es/runtime-logging.md @@ -1,75 +1,75 @@ Registro de anotaciones ======================= -Yii proporciona un poderoso framework dedicado al registro de anotaciones (logging) que es altamente personalizable y -extensible. Usando este framework se pueden guardar fácilmente anotaciones (logs) de varios tipos de mensajes, +Yii proporciona un poderoso framework dedicado al registro de anotaciones (logging) que es altamente personalizable y +extensible. Usando este framework se pueden guardar fácilmente anotaciones (logs) de varios tipos de mensajes, filtrarlos, y unificarlos en diferentes destinos que pueden ser archivos, bases de datos o emails. Usar el framework de registro de anotaciones de Yii involucra los siguientes pasos: * Registrar [mensajes de las anotaciones](#log-messages) en distintos lugares del código; -* Configurar los [destinos de las anotaciones](#log-targets) en la configuración de la aplicación para filtrar y +* Configurar los [destinos de las anotaciones](#log-targets) en la configuración de la aplicación para filtrar y exportar los mensajes de las anotaciones; -* Examinar los mensajes filtrados de los las anotaciones exportadas para diferentes destinos - (p. ej. [Yii debugger](tool-debugger.md)). +* Examinar los mensajes filtrados de los las anotaciones exportadas para diferentes destinos + (ej. [Yii debugger](tool-debugger.md)). En esta sección, se describirán principalmente los dos primeros pasos. -## Anotación de Messages +## Anotación de Messages Registrar mensajes de anotación es tan simple como llamar a uno de los siguientes métodos de registro de anotaciones. -* [[Yii::trace()]]: registra un mensaje para trazar el funcionamiento de una sección de código. Se usa principalmente +* [[Yii::trace()]]: registra un mensaje para trazar el funcionamiento de una sección de código. Se usa principalmente para tareas de desarrollo. * [[Yii::info()]]: registra un mensaje que transmite información útil. * [[Yii::warning()]]: registra un mensaje de advertencia que indica que ha sucedido algo inesperado. * [[Yii::error()]]: registra un error fatal que debe ser investigado tan pronto como sea posible. -Estos métodos registran mensajes de varios *niveles de severidad* y *categorías*. Comparten el mismo registro de -función `function ($message, $category = 'application')`, donde `$message` representa el mensaje del registro que -tiene que ser registrado, mientras que `$category` es la categoría del registro de mensaje. El código del siguiente +Estos métodos registran mensajes de varios *niveles de severidad* y *categorías*. Comparten el mismo registro de +función `function ($message, $category = 'application')`, donde `$message` representa el mensaje del registro que +tiene que ser registrado, mientras que `$category` es la categoría del registro de mensaje. El código del siguiente ejemplo registra la huella del mensaje para la categoría `application`: ```php Yii::trace('start calculating average revenue'); ``` -> Información: Los mensajes de registro pueden ser tanto cadenas de texto como datos complejos, como arrays u objetos. - Es responsabilidad de los [destinos de registros](#log-targets) tratar los mensajes de registro de manera apropiada. - De forma predeterminada, si un mensaje de registro no es una cadena de texto, se exporta como si fuera un string +> Información: Los mensajes de registro pueden ser tanto cadenas de texto como datos complejos, como arrays u objetos. + Es responsabilidad de los [destinos de registros](#log-targets) tratar los mensajes de registro de manera apropiada. + De forma predeterminada, si un mensaje de registro no es una cadena de texto, se exporta como si fuera un string llamando a [[yii\helpers\VarDumper::export()]]. -Para organizar mejor y filtrar los mensajes de registro, se recomienda especificar una categoría apropiada para cada -mensaje de registro. Se puede elegir un sistema de nombres jerárquicos por categorías que facilite a los -[destino de registros](#log-targets) el filtrado de mensajes basándose en categorías. Una manera simple pero -efectiva de organizarlos es usar la constante predefinida (magic constant) de PHP `__METHOD__` como nombre de +Para organizar mejor y filtrar los mensajes de registro, se recomienda especificar una categoría apropiada para cada +mensaje de registro. Se puede elegir un sistema de nombres jerárquicos por categorías que facilite a los +[destino de registros](#log-targets) el filtrado de mensajes basándose en categorías. Una manera simple pero +efectiva de organizarlos es usar la constante predefinida (magic constant) de PHP `__METHOD__` como nombre de categoría. Además este es el enfoque que se usa en el código del núcleo (core) del framework Yii. Por ejemplo, ```php Yii::trace('start calculating average revenue', __METHOD__); ``` -La constante `__METHOD__` equivale al nombre del método (con el prefijo del nombre completo del nombre de clase) donde -se encuentra la constante. Por ejemplo, es igual a la cadena `'app\controllers\RevenueController::calculate'` si la +La constante `__METHOD__` equivale al nombre del método (con el prefijo del nombre completo del nombre de clase) donde +se encuentra la constante. Por ejemplo, es igual a la cadena `'app\controllers\RevenueController::calculate'` si la linea anterior de código se llamara dentro de este método. -> Información: Los métodos de registro de anotaciones descritos anteriormente en realidad son accesos directos al - método [[yii\log\Logger::log()|log()]] del [[yii\log\Logger|logger object]] que es un singleton accesible a través - de la expresión `Yii::getLogger()`. Cuando se hayan registrado suficientes mensajes o cuando la aplicación haya - finalizado, el objeto de registro llamará [[yii\log\Dispatcher|message dispatcher]] para enviar los mensajes de +> Información: Los métodos de registro de anotaciones descritos anteriormente en realidad son accesos directos al + método [[yii\log\Logger::log()|log()]] del [[yii\log\Logger|logger object]] que es un singleton accesible a través + de la expresión `Yii::getLogger()`. Cuando se hayan registrado suficientes mensajes o cuando la aplicación haya + finalizado, el objeto de registro llamará [[yii\log\Dispatcher|message dispatcher]] para enviar los mensajes de registro registrados a los [destiinos de registros](#log-targets). -## Destino de Registros +## Destino de Registros -Un destino de registro es una instancia de la clase [[yii\log\Target]] o de una clase hija. Este filtra los -mensajes de registro por sus niveles de severidad y sus categorías y después los exporta a algún medio. Por ejemplo, -un [[yii\log\DbTarget|database target]] exporta los mensajes de registro filtrados a una tabla de base de datos, -mientras que un [[yii\log\EmailTarget|email target]] exporta los mensajes de registro a una dirección de correo +Un destino de registro es una instancia de la clase [[yii\log\Target]] o de una clase hija. Este filtra los +mensajes de registro por sus niveles de severidad y sus categorías y después los exporta a algún medio. Por ejemplo, +un [[yii\log\DbTarget|database target]] exporta los mensajes de registro filtrados a una tabla de base de datos, +mientras que un [[yii\log\EmailTarget|email target]] exporta los mensajes de registro a una dirección de correo electrónico específica. -Se pueden registrar múltiples destinos de registros en una aplicación configurándolos en la -[aplicación de componente](structure-application-components.md) `log` dentro de la configuración de aplicación, como +Se pueden registrar múltiples destinos de registros en una aplicación configurándolos en la +[aplicación de componente](structure-application-components.md) `log` dentro de la configuración de aplicación, como en el siguiente ejemplo: ```php @@ -100,17 +100,17 @@ return [ ]; ``` -> Nota: El componente `log` debe cargarse durante el proceso de [bootstrapping](runtime-bootstrapping.md) para que -pueda enviar los mensajes de registro a los destinos inmediatamente. Este es el motivo por el que se lista en el +> Nota: El componente `log` debe cargarse durante el proceso de [bootstrapping](runtime-bootstrapping.md) para que +pueda enviar los mensajes de registro a los destinos inmediatamente. Este es el motivo por el que se lista en el array `bootstrap` como se muestra más arriba. En el anterior código, se registran dos destinos de registros en la propiedad [[yii\log\Dispatcher::targets]] * el primer destino gestiona los errores y las advertencias y las guarda en una tabla de la base de datos; -* el segundo destino gestiona mensajes los mensajes de error de las categorías cuyos nombres empiecen por +* el segundo destino gestiona mensajes los mensajes de error de las categorías cuyos nombres empiecen por `yii\db\` y los envía por email a las direcciones `admin@example.com` y `developer@example.com`. -Yii incluye los siguientes destinos. En la API de documentación se pueden referencias a estas clases e +Yii incluye los siguientes destinos. En la API de documentación se pueden referencias a estas clases e información de configuración y uso. * [[yii\log\DbTarget]]: almacena los mensajes de registro en una tabla de la base de datos. @@ -120,10 +120,10 @@ información de configuración y uso. A continuación, se describirá las características más comunes de todos los destinos de registros. -### Filtrado de Mensajes +### Filtrado de Mensajes -Se pueden configurar las propiedades [[yii\log\Target::levels|levels]] y [[yii\log\Target::categories|categories]] -para cada destino de registros, con estas se especifican los niveles de severidad y las categorías de mensajes que +Se pueden configurar las propiedades [[yii\log\Target::levels|levels]] y [[yii\log\Target::categories|categories]] +para cada destino de registros, con estas se especifican los niveles de severidad y las categorías de mensajes que deberán procesar sus destinos. La propiedad [[yii\log\Target::levels|levels]] es un array que consta de uno o varios de los siguientes valores: @@ -132,29 +132,29 @@ La propiedad [[yii\log\Target::levels|levels]] es un array que consta de uno o v * `warning`: correspondiente a los mensajes registrados por [[Yii::warning()]]. * `info`: correspondiente a los mensajes registrados por [[Yii::info()]]. * `trace`: correspondiente a los mensajes registrados por [[Yii::trace()]]. -* `profile`: correspondiente a los mensajes registrados por [[Yii::beginProfile()]] y [[Yii::endProfile()]], que se - explicará más detalladamente en la subsección [Perfiles](#performance-profiling). +* `profile`: correspondiente a los mensajes registrados por [[Yii::beginProfile()]] y [[Yii::endProfile()]], que se + explicará más detalladamente en la subsección [Perfiles](#performance-profiling). -Si no se especifica la propiedad [[yii\log\Target::levels|levels]], significa que el destino procesará los +Si no se especifica la propiedad [[yii\log\Target::levels|levels]], significa que el destino procesará los mensajes de *cualquier* nivel de severidad. -La propiedad [[yii\log\Target::categories|categories]] es un array que consta de categorías de mensaje o patrones. El -destino sólo procesará mensajes de las categorías que se puedan encontrar o si coinciden con algún patrón listado -en el array. Un patrón de categoría es un nombre de categoría al que se le añade un asterisco `*` al final. Un nombre -de categoría coincide con un patrón si empieza por el mismo prefijo que el patrón. Por ejemplo, -`yii\db\Command::execute` y `yii\db\Command::query` que se usan como nombres de categoría para los mensajes +La propiedad [[yii\log\Target::categories|categories]] es un array que consta de categorías de mensaje o patrones. El +destino sólo procesará mensajes de las categorías que se puedan encontrar o si coinciden con algún patrón listado +en el array. Un patrón de categoría es un nombre de categoría al que se le añade un asterisco `*` al final. Un nombre +de categoría coincide con un patrón si empieza por el mismo prefijo que el patrón. Por ejemplo, +`yii\db\Command::execute` y `yii\db\Command::query` que se usan como nombres de categoría para los mensajes registrados en la clase [[yii\db\Command]], coinciden con el patrón `yii\db\*`. -Si no se especifica la propiedad [[yii\log\Target::categories|categories]], significa que el destino procesará +Si no se especifica la propiedad [[yii\log\Target::categories|categories]], significa que el destino procesará los mensajes de *todas* las categorías. -Además añadiendo las categorías en listas blancas (whitelisting) mediante la propiedad -[[yii\log\Target::categories|categories]], también se pueden añadir ciertas categorías en listas negras (blacklist) -configurando la propiedad [[yii\log\Target::except|except]]. Si se encuentra la categoría de un mensaje o coincide +Además añadiendo las categorías en listas blancas (whitelisting) mediante la propiedad +[[yii\log\Target::categories|categories]], también se pueden añadir ciertas categorías en listas negras (blacklist) +configurando la propiedad [[yii\log\Target::except|except]]. Si se encuentra la categoría de un mensaje o coincide algún patrón con esta propiedad, NO será procesada por el destino. -La siguiente configuración de destinos especifica que el destino solo debe procesar los mensajes de error y -de advertencia de las categorías que coincidan con alguno de los siguientes patrones `yii\db\*` o +La siguiente configuración de destinos especifica que el destino solo debe procesar los mensajes de error y +de advertencia de las categorías que coincidan con alguno de los siguientes patrones `yii\db\*` o `yii\web\HttpException:*`, pero no con `yii\web\HttpException:404`. ```php @@ -171,31 +171,31 @@ de advertencia de las categorías que coincidan con alguno de los siguientes pat ] ``` -> Información: Cuando se captura una excepción de tipo HTTP por el [gestor de errores](runtime-handling-errors.md), se - registrará un mensaje de error con el nombre de categoría con formato `yii\web\HttpException:ErrorCode`. Por - ejemplo, la excepción [[yii\web\NotFoundHttpException]] causará un mensaje de error del tipo +> Información: Cuando se captura una excepción de tipo HTTP por el [gestor de errores](runtime-handling-errors.md), se + registrará un mensaje de error con el nombre de categoría con formato `yii\web\HttpException:ErrorCode`. Por + ejemplo, la excepción [[yii\web\NotFoundHttpException]] causará un mensaje de error del tipo `yii\web\HttpException:404`. -### Formato de los Mensajes +### Formato de los Mensajes -Los destinos exportan los mensajes de registro filtrados en cierto formato. Por ejemplo, is se instala un -destino de registros de la calse [[yii\log\FileTarget]], encontraremos un registro similar en el archivo de +Los destinos exportan los mensajes de registro filtrados en cierto formato. Por ejemplo, is se instala un +destino de registros de la calse [[yii\log\FileTarget]], encontraremos un registro similar en el archivo de registro `runtime/log/app.log`: ``` 2014-10-04 18:10:15 [::1][][-][trace][yii\base\Module::getModule] Loading module: debug ``` -De forma predeterminada los mensajes de registro se formatearan por [[yii\log\Target::formatMessage()]] como en el +De forma predeterminada los mensajes de registro se formatearan por [[yii\log\Target::formatMessage()]] como en el siguiente ejemplo: ``` Timestamp [IP address][User ID][Session ID][Severity Level][Category] Message Text ``` -Se puede personalizar el formato configurando la propiedad [[yii\log\Target::prefix]] que es un PHP ejecutable y -devuelve un prefijo de mensaje personalizado. Por ejemplo, el siguiente código configura un destino de registro -anteponiendo a cada mensaje de registro el ID de usuario (se eliminan la dirección IP y el ID por razones de +Se puede personalizar el formato configurando la propiedad [[yii\log\Target::prefix]] que es un PHP ejecutable y +devuelve un prefijo de mensaje personalizado. Por ejemplo, el siguiente código configura un destino de registro +anteponiendo a cada mensaje de registro el ID de usuario (se eliminan la dirección IP y el ID por razones de privacidad). ```php @@ -209,11 +209,11 @@ privacidad). ] ``` -Además de prefijos de mensaje, destinos de registros también añaden alguna información de contexto en cada lote -de mensajes de registro. De forma predeterminada, se incluyen los valores de las siguientes variables globales de -PHP: `$_GET`, `$_POST`, `$_FILES`, `$_COOKIE`, `$_SESSION` y `$_SERVER`. Se puede ajustar el comportamiento -configurando la propiedad [[yii\log\Target::logVars]] con los nombres de las variables globales que se quieran incluir -con el destino del registro. Por ejemplo, la siguiente configuración de destino de registros especifica que +Además de prefijos de mensaje, destinos de registros también añaden alguna información de contexto en cada lote +de mensajes de registro. De forma predeterminada, se incluyen los valores de las siguientes variables globales de +PHP: `$_GET`, `$_POST`, `$_FILES`, `$_COOKIE`, `$_SESSION` y `$_SERVER`. Se puede ajustar el comportamiento +configurando la propiedad [[yii\log\Target::logVars]] con los nombres de las variables globales que se quieran incluir +con el destino del registro. Por ejemplo, la siguiente configuración de destino de registros especifica que sólo se añadirá al mensaje de registro el valor de la variable `$_SERVER`. ```php @@ -223,14 +223,14 @@ sólo se añadirá al mensaje de registro el valor de la variable `$_SERVER`. ] ``` -Se puede configurar `logVars` para que sea un array vacío para deshabilitar totalmente la inclusión de información de -contexto. O si se desea implementar un método propio de proporcionar información de contexto se puede sobrescribir el +Se puede configurar `logVars` para que sea un array vacío para deshabilitar totalmente la inclusión de información de +contexto. O si se desea implementar un método propio de proporcionar información de contexto se puede sobrescribir el método [[yii\log\Target::getContextMessage()]]. -### Nivel de Seguimiento de Mensajes +### Nivel de Seguimiento de Mensajes -Durante el desarrollo, a veces se quiere visualizar de donde proviene cada mensaje de registro. Se puede lograr -configurando la propiedad [[yii\log\Dispatcher::traceLevel|traceLevel]] del componente `log` como en el siguiente +Durante el desarrollo, a veces se quiere visualizar de donde proviene cada mensaje de registro. Se puede lograr +configurando la propiedad [[yii\log\Dispatcher::traceLevel|traceLevel]] del componente `log` como en el siguiente ejemplo: ```php @@ -245,20 +245,20 @@ return [ ]; ``` -La configuración de aplicación anterior establece el [[yii\log\Dispatcher::traceLevel|traceLevel]] para que sea 3 si -`YII_DEBUG` esta habilitado y 0 si esta deshabilitado. Esto significa que si `YII_DEBUG` esta habilitado, a cada -mensaje de registro se le añadirán como mucho 3 niveles de la pila de llamadas del mensaje que se este registrando; y +La configuración de aplicación anterior establece el [[yii\log\Dispatcher::traceLevel|traceLevel]] para que sea 3 si +`YII_DEBUG` esta habilitado y 0 si esta deshabilitado. Esto significa que si `YII_DEBUG` esta habilitado, a cada +mensaje de registro se le añadirán como mucho 3 niveles de la pila de llamadas del mensaje que se este registrando; y si `YII_DEBUG` está deshabilitado, no se incluirá información de la pila de llamadas. -> Información: Obtener información de la pila de llamadas no es trivial. Por lo tanto, sólo se debe usar esta +> Información: Obtener información de la pila de llamadas no es trivial. Por lo tanto, sólo se debe usar esta característica durante el desarrollo o cuando se depura la aplicación. -### Liberación (Flushing) y Exportación de Mensajes +### Liberación (Flushing) y Exportación de Mensajes -Como se ha comentado anteriormente, los mensajes de registro se mantienen en un array por el -[[yii\log\Logger|logger object]]. Para limitar el consumo de memoria de este array, el componente encargado del -registro de mensajes enviará los mensajes registrados a los [destinos de registros](#log-targets) cada vez que el -array acumule un cierto número de mensajes de registro. Se puede personalizar el número configurando la propiedad +Como se ha comentado anteriormente, los mensajes de registro se mantienen en un array por el +[[yii\log\Logger|logger object]]. Para limitar el consumo de memoria de este array, el componente encargado del +registro de mensajes enviará los mensajes registrados a los [destinos de registros](#log-targets) cada vez que el +array acumule un cierto número de mensajes de registro. Se puede personalizar el número configurando la propiedad [[yii\log\Dispatcher::flushInterval|flushInterval]] del componente `log`: ```php @@ -273,13 +273,13 @@ return [ ]; ``` -> Información: También se produce la liberación de mensajes cuando la aplicación finaliza, esto asegura que los +> Información: También se produce la liberación de mensajes cuando la aplicación finaliza, esto asegura que los destinos de los registros reciban los mensajes de registro. -Cuando el [[yii\log\Logger|logger object]] libera los mensajes de registro enviándolos a los -[destinos de registros](#log-targets), estos no se exportan inmediatamente. La exportación de mensajes solo se -produce cuando un destino de registros acumula un cierto número de mensajes filtrados. Se puede personalizar este -número configurando la propiedad [[yii\log\Target::exportInterval|exportInterval]] de un +Cuando el [[yii\log\Logger|logger object]] libera los mensajes de registro enviándolos a los +[destinos de registros](#log-targets), estos no se exportan inmediatamente. La exportación de mensajes solo se +produce cuando un destino de registros acumula un cierto número de mensajes filtrados. Se puede personalizar este +número configurando la propiedad [[yii\log\Target::exportInterval|exportInterval]] de un [destinos de registros](#log-targets) individual, como se muestra a continuación, ```php @@ -289,11 +289,11 @@ número configurando la propiedad [[yii\log\Target::exportInterval|exportInterva ] ``` -Debido al nivel de configuración de la liberación y exportación de mensajes, de forma predeterminada cuando se llama a -`Yii::trace()` o cualquier otro método de registro de mensajes, NO veremos el registro de mensaje inmediatamente en -los destinos de registros. Esto podría ser un problema para algunas aplicaciones de consola de ejecución -prolongada (long-running). Para hacer que los mensajes de registro aparezcan inmediatamente en los destinos de -registro se deben establecer [[yii\log\Dispatcher::flushInterval|flushInterval]] y +Debido al nivel de configuración de la liberación y exportación de mensajes, de forma predeterminada cuando se llama a +`Yii::trace()` o cualquier otro método de registro de mensajes, NO veremos el registro de mensaje inmediatamente en +los destinos de registros. Esto podría ser un problema para algunas aplicaciones de consola de ejecución +prolongada (long-running). Para hacer que los mensajes de registro aparezcan inmediatamente en los destinos de +registro se deben establecer [[yii\log\Dispatcher::flushInterval|flushInterval]] y [[yii\log\Target::exportInterval|exportInterval]] para que tengan valor 1 como se muestra a continuación: ```php @@ -315,17 +315,17 @@ return [ > Nota: El uso frecuente de liberación y exportación puede degradar el rendimiento de la aplicación. -### Conmutación de Destinos de Registros +### Conmutación de Destinos de Registros -Se puede habilitar o deshabilitar un destino de registro configuración su propiedad -[[yii\log\Target::enabled|enabled]]. Esto se puede llevar a cabo a mediante la configuración del destino de +Se puede habilitar o deshabilitar un destino de registro configuración su propiedad +[[yii\log\Target::enabled|enabled]]. Esto se puede llevar a cabo a mediante la configuración del destino de registros o con la siguiente declaración PHP de código: ```php Yii::$app->log->targets['file']->enabled = false; ``` -El código anterior requiere que se asocie un destino como `file`, como se muestra a continuación usando las +El código anterior requiere que se asocie un destino como `file`, como se muestra a continuación usando las claves de texto en el array `targets`: ```php @@ -346,21 +346,21 @@ return [ ]; ``` -### Creación de Nuevos Destinos +### Creación de Nuevos Destinos -La creación de nuevas clases de destinos de registro es muy simple. Se necesita implementar el método -[[yii\log\Target::export()]] enviando el contenido del array [[yii\log\Target::messages]] al medio designado. Se puede -llamar al método [[yii\log\Target::formatMessage()]] para formatear los mensajes. Se pueden encontrar más detalles de +La creación de nuevas clases de destinos de registro es muy simple. Se necesita implementar el método +[[yii\log\Target::export()]] enviando el contenido del array [[yii\log\Target::messages]] al medio designado. Se puede +llamar al método [[yii\log\Target::formatMessage()]] para formatear los mensajes. Se pueden encontrar más detalles de destinos de registros en las clases incluidas en la distribución de Yii. -## Perfilado de Rendimiento +## Perfilado de Rendimiento -El Perfilado de rendimiento es un tipo especial de registro de mensajes que se usa para medir el tiempo que tardan en -ejecutarse ciertos bloques de código y encontrar donde están los cuellos de botella de rendimiento. Por ejemplo, la -clase [[yii\db\Command]] utiliza el perfilado de rendimiento para encontrar conocer el tiempo que tarda cada consulta +El Perfilado de rendimiento es un tipo especial de registro de mensajes que se usa para medir el tiempo que tardan en +ejecutarse ciertos bloques de código y encontrar donde están los cuellos de botella de rendimiento. Por ejemplo, la +clase [[yii\db\Command]] utiliza el perfilado de rendimiento para encontrar conocer el tiempo que tarda cada consulta a la base de datos. -Para usar el perfilado de rendimiento, primero debemos identificar los bloques de código que tienen que ser +Para usar el perfilado de rendimiento, primero debemos identificar los bloques de código que tienen que ser perfilados, para poder enmarcar su contenido como en el siguiente ejemplo: ```php @@ -371,8 +371,8 @@ perfilados, para poder enmarcar su contenido como en el siguiente ejemplo: \Yii::endProfile('myBenchmark'); ``` -Donde `myBenchmark` representa un token único para identificar el bloque de código. Después cuando se examine el -resulte del perfilado, se podrá usar este token para encontrar el tiempo que ha necesitado el correspondiente bloque +Donde `myBenchmark` representa un token único para identificar el bloque de código. Después cuando se examine el +resulte del perfilado, se podrá usar este token para encontrar el tiempo que ha necesitado el correspondiente bloque de código. Es importante asegurarse de que los pares de `beginProfile` y `endProfile` estén bien anidados. Por ejemplo, @@ -389,10 +389,10 @@ Es importante asegurarse de que los pares de `beginProfile` y `endProfile` esté \Yii::endProfile('block1'); ``` -Si nos dejamos el `\Yii::endProfile('block1')` o lo intercambiamos `\Yii::endProfile('block1')` con +Si nos dejamos el `\Yii::endProfile('block1')` o lo intercambiamos `\Yii::endProfile('block1')` con `\Yii::endProfile('block2')`, el perfilado de rendimiento no funcionará. -Se registra un mensaje de registro con el nivel de severidad `profile` para cada bloque de código que se haya -perfilado. Se puede configurar el [destino del registro](#log-targets) para reunir todos los mensajes y exportarlos. -El [depurador de Yii](tool-debugger.md) incluye un panel de perfilado de rendimiento que muestra los resultados de +Se registra un mensaje de registro con el nivel de severidad `profile` para cada bloque de código que se haya +perfilado. Se puede configurar el [destino del registro](#log-targets) para reunir todos los mensajes y exportarlos. +El [depurador de Yii](tool-debugger.md) incluye un panel de perfilado de rendimiento que muestra los resultados de perfilado. \ No newline at end of file diff --git a/docs/guide-es/runtime-requests.md b/docs/guide-es/runtime-requests.md index a1617f8..3179577 100644 --- a/docs/guide-es/runtime-requests.md +++ b/docs/guide-es/runtime-requests.md @@ -7,7 +7,7 @@ objeto request correspondiente a través del [componente de aplicación](structu que, por defecto, es una instancia de [[yii\web\Request]]. En esta sección se describirá como hacer uso de este componente en las aplicaciones. -## Parámetros de Request +## Parámetros de Request Para obtener los parámetros de la petición, se puede llamar a los métodos [[yii\web\Request::get()|get()]] y [[yii\web\Request::post()|post()]] del componente `request`. Estos devuelven los valores de `$_GET` y `$_POST`, @@ -58,7 +58,7 @@ $param = $request->getBodyParam('id'); se acceda a él a través de los métodos descritos anteriormente. Se puede personalizar la manera en como los parámetros se convierten configurando la propiedad [[yii\web\Request::parsers]]. -## Métodos de Request +## Métodos de Request Se puede obtener el método HTTP usado por la petición actual a través de la expresión `Yii::$app->request->method`. Se proporcionan un conjunto de propiedades booleanas para comprobar si el método actual es de un cierto tipo. Por ejemplo: @@ -72,7 +72,7 @@ if ($request->isPost) { // el método de la request es POST } if ($request->isPut) { // el método de la request es PUT } ``` -## URLs de Request +## URLs de Request El componente `request` proporciona muchas maneras de inspeccionar la URL solicitada actualmente. @@ -95,7 +95,7 @@ varias partes de la URL explicadas en los siguientes puntos: * [[yii\web\Request::serverName|serverName]]: devuelve `example.com`, que es el nombre del host dentro de la URL. * [[yii\web\Request::serverPort|serverPort]]: devuelve 80, que es el puerto que usa el servidor web. -## Cabeceras HTTP +## Cabeceras HTTP Se pueden obtener la información de las cabeceras HTTP a través de [[yii\web\HeaderCollection|header collection]] devueltas por la propiedad [[yii\web\Request::headers]]. Por ejemplo: @@ -130,7 +130,7 @@ lista de idiomas soportados por la aplicación, comparados con diatónicamente el content type y el idioma que debe usarse en la respuesta. El filtro implementa la negociación de contenido en la parte superior de las propiedades y métodos descritos anteriormente. -## Información del cliente +## Información del cliente Se puede obtener el nombre del host y la dirección IP de la máquina cliente a través de [[yii\web\Request::userHost|userHost]] y [[yii\web\Request::userIP|userIP]], respectivamente. Por ejemplo: diff --git a/docs/guide-es/runtime-responses.md b/docs/guide-es/runtime-responses.md index c765d09..8b16966 100644 --- a/docs/guide-es/runtime-responses.md +++ b/docs/guide-es/runtime-responses.md @@ -13,7 +13,7 @@ usuario final tal y como se explica a continuación. En esta sección, se describirá como generar y enviar respuestas a usuarios finales. -## Códigos de Estado +## Códigos de Estado Una de las primeras cosas que debería hacerse cuando se genera una respuesta es indicar si la petición se ha gestionado correctamente. Esto se indica asignando la propiedad [[yii\web\Response::statusCode]] a la que se le puede @@ -56,7 +56,7 @@ Si la excepción que se quiere lanzar no se encuentra en la lista anterior, se p throw new \yii\web\HttpException(402); ``` -## Cabeceras HTTP +## Cabeceras HTTP Se puede enviar cabeceras HTTP modificando el [[yii\web\Response::headers|header collection]] en el componente `response`. Por ejemplo: @@ -78,7 +78,7 @@ $values = $headers->remove('Pragma'); Además, las nuevas cabeceras registradas no se enviarán al usuario hasta que se llame al método [[yii\web\Response::send()]]. -## Cuerpo de la Respuesta +## Cuerpo de la Respuesta La mayoría de las respuestas deben tener un cuerpo que contenga el contenido que se quiere mostrar a los usuarios finales. @@ -160,7 +160,7 @@ public function actionInfo() `response` en la configuración de la aplicación. Sin embargo, se puede usar la [inyección de dependencias](concept-di-container.md) para aplicar la configuración común al nuevo objeto response. -## Redirección del Navegador +## Redirección del Navegador La redirección del navegador se basa en el envío de la cabecera HTTP `Location`. Debido a que esta característica se usa comúnmente, Yii proporciona soporte especial para ello. @@ -202,7 +202,7 @@ JavaScript, incluyendo la redirección de navegador basada en la cabecera `X-Red fichero JavaScript (registrándolo *asset bundle* [[yii\web\YiiAsset]]), no se necesitará escribir nada más para tener soporte en redirecciones AJAX. -## Enviar Archivos +## Enviar Archivos Igual que con la redirección, el envío de archivos es otra característica que se basa en cabeceras HTTP especificas. Yii proporciona un conjunto de métodos para dar soporte a varias necesidades del envío de ficheros. Todos ellos @@ -242,7 +242,7 @@ algunos servidores Web populares. - Nginx: [X-Accel-Redirect](http://wiki.nginx.org/XSendfile) - Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) -## Enviar la Respuesta +## Enviar la Respuesta El contenido en una respuesta no se envía al usuario hasta que se llama al método [[yii\web\Response::send()]]. De forma predeterminada, se llama a este método automáticamente al final de [[yii\base\Application::run()]]. Sin embargo, diff --git a/docs/guide-es/runtime-routing.md b/docs/guide-es/runtime-routing.md index cd1d040..45c61ab 100644 --- a/docs/guide-es/runtime-routing.md +++ b/docs/guide-es/runtime-routing.md @@ -6,8 +6,7 @@ Cuando una aplicación Yii empieza a procesar una URL solicitada, lo primero que [acción de controlador](structure-controllers.md) correspondiente para gestionar la petición. A este proceso se le llama *enrutamiento*. -El proceso inverso se llama *creación de URLs*, y crea una URL a partir de una ruta dada y unos parámetros de consulta -(query) asociados. Cuando posteriormente se solicita la URL creada, el proceso de enrutamiento puede resolverla y +El proceso inverso se llama *creación de URLs*, y crea una URL a partir de una ruta dada y unos parámetros de consulta (query) asociados. Cuando posteriormente se solicita la URL creada, el proceso de enrutamiento puede resolverla y convertirla en la ruta original con los parámetros asociados. La principal pieza encargada del enrutamiento y de la creación de URLs es [[yii\web\UrlManager|URL manager]], que se @@ -20,7 +19,8 @@ Configurando el componente `urlManager` en la configuración de la aplicación, reconocimiento arbitrario de formatos de URL sin modificar el código de la aplicación existente. Por ejemplo, se puede usar el siguiente código para crear una URL para la acción `post/view`: -``` php use yii\helpers\Url; +``` php +use yii\helpers\Url; // Url::to() llama a UrlManager::createUrl() para crear una URL $url = Url::to(['post/view', 'id' => 100]); @@ -36,7 +36,8 @@ los parámetros. /posts/100 ``` -## Formatos de URL + +## Formatos de URL El [[yii\web\UrlManager|URL manager]] soporta dos formatos de URL: el formato predeterminado de URL y el formato URL amigable (pretty URL). @@ -58,7 +59,7 @@ Se puede cambiar entre los dos formatos de URL conmutando la propiedad [[yii\web\UrlManager::enablePrettyUrl|enablePrettyUrl]] del [[yii\web\UrlManager|URL manager]] sin cambiar ningún otro código de aplicación. -## Enrutamiento +## Enrutamiento El Enrutamiento involucra dos pasos. El primero, la petición (request) entrante se convierte en una ruta y sus parámetros de consulta asociados. En el segundo paso, se crea la correspondiente @@ -85,16 +86,13 @@ acción. Empezando por la primera parte de la ruta, la aplicación, sigue los si módulo actual. Si está listado, se crea un modulo de acuerdo con la configuración encontrada en el listado de módulos, y se seguirá el Paso 2 para gestionar la siguiente parte de la ruta bajo el contexto de la creación de un nuevo módulo. -4. Trata el ID como si se tratara de un ID de controlador y crea un objeto controlador. Sigue el siguiente paso con la - parte restante de la ruta. -5. El controlador busca el ID en su [[yii\base\Controller::actions()|action map]]. Si lo encuentra, crea una acción de - acuerdo con la configuración encontrada en el mapa. De otra forma, el controlador intenta crear una acción en linea - definida por un método de acción correspondiente al ID actual. +4. Trata el ID como si se tratara de un ID de controlador y crea un objeto controlador. Sigue el siguiente paso con la parte restante de la ruta. +5. El controlador busca el ID en su [[yii\base\Controller::actions()|action map]]. Si lo encuentra, crea una acción de acuerdo con la configuración encontrada en el mapa. De otra forma, el controlador intenta crear una acción en linea definida por un método de acción correspondiente al ID actual. Si ocurre algún error entre alguno de los pasos anteriores, se lanzará una excepción de tipo [[yii\web\NotFoundHttpException]], indicando el fallo de proceso de enrutamiento. -### Ruta Predeterminada +### Ruta Predeterminada Cuando una petición se convierte en una ruta vacía, se usa la llamada *ruta predeterminada*. Por defecto, la ruta predeterminada es `site/index`, que hace referencia a la acción `index` del controlador `site`. Se puede personalizar @@ -108,7 +106,8 @@ aplicación como en el siguiente ejemplo: ]; ``` -### Ruta `catchAll` + +### Ruta `catchAll` A veces, se puede querer poner la aplicación Web en modo de mantenimiento temporalmente y mostrar la misma pagina de información para todas las peticiones. Hay varias maneras de lograr este objetivo. Pero una de las maneras más simples @@ -127,7 +126,7 @@ Con la anterior configuración, se usar la acción `site/offline` para gestionar La propiedad `catchAll` debe tener un array cuyo primer elemento especifique una ruta, y el resto de elementos (pares nombre-valor) especifiquen los parámetros [ligados a la acción](structure-controllers.md#action-parameters). -## Creación de URLs +## Creación de URLs Yii proporciona un método auxiliar (helper method) [[yii\helpers\Url::to()]] para crear varios tipos de URLs a partir de las rutas dadas y sus parámetros de consulta asociados. Por ejemplo, @@ -201,6 +200,7 @@ echo Url::to('@example'); // una URL absoluta: http://example.com/images/logo.gif echo Url::to('/images/logo.gif', true);``` +``` Además del método `to()`, la clase auxiliar [[yii\helpers\Url]] también proporciona algunos otros métodos de creación de URLs. Por ejemplo, @@ -221,7 +221,8 @@ echo Url::canonical(); echo Url::previous(); ``` -## Uso de URLs Amigables + +## Uso de URLs Amigables Para utilizar URLs amigables, hay que configurar el componente `ulrManager` en la configuración de la aplicación como en el siguiente ejemplo: @@ -263,7 +264,8 @@ amigable. El resto de propiedades son opcionales. Sin embargo, la anterior confi Si se usa el servidor Web Apache, se puede utilizar la configuración recomendada descrita en la sección de [Instalación](start-installation.md#recommended-apache-configuration). -### Regalas de URL + +### Reglas de URL Una regla de URL es una instancia de [[yii\web\UrlRule]] o de una clase hija. Cada URL consiste en un patrón utilizado para cotejar la parte de información de ruta de las URLs, una ruta, y algunos parámetros de consulta. Una URL puede @@ -314,11 +316,12 @@ se necesita a menudo cuando se quieren configurar otras propiedades de la regla De forma predeterminada si no se especifica la opción `class` en la configuración de una regla, se utilizará la clase predeterminada [[yii\web\UrlRule]]. -### Parameters Asociativos + +### Parameters Asociativos Una regla de URL puede asociarse a una determinado grupo de parámetros de consulta que se hayan sido especificados en el patrón con el formato ``, donde `ParamName` especifica el nombre del parámetro y `RegExp` es una -expresión regular opcional que se usa para encontrara los valores de los parámetros. Si no se especifica `RegExp` +expresión regular opcional que se usa para encontrar los valores de los parámetros. Si no se especifica `RegExp` significa que el parámetro debe ser una cadena de texto sin ninguna barra. > Nota: Solo se pueden especificar expresiones regulares para los parámetros. La parte restante del patrón se @@ -365,7 +368,8 @@ Y cuando las se usen las reglas para crear URLs: reglas. Hay que tener en cuenta que si no se aplica ninguna de las reglas, la URL se genera simplemente añadiendo la parte de información de la ruta y todos los parámetros como parte de la consulta. -### Parametrización de Rutas + +### Parametrización de Rutas Se pueden incrustar nombres de parámetros en la ruta de una regla de URL. Esto permite a la regla de URL poder ser usada para que coincida con varias rutas. Por ejemplo, la siguiente regla incrusta los parámetros `controller` y @@ -418,7 +422,8 @@ La regla anterior puede usarse para convertir o crear cualquiera de las siguient Sin usar ningún parámetro opcional, se tendrían que crear 4 reglas para lograr el mismo resultado. -### Reglas con Nombres de Servidor + +### Reglas con Nombres de Servidor Es posible incluir nombres de servidores Web en los parámetros de las URLs. Esto es practico principalmente cuando una aplicación debe tener distintos comportamientos paro diferentes nombres de servidores Web. Por ejemplo, las siguientes @@ -448,7 +453,7 @@ ejemplo, la siguiente regla convertirá la URL `http://en.example.com/posts` en permitirá que la aplicación se pueda desarrollar en cualquier directorio sin la necesidad de cambiar el código de la aplicación. -### Sufijos de URL +### Sufijos de URL Se puede querer añadir sufijos a las URLs para varios propósitos. Por ejemplo, se puede añadir `.html`a las URLs para que parezcan URLs para paginas HTML estáticas; también se puede querer añadir `.json` a las URLs para indicar el tipo @@ -506,7 +511,8 @@ siguiente configuración contiene una regla de URL personalizada que usa el sufi ] ``` -### Métodos HTTP + +### Métodos HTTP Cuando se implementan APIs RESTful, normalmente se necesita que ciertas URLs se conviertan en otras de acuerdo con el método HTTP que se esté usando. Esto se puede hacer fácilmente prefijando los métodos HTTP soportados como los @@ -531,7 +537,8 @@ convertirá en `post/view`. de controladores. Para conocer más detalles, se puede visitar la sección [Enrutamiento](rest-routing.md) acerca de el desarrollo de APIs RESTful. -### Personalización de Reglas + +### Personalización de Reglas En los anteriores ejemplos, las reglas de URL se han declarado principalmente en términos de pares de patrón-ruta. Este es un método de acceso directo que se usa a menudo. En algunos escenarios, se puede querer personalizar la regla @@ -554,7 +561,8 @@ array completo de configuración para especificar una regla. El siguiente ejempl > Información: De forma predeterminada si no se especifica una opción `class` para una configuración de regla, se usará la clase predeterminada [[yii\web\UrlRule]]. -### Adición de Reglas Dinámicamente + +### Adición de Reglas Dinámicamente Las reglas de URL se pueden añadir dinámicamente en el [[yii\web\UrlManager|URL manager]]. A menudo se necesita por [módulos](structure-modules.md) redistribubles que se encargan de gestionar sus propias reglas de URL. Para que las @@ -575,7 +583,7 @@ public function bootstrap($app) Hay que tener en cuenta se deben añadir estos módulos en [[yii\web\Application::bootstrap]] para que puedan participar en el proceso de [bootstrapping](runtime-bootstrapping.md) -### Creación de Clases de Reglas +### Creación de Clases de Reglas A pesar del hecho de que de forma predeterminada la clase [[yii\web\UrlRule]] lo suficientemente flexible para la mayoría de proyectos, hay situaciones en las que se tiene que crear una clase de reglas propia. Por ejemplo, en un @@ -634,7 +642,7 @@ Y usa la nueva clase de regla en la configuración de [[yii\web\UrlManager::rule ] ``` -## Consideración del Rendimiento +## Consideración del Rendimiento Cuando se desarrolla una aplicación Web compleja, es importante optimizar las reglas de URL para que tarden el mínimo tiempo posible en convertir las peticiones y crear URLs. @@ -649,4 +657,4 @@ especificas y/o las que se usen más a menudo. Si algunas URLs comparten el mismo prefijo en sus patrones o rutas, se puede considerar usar [[yii\web\GroupUrlRule]] ya que puede ser más eficiente al ser examinado por [[yii\web\UrlManager|URL manager]] como un grupo. Este suele ser el caso cuando una aplicación se compone por módulos, y cada uno tiene su propio conjunto de reglas con un ID de -módulo para sus prefijos más comunes. \ No newline at end of file +módulo para sus prefijos más comunes. diff --git a/docs/guide-es/runtime-sessions-cookies.md b/docs/guide-es/runtime-sessions-cookies.md index 4a7537d..400801b 100644 --- a/docs/guide-es/runtime-sessions-cookies.md +++ b/docs/guide-es/runtime-sessions-cookies.md @@ -4,12 +4,12 @@ Sesiones (Sessions) y Cookies Las sesiones y las cookies permiten la persistencia de datos a través de múltiples peticiones de usuario. En PHP plano, debes acceder a ellos a través de las variables globales `$_SESSION` y `$_COOKIE`, respectivamente. Yii encapsula las sesiones y las cookies como objetos y por lo tanto te permite acceder a ellos de manera orientada a objetos con estupendas mejoras adicionales. -## Sesiones +## Sesiones Como las [peticiones](runtime-requests.md) y las [respuestas](runtime-responses.md), puedes acceder a las sesiones vía el [componente de la aplicación](structure-application-components.md) `session` el cual es una instancia de [[yii\web\Session]], por defecto. -### Abriendo y cerrando sesiones +### Abriendo y cerrando sesiones Para abrir y cerrar una sesión, puedes hacer lo siguiente: @@ -32,7 +32,7 @@ $session->destroy(); Puedes llamar a [[yii\web\Session::open()|open()]] y [[yii\web\Session::close()|close()]] múltiples veces sin causar errores. Esto ocurre porque internamente los métodos verificarán primero si la sesión está ya abierta. -### Accediendo a los datos de sesión +### Accediendo a los datos de sesión Para acceder a los datos almacenados en sesión, puedes hacer lo siguiente: @@ -114,7 +114,7 @@ $session['captcha.lifetime'] = 3600; Para un mejor rendimiento y legibilidad del código, recomendamos la última solución. Es decir, en vez de almacenar un array como una única variable de sesión, almacena cada elemento del array como una variable de sesión que comparta el mismo prefijo clave con otros elementos del array. -### Personalizar el almacenamiento de sesión +### Personalizar el almacenamiento de sesión Por defecto la clase [[yii\web\Session]] almacena los datos de sesión como ficheros en el servidor. Yii también provee de las siguientes clases de sesión que implementan diferentes almacenamientos de sesión: @@ -161,7 +161,7 @@ donde 'BLOB' se refiere al BLOB-type de tu DBMS preferida. Abajo está el tipo B > Nota: De acuerdo con la configuración de php.ini `session.hash_function`, puedes necesitar ajustar el tamaño de la columna `id`. Por ejemplo, si `session.hash_function=sha256`, deberías usar el tamaño 64 en vez de 40. -### Flash Data +### Flash Data Flash data es una clase especial de datos de sesión que, una vez se inicialice en la primera petición, estará sólo disponible durante la siguiente petición y automáticamente se borrará después. Flash data es comúnmente usado para implementar mensajes que deberían ser mostrados una vez a usuarios finales, tal como mostrar un mensaje de confirmación después de que un usuario envíe un formulario con éxito. @@ -207,13 +207,13 @@ $alerts = $session->getFlash('alerts'); del mismo nombre. Esto ocurre porque el último método elimina el flash data dentro del array así que puedes añadir un nuevo flash data con el mismo nombre. Como resultado, cuando llamas a [[yii\web\Session::getFlash()]], puedes encontrarte algunas veces que te está devolviendo un array mientras que otras veces te está devolviendo un string, esto depende del orden que invoques a estos dos métodos. -## Cookies +## Cookies Yii representa cada cookie como un objeto de [[yii\web\Cookie]]. Tanto [[yii\web\Request]] como [[yii\web\Response]] mantienen una colección de cookies vía la propiedad de llamada `cookies`. La colección de cookie en la antigua representación son enviadas en una petición, mientras la colección de cookie en esta última representa las cookies que van a ser enviadas al usuario. -### Leyendo Cookies +### Leyendo Cookies Puedes recuperar las cookies en la petición actual usando el siguiente código: @@ -240,7 +240,7 @@ if (isset($cookies['language'])) ... ``` -### Enviando Cookies +### Enviando Cookies Puedes enviar cookies a usuarios finales usando el siguiente código: @@ -265,7 +265,7 @@ Además de [[yii\web\Cookie::name|name]], [[yii\web\Cookie::value|value]] las pr > Nota: Para mayor seguridad, el valor por defecto de [[yii\web\Cookie::httpOnly]] es true. Esto ayuda a mitigar el riesgo del acceso a la cookie protegida por script desde el lado del cliente (si el navegador lo soporta). Puedes leer el [httpOnly wiki article](https://www.owasp.org/index.php/HttpOnly) para más detalles. -### Validación de la Cookie +### Validación de la Cookie Cuando estás leyendo y enviando cookies a través de los componentes `request` y `response` como mostramos en las dos últimas subsecciones, cuentas con el añadido de seguridad de la validación de cookies el cual protege las cookies de ser modificadas en el lado del cliente. Esto se consigue con la firma de cada cookie con una cadena hash, el cual permite a la aplicación saber si una cookie ha sido modificada en el lado del cliente o no. Si es así, la cookie no será accesible a través de [[yii\web\Request::cookies|cookie collection]] del componente `request`. diff --git a/docs/guide-es/start-databases.md b/docs/guide-es/start-databases.md index a9f6a28..fb9f496 100644 --- a/docs/guide-es/start-databases.md +++ b/docs/guide-es/start-databases.md @@ -18,7 +18,7 @@ En particular, deberás ser capaz de crear una base de datos y saber ejecutar co base de datos. -Preparando una Base de Datos +Preparando una Base de Datos ---------------------------- Para empezar, crea una base de datos llamada `yii2basic` de la cual tomarás los datos en la aplicación. @@ -50,7 +50,7 @@ Al final, tendrás una base de datos llamada `yii2basic`, y dentro de esta, una registros en ella. -Configurando una conexión a la Base de Datos +Configurando una conexión a la Base de Datos -------------------------------------------- Asegúrate de tener instalado la extensión de PHP [PDO](http://www.php.net/manual/es/book.pdo.php) y el driver @@ -83,7 +83,7 @@ La conexión a la base de datos realizada anteriormente puede ser accedida media Para más información, consulta la sección [Configuraciones](concept-configurations.md). -Creando un Active Record +Creando un Active Record ------------------------ Para representar y extraer datos de la tabla `country`, crea una clase [Active Record](db-active-record.md) @@ -131,7 +131,7 @@ Puedes encontrar información más detallada acerca de [Active Record](db-active puedes utilizar un método de acceso de bajo nivel llamado [Data Access Objects](db-dao.md). -Creando una Acción +Creando una Acción ------------------ Para mostrar el país a los usuarios, necesitas crear una acción. En vez de hacerlo en el controlador `site` @@ -188,7 +188,7 @@ Al final, la acción `index` renderiza una vista llamada `index` y le pasa los d de paginación relacionada. -Creando una Vista +Creando una Vista ----------------- Bajo el directorio `views`, crea primero un sub-directorio llamado `country`. Este será usado para contener @@ -220,7 +220,7 @@ El widget `LinkPager` muestra una lista de botones que representan las páginas de ellas mostrará los datos de países de la página correspondiente. -Probándolo +Probándolo ---------- Para ver cómo funciona, utiliza a la siguiente URL en tu navegador: @@ -252,7 +252,7 @@ Entre bastidores, [[yii\data\Pagination|Pagination]] está realizando su magia. siguientes cinco países para mostrar. -Resumen +Resumen ------- En esta sección has aprendido cómo trabajar con una base de datos. También has aprendido cómo traer y mostrar diff --git a/docs/guide-es/start-forms.md b/docs/guide-es/start-forms.md index 6788fc4..2516677 100644 --- a/docs/guide-es/start-forms.md +++ b/docs/guide-es/start-forms.md @@ -15,7 +15,7 @@ A través de este tutorial, aprenderás * Cómo construir un formulario HTML en una [vista](structure-views.md). -Creando un Modelo +Creando un Modelo ----------------- Para representar los datos ingresados por un usuario, crea una clase modelo `EntryForm` cómo se muestra abajo y @@ -60,7 +60,7 @@ de los datos se mostrará en la propiedad [[yii\base\Model::hasErrors|hasErrors] [[yii\base\Model::getErrors|errors]] puedes aprender cuales son los errores de validación que tiene el modelo. -Creando una Acción +Creando una Acción ------------------ Luego, crea una acción `entry` en el controlador `site`, como lo hiciste en la sección anterior. @@ -112,7 +112,7 @@ mostrada, y mostrará el formulario HTML junto con los mensajes de error de vali En el código de arriba, el componente `request` es utilizado para acceder los datos `$_POST`. -Creando Vistas +Creando Vistas -------------- Finalmente, crea dos vistas llamadas `entry-confirm` y `entry` que sean mostradas por la acción `entry`, @@ -160,7 +160,7 @@ y el segundo del dato "email". Después de los campos de input, el método [[yii es llamado para general el botón de submit (enviar). -Probándolo +Probándolo ---------- Para ver cómo funciona, utiliza tu navegador para ir al siguiente URL: @@ -182,7 +182,7 @@ mostrando los datos que acabas de ingresar. -### Magia Explicada +### Magia Explicada Te estarás preguntando cómo funciona toda esa automatización del formulario HTML, porque parece casi mágico que pueda mostrar una etiqueta para cada campo de input y mostrar los mensajes de error si no ingresas los datos correctamente @@ -208,7 +208,7 @@ el siguiente código: código de tus vistas en widgets reutilizables para simplificar el desarrollo de las vistas en un futuro. -Resumen +Resumen ------- En esta sección, has tocado cada parte del patrón de diseño MVC. Ahora has aprendido diff --git a/docs/guide-es/start-gii.md b/docs/guide-es/start-gii.md index 4a67d8e..709acc0 100644 --- a/docs/guide-es/start-gii.md +++ b/docs/guide-es/start-gii.md @@ -13,7 +13,7 @@ A lo largo de este tutorial, aprenderás * Cómo personalizar el código generado por Gii. -Comenzando con Gii +Comenzando con Gii ------------------ [Gii](tool-gii.md) está provisto por Yii en forma de [módulo](structure-modules.md). Puedes habilitar Gii @@ -47,7 +47,7 @@ http://hostname/index.php?r=gii ![Gii](images/start-gii.png) -Generando una Clase Active Record +Generando una Clase Active Record --------------------------------- Para poder generar una clase Active Record con Gii, selecciona "Model Generator" (haciendo click en el vínculo que existe en la página inicial del modulo Gii). Después, completa el formulario de la siguiente manera, @@ -71,7 +71,7 @@ Después, verás una página de confirmación indicando que el código ha sido g ha sido sobrescrito con el nuevo código generado. -Generando código de ABM (CRUD en inglés) +Generando código de ABM (CRUD en inglés) ---------------------------------------- En computación, CRUD es el acrónimo de Crear, Obtener, Actualizar y Borrar (del inglés: Create, Read, Update y Delete) @@ -90,7 +90,7 @@ Si has creado previamente los archivos `controllers/CountryController.php` y `views/country/index.php` (en la sección sobre bases de datos de esta guía), asegúrate de seleccionar el checkbox "overwrite" para reemplazarlos. (Las versiones anteriores no disponían de un soporte ABM (CRUD) completo.) -Probándolo +Probándolo ---------- Para ver cómo funciona, accede desde tu navegador a la siguiente URL: @@ -122,7 +122,7 @@ o por si desearas personalizarlos: sección [Gii](tool-gii.md). -Resumen +Resumen ------- En esta sección, has aprendido a utilizar Gii para generar el código que implementa completamente las características diff --git a/docs/guide-es/start-hello.md b/docs/guide-es/start-hello.md index cc32eb8..76ff1da 100644 --- a/docs/guide-es/start-hello.md +++ b/docs/guide-es/start-hello.md @@ -15,7 +15,7 @@ A lo largo de este tutorial, aprenderás tres cosas: 3. Cómo una aplicación envía peticiones a las [acciones](structure-controllers.md#creating-actions). -Creando una Acción +Creando una Acción ------------------ Para la tarea "Hola", crearás una [acción](structure-controllers.md#creating-actions) `say` que lee @@ -70,7 +70,7 @@ El resultado es devuelto al método de la acción. Ese resultado será recibido navegador (como parte de una página HTML completa). -Creando una Vista +Creando una Vista ----------------- Las [vistas](structure-views.md) son scripts que escribes para generar una respuesta de contenido. @@ -95,7 +95,7 @@ De hecho, la vista `say` es sólo un script PHP que es ejecutado por el método El contenido impreso por el script de la vista será regresado a la aplicación como la respuesta del resultado. La aplicación a cambio mostrará el resultado al usuario final. -Probándolo +Probándolo ---------- Después de crear la acción y la vista, puedes acceder a la nueva página abriendo el siguiente URL: @@ -127,7 +127,7 @@ el método `SiteController::actionSay()` será llamado para manejar el requerimi al nombre de clase del controlador `PostComentarioController`. -Resumen +Resumen ------- En esta sección, has tocado las partes del controlador y la vista del patrón de diseño MVC. diff --git a/docs/guide-es/start-installation.md b/docs/guide-es/start-installation.md index d97861d..837b9a5 100644 --- a/docs/guide-es/start-installation.md +++ b/docs/guide-es/start-installation.md @@ -1,19 +1,19 @@ Instalando Yii ============== -Yii puede ser instalado de dos maneras, usando [Composer](http://getcomposer.org/) o descargando un archivo comprimido. +Yii puede ser instalado de dos maneras, usando [Composer](https://getcomposer.org/) o descargando un archivo comprimido. Es preferible usar la primera forma, ya que te permite instalar [extensiones](structure-extensions.md) o actualizar Yii ejecutando un simple comando. > Nota: A diferencia de Yii 1, la instalación estándar de Yii 2 resulta en la descarga e instalación tanto del framework como del esqueleto de la aplicación. -Instalando a través de Composer +Instalando a través de Composer ------------------------------- Si aún no tienes Composer instalado, puedes hacerlo siguiendo las instrucciones que se encuentran en [getcomposer.org](https://getcomposer.org/download/). En Linux y Mac OS X, se ejecutan los siguientes comandos: - curl -s http://getcomposer.org/installer | php + curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer En Windows, tendrás que descargar y ejecutar [Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe). @@ -26,7 +26,7 @@ Si ya tienes composer instalado asegurate que esté actualizado ejecutando `comp Teniendo Composer instalado, puedes instalar Yii ejecutando los siguientes comandos en un directorio accesible vía Web: Nota: es posible que en al ejecutar el primer comando te pida tu username - composer global require "fxp/composer-asset-plugin:1.0.0-beta4" + composer global require "fxp/composer-asset-plugin:~1.0.0" composer create-project --prefer-dist yiisoft/yii2-app-basic basic El comando anterior instala Yii dentro del directorio `basic`. @@ -39,7 +39,7 @@ El comando anterior instala Yii dentro del directorio `basic`. > Ten en cuenta que la versión de desarrollo de Yii no debería ser usada para producción ya que podría romper el funcionamiento actual de la aplicación. -Instalando desde un Archivo Comprimido +Instalando desde un Archivo Comprimido -------------------------------------- Instalar Yii desde un archivo comprimido involucra dos pasos: @@ -48,7 +48,7 @@ Instalar Yii desde un archivo comprimido involucra dos pasos: 2. Descomprimirlo en un directorio accesible vía Web. -Otras Opciones de Instalación +Otras Opciones de Instalación ----------------------------- Las instrucciones anteriores muestran cómo instalar Yii, lo que también crea una aplicación Web lista para ser usada. @@ -62,7 +62,7 @@ Pero también hay otras opciones de instalación disponibles: deberías considerar instalar el [Template de Aplicación Avanzada](tutorial-advanced-app.md). -Verificando las Instalación +Verificando las Instalación --------------------------- Después de la instalación, puedes acceder a la aplicación instalada a través de la siguiente URL: @@ -92,7 +92,7 @@ También deberías instalar la [Extensión de PHP PDO](http://www.php.net/manual (como `pdo_mysql` para bases de datos MySQL), si tu aplicación lo necesitara. -Configurando Servidores Web +Configurando Servidores Web --------------------------- > Información: Puedes saltear esta sección por ahora si sólo estás probando Yii sin intención de poner la aplicación en un servidor de producción. @@ -115,7 +115,7 @@ la configuración del servidor Web, aún puedes ajustar la estructura de la apli la sección [Entorno de Hosting Compartido](tutorial-shared-hosting.md) para más detalles. -### Configuración Recomendada de Apache +### Configuración Recomendada de Apache Utiliza la siguiente configuración del archivo `httpd.conf` de Apache dentro de la configuración del virtual host. Ten en cuenta que deberás reemplazar `path/to/basic/web` con la ruta real a `basic/web`. @@ -138,7 +138,7 @@ DocumentRoot "path/to/basic/web" ``` -### Configuración Recomendada de Nginx +### Configuración Recomendada de Nginx Deberías haber instalado PHP como un [FPM SAPI](http://php.net/install.fpm) para utilizar [Nginx](http://wiki.nginx.org/). Utiliza la siguiente configuración de Nginx, reemplazando `path/to/basic/web` con la ruta real a `basic/web` y `mysite.local` con el diff --git a/docs/guide-es/start-workflow.md b/docs/guide-es/start-workflow.md index 5b16378..d2c952c 100644 --- a/docs/guide-es/start-workflow.md +++ b/docs/guide-es/start-workflow.md @@ -12,7 +12,7 @@ y cómo la aplicación maneja los requests en general. Dependiendo de tus necesidades, por favor ajusta dichas URLs. -Funcionalidad +Funcionalidad ------------- La aplicación básica contiene 4 páginas: @@ -32,7 +32,7 @@ Esta es la útil [herramienta de depuración](tool-debugger.md) provista por Yii tal como los mensajes de log, response status, las consultas ejecutadas a la base de datos, y más. -Estructura de la aplicación +Estructura de la aplicación --------------------------- Los archivos y directorios más importantes en tu aplicación son (asumiendo que la raíz de la aplicación es `basic`): @@ -74,7 +74,7 @@ y la envía al resto de los elementos MVC. Los [widgets](structure-widgets.md) s para ayudar a construir elementos de interfáz complejos y dinámicos. -Ciclo de Vida de una Petición (Request) +Ciclo de Vida de una Petición (Request) --------------------------------------- El siguiente diagrama muestra cómo una aplicación maneja una petición. diff --git a/docs/guide-es/structure-application-components.md b/docs/guide-es/structure-application-components.md index fd43963..c264587 100644 --- a/docs/guide-es/structure-application-components.md +++ b/docs/guide-es/structure-application-components.md @@ -48,7 +48,7 @@ Por ejemplo: y utilizarlo únicamente cuando sea necesario. -## Componentes del Núcleo de la Aplicación +## Componentes del Núcleo de la Aplicación Yii define un grupo de componentes del *núcleo* con IDs fijos y configuraciones por defecto. Por ejemplo, el componente [[yii\web\Application::request|request]] es utilizado para recolectar información acerca diff --git a/docs/guide-es/structure-applications.md b/docs/guide-es/structure-applications.md index 024fee8..752bc0d 100644 --- a/docs/guide-es/structure-applications.md +++ b/docs/guide-es/structure-applications.md @@ -14,7 +14,7 @@ Hay dos tipos de aplicaciones: [[yii\web\Application|aplicaciones Web]] y Web requests mientras que la última maneja requests (peticiones) de la línea de comandos. -## Configuraciones de las Aplicaciones +## Configuraciones de las Aplicaciones Cuando un [script de entrada](structure-entry-scripts.md) crea una aplicación, cargará una [configuración](concept-configurations.md) y la aplicará a la aplicación, como se muestra a continuación: @@ -36,7 +36,7 @@ suelen ser complejas, son usualmente guardadas en [archivos de configuración](c como en el archivo `web.php` del ejemplo anterior. -## Propiedades de la Aplicación +## Propiedades de la Aplicación Hay muchas propiedades importantes en la aplicación que deberían configurarse en en la configuración de la aplicación. Estas propiedades suelen describir el entorno en el cual la aplicación está corriendo. @@ -44,20 +44,20 @@ Por ejemplo, las aplicaciones necesitan saber cómo cargar [controladores](struc dónde guardar archivos temporales, etc. A continuación, resumiremos esas propiedades. -### Propiedades Requeridas +### Propiedades Requeridas En cualquier aplicación, debes configurar al menos dos propiedades: [[yii\base\Application::id|id]] y [[yii\base\Application::basePath|basePath]]. -#### [[yii\base\Application::id|id]] +#### [[yii\base\Application::id|id]] La propiedad [[yii\base\Application::id|id]] especifica un ID único que diferencia una aplicación de otras. Es mayormente utilizada a nivel programación. A pesar de que no es un requerimiento, para una mejor interoperabilidad, se recomienda utilizar sólo caracteres alfanuméricos. -#### [[yii\base\Application::basePath|basePath]] +#### [[yii\base\Application::basePath|basePath]] La propiedad [[yii\base\Application::basePath|basePath]] especifica el directorio raíz de una aplicación. Es el directorio que alberga todos los archivos protegidos de un sistema. Bajo este directorio, @@ -73,13 +73,13 @@ La propiedad [[yii\base\Application::basePath|basePath]] es utilizada a menudo d Rutas derivadas pueden ser entonces creadas a partir de este alias (ej. `@app/runtime` para referirse al directorio `runtime`). -### Propiedades Importantes +### Propiedades Importantes Las propiedades descritas en esta subsección a menudo necesita ser configurada porque difieren entre las diferentes aplicaciones. -#### [[yii\base\Application::aliases|aliases]] +#### [[yii\base\Application::aliases|aliases]] Esta propiedad te permite definir un grupo de [alias](concept-aliases.md) en términos de un array (matriz). Las claves del array son los nombres de los alias, y los valores su correspondiente definición. @@ -98,7 +98,7 @@ Esta propiedad está provista de tal manera que puedas definir alias en término en vez de llamadas al método [[Yii::setAlias()]]. -#### [[yii\base\Application::bootstrap|bootstrap]] +#### [[yii\base\Application::bootstrap|bootstrap]] Esta es una propiedad importante. Te permite definir un array de los componentes que deben ejecutarse durante el [[yii\base\Application::bootstrap()|proceso de `bootstrapping`]] de la aplicación. @@ -154,7 +154,7 @@ if (YII_ENV_DEV) { por cada request, se necesita correr el mismo grupo de componentes. Por lo tanto, utiliza componentes `bootstrap` con criterio. -#### [[yii\web\Application::catchAll|catchAll]] +#### [[yii\web\Application::catchAll|catchAll]] Esta propiedad está solamente soportada por [[yii\web\Application|aplicaciones Web]]. Especifica la [acción de controlador](structure-controllers.md) que debería manejar todos los requests (peticiones) del usuario. @@ -176,7 +176,7 @@ Por ejemplo: ``` -#### [[yii\base\Application::components|components]] +#### [[yii\base\Application::components|components]] Esta es la propiedad más importante. Te permite registrar una lista de componentes llamados [componentes de aplicación](#structure-application-components.md) que puedes utilizar en otras partes de tu aplicación. Por ejemplo: @@ -204,7 +204,7 @@ la expresión `\Yii::$app->ComponentID`. Por favor, lee la sección [Componentes de la Aplicación](structure-application-components.md) para mayor detalle. -#### [[yii\base\Application::controllerMap|controllerMap]] +#### [[yii\base\Application::controllerMap|controllerMap]] Esta propiedad te permite mapear un ID de controlador a una clase de controlador arbitraria. Por defecto, Yii mapea ID de controladores a clases de controladores basado en una [convención](#controllerNamespace) (ej. el ID `post` será mapeado @@ -230,7 +230,7 @@ Las claves de este array representan los ID de los controladores, mientras que l los nombres de clase de dichos controladores o una [configuración](concept-configurations.md). -#### [[yii\base\Application::controllerNamespace|controllerNamespace]] +#### [[yii\base\Application::controllerNamespace|controllerNamespace]] Esta propiedad especifica el `namespace` bajo el cual las clases de los controladores deben ser ubicados. Por defecto es `app\controllers`. Si el ID es `post`, por convención el controlador correspondiente (sin @@ -246,7 +246,7 @@ un error "Page Not Found" ("Página no Encontrada") cuando accedas a la aplicaci En caso de que quieras romper con la convención cómo se comenta arriba, puedes configurar la propiedad [controllerMap](#controllerMap). -#### [[yii\base\Application::language|language]] +#### [[yii\base\Application::language|language]] Esta propiedad especifica el idioma en el cual la aplicación debería mostrar el contenido a los usuarios. El valor por defecto de esta propiedad es `en`, referido a English. Deberías configurar esta propiedad @@ -263,7 +263,7 @@ Por ejemplo, `en` se refiere a English, mientras que `en-US` se refiere a Englis Se pueden encontrar más detalles de este aspecto en la sección [Internacionalización](tutorial-i18n.md). -#### [[yii\base\Application::modules|modules]] +#### [[yii\base\Application::modules|modules]] Esta propiedad especifica los [módulos](structure-modules.md) que contiene la aplicación. @@ -288,7 +288,7 @@ los IDs de los módulos. Por ejemplo: Por favor consulta la sección [Módulos](structure-modules.md) para más detalles. -#### [[yii\base\Application::name|name]] +#### [[yii\base\Application::name|name]] Esta propiedad especifica el nombre de la aplicación que será mostrado a los usuarios. Al contrario de [[yii\base\Application::id|id]], que debe tomar un valor único, el valor de esta propiedad existe principalmente @@ -297,7 +297,7 @@ para propósito de visualización y no tiene porqué ser única. No siempre necesitas configurar esta propiedad si en tu aplicación no va a ser utilizada. -#### [[yii\base\Application::params|params]] +#### [[yii\base\Application::params|params]] Esta propiedad especifica un array con parámetros accesibles desde cualquier lugar de tu aplicación. En vez de usar números y cadenas fijas por todos lados en tu código, es una buena práctica definirlos como @@ -323,7 +323,7 @@ Más adelante, si decides cambiar el tamaño de las miniaturas, sólo necesitas sin necesidad de tocar el código que lo utiliza. -#### [[yii\base\Application::sourceLanguage|sourceLanguage]] +#### [[yii\base\Application::sourceLanguage|sourceLanguage]] Esta propiedad especifica el idioma en el cual la aplicación está escrita. El valor por defecto es `'en-US'`, referido a English (United States). Deberías configurar esta propiedad si el contenido de texto en tu código no está en inglés. @@ -334,7 +334,7 @@ Por ejemplo, `en` se refiere a English, mientras que `en-US` se refiere a Englis Puedes encontrar más detalles de esta propiedad en la sección [Internacionalización](tutorial-i18n.md). -#### [[yii\base\Application::timeZone|timeZone]] +#### [[yii\base\Application::timeZone|timeZone]] Esta propiedad es provista como una forma alternativa de definir el `time zone` de PHP por defecto en tiempo de ejecución. Configurando esta propiedad, escencialmente estás llamando a la función de PHP [date_default_timezone_set()](http://php.net/manual/es/function.date-default-timezone-set.php). @@ -347,25 +347,25 @@ Por ejemplo: ``` -#### [[yii\base\Application::version|version]] +#### [[yii\base\Application::version|version]] Esta propiedad especifica la versión de la aplicación. Es por defecto `'1.0'`. No hay total necesidad de configurarla si tu no la usarás en tu código. -### Propiedades Útiles +### Propiedades Útiles Las propiedades especificadas en esta sub-sección no son configuradas normalmente ya que sus valores por defecto estipulan convenciones comunes. De cualquier modo, aún puedes configurarlas en caso de que quieras romper con la convención. -#### [[yii\base\Application::charset|charset]] +#### [[yii\base\Application::charset|charset]] Esta propiedad especifica el `charset` que la aplicación utiliza. El valor por defecto es `'UTF-8'`, que debería ser mantenido tal cual para la mayoría de las aplicaciones a menos que estés trabajando con sistemas legados que utilizan muchos datos no-unicode. -#### [[yii\base\Application::defaultRoute|defaultRoute]] +#### [[yii\base\Application::defaultRoute|defaultRoute]] Esta propiedad especifica la [ruta](runtime-routing.md) que una aplicación debería utilizar si el `request` no especifica una. La ruta puede consistir el ID de un sub-módulo, el ID de un controlador, y/o el ID de una acción. @@ -381,12 +381,12 @@ Para [yii\console\Application|aplicaciones de consola], el valor por defecto es sin proveer ningún argumento, mostrará la información de ayuda. -#### [[yii\base\Application::extensions|extensions]] +#### [[yii\base\Application::extensions|extensions]] Esta propiedad especifica la lista de [extensiones](structure-extensions.md) que se encuentran instaladas y son utilizadas por la aplicación. Por defecto, tomará el array devuelto por el archivo `@vendor/yiisoft/extensions.php`. El archivo `extensions.php` -es generado y mantenido automáticamente cuando utilizas [Composer](http://getcomposer.org) para instalar extensiones. +es generado y mantenido automáticamente cuando utilizas [Composer](https://getcomposer.org) para instalar extensiones. Por lo tanto, en la mayoría de los casos no necesitas configurarla. En el caso especial de que quieras mantener las extensiones a mano, puedes configurar la propiedad como se muestra a continuación: @@ -416,7 +416,7 @@ un elemento `bootstrap` puede ser especificado con un nombre de clase o un array Una extensión también puede definir algunos [alias](concept-aliases.md). -#### [[yii\base\Application::layout|layout]] +#### [[yii\base\Application::layout|layout]] Esta propiedad especifica el valor del `layout` por defecto que será utilizado al renderizar una [vista](structure-views.md). El valor por defecto es `'main'`, y se refiere al archivo `main.php` bajo el [`layout path`](#layoutPath) definido. @@ -427,7 +427,7 @@ Puedes configurar esta propiedad con el valor `false` si quieres desactivar el ` caso muy raro. -#### [[yii\base\Application::layoutPath|layoutPath]] +#### [[yii\base\Application::layoutPath|layoutPath]] Esta propiedad especifica el lugar por defecto donde deben buscarse los archivos `layout`. El valor por defecto es el sub-directorio `layouts` bajo el [`view path`](#viewPath). Si el [`view path`](#viewPath) usa su valor por defecto, @@ -436,7 +436,7 @@ el `layout path` puede ser representado con el alias `@app/views/layouts`. Puedes configurarlo como un directorio o utilizar un [alias](concept-aliases.md). -#### [[yii\base\Application::runtimePath|runtimePath]] +#### [[yii\base\Application::runtimePath|runtimePath]] Esta propiedad especifica dónde serán guardados los archivos temporales, como archivos de log y de cache, pueden ser generados. El valor por defecto de esta propiedad es el alias `@app/runtime`. @@ -448,15 +448,15 @@ de ser accedido por usuarios finales, ya que los archivos generados pueden tener Para simplificar el acceso a este directorio, Yii trae predefinido el alias `@runtime` para él. -#### [[yii\base\Application::viewPath|viewPath]] +#### [[yii\base\Application::viewPath|viewPath]] Esta propiedad especifica dónde están ubicados los archivos de la vista. El valor por defecto de esta propiedad está representado por el alias `@app/views`. Puedes configurarlo como un directorio o utilizar un [alias](concept-aliases.md). -#### [[yii\base\Application::vendorPath|vendorPath]] +#### [[yii\base\Application::vendorPath|vendorPath]] -Esta propiedad especifica el directorio `vendor` que maneja [Composer](http://getcomposer.org). Contiene +Esta propiedad especifica el directorio `vendor` que maneja [Composer](https://getcomposer.org). Contiene todas las librerías de terceros utilizadas por tu aplicación, incluyendo el núcleo de Yii. Su valor por defecto está representado por el alias `@app/vendor`. @@ -466,14 +466,14 @@ asegúrate de ajustar la configuración de Composer en concordancia. Para simplificar el acceso a esta ruta, Yii trae predefinido el alias `@vendor`. -#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] +#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] Esta propiedad está sólo soportada por [[yii\console\Application|aplicaciones de consola]]. Especifica si los comandos de consola incluidos en Yii deberían estar habilitados o no. Por defecto está definido como `true`. -## Eventos de la Aplicación +## Eventos de la Aplicación Una aplicación dispara varios eventos durante su ciclo de vida al manejar un `request`. Puedes conectar manejadores a dichos eventos en la configuración de la aplicación como se muestra a continuación: @@ -497,7 +497,7 @@ después de que la instancia de la aplicación es creada. Por ejemplo: }); ``` -### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] +### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] Este evento es disparado *before* (antes) de que la aplicación maneje el `request`. El nombre del evento es `beforeRequest`. @@ -507,7 +507,7 @@ Por ejemplo, en el manejador del evento, podrías definir dinámicamente la prop basada en algunos parámetros. -### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_REQUEST]] +### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_REQUEST]] Este evento es disparado *after* (después) de que una aplicación finaliza el manejo de un `request` pero *before* (antes) de enviar el `response` (respuesta). El nombre del evento es `afterRequest`. @@ -519,7 +519,7 @@ Ten en cuenta que el componente [[yii\web\Response|response]] también dispara a a los usuarios finales. Estos eventos son disparados *after* (después) de este evento. -### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_ACTION]] +### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_ACTION]] Este evento es disparado *before* (antes) de ejecutar cualquier [acción de controlador](structure-controllers.md). El nombre de este evento es `beforeAction`. @@ -545,7 +545,7 @@ seguidos por módulos (si los hubiera), y finalmente controladores. Si un maneja como `false`, todos los eventos siguientes NO serán disparados. -### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_ACTION]] +### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_ACTION]] Este evento es disparado *after* (después) de ejecutar cualquier [acción de controlador](structure-controllers.md). El nombre de este evento es `afterAction`. @@ -571,7 +571,7 @@ que los de `beforeAction`. Esto quiere decir que los controladores son los prime seguido por módulos (si los hubiera), y finalmente aplicaciones. -## Ciclo de Vida de una Aplicación +## Ciclo de Vida de una Aplicación Cuando un [script de entrada](structure-entry-scripts.md) está siendo ejecutado para manejar un `request`, una aplicación experimenta el siguiente ciclo de vida: diff --git a/docs/guide-es/structure-assets.md b/docs/guide-es/structure-assets.md index cfaad01..8f3ea95 100644 --- a/docs/guide-es/structure-assets.md +++ b/docs/guide-es/structure-assets.md @@ -1,30 +1,30 @@ Assets ====== -Un asset en Yii es un archivo al que se puede hacer referencia en una página Web. Puede ser un archivo CSS, un archivo -JavaScript, una imagen o un archivo de vídeo, etc. Los assets se encuentran en los directorios públicos de la web y se +Un asset en Yii es un archivo al que se puede hacer referencia en una página Web. Puede ser un archivo CSS, un archivo +JavaScript, una imagen o un archivo de video, etc. Los assets se encuentran en los directorios públicos de la web y se sirven directamente por los servidores Web. -A menudo es preferible gestionar los assets mediante programación. Por ejemplo, cuando se usa el widget -[[yii\jui\DatePicker]] en una página, éste incluirá automáticamente los archivos CSS y JavaScript requeridos, en vez -de tener que buscar los archivos e incluirlos manualmente. Y cuando se actualice el widget a una nueva versión, ésta +A menudo es preferible gestionar los assets mediante programación. Por ejemplo, cuando se usa el widget +[[yii\jui\DatePicker]] en una página, éste incluirá automáticamente los archivos CSS y JavaScript requeridos, en vez +de tener que buscar los archivos e incluirlos manualmente. Y cuando se actualice el widget a una nueva versión, ésta usará de forma automática la nueva versión de los archivos asset. En este tutorial, se describirá la poderosa capacidad que proporciona la gestión de assets en Yii. -## Asset Bundles +## Asset Bundles -Yii gestiona los assets en unidades de *asset bundle*. Un asset bundle es simplemente un conjunto de assets -localizados en un directorio. Cuando se registra un asset bundle en una [vista](structure-views.md), éste incluirá los +Yii gestiona los assets en unidades de *asset bundle*. Un asset bundle es simplemente un conjunto de assets +localizados en un directorio. Cuando se registra un asset bundle en una [vista](structure-views.md), éste incluirá los archivos CSS y JavaScript del bundle en la página Web renderizada. -## Definición de Asset Bundles +## Definición de Asset Bundles -Los asset bundles son descritos como clases PHP que extienden a [[yii\web\AssetBundle]]. El nombre del bundle es -simplemente su correspondiente nombre de la classe PHP que debe ser [autocargable](concept-autoloading.md). En una -clase asset bundle, lo más habitual es especificar donde se encuentran los archivos asset, que archivos CSS y -JavaScript contiene el bundle, y como depende éste bundle de otros bundles. +Los asset bundles son descritos como clases PHP que extienden a [[yii\web\AssetBundle]]. El nombre del bundle es +simplemente su correspondiente nombre de la classe PHP que debe ser [autocargable](concept-autoloading.md). En una +clase asset bundle, lo más habitual es especificar donde se encuentran los archivos asset, que archivos CSS y +JavaScript contiene el bundle, y como depende este bundle de otros bundles. -El siguiente código define el asset bundle principal que se usa en +El siguiente código define el asset bundle principal que se usa en [la plantilla de aplicación básica](start-installation.md): ```php @@ -50,99 +50,99 @@ class AppAsset extends AssetBundle } ``` -La anterior clase `AppAsset` especifica que los archivos asset se encuentran en el directorio `@webroot` que -corresponde a la URL `@web`; el bundle contiene un único archivo CSS `css/site.css` y ningún archivo JavaScript; -el bundle depende de otros dos bundles: [[yii\web\YiiAsset]] y [[yii\bootstrap\BootstrapAsset]]. +La anterior clase `AppAsset` especifica que los archivos asset se encuentran en el directorio `@webroot` que +corresponde a la URL `@web`; el bundle contiene un único archivo CSS `css/site.css` y ningún archivo JavaScript; +el bundle depende de otros dos bundles: [[yii\web\YiiAsset]] y [[yii\bootstrap\BootstrapAsset]]. A continuación se explicarán más detalladamente las propiedades del [[yii\web\AssetBundle]]: -* [[yii\web\AssetBundle::sourcePath|sourcePath]]: especifica el directorio raiz que contiene los archivos asset en el - bundle. Si no, se deben especificar las propiedades [[yii\web\AssetBundle::basePath|basePath]] y +* [[yii\web\AssetBundle::sourcePath|sourcePath]]: especifica el directorio raíz que contiene los archivos asset en el + bundle. Si no, se deben especificar las propiedades [[yii\web\AssetBundle::basePath|basePath]] y [[yii\web\AssetBundle::baseUrl|baseUrl]], en su lugar. Se pueden usar [alias de ruta](concept-aliases.md). -* [[yii\web\AssetBundle::basePath|basePath]]: especifica el directorio Web público que contiene los archivos assets de - este bundle. Cuando se especifica la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]], el [gestor de - assets](#asset-manager) publicara los assets de este bundle en un directorio Web publico y sobrescribirá la - propiedad en consecuencia. Se debe establecer esta propiedad si los archivos asset ya se encuentran en un directorio - Web publico y no necesitan ser publicados. Se pueden usar [alias de ruta](concept-aliases.md). +* [[yii\web\AssetBundle::basePath|basePath]]: especifica el directorio Web público que contiene los archivos assets de + este bundle. Cuando se especifica la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]], el [gestor de + assets](#asset-manager) publicará los assets de este bundle en un directorio Web público y sobrescribirá la + propiedad en consecuencia. Se debe establecer esta propiedad si los archivos asset ya se encuentran en un directorio + Web público y no necesitan ser publicados. Se pueden usar [alias de ruta](concept-aliases.md). * [[yii\web\AssetBundle::baseUrl|baseUrl]]: especifica la URL correspondiente al directorio - [[yii\web\AssetBundle::basePath|basePath]]. Como en [yii\web\AssetBundle::basePath|basePath]], si se especifica la - propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]], el [gestor de assets](#asset-manager) publicara los assets + [[yii\web\AssetBundle::basePath|basePath]]. Como en [yii\web\AssetBundle::basePath|basePath]], si se especifica la + propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]], el [gestor de assets](#asset-manager) publicara los assets y sobrescribirá esta propiedad en consecuencia. Se pueden usar [alias de ruta](concept-aliases.md). -* [[yii\web\AssetBundle::js|js]]: un array lista los archivos JavaScript que contiene este bundle. Tenga en cuenta que - solo deben usarse las barras invertidas "/" como separadores de directorios. Cada archivo Javascrpt se puede +* [[yii\web\AssetBundle::js|js]]: un array lista los archivos JavaScript que contiene este bundle. Tenga en cuenta que + solo deben usarse las barras invertidas "/" como separadores de directorios. Cada archivo Javascript se puede especificar en uno de los siguientes formatos: - - una ruta relativa que represente un archivo local JavaScript (p. ej. `js/main.js`). La ruta actual del fichero - se puede determinar anteponiendo [[yii\web\AssetManager::basePath]] a la ruta relativa, y la URL actual de un + - una ruta relativa que represente un archivo local JavaScript (ej. `js/main.js`). La ruta actual del fichero + se puede determinar anteponiendo [[yii\web\AssetManager::basePath]] a la ruta relativa, y la URL actual de un archivo puede ser determinada anteponiendo [[yii\web\AssetManager::baseUrl]] a la ruta relativa. - - un URL absoluta que represente un archivo JavaScript externo. Por ejemplo, - `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` o + - una URL absoluta que represente un archivo JavaScript externo. Por ejemplo, + `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` o `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. -* [[yii\web\AssetBundle::css|css]]: un array que lista los archivos CSS que contiene el este bundle. El formato de este +* [[yii\web\AssetBundle::css|css]]: un array que lista los archivos CSS que contiene este bundle. El formato de este array es el mismo que el de [[yii\web\AssetBundle::js|js]]. * [[yii\web\AssetBundle::depends|depends]]: un array que lista los nombres de los asset bundles de los que depende este asset bundle (para explicarlo brevemente). -* [[yii\web\AssetBundle::jsOptions|jsOptions]]: especifica las opciones que se enviaran al método +* [[yii\web\AssetBundle::jsOptions|jsOptions]]: especifica las opciones que se enviarán al método [[yii\web\View::registerJsFile()]] cuando se le llame para registrar *todos* los archivos JavaScript de este bundle. -* [[yii\web\AssetBundle::cssOptions|cssOptions]]: especifica las opciones que se enviaran al método +* [[yii\web\AssetBundle::cssOptions|cssOptions]]: especifica las opciones que se enviarán al método [[yii\web\View::registerCssFile()]] cuando se le llame para registrar *todos* los archivos CSS de este bundle. -* [[yii\web\AssetBundle::publishOptions|publishOptions]]: especifica las opciones que se enviaran al método - [[yii\web\AssetManager::publish()]] cuando se le llame para publicar los archivos de los assets fuente a un +* [[yii\web\AssetBundle::publishOptions|publishOptions]]: especifica las opciones que se enviarán al método + [[yii\web\AssetManager::publish()]] cuando se le llame para publicar los archivos de los assets fuente a un directorio Web. Solo se usa si se especifica la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]]. -### Ubicación de los Assets +### Ubicación de los Assets Según la localización de los assets, se pueden clasificar como: -* assets fuente (source assets): los assets se encuentran junto con el código fuente PHP, al que no se puede acceder - directamente a través de la Web. Para usar los assets fuente en una página, deben ser copiados en un directorio - publico y transformados en los llamados assets publicados. El proceso se llama *publicación de assets* que será +* assets fuente (source assets): los assets se encuentran junto con el código fuente PHP, al que no se puede acceder + directamente a través de la Web. Para usar los assets fuente en una página, deben ser copiados en un directorio + público y transformados en los llamados assets publicados. El proceso se llama *publicación de assets* que será descrito a continuación. -* assets publicados (published assets): los archivos assets se encuentran en el directorio Web y son accesibles via Web. +* assets publicados (published assets): los archivos assets se encuentran en el directorio Web y son accesibles vía Web. * assets externos (external assets): los archivos assets se encuentran en un servidor Web diferente al de la aplicación. -Cuando se define una clase asset bundle, si se especifica la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]], -significa que cualquier asset listado que use rutas relativas será considerado como un asset fuente. Si no se -especifica la propiedad, significa que los assets son assets publicados (se deben especificar -[[yii\web\AssetBundle::basePath|basePath]] y +Cuando se define una clase asset bundle, si se especifica la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]], +significa que cualquier asset listado que use rutas relativas será considerado como un asset fuente. Si no se +especifica la propiedad, significa que los assets son assets publicados (se deben especificar +[[yii\web\AssetBundle::basePath|basePath]] y [[yii\web\AssetBundle::baseUrl|baseUrl]] para hacerle saber a Yii dónde se encuentran.) -Se recomienda ubicar los assets que correspondan a la aplicación en un directorio Web para evitar publicaciones de -assets innecesarias. Por esto en el anterior ejemplo `AppAsset` especifica [[yii\web\AssetBundle::basePath|basePath]] +Se recomienda ubicar los assets que correspondan a la aplicación en un directorio Web para evitar publicaciones de +assets innecesarias. Por esto en el anterior ejemplo `AppAsset` especifica [[yii\web\AssetBundle::basePath|basePath]] en vez de [[yii\web\AssetBundle::sourcePath|sourcePath]]. -Para las [extensiones](structure-extensions.md), por el hecho de que sus assets se encuentran junto con el código -fuente, en directorios que no son accesibles para la Web, se tiene que especificar la propiedad +Para las [extensiones](structure-extensions.md), por el hecho de que sus assets se encuentran junto con el código +fuente, en directorios que no son accesibles para la Web, se tiene que especificar la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]] cuando se definan clases asset bundle para ellas. -> Nota: No se debe usar `@webroot/assets` como [yii\web\AssetBundle::sourcePath|source path]]. Este directorio se usa - por defecto por el [[yii\web\AssetManager|asset manager]] para guardar los archivos asset publicados temporalmente y +> Nota: No se debe usar `@webroot/assets` como [yii\web\AssetBundle::sourcePath|source path]]. Este directorio se usa + por defecto por el [[yii\web\AssetManager|asset manager]] para guardar los archivos asset publicados temporalmente y pueden ser eliminados. -### Dependencias de los Asset +### Dependencias de los Asset -Cuando se incluyen múltiples archivos CSS o JavaScript en una página Web, tienen que cumplir ciertas órdenes para -evitar problemas de sobrescritura. Por ejemplo, si se usa un widget jQuery UI en una página Web, tenemos que -asegurarnos de que el archivo JavaScript jQuery se incluya antes que el archivo JavaScript jQuery UI. A esto se le +Cuando se incluyen múltiples archivos CSS o JavaScript en una página Web, tienen que cumplir ciertas órdenes para +evitar problemas de sobrescritura. Por ejemplo, si se usa un widget jQuery UI en una página Web, tenemos que +asegurarnos de que el archivo JavaScript jQuery se incluya antes que el archivo JavaScript jQuery UI. A esto se le llama ordenar las dependencias entre archivos. -Las dependencias de los assets se especifican principalmente a través de la propiedad [[yii\AssetBundle::depends]]. -En el ejemplo `AppAsset`, el asset bundle depende de otros dos asset bundles [[yii\web\YiiAsset]] y -[[yii\bootstrap\BootstrapAsset]], que significa que los archivos CSS y JavaScript en `AppAsset` se incluirán *después* +Las dependencias de los assets se especifican principalmente a través de la propiedad [[yii\AssetBundle::depends]]. +En el ejemplo `AppAsset`, el asset bundle depende de otros dos asset bundles [[yii\web\YiiAsset]] y +[[yii\bootstrap\BootstrapAsset]], que significa que los archivos CSS y JavaScript en `AppAsset` se incluirán *después* que los archivos de los dos bundles dependientes. -Las dependencias son transitivas. Esto significa, que si un bundle A depende de un bundle B que depende de C, A +Las dependencias son transitivas. Esto significa, que si un bundle A depende de un bundle B que depende de C, A dependerá de C, también. -### Opciones de los Assets +### Opciones de los Assets -Se pueden especificar las propiedades [[yii\web\AssetBundle::cssOptions|cssOptions]] y -[[yii\web\AssetBundle::jsOptions|jsOptions]] para personalizar la forma en que los archivos CSS y JavaScript serán -incluidos en una página. Los valores de estas propiedades serán enviadas a los metodos -[[yii\web\View::registerCssFile()]] y [[yii\web\View::registerJsFile()]], respectivamente cuando las +Se pueden especificar las propiedades [[yii\web\AssetBundle::cssOptions|cssOptions]] y +[[yii\web\AssetBundle::jsOptions|jsOptions]] para personalizar la forma en que los archivos CSS y JavaScript serán +incluidos en una página. Los valores de estas propiedades serán enviadas a los métodos +[[yii\web\View::registerCssFile()]] y [[yii\web\View::registerJsFile()]], respectivamente cuando las [vistas](structure-views.md) los llamen para incluir los archivos CSS y JavaScript. -> Nota: Las opciones que se especifican en una clase bundle se aplican a *todos* los archivos CSS/JavaScript de un - bundle. Si se quiere usar diferentes opciones para diferentes archivos, se deben crear assets bundles separados y +> Nota: Las opciones que se especifican en una clase bundle se aplican a *todos* los archivos CSS/JavaScript de un + bundle. Si se quiere usar diferentes opciones para diferentes archivos, se deben crear assets bundles separados y usar un conjunto de opciones para cada bundle. Por ejemplo, para incluir una archivo CSS condicionalmente para navegadores que como IE9 o anteriores, se puede usar la @@ -173,28 +173,60 @@ Para incluir un archivo JavaScript en la sección cabecera (head) de una página public $jsOptions = ['position' => \yii\web\View::POS_HEAD]; ``` -### Assets Bower y NPM +Por defecto, cuando un asset bundle está siendo publicado, todos los contenidos del directorio especificado por [[yii\web\AssetBundle::sourcePath]] +serán publicados. Puedes personalizar este comportamiento configurando la propiedad [[yii\web\AssetBundle::publishOptions|publishOptions]]. Por +ejemplo, públicar solo uno o unos pocos subdirectorios de [[yii\web\AssetBundle::sourcePath]], puedes hacerlo de la siguiente manera en la clase +asset bundle: -La mayoría de paquetes JavaScript/CSS se gestionan con [Bower](http://bower.io/) y/o [NPM](https://www.npmjs.org/). +```php +publishOptions['beforeCopy'] = function ($from, $to) { + $dirname = basename(dirname($from)); + return $dirname === 'fonts' || $dirname === 'css'; + }; + } +} +``` + +El ejemplo anterior define un asset bundle para el ["fontawesome" package](http://fontawesome.io/). Especificando +la opción de publicación `beforeCopy`, solo los subdirectorios `fonts` y `css` serán publicados. + +### Bower y NPM Assets + +La mayoría de paquetes JavaScript/CSS se gestionan con [Bower](http://bower.io/) y/o [NPM](https://www.npmjs.org/). Si tu aplicación o extensión usa estos paquetes, se recomienda seguir los siguientes pasos para gestionar los assets en la librería: -1. Modificar el archivo `composer.json` de tu aplicación o extensión e introducir el paquete en la lista `require`. - Se debe usar `bower-asset/PackageName` (para paquetes Bower) o `npm-asset/PackageName` (para paquetes NPM) para +1. Modificar el archivo `composer.json` de tu aplicación o extensión e introducir el paquete en la lista `require`. + Se debe usar `bower-asset/PackageName` (para paquetes Bower) o `npm-asset/PackageName` (para paquetes NPM) para referenciar la librería. -2. Crear una clase asset bundle y listar los archivos JavaScript/CSS que se planea usar en la aplicación o extensión. - Se debe especificar la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]] como `@bower\PackageName` o +2. Crear una clase asset bundle y listar los archivos JavaScript/CSS que se planea usar en la aplicación o extensión. + Se debe especificar la propiedad [[yii\web\AssetBundle::sourcePath|sourcePath]] como `@bower\PackageName` o `@npm\PackageName`. Esto se debe a que Composer instalará el paquete Bower o NPM en el correspondiente directorio de este alias. -> Nota: Algunos paquetes pueden distribuir sus archivos en subdirectorios. Si es el caso, se debe especificar el - subdirectorio como valor del [[yii\web\AssetBundle::sourcePath|sourcePath]]. Por ejemplo, [[yii\web\JqueryAsset]] +> Nota: Algunos paquetes pueden distribuir sus archivos en subdirectorios. Si es el caso, se debe especificar el + subdirectorio como valor del [[yii\web\AssetBundle::sourcePath|sourcePath]]. Por ejemplo, [[yii\web\JqueryAsset]] usa `@bower/jquery/dist` en vez de `@bower/jquery`. -## Uso de Asset Bundles +## Uso de Asset Bundles -Para usar un asset bundle, debe registrarse con una [vista](structure-views.md) llamando al método -[[yii\web\AssetBundle::register()]]. Por ejemplo, en plantilla de vista se puede registrar un asset bundle como en el +Para usar un asset bundle, debe registrarse con una [vista](structure-views.md) llamando al método +[[yii\web\AssetBundle::register()]]. Por ejemplo, en plantilla de vista se puede registrar un asset bundle como en el siguiente ejemplo: ```php @@ -202,28 +234,28 @@ use app\assets\AppAsset; AppAsset::register($this); // $this representa el objeto vista ``` -> Información: El método [[yii\web\AssetBundle::register()]] devuelve un objeto asset bundle que contiene la - información acerca de los assets publicados, tales como [[yii\web\AssetBundle::basePath|basePath]] o +> Información: El método [[yii\web\AssetBundle::register()]] devuelve un objeto asset bundle que contiene la + información acerca de los assets publicados, tales como [[yii\web\AssetBundle::basePath|basePath]] o [[yii\web\AssetBundle::baseUrl|baseUrl]]. -Si se registra un asset bundle en otro lugar, se debe proporcionar la vista necesaria al objeto. Por ejemplo, para -registrar un asset bundle en una clase [widget](structure-widgets.md), se puede obtener el objeto vista mediante +Si se registra un asset bundle en otro lugar, se debe proporcionar la vista necesaria al objeto. Por ejemplo, para +registrar un asset bundle en una clase [widget](structure-widgets.md), se puede obtener el objeto vista mediante `$this->view`. -Cuando se registra un asset bundle con una vista, por detrás, Yii registrará todos sus asset bundles dependientes. -Y si un asset bundle se encuentra en un directorio inaccesible por la Web, éste será publicado a un directorio Web -publico. Después cuando la vista renderice una página, se generarán las etiquetas (tags) `` y ` +``` + +CSS ファイルの外部スタイルをリンクしたい場合は、次のようにします。 + +```php + 'IE 5']) ?> + +これは次の HTML を生成します。 + + +``` + +最初の引数は URL であり、第二の引数はオプションの配列です。 +通常のオプションに加えて、次のものを指定することが出来ます。 + +- `condition` - 指定された条件を使って `` タグで囲むことができます。 + この場合、JavaScript がブラウザでサポートされていないか、ユーザが JavaScript を無効にしたときだけ、CSS がインクルードされます。 + +JavaScript ファイルをリンクするためには、次のようにします。 + +```php + +``` + +CSS と同じように、最初の引数はインクルードされるファイルへのリンクを指定するものです。 +オプションを第二の引数として渡すことが出来ます。 +オプションに置いて、`cssFile` のオプションと同じように、`condition` を指定することが出来ます。 + + +## ハイパーリンク + +ハイパーリンクを手軽に生成できるメソッドがあります。 + +```php + $id], ['class' => 'profile-link']) ?> +``` + +最初の引数はタイトルです。 +これはエンコードされませんので、エンドユーザから取得したデータを使う場合は、`Html::encode()` でエンコードする必要があります。 +第二の引数が、` +``` + + +## 画像 + +イメージタグを生成するためには次のようにします。 + +```php + '私のロゴ']) ?> + +これは次の HTML を生成します。 + +私のロゴ +``` + +最初の引数は、[エイリアス](concept-aliases.md) 以外にも、ルートとパラメータ、または URL を受け入れることが出来ます。 +[Url::to()](helper-url.md) と同様です。 + + +## リスト + +順序なしリストは、次のようにして生成することが出来ます。 + +```php + function($item, $index) { + return Html::tag( + 'li', + $this->render('post', ['item' => $item]), + ['class' => 'post'] + ); +}]) ?> +``` + +順序付きリストを生成するためには、代りに `Html:ol()` を使ってください。 diff --git a/docs/guide-ja/helper-overview.md b/docs/guide-ja/helper-overview.md new file mode 100644 index 0000000..8f1722e --- /dev/null +++ b/docs/guide-ja/helper-overview.md @@ -0,0 +1,75 @@ +ヘルパ +====== + +> Note|注意: この節はまだ執筆中です。 + +Yii は、一般的なコーディングのタスク、例えば、文字列や配列の操作、HTML コードの生成などを手助けする多くのクラスを提供しています。 +これらのヘルパクラスは `yii\helpers` 名前空間の下に編成されており、すべてスタティックなクラス (すなわち、スタティックなプロパティとメソッドのみを含み、インスタンス化すべきでないクラス) です。 + +ヘルパクラスは、そのスタティックなメソッドの一つを直接に呼び出すことによって使用します。 +例えば、 + +```php +use yii\helpers\Html; + +echo Html::encode('Test > test'); +``` + +> Note|注意: [ヘルパクラスをカスタマイズする](#customizing-helper-classes) ことをサポートするために、Yii はコアヘルパクラスのすべてを二つのクラスに分割しています。 +> すなわち、基底クラス (例えば `BaseArrayHelper`) と具象クラス (例えば `ArrayHelper`) です。 +> ヘルパを使うときは、具象クラスのみを使うべきであり、基底クラスは決して使ってはいけません。 + + +コアヘルパクラス +---------------- + +以下のコアヘルパクラスが Yii のリリースにおいて提供されています。 + +- [ArrayHelper](helper-array.md) +- Console +- FileHelper +- [Html](helper-html.md) +- HtmlPurifier +- Image +- Inflector +- Json +- Markdown +- Security +- StringHelper +- [Url](helper-url.md) +- VarDumper + + +ヘルパクラスをカスタマイズする +------------------------------ + +コアヘルパクラス (例えば [[yii\helpers\ArrayHelper]]) をカスタマイズするためには、そのヘルパに対応する基底クラス (例えば [[yii\helpers\BaseArrayHelper]]) を拡張するクラスを作成して、名前空間も含めて、対応する具象クラス (例えば [[yii\helpers\ArrayHelper]]) と同じ名前を付けます。 +このクラスが、フレームワークのオリジナルの実装を置き換えるものとしてセットアップされます。 + +次の例は、[[yii\helpers\ArrayHelper]] クラスの [[yii\helpers\ArrayHelper::merge()|merge()]] メソッドをカスタマイズする方法を示すものです。 + +```php + + +よく使う URL を取得するために使うことが出来るメソッドが二つあります。 +すなわち、ホーム URL と、現在のリクエストのベース URL を取得するメソッドです。 +ホーム URL を取得するためには、次のようにします。 + +```php +$relativeHomeUrl = Url::home(); +$absoluteHomeUrl = Url::home(true); +$httpsAbsoluteHomeUrl = Url::home('https'); +``` + +パラメータが渡されない場合は、相対 URL が生成されます。 +`true` を渡すと、現在のスキーマの絶対 URL を取得することが出来ます。 +または、スキーマを明示的に指定して (`http`, `https`) 絶対 URL を取得することも出来ます。 + +現在のリクエストのベース URL を取得するためには、次のようにします。 + +```php +$relativeBaseUrl = Url::base(); +$absoluteBaseUrl = Url::base(true); +$httpsAbsoluteBaseUrl = Url::base('https'); +``` + +このメソッドの唯一のパラメータは、`Url::home()` の場合と全く同じ動作をします。 + + +## URL を生成する + +与えられたルートへの URL を生成するためには、`Url::toRoute()` メソッドを使います。 +このメソッドは、[[\yii\web\UrlManager]] を使って URL を生成します。 + +```php +$url = Url::toRoute(['product/view', 'id' => 42]); +``` + +ルートは、文字列として指定することが出来ます (例えば、`site/index`)。 +または、生成される URL に追加のクエリパラメータを指定したい場合は、配列を使うことも出来ます。 +配列の形式は、以下のようにしなければなりません。 + +```php +// /index.php?r=site/index¶m1=value1¶m2=value2 を生成 +['site/index', 'param1' => 'value1', 'param2' => 'value2'] +``` + +アンカーの付いた URL を生成したい場合は、`#` パラメータを持つ配列を使うことが出来ます。例えば、 + +```php +// /index.php?r=site/index¶m1=value1#name を生成 +['site/index', 'param1' => 'value1', '#' => 'name'] +``` + +ルートは、絶対ルートか相対ルートかのどちらかです。 +絶対ルートは先頭にスラッシュを持ち (例えば `/site/index`)、相対ルートは持ちません (例えば `site/index` または `index`)。 +相対ルートは次の規則に従って絶対ルートに変換されます。 + +- ルートが空文字列である場合は、現在の [[yii\web\Controller::route|ルート]] が使用されます。 +- ルートがスラッシュを全く含まない場合は (例えば `index`)、カレントコントローラのアクション ID であると見なされて、カレントコントローラの [[\yii\web\Controller::uniqueId|uniqueId]] が前置されます。 +- ルートが先頭にスラッシュを含まない場合は (例えば `site/index`)、カレントモジュールに対する相対ルートと見なされて、カレントモジュールの [[\yii\base\Module::uniqueId|uniqueId]] が前置されます。 + +バージョン 2.0.2 以降では、[エイリアス](concept-aliases.md) の形式でルートを指定することが出来ます。 +その場合は、エイリアスが最初に実際のルートに変換され、そのルートが上記の規則に従って絶対ルートに変換されます。 + +以下に、このメソッドの使用例をいくつか挙げます。 + +```php +// /index.php?r=site/index +echo Url::toRoute('site/index'); + +// /index.php?r=site/index&src=ref1#name +echo Url::toRoute(['site/index', 'src' => 'ref1', '#' => 'name']); + +// /index.php?r=post/edit&id=100 エイリアス "@postEdit" は "post/edit" と定義されていると仮定 +echo Url::toRoute(['@postEdit', 'id' => 100]); + +// http://www.example.com/index.php?r=site/index +echo Url::toRoute('site/index', true); + +// https://www.example.com/index.php?r=site/index +echo Url::toRoute('site/index', 'https'); +``` + +もうひとつ、[[toRoute()]] と非常によく似た `Url::to()` というメソッドがあります。 +唯一の違いは、このメソッドはルートを配列として指定することを要求する、という点です。 +文字列が与えられた場合は、URL として扱われます。 + +最初の引数は、次のいずれかを取り得ます。 + +- 配列: URL を生成するために [[toRoute()]] が呼び出されます。例えば、`['site/index']`、`['post/index', 'page' => 2]`。 + ルートの指定方法の詳細については [[toRoute()]] を参照してください。 +- `@` で始まる文字列: これはエイリアスとして扱われ、エイリアスに対応する文字列が返されます。 +- 空文字列: 現在リクエストされている URL が返されます。 +- 通常の文字列: その通りのものとして扱われます。 + +`$scheme` (文字列または `true`) が指定された場合は、ホスト情報 ([[\yii\web\UrlManager::hostInfo]] から取得されます) を伴う絶対 URL が返されます。 +`$url` が既に絶対 URL であった場合には、そのスキームが指定されたものに置き換えられます。 + +下記にいくつかの用例を挙げます。 + +```php +// /index.php?r=site/index +echo Url::to(['site/index']); + +// /index.php?r=site/index&src=ref1#name +echo Url::to(['site/index', 'src' => 'ref1', '#' => 'name']); + +// /index.php?r=post/edit&id=100 エイリアス "@postEdit" が "post/edit" と定義されていると仮定 +echo Url::to(['@postEdit', 'id' => 100]); + +// 現在リクエストされている URL +echo Url::to(); + +// /images/logo.gif +echo Url::to('@web/images/logo.gif'); + +// images/logo.gif +echo Url::to('images/logo.gif'); + +// http://www.example.com/images/logo.gif +echo Url::to('@web/images/logo.gif', true); + +// https://www.example.com/images/logo.gif +echo Url::to('@web/images/logo.gif', 'https'); +``` + +バージョン 2.0.3 以降では、[[yii\helpers\Url::current()]] を使って、現在リクエストされているルートと GET パラメータに基づいて URL を生成することが出来ます。 +`$params` パラメータを渡して、GET パラメータの中のいくつかを修正したり削除したり、または新しい GET パラメータを追加したりすることが出来ます。 +例えば、 + +```php +// $_GET が ['id' => 123, 'src' => 'google'] であり、現在のルートが "post/view" であると仮定 + +// /index.php?r=post/view&id=123&src=google +echo Url::current(); + +// /index.php?r=post/view&id=123 +echo Url::current(['src' => null]); +// /index.php?r=post/view&id=100&src=google +echo Url::current(['id' => 100]); +``` + + +## URL を記憶する + +URL を記憶して、後に続く一連のリクエストの一つを処理するときに、記憶した URL を使わなければならないという場合があります。 +これは、次のようにして達成することが出来ます。 + +```php +// 現在の URL を記憶する +Url::remember(); + +// 指定された URL を記憶する。引数の形式は Url::to() を参照。 +Url::remember(['product/view', 'id' => 42]); + +// 指定された名前で URL を記憶する。 +Url::remember(['product/view', 'id' => 42], 'product'); +``` + +次のリクエストで、記憶された URL を次のようにして取得することが出来ます。 + +```php +$url = Url::previous(); +$productUrl = Url::previous('product'); +``` + +## 相対 URL かどうかチェックする + +URL が相対 URL であること、すなわち、URL がホスト情報の部分を持っていないことを確かめるために、次のコードを使うことが出来ます。 + +```php +$isRelative = Url::isRelative('test/it'); +``` diff --git a/docs/guide-ja/images/start-gii-crud-preview.png b/docs/guide-ja/images/start-gii-crud-preview.png index d7becdd..85c2355 100644 Binary files a/docs/guide-ja/images/start-gii-crud-preview.png and b/docs/guide-ja/images/start-gii-crud-preview.png differ diff --git a/docs/guide-ja/images/start-gii-crud.png b/docs/guide-ja/images/start-gii-crud.png index a3aa21b..77c1ada 100644 Binary files a/docs/guide-ja/images/start-gii-crud.png and b/docs/guide-ja/images/start-gii-crud.png differ diff --git a/docs/guide-ja/images/tutorial-console-help.png b/docs/guide-ja/images/tutorial-console-help.png new file mode 100644 index 0000000..34812a6 Binary files /dev/null and b/docs/guide-ja/images/tutorial-console-help.png differ diff --git a/docs/guide-ja/input-file-upload.md b/docs/guide-ja/input-file-upload.md new file mode 100644 index 0000000..03679d3 --- /dev/null +++ b/docs/guide-ja/input-file-upload.md @@ -0,0 +1,258 @@ +ファイルをアップロードする +========================== + +Yii におけるファイルのアップロードは、フォームモデル、その検証規則、そして、いくらかのコントローラコードによって行われます。 +アップロードを適切に処理するために何が必要とされるのか、見ていきましよう。 + + +一つのファイルをアップロードする +-------------------------------- + +まず最初に、ファイルのアップロードを処理するモデルを作成する必要があります。 +次の内容を持つ `models/UploadForm.php` を作成してください。 + +```php +namespace app\models; + +use yii\base\Model; +use yii\web\UploadedFile; + +/** + * UploadForm : アップロードのフォームの背後にあるモデル + */ +class UploadForm extends Model +{ + /** + * @var UploadedFile file 属性 + */ + public $file; + + /** + * @return array 検証規則 + */ + public function rules() + { + return [ + [['file'], 'file'], + ]; + } +} +``` + +上記のコードにおいて作成した `UploadForm` というモデルは、HTML フォームで `` となる `$file` という属性を持ちます。 +この属性は [[yii\validators\FileValidator|FileValidator]] を使用する `file` という検証規則を持ちます。 + +### フォームのビュー + +次に、フォームを表示するビューを作成します。 + +```php + + + ['enctype' => 'multipart/form-data']]) ?> + +field($model, 'file')->fileInput() ?> + + + + +``` + +ファイルのアップロードを可能にする `'enctype' => 'multipart/form-data'` は不可欠です。 +`fileInput()` がフォームの入力フィールドを表します。 + +### コントローラ + +そして、フォームとモデルを結び付けるコントローラを作成します。 + +```php +namespace app\controllers; + +use Yii; +use yii\web\Controller; +use app\models\UploadForm; +use yii\web\UploadedFile; + +class SiteController extends Controller +{ + public function actionUpload() + { + $model = new UploadForm(); + + if (Yii::$app->request->isPost) { + $model->file = UploadedFile::getInstance($model, 'file'); + + if ($model->file && $model->validate()) { + $model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension); + } + } + + return $this->render('upload', ['model' => $model]); + } +} +``` + +`model->load(...)` の代りに `UploadedFile::getInstance(...)` を使っています。 +[[\yii\web\UploadedFile|UploadedFile]] はモデルの検証を実行せず、アップロードされたファイルに関する情報を提供するだけです。 +そのため、`$model->validate()` を手作業で実行して、[[yii\validators\FileValidator|FileValidator]] を起動する必要があります。 +[[yii\validators\FileValidator|FileValidator]] は、下記のコアコードが示しているように、属性がファイルであることを要求します。 + +```php +if (!$file instanceof UploadedFile || $file->error == UPLOAD_ERR_NO_FILE) { + return [$this->uploadRequired, []]; // "ファイルをアップロードしてください。" というエラーメッセージ +} +``` + +検証が成功したら、ファイルを保存します。 + +```php +$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension); +``` + +「ベーシック」プロジェクトテンプレートを使っている場合は、`uploads` フォルダを `web` の下に作成しなければなりません。 + +以上です。ページをロードして、アップロードを試して見てください。ファイルは `basic/web/uploads` にアップロードされます。 + +検証 +---- + +たいていの場合、検証規則を調整して、特定のファイルだけを受け取るようにしたり、アップロードを必須としたりする必要があります。 +下記で、よく使われる規則の構成を見てみましよう。 + +### Required + +ファイルのアップロードを必須とする必要がある場合は、次のように `skipOnEmpty` を `false` に設定します。 + +```php +public function rules() +{ + return [ + [['file'], 'file', 'skipOnEmpty' => false], + ]; +} +``` + +### MIME タイプ + +アップロードされるファイルのタイプを検証することは賢明なことです。 +`FileValidator` はこの目的のための `extensions` プロパティを持っています。 + +```php +public function rules() +{ + return [ + [['file'], 'file', 'extensions' => 'gif, jpg'], + ]; +} +``` + +デフォルトでは、ファイルのコンテントの MIME タイプが指定された拡張子に対応するものであるかどうかが検証されます。 +例えば、`gif` に対しては `image/gif`、`jpg` に対しては `image/jpeg` であるかどうかが検証されます。 + +MIME タイプの中には、`file` バリデータによって使われている PHP fileinfo 拡張では適切に検知することが出来ないものがあることに注意してください。 +例えば、`csv` ファイルは `text/csv` ではなく `text/plain` として検知されます。 +このような振る舞いを避けるために、`checkExtensionByMimeType` を `false` に設定して、MIME タイプを手動で指定することが出来ます。 + +```php +public function rules() +{ + return [ + [['file'], 'file', 'checkExtensionByMimeType' => false, 'extensions' => 'csv', 'mimeTypes' => 'text/plain'], + ]; +} +``` + +[一般的なメディアタイプの一覧表](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types) + +### 画像のプロパティ + +画像をアップロードするときは、[[yii\validators\ImageValidator|ImageValidator]] が重宝するでしょう。 +このバリデータは、属性が有効な画像を受け取ったか否かを検証します。 +画像は、保存するか、または、[Imagine エクステンション](https://github.com/yiisoft/yii2-imagine) によって処理することが出来ます。 + +複数のファイルをアップロードする +-------------------------------- + +複数のファイルを一度にアップロードする必要がある場合は、少し修正が必要になります。 + +モデル: + +```php +class UploadForm extends Model +{ + /** + * @var UploadedFile|Null ファイル属性 + */ + public $file; + + /** + * @return array 検証規則 + */ + public function rules() + { + return [ + [['file'], 'file', 'maxFiles' => 10], // <--- ここ ! + ]; + } +} +``` + +ビュー: + +```php + ['enctype' => 'multipart/form-data']]); +?> + +field($model, 'file[]')->fileInput(['multiple' => true]) ?> + + + + +``` + +違いがあるのは、次の行です。 + +```php +field($model, 'file[]')->fileInput(['multiple' => true]) ?> +``` + +コントローラ: + +```php +namespace app\controllers; + +use Yii; +use yii\web\Controller; +use app\models\UploadForm; +use yii\web\UploadedFile; + +class SiteController extends Controller +{ + public function actionUpload() + { + $model = new UploadForm(); + + if (Yii::$app->request->isPost) { + $model->file = UploadedFile::getInstances($model, 'file'); + + if ($model->file && $model->validate()) { + foreach ($model->file as $file) { + $file->saveAs('uploads/' . $file->baseName . '.' . $file->extension); + } + } + } + + return $this->render('upload', ['model' => $model]); + } +} +``` + +単一のファイルのアップロードとは、二つの点で異なります。 +最初の違いは、`UploadedFile::getInstance($model, 'file');` の代りに `UploadedFile::getInstances($model, 'file');` が使用されることです。 +前者が一つのインスタンスを返すだけなのに対して、後者はアップロードされた **全ての** ファイルのインスタンスを返します。 +第二の違いは、`foreach` によって、全てのファイルをそれぞれ保存している点です。 diff --git a/docs/guide-ja/input-forms.md b/docs/guide-ja/input-forms.md new file mode 100644 index 0000000..8173b2c --- /dev/null +++ b/docs/guide-ja/input-forms.md @@ -0,0 +1,110 @@ +フォームを作成する +================== + +Yii においてフォームを使用するときは、主として [[yii\widgets\ActiveForm]] による方法を使います。 +フォームがモデルに基づくものである場合はこの方法を選ぶべきです。 +これに加えて、[[yii\helpers\Html]] にはいくつかの有用なメソッドがあり、どんなフォームでも、ボタンやヘルプテキストを追加するのには、通常、それらのメソッドを使います。 + +フォームは、クライアント側で表示されるものですが、たいていの場合、対応する [モデル](structure-models.md) を持ち、それを使ってサーバ側でフォームの入力を検証します +(入力の検証の詳細については、[入力を検証する](input-validation.md) の節を参照してください)。 +モデルに基づくフォームを作成する場合、最初のステップは、モデルそのものを定義することです。 +モデルは、データベースの何らかのデータを表現するために [アクティブレコード](db-active-record.md) から派生させたクラスか、あるいは、任意の入力、例えばログインフォームの入力を保持するための ([[yii\base\Model]] から派生させた) 汎用的な Model クラスか、どちらかにすることが出来ます。 +以下の例においては、ログインフォームのために汎用的なモデルを使う方法を示します。 + +```php + 'login-form', + 'options' => ['class' => 'form-horizontal'], +]) ?> + field($model, 'username') ?> + field($model, 'password')->passwordInput() ?> + +
+
+ 'btn btn-primary']) ?> +
+
+ +``` + +上記のコードでは、[[yii\widgets\ActiveForm::begin()|ActiveForm::begin()]] がフォームのインスタンスを作成するだけでなく、フォームの開始をマークしています。 +[[yii\widgets\ActiveForm::begin()|ActiveForm::begin()]] と [[yii\widgets\ActiveForm::end()|ActiveForm::end()]] の間に置かれた全てのコンテントが HTML の `
` タグによって囲まれます。 +どのウィジェットでも同じですが、ウィジェットをどのように構成すべきかに関するオプションを指定するために、`begin` メソッドに配列を渡すことが出来ます。 +この例では、追加の CSS クラスと要素を特定するための ID が渡されて、`` の開始タグに適用されています。 +利用できるオプションはすべて [[yii\widgets\ActiveForm]] の API ドキュメントに記されていますので参照してください。 + +フォームの中では、フォームの要素を作成するために、ActiveForm ウィジェットの [[yii\widgets\ActiveForm::field()|ActiveForm::field()]] メソッドが呼ばれています。 +これは、フォームの要素だけでなく、そのラベルも作成し、適用できる JavaScript の検証メソッドがあれば、それも追加します。 +[[yii\widgets\ActiveForm::field()|ActiveForm::field()]] メソッドは、[[yii\widgets\ActiveField]] のインスタンスを返します。 +このメソッドの呼び出し結果を直接にエコーすると、結果は通常の (text の) インプットになります。 +このメソッドの呼び出しに追加の [[yii\widgets\ActiveField|ActiveField]] のメソッドをチェーンして、出力結果をカスタマイズすることが出来ます。 + +```php +// パスワードのインプット +field($model, 'password')->passwordInput() ?> +// ヒントとカスタマイズしたラベルを追加 +field($model, 'username')->textInput()->hint('お名前を入力してください')->label('お名前') ?> +// HTML5 のメールインプット要素を作成 +field($model, 'email')->input('email') ?> +``` + +これで、フォームのフィールドによって定義された [[yii\widgets\ActiveField::$template|テンプレート]] に従って、`