Browse Source

Merge branch 'master' into yuriystovbur-13425-fix-url-rules-cache

tags/2.0.14
SilverFire - Dmitry Naumenko 7 years ago
parent
commit
a2f9ff8aac
No known key found for this signature in database
GPG Key ID: 39DD917A92B270A
  1. 30
      .gitlab-ci.yml
  2. 24
      .travis.yml
  3. 3
      Dockerfile
  4. 3
      README.md
  5. 2
      build/controllers/ClassmapController.php
  6. 44
      build/controllers/DevController.php
  7. 92
      build/controllers/MimeTypeController.php
  8. 101
      build/controllers/PhpDocController.php
  9. 38
      build/controllers/ReleaseController.php
  10. 18
      build/controllers/Utf8Controller.php
  11. 462
      composer.lock
  12. 4
      contrib/completion/bash/yii
  13. 4
      contrib/completion/zsh/_yii
  14. 4
      docs/guide-es/caching-data.md
  15. 2
      docs/guide-es/concept-di-container.md
  16. 2
      docs/guide-es/concept-events.md
  17. 10
      docs/guide-es/runtime-logging.md
  18. 4
      docs/guide-es/start-installation.md
  19. 2
      docs/guide-es/structure-filters.md
  20. 4
      docs/guide-fr/caching-data.md
  21. 4
      docs/guide-fr/concept-di-container.md
  22. 4
      docs/guide-fr/concept-events.md
  23. 10
      docs/guide-fr/runtime-logging.md
  24. 4
      docs/guide-fr/start-installation.md
  25. 2
      docs/guide-fr/structure-filters.md
  26. 2
      docs/guide-fr/tutorial-i18n.md
  27. 4
      docs/guide-id/start-installation.md
  28. 4
      docs/guide-it/start-installation.md
  29. 4
      docs/guide-ja/caching-data.md
  30. 6
      docs/guide-ja/concept-di-container.md
  31. 4
      docs/guide-ja/concept-events.md
  32. 10
      docs/guide-ja/runtime-logging.md
  33. 4
      docs/guide-ja/start-installation.md
  34. 2
      docs/guide-ja/structure-filters.md
  35. 2
      docs/guide-ja/tutorial-i18n.md
  36. 4
      docs/guide-pl/start-installation.md
  37. 4
      docs/guide-pt-BR/caching-data.md
  38. 4
      docs/guide-pt-BR/concept-di-container.md
  39. 2
      docs/guide-pt-BR/concept-events.md
  40. 10
      docs/guide-pt-BR/runtime-logging.md
  41. 4
      docs/guide-pt-BR/start-installation.md
  42. 2
      docs/guide-pt-BR/structure-filters.md
  43. 3
      docs/guide-ru/README.md
  44. 4
      docs/guide-ru/caching-data.md
  45. 6
      docs/guide-ru/concept-di-container.md
  46. 4
      docs/guide-ru/concept-events.md
  47. 8
      docs/guide-ru/db-migrations.md
  48. 12
      docs/guide-ru/input-validation.md
  49. 13
      docs/guide-ru/intro-yii.md
  50. 8
      docs/guide-ru/output-data-providers.md
  51. 20
      docs/guide-ru/output-data-widgets.md
  52. 21
      docs/guide-ru/output-formatting.md
  53. 14
      docs/guide-ru/rest-resources.md
  54. 14
      docs/guide-ru/runtime-logging.md
  55. 72
      docs/guide-ru/security-best-practices.md
  56. 4
      docs/guide-ru/start-installation.md
  57. 2
      docs/guide-ru/structure-filters.md
  58. 7
      docs/guide-ru/structure-modules.md
  59. 2
      docs/guide-ru/tutorial-i18n.md
  60. 206
      docs/guide-ru/tutorial-yii-as-micro-framework.md
  61. 4
      docs/guide-uk/start-installation.md
  62. 4
      docs/guide-vi/start-installation.md
  63. 4
      docs/guide-zh-CN/caching-data.md
  64. 2
      docs/guide-zh-CN/concept-di-container.md
  65. 2
      docs/guide-zh-CN/concept-events.md
  66. 4
      docs/guide-zh-CN/start-installation.md
  67. 2
      docs/guide-zh-CN/structure-filters.md
  68. 1
      docs/guide/README.md
  69. 4
      docs/guide/caching-data.md
  70. 3
      docs/guide/caching-fragment.md
  71. 6
      docs/guide/concept-di-container.md
  72. 77
      docs/guide/concept-events.md
  73. 28
      docs/guide/db-active-record.md
  74. 35
      docs/guide/db-migrations.md
  75. 209
      docs/guide/db-query-builder.md
  76. 13
      docs/guide/input-validation.md
  77. 8
      docs/guide/output-data-providers.md
  78. 19
      docs/guide/output-data-widgets.md
  79. 5
      docs/guide/output-formatting.md
  80. 13
      docs/guide/runtime-logging.md
  81. 2
      docs/guide/runtime-requests.md
  82. 4
      docs/guide/security-authorization.md
  83. 28
      docs/guide/start-installation.md
  84. 22
      docs/guide/start-prerequisites.md
  85. 8
      docs/guide/structure-assets.md
  86. 2
      docs/guide/structure-filters.md
  87. 8
      docs/guide/structure-modules.md
  88. 5
      docs/guide/test-fixtures.md
  89. 2
      docs/guide/tutorial-i18n.md
  90. 1
      docs/guide/tutorial-yii-as-micro-framework.md
  91. 87
      docs/internals-ru/git-workflow.md
  92. 4
      docs/internals/README.md
  93. 4
      docs/internals/git-workflow.md
  94. 8
      docs/internals/release.md
  95. 26
      framework/BaseYii.php
  96. 128
      framework/CHANGELOG.md
  97. 36
      framework/UPGRADE.md
  98. 2
      framework/Yii.php
  99. 18
      framework/assets/yii.activeForm.js
  100. 2
      framework/assets/yii.js
  101. Some files were not shown because too many files have changed in this diff Show More

30
.gitlab-ci.yml

@ -1,22 +1,18 @@
before_script:
# set stack isolation
- export ISOLATION=buildpipeline${CI_PIPELINE_ID}${CI_BUILD_NAME}
- export COMPOSE_PROJECT_NAME=${ISOLATION}
- export TUPLE_C=$(expr ${CI_BUILD_ID} % 99)
- echo ${TUPLE_C}
# run docker-compose commands from tests environment
- cd tests
- cp .env-dist .env
- docker-compose config
image: docker:latest
services:
- docker:dind
after_script:
- export ISOLATION=buildpipeline${CI_PIPELINE_ID}${CI_BUILD_NAME}
- export COMPOSE_PROJECT_NAME=${ISOLATION}
# run docker-compose commands from tests environment
variables:
DOCKER_YII2_PHP_IMAGE: yiisoftware/yii2-php:7.1-apache
DOCKER_MYSQL_IMAGE: percona:5.7
DOCKER_POSTGRES_IMAGE: postgres:9.3
before_script:
- apk add --no-cache python py2-pip git
- pip install --no-cache-dir docker-compose==1.16.0
- docker info
- cd tests
- cp .env-dist .env
- docker-compose down -v --remove-orphans
- docker ps -f name=${ISOLATION}
stages:
- travis

24
.travis.yml

@ -46,9 +46,14 @@ cache:
- $HOME/.composer/cache
- $HOME/.npm
# try running against postgres 9.3
# try running against postgres 9.6
addons:
postgresql: "9.3"
postgresql: "9.6"
apt:
sources:
- mysql-5.7-trusty
packages:
- mysql-server
code_climate:
repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b
@ -76,10 +81,10 @@ matrix:
code_climate:
repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b
apt:
sources:
- mysql-5.7-trusty
packages:
- mysql-server-5.6
- mysql-client-core-5.6
- mysql-client-5.6
- mysql-server
services:
- mysql
@ -89,12 +94,12 @@ matrix:
addons:
code_climate:
repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b
postgresql: "9.3"
postgresql: "9.6"
apt:
sources:
- mysql-5.7-trusty
packages:
- mysql-server-5.6
- mysql-client-core-5.6
- mysql-client-5.6
- mysql-server
services:
- mysql
- postgresql
@ -166,6 +171,7 @@ before_script:
- |
if [ $TASK_TESTS_PHP == 1 ]; then
travis_retry mysql -e 'CREATE DATABASE `yiitest`;';
mysql -e "SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';";
mysql -e "CREATE USER 'travis'@'localhost' IDENTIFIED WITH mysql_native_password;";
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'travis'@'localhost' WITH GRANT OPTION;";
psql -U postgres -c 'CREATE DATABASE yiitest;';

3
Dockerfile

@ -1,4 +1,5 @@
FROM dmstr/php-yii2:7.0-fpm-1.9-beta2-alpine-nginx
ARG DOCKER_YII2_PHP_IMAGE
FROM ${DOCKER_YII2_PHP_IMAGE}
# Project source-code
WORKDIR /project

3
README.md

@ -39,9 +39,10 @@ Community
---------
- Participate in [discussions at forums](http://www.yiiframework.com/forum/).
- [Chat in IRC](http://www.yiiframework.com/chat/).
- [Community Slack](https://join.slack.com/t/yii/shared_invite/MjIxMjMxMTk5MTU1LTE1MDE3MDAwMzMtM2VkMTMyMjY1Ng) and [Chat in IRC](http://www.yiiframework.com/chat/).
- Follow us on [Facebook](https://www.facebook.com/groups/yiitalk/), [Twitter](https://twitter.com/yiiframework)
and [GitHub](https://github.com/yiisoft/yii2).
- Check [other communities](https://github.com/yiisoft/yii2/wiki/communities).
Contributing
------------

2
build/controllers/ClassmapController.php

@ -60,7 +60,7 @@ class ClassmapController extends Controller
if (strpos($file, $root) !== 0) {
throw new Exception("Something wrong: $file\n");
}
$path = str_replace('\\', '/', substr($file, strlen($root)));
$path = str_replace('\\', '/', substr($file, \strlen($root)));
$map[$path] = " 'yii" . substr(str_replace('/', '\\', $path), 0, -4) . "' => YII2_PATH . '$path',";
}
ksort($map);

44
build/controllers/DevController.php

@ -24,19 +24,25 @@ use yii\helpers\FileHelper;
*/
class DevController extends Controller
{
/**
* {@inheritdoc}
*/
public $defaultAction = 'all';
/**
* @var bool whether to use HTTP when cloning github repositories
*/
public $useHttp = false;
/**
* @var array
*/
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',
];
/**
* @var array
*/
public $extensions = [
'apidoc' => 'git@github.com:yiisoft/yii2-apidoc.git',
'authclient' => 'git@github.com:yiisoft/yii2-authclient.git',
@ -98,17 +104,17 @@ class DevController extends Controller
*/
public function actionRun($command)
{
$command = implode(' ', func_get_args());
$command = implode(' ', \func_get_args());
// root of the dev repo
$base = dirname(dirname(__DIR__));
$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));
$displayDir = substr($dir, \strlen($base));
$this->stdout("Running '$command' in $displayDir...\n", Console::BOLD);
chdir($dir);
passthru($command);
@ -137,7 +143,7 @@ class DevController extends Controller
public function actionApp($app, $repo = null)
{
// root of the dev repo
$base = dirname(dirname(__DIR__));
$base = \dirname(\dirname(__DIR__));
$appDir = "$base/apps/$app";
if (!file_exists($appDir)) {
@ -188,7 +194,7 @@ class DevController extends Controller
public function actionExt($extension, $repo = null)
{
// root of the dev repo
$base = dirname(dirname(__DIR__));
$base = \dirname(\dirname(__DIR__));
$extensionDir = "$base/extensions/$extension";
if (!file_exists($extensionDir)) {
@ -229,12 +235,12 @@ class DevController extends Controller
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function options($actionID)
{
$options = parent::options($actionID);
if (in_array($actionID, ['ext', 'app', 'all'], true)) {
if (\in_array($actionID, ['ext', 'app', 'all'], true)) {
$options[] = 'useHttp';
}
@ -250,13 +256,13 @@ class DevController extends Controller
{
if (is_link($link = "$dir/vendor/yiisoft/yii2")) {
$this->stdout("Removing symlink $link.\n");
$this->unlink($link);
FileHelper::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);
FileHelper::unlink($link);
}
}
}
@ -294,20 +300,6 @@ class DevController extends Controller
}
/**
* 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);
}
}
/**
* Get a list of subdirectories for directory specified.
* @param string $dir directory to read
*

92
build/controllers/MimeTypeController.php

@ -27,34 +27,60 @@ use yii\helpers\VarDumper;
class MimeTypeController extends Controller
{
/**
* @param string $outFile the file to update. Defaults to @yii/helpers/mimeTypes.php
* @var array MIME type aliases
*/
public function actionIndex($outFile = null)
private $aliases = [
'text/xml' => 'application/xml',
];
/**
* @param string $outFile the mime file to update. Defaults to @yii/helpers/mimeTypes.php
* @param string $aliasesOutFile the aliases file to update. Defaults to @yii/helpers/mimeAliases.php
*/
public function actionIndex($outFile = null, $aliasesOutFile = null)
{
if ($outFile === null) {
$outFile = Yii::getAlias('@yii/helpers/mimeTypes.php');
}
if ($aliasesOutFile === null) {
$aliasesOutFile = Yii::getAlias('@yii/helpers/mimeAliases.php');
}
$this->stdout('downloading mime-type file from apache httpd repository...');
if ($content = file_get_contents('http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=co')) {
if ($apacheMimeTypesFileContent = file_get_contents('http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=co')) {
$this->stdout("done.\n", Console::FG_GREEN);
$this->stdout("generating file $outFile...");
$mimeMap = [];
foreach (explode("\n", $content) as $line) {
$line = trim($line);
if (empty($line) || $line[0] == '#') { // skip comments and empty lines
continue;
}
$parts = preg_split('/\s+/', $line);
$mime = array_shift($parts);
foreach ($parts as $ext) {
if (!empty($ext)) {
$mimeMap[$ext] = $mime;
}
$this->generateMimeTypesFile($outFile, $apacheMimeTypesFileContent);
$this->generateMimeAliasesFile($aliasesOutFile);
} else {
$this->stderr("Failed to download mime.types file from apache SVN.\n");
}
}
/**
* @param string $outFile
* @param string $content
*/
private function generateMimeTypesFile($outFile, $content)
{
$this->stdout("generating file $outFile...");
$mimeMap = [];
foreach (explode("\n", $content) as $line) {
$line = trim($line);
if (empty($line) || $line[0] === '#') { // skip comments and empty lines
continue;
}
$parts = preg_split('/\s+/', $line);
$mime = array_shift($parts);
foreach ($parts as $ext) {
if (!empty($ext)) {
$mimeMap[$ext] = $mime;
}
}
ksort($mimeMap);
$array = VarDumper::export($mimeMap);
$content = <<<EOD
}
ksort($mimeMap);
$array = VarDumper::export($mimeMap);
$content = <<<EOD
<?php
/**
* MIME types.
@ -68,10 +94,28 @@ class MimeTypeController extends Controller
return $array;
EOD;
file_put_contents($outFile, $content);
$this->stdout("done.\n", Console::FG_GREEN);
} else {
$this->stderr("Failed to download mime.types file from apache SVN.\n");
}
file_put_contents($outFile, $content);
$this->stdout("done.\n", Console::FG_GREEN);
}
/**
* @param string $outFile
*/
private function generateMimeAliasesFile($outFile)
{
$this->stdout("generating file $outFile...");
$array = VarDumper::export($this->aliases);
$content = <<<EOD
<?php
/**
* MIME aliases.
*
* This file contains aliases for MIME types.
*/
return $array;
EOD;
file_put_contents($outFile, $content);
$this->stdout("done.\n", Console::FG_GREEN);
}
}

101
build/controllers/PhpDocController.php

@ -11,6 +11,7 @@ use Yii;
use yii\console\Controller;
use yii\helpers\Console;
use yii\helpers\FileHelper;
use yii\helpers\Json;
/**
* PhpDocController is there to help maintaining PHPDoc annotation in class files.
@ -21,6 +22,9 @@ use yii\helpers\FileHelper;
*/
class PhpDocController extends Controller
{
/**
* {@inheritdoc}
*/
public $defaultAction = 'property';
/**
* @var bool whether to update class docs directly. Setting this to false will just output docs
@ -82,7 +86,7 @@ class PhpDocController extends Controller
$nFilesUpdated = 0;
foreach ($files as $file) {
$contents = file_get_contents($file);
$sha = sha1($contents);
$hash = $this->hash($contents);
// fix line endings
$lines = preg_split('/(\r\n|\n|\r)/', $contents);
@ -94,10 +98,10 @@ class PhpDocController extends Controller
$lines = array_values($this->fixLineSpacing($lines));
$newContent = implode("\n", $lines);
if ($sha !== sha1($newContent)) {
if ($hash !== $this->hash($newContent)) {
file_put_contents($file, $newContent);
$nFilesUpdated++;
}
file_put_contents($file, $newContent);
$nFilesTotal++;
}
@ -106,13 +110,18 @@ class PhpDocController extends Controller
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function options($actionID)
{
return array_merge(parent::options($actionID), ['updateFiles', 'skipFrameworkRequirements']);
}
/**
* @param string $root
* @param bool $needsInclude
* @return array list of files.
*/
protected function findFiles($root, $needsInclude = true)
{
$except = [];
@ -132,7 +141,7 @@ class PhpDocController extends Controller
'/generators/extension/default/AutoloadExample.php',
],
'swiftmailer' => [
'/Logger.php',
'src/Logger.php',
],
'twig' => [
'/Extension.php',
@ -147,13 +156,9 @@ class PhpDocController extends Controller
}
if ($root === null) {
$root = dirname(YII2_PATH);
$root = \dirname(YII2_PATH);
$extensionPath = "$root/extensions";
foreach (scandir($extensionPath) as $extension) {
if (ctype_alpha($extension) && is_dir($extensionPath . '/' . $extension)) {
Yii::setAlias("@yii/$extension", "$extensionPath/$extension");
}
}
$this->setUpExtensionAliases($extensionPath);
$except = [
'/apps/',
@ -172,11 +177,11 @@ class PhpDocController extends Controller
}
}
} elseif (preg_match('~extensions/([\w-]+)[\\\\/]?$~', $root, $matches)) {
$extensionPath = dirname(rtrim($root, '\\/'));
$extensionPath = \dirname(rtrim($root, '\\/'));
$this->setUpExtensionAliases($extensionPath);
list(, $extension) = $matches;
Yii::setAlias("@yii/$extension", "$root");
Yii::setAlias("@yii/$extension", (string)$root);
if (is_file($autoloadFile = Yii::getAlias("@yii/$extension/vendor/autoload.php"))) {
include $autoloadFile;
}
@ -195,11 +200,11 @@ class PhpDocController extends Controller
// return [];
// }
} elseif (preg_match('~apps/([\w-]+)[\\\\/]?$~', $root, $matches)) {
$extensionPath = dirname(dirname(rtrim($root, '\\/'))) . '/extensions';
$extensionPath = \dirname(\dirname(rtrim($root, '\\/'))) . '/extensions';
$this->setUpExtensionAliases($extensionPath);
list(, $appName) = $matches;
Yii::setAlias("@app-$appName", "$root");
Yii::setAlias("@app-$appName", (string)$root);
if (is_file($autoloadFile = Yii::getAlias("@app-$appName/vendor/autoload.php"))) {
include $autoloadFile;
}
@ -230,14 +235,30 @@ class PhpDocController extends Controller
'vendor/',
]),
];
return FileHelper::findFiles($root, $options);
}
/**
* @param string $extensionPath root path containing extension repositories.
*/
private function setUpExtensionAliases($extensionPath)
{
foreach (scandir($extensionPath) as $extension) {
if (ctype_alpha($extension) && is_dir($extensionPath . '/' . $extension)) {
Yii::setAlias("@yii/$extension", "$extensionPath/$extension");
$composerConfigFile = $extensionPath . '/' . $extension . '/composer.json';
if (file_exists($composerConfigFile)) {
$composerConfig = Json::decode(file_get_contents($composerConfigFile));
if (isset($composerConfig['autoload']['psr-4'])) {
foreach ($composerConfig['autoload']['psr-4'] as $namespace => $subPath) {
$alias = '@' . str_replace('\\', '/', $namespace);
$path = rtrim("$extensionPath/$extension/$subPath", '/');
Yii::setAlias($alias, $path);
}
}
}
}
}
}
@ -285,6 +306,7 @@ class PhpDocController extends Controller
/**
* Markdown aware fix of whitespace issues in doc comments.
* @param array $lines
*/
protected function fixDocBlockIndentation(&$lines)
{
@ -326,7 +348,7 @@ class PhpDocController extends Controller
$codeBlock = !$codeBlock;
$listIndent = '';
} elseif (preg_match('/^(\s*)([0-9]+\.|-|\*|\+) /', $docLine, $matches)) {
$listIndent = str_repeat(' ', strlen($matches[0]));
$listIndent = str_repeat(' ', \strlen($matches[0]));
$tag = false;
$lines[$i] = $indent . ' * ' . $docLine;
continue;
@ -340,6 +362,10 @@ class PhpDocController extends Controller
}
}
/**
* @param string $line
* @return string
*/
protected function fixParamTypes($line)
{
return preg_replace_callback('~@(param|return) ([\w\\|]+)~i', function ($matches) {
@ -532,10 +558,10 @@ class PhpDocController extends Controller
if (trim($oldDoc) != trim($newDoc)) {
$fileContent = explode("\n", file_get_contents($file));
$start = $ref->getStartLine() - 2;
$docStart = $start - count(explode("\n", $oldDoc)) + 1;
$docStart = $start - \count(explode("\n", $oldDoc)) + 1;
$newFileContent = [];
$n = count($fileContent);
$n = \count($fileContent);
for ($i = 0; $i < $n; $i++) {
if ($i > $start || $i < $docStart) {
$newFileContent[] = $fileContent[$i];
@ -562,7 +588,7 @@ class PhpDocController extends Controller
protected function cleanDocComment($doc)
{
$lines = explode("\n", $doc);
$n = count($lines);
$n = \count($lines);
for ($i = 0; $i < $n; $i++) {
$lines[$i] = rtrim($lines[$i]);
if (trim($lines[$i]) == '*' && trim($lines[$i + 1]) == '*') {
@ -603,7 +629,7 @@ class PhpDocController extends Controller
// if no properties or other tags where present add properties at the end
if ($propertyPosition === false) {
$propertyPosition = count($lines) - 2;
$propertyPosition = \count($lines) - 2;
}
$finalDoc = '';
@ -626,22 +652,22 @@ class PhpDocController extends Controller
$namespace = $namespace['name'];
$classes = $this->match('#\n(?:abstract )?class (?<name>\w+)( extends .+)?( implements .+)?\n\{(?<content>.*)\n\}(\n|$)#', $file);
if (count($classes) > 1) {
if (\count($classes) > 1) {
$this->stderr("[ERR] There should be only one class in a file: $fileName\n", Console::FG_RED);
return false;
}
if (count($classes) < 1) {
if (\count($classes) < 1) {
$interfaces = $this->match('#\ninterface (?<name>\w+)( extends .+)?\n\{(?<content>.*)\n\}(\n|$)#', $file);
if (count($interfaces) == 1) {
if (\count($interfaces) == 1) {
return false;
} elseif (count($interfaces) > 1) {
} elseif (\count($interfaces) > 1) {
$this->stderr("[ERR] There should be only one interface in a file: $fileName\n", Console::FG_RED);
} else {
$traits = $this->match('#\ntrait (?<name>\w+)\n\{(?<content>.*)\n\}(\n|$)#', $file);
if (count($traits) == 1) {
if (\count($traits) == 1) {
return false;
} elseif (count($traits) > 1) {
} elseif (\count($traits) > 1) {
$this->stderr("[ERR] There should be only one class/trait/interface in a file: $fileName\n", Console::FG_RED);
} else {
$this->stderr("[ERR] No class in file: $fileName\n", Console::FG_RED);
@ -682,13 +708,13 @@ class PhpDocController extends Controller
ksort($props);
if (count($props) > 0) {
if (\count($props) > 0) {
$phpdoc .= " *\n";
foreach ($props as $propName => &$prop) {
$docline = ' * @';
$docline .= 'property'; // Do not use property-read and property-write as few IDEs support complex syntax.
$note = '';
if (isset($prop['get']) && isset($prop['set'])) {
if (isset($prop['get'], $prop['set'])) {
if ($prop['get']['type'] != $prop['set']['type']) {
$note = ' Note that the type of this property differs in getter and setter.'
. ' See [[get' . ucfirst($propName) . '()]] and [[set' . ucfirst($propName) . '()]] for details.';
@ -706,7 +732,7 @@ class PhpDocController extends Controller
}
if (!$parentSetter) {
$note = ' This property is read-only.';
// $docline .= '-read';
//$docline .= '-read';
}
} elseif (isset($prop['set'])) {
// check if parent class has getter defined
@ -721,7 +747,7 @@ class PhpDocController extends Controller
}
if (!$parentGetter) {
$note = ' This property is write-only.';
// $docline .= '-write';
//$docline .= '-write';
}
} else {
continue;
@ -773,11 +799,24 @@ class PhpDocController extends Controller
return '';
}
return strtoupper(substr($str, 0, 1)) . substr($str, 1) . ($str[strlen($str) - 1] != '.' ? '.' : '');
return strtoupper(substr($str, 0, 1)) . substr($str, 1) . ($str[\strlen($str) - 1] != '.' ? '.' : '');
}
protected function getPropParam($prop, $param)
{
return isset($prop['property']) ? $prop['property'][$param] : (isset($prop['get']) ? $prop['get'][$param] : $prop['set'][$param]);
}
/**
* Generate a hash value (message digest)
* @param string $string message to be hashed.
* @return string calculated message digest.
*/
private function hash($string)
{
if (!function_exists('hash')) {
return sha1($string);
}
return hash('sha256', $string);
}
}

38
build/controllers/ReleaseController.php

@ -82,7 +82,7 @@ class ReleaseController extends Controller
throw new Exception('Sorry, but releases should be run interactively to ensure you actually verify what you are doing ;)');
}
if ($this->basePath === null) {
$this->basePath = dirname(dirname(__DIR__));
$this->basePath = \dirname(\dirname(__DIR__));
}
$this->basePath = rtrim($this->basePath, '\\/');
return parent::beforeAction($action);
@ -109,7 +109,7 @@ class ReleaseController extends Controller
foreach ($items as $item) {
$this->stdout("fetching tags for $item...");
if ($item === 'framework') {
$this->gitFetchTags("{$this->basePath}");
$this->gitFetchTags((string)$this->basePath);
} elseif (strncmp('app-', $item, 4) === 0) {
$this->gitFetchTags("{$this->basePath}/apps/" . substr($item, 4));
} else {
@ -183,7 +183,7 @@ class ReleaseController extends Controller
*/
public function actionRelease(array $what)
{
if (count($what) > 1) {
if (\count($what) > 1) {
$this->stdout("Currently only one simultaneous release is supported.\n");
return 1;
}
@ -315,7 +315,7 @@ class ReleaseController extends Controller
*/
public function actionSortChangelog(array $what)
{
if (count($what) > 1) {
if (\count($what) > 1) {
$this->stdout("Currently only one simultaneous release is supported.\n");
return 1;
}
@ -376,7 +376,7 @@ class ReleaseController extends Controller
{
foreach ($what as $w) {
if (strncmp('app-', $w, 4) === 0) {
if (!empty($limit) && !in_array('app', $limit)) {
if (!empty($limit) && !\in_array('app', $limit)) {
throw new Exception('Only the following types are allowed: ' . implode(', ', $limit) . "\n");
}
if (!is_dir($appPath = "{$this->basePath}/apps/" . substr($w, 4))) {
@ -386,7 +386,7 @@ class ReleaseController extends Controller
$this->ensureGitClean($appPath);
}
} elseif ($w === 'framework') {
if (!empty($limit) && !in_array('framework', $limit)) {
if (!empty($limit) && !\in_array('framework', $limit)) {
throw new Exception('Only the following types are allowed: ' . implode(', ', $limit) . "\n");
}
if (!is_dir($fwPath = "{$this->basePath}/framework")) {
@ -396,7 +396,7 @@ class ReleaseController extends Controller
$this->ensureGitClean($fwPath);
}
} else {
if (!empty($limit) && !in_array('ext', $limit)) {
if (!empty($limit) && !\in_array('ext', $limit)) {
throw new Exception('Only the following types are allowed: ' . implode(', ', $limit) . "\n");
}
if (!is_dir($extPath = "{$this->basePath}/extensions/$w")) {
@ -414,7 +414,7 @@ class ReleaseController extends Controller
{
$this->stdout("\n");
$this->stdout($h = "Preparing framework release version $version", Console::BOLD);
$this->stdout("\n" . str_repeat('-', strlen($h)) . "\n\n", Console::BOLD);
$this->stdout("\n" . str_repeat('-', \strlen($h)) . "\n\n", Console::BOLD);
if (!$this->confirm('Make sure you are on the right branch for this release and that it tracks the correct remote branch! Continue?')) {
exit(1);
@ -433,8 +433,8 @@ class ReleaseController extends Controller
$this->dryRun || Yii::$app->runAction('classmap', [$frameworkPath]);
$this->stdout("done.\n", Console::FG_GREEN, Console::BOLD);
$this->stdout('updating mimetype magic file...', Console::BOLD);
$this->dryRun || Yii::$app->runAction('mime-type', ["$frameworkPath/helpers/mimeTypes.php"]);
$this->stdout('updating mimetype magic file and mime aliases...', Console::BOLD);
$this->dryRun || Yii::$app->runAction('mime-type', ["$frameworkPath/helpers/mimeTypes.php"], ["$frameworkPath/helpers/mimeAliases.php"]);
$this->stdout("done.\n", Console::FG_GREEN, Console::BOLD);
$this->stdout("fixing various PHPDoc style issues...\n", Console::BOLD);
@ -552,7 +552,7 @@ class ReleaseController extends Controller
{
$this->stdout("\n");
$this->stdout($h = "Preparing release for application $name version $version", Console::BOLD);
$this->stdout("\n" . str_repeat('-', strlen($h)) . "\n\n", Console::BOLD);
$this->stdout("\n" . str_repeat('-', \strlen($h)) . "\n\n", Console::BOLD);
if (!$this->confirm('Make sure you are on the right branch for this release and that it tracks the correct remote branch! Continue?')) {
exit(1);
@ -670,7 +670,7 @@ class ReleaseController extends Controller
{
$this->stdout("\n");
$this->stdout($h = "Preparing release for extension $name version $version", Console::BOLD);
$this->stdout("\n" . str_repeat('-', strlen($h)) . "\n\n", Console::BOLD);
$this->stdout("\n" . str_repeat('-', \strlen($h)) . "\n\n", Console::BOLD);
if (!$this->confirm('Make sure you are on the right branch for this release and that it tracks the correct remote branch! Continue?')) {
exit(1);
@ -817,7 +817,7 @@ class ReleaseController extends Controller
$headline = $version . ' ' . date('F d, Y');
$this->sed(
'/' . $v . ' under development\n(-+?)\n/',
$headline . "\n" . str_repeat('-', strlen($headline)) . "\n",
$headline . "\n" . str_repeat('-', \strlen($headline)) . "\n",
$this->getChangelogs($what)
);
}
@ -825,7 +825,7 @@ class ReleaseController extends Controller
protected function openChangelogs($what, $version)
{
$headline = "\n$version under development\n";
$headline .= str_repeat('-', strlen($headline) - 2) . "\n\n- no changes in this release.\n";
$headline .= str_repeat('-', \strlen($headline) - 2) . "\n\n- no changes in this release.\n";
foreach ($this->getChangelogs($what) as $file) {
$lines = explode("\n", file_get_contents($file));
$hl = [
@ -874,7 +874,7 @@ class ReleaseController extends Controller
$state = 'end';
}
// add continued lines to the last item to keep them together
if (!empty(${$state}) && trim($line !== '') && strpos($line, '- ') !== 0) {
if (!empty(${$state}) && trim($line) !== '' && strncmp($line, '- ', 2) !== 0) {
end(${$state});
${$state}[key(${$state})] .= "\n" . $line;
} else {
@ -919,7 +919,7 @@ class ReleaseController extends Controller
protected function getChangelogs($what)
{
$changelogs = [];
if (in_array('framework', $what)) {
if (\in_array('framework', $what)) {
$changelogs[] = $this->getFrameworkChangelog();
}
@ -947,13 +947,13 @@ class ReleaseController extends Controller
protected function composerSetStability($what, $version)
{
$apps = [];
if (in_array('app-advanced', $what)) {
if (\in_array('app-advanced', $what)) {
$apps[] = $this->basePath . '/apps/advanced/composer.json';
}
if (in_array('app-basic', $what)) {
if (\in_array('app-basic', $what)) {
$apps[] = $this->basePath . '/apps/basic/composer.json';
}
if (in_array('app-benchmark', $what)) {
if (\in_array('app-benchmark', $what)) {
$apps[] = $this->basePath . '/apps/benchmark/composer.json';
}
if (empty($apps)) {

18
build/controllers/Utf8Controller.php

@ -29,7 +29,7 @@ class Utf8Controller extends Controller
public function actionCheckGuide($directory = null)
{
if ($directory === null) {
$directory = dirname(dirname(__DIR__)) . '/docs';
$directory = \dirname(\dirname(__DIR__)) . '/docs';
}
if (is_file($directory)) {
$files = [$directory];
@ -90,7 +90,7 @@ class Utf8Controller extends Controller
}
$hexcode = dechex($this->unicodeOrd($char));
$hexcode = str_repeat('0', max(4 - strlen($hexcode), 0)) . $hexcode;
$hexcode = str_repeat('0', max(4 - \strlen($hexcode), 0)) . $hexcode;
$this->stdout(" at $line:$pos FOUND $what: 0x$hexcode '$char' http://unicode-table.com/en/$hexcode/\n");
}
@ -105,20 +105,20 @@ class Utf8Controller extends Controller
*/
private function unicodeOrd($c)
{
$h = ord($c[0]);
$h = \ord($c[0]);
if ($h <= 0x7F) {
return $h;
} elseif ($h < 0xC2) {
return false;
} elseif ($h <= 0xDF) {
return ($h & 0x1F) << 6 | (ord($c[1]) & 0x3F);
return ($h & 0x1F) << 6 | (\ord($c[1]) & 0x3F);
} elseif ($h <= 0xEF) {
return ($h & 0x0F) << 12 | (ord($c[1]) & 0x3F) << 6
| (ord($c[2]) & 0x3F);
return ($h & 0x0F) << 12 | (\ord($c[1]) & 0x3F) << 6
| (\ord($c[2]) & 0x3F);
} elseif ($h <= 0xF4) {
return ($h & 0x0F) << 18 | (ord($c[1]) & 0x3F) << 12
| (ord($c[2]) & 0x3F) << 6
| (ord($c[3]) & 0x3F);
return ($h & 0x0F) << 18 | (\ord($c[1]) & 0x3F) << 12
| (\ord($c[2]) & 0x3F) << 6
| (\ord($c[3]) & 0x3F);
}
return false;

462
composer.lock generated

File diff suppressed because it is too large Load Diff

4
contrib/completion/bash/yii

@ -15,6 +15,7 @@ _yii()
local cur opts yii command
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
yii="${COMP_WORDS[0]}"
# exit if ./yii does not exist
@ -31,9 +32,10 @@ _yii()
[[ $cur == $command ]] && state="command"
[[ $cur != $command ]] && state="option"
[[ $cur = *=* ]] && state="value"
[[ $prev == "help" ]] && state="help"
case $state in
command)
command|help)
# complete command/route if not given
# fetch available commands from ./yii help/list command
opts=$($yii help/list 2> /dev/null)

4
contrib/completion/zsh/_yii

@ -3,6 +3,7 @@
_yii() {
local state command lastArgument commands options executive
lastArgument=${words[${#words[@]}]}
prevArgument=${words[${#words[@]}-1]}
executive=$words[1]
# lookup for command
@ -16,9 +17,10 @@ _yii() {
[[ $lastArgument == $command ]] && state="command"
[[ $lastArgument != $command ]] && state="option"
[[ $prevArgument == "help" ]] && state="help"
case $state in
command)
command|help)
commands=("${(@f)$(${executive} help/list 2>/dev/null)}")
_describe 'command' commands
;;

4
docs/guide-es/caching-data.md

@ -79,8 +79,8 @@ se muestra un listado con los componentes de caché disponibles:
* [[yii\caching\MemCache]]: utiliza las extensiones de PHP [memcache](http://php.net/manual/es/book.memcache.php) y [memcached](http://php.net/manual/es/book.memcached.php). Esta opción puede ser considerada como la más rápida cuando la caché es manejada en una aplicación distribuida (ej. con varios servidores, con balance de carga, etc..)
* [[yii\redis\Cache]]: implementa un componente de caché basado en [Redis](http://redis.io/) que almacenan pares clave-valor (requiere la versión 2.6.12 de redis).
* [[yii\caching\WinCache]]: utiliza la extensión de PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension) ([ver también](http://php.net/manual/es/book.wincache.php)).
* [[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é.
* [[yii\caching\XCache]] _(deprecated)_: utiliza la extensión de PHP [XCache](http://xcache.lighttpd.net/).
* [[yii\caching\ZendDataCache]] _(deprecated)_: 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é.
> Tip: 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).

2
docs/guide-es/concept-di-container.md

@ -75,7 +75,7 @@ En este caso, el contenedor usará una llamada de retorno PHP registrada para co
clase. La llamada de retorno se responsabiliza de que dependencias debe inyectar al nuevo objeto creado. Por ejemplo,
```php
$container->set('Foo', function () {
$container->set('Foo', function ($container, $params, $config) {
return new Foo(new Bar);
});

2
docs/guide-es/concept-events.md

@ -218,7 +218,7 @@ use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::trace(get_class($event->sender) . ' is inserted');
Yii::debug(get_class($event->sender) . ' is inserted');
});
```

10
docs/guide-es/runtime-logging.md

@ -20,7 +20,7 @@ En esta sección, se describirán principalmente los dos primeros pasos.
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::debug()]]: 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.
@ -32,7 +32,7 @@ tiene que ser registrado, mientras que `$category` es la categoría del registro
ejemplo registra la huella del mensaje para la categoría `application`:
```php
Yii::trace('start calculating average revenue');
Yii::debug('start calculating average revenue');
```
> Info: Los mensajes de registro pueden ser tanto cadenas de texto como datos complejos, como arrays u objetos.
@ -47,7 +47,7 @@ efectiva de organizarlos es usar la constante predefinida (magic constant) de PH
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__);
Yii::debug('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
@ -131,7 +131,7 @@ La propiedad [[yii\log\Target::levels|levels]] es un array que consta de uno o v
* `error`: correspondiente a los mensajes registrados por [[Yii::error()]].
* `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()]].
* `trace`: correspondiente a los mensajes registrados por [[Yii::debug()]].
* `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).
@ -290,7 +290,7 @@ 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
`Yii::debug()` 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

4
docs/guide-es/start-installation.md

@ -189,7 +189,7 @@ DocumentRoot "path/to/basic/web"
Para utilizar [Nginx](http://wiki.nginx.org/), debes instalar PHP como un [FPM SAPI](http://php.net/install.fpm).
Utiliza la siguiente configuración de Nginx, reemplazando `path/to/basic/web` con la ruta real a
`basic/web` y `mysite.local` con el hostname real a servir.
`basic/web` y `mysite.test` con el hostname real a servir.
```
server {
@ -199,7 +199,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

2
docs/guide-es/structure-filters.md

@ -94,7 +94,7 @@ class ActionTimeFilter extends ActionFilter
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
Yii::debug("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}

4
docs/guide-fr/caching-data.md

@ -100,8 +100,8 @@ Yii prend en charge un large panel de supports de stockage pour cache. Ce qui su
(une version de redis égale ou supérieure à 2.6.12 est nécessaire).
* [[yii\caching\WinCache]]: utilise le [WinCache](http://iis.net/downloads/microsoft/wincache-extension) PHP
([voir aussi l'extension](http://php.net/manual/en/book.wincache.php)).
* [[yii\caching\XCache]]: utilise l'extension PHP [XCache](http://xcache.lighttpd.net/).
* [[yii\caching\ZendDataCache]]: utilise le
* [[yii\caching\XCache]] _(deprecated)_: utilise l'extension PHP [XCache](http://xcache.lighttpd.net/).
* [[yii\caching\ZendDataCache]] _(deprecated)_: utilise le
[cache de données Zend](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm)
en tant que médium de cache sous-jacent.

4
docs/guide-fr/concept-di-container.md

@ -99,7 +99,7 @@ $container->get('Foo', [], [
Dans ce cas, le conteneur utilise une fonction de rappel PRP enregistrée pour construire de nouvelles instances d'une classe. À chaque fois que [[yii\di\Container::get()]] est appelée, la fonction de rappel correspondante est invoquée. Cette fonction de rappel est chargée de la résolution des dépendances et de leur injection appropriée dans les objets nouvellement créés. Par exemple :
```php
$container->set('Foo', function () {
$container->set('Foo', function ($container, $params, $config) {
$foo = new Foo(new Bar);
// ... autres initialisations ...
return $foo;
@ -113,7 +113,7 @@ Pour cacher la logique complexe de construction des nouveaux objets, vous pouvez
```php
class FooBuilder
{
public static function build()
public static function build($container, $params, $config)
{
$foo = new Foo(new Bar);
// ... autres initialisations ...

4
docs/guide-fr/concept-events.md

@ -186,7 +186,7 @@ use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::trace(get_class($event->sender) . ' is inserted');
Yii::debug(get_class($event->sender) . ' is inserted');
});
```
@ -263,7 +263,7 @@ Pour gérer l'évenement `EVENT_DANCE` déclenché par n'importe laquelle de ces
```php
Event::on('app\interfaces\DanceEventInterface', DanceEventInterface::EVENT_DANCE, function ($event) {
Yii::trace(get_class($event->sender) . ' just danced'); // Will log that Dog or Developer danced
Yii::debug(get_class($event->sender) . ' just danced'); // Will log that Dog or Developer danced
});
```

10
docs/guide-fr/runtime-logging.md

@ -16,7 +16,7 @@ Dans cette section, nous décrivons principalement les deux premières étapes.
Enregistrer des messages est aussi simple que d'appeler une des méthodes suivantes :
* [[Yii::trace()]]: enregistre un message pour garder une trace de comment un morceau de code fonctionne. Cela est utilisé principalement en développement.
* [[Yii::debug()]]: enregistre un message pour garder une trace de comment un morceau de code fonctionne. Cela est utilisé principalement en développement.
* [[Yii::info()]]: enregistre un message qui contient quelques informations utiles.
* [[Yii::warning()]]: enregistre un message d'avertissement qui indique que quelque chose d'inattendu s'est produit.
* [[Yii::error()]]: enregistre une erreur fatale qui doit être analysée dès que possible.
@ -24,7 +24,7 @@ Enregistrer des messages est aussi simple que d'appeler une des méthodes suivan
Ces méthodes enregistrent les messages à différents niveaux de sévérité et dans différentes catégories. Elles partagent la même signature `function ($message, $category = 'application')`, où `$message` représente le message à enregistrer, tandis que `$category` est la catégorie de ce message. Le code de l'exemple qui suit enregistre un message de trace dans la catégorie `application`:
```php
Yii::trace('start calculating average revenue');
Yii::debug('start calculating average revenue');
```
> Info: les messages enregistrés peuvent être des chaînes de caractères aussi bien que des données complexes telles que des tableaux ou des objets. Il est de la responsabilité des [cibles d'enregistrement](#log-targets) de traiter correctement ces messages. Par défaut, si un message enregistré n'est pas un chaîne de caractères, il est exporté comme une chaîne de caractères en appelant la méthode [[yii\helpers\VarDumper::export()]].
@ -32,7 +32,7 @@ Yii::trace('start calculating average revenue');
Pour mieux organiser et filtrer les messages enregistrés, il est recommandé que vous spécifiiez une catégorie appropriée pour chacun des messages. Vous pouvez choisir une schéma de nommage hiérarchisé pour les catégories, ce qui facilitera le filtrage des messages par les [cibles d'enregistrement](#log-targets) sur la base de ces catégories. Un schéma de nommage simple et efficace est d'utiliser la constante magique `__METHOD__` de PHP dans les noms de catégorie. Par exemple :
```php
Yii::trace('start calculating average revenue', __METHOD__);
Yii::debug('start calculating average revenue', __METHOD__);
```
La constante magique `__METHOD__` est évaluée comme le nom de la méthode (préfixée par le nom pleinement qualifié de la classe), là où la constante apparaît. Par exemple, elle est égale à `'app\controllers\RevenueController::calculate'` si la ligne suivante est utilisée dans cette méthode.
@ -100,7 +100,7 @@ La propriété [[yii\log\Target::levels|levels]] accepte un tableau constitué d
* `error`: correspondant aux messages enregistrés par [[Yii::error()]].
* `warning`: correspondant aux messages enregistrés par [[Yii::warning()]].
* `info`: correspondant aux messages enregistrés par [[Yii::info()]].
* `trace`: correspondant aux messages enregistrés par [[Yii::trace()]].
* `trace`: correspondant aux messages enregistrés par [[Yii::debug()]].
* `profile`: correspondant aux messages enregistrés par [[Yii::beginProfile()]] et [[Yii::endProfile()]], et qui sera expliqué en détails dans la sous-section [Profilage de la performance](#performance-profiling).
Si vous ne spécifiez pas la propriété [[yii\log\Target::levels|levels]], cela signifie que la cible traitera les messages de *n'importe quel* niveau de sévérité.
@ -222,7 +222,7 @@ Lorsque l'[[yii\log\Logger|objet *logger*]] purge les messages enregistrés vers
]
```
À cause des niveaux de purge et d'exportation, par défaut, lorsque vous appelez `Yii::trace()` ou toute autre méthode d'enregistrement, vous ne voyez PAS immédiatement le message enregistré dans la cible. Cela peut représenter un problème pour pour certaines applications de console qui durent longtemps. Pour faire en sorte que les messages apparaissent immédiatement dans les cibles d'enregistrement, vous devriez définir les propriétés [[yii\log\Dispatcher::flushInterval|flushInterval]] et [[yii\log\Target::exportInterval|exportInterval]] toutes deux à 1, comme montré ci-après :
À cause des niveaux de purge et d'exportation, par défaut, lorsque vous appelez `Yii::debug()` ou toute autre méthode d'enregistrement, vous ne voyez PAS immédiatement le message enregistré dans la cible. Cela peut représenter un problème pour pour certaines applications de console qui durent longtemps. Pour faire en sorte que les messages apparaissent immédiatement dans les cibles d'enregistrement, vous devriez définir les propriétés [[yii\log\Dispatcher::flushInterval|flushInterval]] et [[yii\log\Target::exportInterval|exportInterval]] toutes deux à 1, comme montré ci-après :
```php
return [

4
docs/guide-fr/start-installation.md

@ -120,7 +120,7 @@ DocumentRoot "path/to/basic/web"
### Configuration Nginx recommandée <span id="recommended-nginx-configuration"></span>
Pour utiliser Nginx, vous devez avoir installé PHP en utilisant [FPM SAPI](http://php.net/install.fpm).
Utilisez la configuration Nginx suivante, en remplaçant `path/to/basic/web` par le chemin vers le dossier `basic/web` et `mysite.local` par le nom d'hôte de votre serveur.
Utilisez la configuration Nginx suivante, en remplaçant `path/to/basic/web` par le chemin vers le dossier `basic/web` et `mysite.test` par le nom d'hôte de votre serveur.
```
server {
@ -130,7 +130,7 @@ server {
listen 80; ## port pour ipv4
#listen [::]:80 default_server ipv6only=on; ## port pour ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

2
docs/guide-fr/structure-filters.md

@ -72,7 +72,7 @@ class ActionTimeFilter extends ActionFilter
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
Yii::debug("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}

2
docs/guide-fr/tutorial-i18n.md

@ -327,7 +327,7 @@ tandis que `one` correspond à `21` ou `101`:
```
Ces noms d'arguments spéciaux tels que `other`, `few`, `many` et autres varient en fonction de la langue. Pour savoir lesquels utiliser pour une locale particulière, reportez-vous aux "Plural Rules, Cardinal" à [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/).
En alternative, vous pouvez vous reporter aux [rules reference at unicode.org](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html).
En alternative, vous pouvez vous reporter aux [rules reference at unicode.org](http://cldr.unicode.org/index/cldr-spec/plural-rules).
> Note: le message en russe ci-dessus est principalement utilisé comme message traduit, pas comme message source, sauf si vous définissez la [[yii\base\Application::$sourceLanguage|langue source]] de votre application comme étant `ru-RU` et traduisez à partir du russe.
>

4
docs/guide-id/start-installation.md

@ -189,7 +189,7 @@ DocumentRoot "path/to/basic/web"
Untuk menggunakan [Nginx](http://wiki.nginx.org/), Anda harus menginstal PHP sebagai [FPM SAPI](http://php.net/install.fpm).
Anda dapat menggunakan konfigurasi Nginx berikut, menggantikan `path/to/basic/web` dengan path yang sebenarnya untuk
`basic/web` dan `mysite.local` dengan hostname yang sebenarnya untuk server.
`basic/web` dan `mysite.test` dengan hostname yang sebenarnya untuk server.
```nginx
server {
@ -199,7 +199,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

4
docs/guide-it/start-installation.md

@ -161,7 +161,7 @@ DocumentRoot "path/to/basic/web"
### Configurazione consigliata di Nginx <span id="recommended-nginx-configuration"></span>
Devi aver installato PHP con il demone [FPM](http://php.net/install.fpm) per usare [Nginx](http://wiki.nginx.org/).
Usa questa configurazione per Nginx, sostituendo `path/to/basic/web` con il percorso reale di `basic/web` e `mysite.local` con
Usa questa configurazione per Nginx, sostituendo `path/to/basic/web` con il percorso reale di `basic/web` e `mysite.test` con
il nome reale del server web.
```
@ -172,7 +172,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

4
docs/guide-ja/caching-data.md

@ -111,8 +111,8 @@ Yii はさまざまなキャッシュストレージをサポートしていま
分散型のアプリケーションでキャッシュを扱うときには最速の一つとして考えることができます (例えば、複数台のサーバで、ロードバランサがある、などの場合) 。
* [[yii\redis\Cache]]: [Redis](http://redis.io/) の key-value ストアに基づいてキャッシュコンポーネントを実装しています。(Redis の バージョン 2.6.12 以降が必要です) 。
* [[yii\caching\WinCache]]: PHP の [WinCache](http://iis.net/downloads/microsoft/wincache-extension) ([関連リンク](http://php.net/manual/ja/book.wincache.php)) 拡張モジュールを使用します。
* [[yii\caching\XCache]]: PHP の [XCache](http://xcache.lighttpd.net/) 拡張モジュールを使用します。
* [[yii\caching\ZendDataCache]]: キャッシュメディアして [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) を使用します。
* [[yii\caching\XCache]] _(deprecated)_: PHP の [XCache](http://xcache.lighttpd.net/) 拡張モジュールを使用します。
* [[yii\caching\ZendDataCache]] _(deprecated)_: キャッシュメディアして [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) を使用します。
> Tip: 同じアプリケーション内で異なるキャッシュを使用することもできます。一般的なやり方として、小さくとも常に使用されるデータ (例えば、統計データ) を格納する場合はメモリベースのキャッシュストレージを使用し、大きくて使用頻度の低いデータ (例えば、ページコンテント) を格納する場合はファイルベース、またはデータベースのキャッシュストレージを使用します 。

6
docs/guide-ja/concept-di-container.md

@ -114,7 +114,7 @@ $container->get('Foo', [], [
たとえば
```php
$container->set('Foo', function () {
$container->set('Foo', function ($container, $params, $config) {
$foo = new Foo(new Bar);
// ... その他の初期化 ...
return $foo;
@ -129,7 +129,7 @@ $foo = $container->get('Foo');
```php
class FooBuilder
{
public static function build()
public static function build($container, $params, $config)
{
$foo = new Foo(new Bar);
// ... その他の初期化 ...
@ -413,7 +413,7 @@ $container->setDefinitions([
'class' => 'app\components\Response',
'format' => 'json'
],
'app\storage\DocumentsReader' => function () {
'app\storage\DocumentsReader' => function ($container, $params, $config) {
$fs = new app\storage\FileStorage('/var/tempfiles');
return new app\storage\DocumentsReader($fs);
}

4
docs/guide-ja/concept-events.md

@ -209,7 +209,7 @@ use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::trace(get_class($event->sender) . ' が挿入されました');
Yii::debug(get_class($event->sender) . ' が挿入されました');
});
```
@ -292,7 +292,7 @@ class Developer extends Component implements DanceEventInterface
```php
Event::on('app\interfaces\DanceEventInterface', DanceEventInterface::EVENT_DANCE, function ($event) {
Yii::trace(get_class($event->sender) . ' が躍り上がって喜んだ。'); // 犬または開発者が躍り上がって喜んだことをログに記録。
Yii::debug(get_class($event->sender) . ' が躍り上がって喜んだ。'); // 犬または開発者が躍り上がって喜んだことをログに記録。
});
```

10
docs/guide-ja/runtime-logging.md

@ -17,7 +17,7 @@ Yii のロギングフレームワークを使うためには、下記のステ
ログメッセージを記録することは、次のログ記録メソッドのどれかを呼び出すだけの簡単なことです。
* [[Yii::trace()]]: コードの断片がどのように走ったかをトレースするメッセージを記録します。主として開発のために使用します。
* [[Yii::debug()]]: コードの断片がどのように走ったかをトレースするメッセージを記録します。主として開発のために使用します。
* [[Yii::info()]]: 何らかの有用な情報を伝えるメッセージを記録します。
* [[Yii::warning()]]: 何か予期しないことが発生したことを示す警告メッセージを記録します。
* [[Yii::error()]]: 出来るだけ早急に調査すべき致命的なエラーを記録します。
@ -27,7 +27,7 @@ Yii のロギングフレームワークを使うためには、下記のステ
次のコードサンプルは、トレースメッセージをデフォルトのカテゴリである `application` の下に記録するものです。
```php
Yii::trace('平均収益の計算を開始');
Yii::debug('平均収益の計算を開始');
```
> Info: ログメッセージは文字列でも、配列やオブジェクトのような複雑なデータでも構いません。
@ -40,7 +40,7 @@ Yii::trace('平均収益の計算を開始');
これは、Yii フレームワークのコアコードでも使われている方法です。例えば、
```php
Yii::trace('平均収益の計算を開始', __METHOD__);
Yii::debug('平均収益の計算を開始', __METHOD__);
```
`__METHOD__` という定数は、それが出現する場所のメソッド名 (完全修飾のクラス名が前置されます) として評価されます。
@ -116,7 +116,7 @@ Yii は下記のログターゲットをあらかじめ内蔵しています。
* `error`: [[Yii::error()]] によって記録されたメッセージに対応。
* `warning`: [[Yii::warning()]] によって記録されたメッセージに対応。
* `info`: [[Yii::info()]] によって記録されたメッセージに対応。
* `trace`: [[Yii::trace()]] によって記録されたメッセージに対応。
* `trace`: [[Yii::debug()]] によって記録されたメッセージに対応。
* `profile`: [[Yii::beginProfile()]] と [[Yii::endProfile()]] によって記録されたメッセージに対応。
これについては、[プロファイリング](#performance-profiling) の項で詳細に説明します。
@ -255,7 +255,7 @@ return [
]
```
デフォルトの状態では、吐き出しとエクスポートの間隔の設定のために、`Yii::trace()` やその他のログ記録メソッドを呼んでも、ただちには、ログメッセージはログターゲットに出現しません。
デフォルトの状態では、吐き出しとエクスポートの間隔の設定のために、`Yii::debug()` やその他のログ記録メソッドを呼んでも、ただちには、ログメッセージはログターゲットに出現しません。
このことは、長時間にわたって走るコンソールアプリケーションでは、問題になる場合もあります。
各ログメッセージがただちにログターゲットに出現するようにするためには、下記のように、[[yii\log\Dispatcher::flushInterval|flushInterval]] と [[yii\log\Target::exportInterval|exportInterval]] の両方を 1 に設定しなければなりません。

4
docs/guide-ja/start-installation.md

@ -202,7 +202,7 @@ DocumentRoot "path/to/basic/web"
[Nginx](http://wiki.nginx.org/) を使うためには、PHP を [FPM SAPI](http://jp1.php.net/install.fpm) としてインストールしなければなりません。
下記の Nginx の設定を使うことができます。
`path/to/basic/web` の部分を `basic/web` の実際のパスに置き換え、`mysite.local` を実際のサーバのホスト名に置き換えてください。
`path/to/basic/web` の部分を `basic/web` の実際のパスに置き換え、`mysite.test` を実際のサーバのホスト名に置き換えてください。
```nginx
server {
@ -212,7 +212,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

2
docs/guide-ja/structure-filters.md

@ -83,7 +83,7 @@ class ActionTimeFilter extends ActionFilter
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("アクション '{$action->uniqueId}' は $time 秒を消費。");
Yii::debug("アクション '{$action->uniqueId}' は $time 秒を消費。");
return parent::afterAction($action, $result);
}
}

2
docs/guide-ja/tutorial-i18n.md

@ -459,7 +459,7 @@ echo \Yii::t('app', 'There {n,plural,=0{are no cats} =1{is one cat} other{are #
これら `other`、`few`、`many` などの特別な引数の名前は言語によって異なります。
特定のロケールに対してどんな引数を指定すべきかを学ぶためには、[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Plural Rules, Cardinal" を参照してください。
あるいは、その代りに、[unicode.org の規則のリファレンス](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html) を参照することも出来ます。
あるいは、その代りに、[unicode.org の規則のリファレンス](http://cldr.unicode.org/index/cldr-spec/plural-rules) を参照することも出来ます。
> Note: 上記のロシア語のメッセージのサンプルは、主として翻訳メッセージとして使用されるものです。

4
docs/guide-pl/start-installation.md

@ -203,7 +203,7 @@ DocumentRoot "path/to/basic/web"
Aby użyć [Nginx](http://wiki.nginx.org/) powinienieś zainstalować PHP jako [FPM SAPI](http://php.net/install.fpm).
Możesz użyć przedstawionej poniżej konfiguracji Nginx, zastępując jedynie ścieżkę `path/to/basic/web` aktualną ścieżką do `basic/web` Twojej aplikacji oraz
`mysite.local` aktualną nazwą hosta.
`mysite.test` aktualną nazwą hosta.
```nginx
server {
@ -213,7 +213,7 @@ server {
listen 80; ## nasłuchuj ipv4
#listen [::]:80 default_server ipv6only=on; ## nasłuchuj ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

4
docs/guide-pt-BR/caching-data.md

@ -96,8 +96,8 @@ Yii suporta uma ampla gama de sistemas de cache. A seguir um resumo:
[Redis](http://redis.io/) (requer redis versão 2.6.12 ou mais recente).
* [[yii\caching\WinCache]]: usa a extensão PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)
([veja também](http://php.net/manual/en/book.wincache.php)).
* [[yii\caching\XCache]]: usa a extensão PHP [XCache](http://xcache.lighttpd.net/).
* [[yii\caching\ZendDataCache]]: usa
* [[yii\caching\XCache]] _(deprecated)_: usa a extensão PHP [XCache](http://xcache.lighttpd.net/).
* [[yii\caching\ZendDataCache]] _(deprecated)_: usa
[Cache de Dados Zend](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm)
como o meio de cache subjacente.

4
docs/guide-pt-BR/concept-di-container.md

@ -75,7 +75,7 @@ Cada vez que [[yii\di\Container::get()]] for chamado, o callable correspondente
O callable é responsável por resolver as dependências e injetá-las de forma adequada para os objetos recém-criados. Por exemplo:
```php
$container->set('Foo', function () {
$container->set('Foo', function ($container, $params, $config) {
$foo = new Foo(new Bar);
// ... Outras inicializações...
return $foo;
@ -89,7 +89,7 @@ Para ocultar a lógica complexa da construção de um novo objeto você pode usa
```php
class FooBuilder
{
public static function build()
public static function build($container, $params, $config)
{
return function () {
$foo = new Foo(new Bar);

2
docs/guide-pt-BR/concept-events.md

@ -192,7 +192,7 @@ use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::trace(get_class($event->sender) . ' is inserted');
Yii::debug(get_class($event->sender) . ' is inserted');
});
```

10
docs/guide-pt-BR/runtime-logging.md

@ -16,7 +16,7 @@ Nesta seção, vamos descrever principalmente os dois primeiros passos.
Gravar mensagens de log é tão simples como chamar um dos seguintes métodos de registro:
* [[Yii::trace()]]: gravar uma mensagem para rastrear como um determinado trecho de código é executado. Isso é principalmente para o uso de desenvolvimento.
* [[Yii::debug()]]: gravar uma mensagem para rastrear como um determinado trecho de código é executado. Isso é principalmente para o uso de desenvolvimento.
* [[Yii::info()]]: gravar uma mensagem que transmite algumas informações úteis.
* [[Yii::warning()]]: gravar uma mensagem de aviso que indica que algo inesperado aconteceu.
* [[Yii::error()]]: gravar um erro fatal que deve ser investigado o mais rápido possível.
@ -24,7 +24,7 @@ Gravar mensagens de log é tão simples como chamar um dos seguintes métodos de
Estes métodos gravam mensagens de log em vários *níveis* e *categorias*. Eles compartilham a mesma assinatura de função `function ($message, $category = 'application')`, onde `$message` significa a mensagem de log a ser gravada, enquanto `$category` é a categoria da mensagem de log. O código no exemplo a seguir registra uma mensagem de rastreamento sob a categoria padrão `application`:
```php
Yii::trace('start calculating average revenue');
Yii::debug('start calculating average revenue');
```
> Observação: Mensagens de log podem ser strings, bem como dados complexos, tais como arrays ou objetos. É da responsabilidade dos [destinos de log](#log-targets) lidar adequadamente com as mensagens de log. Por padrão, se uma mensagem de log não for uma string, ela será exportada como uma string chamando [[yii\helpers\VarDumper::export()]].
@ -32,7 +32,7 @@ Yii::trace('start calculating average revenue');
Para melhor organizar e filtrar as mensagens de log, é recomendável que você especifique uma categoria apropriada para cada mensagem de log. Você pode escolher um esquema de nomenclatura hierárquica para as categorias, o que tornará mais fácil para os [destinos de log](#log-targets) filtrar mensagens com base em suas categorias. Um esquema de nomes simples, mas eficaz é usar a constante mágica PHP `__METHOD__` para os nomes das categorias. Esta é também a abordagem utilizada no código central do framework Yii. Por exemplo,
```php
Yii::trace('start calculating average revenue', __METHOD__);
Yii::debug('start calculating average revenue', __METHOD__);
```
A constante `__METHOD__` corresponde ao nome do método (prefixado com o caminho completo do nome da classe) onde a constante aparece. Por exemplo, é igual a string `'app\controllers\RevenueController::calculate'` se o código acima for chamado dentro deste método.
@ -100,7 +100,7 @@ A propriedade [[yii\log\Target::levels|levels]] é um array que consiste em um o
* `error`: corresponde a mensagens logadas por [[Yii::error()]].
* `warning`: corresponde a mensagens logadas por [[Yii::warning()]].
* `info`: corresponde a mensagens logadas por [[Yii::info()]].
* `trace`: corresponde a mensagens logadas por [[Yii::trace()]].
* `trace`: corresponde a mensagens logadas por [[Yii::debug()]].
* `profile`: corresponde a mensagens logadas por [[Yii::beginProfile()]] e [[Yii::endProfile()]], que será explicado em mais detalhes na subseção [Perfil de Desempenho](#performance-profiling).
Se você não especificar a propriedade [[yii\log\Target::levels|levels]], significa que o alvo de log processará mensagens de *qualquer* nível.
@ -218,7 +218,7 @@ Quando o [[yii\log\Logger|logger object]] libera mensagens de log para os [alvos
]
```
Devido a configuração de nível, liberação e exportação, por padrão quando você chama `Yii::trace()` ou qualquer outro método de log, você NÃO verá a mensagem de log imediatamente no destino. Isto poderia ser um problema para algumas aplicações console de longa execução. Para fazer cada mensagem de log aparecer imediatamente no destino, você deve configurar ambos [[yii\log\Dispatcher::flushInterval|flushInterval]] e [[yii\log\Target::exportInterval|exportInterval]] para 1, como mostrado a seguir:
Devido a configuração de nível, liberação e exportação, por padrão quando você chama `Yii::debug()` ou qualquer outro método de log, você NÃO verá a mensagem de log imediatamente no destino. Isto poderia ser um problema para algumas aplicações console de longa execução. Para fazer cada mensagem de log aparecer imediatamente no destino, você deve configurar ambos [[yii\log\Dispatcher::flushInterval|flushInterval]] e [[yii\log\Target::exportInterval|exportInterval]] para 1, como mostrado a seguir:
```php
return [

4
docs/guide-pt-BR/start-installation.md

@ -202,7 +202,7 @@ DocumentRoot "path/to/basic/web"
Você deve ter instalado o PHP como um [FPM SAPI](http://php.net/install.fpm) para
usar o [Nginx](http://wiki.nginx.org/). Use a seguinte configuração do Nginx,
substituindo `path/to/basic/web` com o caminho real para `basic/web` e `mysite.local`
substituindo `path/to/basic/web` com o caminho real para `basic/web` e `mysite.test`
com o nome de host real a servidor.
```
@ -213,7 +213,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

2
docs/guide-pt-BR/structure-filters.md

@ -105,7 +105,7 @@ class ActionTimeFilter extends ActionFilter
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
Yii::debug("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}

3
docs/guide-ru/README.md

@ -79,7 +79,7 @@ All Rights Reserved.
* [Active Record](db-active-record.md) - Получение объектов AR, работа с ними и определение связей.
* [Миграции](db-migrations.md) - Контроль версий схемы данных при работе в команде.
* [Sphinx](https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide-ru/README.md)
* [Redis](https://github.com/yiisoft/yii2-redis/blob/master/docs/guide/README.md)
* [Redis](https://github.com/yiisoft/yii2-redis/blob/master/docs/guide-ru/README.md)
* [MongoDB](https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide-ru/README.md)
* [ElasticSearch](https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md)
@ -175,6 +175,7 @@ All Rights Reserved.
* [Окружение виртуального хостинга](tutorial-shared-hosting.md)
* [Шаблонизаторы](tutorial-template-engines.md)
* [Работа со сторонним кодом](tutorial-yii-integration.md)
* [Использование Yii в качестве микро-framework'а](tutorial-yii-as-micro-framework.md)
Виджеты

4
docs/guide-ru/caching-data.md

@ -102,8 +102,8 @@ Yii поддерживает множество хранилищ кэша:
* [[yii\caching\MemCache]]: использует расширения PHP [memcache](http://php.net/manual/en/book.memcache.php) и [memcached](http://php.net/manual/en/book.memcached.php). Этот вариант может рассматриваться как самый быстрый при работе в распределенных приложениях (например, с несколькими серверами, балансировкой нагрузки и так далее);
* [[yii\redis\Cache]]: реализует компонент кэша на основе [Redis](http://redis.io/), хранилища ключ-значение (требуется Redis версии 2.6.12 или выше);
* [[yii\caching\WinCache]]: использует расширение PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension) ([смотрите также](http://php.net/manual/en/book.wincache.php));
* [[yii\caching\XCache]]: использует расширение PHP [XCache](http://xcache.lighttpd.net/);
* [[yii\caching\ZendDataCache]]: использует [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm).
* [[yii\caching\XCache]] _(deprecated)_: использует расширение PHP [XCache](http://xcache.lighttpd.net/);
* [[yii\caching\ZendDataCache]] _(deprecated)_: использует [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm).
> Tip: Вы можете использовать разные способы хранения кэша в одном приложении. Общая стратегия заключается в использовании памяти под хранение небольших часто используемых данных (например, статистические данные). Для больших и реже используемых данных (например, содержимое страницы) лучше использовать файлы или базу данных.

6
docs/guide-ru/concept-di-container.md

@ -151,7 +151,7 @@ $container->setDefinitions([
'class' => 'app\components\Response',
'format' => 'json'
],
'app\storage\DocumentsReader' => function () {
'app\storage\DocumentsReader' => function ($container, $params, $config) {
$fs = new app\storage\FileStorage('/var/tempfiles');
return new app\storage\DocumentsReader($fs);
}
@ -243,7 +243,7 @@ $reader = $container->get('app\storage\DocumentsReader');
Callback отвечает за разрешения зависимостей и внедряет их в соответствии с вновь создаваемыми объектами. Например,
```php
$container->set('Foo', function () {
$container->set('Foo', function ($container, $params, $config) {
$foo = new Foo(new Bar);
// ... дополнительная инициализация
return $foo;
@ -258,7 +258,7 @@ callable:
```php
class FooBuilder
{
public static function build()
public static function build($container, $params, $config)
{
$foo = new Foo(new Bar);
// ... дополнительная инициализация ...

4
docs/guide-ru/concept-events.md

@ -188,7 +188,7 @@ use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::trace(get_class($event->sender) . ' добавлен');
Yii::debug(get_class($event->sender) . ' добавлен');
});
```
@ -266,7 +266,7 @@ class Developer extends Component implements DanceEventInterface
```php
Event::on('app\interfaces\DanceEventInterface', DanceEventInterface::EVENT_DANCE, function ($event) {
Yii::trace(get_class($event->sender) . ' just danced'); // Оставит запись в журнале о том, что кто-то танцевал
Yii::debug(get_class($event->sender) . ' just danced'); // Оставит запись в журнале о том, что кто-то танцевал
});
```

8
docs/guide-ru/db-migrations.md

@ -266,7 +266,7 @@ yii migrate/create create_post_table --fields="author_id:integer:notNull:foreign
class m160328_040430_create_post_table extends Migration
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function up()
{
@ -314,7 +314,7 @@ class m160328_040430_create_post_table extends Migration
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function down()
{
@ -465,7 +465,7 @@ yii migrate/create create_junction_table_for_post_and_tag_tables
class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migration
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function up()
{
@ -512,7 +512,7 @@ class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migra
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function down()
{

12
docs/guide-ru/input-validation.md

@ -358,8 +358,8 @@ class MyForm extends Model
public function validateCountry($attribute, $params)
{
if (!in_array($this->$attribute, ['USA', 'Web'])) {
$this->addError($attribute, 'Страна должна быть либо "USA" или "Web".');
if (!in_array($this->$attribute, ['USA', 'Indonesia'])) {
$this->addError($attribute, 'Страна должна быть либо "USA" или "Indonesia".');
}
}
}
@ -384,7 +384,9 @@ class MyForm extends Model
Вы можете реализовать свою логику проверки путем переопределения метода
[[yii\validators\Validator::validateAttribute()]]. Если атрибут не прошел проверку, вызвать
[[yii\base\Model::addError()]],
чтобы сохранить сообщение об ошибке в модели, как это делают [встроенные валидаторы](#inline-validators). Например:
чтобы сохранить сообщение об ошибке в модели, как это делают [встроенные валидаторы](#inline-validators).
Валидация может быть помещена в отдельный класс [[components/validators/CountryValidator]]. В этом случае можно использовать метод [[yii\validators\Validator::addError()]] для того, чтобы добавить своё сообщение об ошибке в модель:
```php
namespace app\components;
@ -395,8 +397,8 @@ class CountryValidator extends Validator
{
public function validateAttribute($model, $attribute)
{
if (!in_array($model->$attribute, ['USA', 'Web'])) {
$this->addError($model, $attribute, 'Страна должна быть либо "USA" или "Web".');
if (!in_array($model->$attribute, ['USA', 'Indonesia'])) {
$this->addError($model, $attribute, 'Страна должна быть либо "{country1}" либо "{country2}".', ['country1' => 'USA', 'country2' => 'Indonesia']);
}
}
}

13
docs/guide-ru/intro-yii.md

@ -1,16 +1,15 @@
Что такое Yii?
==============
Yii – это высокопроизводительный компонентный PHP фреймворк, предназначенный для быстрой разработки современных веб
приложений. Слово Yii (произносится как `Йи` `[ji:]`) в китайском языке означает «простой и эволюционирующий». Также Yii
Yii – это высокопроизводительный компонентный PHP фреймворк, предназначенный для быстрой разработки современных веб-приложений. Слово Yii (произносится как `Йи` `[ji:]`) в китайском языке означает «простой и эволюционирующий». Также Yii
может расшифровываться как акроним **Yes It Is**!
Для каких задач больше всего подходит Yii?
------------------------------------------
Yii – это универсальный фреймворк и может быть задействован во всех типах веб приложений. Благодаря его компонентной
структуре и отличной поддержке кэширования, фреймворк особенно подходит для разработки таких крупных проектов как
Yii – это универсальный фреймворк и может быть задействован во всех типах веб-приложений. Благодаря его компонентной
структуре и отличной поддержке кэширования, фреймворк особенно подходит для разработки таких крупных проектов, как
порталы, форумы, CMS, магазины или RESTful-приложения.
@ -20,15 +19,15 @@ Yii – это универсальный фреймворк и может бы
Если вы уже знакомы с другими фреймворками, вам наверняка будет интересно сравнить их с Yii.
- Как и многие другие PHP фреймворки, для организации кода Yii использует архитектурный паттерн MVC (Model-View-Controller).
- Yii придерживается философии простого и элегантного кода не пытаясь усложнять дизайн только ради следования каким-либо
- Yii придерживается философии простого и элегантного кода, не пытаясь усложнять дизайн только ради следования каким-либо
шаблонам проектирования.
- Yii является full-stack фреймворком и включает в себя проверенные и хорошо зарекомендовавшие себя возможности, такие как
ActiveRecord для реляционных и NoSQL баз данных, поддержку REST API, многоуровневое кэширование и другие.
- Yii отлично расширяем. Вы можете настроить или заменить практически любую часть основного кода. Используя архитектуру расширений легко делиться кодом или использовать код сообщества.
- Yii отлично расширяем. Вы можете настроить или заменить практически любую часть основного кода. Используя архитектуру расширений, легко делиться кодом или использовать код сообщества.
- Одна из главных целей Yii – производительность.
Yii — не проект одного человека. Он поддерживается и развивается [сильной командой](http://www.yiiframework.com/team/) и большим сообществом разработчиков,
которые ей помогают. Авторы фреймворка следят за тенденциями веб разработки и развитием других проектов. Наиболее
которые ей помогают. Авторы фреймворка следят за тенденциями веб-разработки и развитием других проектов. Наиболее
подходящие возможности и лучшие практики регулярно внедряются в фреймворк в виде простых и элегантных интерфейсов.
Версии Yii

8
docs/guide-ru/output-data-providers.md

@ -258,7 +258,7 @@ class CsvDataProvider extends BaseDataProvider
/**
* @inheritdoc
* {@inheritdoc}
*/
public function init()
{
@ -269,7 +269,7 @@ class CsvDataProvider extends BaseDataProvider
}
/**
* @inheritdoc
* {@inheritdoc}
*/
protected function prepareModels()
{
@ -298,7 +298,7 @@ class CsvDataProvider extends BaseDataProvider
}
/**
* @inheritdoc
* {@inheritdoc}
*/
protected function prepareKeys($models)
{
@ -320,7 +320,7 @@ class CsvDataProvider extends BaseDataProvider
}
/**
* @inheritdoc
* {@inheritdoc}
*/
protected function prepareTotalCount()
{

20
docs/guide-ru/output-data-widgets.md

@ -222,6 +222,13 @@ echo GridView::widget([
'attribute' => 'birthday',
'format' => ['date', 'php:Y-m-d']
],
'created_at:datetime', // короткий вид записи формата
[
'label' => 'Education',
'attribute' => 'education',
'filter' => ['0' => 'Elementary', '1' => 'Secondary', '2' => 'Higher'],
'filterInputOptions' => ['prompt' => 'All educations', 'class' => 'form-control', 'id' => null]
],
],
]);
```
@ -235,6 +242,13 @@ echo GridView::widget([
Для конфигурации колонок данных также доступен короткий вид записи, который описан в API документации для [[yii\grid\GridView::columns|колонок]].
Используйте [[yii\grid\DataColumn::filter|filter]] и [[yii\grid\DataColumn::filterInputOptions|filterInputOptions]] для
настройки HTML кода фильтра.
По умолчанию заголовки колонок генерируются используя [[yii\data\Sort::link]]. Это можно изменить через свойство
[[yii\grid\Column::header]]. Для изменения заголовка нужно задать [[yii\grid\DataColumn::$label]], как в
примере выше. По умолчанию текст будет взят из модели данных. Подробное описание ищите в [[yii\grid\DataColumn::getHeaderCellLabel]].
#### ActionColumn
[[yii\grid\ActionColumn|ActionColumn]] отображает кнопки действия, такие как изменение или удаление для каждой строки.
@ -619,7 +633,7 @@ class UserView extends ActiveRecord
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public static function tableName()
{
@ -632,7 +646,7 @@ class UserView extends ActiveRecord
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function rules()
{
@ -642,7 +656,7 @@ class UserView extends ActiveRecord
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function attributeLabels()
{

21
docs/guide-ru/output-formatting.md

@ -36,9 +36,8 @@ Formatter может быть использован двумя различны
[[yii\i18n\Formatter::locale|locale]]. Если оно не было настроено, то в качестве локали будет использован
[[yii\base\Application::language|язык приложения]]. Подробнее смотрите в разделе «[интернационализация](tutorial-i18n.md)».
Компонент форматирования будет выбирать корректный формат для даты и чисел в соответствии с локалью, включая имена
месяцев и дней недели, переведённые на текущий язык. Форматирование дат также зависит от
[[yii\i18n\Formatter::timeZone|часового пояса]], которая
также будет из свойства [[yii\base\Application::timeZone|timeZone]] приложения, если она не была задана явно.
месяцев и дней недели, переведённые на текущий язык.
Форматирование дат также зависит от [[yii\i18n\Formatter::timeZone|часового пояса]], который будет взят из одноимённого свойства [[yii\base\Application::timeZone|timeZone]] приложения, если не был задан явно. В свою очередь [[yii\base\Application::timeZone|timeZone]] устанавливает / читает временную зону PHP.
Например, форматирование даты, вызванное с разной локалью, отобразит разные результаты::
@ -140,16 +139,14 @@ echo Yii::$app->formatter->asTime('2014-10-06 12:41:00'); // 14:41:00
echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00
```
Начиная с версии 2.0.1 стало возможно настраивать часовой пояс для предполагаемых timestamp, которые не включают в себя
часовой пояс, как во втором примере в коде выше. Вы можете задать [[yii\i18n\Formatter::defaultTimeZone]] часовым поясом,
который вы используете для хранения данных.
> Note: Поскольку часовые пояса являются субъектом ответственности правительств по всему миру и могут часто меняться,
> это значит, что вы, вероятно, не имеете самую свежую информацию в базе данных часовых поясов, установленной на вашем сервере.
> Вы можете обратиться к [ICU руководству](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data)
> для получения подробностей об обновлении базы данных часовых поясов.
> См. также: [Настройка вашего PHP окружения для интернационализации](tutorial-i18n.md#setup-environment).
Если [[yii\i18n\Formatter::timeZone|часовой пояс форматтера]] не задан явно, используется
[[yii\base\Application::timeZone|часовой пояс приложения]], то есть тот же, что задан в
конфигурации PHP.
> Note: Поскольку правила для часовых поясов принимаются различными правительствами и могут часто меняться,
> вероятно, информация в базе данных часовых поясов на вашем сервере не самая свежая.
> Как обновить базу вы можете узнать из [руководства ICU](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data).
> Смотрите также: [Настройка вашего PHP окружения для интернационализации](tutorial-i18n.md#setup-environment).
Форматирование чисел <span id="numbers"></span>
------------------

14
docs/guide-ru/rest-resources.md

@ -50,9 +50,9 @@ http://localhost/users?fields=id,email&expand=profile
[[yii\db\ActiveRecord::fields()]] возвращает только те атрибуты, которые были объявлены в схеме БД.
Вы можете переопределить `fields()` для того, чтобы добавить, удалить, переименовать или переобъявить поля. Значение,
возвращаемое `fields()`, должно быть массивом. Его ключи это имена полей, и значения могут быть либо именами
свойств/атрибутов, либо анонимными функциями, которые возвращают значение соответствующих полей. Если имя атрибута такое же,
как ключ массива вы можете опустить значение:
возвращаемое `fields()`, должно быть массивом. Его ключи — это названия полей. Значения могут быть либо именами
свойств/атрибутов, либо анонимными функциями, которые возвращают значение соответствующих свойств. Когда
название поля совпадает с именем аттрибута вы можете опустить ключ массива:
```php
// явное перечисление всех атрибутов лучше всего использовать когда вы хотите быть уверенным что изменение
@ -61,11 +61,11 @@ http://localhost/users?fields=id,email&expand=profile
public function fields()
{
return [
// название поля совпадает с названием атрибута
// название поля совпадает с именем атрибута
'id',
// имя поля "email", атрибут "email_address"
// название поля "email", атрибут "email_address"
'email' => 'email_address',
// имя поля "name", значение определяется callback-ом PHP
// название поля "name", значение определяется callback-ом PHP
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
@ -77,7 +77,7 @@ public function fields()
{
$fields = parent::fields();
// удаляем не безопасные поля
// удаляем небезопасные поля
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;

14
docs/guide-ru/runtime-logging.md

@ -14,7 +14,7 @@ Yii предоставляет мощную, гибко настраиваему
Запись сообщений лога осуществляется вызовом одного из следующих методов:
* [[Yii::trace()]]: записывает сообщения для отслеживания выполнения кода приложения. Используется, в основном, при разработке.
* [[Yii::debug()]]: записывает сообщения для отслеживания выполнения кода приложения. Используется, в основном, при разработке.
* [[Yii::info()]]: записывает сообщение, содержащее какую-либо полезную информацию.
* [[Yii::warning()]]: записывает *тревожное* сообщение при возникновении неожиданного события.
* [[Yii::error()]]: записывает критическую ошибку, на которую нужно, как можно скорее, обратить внимаение.
@ -22,7 +22,7 @@ Yii предоставляет мощную, гибко настраиваему
Эти методы позволяют записывать сообщения разных *уровней важности* и *категорий*. Они имеют одинаковое описание функции `function ($message, $category = 'application')`, где `$message` передает сообщение для записи, а `$category` - категорию сообщения. В следующем примере будет записано *trace* сообщение с категорией по умолчанию `application`:
```php
Yii::trace('start calculating average revenue');
Yii::debug('start calculating average revenue');
```
> Note: Сообщение может быть как строкой так и объектом или массивом. За корректную работу с содержимым сообщения отвечают [цели лога](#log-targets). По умолчанию, если сообщение не является строкой, оно будет приведено к строковому типу при помощи [[yii\helpers\VarDumper::export()]].
@ -30,7 +30,7 @@ Yii::trace('start calculating average revenue');
Для упрощения работы с сообщениями лога и их фильтрации, рекомендуется явно указывать подходящую категорию для каждого сообщения. Возможно использование иерархической системы именования категорий, что значительно упростит [целям лога](#log-targets) фильтрацию сообщений по категориям. Простым и эффективным способом именования категорий является использование магической PHP константы `__METHOD__`. Такой подход используется в ядре фреймворка Yii. Например,
```php
Yii::trace('начало вычисления среднего дохода', __METHOD__);
Yii::debug('начало вычисления среднего дохода', __METHOD__);
```
Константа `__METHOD__` вычисляется как имя метода (включая полное имя класса), в котором она использована. Например, её значение будет вычислено как `'app\controllers\RevenueController::calculate'`, если показанный выше код вызывается в соответствующем методе.
@ -49,7 +49,9 @@ Yii::trace('начало вычисления среднего дохода', __
return [
// Компонент "log" должен быть загружен на этапе предзагрузки
'bootstrap' => ['log'],
// Компонент "log" обрабатывает сообщения с меткой времени timestamp.
// Задайте временную зону для создания корректных меток времени.
'timeZone' => 'Europe/Moscow',
'components' => [
'log' => [
'targets' => [
@ -99,7 +101,7 @@ return [
* `error`: соответствует сообщениям, сохраненным методом [[Yii::error()]].
* `warning`: соответствует сообщениям, сохраненным методом [[Yii::warning()]].
* `info`: соответствует сообщениям, сохраненным методом [[Yii::info()]].
* `trace`: соответствует сообщениям, сохраненным методом [[Yii::trace()]].
* `trace`: соответствует сообщениям, сохраненным методом [[Yii::debug()]].
* `profile`: соответствует сообщениям, сохраненным методами [[Yii::beginProfile()]] и [[Yii::endProfile()]], подробнее о которых написано в подразделе [Профилирование производительности](#performance-profiling).
Если свойство [[yii\log\Target::levels|levels]] не задано, цель логов будет обрабатывать сообщения с *любым* уровнем важности.
@ -220,7 +222,7 @@ return [
]
```
Из-за того, что значения максимального количества сообщений для передачи и выгрузки по умолчанию достаточно велико, при вызове метода `Yii::trace()`, или любого другого метода логгирования, сообщение не появится сразу в файле или таблице базы данных. Такое поведение может стать проблемой, например, в консольных приложениях с большим временем исполнения. Для того, чтобы все сообщения логов сразу же попадали в лог, необходимо установить значения свойств [[yii\log\Dispatcher::flushInterval|flushInterval]] и [[yii\log\Target::exportInterval|exportInterval]] равными 1, например так:
Из-за того, что значения максимального количества сообщений для передачи и выгрузки по умолчанию достаточно велико, при вызове метода `Yii::debug()`, или любого другого метода логгирования, сообщение не появится сразу в файле или таблице базы данных. Такое поведение может стать проблемой, например, в консольных приложениях с большим временем исполнения. Для того, чтобы все сообщения логов сразу же попадали в лог, необходимо установить значения свойств [[yii\log\Dispatcher::flushInterval|flushInterval]] и [[yii\log\Target::exportInterval|exportInterval]] равными 1, например так:
```php
return [

72
docs/guide-ru/security-best-practices.md

@ -162,16 +162,72 @@ CSRF - это аббревиатура для межсайтинговой по
Если это так, то нужно запретить доступ ко всему, кроме директории `web`. Если на вашем хостинге такое невозможно,
рассмотрите возможность смены хостинга.
Как избежать отладочной информации и утилит в продуктиве
--------------------------------------------------------
Как избежать вывода информации отладки и инструментов в рабочем режиме
----------------------------------------------------------------------
В режиме отладки, Yii отображает довольно подробные ошибки, которые полезны во время разработки. Дело в том, что
подробные ошибки удобны для нападающего, так как могут раскрыть структуру базы данных, параметров конфигурации и части
вашего кода. Никогда не запускайте продуктивное приложение с `YII_DEBUG` установленным в `true` в вашем `index.php`.
вашего кода. Никогда не запускайте приложения в рабочем режиме с `YII_DEBUG` установленным в `true` в вашем `index.php`.
Вы никогда не должны включать Gii на продуктиве. Он может быть использован для получения информации о структуре
базы данных, кода и может позволить заменить файлы, генерируемые Gii автоматически.
Вы никогда не должны включать Gii или Debug панель в рабочем режиме. Это может быть использованно для получения информации о структуре базы данных, кода и может позволить заменить файлы, генерируемые Gii автоматически.
Также следует избегать включения на продуктиве панели отладки, если только в этом нет острой необходимости.
Она раскрывает всё приложение и детали конфигурации. Если вам все таки нужно запустить панель отладки на продуктиве,
проверьте дважды что доступ ограничен только вашими IP-адресами.
Следует избегать включения в рабочем режиме панели отладки, если только в этом нет острой необходимости.
Она раскрывает всё приложение и детали конфигурации. Если Вам всё-таки нужно запустить панель отладки в рабочем режиме,
проверьте дважды, что доступ ограничен только вашими IP-адресами.
Далее по теме читайте:
- <https://www.owasp.org/index.php/Exception_Handling>
- <https://www.owasp.org/index.php/Top_10_2007-Information_Leakage>
Использование безопасного подключения через TLS
-----------------------------------------------
Yii предоставляет функции, которые зависят от куки-файлов и/или сессий PHP. Они могут быть уязвимыми, если Ваше соединение
скомпрометированно. Риск снижается, если приложение использует безопасное соединение через TLS (часто называемое как [SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security)).
Инструкции по настройке смотрите в документации к Вашему веб-серверу. Вы также можете проверить примеры конфигураций
предоставленные проектом H5BP:
- [Nginx](https://github.com/h5bp/server-configs-nginx)
- [Apache](https://github.com/h5bp/server-configs-apache).
- [IIS](https://github.com/h5bp/server-configs-iis).
- [Lighttpd](https://github.com/h5bp/server-configs-lighttpd).
Безопасная конфигурация сервера
-------------------------------
Цель этого раздела - выявить риски, которые необходимо учитывать при создании
конфигурации сервера для обслуживания веб-сайта на основе Yii. Помимо перечисленных здесь пунктов есть и
другие параметры, связанные с безопасностью, которые необходимо учитывать, поэтому не рассматривайте этот раздел как завершенный.
### Как избежать атаки типа `Host`-header
Классы типа [[yii\web\UrlManager]] и [[yii\helpers\Url]] могут использовать [[yii\web\Request::getHostInfo()|запрашиваемое имя хоста]]] для генерации ссылок. Если веб-сервер настроен на обслуживание одного и того же сайта независимо от значения заголовка `Host`, эта информация может быть ненадежной и может быть подделана пользователем, отправляющим HTTP-запрос. В таких ситуациях Вы должны либо исправить конфигурацию своего веб-сервера, чтобы обслуживать сайт только для указанных имен узлов, либо явно установить или отфильтровать значение, установив свойство [[yii\web\Request::setHostInfo()|hostInfo]] компонента приложения `request`.
Дополнительные сведения о конфигурации сервера смотрите в документации Вашего веб-сервера:
- Apache 2: <http://httpd.apache.org/docs/trunk/vhosts/examples.html#defaultallports>
- Nginx: <https://www.nginx.com/resources/wiki/start/topics/examples/server_blocks/>
Если у Вас нет доступа к конфигурации сервера, Вы можете настроить фильтр [[yii\filters\HostControl]] уровня приложения для защиты от такого рода атак:
```php
// Файл конфигурации веб-приложения
return [
'as hostControl' => [
'class' => 'yii\filters\HostControl',
'allowedHosts' => [
'example.com',
'*.example.com',
],
'fallbackHostInfo' => 'https://example.com',
],
// ...
];
```
> Note: Вы всегда должны предпочесть конфигурацию веб-сервера для защиты от `атак заголовков узла` вместо использования фильтра.
[[yii\filters\HostControl]] следует использовать, только если настройка конфигурации сервера недоступна.

4
docs/guide-ru/start-installation.md

@ -176,7 +176,7 @@ DocumentRoot "path/to/basic/web"
PHP должен быть установлен как [FPM SAPI](http://php.net/manual/ru/install.fpm.php) для [Nginx](http://wiki.nginx.org/).
Используйте следующие параметры Nginx и не забудьте заменить `path/to/basic/web` на корректный путь к `basic/web` и
`mysite.local` на ваше имя хоста.
`mysite.test` на ваше имя хоста.
```
server {
@ -186,7 +186,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## слушаем ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

2
docs/guide-ru/structure-filters.md

@ -87,7 +87,7 @@ class ActionTimeFilter extends ActionFilter
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
Yii::debug("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}

7
docs/guide-ru/structure-modules.md

@ -171,6 +171,13 @@ yii <module_id>/<command>/<sub_command>
из идентификатора модуля, то контроллер и действие определяются исходя из свойства [[yii\base\Module::defaultRoute]],
которое по умолчанию равно `default`. Таким образом, маршрут `forum` соответствует контроллеру `default` модуля `forum`.
Добавление маршрутов модуля в URL manager необходимо производить до начала работы [[yii\web\UrlManager::parseRequest()]], что не
позволяет размещать код добавления правил модуля в `init()`, так как инициализация происходит уже после обработки маршрутов. Таким образом, добавление маршрутов необходимо осуществить в [предзагрузке
модуля](structure-extensions.md#bootstrapping-classes). Хорошей практикой, также, будет объединение всех правил модуля
при помощи [[\yii\web\GroupUrlRule]].
Если же вы используете модуль для [версионирования API](rest-versioning.md), добавление маршрутов необходимо
производить непосредственно в конфигурации `urlManager` приложения.
### Получение доступа к модулям <span id="accessing-modules"></span>

2
docs/guide-ru/tutorial-i18n.md

@ -269,7 +269,7 @@ for an argument: U_ARGUMENT_TYPE_MISMATCH":
```
Подробная документация о формах склонений для различных языков доступна на сайте
[unicode.org](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html).
[unicode.org](http://cldr.unicode.org/index/cldr-spec/plural-rules).
#### Вариации

206
docs/guide-ru/tutorial-yii-as-micro-framework.md

@ -0,0 +1,206 @@
# Использование Yii в качестве микро-framework'а
Yii можно легко использовать без функций включенных в базовый и расширенный шаблоны приложений. Другими словами Yii уже является микро-каркасом. Не требуется иметь структуру каталогов предоставляемую этими шаблонами при работе с Yii.
Это особенно удобно, когда Вам не нужен весь пред-установленный шаблонный код, такой как `Assets` или `Views`. Одним из таких случаев является создание JSON API. В следующих разделах будет показано, как это сделать.
## Установка Yii
Создайте каталог для файлов проекта и смените рабочий каталог на этот путь. В примерах используются команды Unix, но аналогичные команды существуют и в Windows.
```bash
mkdir micro-app
cd micro-app
```
> Note: Для продолжения требуется немного знаний о Composer. Если Вы еще не знаете, как использовать Composer, пожалуйста, найдите время, чтобы прочитать [Руководство Composer](https://getcomposer.org/doc/00-intro.md).
Создайте файл `composer.json` в каталоге `micro-app` с помощью Вашего любимого редактора и добавьте следующее:
```json
{
"require": {
"yiisoft/yii2": "~2.0.0"
},
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
}
]
}
```
Сохраните файл и запустите команду `comper install`. Это установит framework со всеми его зависимостями.
## Создание структуры проекта
После того как Вы установили фреймворк, пришло время создать [входную точку](structure-entry-scripts.md) приложения. Точка входа - это самый первый файл, который будет выполнен при попытке открыть приложение. По соображениям безопасности рекомендуется поместить файл точки входа в отдельный каталог и сделать каталог корнем веб директории.
Создайте каталог `web` и поместите в него файл `index.php` со следующим содержимым:
```php
<?php
// закомментируйте следующие две строки при использовании в рабочем режиме
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
$config = require __DIR__ . '/../config.php';
(new yii\web\Application($config))->run();
```
Также создайте файл с именем `config.php`, который будет содержать всю конфигурацию приложения:
```php
<?php
return [
'id' => 'micro-app',
// basePath (базовый путь) приложения будет каталог `micro-app`
'basePath' => __DIR__,
// это пространство имен где приложение будет искать все контроллеры
'controllerNamespace' => 'micro\controllers',
// установим псевдоним '@micro', чтобы включить автозагрузку классов из пространства имен 'micro'
'aliases' => [
'@micro' => __DIR__,
],
];
```
> Info: Несмотря на то, что конфигурация приложения может находиться в файле `index.php` рекомендуется
> содержать её в отдельном файле. Таким образом её можно также использовать и для консольного приложения, как показано ниже.
Теперь Ваш проект готов к наполнению кодом. Вам решать какую структуру каталогов проекта Вы выберите, пока Вы сможете видеть пространства имен.
## Создание первого контроллера
Создайте каталог `controllers` и добавьте туда файл `SiteController.php` который является контроллером по умолчанию, он будет обрабатывать запрос без пути.
```php
<?php
namespace micro\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionIndex()
{
return 'Hello World!';
}
}
```
Если Вы хотите использовать другое имя для этого контроллера, Вы можете изменить его настроив [[yii\base\Application::$defaultRoute]].
Например для `DefaultController` будет соответственно `'defaultRoute' => 'default/index'`.
На данный момент структура проекта должна выглядеть так:
```
micro-app/
├── composer.json
├── web/
└── index.php
└── controllers/
└── SiteController.php
```
Если Вы еще не настроили веб-сервер, Вы можете взглянуть на [примеры конфигурационных файлов веб-серверов](start-installation.md#Настройка-веб-сервера-).
Другой возможностью является использование команды `yii serve` которая будет использовать встроенный веб-сервер PHP. Вы можете запустить её из каталога `micro-app/` через:
vendor/bin/yii serve --docroot=./web
При открытии URL приложения в браузере, он теперь должен печатать "Hello World!" который был возвращен из `SiteController::actionIndex()`.
> Info: В нашем примере мы изменили пространство имен по умолчанию приложения с `app` на` micro`, чтобы продемонстрировать
> что Вы не привязаны к этому имени (в случае, если Вы считали, что это так), а затем скорректировали
> [[yii\base\Application::$controllerNamespace|controllers namespace]] и установили правильный псевдоним.
## Создание REST API
Чтобы продемонстрировать использование нашей "микроархитектуры" мы создадим простой REST API для сообщений.
Чтобы этот API обслуживал некоторые данные, нам нужна база данных. Добавим конфигурацию подключения базы данных
к конфигурации приложения:
```php
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'sqlite:@micro/database.sqlite',
],
],
```
> Info: Для простоты мы используем базу данных sqlite. Дополнительную информацию см. в [Руководство по базам данных](db-dao.md).
Затем мы создаем [миграции базы данных](db-migrations.md) для создания таблицы сообщений.
Убедитесь, что у Вас есть отдельный файл конфигурации, как описано выше, нам это нужно для того, чтобы запустить консольные команды описанные ниже.
Запуск следующих команд создаст файл миграции базы данных и применит миграцию к базе данных:
vendor/bin/yii migrate/create --appconfig=config.php create_post_table --fields="title:string,body:text"
vendor/bin/yii migrate/up --appconfig=config.php
Создайте каталог `models` и файл` Post.php` в этом каталоге. Это код модели:
```php
<?php
namespace micro\models;
use yii\db\ActiveRecord;
class Post extends ActiveRecord
{
public static function tableName()
{
return '{{posts}}';
}
}
```
> Info: Созданная модель представляет собой класс ActiveRecord, который представляет данные из таблицы `posts`.
> Для получения дополнительной информации обратитесь к [active record руководству](db-active-record.md).
Чтобы обслуживать сообщения в нашем API, добавьте `PostController` в` controllers`:
```php
<?php
namespace micro\controllers;
use yii\rest\ActiveController;
class PostController extends ActiveController
{
public $modelClass = 'micro\models\Post';
public function behaviors()
{
// удаляем rateLimiter, требуется для аутентификации пользователя
$behaviors = parent::behaviors();
unset($behaviors['rateLimiter']);
return $behaviors;
}
}
```
На этом этапе наш API предоставляет следующие URL-адреса:
- `/index.php?r=post` - список всех сообщений
- `/index.php?r=post/view&id=1` - просмотр сообщения с ID 1
- `/index.php?r=post/create` - создание сообщения
- `/index.php?r=post/update&id=1` - обновление сообщения with ID 1
- `/index.php?r=post/delete&id=1` - удаление сообщения with ID 1
Начиная с этого момента Вы можете посмотреть следующие руководства для дальнейшего развития своего приложения:
- API в настоящий момент понимает только данные urlencoded как входные данные, чтобы сделать его настоящим JSON API, Вам
необходимо настроить [[yii\web\JsonParser]].
- Чтобы сделать URL более дружественным, вам необходимо настроить маршрутизацию.
См. [Руководство по маршрутизации REST](rest-routing.md) о том, как это сделать.
- Дополнительную информацию см. в разделе [Взгляд в будущее](start-looking-ahead.md).

4
docs/guide-uk/start-installation.md

@ -193,7 +193,7 @@ DocumentRoot "path/to/basic/web"
Для використання [Nginx](http://wiki.nginx.org/) вам потрібно встановити PHP як [FPM SAPI](http://php.net/install.fpm).
Використовуйте наступні параметри Nginx, замінивши `path/to/basic/web` на коректний шлях до
`basic/web`, а `mysite.local` на актуальний домен.
`basic/web`, а `mysite.test` на актуальний домен.
```
server {
@ -203,7 +203,7 @@ server {
listen 80; ## "слухаємо порт" для ipv4
#listen [::]:80 default_server ipv6only=on; ## "слухаємо порт" для ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

4
docs/guide-vi/start-installation.md

@ -163,7 +163,7 @@ DocumentRoot "path/to/basic/web"
Để sử dụng [Nginx](http://wiki.nginx.org/), bạn cần phải cài đặt [FPM SAPI](http://php.net/install.fpm).
Bạn có thể cấu hình Nginx như sau, thay thế đường dẫn `path/to/basic/web` với đường dẫn thực tế ở
`basic/web``mysite.local` thay thế bằng tên máy chủ thực tế để cung cấp dịch vụ.
`basic/web``mysite.test` thay thế bằng tên máy chủ thực tế để cung cấp dịch vụ.
```
server {
@ -173,7 +173,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

4
docs/guide-zh-CN/caching-data.md

@ -74,8 +74,8 @@ Yii 支持一系列缓存存储器,概况如下:
* [[yii\caching\MemCache]]:使用 PHP [memcache](http://php.net/manual/en/book.memcache.php) 和 [memcached](http://php.net/manual/en/book.memcached.php) 扩展。这个选项被看作分布式应用环境中(例如:多台服务器,有负载均衡等)最快的缓存方案。
* [[yii\redis\Cache]]:实现了一个基于 [Redis](http://redis.io/) 键值对存储器的缓存组件(需要 redis 2.6.12 及以上版本的支持 )。
* [[yii\caching\WinCache]]:使用 PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)([另可参考](http://php.net/manual/en/book.wincache.php))扩展.
* [[yii\caching\XCache]]:使用 PHP [XCache](http://xcache.lighttpd.net/)扩展。
* [[yii\caching\ZendDataCache]]:使用 [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) 作为底层缓存媒介。
* [[yii\caching\XCache]] _(deprecated)_:使用 PHP [XCache](http://xcache.lighttpd.net/)扩展。
* [[yii\caching\ZendDataCache]] _(deprecated)_:使用 [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) 作为底层缓存媒介。
> Tip: 你可以在同一个应用程序中使用不同的缓存存储器。一个常见的策略是使用基于内存的缓存存储器存储小而常用的数据(例如:统计数据),使用基于文件或数据库的缓存存储器存储大而不太常用的数据(例如:网页内容)。

2
docs/guide-zh-CN/concept-di-container.md

@ -69,7 +69,7 @@ $container->get('Foo', [], [
这种情况下,容器将使用一个注册过的 PHP 回调创建一个类的新实例。回调负责解决依赖并将其恰当地注入新创建的对象。例如:
```php
$container->set('Foo', function () {
$container->set('Foo', function ($container, $params, $config) {
return new Foo(new Bar);
});

2
docs/guide-zh-CN/concept-events.md

@ -182,7 +182,7 @@ use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::trace(get_class($event->sender) . ' is inserted');
Yii::debug(get_class($event->sender) . ' is inserted');
});
```

4
docs/guide-zh-CN/start-installation.md

@ -132,7 +132,7 @@ DocumentRoot "path/to/basic/web"
### 推荐使用的 Nginx 配置 <span id="recommended-nginx-configuration"></span>
为了使用 [Nginx](http://wiki.nginx.org/),你应该已经将 PHP 安装为 [FPM SAPI](http://php.net/install.fpm) 了。使用如下 Nginx 配置,将 `path/to/basic/web` 替换为实际的 `basic/web` 目录,`mysite.local` 替换为实际的主机名以提供服务。
为了使用 [Nginx](http://wiki.nginx.org/),你应该已经将 PHP 安装为 [FPM SAPI](http://php.net/install.fpm) 了。使用如下 Nginx 配置,将 `path/to/basic/web` 替换为实际的 `basic/web` 目录,`mysite.test` 替换为实际的主机名以提供服务。
```
server {
@ -142,7 +142,7 @@ server {
listen 80; ## 监听 ipv4 上的 80 端口
#listen [::]:80 default_server ipv6only=on; ## 监听 ipv6 上的 80 端口
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

2
docs/guide-zh-CN/structure-filters.md

@ -84,7 +84,7 @@ class ActionTimeFilter extends ActionFilter
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
Yii::debug("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}

1
docs/guide/README.md

@ -18,6 +18,7 @@ Introduction
Getting Started
---------------
* [What do you need to know](start-prerequisites.md)
* [Installing Yii](start-installation.md)
* [Running Applications](start-workflow.md)
* [Saying Hello](start-hello.md)

4
docs/guide/caching-data.md

@ -125,8 +125,8 @@ Yii supports a wide range of cache storage. The following is a summary:
(redis version 2.6.12 or higher is required).
* [[yii\caching\WinCache]]: uses PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)
([see also](http://php.net/manual/en/book.wincache.php)) extension.
* [[yii\caching\XCache]]: uses PHP [XCache](http://xcache.lighttpd.net/) extension.
* [[yii\caching\ZendDataCache]]: uses
* [[yii\caching\XCache]] _(deprecated)_: uses PHP [XCache](http://xcache.lighttpd.net/) extension.
* [[yii\caching\ZendDataCache]] _(deprecated)_: uses
[Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm)
as the underlying caching medium.

3
docs/guide/caching-fragment.md

@ -174,3 +174,6 @@ if ($this->beginCache($id1)) {
The [[yii\base\View::renderDynamic()|renderDynamic()]] method takes a piece of PHP code as its parameter.
The return value of the PHP code is treated as the dynamic content. The same PHP code will be executed
for every request, no matter the enclosing fragment is being served from cached or not.
> Note: since version 2.0.14 a dynamic content API is exposed via the [[yii\base\DynamicContentAwareInterface]] interface and its [[yii\base\DynamicContentAwareTrait]] trait.
As an example, you may refer to the [[yii\widgets\FragmentCache]] class.

6
docs/guide/concept-di-container.md

@ -117,7 +117,7 @@ The callable is responsible to resolve the dependencies and inject them appropri
created objects. For example,
```php
$container->set('Foo', function () {
$container->set('Foo', function ($container, $params, $config) {
$foo = new Foo(new Bar);
// ... other initializations ...
return $foo;
@ -131,7 +131,7 @@ To hide the complex logic for building a new object, you may use a static class
```php
class FooBuilder
{
public static function build()
public static function build($container, $params, $config)
{
$foo = new Foo(new Bar);
// ... other initializations ...
@ -421,7 +421,7 @@ $container->setDefinitions([
'class' => 'app\components\Response',
'format' => 'json'
],
'app\storage\DocumentsReader' => function () {
'app\storage\DocumentsReader' => function ($container, $params, $config) {
$fs = new app\storage\FileStorage('/var/tempfiles');
return new app\storage\DocumentsReader($fs);
}

77
docs/guide/concept-events.md

@ -42,7 +42,7 @@ Attaching Event Handlers <span id="attaching-event-handlers"></span>
You can attach a handler to an event by calling the [[yii\base\Component::on()]] method. For example:
```php
$foo = new Foo;
$foo = new Foo();
// this handler is a global function
$foo->on(Foo::EVENT_HELLO, 'function_name');
@ -212,7 +212,7 @@ use yii\base\Event;
use yii\db\ActiveRecord;
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
Yii::trace(get_class($event->sender) . ' is inserted');
Yii::debug(get_class($event->sender) . ' is inserted');
});
```
@ -296,7 +296,7 @@ pass the interface class name as the first argument:
```php
Event::on('app\interfaces\DanceEventInterface', DanceEventInterface::EVENT_DANCE, function ($event) {
Yii::trace(get_class($event->sender) . ' just danced'); // Will log that Dog or Developer danced
Yii::debug(get_class($event->sender) . ' just danced'); // Will log that Dog or Developer danced
});
```
@ -355,3 +355,74 @@ done through the Singleton (e.g. the application instance).
However, because the namespace of the global events is shared by all parties, you should name the global events
wisely, such as introducing some sort of namespace (e.g. "frontend.mail.sent", "backend.mail.sent").
Wildcard Events <span id="wildcard-events"></span>
---------------
Since 2.0.14 you can setup event handler for multiple events matching wildcard pattern.
For example:
```php
use Yii;
$foo = new Foo();
$foo->on('foo.event.*', function ($event) {
// triggered for any event, which name starts on 'foo.event.'
Yii::debug('trigger event: ' . $event->name);
});
```
Wildcard patterns can be used for class-level events as well. For example:
```php
use yii\base\Event;
use Yii;
Event::on('app\models\*', 'before*', function ($event) {
// triggered for any class in namespace 'app\models' for any event, which name starts on 'before'
Yii::debug('trigger event: ' . $event->name . ' for class: ' . get_class($event->sender));
});
```
This allows you catching all application events by single handler using following code:
```php
use yii\base\Event;
use Yii;
Event::on('*', '*', function ($event) {
// triggered for any event at any class
Yii::debug('trigger event: ' . $event->name);
});
```
> Note: usage wildcards for event handlers setup may reduce the application performance.
It is better to be avoided if possible.
In order to detach event handler specified by wildcard pattern, you should repeat same pattern at
[[yii\base\Component::off()]] or [[yii\base\Event::off()]] invocation. Keep in mind that passing wildcard
during detaching of event handler will detach ony the handler specified for this wildcard, while handlers
attached for regular event names will remain even if they match the pattern. For example:
```php
use Yii;
$foo = new Foo();
// attach regular handler
$foo->on('event.hello', function ($event) {
echo 'direct-handler'
});
// attach wildcard handler
$foo->on('*', function ($event) {
echo 'wildcard-handler'
});
// detach wildcard handler only!
$foo->off('*');
$foo->trigger('event.hello'); // outputs: 'direct-handler'
```

28
docs/guide/db-active-record.md

@ -472,7 +472,7 @@ $customer->loadDefaultValues();
### Attributes Typecasting <span id="attributes-typecasting"></span>
Being populated by query results [[yii\db\ActiveRecord]] performs automatic typecast for its attribute values, using
Being populated by query results, [[yii\db\ActiveRecord]] performs automatic typecast for its attribute values, using
information from [database table schema](db-dao.md#database-schema). This allows data retrieved from table column
declared as integer to be populated in ActiveRecord instance with PHP integer, boolean with boolean and so on.
However, typecasting mechanism has several limitations:
@ -491,6 +491,32 @@ converted during saving process.
> Tip: you may use [[yii\behaviors\AttributeTypecastBehavior]] to facilitate attribute values typecasting
on ActiveRecord validation or saving.
Since 2.0.14, Yii ActiveRecord supports complex data types, such as JSON or multidimensional arrays.
#### JSON in MySQL and PostgreSQL
After data population, the value from JSON column will be automatically decoded from JSON according to standard JSON
decoding rules.
To save attribute value to a JSON column, ActiveRecord will automatically create a [[yii\db\JsonExpression|JsonExpression]] object
that will be encoded to a JSON string on [QueryBuilder](db-query-builder.md) level.
#### Arrays in PostgreSQL
After data population, the value from Array column will be automatically decoded from PgSQL notation to an [[yii\db\ArrayExpression|ArrayExpression]]
object. It implements PHP `ArrayAccess` interface, so you can use it as an array, or call `->getValue()` to get the array itself.
To save attribute value to an array column, ActiveRecord will automatically create an [[yii\db\ArrayExpression|ArrayExpression]] object
that will be encoded by [QueryBuilder](db-query-builder.md) to an PgSQL string representation of array.
You can also use conditions for JSON columns:
```php
$query->andWhere(['=', 'json', new ArrayExpression(['foo' => 'bar'])
```
To learn more about expressions building system read the [Query Builder – Adding custom Conditions and Expressions](db-query-builder.md#adding-custom-conditions-and-expressions)
article.
### Updating Multiple Rows <span id="updating-multiple-rows"></span>

35
docs/guide/db-migrations.md

@ -38,6 +38,13 @@ command `yii help migrate`.
> Tip: migrations could affect not only database schema but adjust existing data to fit new schema, create RBAC
hierarchy or clean up cache.
> Note: When manipulating data using a migration you may find that using your [Active Record](db-active-record.md) classes
> for this might be useful because some of the logic is already implemented there. Keep in mind however, that in contrast
> to code written in the migrations, who's nature is to stay constant forever, application logic is subject to change.
> So when using Active Record in migration code, changes to the logic in the Active Record layer may accidentally break
> existing migrations. For this reason migration code should be kept independent from other application logic such
> as Active Record classes.
## Creating Migrations <span id="creating-migrations"></span>
@ -204,7 +211,7 @@ generates
class m150811_220037_create_post_table extends Migration
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function up()
{
@ -214,7 +221,7 @@ class m150811_220037_create_post_table extends Migration
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function down()
{
@ -238,7 +245,7 @@ generates
class m150811_220037_create_post_table extends Migration
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function up()
{
@ -250,7 +257,7 @@ class m150811_220037_create_post_table extends Migration
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function down()
{
@ -275,7 +282,7 @@ generates
class m150811_220037_create_post_table extends Migration
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function up()
{
@ -287,7 +294,7 @@ class m150811_220037_create_post_table extends Migration
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function down()
{
@ -320,7 +327,7 @@ generates
class m160328_040430_create_post_table extends Migration
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function up()
{
@ -368,7 +375,7 @@ class m160328_040430_create_post_table extends Migration
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function down()
{
@ -533,7 +540,7 @@ generates
class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migration
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public function up()
{
@ -580,7 +587,7 @@ class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migra
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function down()
{
@ -716,14 +723,6 @@ Below is the list of all these database accessing methods:
> ```
> Note: When manipulating data using a migration you may find that using your [Active Record](db-active-record.md) classes
> for this might be useful because some of the logic is already implemented there. Keep in mind however, that in contrast
> to code written in the migrations, who's nature is to stay constant forever, application logic is subject to change.
> So when using Active Record in migration code, changes to the logic in the Active Record layer may accidentally break
> existing migrations. For this reason migration code should be kept independent from other application logic such
> as Active Record classes.
## Applying Migrations <span id="applying-migrations"></span>
To upgrade a database to its latest structure, you should apply all available new migrations using the following command:

209
docs/guide/db-query-builder.md

@ -160,12 +160,12 @@ are in the ["Quoting Tables" section of the "Database Access Objects" guide](gui
### [[yii\db\Query::where()|where()]] <span id="where"></span>
The [[yii\db\Query::where()|where()]] method specifies the `WHERE` fragment of a SQL query. You can use one of
the three formats to specify a `WHERE` condition:
the four formats to specify a `WHERE` condition:
- string format, e.g., `'status=1'`
- hash format, e.g. `['status' => 1, 'type' => 2]`
- operator format, e.g. `['like', 'name', 'test']`
- object format, e.g. `new LikeCondition('name', 'LIKE', 'test')`
#### String Format <span id="string-format"></span>
@ -255,6 +255,9 @@ the operator can be one of the following:
- `between`: operand 1 should be the column name, and operand 2 and 3 should be the
starting and ending values of the range that the column is in.
For example, `['between', 'id', 1, 10]` will generate `id BETWEEN 1 AND 10`.
In case you need to build a condition where value is between two columns (like `11 BETWEEN min_id AND max_id`),
you should use [[yii\db\conditions\BetweenColumnsCondition|BetweenColumnsCondition]].
See [Conditions – Object Format](#object-format) chapter to learn more about object definition of conditions.
- `not between`: similar to `between` except the `BETWEEN` is replaced with `NOT BETWEEN`
in the generated condition.
@ -306,6 +309,41 @@ the operator can be one of the following:
Using the Operator Format, Yii internally uses parameter binding so in contrast to the [string format](#string-format), here
you do not have to add parameters manually.
#### Object Format <span id="object-format"></span>
Object Form is available since 2.0.14 and is both most powerful and most complex way to define conditions.
You need to follow it either if you want to build your own abstraction over query builder or if you want to implement
your own complex conditions.
Instances of condition classes are immutable. Their only purpose is to store condition data and provide getters
for condition builders. Condition builder is a class that holds the logic that transforms data
stored in condition into the SQL expression.
Internally the formats described above are implicitly converted to object format prior to building raw SQL,
so it is possible to combine formats in a single condition:
```php
$query->andWhere(new OrCondition([
new InCondition('type', 'in', $types),
['like', 'name', '%good%'],
'disabled=false'
]))
```
Conversion from operator format into object format is performed according to
[[yii\db\QueryBuilder::conditionClasses|QueryBuilder::conditionClasses]] property, that maps operators names
to representative class names:
- `AND`, `OR` -> `yii\db\conditions\ConjunctionCondition`
- `NOT` -> `yii\db\conditions\NotCondition`
- `IN`, `NOT IN` -> `yii\db\conditions\InCondition`
- `BETWEEN`, `NOT BETWEEN` -> `yii\db\conditions\BetweenCondition`
And so on.
Using the object format makes it possible to create your own conditions or to change the way default ones are built.
See [Creating Custom Conditions and Expressions](#creating-custom-conditions-and-expressions) chapter to learn more.
#### Appending Conditions <span id="appending-conditions"></span>
@ -758,3 +796,170 @@ $unbufferedDb->close();
```
> Note: unbuffered query uses less memory on the PHP-side, but can increase the load on the MySQL server. It is recommended to design your own code with your production practice for extra massive data, [for example, divide the range for integer keys, loop them with Unbuffered Queries](https://github.com/yiisoft/yii2/issues/8420#issuecomment-296109257).
### Adding custom Conditions and Expressions <span id="adding-custom-conditions-and-expressions"></span>
As it was mentioned in [Conditions – Object Format](#object-format) chapter, is is possible to create custom condition
classes. For example, let's create a condition that will check that specific columns are less than some value.
Using the operator format, it would look like the following:
```php
[
'and',
'>', 'posts', $minLimit,
'>', 'comments', $minLimit,
'>', 'reactions', $minLimit,
'>', 'subscriptions', $minLimit
]
```
When such condition applied once, it is fine. In case it is used multiple times in a single query it can
be optimized a lot. Let's create a custom condition object to demonstrate it.
Yii has a [[yii\db\conditions\ConditionInterface|ConditionInterface]], that must be used to mark classes, that represent
a condition. It requires `fromArrayDefinition()` method implementation, in order to make possible to create condition
from array format. In case you don't need it, you can implement this method with exception throwing.
Since we create our custom condition class, we can build API that suits our task the most.
```php
namespace app\db\conditions;
class AllGreaterCondition implements \yii\db\conditions\ConditionInterface
{
private $columns;
private $value;
/**
* @param string[] $columns Array of columns that must be greater, than $value
* @param mixed $value the value to compare each $column against.
*/
public function __construct(array $columns, $value)
{
$this->columns = $columns;
$this->value = $value;
}
public static function fromArrayDefinition($operator, $operands)
{
throw new InvalidArgumentException('Not implemented yet, but we will do it later');
}
public function getColumns() { return $this->columns; }
public function getValue() { return $this->vaule; }
}
```
So we can create a condition object:
```php
$conditon = new AllGreaterCondition(['col1', 'col2'], 42);
```
But `QueryBuilder` still does not know, to to make an SQL condition out of this object.
Now we need to create a builder for this condition. It must implement [[yii\db\ExpressionBuilderInterface]]
that requires us to implement a `build()` method.
```php
namespace app\db\conditions;
class AllGreaterConditionBuilder implements \yii\db\ExpressionBuilderInterface
{
use \yii\db\Condition\ExpressionBuilderTrait; // Contains constructor and `queryBuilder` property.
/**
* @param AllGreaterCondition $condition the condition to be built
* @param array $params the binding parameters.
*/
public function build(ConditionInterface $condition, &$params)
{
$value = $condition->getValue();
$conditions = [];
foreach ($condition->getColumns() as $column) {
$conditions[] = new SimpleCondition($column, '>', $value);
}
return $this->queryBuider->buildCondition(new AndCondition($conditions), $params);
}
}
```
Then simple let [[yii\db\QueryBuilder|QueryBuilder]] know about our new condition – add a mapping for it to
the `expressionBuilders` array. It could be done right from the application configuration:
```php
'db' => [
'class' => 'yii\db\mysql\Connection',
// ...
'queryBuilder' => [
'expressionBuilders' => [
'app\db\conditions\AllGreaterCondition' => 'app\db\conditions\AllGreaterConditionBuilder',
],
],
],
```
Now we can use our condition in `where()`:
```php
$query->andWhere(new AllGreaterCondition(['posts', 'comments', 'reactions', 'subscriptions'], $minValue));
```
If we want to make it possible to create our custom condition using operator format, we should declare it in
[[yii\db\QueryBuilder::conditionClasses|QueryBuilder::conditionClasses]]:
```php
'db' => [
'class' => 'yii\db\mysql\Connection',
// ...
'queryBuilder' => [
'expressionBuilders' => [
'app\db\conditions\AllGreaterCondition' => 'app\db\conditions\AllGreaterConditionBuilder',
],
'conditionClasses' => [
'ALL>' => 'app\db\conditions\AllGreaterCondition',
],
],
],
```
And create a real implementation of `AllGreaterCondition::fromArrayDefinition()` method
in `app\db\conditions\AllGreaterCondition`:
```php
namespace app\db\conditions;
class AllGreaterCondition implements \yii\db\conditions\ConditionInterface
{
// ... see the implementation above
public static function fromArrayDefinition($operator, $operands)
{
return new static($operands[0], $operands[1]);
}
}
```
After that, we can create our custom condition using shorter operator format:
```php
$query->andWhere(['ALL>', ['posts', 'comments', 'reactions', 'subscriptions'], $minValue]);
```
You might notice, that there was two concepts used: Expressions and Conditions. There is a [[yii\db\ExpressionInterface]]
that should be used to mark objects, that require an Expression Builder class, that implements
[[yii\db\ExpressionBuilderInterface]] to be built. Also there is a [[yii\db\condition\ConditionInterface]], that extends
[[yii\db\ExpressionInterface|ExpressionInterface]] and should be used to objects, that can be created from array definition
as it was shown above, but require builder as well.
To summarise:
- Expression – is a Data Transfer Object (DTO) for a dataset, that can be somehow compiled to some SQL
statement (an operator, string, array, JSON, etc).
- Condition – is an Expression superset, that aggregates multiple Expressions (or scalar values) that can be compiled
to a single SQL condition.
You can create your own classes that implement [[yii\db\ExpressionInterface|ExpressionInterface]] to hide the complexity
of transforming data to SQL statements. You will learn more about other examples of Expressions in the
[next article](db-active-record.md);

13
docs/guide/input-validation.md

@ -221,7 +221,7 @@ values are stored in an attribute:
```php
['age', 'trim'],
['age', 'default', 'value' => null],
['age', 'integer', 'integerOnly' => true, 'min' => 0],
['age', 'integer', 'min' => 0],
['age', 'filter', 'filter' => 'intval', 'skipOnEmpty' => true],
```
@ -387,8 +387,8 @@ class MyForm extends Model
public function validateCountry($attribute, $params, $validator)
{
if (!in_array($this->$attribute, ['USA', 'Web'])) {
$this->addError($attribute, 'The country must be either "USA" or "Web".');
if (!in_array($this->$attribute, ['USA', 'Indonesia'])) {
$this->addError($attribute, 'The country must be either "USA" or "Indonesia".');
}
}
}
@ -422,7 +422,8 @@ fails the validation, call [[yii\base\Model::addError()]] to save the error mess
with [inline validators](#inline-validators).
For example the inline validator above could be moved into new [[components/validators/CountryValidator]] class.
For example, the inline validator above could be moved into new [[components/validators/CountryValidator]] class.
In this case we can use [[yii\validators\Validator::addError()]] to set customized message for the model.
```php
namespace app\components;
@ -433,8 +434,8 @@ class CountryValidator extends Validator
{
public function validateAttribute($model, $attribute)
{
if (!in_array($model->$attribute, ['USA', 'Web'])) {
$this->addError($model, $attribute, 'The country must be either "USA" or "Web".');
if (!in_array($model->$attribute, ['USA', 'Indonesia'])) {
$this->addError($model, $attribute, 'The country must be either "{country1}" or "{country2}".', ['country1' => 'USA', 'country2' => 'Indonesia']);
}
}
}

8
docs/guide/output-data-providers.md

@ -262,7 +262,7 @@ class CsvDataProvider extends BaseDataProvider
/**
* @inheritdoc
* {@inheritdoc}
*/
public function init()
{
@ -273,7 +273,7 @@ class CsvDataProvider extends BaseDataProvider
}
/**
* @inheritdoc
* {@inheritdoc}
*/
protected function prepareModels()
{
@ -302,7 +302,7 @@ class CsvDataProvider extends BaseDataProvider
}
/**
* @inheritdoc
* {@inheritdoc}
*/
protected function prepareKeys($models)
{
@ -324,7 +324,7 @@ class CsvDataProvider extends BaseDataProvider
}
/**
* @inheritdoc
* {@inheritdoc}
*/
protected function prepareTotalCount()
{

19
docs/guide/output-data-widgets.md

@ -243,6 +243,13 @@ echo GridView::widget([
'attribute' => 'birthday',
'format' => ['date', 'php:Y-m-d']
],
'created_at:datetime', // shortcut format
[
'label' => 'Education',
'attribute' => 'education',
'filter' => ['0' => 'Elementary', '1' => 'Secondary', '2' => 'Higher'],
'filterInputOptions' => ['prompt' => 'All educations', 'class' => 'form-control', 'id' => null]
],
],
]);
```
@ -256,6 +263,12 @@ For a list of available formatters see the [section about Data Formatting](outpu
For configuring data columns there is also a shortcut format which is described in the
API documentation for [[yii\grid\GridView::columns|columns]].
Use [[yii\grid\DataColumn::filter|filter]] and [[yii\grid\DataColumn::filterInputOptions|filterInputOptions]] to
control HTML for the filter input.
By default, column headers are rendered by [[yii\data\Sort::link]]. It could be adjusted using [[yii\grid\Column::header]].
To change header text you should set [[yii\grid\DataColumn::$label]] like in the example above.
By default the label will be populated from data model. For more details see [[yii\grid\DataColumn::getHeaderCellLabel]].
#### Action column <span id="action-column"></span>
@ -643,7 +656,7 @@ class UserView extends ActiveRecord
{
/**
* @inheritdoc
* {@inheritdoc}
*/
public static function tableName()
{
@ -656,7 +669,7 @@ class UserView extends ActiveRecord
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function rules()
{
@ -666,7 +679,7 @@ class UserView extends ActiveRecord
}
/**
* @inheritdoc
* {@inheritdoc}
*/
public function attributeLabels()
{

5
docs/guide/output-formatting.md

@ -144,13 +144,16 @@ echo Yii::$app->formatter->asTime('2014-10-06 12:41:00'); // 14:41:00
echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00
```
If the [[yii\i18n\Formatter::timeZone|time zone]] is not set explicitly on the formatter component, the
[[yii\base\Application::timeZone|time zone configured in the application]] is used, which is the same time zone
as set in the PHP configuration.
> Note: As time zones are subject to rules made by the governments around the world and may change frequently, it is
> likely that you do not have the latest information in the time zone database installed on your system.
> You may refer to the [ICU manual](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data)
> for details on updating the time zone database. Please also read
> [Setting up your PHP environment for internationalization](tutorial-i18n.md#setup-environment).
## Formatting Numbers <span id="numbers"></span>
The formatter supports the following output formats that are related with numbers:

13
docs/guide/runtime-logging.md

@ -18,7 +18,7 @@ In this section, we will mainly describe the first two steps.
Recording log messages is as simple as calling one of the following logging methods:
* [[Yii::trace()]]: record a message to trace how a piece of code runs. This is mainly for development use.
* [[Yii::debug()]]: record a message to trace how a piece of code runs. This is mainly for development use.
* [[Yii::info()]]: record a message that conveys some useful information.
* [[Yii::warning()]]: record a warning message that indicates something unexpected has happened.
* [[Yii::error()]]: record a fatal error that should be investigated as soon as possible.
@ -29,7 +29,7 @@ the log message to be recorded, while `$category` is the category of the log mes
example records a trace message under the default category `application`:
```php
Yii::trace('start calculating average revenue');
Yii::debug('start calculating average revenue');
```
> Info: Log messages can be strings as well as complex data, such as arrays or objects. It is the responsibility
@ -43,7 +43,7 @@ is to use the PHP magic constant `__METHOD__` for the category names. This is al
Yii framework code. For example,
```php
Yii::trace('start calculating average revenue', __METHOD__);
Yii::debug('start calculating average revenue', __METHOD__);
```
The `__METHOD__` constant evaluates as the name of the method (prefixed with the fully qualified class name) where
@ -70,7 +70,8 @@ in the application configuration, like the following:
return [
// the "log" component must be loaded during bootstrapping time
'bootstrap' => ['log'],
// the "log" component process messages with timestamp. Set PHP timezone to create correct timestamp
'timeZone' => 'America/Los_Angeles',
'components' => [
'log' => [
'targets' => [
@ -124,7 +125,7 @@ The [[yii\log\Target::levels|levels]] property takes an array consisting of one
* `error`: corresponding to messages logged by [[Yii::error()]].
* `warning`: corresponding to messages logged by [[Yii::warning()]].
* `info`: corresponding to messages logged by [[Yii::info()]].
* `trace`: corresponding to messages logged by [[Yii::trace()]].
* `trace`: corresponding to messages logged by [[Yii::debug()]].
* `profile`: corresponding to messages logged by [[Yii::beginProfile()]] and [[Yii::endProfile()]], which will
be explained in more details in the [Profiling](#performance-profiling) subsection.
@ -276,7 +277,7 @@ property of individual [log targets](#log-targets), like the following,
]
```
Because of the flushing and exporting level setting, by default when you call `Yii::trace()` or any other logging
Because of the flushing and exporting level setting, by default when you call `Yii::debug()` or any other logging
method, you will NOT see the log message immediately in the log targets. This could be a problem for some long-running
console applications. To make each log message appear immediately in the log targets, you should set both
[[yii\log\Dispatcher::flushInterval|flushInterval]] and [[yii\log\Target::exportInterval|exportInterval]] to be 1,

2
docs/guide/runtime-requests.md

@ -186,7 +186,7 @@ In case your proxies are using different headers you can use the request configu
'X-Forwarded-Proto',
'X-Proxy-User-Ip',
'Front-End-Https',
];'
];
'ipHeaders' => [
'X-Proxy-User-Ip',
],

4
docs/guide/security-authorization.md

@ -225,6 +225,8 @@ return [
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
// uncomment if you want to cache RBAC items hierarchy
// 'cache' => 'cache',
],
// ...
],
@ -264,7 +266,7 @@ Building authorization data is all about the following tasks:
Depending on authorization flexibility requirements the tasks above could be done in different ways.
If your permissions hierarchy is meant to be changed by developers only, you can use either migrations
or a console command. Migration pro is that it could be executed along with other migrations. Console
command pro is that you have a good overview of the hierarchy in the code rathe than it being scattered
command pro is that you have a good overview of the hierarchy in the code rather than it being scattered
among multiple migrations.
Either way in the end you'll get the following RBAC hierarchy:

28
docs/guide/start-installation.md

@ -111,6 +111,30 @@ But there are other installation options available:
you may consider installing the [Advanced Project Template](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md).
Installing Assets <span id="installing-assets"></span>
-----------------
Yii relies on [Bower](http://bower.io/) and/or [NPM](https://www.npmjs.org/) packages for the asset (CSS and JavaScript) libraries installation.
It uses Composer to obtain these libraries, allowing PHP and CSS/JavaScript package versions to resolve at the same time.
This can be achieved either by usage of [asset-packagist.org](https://asset-packagist.org) or [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/).
Please refer to [Assets documentation](structure-assets.md) for more details.
You may want to either manage your assets via native Bower/NPM client, use CDN or avoid assets installation entirely.
In order to prevent assets installation via Composer, add the following lines to your 'composer.json':
```json
"replace": {
"bower-asset/jquery": ">=1.11.0",
"bower-asset/inputmask": ">=3.2.0",
"bower-asset/punycode": ">=1.3.0",
"bower-asset/yii2-pjax": ">=2.0.0"
},
```
> Note: in case of bypassing asset installation via Composer, you are responsible for the assets installation and resolving
> version collisions. Be prepared for possible inconsistencies among asset files from different extensions.
Verifying the Installation <span id="verifying-installation"></span>
--------------------------
@ -212,7 +236,7 @@ DocumentRoot "path/to/basic/web"
To use [Nginx](http://wiki.nginx.org/), you should install PHP as an [FPM SAPI](http://php.net/install.fpm).
You may use the following Nginx configuration, replacing `path/to/basic/web` with the actual path for
`basic/web` and `mysite.local` with the actual hostname to serve.
`basic/web` and `mysite.test` with the actual hostname to serve.
```nginx
server {
@ -222,7 +246,7 @@ server {
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
server_name mysite.test;
root /path/to/basic/web;
index index.php;

22
docs/guide/start-prerequisites.md

@ -0,0 +1,22 @@
# What do you need to know
Yii learning curve is not as steep as other PHP frameworks but still it requires some beforehand knowledge.
## PHP
Yii is a PHP framework so make sure you [read and understand language reference](http://php.net/manual/en/langref.php).
## Object oriented programming
Basic understanding of object oriented programming is required. If you're not familiar with it, check one of the many
tutorials available such as [the one from tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762).
Note that the more complicated your application is the more advanced OOP concepts your should learn in order to successfully
manage that complexity.
## Command line and composer
Yii extensively uses de-facto standard PHP package manager, [Composer](https://getcomposer.org/) so make sure you read
and understand its guide. If you are not familiar with using command line it is time to start trying. Once you'll
learn the basics you'll never want to work without it.

8
docs/guide/structure-assets.md

@ -194,8 +194,8 @@ class FontAwesomeAsset extends AssetBundle
];
public $publishOptions = [
'only' => [
'fonts/',
'css/',
'fonts/*',
'css/*',
]
];
}
@ -250,8 +250,8 @@ Visit [asset-packagist.org](https://asset-packagist.org) to know, how it works.
##### Using fxp/composer-asset-plugin
Comparing to to using asset-packagist, composer-asset-plugin does not require to change application config. Instead, it
requires to install a special Composer plugin globally by running the following command:
Compared to asset-packagist, composer-asset-plugin does not require any changes to application config. Instead, it
requires global installation of a special Composer plugin by running the following command:
```bash
composer global require "fxp/composer-asset-plugin:^1.4.1"

2
docs/guide/structure-filters.md

@ -90,7 +90,7 @@ class ActionTimeFilter extends ActionFilter
public function afterAction($action, $result)
{
$time = microtime(true) - $this->_startTime;
Yii::trace("Action '{$action->uniqueId}' spent $time second.");
Yii::debug("Action '{$action->uniqueId}' spent $time second.");
return parent::afterAction($action, $result);
}
}

8
docs/guide/structure-modules.md

@ -176,6 +176,14 @@ only contains the module ID, then the [[yii\base\Module::defaultRoute]] property
will determine which controller/action should be used. This means a route `forum` would represent the `default`
controller in the `forum` module.
URL manager routes should be added before [[yii\web\UrlManager::parseRequest()]] is fired. That means doing it
in module's `init()` won't work because module will be initialized when routes were already processed. Thus, routes
should be added at [bootstrap stage](structure-extensions.md#bootstrapping-classes). It is a also a good practice
to wrap module's URL rules with [[\yii\web\GroupUrlRule]].
In case module is used to [version API](rest-versioning.md), routes should be added directly in `urlManager`
section of the application config.
### Accessing Modules <span id="accessing-modules"></span>

5
docs/guide/test-fixtures.md

@ -154,7 +154,10 @@ You may also assign an alias to a fixture. In the above example, the `UserProfil
In the test methods, you may then access a fixture object using its alias in `grabFixture()` method. For example,
```php
$profile = $I->grabFixture('profiles', 'user1');` will return the `UserProfileFixture` object.
$profile = $I->grabFixture('profiles', 'user1');
```
will return the `UserProfileFixture` object.
Because `UserProfileFixture` extends from `ActiveFixture`, you may further use the following syntax to access
the data provided by the fixture:

2
docs/guide/tutorial-i18n.md

@ -416,7 +416,7 @@ while `one` matches `21` or `101`:
These `other`, `few`, `many` and other special argument names vary depending on language. To learn which ones you should
specify for a particular locale, please refer to "Plural Rules, Cardinal" at [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/).
Alternatively you can refer to [rules reference at unicode.org](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html).
Alternatively you can refer to [rules reference at unicode.org](http://cldr.unicode.org/index/cldr-spec/plural-rules).
> Note: The above example Russian message is mainly used as a translated message, not an original message, unless you set
> the [[yii\base\Application::$sourceLanguage|source language]] of your application as `ru-RU` and translating from Russian.

1
docs/guide/tutorial-yii-as-micro-framework.md

@ -104,6 +104,7 @@ At this point the project structure should look like this:
```
micro-app/
├── composer.json
├── config.php
├── web/
└── index.php
└── controllers/

87
docs/internals-ru/git-workflow.md

@ -1,29 +1,29 @@
Рабочий процесс Git для разработчиков Yii 2
===========================================
Итак, вы хотите разрабатывать Yii? Хорошо! Но для того чтоб увеличить шанс принятия ваших изменений,
пожалуйста следуйте следующим шагам. Если вы новичок в git и github, вы можете сначала проверить
[github help](http://help.github.com/), [try git](https://try.github.com) или прочитать о
Итак, вы хотите разрабатывать Yii? Хорошо! Но для того, чтобы увеличить шанс принятия ваших изменений,
пожалуйста, следуйте следующим шагам. Если вы новичок в git и Github, вы можете сначала проверить
[Github help](http://help.github.com/), [try git](https://try.github.com) или прочитать о
[внутренней модели данных git](http://nfarina.com/post/9868516270/git-is-simpler).
Подготовка вашего рабочего окружения
------------------------------------
Следующие шаги будут создавать рабочее окружение для Yii, которое вы можете использовать для работы над основным кодом
Следующие шаги создадут рабочее окружение для Yii, которое вы можете использовать для работы над основным кодом
фреймворка. *Эти шаги будут нужны только в первый раз*.
### 1. [Форкаем](http://help.github.com/fork-a-repo/) репозиторий Yii на github и клонируйте ваш форк в ваше рабочее окружение.
### 1. [Сделайте форк](http://help.github.com/fork-a-repo/) репозитория Yii на Github и клонируйте этот форк в ваше рабочее окружение.
```
git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git
```
Если у вас есть проблемы с настройкой GIT для работы с GitHub в Linux, или вы получаете ошибку похожую на "Permission Denied
(publickey)", тогда вы должны настроить ваш GIT по [этой инструкции](http://help.github.com/linux-set-up-git/)
Если у вас есть проблемы с настройкой Git для работы с GitHub в Linux, или вы получаете ошибку похожую на "Permission Denied
(publickey)", тогда вы должны настроить ваш Git по [этой инструкции](http://help.github.com/linux-set-up-git/)
### 2. Добавляем главный репозиторий Yii как дополнительный внешний git репозиторий называемый "upstream"
### 2. Добавьте главный репозиторий Yii как дополнительный внешний git репозиторий называемый "upstream"
Перейдите в каталог, куда вы склонировали Yii, как правило "yii2". Затем введите следующую команду:
Перейдите в каталог куда вы склонировали Yii, как правило "yii2". Затем введите следующую команду:
```
git remote add upstream git://github.com/yiisoft/yii2.git
@ -33,11 +33,20 @@ git remote add upstream git://github.com/yiisoft/yii2.git
Следующие шаги не обязательны, если вы хотите работать только с переводом или документацией.
- выполните `composer update` для установки зависимостей (если [composer у вас установлен глобально](https://getcomposer.org/doc/00-intro.md#globally)).
- выполните `composer install` для установки зависимостей
(если [composer у вас установлен глобально](https://getcomposer.org/doc/00-intro.md#globally)).
> Note: Если вы видите такие ошибки, как `Problem 1 The requested package bower-asset/jquery could not be found in
> Note: если вы видите такие ошибки, как `Problem 1 The requested package bower-asset/jquery could not be found in
> any version, there may be a typo in the package name.`, необходимо запустить `composer global require "fxp/composer-asset-plugin:^1.4.1"`
Если вы планируете работать с Javascript:
- выполните `npm install` для установки зависимостей и программ тестирования Javascript
(если [Node.js and NPM установлен](https://nodejs.org/en/download/package-manager/)).
> Note: тесты JavaScript зависят от библиотеки jsdom, которой требуется Node.js 4 или более новый.
> Предпочтительнее использовать Node.js 6 or 7.
- выполните `php build/build dev/app basic` для клонирования базового приложения и установки его зависимостей.
Эта команда установит сторонние пакеты composer обычным образом, но создаст ссылку с репозитория yii2 на только
что загруженный репозиторий. Таким образом у вас будет только один экземпляр кода.
@ -56,13 +65,16 @@ git remote add upstream git://github.com/yiisoft/yii2.git
### Модульные тесты
Вы можете выполнить модульные тесты с помощью команды `phpunit` в корневой директории приложения. Если у вас phpunit
не установлен глобально, вы можете запустить `php vendor/bin/phpunit`.
не установлен глобально, вы можете запустить `php vendor/bin/phpunit` или `vendor/bin/phpunit.bat` в случае
использования OS Windows.
Некоторые тесты требуют дополнительно установки и настройки баз данных. Вы можете создать `tests/data/config.local.php`
для переопределения настроек, которые определены в `tests/data/config.php`.
Вы можете ограничить тестирование группой тестов, с которой вы сейчас работаете, например запускать только тесты для
валидаторов и redis. Вы можете получить список доступных групп выполнив `phpunit --list-groups`.
Вы можете ограничить тестирование группой тестов, с которой вы сейчас работаете. Например, запускать только тесты для
валидаторов и redis: `phpunit --group=validators,redis`. Вы можете получить список доступных групп выполнив `phpunit --list-groups`.
Вы можете запустить модульные тесты JavaScript с помощью команды `npm test` в корневой директории приложения.
### Расширения
@ -70,15 +82,16 @@ git remote add upstream git://github.com/yiisoft/yii2.git
сделать это:
```
php build/build dev/ext <extension-name>
php build/build dev/ext <extension-name> <fork>
```
где `<extension-name>` это имя расширения, например `redis`.
где `<extension-name>` это имя расширения, например `redis` и `<fork>` это URL вашего форка расширения, например
`git@github.com:my_nickname/yii2-redis.git`. Если вы контрибьютор ядра фреймворка, вы можете не указывать `<fork>`.
Если вы хотите протестировать расширение в одном из шаблонов приложений, просто добавьте его в `composer.json`
приложения, например добавив `"yiisoft/yii2-redis": "~2.0.0"` в секцию `require` базового приложения.
Запустите `php build/build dev/app basic` для установки расширения и его зависимостей и создания символической
ссылки на `extensions/redis` так чтоб вы работали не папке вендорных пакетов composer, а напрямую в репозиторий yii2.
ссылки на `extensions/redis` так чтоб вы работали не папке вендорных пакетов composer, а напрямую в репозитории yii2.
> Note: по умолчанию URL репозиториев git на GitHub работают через SSH. Чтобы использовать HTTPS, добавьте
> флаг `--useHttp` к команде `build`.
@ -94,21 +107,21 @@ php build/build dev/ext <extension-name>
Потратьте несколько минут на поиск существующей issue, которая соответствует вашим изменениям. Если вы найдёте её в
списке, то пожалуйста оставьте комментарий, что вы начали над ней работать. Если вы не нашли нужной issue пожалуйста
[создайте новую issue](report-an-issue.md) или создайте сразу запрос на изменения если это простые изменения.
Это позволит команде проверить ваше предложение, и обеспечивать соответствующую обратную связь.
Это позволит команде проверить ваше предложение, и обеспечить соответствующую обратную связь.
> Для небольших изменений или документации, или простых исправлений, вам нет необходимости создавать issue,
запрос на изменения в этом случае подходит лучше.
### 2. Вытягивание последнего кода из основного репозитория Yii
### 2. Получите последний код из основного репозитория Yii
```
git fetch upstream
git pull upstream
```
Вы должны начинать с этого действия работу над каждым новым предложением, убеждайтесь что вы работаете над самой
Вы должны начинать с этого действия работу над каждым новым предложением. Убедитесь, что вы работаете с самой
последней версией кода.
### 3. Создание новой ветки для ваших изменений, основанных на текущем мастере Yii
### 3. Сделайте новую ветку для ваших изменений, основанных на текущей ветке master в Yii
> Это очень важно, так как вы не сможете отправлять более одного запроса на изменения из вашего репозитория, если
будете использовать ветку master.
@ -123,7 +136,7 @@ git checkout upstream/master
git checkout -b 999-name-of-your-branch-goes-here
```
### 4. Делайте свою магию, пишите ваш код
### 4. Делайте свою магию, пишите свой код
Убедитесь, что он работает :)
@ -145,7 +158,7 @@ Enh #999: a description of the enhancement (Your Name)
Для очень маленьких исправлений, например опечаток и изменений документации, нет необходимости обновлять CHANGELOG.
### 6. Фиксация ваших изменений
### 6. Зафиксируйте изменения
Добавляем файлы/изменения которые вы хотите зафиксировать в [staging area](http://gitref.org/basic/#add)
@ -155,14 +168,14 @@ git add path/to/my/file.php
Вы можете использовать опцию `-p` для того, чтоб выбрать, какие изменения вы хотите добавить в коммит.
Фиксируйте ваши изменения с описательным сообщением. Убедитесь что в сообщение есть номер `#XXX`, так github
автоматически свяжет ваш коммит с тикетом:
Фиксируйте ваши изменения с описательным сообщением. Убедитесь, что в сообщении есть номер `#XXX`, так Github
автоматически свяжет ваш коммит с issue:
```
git commit -m "A brief description of this change which fixes #999 goes here"
```
### 7. Получение последнего кода из апстрима Yii в вашу ветку
### 7. Получите последний код из upstream Yii в вашу ветку
```
git pull upstream master
@ -172,18 +185,18 @@ git pull upstream master
какие-либо конфликты слияния, вы должны исправить их и зафиксировать изменения ещё раз. Это гарантирует, что команда Yii
сможет слить ваши изменения одним кликом.
### 8. Разрешив зависимости, отправляем код на github
### 8. Разрешив зависимости, отправьте код на Github
```
git push -u origin 999-name-of-your-branch-goes-here
```
Опция `-u` сохранит указание на ветку в github, чтобы при следующем выполнении `git push`, git знал, куда отправлять
Опция `-u` сохранит указание на ветку в Github, чтобы при следующем выполнении `git push`, git знал, куда отправлять
изменения. Это полезно, если вы хотите позже отправлять ещё коммиты в этот запрос на слияние.
### 9. Открываем [запрос на слияние](http://help.github.com/send-pull-requests/) в *upstream*.
### 9. Откройте [запрос на слияние](http://help.github.com/send-pull-requests/) в *upstream*.
Перейдите в репозиторий на github и нажмите "Pull Request", выберите ветку справа и введите больше информации
Перейдите в репозиторий на Github и нажмите "Pull Request", выберите ветку справа и введите больше информации
в поле комментариев. Чтобы связать запрос на изменение с issue, добавьте в комментарий `#999` - где 999 это номер issue.
> Обратите внимание, что каждый запрос на слияние должен исправлять единственное изменение. Для множества независимых
@ -191,10 +204,10 @@ git push -u origin 999-name-of-your-branch-goes-here
### 10. Проверка вашего кода кем-то
Кто-то будет проверять ваш код, и, возможно, вам будет предложено внести некоторые изменения, если это так, то перейдите
Кто-то будет проверять ваш код, и, возможно, вам будет предложено внести некоторые изменения. Eсли это так, то перейдите
к шагу #6 (вам не надо открывать новый запрос на слияние, если текущий ещё открыт). Если код будет принят, он будет
влит в основную ветку и станет частью следующего релиза Yii. Если нет, не унывайте, разным людям необходимы различные
функции и Yii не может реализовывать всё для всех, ваш код будет ещё доступен на github как ссылка для людей кому он
влит в основную ветку и станет частью следующего релиза Yii. Если нет - не унывайте, разным людям необходимы различные
функции и Yii не может реализовывать всё для всех, ваш код будет ещё доступен на Github как ссылка для людей кому он
может пригодится.
### 11. Очистка
@ -210,16 +223,16 @@ git push origin --delete 999-name-of-your-branch-goes-here
### Примечание
Для обнаружения регрессии как можно раньше, каждое слияние кодовой базы Yii на github будет подхвачено
Для обнаружения регрессии как можно раньше, каждое слияние кодовой базы Yii на Github будет подхвачено
[Travis CI](http://travis-ci.org) для автоматического запуска тестов. Люди из *core team* не хотят нагружать
этот сервис, поэтому добавляют текст [`[ci skip]`](http://about.travis-ci.org/docs/user/how-to-skip-a-build/) в описание
запроса на слияние, в следующих ситуациях:
* затронуты только javascript, css файлы или файлы изображений,
* затронуты только JavaScript, CSS файлы или файлы изображений,
* обновление документации,
* изменения затрагивают только строки (например обновление переводов).
Это защитит travis от запуска тестов на изменениях, которые не покрыты тестами.
Это защитит Travis CI от запуска тестов на изменениях, которые не покрыты тестами.
### Обзор команд (для продвинутых участников)

4
docs/internals/README.md

@ -42,3 +42,7 @@ Misc
### Exception Hierarchy
![Yii Framework Exception Hierarchy](exception_hierarchy.png)
### Database testing
[Here](https://gist.github.com/sergeymakinen/0696a5952f160ea28d7b64c3adfecf6f) is config for test environments for all supported Yii databases.

4
docs/internals/git-workflow.md

@ -111,10 +111,10 @@ review your suggestion, and provide appropriate feedback along the way.
> For small changes or documentation issues or straightforward fixes, you don't need to create an issue, a pull request is enough in this case.
### 2. Fetch the latest code from the main Yii branch
### 2. Pull the latest code from the main Yii branch
```
git fetch upstream
git pull upstream
```
You should start at this point for every new contribution to make sure you are working on the latest code.

8
docs/internals/release.md

@ -53,13 +53,13 @@ You may run it with `--update` to fetch tags for all repos to get the newest inf
Making a framework release includes the following commands (apps are always released together with the framework):
./build release framework
./build release app-basic
./build release app-advanced
./build/build release framework
./build/build release app-basic
./build/build release app-advanced
Making an extension release includes only one command (e.g. for redis):
./build release redis
./build/build release redis
The default release command will release a new minor version from the currently checked out branch.
To release another version than the default, you have to specify it using the `--version` option, e.g.

26
framework/BaseYii.php

@ -7,8 +7,8 @@
namespace yii;
use yii\base\InvalidArgumentException;
use yii\base\InvalidConfigException;
use yii\base\InvalidParamException;
use yii\base\UnknownClassException;
use yii\di\Container;
use yii\log\Logger;
@ -125,7 +125,7 @@ class BaseYii
* @param bool $throwException whether to throw an exception if the given alias is invalid.
* If this is false and an invalid alias is given, false will be returned by this method.
* @return string|bool the path corresponding to the alias, false if the root alias is not previously registered.
* @throws InvalidParamException if the alias is invalid while $throwException is true.
* @throws InvalidArgumentException if the alias is invalid while $throwException is true.
* @see setAlias()
*/
public static function getAlias($alias, $throwException = true)
@ -151,7 +151,7 @@ class BaseYii
}
if ($throwException) {
throw new InvalidParamException("Invalid path alias: $alias");
throw new InvalidArgumentException("Invalid path alias: $alias");
}
return false;
@ -211,7 +211,7 @@ class BaseYii
* - a path alias (e.g. `@yii/base`). In this case, the path alias will be converted into the
* actual path first by calling [[getAlias()]].
*
* @throws InvalidParamException if $path is an invalid alias.
* @throws InvalidArgumentException if $path is an invalid alias.
* @see getAlias()
*/
public static function setAlias($alias, $path)
@ -380,15 +380,16 @@ class BaseYii
}
/**
* Logs a trace message.
* Logs a debug message.
* Trace messages are logged mainly for development purpose to see
* the execution work flow of some code. This method will only log
* a message when the application is in debug mode.
* @param string|array $message the message to be logged. This can be a simple string or a more
* complex data structure, such as array.
* @param string $category the category of the message.
* @since 2.0.14
*/
public static function trace($message, $category = 'application')
public static function debug($message, $category = 'application')
{
if (YII_DEBUG) {
static::getLogger()->log($message, Logger::LEVEL_TRACE, $category);
@ -396,6 +397,18 @@ class BaseYii
}
/**
* Alias of [[debug()]].
* @param string|array $message the message to be logged. This can be a simple string or a more
* complex data structure, such as array.
* @param string $category the category of the message.
* @deprecated 2.0.14 Use [[debug()]]
*/
public static function trace($message, $category = 'application')
{
static::debug($message, $category);
}
/**
* Logs an error message.
* An error message is typically logged when an unrecoverable error occurs
* during the execution of an application.
@ -472,6 +485,7 @@ class BaseYii
/**
* Returns an HTML hyperlink that can be displayed on your Web page showing "Powered by Yii Framework" information.
* @return string an HTML hyperlink that can be displayed on your Web page showing "Powered by Yii Framework" information
* @deprecated 2.0.14
*/
public static function powered()
{

128
framework/CHANGELOG.md

@ -4,7 +4,130 @@ Yii Framework 2 Change Log
2.0.14 under development
------------------------
- no changes in this release.
- Bug #15644: Avoid wrong default selection on a dropdown, checkbox list, and radio list, when a option has a key equals to zero (berosoboy)
- Enh #14538: Added `yii\behaviors\AttributeTypecastBehavior::typecastAfterFind` property (littlefuntik, silverfire)
- Enh #14254: add an option to specify whether validator is forced to always use master DB for `yii\validators\UniqueValidator` and `yii\validators\ExistValidator` (rossoneri, samdark)
- Enh #15272: Removed type attribute from script tag (aleksbelic)
- Enh #15120: Refactored dynamic caching introducing `DynamicContentAwareInterface` and `DynamicContentAwareTrait` (sergeymakinen)
- Bug #8983: Only truncate the original log file for rotation (matthewyang, developeruz)
- Bug #11401: Fixed `yii\web\DbSession` concurrency issues when writing and regenerating IDs (samdark, andreasanta, cebe)
- Bug #13034: Fixed `normalizePath` for windows network shares that start with two backslashes (developeruz)
- Bug #14135: Fixed `yii\web\Request::getBodyParam()` crashes on object type body params (klimov-paul)
- Bug #14157: Add support for loading default value `CURRENT_TIMESTAMP` of MySQL `datetime` field (rossoneri)
- Bug #14276: Fixed I18N format with dotted parameters (developeruz)
- Bug #14296: Fixed log targets to throw exception in case log can not be properly exported (bizley)
- Bug #14484: Fixed `yii\validators\UniqueValidator` for target classes with a default scope (laszlovl, developeruz)
- Bug #14604: Fixed `yii\validators\CompareValidator` `compareAttribute` does not work if `compareAttribute` form ID has been changed (mikk150)
- Bug #14711: Fixed `yii\web\ErrorHandler` displaying exception message in non-debug mode (samdark)
- Bug #14811: Fixed `yii\filters\HttpCache` to work with PHP 7.2 (samdark)
- Bug #14859: Fixed OCI DB `defaultSchema` failure when `masterConfig` is used (lovezhl456)
- Bug #14903: Fixed route with extra dashes is executed controller while it should not (developeruz)
- Bug #14916: Fixed `yii\db\Query::each()` iterator key starts from 1 instead of 0 (Vovan-VE)
- Bug #14980: Fix looping in `yii\i18n\MessageFormatter` tokenize pattern if pattern is invalid (uaoleg, developeruz)
- Bug #15031: Fixed incorrect string type length detection for OCI DB schema (Murolike)
- Bug #15046: Throw an `yii\web\HeadersAlreadySentException` if headers were sent before web response (dmirogin)
- Bug #15122: Fixed `yii\db\Command::getRawSql()` to properly replace expressions (hiscaler, samdark)
- Bug #15142: Fixed array params replacing in `yii\helpers\BaseUrl::current()` (IceJOKER)
- Bug #15169: Fixed translating a string when NULL parameter is passed (developeruz)
- Bug #15194: Fixed `yii\db\QueryBuilder::insert()` to preserve passed params when building a `INSERT INTO ... SELECT` query for MSSQL, PostgreSQL and SQLite (sergeymakinen)
- Bug #15229: Fixed `yii\console\widgets\Table` default value for `getScreenWidth()`, when `Console::getScreenSize()` can't determine screen size (webleaf)
- Bug #15234: Fixed `\yii\widgets\LinkPager` removed `tag` from `disabledListItemSubTagOptions` (SDKiller)
- Bug #15249: Controllers in subdirectories were not visible in commands list (IceJOKER)
- Bug #15270: Resolved potential race conditions when writing generated php-files (kalessil)
- Bug #15300: Fixed "Cannot read property 'style' of undefined" error at the error screen (vitorarantes)
- Bug #15301: Fixed `ArrayHelper::filter()` to work properly with `0` in values (hhniao)
- Bug #15302: Fixed `yii\caching\DbCache` so that `getValues` now behaves the same as `getValue` with regards to streams (edwards-sj)
- Bug #15317: Regenerate CSRF token if an empty value is given (sammousa)
- Bug #15320: Fixed special role checks in `yii\filters\AccessRule::matchRole()` (Izumi-kun)
- Bug #15322: Fixed PHP 7.2 compatibility of `FileHelper::getExtensionsByMimeType()` (samdark)
- Bug #15353: Remove side effect of ActiveQuery::getTablesUsedInFrom() introduced in 2.0.13 (terales)
- Bug #15355: Fixed `yii\db\Query::from()` does not work with `yii\db\Expression` (vladis84, silverfire, samdark)
- Bug #15356: Fixed multiple bugs in `yii\db\Query::getTablesUsedInFrom()` (vladis84, samdark)
- Bug #15380: `FormatConverter::convertDateIcuToPhp()` now converts `a` ICU symbols to `A` (brandonkelly)
- Bug #15407: Fixed rendering rows with associative arrays in `yii\console\widgets\Table` (dmrogin)
- Bug #15432: Fixed wrong value being set in `yii\filters\RateLimiter::checkRateLimit()` resulting in wrong `X-Rate-Limit-Reset` header value (bizley)
- Bug #15440: Fixed `yii\behaviors\AttributeTypecastBehavior::$attributeTypes` auto-detection fails for rule, which specify attribute with '!' prefix (klimov-paul)
- Bug #15462: Fixed `accessChecker` configuration error (developeruz)
- Bug #15494: Fixed missing `WWW-Authenticate` header (developeruz)
- Bug #15522: Fixed `yii\db\ActiveRecord::refresh()` method does not use an alias in the condition (vladis84)
- Bug #15523: `yii\web\Session` settings could now be configured after session is started (StalkAlex, rob006, daniel1302, samdark)
- Bug #15536: Fixed `yii\widgets\ActiveForm::init()` for call `parent::init()` (panchenkodv)
- Bug #15540: Fixed `yii\db\ActiveRecord::with()` unable to use relation defined via attached behavior in case `asArray` is enabled (klimov-paul)
- Bug #15553: Fixed `yii\validators\NumberValidator` incorrectly validate resource (developeruz)
- Bug #15621: Fixed `yii\web\User::getIdentity()` returning `null` if an exception had been thrown when it was called previously (brandonkelly)
- Enh #3087: Added `yii\helpers\BaseHtml::error()` "errorSource" option to be able to customize errors display (yanggs07, developeruz, silverfire)
- Enh #3250: Added support for events partial wildcard matching (klimov-paul)
- Enh #5515: Added default value for `yii\behaviors\BlameableBehavior` for cases when the user is guest (dmirogin)
- Enh #6844: `yii\base\ArrayableTrait::toArray()` now allows recursive `$fields` and `$expand` (bboure)
- Enh #7988: Added `\yii\helpers\Console::errorSummary()` and `\yii\helpers\Json::errorSummary()` (developeruz)
- Enh #7996: Short syntax for verb in GroupUrlRule (schojniak, developeruz)
- Enh #8092: ExistValidator for relations (developeruz)
- Enh #8527: Added `yii\i18n\Locale` component having `getCurrencySymbol()` method (amarox, samdark)
- Enh #8752: Allow specify `$attributeNames` as a string for `yii\base\Model` `validate()` method (developeruz)
- Enh #9137: Added `Access-Control-Allow-Method` header for the OPTIONS request (developeruz)
- Enh #9253: Allow `variations` to be a string for `yii\filters\PageCache` and `yii\widgets\FragmentCache` (schojniak, developeruz)
- Enh #9771: Assign hidden input with its own set of HTML options via `$hiddenOptions` in activeFileInput `$options` (HanafiAhmat)
- Enh #10186: Use native `hash_equals` in `yii\base\Security::compareString()` if available, throw exception if non-strings are compared (aotd1, samdark)
- Enh #11611: Added `BetweenColumnsCondition` to build SQL condition like `value BETWEEN col1 and col2` (silverfire)
- Enh #12623: Added `yii\helpers\StringHelper::matchWildcard()` replacing usage of `fnmatch()`, which may be unreliable (klimov-paul)
- Enh #13019: Support JSON in SchemaBuilderTrait (zhukovra, undefinedor)
- Enh #13465: Added `yii\helpers\FileHelper::findDirectory()` method (ArsSirek, developeruz)
- Enh #13618: Active record now resets related models after corresponding attributes updates (Kolyunya, rob006)
- Enh #13679: Added `yii\behaviors\CacheableWidgetBehavior` (Kolyunya)
- Enh #13814: MySQL unique index names can now contain spaces (df2)
- Enh #13879: Added upsert support for `yii\db\QueryBuilder` and `yii\db\Command` (sergeymakinen)
- Enh #13919: Added option to add comment for created table to migration console command (mixartemev, developeruz)
- Enh #13996: Added `yii\web\View::registerJsVar()` method that allows registering JavaScript variables (Eseperio, samdark)
- Enh #14043: Added `yii\helpers\IpHelper` (silverfire, cebe)
- Enh #14355: Added ability to pass an empty array as a parameter in console command (developeruz)
- Enh #14488: Added support for X-Forwarded-Host to `yii\web\Request`, fixed `getServerPort()` usage (si294r, samdark)
- Enh #14546: Added `dataDirectory` property into `BaseActiveFixture` (leandrogehlen)
- Enh #14568: Refactored migration templates to use `safeUp()` and `safeDown()` methods (Kolyunya)
- Enh #14638: Added `yii\db\SchemaBuilderTrait::tinyInteger()` (rob006)
- Enh #14643: Added `yii\web\ErrorAction::$layout` property to conveniently set layout from error action config (swods, cebe, samdark)
- Enh #14662: Added support for custom `Content-Type` specification to `yii\web\JsonResponseFormatter` (Kolyunya)
- Enh #14732, #11218, #14810, #10855: It is now possible to pass `yii\db\Query` anywhere, where `yii\db\Expression` was supported (silverfire)
- Enh #14806: Added $placeFooterAfterBody option for GridView (terehru)
- Enh #15024: `yii\web\Pjax` widget does not prevent CSS files from sending anymore because they are handled by client-side plugin correctly (onmotion)
- Enh #15047: `yii\db\Query::select()` and `yii\db\Query::addSelect()` now check for duplicate column names (wapmorgan)
- Enh #15135: Automatic completion for help in bash and zsh (Valkeru)
- Enh #15216: Added `yii\web\ErrorHandler::$traceLine` to allow opening file at line clicked in IDE (vladis84)
- Enh #15219: Added `yii\filters\auth\HttpHeaderAuth` (bboure)
- Enh #15221: Added support for specifying `--camelCase` console options in `--kebab-case` (brandonkelly)
- Enh #15221: Added support for the `--<option> <value>` console option syntax (brandonkelly)
- Enh #15221: Improved the `help/list-action-options` console command output for command options without a description (brandonkelly)
- Enh #15226: Auto generate placeholder from fields (vladis84)
- Enh #15332: Always check for availability of `openssl_pseudo_random_bytes`, even if LibreSSL is available (sammousa)
- Enh #15335: Added `FileHelper::unlink()` that works well under all OSes (samdark)
- Enh #15340: Test CHANGELOG.md for valid format (sammousa)
- Enh #15347: Add `Instance` support for object property in DI container (kojit2009)
- Enh #15357: Added multi statement support for `yii\db\sqlite\Command` (sergeymakinen)
- Enh #15360: Refactored `BaseConsole::updateProgress()` (developeruz)
- Enh #15398: Extract cache-related methods from `yii\db\Command` to `yii\db\CacheableQueryTrait` and use it in `yii\db\Query` (hubeiwei, silverfire)
- Enh #15415: Added transaction/retry support for `yii\db\Command` (sergeymakinen)
- Enh #15417: Added `yii\validators\FileValidator::$minFiles` (vladis84)
- Enh #15422: Added default roles dynamic definition support via closure for `yii\rbac\BaseManager` (deltacube)
- Enh #15426: Added abilitiy to create and drop database views (igravity, vladis84)
- Enh #15476: Added `\yii\widgets\ActiveForm::$validationStateOn` to be able to specify where to add class for invalid fields (samdark)
- Enh #15496: CSRF token is now regenerated on changing identity (samdark, rhertogh)
- Enh #15595: `yii\data\DataFilter` can now handle `lt`,`gt`,`lte` and `gte` on `yii\validators\DateValidator` (mikk150)
- Enh: Added check to `yii\base\Model::formName()` to prevent source path disclosure when form is represented by an anonymous class (silverfire)
- Chg #15420: Handle OPTIONS request in `yii\filter\Cors` so the preflight check isn't passed trough authentication filters (michaelarnauts, leandrogehlen)
- Chg #15625: `yii\grid\DataColumn` boolean filter dropdown list values are now in reversed order (bizley)
- Chg #15633: Deprecated `yii\base\BaseObject::className()` in favor of native PHP syntax `::class`, which does not trigger autoloading (brandonkelly)
- Chg #15633: Deprecated XCache and Zend data cache support as caching backends (brandonkelly)
- Chg #15633: Deprecated `yii\BaseYii::powered()` method (brandonkelly)
- Chg #15633: Added `yii\base\InvalidArgumentException` and deprecated `yii\base\InvalidParamException` (brandonkelly)
- Chg #15633: Added `yii\BaseYii::debug()` and deprecated `yii\BaseYii::trace()` (brandonkelly)
2.0.13.1 November 14, 2017
--------------------------
- Bug #15081: Fixed "Undefined offset: 1" in log Target (ischenko)
- Bug #15086: Fixed jQuery onLoad event handling (alexantr)
- Bug #15108: Fixed `yii\db\Schema::getSchemaNames()` for MSSQL and added tests for all DBMSes (sergeymakinen)
- Bug #15117: Fixed DB schema cache did not honor table prefixes (sergeymakinen)
2.0.13 November 03, 2017
@ -64,6 +187,7 @@ Yii Framework 2 Change Log
- Enh #4495: Added closure support in `yii\i18n\Formatter` (developeruz)
- Enh #5786: Allowed to use custom constructors in ActiveRecord-based classes (ElisDN, klimov-paul)
- Enh #6644: Added `yii\helpers\ArrayHelper::setValue()` (LAV45)
- Enh #7640: Implemented custom data types support. Added JSON support for MySQL and PostgreSQL, array support for PostgreSQL (silverfire, cebe)
- Enh #7823: Added `yii\filters\AjaxFilter` filter (dmirogin)
- Enh #9438: `yii\web\DbSession` now relies on error handler to display errors (samdark)
- Enh #9703, #9709: Added `yii\i18n\Formatter::asWeight()` and `::asLength()` formatters (nineinchnick, silverfire)
@ -106,13 +230,13 @@ Yii Framework 2 Change Log
- Enh #14958: Added options to copy stacktrace and search for error message to the exception page (cebe)
- Enh #14967: Added Armenian Translations (gevorgmansuryan)
- Enh #15015: Added `StringHelper::floatToString()` to safely cast float values independent of the locale, also fixes some places in the framework that use it now (cebe)
- Enh #15076: Perfect `yii\db\QueryBuilder` buildColumns function (hiscaler)
- Chg #7936: Deprecate `yii\base\Object` in favor of `yii\base\BaseObject` for compatibility with PHP 7.2 (rob006, cebe, klimov-paul)
- Chg #14201: `yii\console\controllers\MessageController::extractMessagesFromTokens()` is now protected (faenir)
- Chg #14286: Used primary inputmask package name instead of an alias (samdark)
- Chg #14321: `yii\widgets\MaskedInput` is now registering its JavaScript `clientOptions` initialization code in head section (DaveFerger)
- Chg #14487: Changed i18n message error to warning (dmirogin)
2.0.12 June 05, 2017
--------------------

36
framework/UPGRADE.md

@ -50,6 +50,30 @@ if you want to upgrade from version A to version C and there is
version B between A and C, you need to follow the instructions
for both A and B.
Upgrade from Yii 2.0.13
-----------------------
* Constants `IPV6_ADDRESS_LENGTH`, `IPV4_ADDRESS_LENGTH` were moved from `yii\validators\IpValidator` to `yii\helpers\IpHelper`.
If your application relies on these constants, make sure to update your code to follow the changes.
* `yii\base\Security::compareString()` is now throwing `yii\base\InvalidParamException` in case non-strings are compared.
* `yii\db\ExpressionInterface` has been introduced to represent a wider range of SQL expressions. In case you check for
`instanceof yii\db\Expression` in your code, you might consider changing that to checking for the interface and use the newly
introduced methods to retrieve the expression content.
* `yii\db\PdoValue` class has been introduced to replace a special syntax that was used to declare PDO parameter type
when binding parameters to an SQL command, for example: `['value', \PDO::PARAM_STR]`.
You should use `new PdoValue('value', \PDO::PARAM_STR)` instead. Old syntax will be removed in Yii 2.1.
* `yii\db\QueryBuilder::conditionBuilders` property and method-based condition builders are no longer used.
Class-based conditions and builders are introduced instead to provide more flexibility, extensibility and
space to customization. In case you rely on that property or override any of default condition builders, follow the
special [guide article](http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html#adding-custom-conditions-and-expressions)
to update your code.
* Log targets (like `yii\log\EmailTarget`) are now throwing `yii\log\LogRuntimeException` in case log can not be properly exported.
Upgrade from Yii 2.0.12
-----------------------
@ -130,6 +154,9 @@ Upgrade from Yii 2.0.12
However, this change may affect your application if you have code that uses method `yii\base\Module::has()` in order
to check existence of the component exactly in this specific module. In this case make sure the logic is not corrupted.
* If you are using "asset" command to compress assets and your web applicaiton `assetManager` has `linkAssets` turned on,
make sure that "asset" command config has `linkAssets` turned on as well.
Upgrade from Yii 2.0.11
-----------------------
@ -150,9 +177,10 @@ Upgrade from Yii 2.0.11
internal cache for `createUrl()` calls. Ensure that all your custom rules implement this method in order to fully
benefit from the acceleration provided by this cache.
* `yii\filters\AccessControl` now can be used without `user` component.
In this case `yii\filters\AccessControl::denyAccess()` throws `yii\web\ForbiddenHttpException` and using `AccessRule`
matching a role throws `yii\base\InvalidConfigException`.
* `yii\filters\AccessControl` now can be used without `user` component. This has two consequences:
1. If used without user component, `yii\filters\AccessControl::denyAccess()` throws `yii\web\ForbiddenHttpException` instead of redirecting to login page.
2. If used without user component, using `AccessRule` matching a role throws `yii\base\InvalidConfigException`.
* Inputmask package name was changed from `jquery.inputmask` to `inputmask`. If you've configured path to
assets manually, please adjust it.
@ -488,7 +516,7 @@ new ones save the following code as `convert.php` that should be placed in the s
$out = var_export($data, true);
$out = "<?php\nreturn " . $out . ';';
$out = str_replace(['array (', ')'], ['[', ']'], $out);
file_put_contents($fileName, $out);
file_put_contents($fileName, $out, LOCK_EX);
}
$items = [];

2
framework/Yii.php

@ -5,8 +5,6 @@
* @license http://www.yiiframework.com/license/
*/
require __DIR__ . '/BaseYii.php';
/**
* Yii is a helper class serving common framework functionalities.
*

18
framework/assets/yii.activeForm.js

@ -134,7 +134,9 @@
// whether to scroll to first visible error after validation.
scrollToError: true,
// offset in pixels that should be added when scrolling to the first error.
scrollToErrorOffset: 0
scrollToErrorOffset: 0,
// where to add validation class: container or input
validationStateOn: 'container'
};
// NOTE: If you change any of these defaults, make sure you update yii\widgets\ActiveField::getClientOptions() as well
@ -441,8 +443,11 @@
// Without setTimeout() we would get the input values that are not reset yet.
this.value = getValue($form, this);
this.status = 0;
var $container = $form.find(this.container);
$container.removeClass(
var $container = $form.find(this.container),
$input = findInput($form, attribute),
$errorElement = data.settings.validationStateOn === 'input' ? $input : $container;
$errorElement.removeClass(
data.settings.validatingCssClass + ' ' +
data.settings.errorCssClass + ' ' +
data.settings.successCssClass
@ -711,17 +716,20 @@
var $container = $form.find(attribute.container);
var $error = $container.find(attribute.error);
updateAriaInvalid($form, attribute, hasError);
var $errorElement = data.settings.validationStateOn === 'input' ? $input : $container;
if (hasError) {
if (attribute.encodeError) {
$error.text(messages[attribute.id][0]);
} else {
$error.html(messages[attribute.id][0]);
}
$container.removeClass(data.settings.validatingCssClass + ' ' + data.settings.successCssClass)
$errorElement.removeClass(data.settings.validatingCssClass + ' ' + data.settings.successCssClass)
.addClass(data.settings.errorCssClass);
} else {
$error.empty();
$container.removeClass(data.settings.validatingCssClass + ' ' + data.settings.errorCssClass + ' ')
$errorElement.removeClass(data.settings.validatingCssClass + ' ' + data.settings.errorCssClass + ' ')
.addClass(data.settings.successCssClass);
}
attribute.value = getValue($form, attribute);

2
framework/assets/yii.js

@ -253,7 +253,7 @@ window.yii = (function ($) {
$form.trigger('submit');
$.when($form.data('yiiSubmitFinalizePromise')).then(function () {
$.when($form.data('yiiSubmitFinalizePromise')).done(function () {
if (newForm) {
$form.remove();
return;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save