diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9174ec11c89..cecccf6dcf1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,5 +3,4 @@ | Is bugfix? | ✔️/❌ | New feature? | ✔️/❌ | Breaks BC? | ✔️/❌ -| Tests pass? | ✔️/❌ -| Fixed issues | comma-separated list of tickets # fixed by the PR, if any +| Fixed issues | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a912dbfd1b5..f69cc79f804 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,7 @@ on: [push, pull_request] env: DEFAULT_COMPOSER_FLAGS: "--prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi" PHPUNIT_EXCLUDE_GROUP: mssql,oci,wincache,xcache,zenddata,cubrid + XDEBUG_MODE: coverage, develop jobs: phpunit: @@ -28,28 +29,17 @@ jobs: ports: - 5432:5432 options: --name=postgres --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3 - mssql: - image: mcr.microsoft.com/mssql/server:2017-latest - env: - SA_PASSWORD: YourStrong!Passw0rd - ACCEPT_EULA: Y - MSSQL_PID: Developer - ports: - - 1433:1433 - options: --name=mssql --health-cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'YourStrong!Passw0rd' -Q 'SELECT 1'" --health-interval=10s --health-timeout=5s --health-retries=3 strategy: fail-fast: false matrix: os: [ubuntu-latest] - php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0'] + php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1] steps: - name: Generate french locale run: sudo locale-gen fr_FR.UTF-8 - - name: Create MS SQL Database - run: docker exec -i mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'YourStrong!Passw0rd' -Q 'CREATE DATABASE yiitest' - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@v2 with: @@ -57,51 +47,21 @@ jobs: tools: pecl extensions: apc, curl, dom, imagick, intl, mbstring, mcrypt, memcached, mysql, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, pgsql, sqlite ini-values: date.timezone='UTC', session.save_path="${{ runner.temp }}" - - name: Install php-sqlsrv - run: | - curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - >/dev/null 2>&1 - curl -sSL https://packages.microsoft.com/config/ubuntu/16.04/mssql-server-2017.list | sudo tee /etc/apt/sources.list.d/mssql-server-2017.list >/dev/null 2>&1 - printf "\033[32;1m✓ \033[0m\033[90;1madd microsoft keys & repository\n" - sudo apt-get -q update >/dev/null 2>&1 - printf "\033[32;1m✓ \033[0m\033[90;1mapt-get update\n" - sudo pecl -q install pdo_sqlsrv > /dev/null 2>&1 - printf "\033[32;1m✓ \033[0m\033[90;1mpecl install pdo_sqlsrv\n" - if (php -m | grep -i -q -w "pdo_sqlsrv"); then - printf "\033[32;1mpdo_sqlsrv installed correct\n" - else - printf "\033[31;1mpdo_sqlsrv not installed :-(\n" - fi - if: matrix.php == '7.4' || matrix.php == '7.3' || matrix.php == '7.2' - name: Install Memcached uses: niden/actions-memcached@v7 - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install dependencies run: composer update $DEFAULT_COMPOSER_FLAGS - - name: PHP Unit tests for PHP 7.1 - run: vendor/bin/phpunit --verbose --coverage-clover=coverage.clover --exclude-group oci,wincache,xcache,zenddata,cubrid --colors=always - if: matrix.php == '7.1' - - name: PHP Unit tests for PHP >= 7.2 - run: vendor/bin/phpunit --verbose --exclude-group $PHPUNIT_EXCLUDE_GROUP --colors=always - env: - PHPUNIT_EXCLUDE_GROUP: oci,wincache,xcache,zenddata,cubrid - if: matrix.php >= '7.2' - - name: PHP Unit tests for PHP <= 7.0 + - name: PHP Unit tests run: vendor/bin/phpunit --verbose --exclude-group $PHPUNIT_EXCLUDE_GROUP --colors=always - if: matrix.php <= '7.0' - - name: Code coverage - run: | - wget https://scrutinizer-ci.com/ocular.phar - php ocular.phar code-coverage:upload --format=php-clover coverage.clover - if: matrix.php == '7.1' - continue-on-error: true # if is fork npm: name: NPM 6 on ubuntu-latest @@ -109,7 +69,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install PHP uses: shivammathur/setup-php@v2 with: @@ -119,7 +79,7 @@ jobs: id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} diff --git a/.github/workflows/ci-mssql.yml b/.github/workflows/ci-mssql.yml new file mode 100644 index 00000000000..f8ad3eff475 --- /dev/null +++ b/.github/workflows/ci-mssql.yml @@ -0,0 +1,103 @@ +on: + - pull_request + - push + +name: ci-mssql + +jobs: + tests: + name: PHP ${{ matrix.php }}-mssql-${{ matrix.mssql }} + + env: + key: cache + + runs-on: ubuntu-latest + + strategy: + matrix: + include: + - php: 7.0 + extensions: pdo, pdo_sqlsrv-5.8.1 + mssql: server:2017-latest + - php: 7.1 + extensions: pdo, pdo_sqlsrv-5.8.1 + mssql: server:2017-latest + - php: 7.2 + extensions: pdo, pdo_sqlsrv-5.8.1 + mssql: server:2017-latest + - php: 7.3 + extensions: pdo, pdo_sqlsrv-5.8.1 + mssql: server:2017-latest + - php: 7.4 + extensions: pdo, pdo_sqlsrv + mssql: server:2017-latest + - php: 7.4 + extensions: pdo, pdo_sqlsrv + mssql: server:2019-latest + - php: 8.0 + extensions: pdo, pdo_sqlsrv + mssql: server:2017-latest + - php: 8.0 + extensions: pdo, pdo_sqlsrv + mssql: server:2019-latest + + services: + mssql: + image: mcr.microsoft.com/mssql/${{ matrix.mssql }} + env: + SA_PASSWORD: YourStrong!Passw0rd + ACCEPT_EULA: Y + MSSQL_PID: Developer + ports: + - 1433:1433 + options: --name=mssql --health-cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'YourStrong!Passw0rd' -Q 'SELECT 1'" --health-interval=10s --health-timeout=5s --health-retries=3 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Create MS SQL Database + run: docker exec -i mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'YourStrong!Passw0rd' -Q 'CREATE DATABASE yiitest' + + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: ${{ matrix.extensions }} + ini-values: date.timezone='UTC' + tools: composer:v2, pecl + + - name: Determine composer cache directory on Linux + run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php }}-composer- + + - name: Update composer + run: composer self-update + + - name: Install dependencies with composer + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Install dependencies with composer php 8.0 + if: matrix.php == '8.0' + run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: PHP Unit tests for PHP 7.1 + run: vendor/bin/phpunit --coverage-clover=coverage.clover --group mssql --colors=always + if: matrix.php == '7.1' + + - name: Run tests with phpunit without coverage + run: vendor/bin/phpunit --group mssql --colors=always + + - name: Code coverage + run: | + wget https://scrutinizer-ci.com/ocular.phar + php ocular.phar code-coverage:upload --format=php-clover coverage.clover + if: matrix.php == '7.1' + continue-on-error: true # if is fork diff --git a/.github/workflows/ci-mysql.yml b/.github/workflows/ci-mysql.yml index de0a5e1a44f..639609b0e84 100644 --- a/.github/workflows/ci-mysql.yml +++ b/.github/workflows/ci-mysql.yml @@ -19,10 +19,10 @@ jobs: - ubuntu-latest php-version: - - "7.4" + - 7.4 mysql-version: - - "latest" + - latest services: mysql: @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup cache environment id: cache-env @@ -47,7 +47,7 @@ jobs: key: ${{ env.key }} - name: Cache extensions - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ steps.cache-env.outputs.dir }} key: ${{ steps.cache-env.outputs.key }} diff --git a/.github/workflows/ci-oracle.yml b/.github/workflows/ci-oracle.yml new file mode 100644 index 00000000000..d6c9db0f428 --- /dev/null +++ b/.github/workflows/ci-oracle.yml @@ -0,0 +1,81 @@ +on: + - pull_request + - push + +name: ci-oracle + +jobs: + tests: + name: PHP ${{ matrix.php }}-${{ matrix.os }} + + env: + extensions: oci8, pdo, pdo_oci + key: cache-v1 + + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: + - ubuntu-latest + + php: + - 7.4 + + services: + oci: + image: wnameless/oracle-xe-11g-r2:latest + ports: + - 1521:1521 + options: --name=oci + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup cache environment + id: cache-env + uses: shivammathur/cache-extensions@v1 + with: + php-version: ${{ matrix.php }} + extensions: ${{ env.extensions }} + key: ${{ env.key }} + + - name: Cache extensions + uses: actions/cache@v1 + with: + path: ${{ steps.cache-env.outputs.dir }} + key: ${{ steps.cache-env.outputs.key }} + restore-keys: ${{ steps.cache-env.outputs.key }} + + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: ${{ env.extensions }} + ini-values: date.timezone='UTC' + coverage: pcov + tools: composer:v2, pecl + + - name: Determine composer cache directory + run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php }}-composer- + + - name: Install dependencies with composer + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: PHP Unit tests + run: vendor/bin/phpunit --coverage-clover=coverage.clover --group oci --colors=always + + - name: Code coverage + run: | + wget https://scrutinizer-ci.com/ocular.phar + php ocular.phar code-coverage:upload --format=php-clover coverage.clover + continue-on-error: true # if is fork diff --git a/.github/workflows/ci-pgsql.yml b/.github/workflows/ci-pgsql.yml index b934f6ab791..7bfa4d44659 100644 --- a/.github/workflows/ci-pgsql.yml +++ b/.github/workflows/ci-pgsql.yml @@ -19,13 +19,14 @@ jobs: - ubuntu-latest php-version: - - "7.4" + - 7.4 pgsql-version: - - "10" - - "11" - - "12" - - "13" + - 10 + - 11 + - 12 + - 13 + - 14 services: postgres: @@ -40,7 +41,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup cache environment id: cache-env @@ -70,7 +71,7 @@ jobs: run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV - name: Cache dependencies installed with composer - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ${{ env.COMPOSER_CACHE_DIR }} key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} diff --git a/.gitignore b/.gitignore index 769d4053ba4..02326c0cb90 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ phpunit.phar # NPM packages /node_modules .env +package-lock.json diff --git a/.php_cs b/.php_cs index 8550239097a..0350dff093c 100644 --- a/.php_cs +++ b/.php_cs @@ -1,7 +1,7 @@ SERVICE_IP:12345 + - 3306 + + # If your service writes data to disk like most databases do, you can significantly + # speed up tests by mounting a ramdisk at those paths. + ramdisks: + - /var/lib/data + + db-pgsql: + image: postgres:14 + + # Define any additional environment variables that are needed by the service. + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: yiitest + + # We automatically forward these ports from your localhost to the service's port. + # Alternatively, you can also access the service on the "$SERVICE_SOME_NAME_IP" + # environment variable. + ports: + # Forward 127.0.0.1:12345 -> SERVICE_IP:12345 + - 5432 + + # If your service writes data to disk like most databases do, you can significantly + # speed up tests by mounting a ramdisk at those paths. + ramdisks: + - /var/lib/data + + memcached: + image: memcached + + tests: + before: + - sudo locale-gen fr_FR.UTF-8 + + override: + - command: ./vendor/bin/phpunit --verbose --exclude-group cubrid,oci,mssql,wincache,xcache,zenddata --colors=always --coverage-clover ./coverage.xml + on_node: 1 + coverage: + file: coverage.xml + format: php-clover diff --git a/README.md b/README.md index 53b565a998c..2bcf182fab8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- Yii Framework + Yii Framework

@@ -19,7 +19,7 @@ Installation ------------ - The minimum required PHP version of Yii is PHP 5.4. -- It works best with PHP 7. +- It works best with PHP 8. - [Follow the Definitive Guide](https://www.yiiframework.com/doc-2.0/guide-start-installation.html) in order to get step by step instructions. diff --git a/build/controllers/DevController.php b/build/controllers/DevController.php index 8962cbecfae..b1ac12854be 100644 --- a/build/controllers/DevController.php +++ b/build/controllers/DevController.php @@ -16,8 +16,8 @@ /** * This command helps to set up a dev environment with all extensions and applications. * - * It will clone an extension or app repo and link the yii2 dev installation to the containted applications/extensions vendor dirs - * to help working on yii using the application to test it. + * It will clone an extension or app repo and link the yii2 dev installation to the contained applications/extensions vendor dirs + * to help to work on yii using the application to test it. * * @author Carsten Brandt * @since 2.0 @@ -29,7 +29,7 @@ class DevController extends Controller */ public $defaultAction = 'all'; /** - * @var bool whether to use HTTP when cloning github repositories + * @var bool whether to use HTTP when cloning GitHub repositories */ public $useHttp = false; /** @@ -52,7 +52,7 @@ class DevController extends Controller 'authclient' => 'git@github.com:yiisoft/yii2-authclient.git', 'bootstrap' => 'git@github.com:yiisoft/yii2-bootstrap.git', 'bootstrap4' => 'git@github.com:yiisoft/yii2-bootstrap4.git', - 'codeception' => 'git@github.com:yiisoft/yii2-codeception.git', + 'bootstrap5' => 'git@github.com:yiisoft/yii2-bootstrap5.git', 'composer' => 'git@github.com:yiisoft/yii2-composer.git', 'debug' => 'git@github.com:yiisoft/yii2-debug.git', 'elasticsearch' => 'git@github.com:yiisoft/yii2-elasticsearch.git', @@ -68,6 +68,7 @@ class DevController extends Controller 'smarty' => 'git@github.com:yiisoft/yii2-smarty.git', 'sphinx' => 'git@github.com:yiisoft/yii2-sphinx.git', 'swiftmailer' => 'git@github.com:yiisoft/yii2-swiftmailer.git', + 'symfonymailer' => 'git@github.com:yiisoft/yii2-symfonymailer.git', 'twig' => 'git@github.com:yiisoft/yii2-twig.git', ]; @@ -335,7 +336,7 @@ protected function listSubDirs($dir) continue; } // ignore hidden directories - if ($file[0] === '.') { + if (strpos($file, '.') === 0) { continue; } if (is_dir("$dir/$file")) { diff --git a/build/controllers/MimeTypeController.php b/build/controllers/MimeTypeController.php index 5645e88554c..693a97cc6e6 100644 --- a/build/controllers/MimeTypeController.php +++ b/build/controllers/MimeTypeController.php @@ -30,6 +30,7 @@ class MimeTypeController extends Controller * @var array MIME type aliases */ private $aliases = [ + 'text/rtf' => 'application/rtf', 'text/xml' => 'application/xml', 'image/svg' => 'image/svg+xml', 'image/x-bmp' => 'image/bmp', @@ -85,7 +86,7 @@ private function generateMimeTypesFile($outFile, $content) $mimeMap = []; foreach (explode("\n", $content) as $line) { $line = trim($line); - if (empty($line) || $line[0] === '#') { // skip comments and empty lines + if (empty($line) || strpos($line, '#') === 0) { // skip comments and empty lines continue; } $parts = preg_split('/\s+/', $line); @@ -99,6 +100,11 @@ private function generateMimeTypesFile($outFile, $content) $mimeMap = array_merge($mimeMap, $this->additionalMimeTypes); ksort($mimeMap); $array = VarDumper::export($mimeMap); + + if (PHP_VERSION_ID >= 80100) { + $array = array_replace($array, array('xz' => 'application/octet-stream')); + } + $content = << * @author Alexander Makarov @@ -329,16 +329,16 @@ protected function fixDocBlockIndentation(&$lines) $tag = false; } elseif ($docBlock) { $line = ltrim($line); - if (isset($line[0]) && $line[0] === '*') { + if (strpos($line, '*') === 0) { $line = substr($line, 1); } - if (isset($line[0]) && $line[0] === ' ') { + if (strpos($line, ' ') === 0) { $line = substr($line, 1); } $docLine = str_replace("\t", ' ', rtrim($line)); if (empty($docLine)) { $listIndent = ''; - } elseif ($docLine[0] === '@') { + } elseif (strpos($docLine, '@') === 0) { $listIndent = ''; $codeBlock = false; $tag = true; @@ -453,15 +453,15 @@ protected function fixLineSpacing($lines) $endofPrivate = $i; $property = 'Private'; $level = 0; - } elseif (substr($line, 0, 6) === 'const ') { + } elseif (strpos($line, 'const ') === 0) { $endofConst = $i; $property = false; - } elseif (substr($line, 0, 4) === 'use ') { + } elseif (strpos($line, 'use ') === 0) { $endofUse = $i; $property = false; - } elseif (!empty($line) && $line[0] === '*') { + } elseif (strpos($line, '*') === 0) { $property = false; - } elseif (!empty($line) && $line[0] !== '*' && strpos($line, 'function ') !== false || $line === '}') { + } elseif (strpos($line, '*') !== 0 && strpos($line, 'function ') !== false || $line === '}') { break; } @@ -733,19 +733,17 @@ protected function generateClassPropertyDocs($fileName) $docLine = ' * @property'; $note = ''; if (isset($prop['get'], $prop['set'])) { - if ($prop['get']['type'] != $prop['set']['type']) { + if ($prop['get']['type'] !== $prop['set']['type']) { $note = ' Note that the type of this property differs in getter and setter.' - . ' See [[get' . ucfirst($propName) . '()]] ' + . ' See [[get' . ucfirst($propName) . '()]]' . ' and [[set' . ucfirst($propName) . '()]] for details.'; } } elseif (isset($prop['get'])) { if (!$this->hasSetterInParents($className, $propName)) { - $note = ' This property is read-only.'; $docLine .= '-read'; } } elseif (isset($prop['set'])) { if (!$this->hasGetterInParents($className, $propName)) { - $note = ' This property is write-only.'; $docLine .= '-write'; } } else { @@ -754,7 +752,7 @@ protected function generateClassPropertyDocs($fileName) $docLine .= ' ' . $this->getPropParam($prop, 'type') . " $$propName "; $comment = explode("\n", $this->getPropParam($prop, 'comment') . $note); foreach ($comment as &$cline) { - $cline = ltrim($cline, '* '); + $cline = ltrim(rtrim($cline), '* '); } $docLine = wordwrap($docLine . implode(' ', $comment), 110, "\n * ") . "\n"; @@ -797,7 +795,7 @@ protected function fixSentence($str) 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) @@ -826,11 +824,17 @@ private function hash($string) protected function hasGetterInParents($className, $propName) { $class = $className; - while ($parent = get_parent_class($class)) { - if (method_exists($parent, 'get' . ucfirst($propName))) { - return true; + + try { + while ($parent = get_parent_class($class)) { + if (method_exists($parent, 'get' . ucfirst($propName))) { + return true; + } + $class = $parent; } - $class = $parent; + } catch (\Throwable $t) { + $this->stderr("[ERR] Error when getting parents for $className\n", Console::FG_RED); + return false; } return false; } @@ -843,11 +847,17 @@ protected function hasGetterInParents($className, $propName) protected function hasSetterInParents($className, $propName) { $class = $className; - while ($parent = get_parent_class($class)) { - if (method_exists($parent, 'set' . ucfirst($propName))) { - return true; + + try { + while ($parent = get_parent_class($class)) { + if (method_exists($parent, 'set' . ucfirst($propName))) { + return true; + } + $class = $parent; } - $class = $parent; + } catch (\Throwable $t) { + $this->stderr("[ERR] Error when getting parents for $className\n", Console::FG_RED); + return false; } return false; } @@ -859,11 +869,11 @@ protected function hasSetterInParents($className, $propName) */ protected function isBaseObject($className, \ReflectionClass $ref) { - $isDepreceatedObject = false; + $isDeprecatedObject = false; if (PHP_VERSION_ID <= 70100) { - $isDepreceatedObject = $ref->isSubclassOf('yii\base\Object') || $className === 'yii\base\Object'; + $isDeprecatedObject = $ref->isSubclassOf('yii\base\Object') || $className === 'yii\base\Object'; } - return !$isDepreceatedObject && !$ref->isSubclassOf('yii\base\BaseObject') && $className !== 'yii\base\BaseObject'; + return !$isDeprecatedObject && !$ref->isSubclassOf('yii\base\BaseObject') && $className !== 'yii\base\BaseObject'; } private function shouldSkipClass($className) diff --git a/build/controllers/ReleaseController.php b/build/controllers/ReleaseController.php index e3d1765a993..1d73fa5f6d8 100644 --- a/build/controllers/ReleaseController.php +++ b/build/controllers/ReleaseController.php @@ -15,7 +15,7 @@ use yii\helpers\FileHelper; /** - * ReleaseController is there to help preparing releases. + * ReleaseController is there to help to prepare releases. * * Get a version overview: * @@ -53,7 +53,7 @@ class ReleaseController extends Controller */ public $dryRun = false; /** - * @var bool whether to fetch latest tags. + * @var bool whether to fetch the latest tags. */ public $update = false; /** @@ -206,7 +206,7 @@ public function actionRelease(array $what) $newVersions[$k] = $this->version; } } else { - // otherwise get next patch or minor + // otherwise, get next patch or minor $newVersions = $this->getNextVersions($versions, self::PATCH); } @@ -629,7 +629,7 @@ protected function releaseApplication($name, $path, $version) $this->stdout("\n\nThe following steps are left for you to do manually:\n\n"); $nextVersion2 = $this->getNextVersions($nextVersion, self::PATCH); // TODO support other versions $this->stdout("- close the $version milestone on github and open new ones for {$nextVersion["app-$name"]} and {$nextVersion2["app-$name"]}: https://github.com/yiisoft/yii2-app-$name/milestones\n"); - $this->stdout("- Create Application packages and upload them to framework releast at github: ./build/build release/package app-$name\n"); + $this->stdout("- Create Application packages and upload them to framework release at github: ./build/build release/package app-$name\n"); $this->stdout("\n"); } @@ -803,7 +803,7 @@ protected function gitFetchTags($path) try { chdir($path); } catch (\yii\base\ErrorException $e) { - throw new Exception('Failed to getch git tags in ' . $path . ': ' . $e->getMessage()); + throw new Exception('Failed to fetch git tags in ' . $path . ': ' . $e->getMessage()); } exec('git fetch --tags', $output, $ret); if ($ret != 0) { diff --git a/build/controllers/TranslationController.php b/build/controllers/TranslationController.php index 0200ad9f0fa..dd89ad24ea9 100644 --- a/build/controllers/TranslationController.php +++ b/build/controllers/TranslationController.php @@ -29,7 +29,6 @@ class TranslationController extends Controller * @param string $sourcePath the directory where the original documentation files are * @param string $translationPath the directory where the translated documentation files are * @param string $title custom title to use for report - * @return string */ public function actionReport($sourcePath, $translationPath, $title = 'Translation report') { @@ -126,11 +125,11 @@ public function highlightDiff($diff) { $lines = explode("\n", $diff); foreach ($lines as $key => $val) { - if (mb_substr($val, 0, 1, 'utf-8') === '@') { + if (strpos($val, '@') === 0) { $lines[$key] = '' . Html::encode($val) . ''; - } elseif (mb_substr($val, 0, 1, 'utf-8') === '+') { + } elseif (strpos($val, '+') === 0) { $lines[$key] = '' . Html::encode($val) . ''; - } elseif (mb_substr($val, 0, 1, 'utf-8') === '-') { + } elseif (strpos($val, '-') === 0) { $lines[$key] = '' . Html::encode($val) . ''; } else { $lines[$key] = Html::encode($val); diff --git a/build/controllers/Utf8Controller.php b/build/controllers/Utf8Controller.php index ca5175dbfd6..673d9bfdeeb 100644 --- a/build/controllers/Utf8Controller.php +++ b/build/controllers/Utf8Controller.php @@ -69,11 +69,11 @@ public function actionCheckGuide($directory = null) } if ($ord < 0x0020 && $ord != 0x000A && $ord != 0x0009 || 0x0080 <= $ord && $ord < 0x009F) { - $this->found('CONTROL CHARARCTER', $c, $line, $pos, $file); + $this->found('CONTROL CHARACTER', $c, $line, $pos, $file); continue; } // if ($ord > 0x009F) { -// $this->found("NON ASCII CHARARCTER", $c, $line, $pos, $file); +// $this->found("NON ASCII CHARACTER", $c, $line, $pos, $file); // continue; // } } diff --git a/code-of-conduct.md b/code-of-conduct.md index 82fdef14465..4428c7b15e4 100644 --- a/code-of-conduct.md +++ b/code-of-conduct.md @@ -62,7 +62,7 @@ the project's leadership. This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4.0, available at -[http://contributor-covenant.org/version/1/4/][version] +[https://contributor-covenant.org/version/1/4/][version] -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ +[homepage]: https://contributor-covenant.org +[version]: https://contributor-covenant.org/version/1/4/ diff --git a/composer.json b/composer.json index ced9703ef4d..78ffddbb17c 100644 --- a/composer.json +++ b/composer.json @@ -5,20 +5,20 @@ "yii2", "framework" ], - "homepage": "http://www.yiiframework.com/", + "homepage": "https://www.yiiframework.com/", "type": "yii2-extension", "license": "BSD-3-Clause", "authors": [ { "name": "Qiang Xue", "email": "qiang.xue@gmail.com", - "homepage": "http://www.yiiframework.com/", + "homepage": "https://www.yiiframework.com/", "role": "Founder and project lead" }, { "name": "Alexander Makarov", "email": "sam@rmcreative.ru", - "homepage": "http://rmcreative.ru/", + "homepage": "https://rmcreative.ru/", "role": "Core framework development" }, { @@ -29,7 +29,7 @@ { "name": "Carsten Brandt", "email": "mail@cebe.cc", - "homepage": "http://cebe.cc/", + "homepage": "https://www.cebe.cc/", "role": "Core framework development" }, { @@ -57,9 +57,9 @@ ], "support": { "issues": "https://github.com/yiisoft/yii2/issues?state=open", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "minimum-stability": "dev", @@ -75,10 +75,11 @@ "yiisoft/yii2-composer": "~2.0.4", "ezyang/htmlpurifier": "~4.6", "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", - "bower-asset/jquery": "3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", + "bower-asset/jquery": "3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", "bower-asset/inputmask": "~3.2.2 | ~3.3.5", "bower-asset/punycode": "1.3.*", - "bower-asset/yii2-pjax": "~2.0.1" + "bower-asset/yii2-pjax": "~2.0.1", + "paragonie/random_compat": ">=1" }, "require-dev": { "cweagans/composer-patches": "^1.7", @@ -98,12 +99,22 @@ }, "autoload": { "psr-4": { - "yii\\": "framework/", - "yii\\cs\\": "cs/src/" + "yii\\": "framework/" + } + }, + "autoload-dev": { + "psr-4": { + "yii\\cs\\": "cs/src/", + "yii\\build\\": "build/", + "yiiunit\\": "tests/" } }, "config": { - "platform": {"php": "5.4"} + "platform": {"php": "5.4"}, + "allow-plugins": { + "cweagans/composer-patches": true, + "yiisoft/yii2-composer": true + } }, "bin": [ "framework/yii" @@ -117,9 +128,13 @@ "phpunit/phpunit-mock-objects": { "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch" }, + "phpunit/php-file-iterator": { + "Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_path_file_iterator.patch" + }, "phpunit/phpunit": { "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch", - "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch" + "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch", + "Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php81.patch" } } } diff --git a/composer.lock b/composer.lock index 654dae1084e..9837fbe353e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6282c196c2380b0d30b7104eccef989a", + "content-hash": "a9d10c9948017f8926d64be83e5e2397", "packages": [ { "name": "bower-asset/inputmask", @@ -29,16 +29,16 @@ }, { "name": "bower-asset/jquery", - "version": "3.5.1", + "version": "3.6.0", "source": { "type": "git", - "url": "git@github.com:jquery/jquery-dist.git", - "reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215" + "url": "https://github.com/jquery/jquery-dist.git", + "reference": "e786e3d9707ffd9b0dd330ca135b66344dcef85a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/4c0e4becb8263bb5b3e6dadc448d8e7305ef8215", - "reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215" + "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/e786e3d9707ffd9b0dd330ca135b66344dcef85a", + "reference": "e786e3d9707ffd9b0dd330ca135b66344dcef85a" }, "type": "bower-asset", "license": [ @@ -50,28 +50,28 @@ "version": "v1.3.2", "source": { "type": "git", - "url": "git@github.com:bestiejs/punycode.js.git", + "url": "https://github.com/mathiasbynens/punycode.js.git", "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", + "url": "https://api.github.com/repos/mathiasbynens/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" }, "type": "bower-asset" }, { "name": "bower-asset/yii2-pjax", - "version": "v2.0.7", + "version": "2.0.7.1", "source": { "type": "git", "url": "https://github.com/yiisoft/jquery-pjax.git", - "reference": "885fc8c2d36c93a801b6af0ee8ad55d79df97cb1" + "reference": "aef7b953107264f00234902a3880eb50dafc48be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/885fc8c2d36c93a801b6af0ee8ad55d79df97cb1", - "reference": "885fc8c2d36c93a801b6af0ee8ad55d79df97cb1" + "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/aef7b953107264f00234902a3880eb50dafc48be", + "reference": "aef7b953107264f00234902a3880eb50dafc48be" }, "require": { "bower-asset/jquery": ">=1.8" @@ -147,32 +147,29 @@ }, { "name": "ezyang/htmlpurifier", - "version": "v4.13.0", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75" + "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75", - "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75", + "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75", "shasum": "" }, "require": { "php": ">=5.2" }, - "require-dev": { - "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd" - }, "type": "library", "autoload": { - "psr-0": { - "HTMLPurifier": "library/" - }, "files": [ "library/HTMLPurifier.composer.php" ], + "psr-0": { + "HTMLPurifier": "library/" + }, "exclude-from-classmap": [ "/library/HTMLPurifier/Language/" ] @@ -195,9 +192,63 @@ ], "support": { "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/master" + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0" + }, + "time": "2021-12-25T01:21:49+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.21", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/96c132c7f2f7bc3230723b66e89f8f150b29d5ae", + "reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" }, - "time": "2020-06-29T00:56:53+00:00" + "time": "2022-02-16T17:07:03+00:00" }, { "name": "yiisoft/yii2-composer", @@ -316,20 +367,20 @@ }, { "name": "composer/semver", - "version": "1.7.1", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "38276325bd896f90dfcfe30029aa5db40df387a7" + "reference": "647490bbcaf7fc4891c58f47b825eb99d19c377a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/38276325bd896f90dfcfe30029aa5db40df387a7", - "reference": "38276325bd896f90dfcfe30029aa5db40df387a7", + "url": "https://api.github.com/repos/composer/semver/zipball/647490bbcaf7fc4891c58f47b825eb99d19c377a", + "reference": "647490bbcaf7fc4891c58f47b825eb99d19c377a", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^4.5 || ^5.0.5" @@ -376,7 +427,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/1.7.1" + "source": "https://github.com/composer/semver/tree/1.7.2" }, "funding": [ { @@ -392,20 +443,20 @@ "type": "tidelift" } ], - "time": "2020-09-27T13:13:07+00:00" + "time": "2020-12-03T15:47:16+00:00" }, { "name": "composer/xdebug-handler", - "version": "1.4.4", + "version": "1.4.6", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba" + "reference": "f27e06cd9675801df441b3656569b328e04aa37c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6e076a124f7ee146f2487554a94b6a19a74887ba", - "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f27e06cd9675801df441b3656569b328e04aa37c", + "reference": "f27e06cd9675801df441b3656569b328e04aa37c", "shasum": "" }, "require": { @@ -413,7 +464,8 @@ "psr/log": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "autoload": { @@ -439,7 +491,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/1.4.4" + "source": "https://github.com/composer/xdebug-handler/tree/1.4.6" }, "funding": [ { @@ -455,20 +507,20 @@ "type": "tidelift" } ], - "time": "2020-10-24T12:39:10+00:00" + "time": "2021-03-25T17:01:18+00:00" }, { "name": "cweagans/composer-patches", - "version": "1.7.0", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/cweagans/composer-patches.git", - "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf" + "reference": "e9969cfc0796e6dea9b4e52f77f18e1065212871" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/ae02121445ad75f4eaff800cc532b5e6233e2ddf", - "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/e9969cfc0796e6dea9b4e52f77f18e1065212871", + "reference": "e9969cfc0796e6dea9b4e52f77f18e1065212871", "shasum": "" }, "require": { @@ -501,9 +553,9 @@ "description": "Provides a way to patch Composer packages.", "support": { "issues": "https://github.com/cweagans/composer-patches/issues", - "source": "https://github.com/cweagans/composer-patches/tree/1.7.0" + "source": "https://github.com/cweagans/composer-patches/tree/1.7.2" }, - "time": "2020-09-30T17:56:20+00:00" + "time": "2022-01-25T19:21:20+00:00" }, { "name": "doctrine/annotations", @@ -890,60 +942,6 @@ }, "time": "2015-09-13T19:01:00+00:00" }, - { - "name": "paragonie/random_compat", - "version": "v2.0.19", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/446fc9faa5c2a9ddf65eb7121c0af7e857295241", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241", - "shasum": "" - }, - "require": { - "php": ">=5.2.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "autoload": { - "files": [ - "lib/random.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "time": "2020-10-15T10:06:57+00:00" - }, { "name": "phpdocumentor/reflection-docblock", "version": "2.0.5", @@ -1475,16 +1473,16 @@ }, { "name": "psr/log", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { @@ -1508,7 +1506,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -1519,9 +1517,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.3" + "source": "https://github.com/php-fig/log/tree/1.1.4" }, - "time": "2020-03-23T09:12:05+00:00" + "time": "2021-05-03T11:20:27+00:00" }, { "name": "sebastian/comparator", @@ -2303,12 +2301,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2382,12 +2380,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2459,12 +2457,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php54\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2539,12 +2537,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Php55\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2616,12 +2614,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2695,12 +2693,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2918,5 +2916,5 @@ "platform-overrides": { "php": "5.4" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.2.0" } diff --git a/cs/src/YiiConfig.php b/cs/src/YiiConfig.php index 4e2e28ff703..95442861a4e 100644 --- a/cs/src/YiiConfig.php +++ b/cs/src/YiiConfig.php @@ -156,7 +156,7 @@ public function __construct($name = 'yii-cs-config') } /** - * Merge current rules config with provided list of rules. + * Merge current rules' config with provided list of rules. * * @param array $rules * @return $this diff --git a/docs/guide-ar/README.md b/docs/guide-ar/README.md index 11b9e4272cf..2134d2b9421 100644 --- a/docs/guide-ar/README.md +++ b/docs/guide-ar/README.md @@ -1,7 +1,7 @@ Yii 2.0 الدليل التقني الخاص ببيئة العمل =============================== -تم تحرير هذا الملف اعتمادا على [الشروط الخاصة بتوثيف ال Yii](http://www.yiiframework.com/doc/terms/). +تم تحرير هذا الملف اعتمادا على [الشروط الخاصة بتوثيف ال Yii](https://www.yiiframework.com/doc/terms/). جميع الحقوق محفوظة diff --git a/docs/guide-ar/intro-yii.md b/docs/guide-ar/intro-yii.md index 7177d094b8a..bff073a5c4f 100644 --- a/docs/guide-ar/intro-yii.md +++ b/docs/guide-ar/intro-yii.md @@ -17,6 +17,7 @@ Yii هو إطار عام لبرمجة الويب ، مما يعني أنه يم

إذا كنت بالفعل على دراية بإطار العمل الأخرى ، فيمكنك معرفة كيف تتم مقارنة ال Yii: +

  • مثل معظم أطر عمل ال PHP ، يطبق Yii النمط المعماري MVC (Model-View-Controller).
  • @@ -25,10 +26,9 @@ Yii هو إطار عام لبرمجة الويب ، مما يعني أنه يم
  • من مميزات ال Yii إمكانية التعديل (استبدال جزء معين أو تخيصيص وإضافة) جزء معين على أغلب ال Yii core code، وبالإضافة الى هذا، يمكنك بناء ملحقات برمجية اعتمادا على ال core code، ومن ثم نشر هذه الشيفرة وتوزيعها واستخدامها دون وجود أي مشاكل أو صعوبة تذكر.
  • الأداء العالي هو الهدف الأساسي من ال Yii.
-

-ال Yii إطار عمل صمم من قبل فريق برمجي متكامل، فهو ليس مجرد عمل فردي ، بل يتكون من فريق تطوير أساسي وقوي(http://www.yiiframework.com/team/) ، بالإضافة إلى منتدى كبير +ال Yii إطار عمل صمم من قبل فريق برمجي متكامل، فهو ليس مجرد عمل فردي ، بل يتكون من فريق تطوير أساسي وقوي ، بالإضافة إلى منتدى كبير من المهنيين الذين يساهمون باستمرار في تطوير هذا الإطار. فريق المطورين الخاص بال Yii يراقب عن كثب أحدث اتجاهات تطوير الويب وأفضل الممارسات والمميزات التي وجدت في الأطر والمشاريع الأخرى. وتدرج بانتظام بإضافة أفضل الممارسات والميزات الى ال Yii عبر واجهات بسيطة وأنيقة. @@ -44,13 +44,11 @@ Yii هو إطار عام لبرمجة الويب ، مما يعني أنه يم #

المتطلبات الأساسية للعمل على إطار ال Yii
-

-

    -
  • الإصدار PHP 5.4.0 أو أكثر
  • -
  • المعرفة الأساسية بمفاهيم البرمجة كائنية التوجه OOP
  • -
  • المعرفة بآخر وأحدث التقنيات الموجودة بال php مثل ال namespaces, traits، الفهم لهذه المفاهيم سيسهل عليك العمل كثيرا
  • -
-

+
    +
  • الإصدار PHP 5.4.0 أو أكثر
  • +
  • المعرفة الأساسية بمفاهيم البرمجة كائنية التوجه OOP
  • +
  • المعرفة بآخر وأحدث التقنيات الموجودة بال php مثل ال namespaces, traits، الفهم لهذه المفاهيم سيسهل عليك العمل كثيرا
  • +

ملاحظة: يمكن التحقق من توافق المتطلبات الخاصة بك مع ال yii من خلال الدخول الى الصفحة requirement الموجودة بال yii diff --git a/docs/guide-ar/start-databases.md b/docs/guide-ar/start-databases.md index 28161a82455..883595e3d8d 100644 --- a/docs/guide-ar/start-databases.md +++ b/docs/guide-ar/start-databases.md @@ -60,7 +60,7 @@ INSERT INTO `country` VALUES ('US','United States',322976000); ##

إعدادات الإتصال الخاصة بقواعد البيانات - Configuring a DB Connection

- قبل أن تكمل الشرح، تأكد من تثبيت ال PHP PDO وال PDO driver، بالنسبة لهذا المثال، فإننا سنستخدم ال driver الخاص بال MySql وهو ال pdo_mysql، وهذه هي المتطلبات الأساسية لبناء أي التطبيق اذا كان التطبيق يستخدم ال relational database. + قبل أن تكمل الشرح، تأكد من تثبيت ال PHP PDO وال PDO driver، بالنسبة لهذا المثال، فإننا سنستخدم ال driver الخاص بال MySql وهو ال pdo_mysql، وهذه هي المتطلبات الأساسية لبناء أي التطبيق اذا كان التطبيق يستخدم ال relational database.

@@ -68,7 +68,7 @@ INSERT INTO `country` VALUES ('US','United States',322976000); كما يمكنك تفعيل ال driver المطلوب عن طريق حذف الفاصلة المنقوطة قبل ال driver المقصود مثل: extension=php_pdo_mysql.dll ويمكنك الإطلاع على المزيد من هنا: -pdo installation +pdo installation

@@ -112,7 +112,7 @@ return [

  • MariaDB
  • -##
    إنشاء ال Active Record +##
    إنشاء ال Active Record

    لجلب البيانات وعرضها من جدول ال country، سنقوم بإضافة ال Active Record الى ال class المسمى ب country، والموجود في المسار models/Country.php. @@ -163,7 +163,7 @@ $country->save(); ستجد معلومات أكثر تفصيلاً في الجزء الخاص بال Active Record. بالإضافة الى ذلك، يمكنك التفاعل مباشرة مع قاعدة البيانات باستخدام lower-level data accessing والتي تسمى ب Database Access Objects.

    -##
    إنشاء ال Action +##
    إنشاء ال Action

    لعرض بيانات ال country للمستخدمين، يلزمك إنشاء action جديد، وبدلاً من وضع ال action الجديد في ال site controller كما فعلنا في المرات السابقة، سنقوم بإنشاء controller جديد، ومن ثم سنقوم بوضع ال action بداخله، والسبب المنطقي لهذا العمل أنك ستقوم بتجميع الشيفرة البرمجية المسؤولة عن أداء وظائف معينة في مكان واحد، وبهذا فإن جميع الإجرائات التي تخص ال country من المنطقي أن تكون موجودة داخل ال CountryController، والآن لنقم بإنشاء هذا ال controller الجديد، وال action الجديد وسيكون باسم index، كما هو موضح أدناه: diff --git a/docs/guide-ar/start-forms.md b/docs/guide-ar/start-forms.md index 2383fe52089..e607a1fcc5b 100644 --- a/docs/guide-ar/start-forms.md +++ b/docs/guide-ar/start-forms.md @@ -135,7 +135,7 @@ class SiteController extends Controller

    -ملاحظة: في هذا المثال البسيط، نعرض صفحة التأكيد فقط عند إرسال البيانات بشكل صحيح. عند الممارسة العملية، يجب عليك استخدام [[yii\web\Controller::refresh()|refresh()]] أو [[yii\web\Controller::redirect()|redirect()]] لتجنب أي مشكلة تحصل عن طريق ال resubmission والتي تندرج تحت العنوان form resubmission problems. +ملاحظة: في هذا المثال البسيط، نعرض صفحة التأكيد فقط عند إرسال البيانات بشكل صحيح. عند الممارسة العملية، يجب عليك استخدام [[yii\web\Controller::refresh()|refresh()]] أو [[yii\web\Controller::redirect()|redirect()]] لتجنب أي مشكلة تحصل عن طريق ال resubmission والتي تندرج تحت العنوان form resubmission problems.

    ##
    إنشاء ال views
    diff --git a/docs/guide-ar/start-gii.md b/docs/guide-ar/start-gii.md index 2d8c59eb8d2..0dd7f11943b 100644 --- a/docs/guide-ar/start-gii.md +++ b/docs/guide-ar/start-gii.md @@ -12,10 +12,10 @@
  • تفعيل ال Gii داخل التطبيق الخاص بك
  • إستخدام ال Gii لإنشاء ال Active Record class
  • إستخدام ال Gii لإنشاء الشيفرة البرمجية الخاصة بال CRUD إعتمادا على الجداول الموجودة في قاعدة البيانات
  • -
  • تخصيص (custmize) الشيفرة البرمجية التي سيتم إنتاجها من خلال ال Gii.
  • +
  • تخصيص (customize) الشيفرة البرمجية التي سيتم إنتاجها من خلال ال Gii.
  • -##
    البدء باستخدام ال Gii +##
    البدء باستخدام ال Gii

    يتم تقديم ال Gii داخل على ال Yii على أنه module، ويمكنك تفعيله من خلال الإعدادات الخاصة به والتي تجدها داخل ال application، وبالتحديد داخل ال property التالية [[yii\base\Application::modules|modules]]، واعتمادا على كيفية إنشائك للمشروع، فيمكنك إيجاد الشيفرة البرمجية التالية موجودة بشكل مسبق داخل ال config/web.php: diff --git a/docs/guide-ar/start-hello.md b/docs/guide-ar/start-hello.md index cb855db9ea2..ddcb12f405c 100644 --- a/docs/guide-ar/start-hello.md +++ b/docs/guide-ar/start-hello.md @@ -25,9 +25,9 @@ لإنشاء صفحة "Hello"، ستقوم بإنشاء say action والذي بدوره سيقوم بقراءة ال message parameter من ال request، ومن ثم عرض ال message مرة أخرى إلى المستخدم. إذا كان ال request لا يحمل معه ال message parameter فإن ال action سيقوم بطباعة message إفتراضية وهي "Hello".

    -

    +

    معلومة: ال Actions هي الكائنات(objects) التي يمكن للمستخدمين من الوصول اليها وتنفيذ ما في بداخلها بشكل مباشر. يتم تجميع هذه ال Actions بواسطة ال controllers. ونتيجة لذلك فإن ال response الراجعة للمستخدم ستكون هي نتيجة التنفيذ الخاصة بال action. -

    +

    يجب تعريف ال actions داخل ال controller، ولتبسيط الفكرة، سنقوم بتعريف ال say action داخل أحد ال controller الموجود مسبقا وهو ال siteController. هذا ال controller ستجده داخل المسار controllers/siteController.php. ومن هنا سنبدأ بإضافة ال action الجديد: @@ -89,7 +89,7 @@ use yii\helpers\Html;

    - ملاحظة: في الشيفرة البرمجية أعلاه، تكون ال message مضمنة داخل ال [[yii\helpers\Html::encode()]] قبل أن يتم طباعتها، هذا الأمر ضروري لأن ال parameter التي تأتي من المستخدم النهائي لا يجب الوثوق بها، فهي يمكن أن تحتوي على شيفرات برمجية تستغل الضعف الحاص بك بموضوع الأمان مثل vulnerable to XSS attack عن طريق دمج JS code مع ال parameter. + ملاحظة: في الشيفرة البرمجية أعلاه، تكون ال message مضمنة داخل ال [[yii\helpers\Html::encode()]] قبل أن يتم طباعتها، هذا الأمر ضروري لأن ال parameter التي تأتي من المستخدم النهائي لا يجب الوثوق بها، فهي يمكن أن تحتوي على شيفرات برمجية تستغل الضعف الحاص بك بموضوع الأمان مثل vulnerable to XSS attack عن طريق دمج JS code مع ال parameter.

    diff --git a/docs/guide-ar/start-installation.md b/docs/guide-ar/start-installation.md index b8eb08af2c6..187ee325fdb 100644 --- a/docs/guide-ar/start-installation.md +++ b/docs/guide-ar/start-installation.md @@ -87,7 +87,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic يتضمن تثبيت Yii من ملف أرشيف ثلاث خطوات وهي:

      -
    1. تثبت الملف من خلال الموقع الرسمي yiiframework.com.
    2. +
    3. تثبت الملف من خلال الموقع الرسمي yiiframework.com.
    4. قم بفك ضغط الملف الذي تم تنزيله إلى مجلد يمكن الوصول إليه عبر الويب.
    5. قم بتعديل ملف config/web.php عن طريق إدخال secret key ل cookieValidationKey (يتم ذلك تلقائيًا إذا قمت بتثبيت ال Yii باستخدام Composer):
    6. @@ -121,7 +121,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic --------------------------

      - تعتمد ال Yii على حزم Bower و/أو NPM لتثبيت مكتبات ال (CSS و JavaScript). ويستخدم ال composer للحصول على هذه المكتبات ، مما يسمح بالحصول على إصدارات ال PHP و CSS/JavaScript في نفس الوقت. ويمكن تحقيق ذلك إما عن طريق استخدام asset-packagist.org أو من خلال ال composer asset plugin، يرجى الرجوع إلى Assets documentation لمزيد من التفاصيل. + تعتمد ال Yii على حزم Bower و/أو NPM لتثبيت مكتبات ال (CSS و JavaScript). ويستخدم ال composer للحصول على هذه المكتبات ، مما يسمح بالحصول على إصدارات ال PHP و CSS/JavaScript في نفس الوقت. ويمكن تحقيق ذلك إما عن طريق استخدام asset-packagist.org أو من خلال ال composer asset plugin، يرجى الرجوع إلى Assets documentation لمزيد من التفاصيل.

      قد ترغب في إدارة ال assets عبر ال native Bower/NPM أو استخدام ال CDN أو تجنب تثبيت ال assets بالكامل من حلال ال Composer ، ويمكن ذلك من خلال إضافة الأسطر التالية إلى "composer.json":

      @@ -143,7 +143,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic --------------------------

      - بعد الانتهاء من التثبيت، ستحتاج الى القيام بإعداد خادم الويب الخاص بك(your web server) (انظر القسم التالي) أو قم باستخدام built-in PHP web server عن طريق تنفيذ الأمر التالي داخل المسار web في المشروع الخاص بك: + بعد الانتهاء من التثبيت، ستحتاج الى القيام بإعداد خادم الويب الخاص بك(your web server) (انظر القسم التالي) أو قم باستخدام built-in PHP web server عن طريق تنفيذ الأمر التالي داخل المسار web في المشروع الخاص بك:

      ```bash @@ -179,7 +179,7 @@ http://localhost:8080/

      - يجب عليك أن تقوم بتثبيت وإعداد ال PHP الخاص بك بحيث تلبي الحد الأدنى من متطلبات ال Yii. الأهم من ذلك يجب أن يكون الإصدار الخاص بال PHP أعلى أو يساوي 5.4. من الناحية المثالية أحدث إصدار يعمل مع ال Yii هو ال PHP 7. يجب عليك أيضًا تثبيت ال PDO PHP Extension. + يجب عليك أن تقوم بتثبيت وإعداد ال PHP الخاص بك بحيث تلبي الحد الأدنى من متطلبات ال Yii. الأهم من ذلك يجب أن يكون الإصدار الخاص بال PHP أعلى أو يساوي 5.4. من الناحية المثالية أحدث إصدار يعمل مع ال Yii هو ال PHP 7. يجب عليك أيضًا تثبيت ال PDO PHP Extension.

      @@ -191,7 +191,7 @@ http://localhost:8080/

      - يجب أن يعمل التطبيق الذي تم تثبيته وفقًا للتعليمات المذكورة أعلاه مع أي من الخوادم ال Apache HTTP أو ال Nginx HTTP في كل من أنظمة التشغيل Windows, Mac OS X أو Linux ممن لديها إصدار أعلى أو يساوي PHP 5.4، كما أن ال Yii 2.0 متوافق مع ال Facebook HHVM، لكن، يجب أن تأخذ بعين الإعتبار أن ال HHVM يسلك في بعض الأحيان بطريقة مختلفة عن ال Native PHP، لذلك يجب أن تأخذ عناية إضافية عندما تعمل على ال HHVM. + يجب أن يعمل التطبيق الذي تم تثبيته وفقًا للتعليمات المذكورة أعلاه مع أي من الخوادم ال Apache HTTP أو ال Nginx HTTP في كل من أنظمة التشغيل Windows, Mac OS X أو Linux ممن لديها إصدار أعلى أو يساوي PHP 5.4، كما أن ال Yii 2.0 متوافق مع ال Facebook HHVM، لكن، يجب أن تأخذ بعين الإعتبار أن ال HHVM يسلك في بعض الأحيان بطريقة مختلفة عن ال Native PHP، لذلك يجب أن تأخذ عناية إضافية عندما تعمل على ال HHVM.

      @@ -244,7 +244,7 @@ DocumentRoot "path/to/basic/web" -----------------------

      - لاستخدام Nginx، يجب تثبيت PHP على أنه FPM SAPI، ويمكنك استخدام إعدادات ال Nginx التالية، مع الإنتباه على استبدال المسار من path/to/basic/web الى المسار الفعلي وصولا إلى basic/web بالإضافة الى إستبدال mysite.test إلى ال hostname الخاص بالتطبيق. + لاستخدام Nginx، يجب تثبيت PHP على أنه FPM SAPI، ويمكنك استخدام إعدادات ال Nginx التالية، مع الإنتباه على استبدال المسار من path/to/basic/web الى المسار الفعلي وصولا إلى basic/web بالإضافة الى إستبدال mysite.test إلى ال hostname الخاص بالتطبيق.

      diff --git a/docs/guide-ar/start-looking-ahead.md b/docs/guide-ar/start-looking-ahead.md index 8fccb9caa74..4b760f8dca6 100644 --- a/docs/guide-ar/start-looking-ahead.md +++ b/docs/guide-ar/start-looking-ahead.md @@ -12,25 +12,25 @@
    7. التوثيق
        -
      • The Definitive Guide - الدليل الشامل: كما يشير الإسم، فإن هذا الدليل يحدد آلية عمل ال Yii بدقة عالية، ويوفر إرشادات حول كيفية إستخدام ال Yii، هذا الجزء الأكثر أهمية في ال Yii، والذي يجب عليك قرائته قبل كتابة أي Yii code (ملاحظة: جزء البداية من هنا، والذي قمنا بدراسته هو أحد هذه الأجزاء، ومن أهمها للبدء بإنشاء التطبيقات من خلال ال Yii).
      • -
      • The Class Reference - المرجع الخاص بال Class في هذا الجزء يتم تحديد الية إستخدام كل Class يقدمه ال Yii، في العادة يتم إستخدام هذا المرجع عند كتابة شيفرة برمجية وأنت ترغب في فهم آلية العمل ل Class معين، أو Method, او فهم Proporty معينة...الخ، من الأفضل إستخدام المرجع الخاص بال Class فقط عند فهم آلية العمل لل Yii.
      • -
      • The Wiki Articles - مقالات الويكي مقالات الويكي هي مجموعة من الخبرات العملية للمستخدمين، تمت كتابتها ونشرها على شكل مقالات لمشاركة الخبرات، ومعظم هذه الكتابات تكون مثل الوصفات الخاصة بالطبخ، موجودة لخدمة هدف معين، وحل مشكلة محددة باستخدام ال Yii، وبالرغم من أن هذه الكتابات قد لا تكون بجودة ودقة الدليل الشامل، الا أنها قد تغطي مواضيع أكثر، وتطرح أيضا حلولا مباشرة للإستخدام.
      • -
      • الكتب
      • +
      • The Definitive Guide - الدليل الشامل: كما يشير الإسم، فإن هذا الدليل يحدد آلية عمل ال Yii بدقة عالية، ويوفر إرشادات حول كيفية إستخدام ال Yii، هذا الجزء الأكثر أهمية في ال Yii، والذي يجب عليك قرائته قبل كتابة أي Yii code (ملاحظة: جزء البداية من هنا، والذي قمنا بدراسته هو أحد هذه الأجزاء، ومن أهمها للبدء بإنشاء التطبيقات من خلال ال Yii).
      • +
      • The Class Reference - المرجع الخاص بال Class في هذا الجزء يتم تحديد الية إستخدام كل Class يقدمه ال Yii، في العادة يتم إستخدام هذا المرجع عند كتابة شيفرة برمجية وأنت ترغب في فهم آلية العمل ل Class معين، أو Method, او فهم Proporty معينة...الخ، من الأفضل إستخدام المرجع الخاص بال Class فقط عند فهم آلية العمل لل Yii.
      • +
      • The Wiki Articles - مقالات الويكي مقالات الويكي هي مجموعة من الخبرات العملية للمستخدمين، تمت كتابتها ونشرها على شكل مقالات لمشاركة الخبرات، ومعظم هذه الكتابات تكون مثل الوصفات الخاصة بالطبخ، موجودة لخدمة هدف معين، وحل مشكلة محددة باستخدام ال Yii، وبالرغم من أن هذه الكتابات قد لا تكون بجودة ودقة الدليل الشامل، الا أنها قد تغطي مواضيع أكثر، وتطرح أيضا حلولا مباشرة للإستخدام.
      • +
      • الكتب
    8. -
    9. Extensions - الملحقات: تفتخر ال Yii بوجود مكتبة ضخمة من الملحقات التي تمت برمجتها وإضافتها من قبل المستخدمين المتطوعين الذين شاركوا أعمالهم وطورها لتجعل مهمة المطورين الآخرين أسهل وأسرع في تطوير التطبيفات المبنية بواسطة ال Yii.
    10. +
    11. Extensions - الملحقات: تفتخر ال Yii بوجود مكتبة ضخمة من الملحقات التي تمت برمجتها وإضافتها من قبل المستخدمين المتطوعين الذين شاركوا أعمالهم وطورها لتجعل مهمة المطورين الآخرين أسهل وأسرع في تطوير التطبيفات المبنية بواسطة ال Yii.
    12. المجتمع
    13. diff --git a/docs/guide-ar/start-prerequisites.md b/docs/guide-ar/start-prerequisites.md index e9cf78e0c14..03050b54079 100644 --- a/docs/guide-ar/start-prerequisites.md +++ b/docs/guide-ar/start-prerequisites.md @@ -7,7 +7,7 @@ ##
      PHP

      - ال Yii هو إطار عمل PHP، لذا تأكد من قراءة وفهم المرجع الرسمي الخاص بلغة ال PHP. عند البدء بتطوير المشاريع أو التطبيقات باستخدام ال Yii ، ستكتب التعليمات البرمجية بطريقة كائنية التوجه OOP، لذا تأكد من أنك على دراية بـمفاهيم ال OOP وكذلك ال namespaces. + ال Yii هو إطار عمل PHP، لذا تأكد من قراءة وفهم المرجع الرسمي الخاص بلغة ال PHP. عند البدء بتطوير المشاريع أو التطبيقات باستخدام ال Yii ، ستكتب التعليمات البرمجية بطريقة كائنية التوجه OOP، لذا تأكد من أنك على دراية بـمفاهيم ال OOP وكذلك ال namespaces.

      ##
      البرمجة كائنية التوجه object oriented programming
      diff --git a/docs/guide-ar/start-workflow.md b/docs/guide-ar/start-workflow.md index 826fa129e11..34d5ecf421d 100644 --- a/docs/guide-ar/start-workflow.md +++ b/docs/guide-ar/start-workflow.md @@ -45,7 +45,7 @@ -##
      هيكلية التطبيق - Application Structure +##
      هيكلية التطبيق - Application Structure

      أكثر المسارات والملفات أهمية الموجودة داخل التطبيق (بافتراض أن ال application's root directory هو basic) هي: @@ -70,12 +70,12 @@ basic/ application base path ```

      -بشكل عام، يمكن تقسيم الملفات داخل التطبيق إلى نوعين: الاول تجده تحت المسار التالي: basic/web +بشكل عام، يمكن تقسيم الملفات داخل التطبيق إلى نوعين: الاول تجده تحت المسار التالي: basic/web والثاني تجده بالمسارات الأخرى.
      وبنائا على ذلك، فإنه من الممكن الوصول إلى النوع الأول مباشرة عبر ال HTTP (أي من خلال المتصفح) ، بينما لا يمكن أن يكون ذلك للنوع الثاني.

      - يعتمد ال Yii على إستخدام ال MVC، وال MVC هو أحد ال Architectural Pattern، وهي اختصار ل model-view-controller، + يعتمد ال Yii على إستخدام ال MVC، وال MVC هو أحد ال Architectural Pattern، وهي اختصار ل model-view-controller، هذا الأسلوب ينعكس في تنظيم المسارات الخاصة بالملفات كما في الشكل أعلاه. يحتوي المسار models على جميع الكلاس (model classes) ، ويحتوي مسار ال views على جميع الصفحات التي ستستخدم في العرض (view scripts)، ويحتوي مسار الcontrollers على جميع (controller classes)

      @@ -88,11 +88,10 @@ basic/ application base path

      يحتوي كل تطبيق على نص برمجي يستخدم للدخول الى التطبيق (كبوابة بعدها يظهر التطبيق للناظر)، ويسمى هذا الجزء بال entry script، وهو يمثل الصفحة web/index.php، ويعد هذا المدخل النص البرمجي الوحيد الذي يمكن الوصول إليه من خلال ال PHP في التطبيق، ويعمل هذا ال entry script على أخذ ال request ومن ثم إنشاء instance خاص بالتطبيق ليستطيع التعامل معه (التعامل مع التطبيق ومكوناته). - يقوم التطبيق على معالجة ال request بمساعدة من ال components، ومن ثم بقوم التطبيق بإرسال ال request الى عناصر ال MVC، كما يتم استخدام ال Widgets في ال views للمساعدة في إنشاء العناصر المعقدة والمتغيرة (Complex & Dynamic user interface) لواجهة المستخدم. + يقوم application على معالجة ال request بمساعدة من ال components، ومن ثم بقوم التطبيق بإرسال ال request الى عناصر ال MVC، كما يتم استخدام ال Widgets في ال views للمساعدة في إنشاء العناصر المعقدة والمتغيرة (Complex & Dynamic user interface) لواجهة المستخدم.

      - -##
      دورة الحياة الخاصة بال request +##
      دورة الحياة الخاصة بال request

      يوضح المخطط التالي كيفية معالجة التطبيق ل request معين. diff --git a/docs/guide-de/README.md b/docs/guide-de/README.md index ca8d6c02c21..b09aee46e61 100644 --- a/docs/guide-de/README.md +++ b/docs/guide-de/README.md @@ -1,7 +1,7 @@ Das umfassende Handbuch für Yii 2.0 =================================== -Dieses Tutorial wurde unter den [Bedingungen der Yii-Dokumentation](http://www.yiiframework.com/doc/terms/) veröffentlicht. +Dieses Tutorial wurde unter den [Bedingungen der Yii-Dokumentation](https://www.yiiframework.com/doc/terms/) veröffentlicht. Alle Rechte vorbehalten. diff --git a/docs/guide-es/README.md b/docs/guide-es/README.md index 568694cde5a..80d5266fe87 100644 --- a/docs/guide-es/README.md +++ b/docs/guide-es/README.md @@ -1,7 +1,7 @@ Guía Definitiva de Yii 2.0 ========================== -Este tutorial se publica bajo los [Términos de Documentación Yii](http://www.yiiframework.com/doc/terms/). +Este tutorial se publica bajo los [Términos de Documentación Yii](https://www.yiiframework.com/doc/terms/). Todos los derechos reservados. diff --git a/docs/guide-es/caching-data.md b/docs/guide-es/caching-data.md index 943a7731cb7..1349865d064 100644 --- a/docs/guide-es/caching-data.md +++ b/docs/guide-es/caching-data.md @@ -28,7 +28,7 @@ representan diferentes tipos de almacenamiento en caché, como por ejemplo en me Los Componentes de Caché están normalmente registrados como [componentes de la aplicación](structure-application-components.md) para que de esta forma puedan ser configurados y accesibles globalmente. El siguiente código muestra cómo configurar el componente de aplicación -`cache` para usar [memcached](http://memcached.org/) con dos servidores caché: +`cache` para usar [memcached](https://memcached.org/) con dos servidores caché: ```php 'components' => [ @@ -72,15 +72,15 @@ el código que utiliza la caché. Por ejemplo, podrías modificar la configuraci Yii proporciona varios componentes de caché que pueden almacenar datos en diferentes medios. A continuación se muestra un listado con los componentes de caché disponibles: -* [[yii\caching\ApcCache]]: utiliza la extensión de PHP [APC](https://secure.php.net/manual/es/book.apc.php). Esta opción puede ser considerada como la más rápida de entre todas las disponibles para una aplicación centralizada. (ej. un servidor, no dedicado al balance de carga, etc). -* [[yii\caching\DbCache]]: utiliza una tabla de base de datos para almacenar los datos. Por defecto, se creará y usará como base de datos [SQLite3](http://sqlite.org/) en el directorio runtime. Se puede especificar explícitamente que base de datos va a ser utilizada configurando la propiedad `db`. +* [[yii\caching\ApcCache]]: utiliza la extensión de PHP [APC](https://www.php.net/manual/es/book.apc.php). Esta opción puede ser considerada como la más rápida de entre todas las disponibles para una aplicación centralizada. (ej. un servidor, no dedicado al balance de carga, etc). +* [[yii\caching\DbCache]]: utiliza una tabla de base de datos para almacenar los datos. Por defecto, se creará y usará como base de datos [SQLite3](https://sqlite.org/) en el directorio runtime. Se puede especificar explícitamente que base de datos va a ser utilizada configurando la propiedad `db`. * [[yii\caching\DummyCache]]: dummy cache (caché tonta) que no almacena en caché nada. El propósito de este componente es simplificar el código necesario para chequear la disponibilidad de caché. Por ejemplo, durante el desarrollo o si el servidor no tiene soporte de caché actualmente, puede utilizarse este componente de caché. Cuando este disponible un soporte en caché, puede cambiarse el componente correspondiente. En ambos casos, puede utilizarse el mismo código `Yii::$app->cache->get($key)` para recuperar un dato sin la preocupación de que `Yii::$app->cache` pueda ser `null`. * [[yii\caching\FileCache]]: utiliza un fichero estándar para almacenar los datos. Esto es adecuado para almacenar grandes bloques de datos (como páginas). -* [[yii\caching\MemCache]]: utiliza las extensiones de PHP [memcache](https://secure.php.net/manual/es/book.memcache.php) y [memcached](https://secure.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](https://secure.php.net/manual/es/book.wincache.php)). -* [[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é. +* [[yii\caching\MemCache]]: utiliza las extensiones de PHP [memcache](https://www.php.net/manual/es/book.memcache.php) y [memcached](https://www.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](https://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](https://iis.net/downloads/microsoft/wincache-extension) ([ver también](https://www.php.net/manual/es/book.wincache.php)). +* [[yii\caching\XCache]] _(deprecated)_: utiliza la extensión de PHP [XCache](https://en.wikipedia.org/wiki/List_of_PHP_accelerators#XCache). +* [[yii\caching\ZendDataCache]] _(deprecated)_: utiliza [Zend Data Cache](https://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). @@ -221,7 +221,7 @@ $result = Customer::getDb()->cache(function ($db) { }); ``` -> Note: Algunos DBMS (ej. [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) también soporta el almacenamiento en caché desde el mismo servidor de la BD. Puedes optar por utilizar cualquiera de los mecanismos de memoria caché. El almacenamiento en caché de consultas previamente descrito tiene la ventaja que de que se puede especificar dependencias de caché de una forma flexible y son potencialmente mucho más eficientes. +> Note: Algunos DBMS (ej. [MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html)) también soporta el almacenamiento en caché desde el mismo servidor de la BD. Puedes optar por utilizar cualquiera de los mecanismos de memoria caché. El almacenamiento en caché de consultas previamente descrito tiene la ventaja que de que se puede especificar dependencias de caché de una forma flexible y son potencialmente mucho más eficientes. ### Configuraciones diff --git a/docs/guide-es/caching-http.md b/docs/guide-es/caching-http.md index e31025e360f..e364ff8d0ca 100644 --- a/docs/guide-es/caching-http.md +++ b/docs/guide-es/caching-http.md @@ -110,7 +110,7 @@ La generación de un ETag que requiera muchos recursos puede echar por tierra el introducir una sobrecarga innecesaria, ya que debe ser re-evaluada en cada solicitud (request). Trata de encontrar una expresión sencilla para invalidar la caché si la página ha sido modificada. -> Note: En cumplimiento con [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4), +> Note: En cumplimiento con [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4), `HttpCache` enviará ambas cabeceras `ETag` y `Last-Modified` si ambas están configuradas. Y si el clientes envía tanto la cabecera `If-None-Match` como la cabecera `If-Modified-Since`, solo la primera será respetada. ## La Cabecera `Cache-Control` @@ -130,7 +130,7 @@ especifican en `session.cache_limiter` de la configuración INI de PHP. Estas ca el almacenamiento de caché que desees de `HttpCache`. Para evitar este problema, por defecto `HttpCache` deshabilitará automáticamente el envío de estas cabeceras. Si deseas modificar este comportamiento, tienes que configurar la propiedad [[yii\filters\HttpCache::sessionCacheLimiter]]. La propiedad puede tomar un valor de cadena, incluyendo `public`, `private`, -`private_no_expire`, and `nocache`. Por favor, consulta el manual PHP acerca de [session_cache_limiter()](https://secure.php.net/manual/es/function.session-cache-limiter.php) +`private_no_expire`, and `nocache`. Por favor, consulta el manual PHP acerca de [session_cache_limiter()](https://www.php.net/manual/es/function.session-cache-limiter.php) para una mejor explicación sobre esos valores. diff --git a/docs/guide-es/concept-aliases.md b/docs/guide-es/concept-aliases.md index a44566d39b7..a617d2a6328 100644 --- a/docs/guide-es/concept-aliases.md +++ b/docs/guide-es/concept-aliases.md @@ -113,8 +113,8 @@ utilizadas regularmente. La siguiente es la lista de alias predefinidos por Yii: - `@webroot`: el directorio raíz Web de la aplicación Web se está ejecutando actualmente. - `@web`: la URL base de la aplicación web se ejecuta actualmente. Tiene el mismo valor que [[yii\web\Request::baseUrl]]. - `@vendor`: el [[yii\base\Application::vendorPath|directorio vendor de Composer]]. Por defecto `@app/vendor`. -- `@bower`, el directorio raíz que contiene [paquetes bower](http://bower.io/). Por defecto `@vendor/bower`. -- `@npm`, el directorio raíz que contiene [paquetes npm](https://www.npmjs.org/). Por defecto `@vendor/npm`. +- `@bower`, el directorio raíz que contiene [paquetes bower](https://bower.io/). Por defecto `@vendor/bower`. +- `@npm`, el directorio raíz que contiene [paquetes npm](https://www.npmjs.com/). Por defecto `@vendor/npm`. El alias `@yii` se define cuando incluyes el archivo `Yii.php` en tu [script de entrada](structure-entry-scripts.md), mientras que el resto de los alias están definidos en el constructor de la aplicación cuando se aplica la diff --git a/docs/guide-es/concept-autoloading.md b/docs/guide-es/concept-autoloading.md index 98c1a18f7ff..598bf7a342d 100644 --- a/docs/guide-es/concept-autoloading.md +++ b/docs/guide-es/concept-autoloading.md @@ -1,7 +1,7 @@ Autocarga de clases =================== -Yii depende del [mecanismo de autocarga de clases](https://secure.php.net/manual/es/language.oop5.autoload.php) para localizar +Yii depende del [mecanismo de autocarga de clases](https://www.php.net/manual/es/language.oop5.autoload.php) para localizar e incluir los archivos de las clases requiridas. Proporciona un cargador de clases de alto rendimiento que cumple con el [estandard PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md). El cargador se instala cuando incluyes el archivo `Yii.php`. diff --git a/docs/guide-es/concept-behaviors.md b/docs/guide-es/concept-behaviors.md index 61a85046bd1..f9347fcff8e 100644 --- a/docs/guide-es/concept-behaviors.md +++ b/docs/guide-es/concept-behaviors.md @@ -2,7 +2,7 @@ Comportamientos =============== Comportamientos son instancias de [[yii\base\Behavior]] o sus clases "hija". Comportamientos, también conocido como -[mixins](http://en.wikipedia.org/wiki/Mixin), te permiten mejorar la funcionalidad de un [[yii\base\Component|componente]] +[mixins](https://en.wikipedia.org/wiki/Mixin), te permiten mejorar la funcionalidad de un [[yii\base\Component|componente]] existente sin necesidad de modificar su herencia de clases. Cuando un comportamiento se une a un componente, "inyectará" sus métodos y propiedades dentro del componente, y podrás acceder a esos métodos y propiedades como si hubieran estado definidos por la clase de componente. Además, un @@ -116,21 +116,21 @@ class User extends ActiveRecord { return [ // anonymous behavior, behavior class name only - MyBehavior::className(), + MyBehavior::class, // named behavior, behavior class name only - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // anonymous behavior, configuration array [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // named behavior, configuration array 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ] @@ -151,14 +151,14 @@ que se le va a unir el comportamiento: use app\components\MyBehavior; // vincular un objeto comportamiento "behavior" -$component->attachBehavior('myBehavior1', new MyBehavior); +$component->attachBehavior('myBehavior1', new MyBehavior()); // vincular una clase comportamiento -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // asociar una matriz de configuración $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -167,8 +167,8 @@ Puede vincular múltiples comportamientos a la vez mediante el uso del método [ ```php $component->attachBehaviors([ - 'myBehavior1' => new MyBehavior, // un comportamiento nombrado - MyBehavior::className(), // un comportamiento anónimo + 'myBehavior1' => new MyBehavior(), // un comportamiento nombrado + MyBehavior::class, // un comportamiento anónimo ]); ``` @@ -176,10 +176,10 @@ También puedes asociar comportamientos a traves de [configuraciones](concept-co ```php [ - 'as myBehavior2' => MyBehavior::className(), + 'as myBehavior2' => MyBehavior::class, 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -270,7 +270,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -309,7 +309,7 @@ $user->touch('login_time'); Comparación con Traits ---------------------- -Mientras que los comportamientos son similares a [traits](https://secure.php.net/traits) en cuanto que ambos "inyectan" sus +Mientras que los comportamientos son similares a [traits](https://www.php.net/traits) en cuanto que ambos "inyectan" sus métodos y propiedades a la clase primaria, son diferentes en muchos aspectos. Tal y como se describe abajo, los dos tienen sus ventajas y desventajas. Son más como complementos el uno al otro en lugar de alternativas. diff --git a/docs/guide-es/concept-components.md b/docs/guide-es/concept-components.md index 8c0e6923762..f4ebbe6aa60 100644 --- a/docs/guide-es/concept-components.md +++ b/docs/guide-es/concept-components.md @@ -67,7 +67,7 @@ Siguiendo esas directrices hará que tus componentes sean [configurables](concep $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // alternativamente $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide-es/concept-di-container.md b/docs/guide-es/concept-di-container.md index 3b37fa9951a..9c46419f077 100644 --- a/docs/guide-es/concept-di-container.md +++ b/docs/guide-es/concept-di-container.md @@ -2,7 +2,7 @@ Contenedor de Inyección de Dependencias ======================================= Un contenedor de Inyección de Dependencias (ID), es un objeto que sabe como instancias y configurar objetos y sus -objetos dependientes. El [articulo de Martin](http://martinfowler.com/articles/injection.html) contiene una buena +objetos dependientes. El [articulo de Martin](https://martinfowler.com/articles/injection.html) contiene una buena explicación de porque son útiles los contenedores de ID. A continuación explicaremos como usar el contenedor de ID que proporciona Yii. @@ -14,7 +14,7 @@ de ID: * Inyección de constructores; * Inyección de setters y propiedades; -* Inyección de [llamadas de retorno PHP](https://secure.php.net/manual/es/language.types.callable.php); +* Inyección de [llamadas de retorno PHP](https://www.php.net/manual/es/language.types.callable.php); ### Inyección de Constructores @@ -316,7 +316,7 @@ Resumen Tanto la inyección de dependencias como el [localizador de servicios](concept-service-locator.md) son patrones de diseño populares que permiten construir software con acoplamiento flexible y más fácil de testear. Se recomienda -encarecida la lectura del articulo de [Martin](http://martinfowler.com/articles/injection.html) para obtener una mejor +encarecida la lectura del articulo de [Martin](https://martinfowler.com/articles/injection.html) para obtener una mejor comprensión de la inyección de dependencias y de la localización de servicios. Yii implementa su propio [localizador de servicios](concept-service-locator.md) por encima del contenedor de ID. diff --git a/docs/guide-es/concept-events.md b/docs/guide-es/concept-events.md index 436a719c60f..664d6109b7a 100644 --- a/docs/guide-es/concept-events.md +++ b/docs/guide-es/concept-events.md @@ -13,7 +13,7 @@ Gestor de Eventos ----------------- Un gestor de eventos es una -[llamada de retorno PHP (PHP callback)](https://secure.php.net/manual/es/language.types.callable.php) que se ejecuta cuando se +[llamada de retorno PHP (PHP callback)](https://www.php.net/manual/es/language.types.callable.php) que se ejecuta cuando se lanza el evento al que corresponde. Se puede usar cualquier llamada de retorno de las enumeradas a continuación: - una función de PHP global especificada como una cadena de texto (sin paréntesis), ej. `'trim'`; @@ -217,7 +217,7 @@ use Yii; use yii\base\Event; use yii\db\ActiveRecord; -Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { +Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::debug(get_class($event->sender) . ' is inserted'); }); ``` @@ -236,11 +236,11 @@ invocación de los gestores de eventos a nivel de clase. ```php use yii\base\Event; -Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { +Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) { var_dump($event->sender); // displays "null" }); -Event::trigger(Foo::className(), Foo::EVENT_HELLO); +Event::trigger(Foo::class, Foo::EVENT_HELLO); ``` Tenga en cuenta que en este caso, el `$event->sender` hace referencia al nombre de la clase que lanza el evento en @@ -254,10 +254,10 @@ Para desadjuntar un gestor de eventos a nivel de clase, se tiene que llamar a [[ ```php // desadjunta $handler -Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); +Event::off(Foo::class, Foo::EVENT_HELLO, $handler); // desadjunta todos los gestores de Foo::EVENT_HELLO -Event::off(Foo::className(), Foo::EVENT_HELLO); +Event::off(Foo::class, Foo::EVENT_HELLO); ``` Eventos Globales diff --git a/docs/guide-es/db-dao.md b/docs/guide-es/db-dao.md index cf52020717b..38cebcec7f9 100644 --- a/docs/guide-es/db-dao.md +++ b/docs/guide-es/db-dao.md @@ -1,7 +1,7 @@ Objetos de Acceso a Bases de Datos ================================== -Construido sobre [PDO](https://secure.php.net/manual/es/book.pdo.php), Yii DAO (Objetos de Acceso a Bases de Datos) proporciona una +Construido sobre [PDO](https://www.php.net/manual/es/book.pdo.php), Yii DAO (Objetos de Acceso a Bases de Datos) proporciona una API orientada a objetos para el acceso a bases de datos relacionales. Es el fundamento para otros métodos de acceso a bases de datos más avanzados, incluyendo el [constructor de consultas](db-query-builder.md) y [active record](db-active-record.md). @@ -11,12 +11,12 @@ Yii DAO también significa que tienes que tienes que tomar un esfuerzo adicional Yii DAO soporta las siguientes bases de datos: -- [MySQL](http://www.mysql.com/) +- [MySQL](https://www.mysql.com/) - [MariaDB](https://mariadb.com/) -- [SQLite](http://sqlite.org/) -- [PostgreSQL](http://www.postgresql.org/): versión 8.4 o superior. -- [CUBRID](http://www.cubrid.org/): versión 9.3 o superior. -- [Oracle](http://www.oracle.com/us/products/database/overview/index.html) +- [SQLite](https://sqlite.org/) +- [PostgreSQL](https://www.postgresql.org/): versión 8.4 o superior. +- [CUBRID](https://www.cubrid.org/): versión 9.3 o superior. +- [Oracle](https://www.oracle.com/database/) - [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): versión 2008 o superior. ## Creando Conexiones DB @@ -60,7 +60,7 @@ Puedes acceder a la conexión DB mediante la expresión `Yii::$app->db`. Cuando configuras una conexión DB, deberías siempre especificar el Nombre de Origen de Datos (DSN) mediante la propiedad [[yii\db\Connection::dsn|dsn]]. El formato del DSN varia para cada diferente base de datos. Por favor consulte el -[manual de PHP](https://secure.php.net/manual/es/function.PDO-construct.php) para más detalles. Abajo están algunos ejemplos: +[manual de PHP](https://www.php.net/manual/es/function.PDO-construct.php) para más detalles. Abajo están algunos ejemplos: * MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` * SQLite: `sqlite:/path/to/database/file` @@ -185,7 +185,7 @@ $post = $db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status', ->queryOne(); ``` -La vinculación parámetros es implementada mediante [sentencias preparadas (prepared statements)](https://secure.php.net/manual/es/mysqli.quickstart.prepared-statements.php). +La vinculación parámetros es implementada mediante [sentencias preparadas (prepared statements)](https://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php). Además de prevenir ataques de inyección de SQL, también puede mejorar el rendimiento preparando una sola vez una sentencia SQL y ejecutándola múltiples veces con diferentes parámetros. Por ejemplo, @@ -396,7 +396,7 @@ En el momento de escribir esto, solo MSSQL y SQLite serán afectadas. puede especificar el nivel de aislamiento directamente cuando empieza la transacción. Se tiene que llamar a [[yii\db\Transaction::setIsolationLevel()]] después de que la transacción haya empezado. -[isolation levels]: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels +[isolation levels]: https://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels ### Transacciones Anidadas @@ -437,7 +437,7 @@ try { ## Replicación y División Lectura-Escritura -Muchos DBMS soportan [replicación de bases de datos](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) para tener +Muchos DBMS soportan [replicación de bases de datos](https://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) para tener una mejor disponibilidad de la base de datos y un mejor tiempo de respuesta del servidor. Con la replicación de bases de datos, los datos están replicados en los llamados *servidores maestros* (master servers) y *servidores esclavos* (slave servers). Todas las escrituras y actualizaciones deben hacerse en el servidor maestro, mientras que las lecturas diff --git a/docs/guide-es/db-migrations.md b/docs/guide-es/db-migrations.md index 2c4470929e7..bb797bcccfb 100644 --- a/docs/guide-es/db-migrations.md +++ b/docs/guide-es/db-migrations.md @@ -648,7 +648,7 @@ en `safeDown()`. En el ejemplo anterior primero creamos la tabla y luego inserta que en `safeDown()` primero eliminamos el registro y posteriormente eliminamos la tabla. > Note: No todos los DBMS soportan transacciones. Y algunas consultas a la BD no pueden ser puestas en transacciones. Para algunos ejemplos, - por favor lee acerca de [commits implícitos](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). En estos casos, + por favor lee acerca de [commits implícitos](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). En estos casos, deberías igualmente implementar `up()` y `down()`. diff --git a/docs/guide-es/db-query-builder.md b/docs/guide-es/db-query-builder.md index d09c5e3516a..0ca6212a7ae 100644 --- a/docs/guide-es/db-query-builder.md +++ b/docs/guide-es/db-query-builder.md @@ -241,7 +241,7 @@ El operando puede ser uno de los siguientes (ver también [[yii\db\QueryInterfac automáticamente entre un par de caracteres de porcentaje. > Note: Cuando se usa PostgreSQL también se puede usar -[`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) en lugar de `like` para +[`ilike`](https://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) en lugar de `like` para filtrar resultados insensibles a mayúsculas (case-insensitive). - `or like`: similar al operando `like` exceptuando que se usa `OR` para concatenar los predicados `LIKE` cuando haya diff --git a/docs/guide-es/glossary.md b/docs/guide-es/glossary.md index 7989ac5c5a0..63ce5cbd91c 100644 --- a/docs/guide-es/glossary.md +++ b/docs/guide-es/glossary.md @@ -52,7 +52,7 @@ Módulo es una sub-aplicación que contiene elementos MVC en sí mismo, como mod ## namespace -Namespace (espacio de nombres) se refiere a una [característica de PHP](https://secure.php.net/manual/es/language.namespaces.php) activamente utilizada en Yii 2. +Namespace (espacio de nombres) se refiere a una [característica de PHP](https://www.php.net/manual/es/language.namespaces.php) activamente utilizada en Yii 2. # P diff --git a/docs/guide-es/helper-array.md b/docs/guide-es/helper-array.md index ea1bcfc5dd1..9e0e869f508 100644 --- a/docs/guide-es/helper-array.md +++ b/docs/guide-es/helper-array.md @@ -1,7 +1,7 @@ ArrayHelper =========== -Adicionalmente al [rico conjunto de funciones para arrays de PHP](https://secure.php.net/manual/es/book.array.php), el array helper de Yii proporciona +Adicionalmente al [rico conjunto de funciones para arrays de PHP](https://www.php.net/manual/es/book.array.php), el array helper de Yii proporciona métodos estáticos adicionales permitiendo trabajar con arrays de manera más eficiente. @@ -66,7 +66,7 @@ Después de ejecutar el código el `$array` contendrá `['options' => [1, 2]]` y ## Comprobando la Existencia de Claves -`ArrayHelper::keyExists` funciona de la misma manera que [array_key_exists](https://secure.php.net/manual/es/function.array-key-exists.php) +`ArrayHelper::keyExists` funciona de la misma manera que [array_key_exists](https://www.php.net/manual/es/function.array-key-exists.php) excepto que también soporta case-insensitive para la comparación de claves. Por ejemplo, ```php @@ -270,7 +270,7 @@ El tercer argumento es la dirección. En caso de ordenar por una clave podría s direcciones de ordenación. El último argumento es un PHP sort flag que toma los mismos valores que los pasados a -PHP [sort()](https://secure.php.net/manual/es/function.sort.php). +PHP [sort()](https://www.php.net/manual/es/function.sort.php). ## Detectando Tipos de Array @@ -373,7 +373,7 @@ A pesar de que PHP ofrece `in_array()`, este no soporta sub-grupos u objetos de Para ayudar en este tipo de pruebas, [[yii\helpers\ArrayHelper]] provee [[yii\helpers\ArrayHelper::isIn()|isIn()]] y [[yii\helpers\ArrayHelper::isSubset()|isSubset()]] con la misma firma del método -[in_array()](https://secure.php.net/manual/en/function.in-array.php). +[in_array()](https://www.php.net/manual/en/function.in-array.php). ```php // true diff --git a/docs/guide-es/helper-html.md b/docs/guide-es/helper-html.md index a3eac70b279..17aeb525c01 100644 --- a/docs/guide-es/helper-html.md +++ b/docs/guide-es/helper-html.md @@ -3,7 +3,7 @@ Clase auxiliar Html (Html helper) Todas las aplicaciones web generan grandes cantidades de marcado HTML (HTML markup). Si el marcado es estático, se puede realizar de forma efectiva -[mezclando PHP y HTML en un mismo archivo](https://secure.php.net/manual/es/language.basic-syntax.phpmode.php) pero cuando se +[mezclando PHP y HTML en un mismo archivo](https://www.php.net/manual/es/language.basic-syntax.phpmode.php) pero cuando se generan dinámicamente empieza a complicarse su gestión sin ayuda extra. Yii ofrece esta ayuda en forma de una clase auxiliar Html que proporciona un conjunto de métodos estáticos para gestionar las etiquetas HTML más comúnmente usadas, sus opciones y contenidos. @@ -45,7 +45,7 @@ gestión adicional que se debe conocer: - Si un valor es `null`, el correspondiente atributo no se renderizará. - Los atributos cuyos valores son de tipo booleano serán tratados como - [atributos booleanos](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes). + [atributos booleanos](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes). - Los valores de los atributos se codificarán en HTML usando [[yii\helpers\Html::encode()|Html::encode()]]. - El atributo "data" puede recibir un array. En este caso, se "expandirá" y se renderizará una lista de atributos `data` ej. `'data' => ['id' => 1, 'name' => 'yii']` se convierte en `data-id="1" data-name="yii"`. @@ -96,8 +96,8 @@ eliminara una propiedad, se puede especificar como una cadena de texto. Para que el contenido se muestre correctamente y de forma segura con caracteres especiales HTML el contenido debe ser -codificado. En PHP esto se hace con [htmlspecialchars](https://secure.php.net/manual/es/function.htmlspecialchars.php) y -[htmlspecialchars_decode](https://secure.php.net/manual/es/function.htmlspecialchars-decode.php). El problema con el uso +codificado. En PHP esto se hace con [htmlspecialchars](https://www.php.net/manual/es/function.htmlspecialchars.php) y +[htmlspecialchars_decode](https://www.php.net/manual/es/function.htmlspecialchars-decode.php). El problema con el uso de estos métodos directamente es que se tiene que especificar la codificación y opciones extra cada vez. Ya que las opciones siempre son las mismas y la codificación debe coincidir con la de la aplicación para prevenir problemas de seguridad, Yii proporciona dos métodos simples y compactos: diff --git a/docs/guide-es/input-file-upload.md b/docs/guide-es/input-file-upload.md index 022fa3acb56..ccfe76ab408 100644 --- a/docs/guide-es/input-file-upload.md +++ b/docs/guide-es/input-file-upload.md @@ -123,7 +123,7 @@ También puedes subir varios archivos a la vez, con algunos ajustes en el códig Primero debes ajustar la clase del modelo, agregando la opción `maxFiles` en la regla de validación `file` para limitar el número máximo de archivos a subir. Definir `maxFiles` como `0` significa que no hay límite en el número de archivos a subir simultáneamente. El número máximo de archivos permitidos para subir simultáneamente está también limitado -por la directiva PHP [`max_file_uploads`](https://secure.php.net/manual/en/ini.core.php#ini.max-file-uploads), +por la directiva PHP [`max_file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads), cuyo valor por defecto es 20. El método `upload()` debería también ser modificado para guardar los archivos uno a uno. ```php diff --git a/docs/guide-es/input-validation.md b/docs/guide-es/input-validation.md index a64abefa88f..dd461e355f7 100644 --- a/docs/guide-es/input-validation.md +++ b/docs/guide-es/input-validation.md @@ -434,7 +434,7 @@ class EntryForm extends Model { return [ [['name', 'email'], 'required'], - ['country', CountryValidator::className()], + ['country', CountryValidator::class], ['email', 'email'], ]; } @@ -584,7 +584,7 @@ JS; ### Validación Diferida -Si necesitas realizar validación del lado del cliente asincrónica, puedes crear [Objetos Diferidos](http://api.jquery.com/category/deferred-object/). +Si necesitas realizar validación del lado del cliente asincrónica, puedes crear [Objetos Diferidos](https://api.jquery.com/category/deferred-object/). Por ejemplo, para realizar validación AJAX personalizada, puedes utilizar el siguiente código: ```php diff --git a/docs/guide-es/intro-upgrade-from-v1.md b/docs/guide-es/intro-upgrade-from-v1.md index 580a904654b..7a2e5a5c5a6 100644 --- a/docs/guide-es/intro-upgrade-from-v1.md +++ b/docs/guide-es/intro-upgrade-from-v1.md @@ -29,15 +29,15 @@ Yii 2.0 requiere PHP 5.4 o mayor, lo que es un gran progreso ya que Yii 1.1 func Como resultado, hay muchas diferencias a nivel del lenguaje a las que deberías prestar atención. Abajo hay un resumen de los mayores cambios en relación a PHP: -- [Namespaces](https://secure.php.net/manual/es/language.namespaces.php). -- [Funciones anónimas](https://secure.php.net/manual/es/functions.anonymous.php). +- [Namespaces](https://www.php.net/manual/es/language.namespaces.php). +- [Funciones anónimas](https://www.php.net/manual/es/functions.anonymous.php). - La sintaxis corta de Arrays `[...elementos...]` es utilizada en vez de `array(...elementos...)`. - Etiquetas cortas de `echo`. Ahora en las vistas se usa `registerJsFile('http://example.com/js/main.js', ['depends' => [\yii\web\JqueryAsset::className()]]); +$this->registerJsFile('http://example.com/js/main.js', ['depends' => [\yii\web\JqueryAsset::class]]); ``` Los argumentos para [[yii\web\View::registerJsFile()|registerJsFile()]] son similares a los de @@ -77,7 +77,7 @@ Si necesitas asegurarte que haya sólo una etiqueta style utiliza el cuarto argu ```php $this->registerCssFile("http://example.com/css/themes/black-and-white.css", [ - 'depends' => [BootstrapAsset::className()], + 'depends' => [BootstrapAsset::class], 'media' => 'print', ], 'css-print-theme'); ``` diff --git a/docs/guide-es/rest-authentication.md b/docs/guide-es/rest-authentication.md index eef25a98c66..53b070a43a1 100644 --- a/docs/guide-es/rest-authentication.md +++ b/docs/guide-es/rest-authentication.md @@ -19,7 +19,7 @@ Hay muchas maneras de enviar una token (pieza) de acceso: que no usen las cabeceras HTTP para enviar piezas de acceso. * [OAuth 2](http://oauth.net/2/): la pieza de acceso es obtenida por el consumidor por medio de una autorización del servidor y enviada al API del servidor según el protocolo - OAuth 2 [tokens HTTP del portador](http://tools.ietf.org/html/rfc6750). + OAuth 2 [tokens HTTP del portador](https://datatracker.ietf.org/doc/html/rfc6750). Yii soporta todos los métodos anteriores de autenticación. Puedes crear nuevos métodos de autenticación de una forma fácil. @@ -57,7 +57,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -75,11 +75,11 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => CompositeAuth::className(), + 'class' => CompositeAuth::class, 'authMethods' => [ - HttpBasicAuth::className(), - HttpBearerAuth::className(), - QueryParamAuth::className(), + HttpBasicAuth::class, + HttpBearerAuth::class, + QueryParamAuth::class, ], ]; return $behaviors; diff --git a/docs/guide-es/rest-controllers.md b/docs/guide-es/rest-controllers.md index 81d6bceac8c..724fd567fe3 100644 --- a/docs/guide-es/rest-controllers.md +++ b/docs/guide-es/rest-controllers.md @@ -69,7 +69,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } diff --git a/docs/guide-es/rest-quick-start.md b/docs/guide-es/rest-quick-start.md index 05b9844693d..06ae63d2a32 100644 --- a/docs/guide-es/rest-quick-start.md +++ b/docs/guide-es/rest-quick-start.md @@ -9,7 +9,7 @@ En particular, Yii soporta las siguientes características sobre APIs RESTful; * Formato de respuesta de negocio (soporta JSON y XML por defecto); * Personalización de objetos serializados con soporte para campos de salida seleccionables; * Formateo apropiado de colecciones de datos y validación de errores; -* Soporte para [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS); +* Soporte para [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS); * Eficiente enrutamiento con una adecuada comprobación del verbo(verb) HTTP; * Incorporado soporte para las `OPTIONS` y `HEAD` verbos; * Autenticación y autorización; diff --git a/docs/guide-es/rest-resources.md b/docs/guide-es/rest-resources.md index b2353103505..18b4066910e 100644 --- a/docs/guide-es/rest-resources.md +++ b/docs/guide-es/rest-resources.md @@ -116,7 +116,7 @@ la petición `http://localhost/users?fields=id,email&expand=profile` puede devol ## Enlaces (Links) -[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), es una abreviación de Hipermedia es el Motor del Estado de la Aplicación (Hypermedia as the Engine of Application State), promueve que las APIs RESTfull devuelvan información que permita a los clientes descubrir las acciones que soportan los recursos devueltos. El sentido de HATEOAS es devolver un conjunto de hiperenlaces con relación a la información, cuando los datos de los recursos son servidos por las APIs. +[HATEOAS](https://en.wikipedia.org/wiki/HATEOAS), es una abreviación de Hipermedia es el Motor del Estado de la Aplicación (Hypermedia as the Engine of Application State), promueve que las APIs RESTfull devuelvan información que permita a los clientes descubrir las acciones que soportan los recursos devueltos. El sentido de HATEOAS es devolver un conjunto de hiperenlaces con relación a la información, cuando los datos de los recursos son servidos por las APIs. Las clases con recursos pueden soportar HATEOAS implementando el interfaz [[yii\web\Linkable]] . El interfaz contiene sólo un método [[yii\web\Linkable::getLinks()|getLinks()]] el cual debe de de devolver una lista de [[yii\web\Link|links]]. Típicamente, debes devolver al menos un enlace `self` representando la URL al mismo recurso objeto. Por ejemplo, diff --git a/docs/guide-es/rest-response-formatting.md b/docs/guide-es/rest-response-formatting.md index 7f967a5d6a5..c1727d923fb 100644 --- a/docs/guide-es/rest-response-formatting.md +++ b/docs/guide-es/rest-response-formatting.md @@ -5,7 +5,7 @@ Cuando se maneja una petición al API RESTful, una aplicación realiza usualment con el formato de la respuesta: 1. Determinar varios factores que pueden afectar al formato de la respuesta, como son el tipo de medio, lenguaje, versión, etc. - Este proceso es también conocido como [negociación de contenido (content negotiation)](http://en.wikipedia.org/wiki/Content_negotiation). + Este proceso es también conocido como [negociación de contenido (content negotiation)](https://en.wikipedia.org/wiki/Content_negotiation). 2. La conversión de objetos recurso en arrays, como está descrito en la sección [Recursos (Resources)](rest-resources.md). Esto es realizado por la clase [[yii\rest\Serializer]]. 3. La conversión de arrays en cadenas con el formato determinado por el paso de negociación de contenido. Esto es diff --git a/docs/guide-es/rest-versioning.md b/docs/guide-es/rest-versioning.md index 49ea108678d..504b677d49a 100644 --- a/docs/guide-es/rest-versioning.md +++ b/docs/guide-es/rest-versioning.md @@ -5,7 +5,7 @@ Una buena API ha de ser *versionada*: los cambios y las nuevas características las APIs están destinadas a ser usadas por los clientes fuera de tu control. Por esta razón, compatibilidad hacia atrás (BC Backward compatibility) de las APIs ha de ser mantenida siempre que sea posible. Si es necesario un cambio que puede romper la BC, debes de introducirla en la nueva versión del API, e incrementar el número de versión. Los clientes que la usan pueden continuar usando la antigua versión de trabajo del API; los nuevos y actualizados clientes pueden obtener la nueva funcionalidad de la nueva versión del API. -> Tip: referirse a [Semántica del versionado](http://semver.org/) +> Tip: referirse a [Semántica del versionado](https://semver.org/) para más información en el diseño del número de versión del API. Una manera común de implementar el versionado de la API es embeber el número de versión en las URLs de la API. diff --git a/docs/guide-es/runtime-bootstrapping.md b/docs/guide-es/runtime-bootstrapping.md index 5fe4daeb71f..db4a973ccec 100644 --- a/docs/guide-es/runtime-bootstrapping.md +++ b/docs/guide-es/runtime-bootstrapping.md @@ -19,6 +19,6 @@ Debido a que el trabajo de bootstrapping se tiene que ejecutar antes de gestiona Intenta no registrar demasiados componentes de bootstrapping. Un componente de bootstrapping sólo es necesario si tiene que interaccionar en todo el ciclo de vida de la gestión de la petición. Por ejemplo, si un modulo necesita registrar reglas de análisis de URL adicionales, se debe incluirse en la [propiedad bootstrap](structure-applications.md#bootstrap) para que la nueva regla de URL tenga efecto antes de que sea utilizada para resolver peticiones. -En modo de producción, hay que habilitar la cache bytecode, así como [APC](https://secure.php.net/manual/es/book.apc.php), para minimizar el tiempo necesario para incluir y analizar archivos PHP. +En modo de producción, hay que habilitar la cache bytecode, así como [APC](https://www.php.net/manual/es/book.apc.php), para minimizar el tiempo necesario para incluir y analizar archivos PHP. Algunas grandes aplicaciones tienen [configuraciones](concept-configurations.md) de aplicación muy complejas que están dividida en muchos archivos de configuración más pequeños. diff --git a/docs/guide-es/runtime-responses.md b/docs/guide-es/runtime-responses.md index e1e12511b14..d5a7ee9cadd 100644 --- a/docs/guide-es/runtime-responses.md +++ b/docs/guide-es/runtime-responses.md @@ -236,11 +236,11 @@ puede terminar antes mientras el servidor Web envía el fichero. Para usar esta [[yii\web\Response::xSendFile()]]. La siguiente lista resume como habilitar la característica `X-Sendfile` para algunos servidores Web populares. -- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile) -- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Lighttpd v1.5: [X-Sendfile](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Nginx: [X-Accel-Redirect](http://wiki.nginx.org/XSendfile) -- Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) +- Apache: [X-Sendfile](https://tn123.org/mod_xsendfile) +- Lighttpd v1.4: [X-LIGHTTPD-send-file](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Lighttpd v1.5: [X-Sendfile](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Nginx: [X-Accel-Redirect](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) +- Cherokee: [X-Sendfile and X-Accel-Redirect](https://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) ## Enviar la Respuesta diff --git a/docs/guide-es/runtime-sessions-cookies.md b/docs/guide-es/runtime-sessions-cookies.md index 1995aee316b..c409fa05328 100644 --- a/docs/guide-es/runtime-sessions-cookies.md +++ b/docs/guide-es/runtime-sessions-cookies.md @@ -120,8 +120,8 @@ Por defecto la clase [[yii\web\Session]] almacena los datos de sesión como fich * [[yii\web\DbSession]]: almacena los datos de sesión en una tabla en la base de datos. * [[yii\web\CacheSession]]: almacena los datos de sesión en una caché con la ayuda de la configuración del [componente caché](caching-data.md#cache-components). -* [[yii\redis\Session]]: almacena los datos de sesión usando [redis](http://redis.io/) como medio de almacenamiento. -* [[yii\mongodb\Session]]: almacena los datos de sesión en [MongoDB](http://www.mongodb.org/). +* [[yii\redis\Session]]: almacena los datos de sesión usando [redis](https://redis.io/) como medio de almacenamiento. +* [[yii\mongodb\Session]]: almacena los datos de sesión en [MongoDB](https://www.mongodb.com/). Todas estas clases de sesión soportan los mismos métodos de la API. Como consecuencia, puedes cambiar el uso de diferentes almacenamientos de sesión sin la necesidad de modificar el código de tu aplicación que usa sesiones. @@ -262,7 +262,7 @@ unset($cookies['language']); Además de [[yii\web\Cookie::name|name]], [[yii\web\Cookie::value|value]] las propiedades que se muestran en los anteriores ejemplos, la clase [[yii\web\Cookie]] también define otras propiedades para representar toda la información posible de las cookies, tal como [[yii\web\Cookie::domain|domain]], [[yii\web\Cookie::expire|expire]]. Puedes configurar estas propiedades según sea necesario para preparar una cookie y luego añadirlo a la colección de cookies de la respuesta. -> Note: Para mayor seguridad, el valor por defecto de [[yii\web\Cookie::httpOnly]] es `true`. Esto ayuda a mitigar el riesgo del acceso a la cookie protegida por script desde el lado del cliente (si el navegador lo soporta). Puedes leer el [httpOnly wiki article](https://www.owasp.org/index.php/HttpOnly) para más detalles. +> Note: Para mayor seguridad, el valor por defecto de [[yii\web\Cookie::httpOnly]] es `true`. Esto ayuda a mitigar el riesgo del acceso a la cookie protegida por script desde el lado del cliente (si el navegador lo soporta). Puedes leer el [httpOnly wiki article](https://owasp.org/www-community/HttpOnly) para más detalles. ### Validación de la Cookie diff --git a/docs/guide-es/security-authorization.md b/docs/guide-es/security-authorization.md index 11d01a914a7..2e7590f326b 100644 --- a/docs/guide-es/security-authorization.md +++ b/docs/guide-es/security-authorization.md @@ -25,7 +25,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['login', 'logout', 'signup'], 'rules' => [ [ @@ -70,7 +70,7 @@ Puedes personalizar este comportamiento configurando la propiedad [[yii\filters\ ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, ... 'denyCallback' => function ($rule, $action) { throw new \Exception('No tienes los suficientes permisos para acceder a esta página'); @@ -126,7 +126,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['special-callback'], 'rules' => [ [ @@ -153,10 +153,10 @@ class SiteController extends Controller ## Control de Acceso Basado en Roles (RBAC) El Control de Acceso Basado en Roles (RBAC) provee una simple pero poderosa manera centralizada de control de acceso. Por favos consulta -la [Wikipedia](http://en.wikipedia.org/wiki/Role-based_access_control) para más detalles sobre comparar RBAC +la [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) para más detalles sobre comparar RBAC con otros mecanismos de control de acceso más tradicionales. -Yii implementa una Jerarquía General RBAC, siguiendo el [modelo NIST RBAC](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf). +Yii implementa una Jerarquía General RBAC, siguiendo el [modelo NIST RBAC](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf). Esto provee la funcionalidad RBAC a través de [componente de la aplicación](structure-application-components.md) [[yii\rbac\ManagerInterface|authManager]]. Utilizar RBAC envuelve dos cosas. La primera es construir los datos de autorización RBAC, y la segunda diff --git a/docs/guide-es/security-passwords.md b/docs/guide-es/security-passwords.md index f2c356af6a7..679f081cfda 100644 --- a/docs/guide-es/security-passwords.md +++ b/docs/guide-es/security-passwords.md @@ -7,7 +7,7 @@ pero el hardware moderno hace posible que ese tipo de hash e incluso más fuerte Para poder proveer de una seguridad mayor para los passwords de los usuarios, incluso en el peor de los escenarios (tu aplicación sufre una brecha de seguridad), necesitas utilizar un algoritmo que resista los ataques de fuerza bruta. La mejor elección actualmente es `bcrypt`. -En PHP, puedes generar un hash `bcrypt` utilizando la [función crypt](https://secure.php.net/manual/en/function.crypt.php). Yii provee +En PHP, puedes generar un hash `bcrypt` utilizando la [función crypt](https://www.php.net/manual/en/function.crypt.php). Yii provee dos funciones auxiliares que hacen que `crypt` genere y verifique los hash más fácilmente. Cuando un usuario provee un password por primera vez (por ej., en la registración), dicho password necesita ser pasado por un hash: diff --git a/docs/guide-es/start-databases.md b/docs/guide-es/start-databases.md index ee23d3f83bc..6080cd31a5e 100644 --- a/docs/guide-es/start-databases.md +++ b/docs/guide-es/start-databases.md @@ -49,7 +49,7 @@ Al final, tendrás una base de datos llamada `yii2basic`, y dentro de esta, una Configurar una conexión a la Base de Datos ------------------------------------------ -Asegúrate de tener instalado la extensión de PHP [PDO](https://secure.php.net/manual/es/book.pdo.php) y el driver +Asegúrate de tener instalado la extensión de PHP [PDO](https://www.php.net/manual/es/book.pdo.php) y el driver de PDO para el motor que estés utilizando (ej. `pdo_mysql` para MySQL). Este es un requisito básico si tu aplicación va a utilizar bases de datos relacionales. diff --git a/docs/guide-es/start-hello.md b/docs/guide-es/start-hello.md index a75f4005393..84b3f969630 100644 --- a/docs/guide-es/start-hello.md +++ b/docs/guide-es/start-hello.md @@ -88,7 +88,7 @@ es llamado en una acción, buscará un archivo PHP llamado `views/ControllerID/N Nota que en el código de arriba, el parámetro `message` es procesado por [[yii\helpers\Html::encode()|HTML-encoded]] antes de ser impreso. Esto es necesario ya que el parámetro viene de un usuario final, haciéndolo vulnerable a -[ataques cross-site scripting (XSS)](http://es.wikipedia.org/wiki/Cross-site_scripting) pudiendo inyectar código de Javascript malicioso dentro del parámetro. +[ataques cross-site scripting (XSS)](https://es.wikipedia.org/wiki/Cross-site_scripting) pudiendo inyectar código de Javascript malicioso dentro del parámetro. Naturalmente, puedes colocar mas contenido en la vista `say`. El contenido puede consistir de etiquetas HTML, texto plano, e inclusive código PHP. De hecho, la vista `say` es sólo un script PHP que es ejecutado por el método [[yii\web\Controller::render()|render()]]. diff --git a/docs/guide-es/start-installation.md b/docs/guide-es/start-installation.md index 90e181ca3e6..be08e85fc52 100644 --- a/docs/guide-es/start-installation.md +++ b/docs/guide-es/start-installation.md @@ -44,7 +44,7 @@ composer global require "fxp/composer-asset-plugin:^1.4.1" composer create-project --prefer-dist yiisoft/yii2-app-basic basic ``` -El primer comando instala [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/), +El primer comando instala [composer asset plugin](https://github.com/fxpio/composer-asset-plugin), que permite administrar dependencias de paquetes bower y npm a través de Composer. Sólo necesitas ejecutar este comando una vez. El segundo comando instala Yii en un directorio llamado `basic`. Puedes elegir un nombre de directorio diferente si así lo deseas. @@ -67,7 +67,7 @@ Instalar desde un Archivo Comprimido --------------------------- Una vez finalizada la instalación, o bien configura tu servidor web (mira la sección siguiente) o utiliza -el [servidor web incluido en PHP](https://secure.php.net/manual/en/features.commandline.webserver.php) ejecutando el siguiente +el [servidor web incluido en PHP](https://www.php.net/manual/en/features.commandline.webserver.php) ejecutando el siguiente comando de consola estando parado en el directorio `web` de la aplicación: ```bash @@ -131,7 +131,7 @@ de PHP satisfaga los requerimientos de Yii. Esto puedes hacerlo usando cualquier ``` Deberías configurar tu instalación de PHP para que satisfaga los requisitos mínimos de Yii. Lo que es más importante, -debes tener PHP 5.4 o mayor. También deberías instalar la [Extensión de PHP PDO](https://secure.php.net/manual/es/pdo.installation.php) +debes tener PHP 5.4 o mayor. También deberías instalar la [Extensión de PHP PDO](https://www.php.net/manual/es/pdo.installation.php) y el correspondiente driver de base de datos (como `pdo_mysql` para bases de datos MySQL), si tu aplicación lo necesitara. @@ -142,8 +142,8 @@ Configurar Servidores Web de poner la aplicación en un servidor de producción. La aplicación instalada siguiendo las instrucciones mencionadas debería estar lista para usar tanto -con un [servidor HTTP Apache](http://httpd.apache.org/) como con un [servidor HTTP Nginx](http://nginx.org/), -en Windows, Mac OS X, o Linux utilizando PHP 5.4 o mayor. Yii 2.0 también es compatible con [HHVM](http://hhvm.com/) +con un [servidor HTTP Apache](https://httpd.apache.org/) como con un [servidor HTTP Nginx](https://nginx.org/), +en Windows, Mac OS X, o Linux utilizando PHP 5.4 o mayor. Yii 2.0 también es compatible con [HHVM](https://hhvm.com/) de Facebook. De todos modos, hay algunos casos donde HHVM se comporta diferente del PHP oficial, por lo que tendrás que tener cuidados extra al utilizarlo. @@ -187,7 +187,7 @@ DocumentRoot "path/to/basic/web" ### Configuración Recomendada de Nginx -Para utilizar [Nginx](http://wiki.nginx.org/), debes instalar PHP como un [FPM SAPI](https://secure.php.net/install.fpm). +Para utilizar [Nginx](https://wiki.nginx.org/), debes instalar PHP como un [FPM SAPI](https://www.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.test` con el hostname real a servir. diff --git a/docs/guide-es/start-looking-ahead.md b/docs/guide-es/start-looking-ahead.md index 39129b378d7..a881087c011 100644 --- a/docs/guide-es/start-looking-ahead.md +++ b/docs/guide-es/start-looking-ahead.md @@ -9,27 +9,27 @@ código automáticamente. Utilizar Gii para la generación de código transforma Esta sección resumirá los recursos disponibles de Yii que te ayudarán a ser más productivo al utilizar el framework. * Documentación - - [La Guía Definitiva](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [La Guía Definitiva](https://www.yiiframework.com/doc-2.0/guide-README.html): Como su nombre lo indica, la guía define precisamente cómo debería trabajar Yii y provee guías generales acerca de su utilización. Es el tutorial más importante de Yii, y el que deberías leer antes de escribir cualquier código en Yii. - - [La Referencia de Clases](http://www.yiiframework.com/doc-2.0/index.html): + - [La Referencia de Clases](https://www.yiiframework.com/doc-2.0/index.html): Esta especifica el uso de cada clase provista por Yii. Debería ser utilizada principalmente cuando estás escribiendo código y deseas entender el uso de una clase, método o propiedad en particular. El uso de la referencia de clases es mejor luego de un entendimiento contextual del framework. - - [Los Artículos de la Wiki](http://www.yiiframework.com/wiki/?tag=yii2): + - [Los Artículos de la Wiki](https://www.yiiframework.com/wiki/?tag=yii2): Los artículos de la wiki son escritos por usuarios de Yii basados en sus propias experiencias. La mayoría de ellos están escritos como recetas de cocina, y muestran cómo resolver problemas particulares utilizando Yii. Si bien la calidad de estos puede no ser tan buena como la de la Guía Definitiva, son útiles ya que cubren un espectro muy amplio de temas y puede proveer a menudo soluciones listas para usar. - - [Libros](http://www.yiiframework.com/doc/) -* [Extensiones](http://www.yiiframework.com/extensions/): + - [Libros](https://www.yiiframework.com/books) +* [Extensiones](https://www.yiiframework.com/extensions/): Yii puede hacer alarde de una librería de miles de extensiones contribuidas por usuarios, que pueden fácilmente conectadas a tu aplicación, haciendo que el desarrollo de la misma sea todavía más fácil y rápido. * Comunidad - - Foro: - - Chat IRC: El canal #yii en la red freenode () + - Foro: + - Chat IRC: El canal #yii en la red Libera () - Chat Gitter: - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide-es/start-prerequisites.md b/docs/guide-es/start-prerequisites.md index bb184eca7ff..d4771f8d998 100644 --- a/docs/guide-es/start-prerequisites.md +++ b/docs/guide-es/start-prerequisites.md @@ -6,11 +6,11 @@ pero todavía hay algunas cosas que debería aprender antes de empezar con Yii. ## PHP Yii es un _framework_ (base estructurada de desarrollo) en PHP, así que asegúrese de -[leer y comprender la referencia del lenguaje](https://secure.php.net/manual/es/langref.php). +[leer y comprender la referencia del lenguaje](https://www.php.net/manual/es/langref.php). Al desarrollar con Yii deberá escribir código de manera orientada a objetos, así que asegúrese de estar familiarizado con -[clases y objetos](https://secure.php.net/manual/es/language.oop5.basic.php) así como con -[espacios de nombres](https://secure.php.net/manual/es/language.namespaces.php). +[clases y objetos](https://www.php.net/manual/es/language.oop5.basic.php) así como con +[espacios de nombres](https://www.php.net/manual/es/language.namespaces.php). ## Programación orientada a objetos diff --git a/docs/guide-es/start-workflow.md b/docs/guide-es/start-workflow.md index 2695c3e8898..c25a18091f1 100644 --- a/docs/guide-es/start-workflow.md +++ b/docs/guide-es/start-workflow.md @@ -42,7 +42,7 @@ Estructura de la aplicación Los archivos y directorios más importantes en tu aplicación son (asumiendo que la raíz de la aplicación es `basic`): -``` +```js basic/ base path de la aplicación composer.json archivo utilizado por Composer, describe información de sus paquetes y librerías config/ contiene la configuración de las aplicaciones (y otras) @@ -63,7 +63,7 @@ basic/ base path de la aplicación En general, los archivos de la aplicación pueden ser divididos en dos: aquellos bajo `basic/web` y aquellos bajo otros directorios. Los primeros pueden accederse directo por HTTP (ej., en un navegador), mientras que los últimos no pueden ni deben ser accedidos así. -Yii implementa el patrón de diseño [modelo-vista-controlador (MVC)](http://wikipedia.org/wiki/Model-view-controller), +Yii implementa el patrón de diseño [modelo-vista-controlador (MVC)](https://wikipedia.org/wiki/Model-view-controller), que es reflejado en la estructura de directorios utilizada. El directorio `models` contiene todas las [clases del modelo](structure-models.md), el directorio `views` contiene todas las [vistas (templates)](structure-views.md), y el directorio `controllers` contiene todas las [clases de controladores](structure-controllers.md). diff --git a/docs/guide-es/structure-applications.md b/docs/guide-es/structure-applications.md index bf85cba98a2..d01e1a6ec2c 100644 --- a/docs/guide-es/structure-applications.md +++ b/docs/guide-es/structure-applications.md @@ -255,7 +255,7 @@ incluido la traducción de mensajes, formato de fecha y números, etc. Por ejemp utilizará el valor de esta propiedad para determinar en qué idioma el calendario debe ser mostrado y cómo dar formato a la fecha. -Se recomienda que especifiques el idioma en términos de una [Código de idioma IETF](http://es.wikipedia.org/wiki/Código_de_idioma_IETF). +Se recomienda que especifiques el idioma en términos de una [Código de idioma IETF](https://es.wikipedia.org/wiki/Código_de_idioma_IETF). Por ejemplo, `en` se refiere a English, mientras que `en-US` se refiere a English (United States). Se pueden encontrar más detalles de este aspecto en la sección [Internacionalización](tutorial-i18n.md). @@ -326,7 +326,7 @@ sin necesidad de tocar el código que lo utiliza. Esta propiedad especifica el idioma en el cual la aplicación está escrita. El valor por defecto es `'en-US'`, referido a English (United States). Deberías configurar esta propiedad si el contenido de texto en tu código no está en inglés. -Como la propiedad [language](#language), deberías configurar esta propiedad siguiendo el [Código de idioma IETF](http://es.wikipedia.org/wiki/Código_de_idioma_IETF). +Como la propiedad [language](#language), deberías configurar esta propiedad siguiendo el [Código de idioma IETF](https://es.wikipedia.org/wiki/Código_de_idioma_IETF). Por ejemplo, `en` se refiere a English, mientras que `en-US` se refiere a English (United States). Puedes encontrar más detalles de esta propiedad en la sección [Internacionalización](tutorial-i18n.md). @@ -335,7 +335,7 @@ Puedes encontrar más detalles de esta propiedad en la sección [Internacionaliz #### [[yii\base\Application::timeZone|timeZone]] Esta propiedad es provista como una forma alternativa de definir el `time zone` de PHP por defecto en tiempo de ejecución. -Configurando esta propiedad, escencialmente estás llamando a la función de PHP [date_default_timezone_set()](https://secure.php.net/manual/es/function.date-default-timezone-set.php). +Configurando esta propiedad, escencialmente estás llamando a la función de PHP [date_default_timezone_set()](https://www.php.net/manual/es/function.date-default-timezone-set.php). Por ejemplo: ```php diff --git a/docs/guide-es/structure-assets.md b/docs/guide-es/structure-assets.md index 0231d53c430..7edbf5d1b1b 100644 --- a/docs/guide-es/structure-assets.md +++ b/docs/guide-es/structure-assets.md @@ -74,7 +74,7 @@ A continuación se explicarán más detalladamente las propiedades del [[yii\web se puede determinar anteponiendo [[yii\web\AssetManager::basePath]] a la ruta relativa, y la URL actual de un archivo puede ser determinada anteponiendo [[yii\web\AssetManager::baseUrl]] a la ruta relativa. - una URL absoluta que represente un archivo JavaScript externo. Por ejemplo, - `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` o + `https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` o `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. * [[yii\web\AssetBundle::css|css]]: un array que lista los archivos CSS que contiene este bundle. El formato de este array es el mismo que el de [[yii\web\AssetBundle::js|js]]. @@ -202,12 +202,12 @@ class FontAwesomeAsset extends AssetBundle } ``` -El ejemplo anterior define un asset bundle para el ["fontawesome" package](http://fontawesome.io/). Especificando +El ejemplo anterior define un asset bundle para el ["fontawesome" package](https://fontawesome.com/). Especificando la opción de publicación `beforeCopy`, solo los subdirectorios `fonts` y `css` serán publicados. ### Bower y NPM Assets -La mayoría de paquetes JavaScript/CSS se gestionan con [Bower](http://bower.io/) y/o [NPM](https://www.npmjs.org/). +La mayoría de paquetes JavaScript/CSS se gestionan con [Bower](https://bower.io/) y/o [NPM](https://www.npmjs.com/). Si tu aplicación o extensión usa estos paquetes, se recomienda seguir los siguientes pasos para gestionar los assets en la librería: @@ -393,8 +393,8 @@ personalizar como se describe en la subsección [Personalización de Asset Bundl En lugar de escribir código CSS y/o JavaScript directamente, los desarrolladores a menudo escriben código usando una sintaxis extendida y usan herramientas especiales para convertirlos en CSS/JavaScript. Por ejemplo, para código CSS se -puede usar [LESS](http://lesscss.org) o [SCSS](http://sass-lang.com/); y para JavaScript se puede usar -[TypeScript](http://www.typescriptlang.org/). +puede usar [LESS](https://lesscss.org) o [SCSS](https://sass-lang.com/); y para JavaScript se puede usar +[TypeScript](https://www.typescriptlang.org/). Se pueden listar los archivos asset con sintaxis extendida (extended syntax) en [[yii\web\AssetBundle::css|css]] y [[yii\web\AssetBundle::js|js]] en un asset bundle. Por ejemplo: @@ -425,14 +425,14 @@ en la página, en lugar de los assets originales en sintaxis extendidas. Yii usa las extensiones de archivo para identificar que sintaxis extendida se está usando. De forma predeterminada se reconocen las siguientes sintaxis y extensiones de archivo. -- [LESS](http://lesscss.org/): `.less` -- [SCSS](http://sass-lang.com/): `.scss` -- [Stylus](http://learnboost.github.io/stylus/): `.styl` -- [CoffeeScript](http://coffeescript.org/): `.coffee` -- [TypeScript](http://www.typescriptlang.org/): `.ts` +- [LESS](https://lesscss.org/): `.less` +- [SCSS](https://sass-lang.com/): `.scss` +- [Stylus](https://stylus-lang.com/): `.styl` +- [CoffeeScript](https://coffeescript.org/): `.coffee` +- [TypeScript](https://www.typescriptlang.org/): `.ts` Yii se basa en las herramientas pre-procesadoras instalada para convertir los assets. Por ejemplo, para usar -[LESS](http://lesscss.org/) se debe instalar el comando pre-procesador `lessc`. +[LESS](https://lesscss.org/) se debe instalar el comando pre-procesador `lessc`. Se pueden personalizar los comandos de los pre-procesadores y las sintaxis extendidas soportadas configurando [[yii\web\AssetManager::converter]] como en el siguiente ejemplo: @@ -460,7 +460,7 @@ Los tokens `{from}` y `{to}` en los comandos se reemplazarán por las rutas de o de destino de los archivos asset. > Info: Hay otras maneras de trabajar con las assets de sintaxis extendidas, además de la descrita - anteriormente. Por ejemplo, se pueden usar herramientas generadoras tales como [grunt](http://gruntjs.com/) para + anteriormente. Por ejemplo, se pueden usar herramientas generadoras tales como [grunt](https://gruntjs.com/) para monitorear y convertir automáticamente los assets de sintaxis extendidas. En este caso, se deben listar los archivos CSS/JavaScript resultantes en lugar de los archivos de originales. @@ -641,5 +641,5 @@ El archivo de configuración generado se puede incluir en la configuración de l anterior subsección. > Info: Usar el comando `asset` no es la única opción de automatizar el proceso de combinación y compresión. - Se puede usar la excelente herramienta de ejecución de tareas [grunt](http://gruntjs.com/) para lograr el mismo + Se puede usar la excelente herramienta de ejecución de tareas [grunt](https://gruntjs.com/) para lograr el mismo objetivo. diff --git a/docs/guide-es/structure-controllers.md b/docs/guide-es/structure-controllers.md index c9fb8b0b674..bbb9a4bc55c 100644 --- a/docs/guide-es/structure-controllers.md +++ b/docs/guide-es/structure-controllers.md @@ -1,7 +1,7 @@ Controladores ============= -Los controladores son parte del patrón o arquitectura [MVC](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). +Los controladores son parte del patrón o arquitectura [MVC](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Son objetos que extienden de [[yii\base\Controller]] y se encargan de procesar los `requests` (consultas) generando `responses` (respuestas). Particularmente, después de tomar el control desde las [aplicaciones](structure-applications.md), los controladores analizarán los datos que entran en el `request`, los pasan a los [modelos](structure-models.md), inyectan los diff --git a/docs/guide-es/structure-entry-scripts.md b/docs/guide-es/structure-entry-scripts.md index 162f9ecb6ed..b2f69af8da0 100644 --- a/docs/guide-es/structure-entry-scripts.md +++ b/docs/guide-es/structure-entry-scripts.md @@ -56,9 +56,9 @@ De la misma manera, el siguiente código es el script de entrada para la [aplica /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-es/structure-extensions.md b/docs/guide-es/structure-extensions.md index 31d7585478b..b157a9fbb83 100644 --- a/docs/guide-es/structure-extensions.md +++ b/docs/guide-es/structure-extensions.md @@ -81,7 +81,7 @@ En algunas ocasiones excepcionales es posible que tengamos que instalar alguna o 3. descargar e instalar todas las extensiones dependientes como siguiendo estas mismas instrucciones. Si una extensión no proporciona clase de autocarga pero sigue el estándar -[PSR-4](http://www.php-fig.org/psr/psr-4/), se puede usar la clase de autocarga proporcionada por Yii para cargar +[PSR-4](https://www.php-fig.org/psr/psr-4/), se puede usar la clase de autocarga proporcionada por Yii para cargar automáticamente las clases de las extensiones. Todo lo que se tiene que hacer es declarar un [alias de raíz (root)](concept-aliases.md#defining-aliases) para las extensiones del directorio raíz. Por ejemplo, asumiendo que tenemos instalada una extensión en el directorio `vendor/mycompany/myext`, y las clases de extensión se @@ -135,9 +135,9 @@ muestra el archivo `composer.json` para la extensión `yiisoft/yii2-imagine`: "license": "BSD-3-Clause", "support": { "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki/", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "authors": [ @@ -193,8 +193,8 @@ La extensión depende de Yii (por supuesto). Por ello se debe añadir (`yiisoft/ apropiadas (ej. `1.*`, `@stable`) para cada paquete dependiente. Se deben usar dependencias estables en versiones estables de nuestras extensiones. -La mayoría de paquetes JavaScript/CSS se gestionan usando [Bower](http://bower.io/) y/o [NPM](https://www.npmjs.org/), -en lugar de Composer. Yii utiliza el [Composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin) +La mayoría de paquetes JavaScript/CSS se gestionan usando [Bower](https://bower.io/) y/o [NPM](https://www.npmjs.com/), +en lugar de Composer. Yii utiliza el [Composer asset plugin](https://github.com/fxpio/composer-asset-plugin) para habilitar la gestión de estos tipos de paquetes a través de Composer. Si la extensión depende de un paquete Bower, se puede, simplemente, añadir la dependencia de el archivo `composer.json` como se muestra a continuación: @@ -248,8 +248,8 @@ extensiones de alta calidad. #### Namespaces Para evitar colisiones de nombres y permitir que las clases usen la autocarga en extensiones propias, se deben usar -namespaces y nombres de clase siguiendo el [estándar PSR-4](http://www.php-fig.org/psr/psr-4/) o el -[estándar PSR-0](http://www.php-fig.org/psr/psr-0/). +namespaces y nombres de clase siguiendo el [estándar PSR-4](https://www.php-fig.org/psr/psr-4/) o el +[estándar PSR-0](https://www.php-fig.org/psr/psr-0/). Los namespaces de clases propias deben empezar por `NombreProveedor\NombreExtension` donde `NombreExtension` es similar al nombre del paquete pero este no debe contener el prefijo `yii2-`. Por ejemplo, para la extensión @@ -359,7 +359,7 @@ pruebas unitarias (unit tests), pruebas de aceptación (acceptance tests) y prue #### Versiones Se debe asignar un número de versión cada vez que se lance una nueva distribución. (ej. `1.0.1`). Recomendamos -seguir la práctica [Versionamiento Semántico](http://semver.org/lang/es/) para determinar que números se deben usar. +seguir la práctica [Versionamiento Semántico](https://semver.org/lang/es/) para determinar que números se deben usar. #### Lanzamientos @@ -375,7 +375,7 @@ En los lanzamientos de una extensión, además de archivos de código, también mencionados a continuación para facilitar a otra gente el uso de nuestra extensión: * Un archivo léame (readme) en el directorio raíz: describe que hace la extensión y como instalarla y utilizarla. - Recomendamos que se escriba en formato [Markdown](http://daringfireball.net/projects/markdown/) y llamarlo + Recomendamos que se escriba en formato [Markdown](https://daringfireball.net/projects/markdown/) y llamarlo `readme.md`. * Un archivo de registro de cambios (changelog) en el directorio raíz: enumera que cambios se realizan en cada lanzamiento. El archivo puede escribirse en formato Markdown y llamarlo `changelog.md`. @@ -392,7 +392,7 @@ mencionados a continuación para facilitar a otra gente el uso de nuestra extens > Info: Aunque no es un requerimiento, se recomienda que la extensión se adhiera a ciertos estilos de codificación. Se puede hacer referencia a - [estilo de código del núcleo del framework](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style) para + [estilo de código del núcleo del framework](https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md) para obtener más detalles. ## Extensiones del Núcleo @@ -406,14 +406,12 @@ se describe en la subsección [Uso de Extensiones](#using-extensions) - [yiisoft/yii2-authclient](https://github.com/yiisoft/yii2-authclient):proporciona un conjunto de clientes de autorización tales como el cliente OAuth2 de Facebook, el cliente GitHub OAuth2. - [yiisoft/yii2-bootstrap](https://github.com/yiisoft/yii2-bootstrap): proporciona un conjunto de widgets que - encapsulan los componentes y plugins de [Bootstrap](http://getbootstrap.com/). -- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception): proporciona soporte de testing basado en - [Codeception](http://codeception.com/). + encapsulan los componentes y plugins de [Bootstrap](https://getbootstrap.com/). - [yiisoft/yii2-debug](https://github.com/yiisoft/yii2-debug): proporciona soporte de depuración para aplicaciones Yii. Cuando se usa esta extensión, aparece una barra de herramientas de depuración en la parte inferior de cada página. La extensión también proporciona un conjunto de páginas para mostrar información detallada de depuración. - [yiisoft/yii2-elasticsearch](https://github.com/yiisoft/yii2-elasticsearch): proporciona soporte para usar - [Elasticsearch](http://www.elasticsearch.org/). Incluye soporte básico para realizar consultas/búsquedas y también + [Elasticsearch](https://www.elastic.co/). Incluye soporte básico para realizar consultas/búsquedas y también implementa patrones de [Active Record](db-active-record.md) que permiten y permite guardar los `active records` en Elasticsearch. - [yiisoft/yii2-faker](https://github.com/yiisoft/yii2-faker): proporciona soporte para usar @@ -423,20 +421,20 @@ se describe en la subsección [Uso de Extensiones](#using-extensions) - [yiisoft/yii2-httpclient](https://github.com/yiisoft/yii2-httpclient): provides an HTTP client. - [yiisoft/yii2-imagine](https://github.com/yiisoft/yii2-imagine): proporciona funciones comunes de manipulación de - imágenes basadas en [Imagine](http://imagine.readthedocs.org/). + imágenes basadas en [Imagine](https://imagine.readthedocs.org/). - [yiisoft/yii2-jui](https://github.com/yiisoft/yii2-jui): proporciona un conjunto de widgets que encapsulan las - iteraciones y widgets de [JQuery UI](http://jqueryui.com/). + iteraciones y widgets de [JQuery UI](https://jqueryui.com/). - [yiisoft/yii2-mongodb](https://github.com/yiisoft/yii2-mongodb): proporciona soporte para utilizar - [MongoDB](http://www.mongodb.org/). incluye características como consultas básicas, Active Record, migraciones, + [MongoDB](https://www.mongodb.com/). incluye características como consultas básicas, Active Record, migraciones, caching, generación de código, etc. - [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis): proporciona soporte para utilizar - [redis](http://redis.io/). incluye características como consultas básicas, Active Record, caching, etc. + [redis](https://redis.io/). incluye características como consultas básicas, Active Record, caching, etc. - [yiisoft/yii2-smarty](https://github.com/yiisoft/yii2-smarty): proporciona un motor de plantillas basado en - [Smarty](http://www.smarty.net/). + [Smarty](https://www.smarty.net/). - [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx): proporciona soporte para utilizar - [Sphinx](http://sphinxsearch.com). incluye características como consultas básicas, Active Record, code generation, + [Sphinx](https://sphinxsearch.com). incluye características como consultas básicas, Active Record, code generation, etc. - [yiisoft/yii2-swiftmailer](https://github.com/yiisoft/yii2-swiftmailer): proporciona características de envío de correos electrónicos basadas en [swiftmailer](http://swiftmailer.org/). - [yiisoft/yii2-twig](https://github.com/yiisoft/yii2-twig): proporciona un motor de plantillas basado en - [Twig](http://twig.sensiolabs.org/). + [Twig](https://twig.symfony.com/). diff --git a/docs/guide-es/structure-filters.md b/docs/guide-es/structure-filters.md index a54ddc3c08d..d096655ab1c 100644 --- a/docs/guide-es/structure-filters.md +++ b/docs/guide-es/structure-filters.md @@ -124,7 +124,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['create', 'update'], 'rules' => [ // permitido para usuarios autenticados @@ -145,8 +145,8 @@ Para conocer más detalles acerca del control de acceso en general, refiérase a ### Filtros del Método de Autenticación Los filtros del método de autenticación se usan para autenticar a un usuario utilizando varios métodos, tales como la -[Autenticación de acceso básico HTTP](http://es.wikipedia.org/wiki/Autenticaci%C3%B3n_de_acceso_b%C3%A1sica), -[Oauth 2](http://oauth.net/2/). Estas clases de filtros se encuentran en el espacio de nombres `yii\filters\auth`. +[Autenticación de acceso básico HTTP](https://es.wikipedia.org/wiki/Autenticaci%C3%B3n_de_acceso_b%C3%A1sica), +[Oauth 2](https://oauth.net/2/). Estas clases de filtros se encuentran en el espacio de nombres `yii\filters\auth`. El siguiente ejemplo muestra como usar [[yii\filters\auth\HttpBasicAuth]] para autenticar un usuario usando un token de acceso basado en el método de Autenticación de acceso básico HTTP. Tenga en cuenta que para que esto funcione, la @@ -160,7 +160,7 @@ public function behaviors() { return [ 'basicAuth' => [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ], ]; } @@ -185,7 +185,7 @@ public function behaviors() { return [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -212,7 +212,7 @@ use yii\web\Response; [ 'bootstrap' => [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -242,7 +242,7 @@ public function behaviors() { return [ [ - 'class' => HttpCache::className(), + 'class' => HttpCache::class, 'only' => ['index'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); @@ -270,11 +270,11 @@ public function behaviors() { return [ 'pageCache' => [ - 'class' => PageCache::className(), + 'class' => PageCache::class, 'only' => ['index'], 'duration' => 60, 'dependency' => [ - 'class' => DbDependency::className(), + 'class' => DbDependency::class, 'sql' => 'SELECT COUNT(*) FROM post', ], 'variations' => [ @@ -290,7 +290,7 @@ Por favor refiérase a [Caché de Páginas](caching-page.md) para obtener más d ### [[yii\filters\RateLimiter|RateLimiter]] RateLimiter implementa un algoritmo de para limitar la tasa de descarga basándose en -[leaky bucket algorithm](http://en.wikipedia.org/wiki/Leaky_bucket). Este se utiliza sobre todo en la implementación +[leaky bucket algorithm](https://en.wikipedia.org/wiki/Leaky_bucket). Este se utiliza sobre todo en la implementación de APIs RESTful. Por favor, refiérase a la sección [limite de tasa](rest-rate-limiting.md) para obtener más detalles acerca de el uso de este filtro. @@ -307,7 +307,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'index' => ['get'], 'view' => ['get'], @@ -339,7 +339,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, ], ], parent::behaviors()); } @@ -366,7 +366,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], @@ -387,7 +387,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], diff --git a/docs/guide-es/structure-models.md b/docs/guide-es/structure-models.md index 5a24142d803..d6dd7d80611 100644 --- a/docs/guide-es/structure-models.md +++ b/docs/guide-es/structure-models.md @@ -2,7 +2,7 @@ Modelos ======= Los modelos forman parte de la arquitectura -[MVC](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Son objetos que representan datos de +[MVC](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Son objetos que representan datos de negocio, reglas y lógica. Se pueden crear clases modelo extendiendo a [[yii\base\Model]] o a sus clases hijas. La clase base [[yii\base\Model]] @@ -39,8 +39,8 @@ echo $model->name; ``` También se puede acceder a los atributos como se accede a los elementos de un array, gracias al soporte para -[ArrayAccess](https://secure.php.net/manual/es/class.arrayaccess.php) y -[ArrayIterator](https://secure.php.net/manual/es/class.arrayiterator.php) que brinda [[yii\base\Model]]: +[ArrayAccess](https://www.php.net/manual/es/class.arrayaccess.php) y +[ArrayIterator](https://www.php.net/manual/es/class.arrayiterator.php) que brinda [[yii\base\Model]]: ```php $model = new \app\models\ContactForm; diff --git a/docs/guide-es/structure-modules.md b/docs/guide-es/structure-modules.md index 5e7c282220e..19964295a73 100644 --- a/docs/guide-es/structure-modules.md +++ b/docs/guide-es/structure-modules.md @@ -14,7 +14,7 @@ módulo. Dentro de este directorio, hay subdirectorios tales como 'controllers', controladores, modelos, vistas y otro código, exactamente como una aplicación. El siguiente ejemplo muestra el contenido dentro de un módulo: -``` +```js forum/ Module.php archivo clase módulo controllers/ contiene archivos de la clase controlador diff --git a/docs/guide-es/structure-overview.md b/docs/guide-es/structure-overview.md index e03c84298fa..a8c1b76f945 100644 --- a/docs/guide-es/structure-overview.md +++ b/docs/guide-es/structure-overview.md @@ -1,7 +1,7 @@ Información general =================== -Las aplicaciones realizadas con Yii están organizadas de acuerdo al patrón de diseño [modelo-vista-controlador (MVC)](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Los +Las aplicaciones realizadas con Yii están organizadas de acuerdo al patrón de diseño [modelo-vista-controlador (MVC)](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Los [modelos](structure-models.md) representan datos, la lógica de negocios y sus reglas; las [vistas](structure-views.md) son la representación de salida de los modelos; y finalmente, los [controladores](structure-controllers.md) que toman datos de entrada y los convierten en instrucciones para los [modelos](structure-models.md) y [vistas](structure-views.md). diff --git a/docs/guide-es/structure-views.md b/docs/guide-es/structure-views.md index b32a3f3a82d..e5a7068a33c 100644 --- a/docs/guide-es/structure-views.md +++ b/docs/guide-es/structure-views.md @@ -1,7 +1,7 @@ Vistas ====== -Las Vistas (views) son una parte de la arquitectura [MVC](http://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). +Las Vistas (views) son una parte de la arquitectura [MVC](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Estas son el código responsable de presentar los datos al usuario final. En una aplicación Web, las vistas son usualmente creadas en términos de *templates* que son archivos PHP que contienen principalmente HTML y PHP. Estas son manejadas por el [componente de la aplicación](structure-application-components.md) [[yii\web\View|view]], el cual provee los métodos comúnmente utilizados @@ -52,7 +52,7 @@ o algún otro objeto que dispara la [renderización de la vista](#rendering-view Al crear vistas que generan páginas HTML, es importante que codifiques (encode) y/o filtres los datos provenientes de los usuarios antes de mostrarlos. De otro modo, tu aplicación puede estar expuesta -a ataques tipo [cross-site scripting](http://es.wikipedia.org/wiki/Cross-site_scripting). +a ataques tipo [cross-site scripting](https://es.wikipedia.org/wiki/Cross-site_scripting). Para mostrar un texto plano, codifícalos previamente utilizando [[yii\helpers\Html::encode()]]. Por ejemplo, el siguiente código aplica una codificación del nombre de usuario antes de mostrarlo: @@ -545,7 +545,7 @@ Los componentes de vista proveen las siguientes características útiles, cada u * [manejo de scripts del cliente](output-client-scripts.md): soporte para registro y renderización de CSS y JavaScript. * [manejo de asset bundle](structure-assets.md): soporte de registro y renderización de [asset bundles](structure-assets.md). * [motores de template alternativos](tutorial-template-engines.md): te permite utilizar otros motores de templates, como - [Twig](http://twig.sensiolabs.org/) o [Smarty](http://www.smarty.net/). + [Twig](https://twig.symfony.com/) o [Smarty](https://www.smarty.net/). Puedes también utilizar frecuentemente el siguiente menor pero útil grupo de características al desarrollar páginas Web. @@ -616,14 +616,14 @@ $this->registerLinkTag([ 'title' => 'Noticias en Vivo de Yii', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` El resultado del código es el siguiente: ```html - + ``` Al igual que con [[yii\web\View::registerMetaTag()|registerMetaTags()]], puedes especificar una clave al llamar diff --git a/docs/guide-es/structure-widgets.md b/docs/guide-es/structure-widgets.md index 87273a01b86..75b9f904359 100644 --- a/docs/guide-es/structure-widgets.md +++ b/docs/guide-es/structure-widgets.md @@ -72,7 +72,7 @@ Hay que tener en cuenta que, a diferencia de [[yii\base\Widget::widget()]] que d representación resultante del _widget_, el método [[yii\base\Widget::begin()]] devuelve una instancia del _widget_, que se puede usar para generar el contenido del _widget_. -> Nota: Algunos _widgets_ utilizan un [búfer de salida](https://secure.php.net/manual/es/book.outcontrol.php) +> Nota: Algunos _widgets_ utilizan un [búfer de salida](https://www.php.net/manual/es/book.outcontrol.php) > para ajustar el contenido rodeado al invocar [[yii\base\Widget::end()]]. Por este motivo se espera > que las llamadas a [[yii\base\Widget::begin()]] y [[yii\base\Widget::end()]] tengan lugar en el > mismo fichero de vista. diff --git a/docs/guide-es/test-acceptance.md b/docs/guide-es/test-acceptance.md index 8df65e44dbc..f9e16082b8e 100644 --- a/docs/guide-es/test-acceptance.md +++ b/docs/guide-es/test-acceptance.md @@ -9,8 +9,8 @@ servida por un servidor web. Los tests de aceptación se implementan con ayuda del _framework_ Codeception, que tiene una buena documentación: -- [Codeception para el _framework_ Yii](http://codeception.com/for/yii) -- [Tests funcionales de Codeception](http://codeception.com/docs/04-FunctionalTests) +- [Codeception para el _framework_ Yii](https://codeception.com/for/yii) +- [Tests funcionales de Codeception](https://codeception.com/docs/04-FunctionalTests) ## Ejecución de tests en las plantillas básica y avanzada diff --git a/docs/guide-es/test-fixtures.md b/docs/guide-es/test-fixtures.md index 238f636aa32..c17a0fc579b 100644 --- a/docs/guide-es/test-fixtures.md +++ b/docs/guide-es/test-fixtures.md @@ -108,7 +108,7 @@ Arriba te mostramos cómo definir un fixture de BD. Para definir un fixture no r Utilizar Fixtures ----------------- -Si estás utilizando [Codeception](http://codeception.com/) para hacer tests de tu código, deberías considerar el utilizar +Si estás utilizando [Codeception](https://codeception.com/) para hacer tests de tu código, deberías considerar el utilizar la extensión `yii2-codeception`, que tiene soporte incorporado para la carga y acceso a fixtures. En caso de que utilices otros frameworks de testing, puedes usar [[yii\test\FixtureTrait]] en tus casos de tests para alcanzar el mismo objetivo. @@ -129,7 +129,7 @@ class UserProfileTest extends DbTestCase public function fixtures() { return [ - 'profiles' => UserProfileFixture::className(), + 'profiles' => UserProfileFixture::class, ]; } diff --git a/docs/guide-es/test-functional.md b/docs/guide-es/test-functional.md index b48238cb2cd..cf1eea4ab1f 100644 --- a/docs/guide-es/test-functional.md +++ b/docs/guide-es/test-functional.md @@ -14,8 +14,8 @@ web especial o una interfaz de usuario compleja en Javascript. Las pruebas funcionales se implementan con ayuda del _framework_ Codeception, que tiene una buena documentación: -- [Codeception para el _framework_ Yii](http://codeception.com/for/yii) -- [Tests funcionales de Codeception](http://codeception.com/docs/04-FunctionalTests) +- [Codeception para el _framework_ Yii](https://codeception.com/for/yii) +- [Tests funcionales de Codeception](https://codeception.com/docs/04-FunctionalTests) ## Ejecución de tests en las plantillas básica y avanzada diff --git a/docs/guide-es/test-unit.md b/docs/guide-es/test-unit.md index c6b47adfc61..d5054edc69a 100644 --- a/docs/guide-es/test-unit.md +++ b/docs/guide-es/test-unit.md @@ -8,9 +8,9 @@ Normalmente los tests unitarios son desarrollados por la persona que escribe las Los tests unitarios en Yii están construidos en base a PHPUnit y, opcionalmente, Codeception, por lo que se recomienda consultar su respectiva documentación: -- [Codeception para el _framework_ Yii](http://codeception.com/for/yii) -- [Tests unitarios con Codeception](http://codeception.com/docs/05-UnitTests) -- [Documentación de PHPUnit, empezando por el capítulo 2](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html) +- [Codeception para el _framework_ Yii](https://codeception.com/for/yii) +- [Tests unitarios con Codeception](https://codeception.com/docs/05-UnitTests) +- [Documentación de PHPUnit, empezando por el capítulo 2](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html) ## Ejecución de tests en las plantillas básica y avanzada diff --git a/docs/guide-es/tutorial-core-validators.md b/docs/guide-es/tutorial-core-validators.md index cbb93f9c944..86030ff8f78 100644 --- a/docs/guide-es/tutorial-core-validators.md +++ b/docs/guide-es/tutorial-core-validators.md @@ -95,8 +95,8 @@ Este validador comprueba si el valor de entrada es una fecha, tiempo or fecha/ti Opcionalmente, puede convertir el valor de entrada en una fecha/tiempo UNIX y almacenarla en un atributo especificado vía [[yii\validators\DateValidator::timestampAttribute|timestampAttribute]]. - `format`: el formato fecha/tiempo en el que debe estar el valor a ser validado. - Esto tiene que ser un patrón fecha/tiempo descrito en [manual ICU](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). - Alternativamente tiene que ser una cadena con el prefijo `php:` representando un formato que ha de ser reconocido por la clase `Datetime` de PHP. Por favor, refiérase a sobre los formatos soportados. + Esto tiene que ser un patrón fecha/tiempo descrito en [manual ICU](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax). + Alternativamente tiene que ser una cadena con el prefijo `php:` representando un formato que ha de ser reconocido por la clase `Datetime` de PHP. Por favor, refiérase a sobre los formatos soportados. Si no tiene ningún valor, ha de coger el valor de `Yii::$app->formatter->dateFormat`. - `timestampAttribute`: el nombre del atributo al cual este validador puede asignar el fecha/hora UNIX convertida desde la entrada fecha/hora. diff --git a/docs/guide-es/tutorial-start-from-scratch.md b/docs/guide-es/tutorial-start-from-scratch.md index ca5e7851794..9633b9964da 100644 --- a/docs/guide-es/tutorial-start-from-scratch.md +++ b/docs/guide-es/tutorial-start-from-scratch.md @@ -39,7 +39,7 @@ Luego, pasa a modificar la estructura y contenido de la aplicación como te gust Hacer un Paquete ---------------- -Con el template definido, crea un repositorio Git a partir de él, y sube tus archivos ahí. Si tu template va a ser de código abierto, [Github](http://github.com) es el mejor lugar para alojarlo. Si tu intención es que el template no sea colaborativo, cualquier sitio de repositorios Git servirá. +Con el template definido, crea un repositorio Git a partir de él, y sube tus archivos ahí. Si tu template va a ser de código abierto, [Github](https://github.com) es el mejor lugar para alojarlo. Si tu intención es que el template no sea colaborativo, cualquier sitio de repositorios Git servirá. Ahora, necesitas registrar tu paquete para Composer. Para templates públicos, el paquete debe ser registrado en [Packagist](https://packagist.org/). Para templates privados, es un poco más complicado registrarlo. Puedes ver instrucciones para hacerlo en la [documentación de Composer](https://getcomposer.org/doc/05-repositories.md#hosting-your-own). diff --git a/docs/guide-es/tutorial-template-engines.md b/docs/guide-es/tutorial-template-engines.md index 931babc0006..100b1f920af 100644 --- a/docs/guide-es/tutorial-template-engines.md +++ b/docs/guide-es/tutorial-template-engines.md @@ -2,7 +2,7 @@ Usar motores de plantillas ========================== Por defecto, Yii utiliza PHP como su lenguaje de plantilla, pero puedes configurar Yii para que soporte otros motores de renderizado, tal como -[Twig](http://twig.sensiolabs.org/) o [Smarty](http://www.smarty.net/), disponibles como extensiones. +[Twig](https://twig.symfony.com/) o [Smarty](https://www.smarty.net/), disponibles como extensiones. El componente `view` es el responsable de renderizar las vistas. Puedes agregar un motor de plantillas personalizado reconfigurando el comportamiento (behavior) de este componente: diff --git a/docs/guide-es/tutorial-yii-integration.md b/docs/guide-es/tutorial-yii-integration.md index 22d80b1bfc9..11407090c26 100644 --- a/docs/guide-es/tutorial-yii-integration.md +++ b/docs/guide-es/tutorial-yii-integration.md @@ -41,7 +41,7 @@ Si la librería lleva su propio cargador automático (autoloader), puedes instal Es recomendable que la instalación se termine antes de incluir el fichero `Yii.php` de forma que el cargador automático tenga precedencia al cargar de forma automática las clases. -Si la librería no provee un cargador automático de clases, pero la denominación de sus clases sigue el [PSR-4](http://www.php-fig.org/psr/psr-4/), +Si la librería no provee un cargador automático de clases, pero la denominación de sus clases sigue el [PSR-4](https://www.php-fig.org/psr/psr-4/), puedes usar el cargador automático de Yii para cargar de forma automática las clases. Todo lo que necesitas es declarar un [alias raíz](concept-aliases.md#defining-aliases) para cada espacio de nombres (namespace) raiz usado en sus clases. Por ejemplo, asume que has instalado una librería en el directorio `vendor/foo/bar`, y que las clases de la librería están bajo el espacio de nombres raiz `xyz`. @@ -86,7 +86,7 @@ para instalar Yii: composer require yiisoft/yii2 composer install -El primer comando instala el [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/), +El primer comando instala el [composer asset plugin](https://github.com/fxpio/composer-asset-plugin), que permite administrar paquetes bower y npm a través de Composer. Incluso si sólo quieres utilizar la capa de base de datos u otra característica de Yii no relacionada a assets, requiere que instales el paquete composer de Yii. @@ -108,7 +108,7 @@ a la sección `extra` de tu `composer.json`: Visita también la [sección de cómo instalar Yii](start-installation.md#installing-via-composer) para más información sobre Composer y sobre cómo solucionar posibles problemas que surjan durante la instalación. -En otro caso, puedes [descargar](http://www.yiiframework.com/download/) el archivo de la edición de Yii +En otro caso, puedes [descargar](https://www.yiiframework.com/download/) el archivo de la edición de Yii y desempaquetarla en el directorio `BasePath/vendor`. Después, debes de modificar el script de entrada de sistema de terceros para incluir el siguiente código al principio: diff --git a/docs/guide-fr/README.md b/docs/guide-fr/README.md index 642d3484820..dc1bf735705 100644 --- a/docs/guide-fr/README.md +++ b/docs/guide-fr/README.md @@ -1,7 +1,7 @@ Guide définitif pour Yii 2.0 ============================ -Ce guide est soumis aux [Conditions de la Documentation de Yii](http://www.yiiframework.com/doc/terms/). +Ce guide est soumis aux [Conditions de la Documentation de Yii](https://www.yiiframework.com/doc/terms/). Tous droits réservés. diff --git a/docs/guide-fr/caching-data.md b/docs/guide-fr/caching-data.md index 1763ef3bb15..09a5c3d50c9 100644 --- a/docs/guide-fr/caching-data.md +++ b/docs/guide-fr/caching-data.md @@ -49,7 +49,7 @@ $data = $cache->getOrSet($key, function () use ($user_id) { La mise en cache s'appuie sur ce qu'on appelle les *composants de mise en cache* qui représentent des supports de mise en cache tels que les mémoires, les fichiers et les bases de données. -Les composants de mise en cache sont généralement enregistrés en tant que [composants d'application](structure-application-components.md) de façon à ce qu'ils puissent être configurables et accessibles globalement. Le code qui suit montre comment configurer le composant d'application `cache` pour qu'il utilise [memcached](http://memcached.org/) avec deux serveurs de cache : +Les composants de mise en cache sont généralement enregistrés en tant que [composants d'application](structure-application-components.md) de façon à ce qu'ils puissent être configurables et accessibles globalement. Le code qui suit montre comment configurer le composant d'application `cache` pour qu'il utilise [memcached](https://memcached.org/) avec deux serveurs de cache : ```php 'components' => [ @@ -91,18 +91,18 @@ Comme tous les composants de mise en cache prennent en charge le même jeux d'AP Yii prend en charge un large panel de supports de stockage pour cache. Ce qui suit est un résumé : -* [[yii\caching\ApcCache]]: utilise l'extension PHP [APC](https://secure.php.net/manual/en/book.apc.php). Cette option peut être considérée comme la plus rapide lorsqu'on utilise un cache pour une grosse application centralisée (p. ex. un serveur, pas d'équilibrage de charge dédié, etc.). +* [[yii\caching\ApcCache]]: utilise l'extension PHP [APC](https://www.php.net/manual/en/book.apcu.php). Cette option peut être considérée comme la plus rapide lorsqu'on utilise un cache pour une grosse application centralisée (p. ex. un serveur, pas d'équilibrage de charge dédié, etc.). * [[yii\caching\DbCache]]: utilise une table de base de données pour stocker les données en cache. Pour utiliser ce cache, vous devez créer une table comme spécifié dans [[yii\caching\DbCache::cacheTable]]. * [[yii\caching\DummyCache]]: tient lieu de cache à remplacer qui n'assure pas de mise en cache réelle. Le but de ce composant est de simplifier le code qui a besoin de vérifier la disponibilité du cache. Par exemple, lors du développement ou si le serveur ne dispose pas de la prise en charge d'un cache, vous pouvez configurer un composant de mise en cache pour qu'il utilise ce cache. Lorsque la prise en charge réelle de la mise en cache est activée, vous pouvez basculer sur le composant de mise en cache correspondant. Dans les deux cas, vous pouvez utiliser le même code `Yii::$app->cache->get($key)` pour essayer de retrouver les données du cache sans vous préoccuper du fait que `Yii::$app->cache` puisse être `null`. * [[yii\caching\FileCache]]: utilise des fichiers standards pour stocker les données en cache. Cela est particulièrement adapté à la mise en cache de gros blocs de données, comme le contenu d'une page. -* [[yii\caching\MemCache]]: utilise le [memcache](https://secure.php.net/manual/en/book.memcache.php) PHP et l'extension [memcached](https://secure.php.net/manual/en/book.memcached.php). Cette option peut être considérée comme la plus rapide lorsqu'on utilise un cache dans des applications distribuées (p. ex. avec plusieurs serveurs, l'équilibrage de charge, etc.). -* [[yii\redis\Cache]]: met en œuvre un composant de mise en cache basé sur un stockage clé-valeur [Redis](http://redis.io/) +* [[yii\caching\MemCache]]: utilise le [memcache](https://www.php.net/manual/en/book.memcache.php) PHP et l'extension [memcached](https://www.php.net/manual/en/book.memcached.php). Cette option peut être considérée comme la plus rapide lorsqu'on utilise un cache dans des applications distribuées (p. ex. avec plusieurs serveurs, l'équilibrage de charge, etc.). +* [[yii\redis\Cache]]: met en œuvre un composant de mise en cache basé sur un stockage clé-valeur [Redis](https://redis.io/) (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](https://secure.php.net/manual/en/book.wincache.php)). -* [[yii\caching\XCache]] _(deprecated)_: utilise l'extension PHP [XCache](http://xcache.lighttpd.net/). +* [[yii\caching\WinCache]]: utilise le [WinCache](https://iis.net/downloads/microsoft/wincache-extension) PHP + ([voir aussi l'extension](https://www.php.net/manual/en/book.wincache.php)). +* [[yii\caching\XCache]] _(deprecated)_: utilise l'extension PHP [XCache](https://en.wikipedia.org/wiki/List_of_PHP_accelerators#XCache). * [[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) + [cache de données Zend](https://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) en tant que médium de cache sous-jacent. @@ -248,11 +248,11 @@ $result = Customer::getDb()->cache(function ($db) { }); ``` -> Info : quelques systèmes de gestion de bases de données (DBMS) (p. ex. [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) +> Info : quelques systèmes de gestion de bases de données (DBMS) (p. ex. [MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html)) prennent également en charge la mise en cache de requêtes du côté serveur de base de données. Vous pouvez choisir d'utiliser l'un ou l'autre des ces mécanismes de mise en cache de requêtes. Les mises en cache de requêtes décrites ci-dessus offrent l'avantage de pouvoir spécifier des dépendances de mise en cache flexibles et sont potentiellement plus efficaces. -### Vidage du cache +### Vidage du cache Lorsque vous avez besoin d'invalider toutes les données stockées dans le cache, vous pouvez appeler [[yii\caching\Cache::flush()]]. diff --git a/docs/guide-fr/caching-http.md b/docs/guide-fr/caching-http.md index 10ac1bce51e..6fa116742f5 100644 --- a/docs/guide-fr/caching-http.md +++ b/docs/guide-fr/caching-http.md @@ -86,7 +86,7 @@ ETags vous autorise des stratégies de mises en cache plus complexes et/ou plus Des génération coûteuses d'ETag peuvent contrecarrer l'objectif poursuivi en utilisant `HttpCache` et introduire une surcharge inutile, car il faut les réévaluer à chacune des requêtes. Essayez de trouver une expression simple qui invalide le cache si le contenu de la page a été modifié. -> Note : en conformité avec la norme [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4), +> Note : en conformité avec la norme [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4), `HttpCache` envoie les entêtes `ETag` et `Last-Modified` à la fois si ils sont tous deux configurés. Et si le client envoie les entêtes `If-None-Match` et `If-Modified-Since` à la fois, seul le premier est respecté. @@ -100,7 +100,7 @@ Cache-Control: public, max-age=3600 ## Propriété "Session Cache Limiter" -Lorsqu'une page utilise une session, PHP envoie automatiquement quelques entêtes HTTP relatifs à la mise en cache comme spécifié dans la propriété `session.cache_limiter` de PHP INI. Ces entêtes peuvent interférer ou désactiver la mise en cache que vous voulez obtenir de `HttpCache`. Pour éviter ce problème, par défaut, `HttpCache` désactive l'envoi de ces entêtes automatiquement. Si vous désirez modifier ce comportement, vous devez configurer la propriété [[yii\filters\HttpCache::sessionCacheLimiter]]. Cette propriété accepte une chaîne de caractères parmi `public`, `private`, `private_no_expire` et `nocache`. Reportez-vous au manuel de PHP à propos de [session_cache_limiter()](https://secure.php.net/manual/en/function.session-cache-limiter.php) pour des explications sur ces valeurs. +Lorsqu'une page utilise une session, PHP envoie automatiquement quelques entêtes HTTP relatifs à la mise en cache comme spécifié dans la propriété `session.cache_limiter` de PHP INI. Ces entêtes peuvent interférer ou désactiver la mise en cache que vous voulez obtenir de `HttpCache`. Pour éviter ce problème, par défaut, `HttpCache` désactive l'envoi de ces entêtes automatiquement. Si vous désirez modifier ce comportement, vous devez configurer la propriété [[yii\filters\HttpCache::sessionCacheLimiter]]. Cette propriété accepte une chaîne de caractères parmi `public`, `private`, `private_no_expire` et `nocache`. Reportez-vous au manuel de PHP à propos de [session_cache_limiter()](https://www.php.net/manual/en/function.session-cache-limiter.php) pour des explications sur ces valeurs. ## Implications SEO diff --git a/docs/guide-fr/concept-aliases.md b/docs/guide-fr/concept-aliases.md index 2d5f22a9f1b..dabe0abe7a0 100644 --- a/docs/guide-fr/concept-aliases.md +++ b/docs/guide-fr/concept-aliases.md @@ -100,8 +100,8 @@ Yii prédéfinit un jeu d'alias pour faire référence à des chemins de fichier - `@webroot`, le dossier Web racine de l'application en cours d'exécution. Il est déterminé en se basant sur le dossier qui contient le [script d'entrée](structure-entry-scripts.md). - `@web`, l'URL de base de l'application en cours d'exécution. Cet alias a la même valeur que [[yii\web\Request::baseUrl]]. - `@vendor`, le [[yii\base\Application::vendorPath|dossier vendor de Composer]]. Valeur par défaut `@app/vendor`. -- `@bower`, le dossier racine des [paquets bower](http://bower.io/). Valeur par défaut `@vendor/bower`. -- `@npm`, le dossier racine des [paquets npm](https://www.npmjs.org/). Valeur par défaut `@vendor/npm`. +- `@bower`, le dossier racine des [paquets bower](https://bower.io/). Valeur par défaut `@vendor/bower`. +- `@npm`, le dossier racine des [paquets npm](https://www.npmjs.com/). Valeur par défaut `@vendor/npm`. L'alias `@yii` est défini lorsque vous incluez le fichier `Yii.php` dans votre [script d'entrée](structure-entry-scripts.md). Les alias restants sont définis dans le constructeur de l'application au moment où la [configuration](concept-configurations.md) de l'application est appliquée. . diff --git a/docs/guide-fr/concept-autoloading.md b/docs/guide-fr/concept-autoloading.md index 4e530c1f001..4efca62dd72 100644 --- a/docs/guide-fr/concept-autoloading.md +++ b/docs/guide-fr/concept-autoloading.md @@ -1,7 +1,7 @@ Chargement automatique des classes ================================== -Yii compte sur le [mécanisme de chargement automatique des classes](https://secure.php.net/manual/en/language.oop5.autoload.php) pour localiser et inclure tous les fichiers de classes requis. Il fournit un chargeur automatique de classes de haute performance qui est conforme à la [norme PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md). Le chargeur automatique est installé lorsque vous incluez le fichier `Yii.php`. +Yii compte sur le [mécanisme de chargement automatique des classes](https://www.php.net/manual/fr/language.oop5.autoload.php) pour localiser et inclure tous les fichiers de classes requis. Il fournit un chargeur automatique de classes de haute performance qui est conforme à la [norme PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md). Le chargeur automatique est installé lorsque vous incluez le fichier `Yii.php`. > Note: pour simplifier la description, dans cette section, nous ne parlerons que du chargement automatique des classes. Néanmoins, gardez présent à l'esprit que le contenu que nous décrivons ici s'applique aussi au chargement automatique des interfaces et des traits. @@ -11,7 +11,7 @@ Utilisation du chargeur automatique de Yii @@ -106,21 +106,21 @@ class User extends ActiveRecord { return [ // comportement anonyme, nom de la classe de comportement seulement - MyBehavior::className(), + MyBehavior::class, // comportement nommé, nom de classe de comportement seulement - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // comportement anonyme, tableau de configuration [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // comportement nommé, tableau de configuration 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ] @@ -138,14 +138,14 @@ Pour attacher un comportement de manière dynamique, appelez la méthode [[yii\b use app\components\MyBehavior; // attache un objet comportement -$component->attachBehavior('myBehavior1', new MyBehavior); +$component->attachBehavior('myBehavior1', new MyBehavior()); // attache un classe de comportement -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // attache un tableau de configuration $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -155,8 +155,8 @@ Vous pouvez attacher plusieurs comportements à la fois en utilisant la méthode ```php $component->attachBehaviors([ - 'myBehavior1' => new MyBehavior, // un comportement nommé - MyBehavior::className(), // un comportement anonyme + 'myBehavior1' => new MyBehavior(), // un comportement nommé + MyBehavior::class, // un comportement anonyme ]); ``` @@ -164,10 +164,10 @@ Vous pouvez aussi attacher des comportements via les [configurations](concept-co ```php [ - 'as myBehavior2' => MyBehavior::className(), + 'as myBehavior2' => MyBehavior::class, 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -250,7 +250,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -299,7 +299,7 @@ Il existe plusieurs comportements pré-inclus et extérieurs disponibles : Comparaison des comportement et des traits ------------------------------------------ -Bien que les comportements soient similaires aux [traits](https://secure.php.net/traits) par le fait qu'ils *injectent* tous deux leurs propriétés et leurs méthodes dans la classe primaire, ils diffèrent par de nombreux aspects. Comme nous l'expliquons ci-dessous, ils ont chacun leurs avantages et leurs inconvénients. Ils sont plus des compléments l'un envers l'autre, que des alternatives. +Bien que les comportements soient similaires aux [traits](https://www.php.net/traits) par le fait qu'ils *injectent* tous deux leurs propriétés et leurs méthodes dans la classe primaire, ils diffèrent par de nombreux aspects. Comme nous l'expliquons ci-dessous, ils ont chacun leurs avantages et leurs inconvénients. Ils sont plus des compléments l'un envers l'autre, que des alternatives. ### Raisons d'utiliser des comportements diff --git a/docs/guide-fr/concept-components.md b/docs/guide-fr/concept-components.md index 9fb1ff0d26e..fd61bbe0d29 100644 --- a/docs/guide-fr/concept-components.md +++ b/docs/guide-fr/concept-components.md @@ -67,7 +67,7 @@ Le respect de ces conseils rend vos composants [configurables](concept-configur $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // alternatively $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide-fr/concept-di-container.md b/docs/guide-fr/concept-di-container.md index 883699d2640..c547378245b 100644 --- a/docs/guide-fr/concept-di-container.md +++ b/docs/guide-fr/concept-di-container.md @@ -1,7 +1,7 @@ Conteneur d'injection de dépendances ==================================== -Un conteneur d'injection de dépendances (DI container) est un objet qui sait comment instancier et configurer des objets et tous leurs objets dépendants. [Cet article de Martin Fowler](http://martinfowler.com/articles/injection.html) explique très bien en quoi un conteneur d'injection de dépendances est utile. Ici nous expliquons essentiellement l'utilisation qui est faite du conteneur d'injection de dépendances que fournit Yii. +Un conteneur d'injection de dépendances (DI container) est un objet qui sait comment instancier et configurer des objets et tous leurs objets dépendants. [Cet article de Martin Fowler](https://martinfowler.com/articles/injection.html) explique très bien en quoi un conteneur d'injection de dépendances est utile. Ici nous expliquons essentiellement l'utilisation qui est faite du conteneur d'injection de dépendances que fournit Yii. Injection de dépendances @@ -410,7 +410,7 @@ $container->setDefinitions([ ] ]); -$reader = $container->get('app\storage\DocumentsReader); +$reader = $container->get('app\storage\DocumentsReader'); // Se comporte exactement comme l'exemple précédent ``` @@ -461,7 +461,7 @@ Comme les dépendances sont nécessaires lorsque de nouveaux objets sont créés Résumé ------- -L'injection de dépendances et le [localisateur de services](concept-service-locator.md) sont tous deux des modèles de conception populaires qui permettent des construire des logiciels d'une manière faiblement couplée et plus testable. Nous vous recommandons fortement de lire [l'article de Martin](http://martinfowler.com/articles/injection.html) pour acquérir une compréhension plus profonde de l'injection de dépendances et du localisateur de services. +L'injection de dépendances et le [localisateur de services](concept-service-locator.md) sont tous deux des modèles de conception populaires qui permettent des construire des logiciels d'une manière faiblement couplée et plus testable. Nous vous recommandons fortement de lire [l'article de Martin](https://martinfowler.com/articles/injection.html) pour acquérir une compréhension plus profonde de l'injection de dépendances et du localisateur de services. Yii implémente son [localisateur de services](concept-service-locator.md) par dessus le conteneur d'injection de dépendances. Lorsqu'un localisateur de services essaye de créer une nouvelle instance d'un objet, il appelle le conteneur d'injection de dépendances. Ce dernier résout les dépendances automatiquement comme c'est expliqué plus haut. diff --git a/docs/guide-fr/concept-events.md b/docs/guide-fr/concept-events.md index 88ccefaad72..3170c6829ab 100644 --- a/docs/guide-fr/concept-events.md +++ b/docs/guide-fr/concept-events.md @@ -9,7 +9,7 @@ Yii introduit une classe de base appelée [[yii\base\Component]] pour prendre en Gestionnaires d'événements -------------------------- -Un gestionnaire d'événement est une [fonction de rappel PHP](https://secure.php.net/manual/en/language.types.callable.php) qui est exécutée lorsque l'événement à laquelle elle est attachée est déclenché. Vous pouvez utiliser n'importe laquelle des fonctions de rappel suivantes : +Un gestionnaire d'événement est une [fonction de rappel PHP](https://www.php.net/manual/en/language.types.callable.php) qui est exécutée lorsque l'événement à laquelle elle est attachée est déclenché. Vous pouvez utiliser n'importe laquelle des fonctions de rappel suivantes : - une fonction PHP globale spécifiée sous forme de chaîne de caractères (sans les parenthèses) p. ex., `'trim'` ; - une méthode d'objet spécifiée sous forme de tableau constitué d'un nom d'objet et d'un nom de méthode sous forme de chaîne de caractères (sans les parenthèses), p. ex., `[$object, 'methodName']`; @@ -185,7 +185,7 @@ use Yii; use yii\base\Event; use yii\db\ActiveRecord; -Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { +Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::debug(get_class($event->sender) . ' is inserted'); }); ``` @@ -199,11 +199,11 @@ Vous pouvez déclencher un événement au *niveau de la classe* en appelant la m ```php use yii\base\Event; -Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { +Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) { var_dump($event->sender); // displays "null" }); -Event::trigger(Foo::className(), Foo::EVENT_HELLO); +Event::trigger(Foo::class, Foo::EVENT_HELLO); ``` Notez que, dans ce cas, `$event->sender` fait référence au nom de la classe qui a déclenché l'événement plutôt qu'à une instance de classe. @@ -214,10 +214,10 @@ Pour détacher un gestionnaire attaché au niveau de la classe, appelez [[yii\b ```php // détache $handler -Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); +Event::off(Foo::class, Foo::EVENT_HELLO, $handler); // détache tous les gestionnaires de Foo::EVENT_HELLO -Event::off(Foo::className(), Foo::EVENT_HELLO); +Event::off(Foo::class, Foo::EVENT_HELLO); ``` @@ -271,10 +271,10 @@ Vous pouvez déclencher l'événement de ces classes : ```php // trigger event for Dog class -Event::trigger(Dog::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Dog::class, DanceEventInterface::EVENT_DANCE); // trigger event for Developer class -Event::trigger(Developer::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Developer::class, DanceEventInterface::EVENT_DANCE); ``` Notez bien que vous ne pouvez pas déclencher l'événement de toutes les classes qui implémentent l'interface :, diff --git a/docs/guide-fr/db-active-record.md b/docs/guide-fr/db-active-record.md index 9a3ff0593c7..c858040833f 100644 --- a/docs/guide-fr/db-active-record.md +++ b/docs/guide-fr/db-active-record.md @@ -1,7 +1,7 @@ Enregistrement actif (*Active Record*) ===================================== -L'[enregistrement actif](http://en.wikipedia.org/wiki/Active_record_pattern) fournit une interface orientée objet pour accéder aux données stockées dans une base de données et les manipuler. +L'[enregistrement actif](https://en.wikipedia.org/wiki/Active_record_pattern) fournit une interface orientée objet pour accéder aux données stockées dans une base de données et les manipuler. Une classe d'enregistrement actif (ActiveRecord) est associée à une table de base de données, une instance de cette classe représente une ligne de cette table, et un *attribut* d'une instance d'enregistrement actif représente la valeur d'une colonne particulière dans cette ligne. Au lieu d'écrire des instructions SQL brutes, vous pouvez accéder aux attributs de l'objet enregistrement actif et appeler ses méthodes pour accéder aux données stockées dans les tables de la base de données et les manipuler. @@ -35,7 +35,7 @@ Yii assure la prise en charge de l'enregistrement actif (*Active Record*) pour l * Microsoft SQL Server 2008 ou versions postérieures : via [[yii\db\ActiveRecord]] * Oracle : via [[yii\db\ActiveRecord]] * CUBRID 9.3 ou versions postérieures : via [[yii\db\ActiveRecord]] - (Notez que, à cause d'un [bogue](http://jira.cubrid.org/browse/APIS-658) dans l'extension CUBRID 9.3, l'entourage des valeurs par des marques de citation ne fonctionne pas, c'est pourquoi vous avez besoin de CUBRID 9.3 à la fois comme client et comme serveur) + (Notez que, à cause d'un [bogue](https://jira.cubrid.org/browse/APIS-658) dans l'extension CUBRID 9.3, l'entourage des valeurs par des marques de citation ne fonctionne pas, c'est pourquoi vous avez besoin de CUBRID 9.3 à la fois comme client et comme serveur) * Sphinx : via [[yii\sphinx\ActiveRecord]], requiert l'extension `yii2-sphinx` * ElasticSearch : via [[yii\elasticsearch\ActiveRecord]], requiert l'extension `yii2-elasticsearch` @@ -472,9 +472,9 @@ ou la méthode [[yii\db\ActiveRecord::getOldAttribute()|getOldAttribute()]]. Cela est souvent le cas lorsque le modèle reçoit des entrées utilisateur de formulaires HTML ou chacune des valeurs est représentée par une chaîne de caractères. Pour garantir le type correct pour p. ex. des valeurs entières, vous devez appliquer un [filtre de validation](input-validation.md#data-filtering): > `['attributeName', 'filter', 'filter' => 'intval']`. -Cela fonctionne pour toutes les fonctions de transformation de type de PHP comme [intval()](https://secure.php.net/manual/en/function.intval.php), -[floatval()](https://secure.php.net/manual/en/function.floatval.php), -[boolval](https://secure.php.net/manual/en/function.boolval.php), etc... +Cela fonctionne pour toutes les fonctions de transformation de type de PHP comme [intval()](https://www.php.net/manual/en/function.intval.php), +[floatval()](https://www.php.net/manual/en/function.floatval.php), +[boolval](https://www.php.net/manual/en/function.boolval.php), etc... ### Valeurs d'attribut par défaut @@ -688,7 +688,7 @@ try { ``` > Note : dans le code précédent, nous utilisons deux blocs de capture pour être compatible avec PHP 5.x et PHP 7.x. -`\Exception` met en œuvre l'[interface `\Throwable`](https://secure.php.net/manual/en/class.throwable.php) +`\Exception` met en œuvre l'[interface `\Throwable`](https://www.php.net/manual/en/class.throwable.php) > à partir de PHP 7.0, c'est pourquoi vous pouvez sauter la partie avec `\Exception` si votre application utilise PHP 7.0 ou une version plus récente. La deuxième façon consiste à lister les opérations de base de données qui nécessitent une prise en charge transactionnelle dans la méthode [[yii\db\ActiveRecord::transactions()]]. @@ -788,9 +788,15 @@ use yii\behaviors\OptimisticLockBehavior; public function behaviors() { return [ - OptimisticLockBehavior::className(), + OptimisticLockBehavior::class, ]; } + +public function optimisticLock() +{ + return 'version'; +} + ``` > Note : comme [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] garantit que l'enregistrement n'est sauvegardé que > si l'utilisateur soumet un numéro de version valide en analysant directement [[\yii\web\Request::getBodyParam()|getBodyParam()]], @@ -820,7 +826,7 @@ class Customer extends ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -830,7 +836,7 @@ class Order extends ActiveRecord public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -847,7 +853,7 @@ En déclarant une relation, vous devez spécifier les informations suivantes : soit la méthode [[yii\db\ActiveRecord::hasOne()|hasOne()]]. Dans l'exemple ci-dessus vous pouvez facilement déduire en lisant la déclaration des relations qu'un client a beaucoup de commandes, tandis qu'une commande n'a qu'un client. - le nom de la classe d'enregistrement actif : spécifié comme le premier paramètre de [[yii\db\ActiveRecord::hasMany()|hasMany()]] ou de [[yii\db\ActiveRecord::hasOne()|hasOne()]]. -Une pratique conseillée est d'appeler `Xyz::className()` +Une pratique conseillée est d'appeler `Xyz::class` pour obtenir la chaîne de caractères représentant le nom de la classe de manière à bénéficier de l'auto-complètement de l'EDI et de la détection d'erreur dans l'étape de compilation. - Le lien entre les deux types de données : spécifie le(s) colonne(s) via lesquelles les deux types de données sont en relation. @@ -926,7 +932,7 @@ class Customer extends ActiveRecord { public function getBigOrders($threshold = 100) { - return $this->hasMany(Order::className(), ['customer_id' => 'id']) + return $this->hasMany(Order::class, ['customer_id' => 'id']) ->where('subtotal > :threshold', [':threshold' => $threshold]) ->orderBy('id'); } @@ -961,7 +967,7 @@ class Order extends ActiveRecord { public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->viaTable('order_item', ['order_id' => 'id']); } } @@ -974,12 +980,12 @@ class Order extends ActiveRecord { public function getOrderItems() { - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } } @@ -1013,21 +1019,21 @@ class Customer extends ActiveRecord public function getPurchasedItems() { // items de clients pour lesquels la colonne 'id' de `Item` correspond à 'item_id' dans OrderItem - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } public function getOrderItems() { // items de commandes clients pour lesquels, la colonne 'id' de `Order` correspond à 'order_id' dans OrderItem - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']) + return $this->hasMany(OrderItem::class, ['order_id' => 'id']) ->via('orders'); } public function getOrders() { // idem à ci-dessus - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1280,7 +1286,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -1288,7 +1294,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -1322,7 +1328,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); } } ``` @@ -1433,7 +1439,7 @@ class Customer extends \yii\db\ActiveRecord public function getComments() { // a customer has many comments - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1448,7 +1454,7 @@ class Comment extends \yii\mongodb\ActiveRecord public function getCustomer() { // un commentaire (comment) a un client (customer) - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } @@ -1532,7 +1538,7 @@ class Customer extends \yii\db\ActiveRecord { public function getActiveComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id'])->active(); + return $this->hasMany(Comment::class, ['customer_id' => 'id'])->active(); } } @@ -1543,7 +1549,7 @@ class Customer extends \yii\db\ActiveRecord { public function getComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1609,7 +1615,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1704,7 +1710,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1735,7 +1741,7 @@ class Customer extends \yii\db\ActiveRecord */ public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } /** diff --git a/docs/guide-fr/db-dao.md b/docs/guide-fr/db-dao.md index b3e8a455fa6..e99a01ad9a3 100644 --- a/docs/guide-fr/db-dao.md +++ b/docs/guide-fr/db-dao.md @@ -1,26 +1,26 @@ Objets d'accès aux bases de données =================================== -Construits au-dessus des [objets de bases de données PHP (PDO – PHP Data Objects)](https://secure.php.net/manual/en/book.pdo.php), les objets d'accès aux bases de données de Yii (DAO – Database Access Objects) fournissent une API orientée objets pour accéder à des bases de données relationnelles. C'est la fondation pour d'autres méthodes d'accès aux bases de données plus avancées qui incluent le [constructeur de requêtes (*query builder*)](db-query-builder.md) et l'[enregistrement actif (*active record*)](db-active-record.md). +Construits au-dessus des [objets de bases de données PHP (PDO – PHP Data Objects)](https://www.php.net/manual/en/book.pdo.php), les objets d'accès aux bases de données de Yii (DAO – Database Access Objects) fournissent une API orientée objets pour accéder à des bases de données relationnelles. C'est la fondation pour d'autres méthodes d'accès aux bases de données plus avancées qui incluent le [constructeur de requêtes (*query builder*)](db-query-builder.md) et l'[enregistrement actif (*active record*)](db-active-record.md). -Lorsque vous utilisez les objets d'accès aux bases de données de Yii, vous manipulez des requêtes SQL et des tableaux PHP. En conséquence, cela reste le moyen le plus efficace pour accéder aux bases de données. Néanmoins, étant donné que la syntaxe du langage SQL varie selon le type de base de données, l'utilisation des objets d'accès aux bases de données de Yii signifie également que vous avez à faire un travail supplémentaire pour créer une application indifférente au type de base de données. +Lorsque vous utilisez les objets d'accès aux bases de données de Yii, vous manipulez des requêtes SQL et des tableaux PHP. En conséquence, cela reste le moyen le plus efficace pour accéder aux bases de données. Néanmoins, étant donné que la syntaxe du langage SQL varie selon le type de base de données, l'utilisation des objets d'accès aux bases de données de Yii signifie également que vous avez à faire un travail supplémentaire pour créer une application indifférente au type de base de données. Dans Yii 2.0, les objets d'accès aux bases de données prennent en charge les bases de données suivantes sans configuration supplémentaire : -- [MySQL](http://www.mysql.com/) +- [MySQL](https://www.mysql.com/) - [MariaDB](https://mariadb.com/) -- [SQLite](http://sqlite.org/) -- [PostgreSQL](http://www.postgresql.org/): version 8.4 ou plus récente. -- [CUBRID](http://www.cubrid.org/): version 9.3 ou plus récente. -- [Oracle](http://www.oracle.com/us/products/database/overview/index.html) +- [SQLite](https://sqlite.org/) +- [PostgreSQL](https://www.postgresql.org/): version 8.4 ou plus récente. +- [CUBRID](https://www.cubrid.org/): version 9.3 ou plus récente. +- [Oracle](https://www.oracle.com/database/) - [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): version 2008 ou plus récente. > Info: depuis Yii 2.1, la prise en charge des objets d'accès aux bases de données pour CUBRID, Oracle et MSSQL n'est plus fournie en tant que composants du noyau. Cette prise en charge nécessite l'installation d'[extensions](structure-extensions.md) séparées. Parmi les [extensions officielles](https://www.yiiframework.com/extensions/official), on trouve [yiisoft/yii2-oracle](https://www.yiiframework.com/extension/yiisoft/yii2-oracle) et - [yiisoft/yii2-mssql](https://www.yiiframework.com/extension/yiisoft/yii2-mssql). +[yiisoft/yii2-mssql](https://www.yiiframework.com/extension/yiisoft/yii2-mssql). > Note: la nouvelle version de pdo_oci pour PHP 7 n'existe pour le moment que sous forme de code source. Suivez les [instructions de la communauté](https://github.com/yiisoft/yii2/issues/10975#issuecomment-248479268) - pour la compiler ou utilisez [la couche d'émulation de PDO](https://github.com/taq/pdooci). +pour la compiler ou utilisez [la couche d'émulation de PDO](https://github.com/taq/pdooci). ## Création de connexions à une base de données @@ -57,10 +57,10 @@ return [ Vous pouvez ensuite accéder à la base de données via l'expression `Yii::$app->db`. -> Tip: vous pouvez configurer plusieurs composants d'application « base de données » si votre application a besoin d'accéder à plusieurs bases de données. +> Tip: vous pouvez configurer plusieurs composants d'application « base de données » si votre application a besoin d'accéder à plusieurs bases de données. + +Lorsque vous configurez une connexion à une base de données, vous devez toujours spécifier le nom de sa source de données (DSN – Data Source Name) via la propriété [[yii\db\Connection::dsn|dsn]]. Les formats des noms de source de données varient selon le type de base de données. Reportez-vous au [manuel de PHP](https://www.php.net/manual/en/pdo.construct.php) pour plus de détails. Ci-dessous, nous donnons quelques exemples : -Lorsque vous configurez une connexion à une base de données, vous devez toujours spécifier le nom de sa source de données (DSN – Data Source Name) via la propriété [[yii\db\Connection::dsn|dsn]]. Les formats des noms de source de données varient selon le type de base de données. Reportez-vous au [manuel de PHP](https://secure.php.net/manual/en/function.PDO-construct.php) pour plus de détails. Ci-dessous, nous donnons quelques exemples : - * MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` * SQLite: `sqlite:/path/to/database/file` * PostgreSQL: `pgsql:host=localhost;port=5432;dbname=mydatabase` @@ -87,7 +87,7 @@ En plus de la propriété [[yii\db\Connection::dsn|dsn]], vous devez souvent con > Info: lorsque vous créez une instance de connexion à une base de données, la connexion réelle à la base de données n'est pas établie tant que vous n'avez pas exécuté la première requête SQL ou appelé la méthode [[yii\db\Connection::open()|open()]] explicitement. > Tip: parfois, vous désirez effectuer quelques requêtes juste après l'établissement de la connexion à la base de données pour initialiser quelques variables d'environnement (p. ex. pour définir le fuseau horaire ou le jeu de caractères). Vous pouvez le faire en enregistrant un gestionnaire d'événement pour l'événement [[yii\db\Connection::EVENT_AFTER_OPEN|afterOpen]] de la connexion à la base de données. Vous pouvez enregistrer le gestionnaire directement dans la configuration de l'application comme ceci : -> +> > ```php > 'db' => [ > // ... @@ -108,7 +108,7 @@ Une fois que vous avez une instance de connexion à la base de données, vous po 3. Appeler l'une des méthodes d'exécution SQL dans la [[yii\db\Command|commande]]. L'exemple qui suit montre différentes façons d'aller chercher des données dans une base de données : - + ```php // retourne un jeu de lignes. Chaque ligne est un tableau associatif (couples clé-valeur) dont les clés sont des noms de colonnes // retourne un tableau vide si la requête ne retourne aucun résultat @@ -131,12 +131,12 @@ $count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM post') ->queryScalar(); ``` -> Note: pour préserver la précision, les données extraites des bases de données sont toutes représentées sous forme de chaînes de caractères, même si les colonnes sont de type numérique. +> Note: pour préserver la précision, les données extraites des bases de données sont toutes représentées sous forme de chaînes de caractères, même si les colonnes sont de type numérique. ### Liaison des paramètres -Lorsque vous créez une commande de base de données à partir d'une requête SQL avec des paramètres, vous devriez presque toujours utiliser l'approche de liaison des paramètres pour éviter les attaques par injection SQL. Par exemple : +Lorsque vous créez une commande de base de données à partir d'une requête SQL avec des paramètres, vous devriez presque toujours utiliser l'approche de liaison des paramètres pour éviter les attaques par injection SQL. Par exemple : ```php $post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status') @@ -164,7 +164,7 @@ $post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status ->queryOne(); ``` -La liaison des paramètres est implémentée via des [instructions préparées](https://secure.php.net/manual/en/mysqli.quickstart.prepared-statements.php). En plus d'empêcher les attaques par injection SQL, cela peut aussi améliorer la performance en préparant l'instruction SQL une seule fois et l'exécutant de multiples fois avec des paramètres différents. Par exemple : +La liaison des paramètres est implémentée via des [instructions préparées](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php). En plus d'empêcher les attaques par injection SQL, cela peut aussi améliorer la performance en préparant l'instruction SQL une seule fois et l'exécutant de multiples fois avec des paramètres différents. Par exemple : ```php $command = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id'); @@ -188,11 +188,11 @@ $post2 = $command->queryOne(); // ... ``` -Notez que vous devez lier la valeur à remplacer à la variable `$id` avant l'exécution, et ensuite changer la valeur de cette variable avant chacune des exécutions subséquentes (cela est souvent réalisé dans une boucle). L'exécution de requêtes de cette façon peut être largement plus efficace que d'exécuter une nouvelle requête pour chacune des valeurs du paramètre). +Notez que vous devez lier la valeur à remplacer à la variable `$id` avant l'exécution, et ensuite changer la valeur de cette variable avant chacune des exécutions subséquentes (cela est souvent réalisé dans une boucle). L'exécution de requêtes de cette façon peut être largement plus efficace que d'exécuter une nouvelle requête pour chacune des valeurs du paramètre). -> Info: la liaison de paramètres n'est utilisée qu'en des endroits où les valeurs doivent être insérées dans des chaînes de caractères qui contiennent du langage SQL. -> Dans de nombreux endroits dans des couches plus abstraites comme le [query builder](db-query-builder.md) (constructeur de requêtes) et [active record](db-active-record.md) (enregistrement actif) -> vous spécifiez souvent un tableau de valeurs qui est transformé en SQL. À ces endroits, la liaison de paramètres est assurée par Yii en interne. Il n'est donc pas nécessaire de spécifier ces paramètres manuellement. +> Info: la liaison de paramètres n'est utilisée qu'en des endroits où les valeurs doivent être insérées dans des chaînes de caractères qui contiennent du langage SQL. +> Dans de nombreux endroits dans des couches plus abstraites comme le [query builder](db-query-builder.md) (constructeur de requêtes) et [active record](db-active-record.md) (enregistrement actif) +> vous spécifiez souvent un tableau de valeurs qui est transformé en SQL. À ces endroits, la liaison de paramètres est assurée par Yii en interne. Il n'est donc pas nécessaire de spécifier ces paramètres manuellement. ### Exécution de requête sans sélection @@ -204,7 +204,7 @@ Yii::$app->db->createCommand('UPDATE post SET status=1 WHERE id=1') ->execute(); ``` -La méthode [[yii\db\Command::execute()]] exécute retourne le nombre de lignes affectées par l'exécution de la requête SQL. +La méthode [[yii\db\Command::execute()]] exécute retourne le nombre de lignes affectées par l'exécution de la requête SQL. Pour les requeêtes INSERT, UPDATE et DELETE, au lieu d'écrire des instructions SQL simples, vous pouvez appeler les méthodes [[yii\db\Command::insert()|insert()]], [[yii\db\Command::update()|update()]] ou [[yii\db\Command::delete()|delete()]], respectivement, pour construire les instructions SQL correspondantes. Ces méthodes entourent correctement les noms de tables et de colonnes par des marques de citation et lient les paramètres. Par exemple : @@ -246,14 +246,14 @@ Yii::$app->db->createCommand()->upsert('pages', [ Le code ci-dessus, soit insère un enregistrement pour une nouvelle page, soit incrémente sont compteur de visite automatiquement. -Notez que les méthodes mentionnées ci-dessus ne font que créer les requêtes, vous devez toujours appeler [[yii\db\Command::execute()|execute()]] pour les exécuter réellement. +Notez que les méthodes mentionnées ci-dessus ne font que créer les requêtes, vous devez toujours appeler [[yii\db\Command::execute()|execute()]] pour les exécuter réellement. ## Entourage de noms de table et de colonne par des marque de citation Lorsque l'on écrit du code indifférent au type de base de données, entourer correctement les noms table et de colonne avec des marques de citation (p. ex. guillemets ou simple apostrophe) et souvent un casse-tête parce que les différentes base de données utilisent des règles de marquage de citation différentes. Pour vous affranchir de cette difficulté, vous pouvez utiliser la syntaxe de citation introduite par Yii : -* `[[column name]]`: entourez un nom de colonne qui doit recevoir les marques de citation par des doubles crochets ; +* `[[column name]]`: entourez un nom de colonne qui doit recevoir les marques de citation par des doubles crochets ; * `{{table name}}`: entourez un nom de table qui doit recevoir les marques de citation par des doubles accolades ; Les objets d'accès aux base de données de Yii convertissent automatiquement de telles constructions en les noms de colonne ou de table correspondants en utilisant la syntaxe spécifique au système de gestion de la base de données. Par exemple : @@ -295,8 +295,8 @@ $count = Yii::$app->db->createCommand("SELECT COUNT([[id]]) FROM {{%employee}}") ## Réalisation de transactions -Lorsque vous exécutez plusieurs requêtes liées en séquence, il arrive que vous ayez besoin de les envelopper dans une transactions pour garantir l'intégrité et la cohérence de votre base de données. Si une des requêtes échoue, la base de données est ramenée en arrière dans l'état dans lequel elle se trouvait avant qu'aucune de ces requêtes n'ait été exécutée. - +Lorsque vous exécutez plusieurs requêtes liées en séquence, il arrive que vous ayez besoin de les envelopper dans une transactions pour garantir l'intégrité et la cohérence de votre base de données. Si une des requêtes échoue, la base de données est ramenée en arrière dans l'état dans lequel elle se trouvait avant qu'aucune de ces requêtes n'ait été exécutée. + Le code suivant montre une façon typique d'utiliser les transactions : ```php @@ -329,8 +329,8 @@ try { En appelant la méthode [[yii\db\Connection::beginTransaction()|beginTransaction()]], une nouvelle transaction est démarrée. La transaction est représentée sous forme d'objet [[yii\db\Transaction]] stocké dans la variable `$transaction`. Ensuite, les requêtes à exécuter sont placées dans un bloc `try...catch...`. Si toutes les requêtes réussissent, la méthode [[yii\db\Transaction::commit()|commit()]] est appelée pour entériner la transaction. Autrement, si une exception a été levée et capturée, la méthode [[yii\db\Transaction::rollBack()|rollBack()]] est appelée pour défaire les changements faits par les requêtes de la transaction antérieures à celle qui a échoué. `throw $e` est alors à nouveau exécutée comme si l'exception n'avait jamais été capturée, ce qui permet au processus normal de gestion des erreurs de s'en occuper. -> Note: dans le code précédent nous avons deux blocs « catch » pour compatibilité -> avec PHP 5.x et PHP 7.x. `\Exception` met en œuvre l'[interface `\Throwable`](https://secure.php.net/manual/en/class.throwable.php) +> Note: dans le code précédent nous avons deux blocs « catch » pour compatibilité +> avec PHP 5.x et PHP 7.x. `\Exception` met en œuvre l'[interface `\Throwable`](https://www.php.net/manual/en/class.throwable.php) > depuis PHP 7.0, ainsi vous pouvez sauter la partie avec `\Exception` si votre application utilise seulement PHP 7.0 et plus récent. ### Spécification de niveaux d'isolation @@ -351,22 +351,22 @@ $transaction = Yii::$app->db->beginTransaction($isolationLevel); Yii fournit quatre constantes pour les niveaux d'isolation les plus courants : -- [[\yii\db\Transaction::READ_UNCOMMITTED]] – le niveau le plus faible, des lectures sales (*dirty reads*) , des lectures non répétables) (*non-repeatable reads*) et des lectures fantômes (*phantoms*) peuvent se produire. +- [[\yii\db\Transaction::READ_UNCOMMITTED]] – le niveau le plus faible, des lectures sales (*dirty reads*) , des lectures non répétables) (*non-repeatable reads*) et des lectures fantômes (*phantoms*) peuvent se produire. - [[\yii\db\Transaction::READ_COMMITTED]] – évite les lectures sales. -- [[\yii\db\Transaction::REPEATABLE_READ]] – évite les lectures sales et les lectures non répétables. +- [[\yii\db\Transaction::REPEATABLE_READ]] – évite les lectures sales et les lectures non répétables. - [[\yii\db\Transaction::SERIALIZABLE]] – le niveau le plus élevé, évite tous les problèmes évoqués ci-dessus. -En plus de l'utilisation des constantes présentées ci-dessus pour spécifier un niveau d'isolation, vous pouvez également utiliser des chaînes de caractères avec une syntaxe valide prise en charges par le système de gestion de base de données que vous utilisez. Par exemple, dans PostgreSQL, vous pouvez utiliser `"SERIALIZABLE READ ONLY DEFERRABLE"`. +En plus de l'utilisation des constantes présentées ci-dessus pour spécifier un niveau d'isolation, vous pouvez également utiliser des chaînes de caractères avec une syntaxe valide prise en charges par le système de gestion de base de données que vous utilisez. Par exemple, dans PostgreSQL, vous pouvez utiliser `"SERIALIZABLE READ ONLY DEFERRABLE"`. -Notez que quelques systèmes de gestion de base de données autorisent la définition des niveaux d'isolation uniquement au niveau de la connexion tout entière. Toutes les transactions subséquentes auront donc le même niveau d'isolation même si vous n'en spécifiez aucun. En utilisant cette fonctionnalité, vous avez peut-être besoin de spécifier le niveau d'isolation de manière explicite pour éviter les conflits de définition. Au moment d'écrire ces lignes, seules MSSQL et SQLite sont affectées par cette limitation. +Notez que quelques systèmes de gestion de base de données autorisent la définition des niveaux d'isolation uniquement au niveau de la connexion tout entière. Toutes les transactions subséquentes auront donc le même niveau d'isolation même si vous n'en spécifiez aucun. En utilisant cette fonctionnalité, vous avez peut-être besoin de spécifier le niveau d'isolation de manière explicite pour éviter les conflits de définition. Au moment d'écrire ces lignes, seules MSSQL et SQLite sont affectées par cette limitation. -> Note: SQLite ne prend en charge que deux niveaux d'isolation, c'est pourquoi vous ne pouvez utiliser que `READ UNCOMMITTED` et `SERIALIZABLE`. L'utilisation d'autres niveaux provoque la levée d'une exception. +> Note: SQLite ne prend en charge que deux niveaux d'isolation, c'est pourquoi vous ne pouvez utiliser que `READ UNCOMMITTED` et `SERIALIZABLE`. L'utilisation d'autres niveaux provoque la levée d'une exception. -> Note: PostgreSQL n'autorise pas la définition du niveau d'isolation tant que la transaction n'a pas démarré, aussi ne pouvez-vous pas spécifier le niveau d'isolation directement en démarrant la transaction. Dans ce cas, vous devez appeler [[yii\db\Transaction::setIsolationLevel()]] après que la transaction a démarré. +> Note: PostgreSQL n'autorise pas la définition du niveau d'isolation tant que la transaction n'a pas démarré, aussi ne pouvez-vous pas spécifier le niveau d'isolation directement en démarrant la transaction. Dans ce cas, vous devez appeler [[yii\db\Transaction::setIsolationLevel()]] après que la transaction a démarré. -[isolation levels]: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels +[isolation levels]: https://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels ### Imbrication des transactions @@ -415,7 +415,7 @@ try { ## Réplication et éclatement lecture-écriture -Beaucoup de systèmes de gestion de bases de données prennent en charge la [réplication de la base de données](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) pour obtenir une meilleure disponibilité et des temps de réponse de serveur plus courts. Avec la réplication de la base de données, les données sont répliquées depuis les serveurs dits *serveurs maîtres* vers les serveurs dit *serveurs esclaves*. Toutes les écritures et les mises à jour ont lieu sur les serveurs maîtres, tandis que les lectures ont lieu sur les serveurs esclaves. +Beaucoup de systèmes de gestion de bases de données prennent en charge la [réplication de la base de données](https://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) pour obtenir une meilleure disponibilité et des temps de réponse de serveur plus courts. Avec la réplication de la base de données, les données sont répliquées depuis les serveurs dits *serveurs maîtres* vers les serveurs dit *serveurs esclaves*. Toutes les écritures et les mises à jour ont lieu sur les serveurs maîtres, tandis que les lectures ont lieu sur les serveurs esclaves. Pour tirer parti de la réplication des bases de données et réaliser l'éclatement lecture-écriture, vous pouvez configurer un composant [[yii\db\Connection]] comme le suivant : @@ -465,10 +465,10 @@ Yii::$app->db->createCommand("UPDATE user SET username='demo' WHERE id=1")->exec Le composant `Connection` prend en charge l'équilibrage de charge et de basculement entre esclaves. Lorsque vous effectuez une requête en lecture par la première fois, le composant `Connection` sélectionne un esclave de façon aléatoire et essaye de s'y connecter. Si l'esclave set trouvé « mort », il en essaye un autre. Si aucun des esclaves n'est disponible, il se connecte au maître. En configurant un [[yii\db\Connection::serverStatusCache|cache d'état du serveur]], le composant mémorise le serveur « mort » et ainsi, pendant un [[yii\db\Connection::serverRetryInterval|certain intervalle de temps]], n'essaye plus de s'y connecter. -> Info: dans la configuration précédente, un temps d'attente de connexion de 10 secondes est spécifié pour chacun des esclaves. Cela signifie que, si un esclave ne peut être atteint pendant ces 10 secondes, il est considéré comme « mort ». Vous pouvez ajuster ce paramètre en fonction de votre environnement réel. +> Info: dans la configuration précédente, un temps d'attente de connexion de 10 secondes est spécifié pour chacun des esclaves. Cela signifie que, si un esclave ne peut être atteint pendant ces 10 secondes, il est considéré comme « mort ». Vous pouvez ajuster ce paramètre en fonction de votre environnement réel. -Vous pouvez aussi configurer plusieurs maîtres avec plusieurs esclaves. Par exemple : +Vous pouvez aussi configurer plusieurs maîtres avec plusieurs esclaves. Par exemple : ```php diff --git a/docs/guide-fr/db-migrations.md b/docs/guide-fr/db-migrations.md index 51cf22d0af2..82c82e38196 100644 --- a/docs/guide-fr/db-migrations.md +++ b/docs/guide-fr/db-migrations.md @@ -616,7 +616,7 @@ class m150101_185401_create_news_table extends Migration Notez que, généralement, si vous effectuez de multiples opérations de base de données dans `safeUp()`, vous devriez les défaire dans `safeDown()`. Dans l'exemple ci-dessus, dans `safeUp()`, nous créons d'abord la table puis nous insérons une ligne, tandis que, dans `safeDown`, nous commençons par supprimer la ligne, puis nous supprimons la table. -> Note: tous les systèmes de gestion de bases de données NE prennent PAS en charge les transactions. De plus, quelques requêtes de base de données ne peuvent être placées dans une transaction. Pour quelques exemples, reportez-vous à [entérinement implicite](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). Si c'est le cas, vous devez simplement mettre en œuvre `up()` et`down()`, à la place. +> Note: tous les systèmes de gestion de bases de données NE prennent PAS en charge les transactions. De plus, quelques requêtes de base de données ne peuvent être placées dans une transaction. Pour quelques exemples, reportez-vous à [entérinement implicite](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). Si c'est le cas, vous devez simplement mettre en œuvre `up()` et`down()`, à la place. ### Méthodes d'accès aux bases de données diff --git a/docs/guide-fr/db-query-builder.md b/docs/guide-fr/db-query-builder.md index 3cd66ae1df4..ecfdc9c8dd2 100644 --- a/docs/guide-fr/db-query-builder.md +++ b/docs/guide-fr/db-query-builder.md @@ -155,7 +155,7 @@ $query->from(['u' => $subQuery]); #### Préfixes Un [[yii\db\Connection::$tablePrefix|préfixe de table]] peut aussi être appliqué. Les instructions de mise en œuvre sont données à la section -["Entourage des noms de table et de colonne par des marques de citation" du guide sur les objets d'accès aux bases de données" ](guide-db-dao.html#quoting-table-and-column-names). +["Entourage des noms de table et de colonne par des marques de citation" du guide sur les objets d'accès aux bases de données" ](db-dao.md#quoting-table-and-column-names). ### [[yii\db\Query::where()|where()]] La méthode [[yii\db\Query::where()|where()]] spécifie le fragment `WHERE`d'une requête SQL. Vous pouvez utiliser un des quatre formats suivants pour spécifier une condition `WHERE` : @@ -296,7 +296,7 @@ L'opérande 2 peut être soit un tableau, soit un objet `Query`. Vous pouvez utiliser `false` ou un tableau vide pour indiquer que les valeurs sont déjà échappées et qu'aucun échappement ne doit être appliqué. Notez que lorsqu'un tableau de mise en correspondance pour l'échappement est utilisé (ou quand le troisième opérande n'est pas fourni), les valeurs sont automatiquement entourées par une paire de caractères `%`. - > Note: lors de l'utilisation de PostgreSQL vous pouvez aussi utiliser [`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) + > Note: lors de l'utilisation de PostgreSQL vous pouvez aussi utiliser [`ilike`](https://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) >à la place de `like` pour une mise en correspondance insensible à la casse. - `or like`: similaire à l'opérateur `like` sauf que `OR`est utilisé pour concaténer les prédicats `LIKE` @@ -771,7 +771,7 @@ foreach ($query->each() as $username => $user) { #### Limitations des requêtes par lots dans MySQL La mise en œuvre des requêtes par lots de MySQL s'appuie sur la bibliothèque du pilote PDO. Par défaut, les requêtes MySQL sont -[`mises en tampon`](https://secure.php.net/manual/en/mysqlinfo.concepts.buffering.php). +[`mises en tampon`](https://www.php.net/manual/en/mysqlinfo.concepts.buffering.php). Cela empêche d'utiliser le curseur pour obtenir les données, parce que cela n'empêche pas le jeu résultant complet d'être chargé dans la mémoire du client par le pilote. diff --git a/docs/guide-fr/helper-array.md b/docs/guide-fr/helper-array.md index c8ccd69892b..a4029deee11 100644 --- a/docs/guide-fr/helper-array.md +++ b/docs/guide-fr/helper-array.md @@ -1,7 +1,7 @@ Classe assistante ArrayHelper ============================= -En plus du jeu riche de [fonctions de tableaux](https://secure.php.net/manual/en/book.array.php) qu'offre PHP, la classe assistante traitant les tableaux dans Yii fournit des méthodes statiques supplémentaires qui vous permettent de traiter les tableaux avec plus d'efficacité. +En plus du jeu riche de [fonctions de tableaux](https://www.php.net/manual/en/book.array.php) qu'offre PHP, la classe assistante traitant les tableaux dans Yii fournit des méthodes statiques supplémentaires qui vous permettent de traiter les tableaux avec plus d'efficacité. ## Obtention de valeurs @@ -61,7 +61,7 @@ Après exécution du code, `$array` contiendra `['options' => [1, 2]]` et `$type ## Tester l'existence des clés -`ArrayHelper::keyExists` fonctionne comme [array_key_exists](https://secure.php.net/manual/en/function.array-key-exists.php) sauf qu'elle prend également en charge la comparaison de clés insensible à la casse. Par exemple, +`ArrayHelper::keyExists` fonctionne comme [array_key_exists](https://www.php.net/manual/en/function.array-key-exists.php) sauf qu'elle prend également en charge la comparaison de clés insensible à la casse. Par exemple, ```php $data1 = [ @@ -252,7 +252,7 @@ ArrayHelper::multisort($data, function($item) { Le troisième argument précise la direction. Dans le cas d'un tri selon une clé unique, il s'agit soit de `SORT_ASC`, soit de `SORT_DESC`. Si le tri se fait selon des valeurs multiples, vous pouvez préciser des directions de tri différentes pour chacune des clés en présentant ces directions sous forme de tableau. -Le dernier argument est une option de tri de PHP qui peut prendre les mêmes valeurs que celles acceptées par la fonction [sort()](https://secure.php.net/manual/en/function.sort.php) de PHP. +Le dernier argument est une option de tri de PHP qui peut prendre les mêmes valeurs que celles acceptées par la fonction [sort()](https://www.php.net/manual/en/function.sort.php) de PHP. ## Détection des types de tableau @@ -284,7 +284,7 @@ Seules les valeurs sont encodées par défaut. En passant un deuxième argument ## Fusion de tableaux -La fonction [[yii\helpers\ArrayHelper::merge()|ArrayHelper::merge()]] vous permet de fusionner deux, ou plus, tableaux en un seul de manière récursive. Si chacun des tableaux possède un élément avec la même chaîne clé valeur, le dernier écrase le premier (ce qui est un fonctionnement différent de [array_merge_recursive()](https://secure.php.net/manual/en/function.array-merge-recursive.php)). +La fonction [[yii\helpers\ArrayHelper::merge()|ArrayHelper::merge()]] vous permet de fusionner deux, ou plus, tableaux en un seul de manière récursive. Si chacun des tableaux possède un élément avec la même chaîne clé valeur, le dernier écrase le premier (ce qui est un fonctionnement différent de [array_merge_recursive()](https://www.php.net/manual/en/function.array-merge-recursive.php)). La fusion récursive est entreprise si les deux tableaux possèdent un élément de type tableau avec la même clé. Pour des éléments dont la clé est un entier, les éléments du deuxième tableau sont ajoutés aux éléments du premier tableau. Vous pouvez utiliser l'objet [[yii\helpers\UnsetArrayValue]] pour supprimer la valeur du premier tableau ou [[yii\helpers\ReplaceArrayValue]] pour forcer le remplacement de la première valeur au lieu de la fusion récursive. Par exemple : @@ -391,7 +391,7 @@ Il est possible de fournir une manière par défaut de convertir un objet en tab Souvent, vous devez savoir si un élément se trouve dans un tableau ou si un jeu d'éléments est un sous-ensemble d'un autre. Bien que PHP offre la fonction `in_array()`, cette dernière ne prend pas en charge les sous-ensembles ou les objets `\Traversable`. Pour faciliter ce genre de tests, [[yii\helpers\ArrayHelper]] fournit les méthodes [[yii\helpers\ArrayHelper::isIn()|isIn()]] -et [[yii\helpers\ArrayHelper::isSubset()|isSubset()]] avec la même signature que [in_array()](https://secure.php.net/manual/en/function.in-array.php). +et [[yii\helpers\ArrayHelper::isSubset()|isSubset()]] avec la même signature que [in_array()](https://www.php.net/manual/en/function.in-array.php). ```php // true diff --git a/docs/guide-fr/helper-html.md b/docs/guide-fr/helper-html.md index c494aedc038..2f3871d6431 100644 --- a/docs/guide-fr/helper-html.md +++ b/docs/guide-fr/helper-html.md @@ -1,7 +1,7 @@ Classe assistante Html ====================== -Toutes les applications Web génèrent un grand nombre de balises HTML. Si le code HTML est statique, il peut être créé efficacement sous forme de [mélange de code PHP et de code HTML dans un seul fichier](https://secure.php.net/manual/en/language.basic-syntax.phpmode.php), mais lorsqu'il est généré dynamiquement, cela commence à être compliqué à gérer sans une aide supplémentaire. Yii fournit une telle aide sous la forme de la classe assistante Html, qui offre un jeu de méthodes statiques pour manipuler les balises Html les plus courantes, leurs options et leur contenu. +Toutes les applications Web génèrent un grand nombre de balises HTML. Si le code HTML est statique, il peut être créé efficacement sous forme de [mélange de code PHP et de code HTML dans un seul fichier](https://www.php.net/manual/en/language.basic-syntax.phpmode.php), mais lorsqu'il est généré dynamiquement, cela commence à être compliqué à gérer sans une aide supplémentaire. Yii fournit une telle aide sous la forme de la classe assistante Html, qui offre un jeu de méthodes statiques pour manipuler les balises Html les plus courantes, leurs options et leur contenu. > Note: si votre code HTML est presque statique, il vaut mieux utiliser HTML directement. Il n'est pas nécessaire d'envelopper tout dans des appels aux méthodes de la classe assistante Html. @@ -36,7 +36,7 @@ Des options sont utilisées dans de nombreuses méthodes de la classe assistante - Si une valeur est `null`, l'attribut correspondant n'est pas rendu. - Les attributs du type booléen sont traités comme des - [attributs booléens ](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes). + [attributs booléens ](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes). - Les valeurs des attributs sont encodés HTML à l'aide de la méthode [[yii\helpers\Html::encode()|Html::encode()]]. - Si la valeur d'un attribut est un tableau, il est géré comme suit : @@ -134,8 +134,8 @@ accepte un tableau de propriétés à retirer. S'il s'agit d'une propriété uni ### Encodage et décodage du contenu -Pour que le contenu puisse être affiché en HTML de manière propre et en toute sécurité, les caractères spéciaux du contenu doivent être encodés. En PHP, cela s'obtient avec [htmlspecialchars](https://secure.php.net/manual/en/function.htmlspecialchars.php) et -[htmlspecialchars_decode](https://secure.php.net/manual/en/function.htmlspecialchars-decode.php). Le problème rencontré en utilisant ces méthodes directement est que vous devez spécifier l'encodage et des options supplémentaires tout le temps. Comme ces options restent toujours les mêmes et que l'encodage doit correspondre à celui de l'application pour éviter les problèmes de sécurité, Yii fournit deux méthodes compactes et faciles à utiliser : +Pour que le contenu puisse être affiché en HTML de manière propre et en toute sécurité, les caractères spéciaux du contenu doivent être encodés. En PHP, cela s'obtient avec [htmlspecialchars](https://www.php.net/manual/en/function.htmlspecialchars.php) et +[htmlspecialchars_decode](https://www.php.net/manual/en/function.htmlspecialchars-decode.php). Le problème rencontré en utilisant ces méthodes directement est que vous devez spécifier l'encodage et des options supplémentaires tout le temps. Comme ces options restent toujours les mêmes et que l'encodage doit correspondre à celui de l'application pour éviter les problèmes de sécurité, Yii fournit deux méthodes compactes et faciles à utiliser : ```php $userName = Html::encode($user->name); diff --git a/docs/guide-fr/input-file-upload.md b/docs/guide-fr/input-file-upload.md index c58a234b2f6..4b26bf727b7 100644 --- a/docs/guide-fr/input-file-upload.md +++ b/docs/guide-fr/input-file-upload.md @@ -107,7 +107,7 @@ Dans le code ci-dessus, lorsque le formulaire est soumis, la méthode [[yii\web\ Vous pouvez également charger sur le serveur plusieurs fichiers à la fois, avec quelques ajustements au code présenté dans les sous-sections précédentes. -Tout d'abord, vous devez ajuster la classe du modèle en ajoutant l'option `maxFiles` dans la règle de validation de `file` pour limiter le nombre maximum de fichiers à charger simultanément. Définir `maxFiles` à `0` signifie que ce nombre n'est pas limité. Le nombre maximal de fichiers que l'on peut charger simultanément est aussi limité par la directive PHP [`max_file_uploads`](https://secure.php.net/manual/en/ini.core.php#ini.max-file-uploads), dont la valeur par défaut est 20. La méthode `upload()` doit aussi être modifiée pour permettre la sauvegarde des fichiers un à un. +Tout d'abord, vous devez ajuster la classe du modèle en ajoutant l'option `maxFiles` dans la règle de validation de `file` pour limiter le nombre maximum de fichiers à charger simultanément. Définir `maxFiles` à `0` signifie que ce nombre n'est pas limité. Le nombre maximal de fichiers que l'on peut charger simultanément est aussi limité par la directive PHP [`max_file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads), dont la valeur par défaut est 20. La méthode `upload()` doit aussi être modifiée pour permettre la sauvegarde des fichiers un à un. ```php namespace app\models; diff --git a/docs/guide-fr/input-forms.md b/docs/guide-fr/input-forms.md index 7db82ec89de..d55d4e471a4 100644 --- a/docs/guide-fr/input-forms.md +++ b/docs/guide-fr/input-forms.md @@ -73,7 +73,7 @@ echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Ite Soyez prudent lorsque vous nommez des éléments de formulaire tels que des boutons de soumission. Selon la [documentation de jQuery](https://api.jquery.com/submit/), certains noms sont réservés car ils peuvent créer des conflits : -> Les éléments *forms* et leurs éléments enfants ne devraient par utiliser des noms de champ de saisie, ou des identifiants que entrent en conflit avec les propriétés d'un élément de *form*, tels que `submit`, `length`, ou `method`. Les conflits de noms peuvent créer des échecs troublants. Pour une liste complètes des règles et pour vérifier votre code HTML à propos de ces problèmes, reportez-vous à [DOMLint](http://kangax.github.io/domlint/). +> Les éléments *forms* et leurs éléments enfants ne devraient par utiliser des noms de champ de saisie, ou des identifiants que entrent en conflit avec les propriétés d'un élément de *form*, tels que `submit`, `length`, ou `method`. Les conflits de noms peuvent créer des échecs troublants. Pour une liste complètes des règles et pour vérifier votre code HTML à propos de ces problèmes, reportez-vous à [DOMLint](https://kangax.github.io/domlint/). Des balises additionnelles HTML peuvent être ajoutées au formulaire en utilisant du HTML simple ou en utilisant les méthodes de la classe [[yii\helpers\Html|Html]]-helper comme cela est fait dans l'exemple ci-dessus avec le [[yii\helpers\Html::submitButton()|bouton de soumission]]. @@ -93,7 +93,7 @@ Des balises additionnelles HTML peuvent être ajoutées au formulaire en utilisa Création d'une liste déroulante ------------------------------- -Vous pouvez utiliser la méthode [dropDownList()](http://www.yiiframework.com/doc-2.0/yii-widgets-activefield.html#dropDownList()-detail) de ActiveForm pour créer une liste déroulante : +Vous pouvez utiliser la méthode [dropDownList()](https://www.yiiframework.com/doc-2.0/yii-widgets-activefield.html#dropDownList()-detail) de ActiveForm pour créer une liste déroulante : ```php diff --git a/docs/guide-fr/input-validation.md b/docs/guide-fr/input-validation.md index 6e59fbfedeb..2ac0c1d4d2d 100644 --- a/docs/guide-fr/input-validation.md +++ b/docs/guide-fr/input-validation.md @@ -370,7 +370,7 @@ class EntryForm extends Model { return [ [['name', 'email'], 'required'], - ['country', CountryValidator::className()], + ['country', CountryValidator::class], ['email', 'email'], ]; } @@ -494,7 +494,7 @@ JS; ### Validation différée -Si vous devez effectuer une validation asynchrone côté client, vous pouvez créer des [objets différés](http://api.jquery.com/category/deferred-object/). Par exemple, pour effectuer une validation AJAX personnalisée, vous pouvez utiliser le code suivant : +Si vous devez effectuer une validation asynchrone côté client, vous pouvez créer des [objets différés](https://api.jquery.com/category/deferred-object/). Par exemple, pour effectuer une validation AJAX personnalisée, vous pouvez utiliser le code suivant : ```php public function clientValidateAttribute($model, $attribute, $view) diff --git a/docs/guide-fr/intro-upgrade-from-v1.md b/docs/guide-fr/intro-upgrade-from-v1.md index 3dfcc943041..096b39e54bc 100644 --- a/docs/guide-fr/intro-upgrade-from-v1.md +++ b/docs/guide-fr/intro-upgrade-from-v1.md @@ -31,15 +31,15 @@ Yii 2.0 requiert PHP 5.4 ou plus, ce qui est une grosse amélioration par rappor Par conséquent, il y a beaucoup de différences au niveau du langage auxquelles vous devriez prêter attention. Voici un résumé des principaux changements concernant PHP: -- [Espaces de noms](https://secure.php.net/manual/fr/language.namespaces.php). -- [Fonctions anonymes](https://secure.php.net/manual/fr/functions.anonymous.php). +- [Espaces de noms](https://www.php.net/manual/fr/language.namespaces.php). +- [Fonctions anonymes](https://www.php.net/manual/fr/functions.anonymous.php). - Syntaxe courte pour les tableaux : `[...éléments...]` est utilisé au lieu de `array(...éléments...)`. - Syntaxe courte pour echo : `registerJsFile('http://example.com/js/main.js', ['depends' => [\yii\web\JqueryAsset::className()]]); +$this->registerJsFile('http://example.com/js/main.js', ['depends' => [\yii\web\JqueryAsset::class]]); ``` Les arguments pour [[yii\web\View::registerJsFile()|registerJsFile()]] sont semblables à ceux utilisés pour [[yii\web\View::registerCssFile()|registerCssFile()]]. Dans l'exemple précédent, nous enregistrons le fichier `main.js` avec une dépendance sur `JqueryAsset`. Cela siginifie que le fichier `main.js` sera ajouté APRÈS `jquery.js`. Sans la spécification de cette dépendance, l'ordre relatif entre `main.js` et `jquery.js` resterait indéfini. @@ -65,7 +65,7 @@ Si vous désirez spécifier des propriétés additionnelles du style balise, pas ```php $this->registerCssFile("http://example.com/css/themes/black-and-white.css", [ - 'depends' => [BootstrapAsset::className()], + 'depends' => [BootstrapAsset::class], 'media' => 'print', ], 'css-print-theme'); ``` diff --git a/docs/guide-fr/output-data-widgets.md b/docs/guide-fr/output-data-widgets.md index fe70d291c2b..c50b5c69a4b 100644 --- a/docs/guide-fr/output-data-widgets.md +++ b/docs/guide-fr/output-data-widgets.md @@ -664,4 +664,4 @@ Qui génère un composant graphique [[yii\widgets\Pjax|Pjax]] enveloppant les co Lectures complémentaires ------------------------ -- [Rendering Data in Yii 2 with GridView and ListView](http://www.sitepoint.com/rendering-data-in-yii-2-with-gridview-and-listview/) d'Arno Slatius. +- [Rendering Data in Yii 2 with GridView and ListView](https://www.sitepoint.com/rendering-data-in-yii-2-with-gridview-and-listview/) d'Arno Slatius. diff --git a/docs/guide-fr/output-formatting.md b/docs/guide-fr/output-formatting.md index bd1fb42c598..bfdef0316bb 100644 --- a/docs/guide-fr/output-formatting.md +++ b/docs/guide-fr/output-formatting.md @@ -35,7 +35,7 @@ echo Yii::$app->formatter->format('2014-01-01', 'date'); echo Yii::$app->formatter->format(0.125, ['percent', 2]); ``` -> Note: le composant de formatage est conçu pour formater des valeurs à présenter à l'utilisateur. Si vous voulez convertir des entrées utilisateur en un format lisible par la machine, ou simplement formater une date dans un format lisible par la machine, le formateur n'est pas l'outil adapté à cela. Pour convertir une entrée utilisateur pour une date et un temps, vous pouvez utiliser [[yii\validators\DateValidator]] et [[yii\validators\NumberValidator]] respectivement. Pour une simple conversion entre les formats lisibles par la machine de date et de temps, la fonction PHP [date()](https://secure.php.net/manual/en/function.date.php) suffit. +> Note: le composant de formatage est conçu pour formater des valeurs à présenter à l'utilisateur. Si vous voulez convertir des entrées utilisateur en un format lisible par la machine, ou simplement formater une date dans un format lisible par la machine, le formateur n'est pas l'outil adapté à cela. Pour convertir une entrée utilisateur pour une date et un temps, vous pouvez utiliser [[yii\validators\DateValidator]] et [[yii\validators\NumberValidator]] respectivement. Pour une simple conversion entre les formats lisibles par la machine de date et de temps, la fonction PHP [date()](https://www.php.net/manual/en/function.date.php) suffit. ## Configuration du formateur @@ -64,14 +64,14 @@ Le formateur prend en charge les formats de sortie suivants en relation avec les - [[yii\i18n\Formatter::asDate()|date]]: la valeur est formatée sous la forme d'une date, p. ex. `January 01, 2014`. - [[yii\i18n\Formatter::asTime()|time]]: la valeur est formatée sous la forme d'un temps, p. ex. `14:23`. - [[yii\i18n\Formatter::asDatetime()|datetime]]: la valeur est formatée sous la forme d'une date et d'un temps, p. ex. `January 01, 2014 14:23`. -- [[yii\i18n\Formatter::asTimestamp()|timestamp]]: la valeur est formatée sous la forme d'un [horodatage unix ](http://en.wikipedia.org/wiki/Unix_time), p. ex. `1412609982`. +- [[yii\i18n\Formatter::asTimestamp()|timestamp]]: la valeur est formatée sous la forme d'un [horodatage unix ](https://en.wikipedia.org/wiki/Unix_time), p. ex. `1412609982`. - [[yii\i18n\Formatter::asRelativeTime()|relativeTime]]: la valeur est formatée sous la forme d'un intervalle de temps entre un temps et le temps actuel dans une forme lisible par l'homme, p.ex. `1 hour ago`. - [[yii\i18n\Formatter::asDuration()|duration]]: la valeur est formatée comme une durée dans un format lisible par l'homme, p. ex. `1 day, 2 minutes`. Les formats par défaut pour les dates et les temps utilisés pour les méthodes [[yii\i18n\Formatter::asDate()|date]], [[yii\i18n\Formatter::asTime()|time]], et [[yii\i18n\Formatter::asDatetime()|datetime]] peuvent être configurés globalement en configurant [[yii\i18n\Formatter::dateFormat|dateFormat]], [[yii\i18n\Formatter::timeFormat|timeFormat]], et [[yii\i18n\Formatter::datetimeFormat|datetimeFormat]]. -Vous pouvez spécifier les formats de date et de temps en utilisant la [syntaxe ICU](http://userguide.icu-project.org/formatparse/datetime). Vous pouvez aussi utiliser la [syntaxe date() de PHP](https://secure.php.net/manual/en/function.date.php) avec le préfixe `php:` pour la différentier de la syntaxe ICU. Par exemple : +Vous pouvez spécifier les formats de date et de temps en utilisant la [syntaxe ICU](http://userguide.icu-project.org/formatparse/datetime). Vous pouvez aussi utiliser la [syntaxe date() de PHP](https://www.php.net/manual/en/function.date.php) avec le préfixe `php:` pour la différentier de la syntaxe ICU. Par exemple : ```php // format ICU @@ -125,7 +125,7 @@ Pour les nombres, le formateur prend en charge les formats de sortie suivants : Le format pour un nombre peut être ajusté en utilisant [[yii\i18n\Formatter::decimalSeparator|decimalSeparator (séparateur de décimales)]] et [[yii\i18n\Formatter::thousandSeparator|thousandSeparator (séparateur de milliers) ]], qui prennent tous les deux les valeurs par défaut déterminées par la [[yii\i18n\Formatter::locale|locale]] courante. -Pour une configuration plus avancée, [[yii\i18n\Formatter::numberFormatterOptions]] et [[yii\i18n\Formatter::numberFormatterTextOptions]] peuvent être utilisés pour configurer la classe [NumberFormater (formateur de nombres)](https://secure.php.net/manual/en/class.numberformatter.php) utilisée en interne pour implémenter le formateur. Par exemple, pour ajuster la valeur minimum et maximum des chiffres fractionnaires, vous pouvez configurer la propriété [[yii\i18n\Formatter::numberFormatterOptions]] comme ceci : +Pour une configuration plus avancée, [[yii\i18n\Formatter::numberFormatterOptions]] et [[yii\i18n\Formatter::numberFormatterTextOptions]] peuvent être utilisés pour configurer la classe [NumberFormater (formateur de nombres)](https://www.php.net/manual/en/class.numberformatter.php) utilisée en interne pour implémenter le formateur. Par exemple, pour ajuster la valeur minimum et maximum des chiffres fractionnaires, vous pouvez configurer la propriété [[yii\i18n\Formatter::numberFormatterOptions]] comme ceci : ```php 'numberFormatterOptions' => [ @@ -172,7 +172,7 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // affiche : 1 января 20 Par défaut, la [[yii\i18n\Formatter::locale|locale]] est déterminée par la valeur de [[yii\base\Application::language]]. Vous pouvez la redéfinir en définissant la propriété [[yii\i18n\Formatter::locale]] explicitement. -> Note: le formateur de Yii a besoin de l'[extension intl de PHP](https://secure.php.net/manual/en/book.intl.php) pour prendre en charge la localisation des formats de données. Parce que différentes versions de la bibliothèque ICU compilées par PHP produisent des résultats de formatage différents, il est recommandé que vous utilisiez la même version de la bibliothèque ICU pour tous vos environnements. Pour plus de détails, reportez-vous au tutoriel [Configuration de votre environnement PHP pour l'internationalisation](tutorial-i18n.md#setup-environment). +> Note: le formateur de Yii a besoin de l'[extension intl de PHP](https://www.php.net/manual/en/book.intl.php) pour prendre en charge la localisation des formats de données. Parce que différentes versions de la bibliothèque ICU compilées par PHP produisent des résultats de formatage différents, il est recommandé que vous utilisiez la même version de la bibliothèque ICU pour tous vos environnements. Pour plus de détails, reportez-vous au tutoriel [Configuration de votre environnement PHP pour l'internationalisation](tutorial-i18n.md#setup-environment). > > Si l'extension intl extension n'est pas installée, les données ne sont pas localisées. > diff --git a/docs/guide-fr/runtime-bootstrapping.md b/docs/guide-fr/runtime-bootstrapping.md index 788b954719b..c1d1835bc1f 100644 --- a/docs/guide-fr/runtime-bootstrapping.md +++ b/docs/guide-fr/runtime-bootstrapping.md @@ -21,7 +21,7 @@ Comme le travail d'amorçage doit être fait avant *chacune* des requêtes, il e Dans le mode production, activez un cache bytecode, tel que [PHP OPcache] ou [APC], pour minimiser le temps nécessaire à l'inclusion et à l'analyse des fichiers PHP. -[PHP OPcache]: https://secure.php.net/manual/en/intro.opcache.php -[APC]: https://secure.php.net/manual/en/book.apc.php +[PHP OPcache]: https://www.php.net/manual/fr/book.opcache.php +[APC]: https://www.php.net/manual/fr/book.apcu.php Quelques applications volumineuses ont des [configurations](concept-configurations.md) d'application très complexes qui sont divisées en fichiers de configuration plus petits. Si c'est le cas, envisagez de mettre tout le tableau de configuration en cache et de le charger directement à partir cache avant la création de l'instance d'application dans le script d'entrée. diff --git a/docs/guide-fr/runtime-responses.md b/docs/guide-fr/runtime-responses.md index bbc13fab839..bd82c6559fa 100644 --- a/docs/guide-fr/runtime-responses.md +++ b/docs/guide-fr/runtime-responses.md @@ -187,11 +187,11 @@ Si vous appelez la méthode d'envoi de fichiers dans des endroits autres qu'une Quelques serveurs Web assurent une prise en charge spéciale de l'envoi de fichiers appelée *X-Sendfile*. L'idée est de rediriger la requête d'un fichier sur le serveur Web qui sert directement le fichier. En conséquence, l'application Web peut terminer plus rapidement tandis que le serveur Web est en train d'envoyer le fichier. Pour utiliser cette fonctionnalité, vous pouvez appeler la méthode [[yii\web\Response::xSendFile()]]. La liste suivante résume, comment activer la fonctionnalité `X-Sendfile` pour quelques serveurs Web populaires : -- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile) -- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Lighttpd v1.5: [X-Sendfile](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Nginx: [X-Accel-Redirect](http://wiki.nginx.org/XSendfile) -- Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) +- Apache: [X-Sendfile](https://tn123.org/mod_xsendfile) +- Lighttpd v1.4: [X-LIGHTTPD-send-file](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Lighttpd v1.5: [X-Sendfile](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Nginx: [X-Accel-Redirect](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) +- Cherokee: [X-Sendfile and X-Accel-Redirect](https://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) ## Envoi de la réponse diff --git a/docs/guide-fr/runtime-sessions-cookies.md b/docs/guide-fr/runtime-sessions-cookies.md index d9a31753c5f..b525205a850 100644 --- a/docs/guide-fr/runtime-sessions-cookies.md +++ b/docs/guide-fr/runtime-sessions-cookies.md @@ -120,8 +120,8 @@ La classe par défaut [[yii\web\Session]] stocke les données de session sous fo * [[yii\web\DbSession]]: stocke les données de session dans une base de données. * [[yii\web\CacheSession]]: stocke les données de session dans un cache avec l'aide d'un [composant cache](caching-data.md#cache-components) configuré. -* [[yii\redis\Session]]: stocke les données de session en utilisant le médium de stockage [redis](http://redis.io/) as the storage medium. -* [[yii\mongodb\Session]]: stocke les données de session dans une base de données de documents [MongoDB](http://www.mongodb.org/). +* [[yii\redis\Session]]: stocke les données de session en utilisant le médium de stockage [redis](https://redis.io/) as the storage medium. +* [[yii\mongodb\Session]]: stocke les données de session dans une base de données de documents [MongoDB](https://www.mongodb.com/). Toutes ces classes de session prennent en charge le même jeu de méthodes d'API. En conséquence, vous pouvez changer de support de stockage sans avoir à modifier le code de votre application qui utilise ces sessions. @@ -299,7 +299,7 @@ unset($cookies['language']); En plus des propriétés [[yii\web\Cookie::name|name (nom)]], [[yii\web\Cookie::value|value (valeur)]] montrées dans les exemples ci-dessus, la classe [[yii\web\Cookie]] définit également d'autres propriétés pour représenter complètement toutes les informations de témoin de connexion disponibles, comme les propriétés [[yii\web\Cookie::domain|domain (domaine)]], [[yii\web\Cookie::expire|expire (date d'expiration)]]. Vous pouvez configurer ces propriété selon vos besoins pour préparer un témoin de connexion et ensuite l'ajouter à la collection de témoins de connexion de la réponse. -> Note: pour une meilleure sécurité, la valeur par défaut de la propriété [[yii\web\Cookie::httpOnly]] est définie à `true`. Cela permet de limiter le risque qu'un script client n'accède à un témoin de connexion protégé (si le navigateur le prend en charge). Reportez-vous à l'[article de wiki httpOnly](https://www.owasp.org/index.php/HttpOnly) pour plus de détails. +> Note: pour une meilleure sécurité, la valeur par défaut de la propriété [[yii\web\Cookie::httpOnly]] est définie à `true`. Cela permet de limiter le risque qu'un script client n'accède à un témoin de connexion protégé (si le navigateur le prend en charge). Reportez-vous à l'[article de wiki httpOnly](https://owasp.org/www-community/HttpOnly) pour plus de détails. ### Validation des témoins de connexion diff --git a/docs/guide-fr/security-authorization.md b/docs/guide-fr/security-authorization.md index a6a06c968ae..9c124881217 100644 --- a/docs/guide-fr/security-authorization.md +++ b/docs/guide-fr/security-authorization.md @@ -20,7 +20,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['login', 'logout', 'signup'], 'rules' => [ [ @@ -57,7 +57,7 @@ Vous pouvez personnaliser ce comportement en configurant la propriété [[yii\fi ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, ... 'denyCallback' => function ($rule, $action) { throw new \Exception('You are not allowed to access this page'); @@ -99,7 +99,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['special-callback'], 'rules' => [ [ @@ -125,9 +125,9 @@ class SiteController extends Controller ## Contrôle d'accès basé sur les rôles -Le contrôle d'accès basé sur les rôles (Role-Based Access Control – RBAC) fournit un contrôle d'accès centralisé simple mais puissant. Reportez-vous à [Wikipedia](http://en.wikipedia.org/wiki/Role-based_access_control) pour des détails comparatifs entre le contrôle d'accès basé sur les rôles et d'autres schéma de contrôle d'accès plus traditionnels. +Le contrôle d'accès basé sur les rôles (Role-Based Access Control – RBAC) fournit un contrôle d'accès centralisé simple mais puissant. Reportez-vous à [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) pour des détails comparatifs entre le contrôle d'accès basé sur les rôles et d'autres schéma de contrôle d'accès plus traditionnels. -Yii met en œuvre un contrôle d'accès basé sur les rôles général hiérarchisé, qui suit le [modèle NIST RBAC](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf). Il fournit la fonctionnalité de contrôle d'accès basé sur les rôles via le [composant d'application](structure-application-components.md)[[yii\RBAC\ManagerInterface|authManager]]. +Yii met en œuvre un contrôle d'accès basé sur les rôles général hiérarchisé, qui suit le [modèle NIST RBAC](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf). Il fournit la fonctionnalité de contrôle d'accès basé sur les rôles via le [composant d'application](structure-application-components.md)[[yii\RBAC\ManagerInterface|authManager]]. L'utilisation du contrôle d'accès basé sur les rôles implique deux partie de travail. La première partie est de construire les données d'autorisation du contrôle d'accès basé sur les rôles, et la seconde partie est d'utiliser les données d'autorisation pour effectuer les vérifications d'autorisation d'accès là où elles sont nécessaires. @@ -390,7 +390,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'rules' => [ [ 'allow' => true, diff --git a/docs/guide-fr/security-passwords.md b/docs/guide-fr/security-passwords.md index 6380a5aebef..3cf9b3f20b1 100644 --- a/docs/guide-fr/security-passwords.md +++ b/docs/guide-fr/security-passwords.md @@ -5,7 +5,7 @@ La plupart des développeurs savent que les mots de passe ne peuvent pas être s Pour apporter une sécurité améliorée pour les mots de passe des utilisateurs, même dans le pire des scénario (une brèche est ouverte dans votre application), vous devez utiliser des algorithmes de hachage qui résistent aux attaques en force brute. Le choix le meilleur couramment utilisé est `bcrypt`. -En PHP, vous pouvez créer une valeur de hachage `bcrypt` à l'aide de la [fonction crypt](https://secure.php.net/manual/en/function.crypt.php). Yii fournit deux fonctions d'aide qui facilitent l'utilisation de `crypt` pour générer et vérifier des valeurs de hachage de manière sure. +En PHP, vous pouvez créer une valeur de hachage `bcrypt` à l'aide de la [fonction crypt](https://www.php.net/manual/en/function.crypt.php). Yii fournit deux fonctions d'aide qui facilitent l'utilisation de `crypt` pour générer et vérifier des valeurs de hachage de manière sure. Quand un utilisateur fournit un mot de passe pour la première fois (p. ex. à l'enregistrement), le mot de passe doit être haché : diff --git a/docs/guide-fr/start-databases.md b/docs/guide-fr/start-databases.md index f1144159c2c..7746d4060da 100644 --- a/docs/guide-fr/start-databases.md +++ b/docs/guide-fr/start-databases.md @@ -53,7 +53,7 @@ Configurer une Connexion à la BDD --------------------------- Avant de continuer, vérifiez que vous avez installé à la fois l'extension PHP -[PDO](https://secure.php.net/manual/fr/book.pdo.php) et le pilote PDO pour la base de données que vous utilisez (c'est +[PDO](https://www.php.net/manual/fr/book.pdo.php) et le pilote PDO pour la base de données que vous utilisez (c'est à dire `pdo_mysql` pour MySQL). C'est une exigence de base si votre application utilise une base de données relationnelle. Une fois ces éléments installés, ouvrez le fichier `config/db.php` et modifiez les paramètres pour qu'ils correspondent à votre base de données. Par défaut, le fichier contient ce qui suit : diff --git a/docs/guide-fr/start-forms.md b/docs/guide-fr/start-forms.md index 63482d17b88..1072663cd29 100644 --- a/docs/guide-fr/start-forms.md +++ b/docs/guide-fr/start-forms.md @@ -135,7 +135,7 @@ sera générée, dans laquelle le formulaire HTML sera affiché, ainsi que tout > Note: Dans cet exemple très simple, nous effectuons le rendu de la page de confirmation après soumission de données valides. En pratique, vous devriez envisager d'utiliser [[yii\web\Controller::refresh()|refresh()]] ou [[yii\web\Controller::redirect()|redirect()]] pour éviter les -[problèmes de multiple soumission de formulaire](http://fr.wikipedia.org/wiki/Post-Redirect-Get). +[problèmes de multiple soumission de formulaire](https://fr.wikipedia.org/wiki/Post-Redirect-Get). Créer des Vues diff --git a/docs/guide-fr/start-hello.md b/docs/guide-fr/start-hello.md index 10321f949fb..a7215af909a 100644 --- a/docs/guide-fr/start-hello.md +++ b/docs/guide-fr/start-hello.md @@ -71,7 +71,7 @@ La vue `dire` doit être enregistrée dans le fichier `views/site/dire.php`. Qua est appelée dans une action, elle cherchera un fichier PHP nommé `views/ControllerID/NomDeLaVue.php`. Notez que dans le code ci-dessus, le paramètre `message` est [[yii\helpers\Html::encode()|Encodé-HTML]] -avant d'être affiché. Cela est nécessaire car le paramètre vient de l'utilisateur, le rendant vulnérable aux [attaques cross-site scripting (XSS)](http://fr.wikipedia.org/wiki/Cross-site_scripting) en intégrant du code Javascript malicieux dans le paramètre. +avant d'être affiché. Cela est nécessaire car le paramètre vient de l'utilisateur, le rendant vulnérable aux [attaques cross-site scripting (XSS)](https://fr.wikipedia.org/wiki/Cross-site_scripting) en intégrant du code Javascript malicieux dans le paramètre. Bien entendu, vous pouvez insérer plus de contenu dans la vue `dire`. Le contenu peut être des tags HTMML, du texte brut, ou même des expressions PHP. En réalité, la vue `dire` est simplement un script PHP exécuté par la méthode [[yii\web\Controller::render()|render()]]. diff --git a/docs/guide-fr/start-installation.md b/docs/guide-fr/start-installation.md index 655796137ad..a989b7bd6bc 100644 --- a/docs/guide-fr/start-installation.md +++ b/docs/guide-fr/start-installation.md @@ -67,7 +67,7 @@ Installer depuis une archive Installer Yii depuis une archive se fait en trois étapes : -1. Télécharger l'archive sur le site [yiiframework.com](http://www.yiiframework.com/download/). +1. Télécharger l'archive sur le site [yiiframework.com](https://www.yiiframework.com/download/). 2. Décompresser l'archive dans un dossier accessible via le Web. 3. Modifier le fichier `config/web.php` en entrant une clé secrète pour la configuration de `cookieValidationKey` (cela est fait automatiquement si vous installez Yii avec Composer) : @@ -91,10 +91,10 @@ Mais il y a d'autres options d'installation disponibles : Installer les Assets (ici bibliothèques CSS et JavaScript) ----------------- -Yii s'appuie sur les paquets [Bower](http://bower.io/) et/ou [NPM](https://www.npmjs.org/) pour l'installation des bibliothèques CSS et JavaScript. +Yii s'appuie sur les paquets [Bower](https://bower.io/) et/ou [NPM](https://www.npmjs.com/) pour l'installation des bibliothèques CSS et JavaScript. Il utilise Composer pour les obtenir, permettant ainsi aux versions de paquet de PHP et à celles de CSS/JavaScript, d'être résolues en même temps. -Cela peut être obtenue soit en utilisant [asset-packagist.org](https://asset-packagist.org) ou [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/). +Cela peut être obtenue soit en utilisant [asset-packagist.org](https://asset-packagist.org) ou [composer asset plugin](https://github.com/fxpio/composer-asset-plugin). Reportez-vous à la documentation sur les [Assets](structure-assets.md) pour plus de détail. @@ -115,7 +115,7 @@ Afin d'empêcher l'installation des « assets » via Composer, ajoutez les lig Vérifier l'installation ----------------------- -Après l'installation, vous pouvez, soit configurer votre serveur Web (voir section suivante), soit utiliser le [serveur PHP web incorporé](https://secure.php.net/manual/fr/features.commandline.webserver.php) en utilisant la commande en console suivante depuis le dossier racine de votre projet : +Après l'installation, vous pouvez, soit configurer votre serveur Web (voir section suivante), soit utiliser le [serveur PHP web incorporé](https://www.php.net/manual/fr/features.commandline.webserver.php) en utilisant la commande en console suivante depuis le dossier racine de votre projet : ```bash php yii serve @@ -145,7 +145,7 @@ Vous devriez voir dans votre navigateur la page ci-dessus. Sinon, merci de véri php requirements.php ``` -Vous devez configurer votre installation de PHP afin qu'elle réponde aux exigences minimales de Yii. Le plus important étant que vous ayez PHP 5.4 ou plus, idéalement PHP 7. Si votre application a besoin d'une base de données, vous devez également installer l'[extension PHP PDO](https://secure.php.net/manual/fr/pdo.installation.php) ainsi qu'un pilote correspondant à votre système de base de données (par exemple `pdo_mysql` pour MySQL). +Vous devez configurer votre installation de PHP afin qu'elle réponde aux exigences minimales de Yii. Le plus important étant que vous ayez PHP 5.4 ou plus, idéalement PHP 7. Si votre application a besoin d'une base de données, vous devez également installer l'[extension PHP PDO](https://www.php.net/manual/fr/pdo.installation.php) ainsi qu'un pilote correspondant à votre système de base de données (par exemple `pdo_mysql` pour MySQL). Configuration du serveur Web @@ -153,8 +153,8 @@ Configuration du serveur Web > Note: si vous voulez juste tester Yii sans intention de l'utiliser sur un serveur de production, vous pouvez ignorer ce paragraphe. -L'application installée selon les instructions ci-dessus devrait fonctionner *out of the box* (sans configuration supplémentaire) avec le [serveur HTTP Apache](http://httpd.apache.org/) ou le [serveur HTTP Nginx](http://nginx.org/), sous Windows, Mac OX X, ou Linux avec PHP 5.4 ou plus récent. Yii 2.0 est aussi compatible avec -[HHVM](http://hhvm.com/) de Facebook. Cependant, il existe des cas marginaux pour lesquels HHVM se comporte différemment du PHP natif; c'est pourquoi vous devez faire plus attention en utilisant HHVM.. +L'application installée selon les instructions ci-dessus devrait fonctionner *out of the box* (sans configuration supplémentaire) avec le [serveur HTTP Apache](https://httpd.apache.org/) ou le [serveur HTTP Nginx](https://nginx.org/), sous Windows, Mac OX X, ou Linux avec PHP 5.4 ou plus récent. Yii 2.0 est aussi compatible avec +[HHVM](https://hhvm.com/) de Facebook. Cependant, il existe des cas marginaux pour lesquels HHVM se comporte différemment du PHP natif; c'est pourquoi vous devez faire plus attention en utilisant HHVM.. Sur un serveur de production, vous pouvez configurer votre serveur Web afin que l'application soit accessible via l'URL `http://www.example.com/index.php` au lieu de `http://www.example.com/basic/web/index.php`. Cela implique que le dossier racine de votre serveur Web pointe vers le dossier `basic/web`. Vous pouvez également cacher `index.php` dans l'URL, comme décrit dans la partie [Génération et traitement des URL](runtime-url-handling.md), vous y apprendrez comment configurer votre serveur Apache ou Nginx pour atteindre ces objectifs. @@ -194,7 +194,7 @@ DocumentRoot "path/to/basic/web" ### Configuration Nginx recommandée -Pour utiliser Nginx, vous devez avoir installé PHP en utilisant [FPM SAPI](https://secure.php.net/install.fpm). +Pour utiliser Nginx, vous devez avoir installé PHP en utilisant [FPM SAPI](https://www.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.test` par le nom d'hôte de votre serveur. ```nginx diff --git a/docs/guide-fr/start-looking-ahead.md b/docs/guide-fr/start-looking-ahead.md index 8592ce84daf..a4bdd9dfdba 100644 --- a/docs/guide-fr/start-looking-ahead.md +++ b/docs/guide-fr/start-looking-ahead.md @@ -9,30 +9,30 @@ simples formulaires. Cette section va résumer les ressources Yii disponibles pour vous aider à être plus productif dans l'utilisation du framework. * Documentation - - [Le Guide complet](http://www.yiiframework.com/doc-2.0/guide-README.html) : + - [Le Guide complet](https://www.yiiframework.com/doc-2.0/guide-README.html) : Comme son nom l'indique, le guide définit précisément comment Yii fonctionne et fournit des instructions générales sur l'utilisation de Yii. C'est le tutoriel pour Yii le plus important, un que vous devriez lire avant d'écrire le moindre code Yii. - - [Le référentiel des Classes](http://www.yiiframework.com/doc-2.0/index.html) : + - [Le référentiel des Classes](https://www.yiiframework.com/doc-2.0/index.html) : Il spécifie le mode d'utilisation de toutes les classes fournies par Yii. Il doit être principalement utilisé lorsque vous écrivez du code et souhaitez comprendre le mode d'utilisation d'une classe, méthode ou propriété particulière. L'utilisation du référentiel des classes est plus appropriée quand vous avez une compréhension contextuelle du framework entier. - - [Les Articles du Wiki](http://www.yiiframework.com/wiki/?tag=yii2): + - [Les Articles du Wiki](https://www.yiiframework.com/wiki/?tag=yii2): Les articles wiki sont écrits par des utilisateurs de Yii sur la base de leurs propres expériences. Ils sont en général écrits comme des recettes de cuisine, et montrent comment résoudre des problèmes pratiques en utilisant Yii. Bien que la qualité de ces articles puisse être moindre que celle du Guide complet, ils sont utiles du fait qu'ils couvrent des sujets plus vastes et peuvent fournir des solutions clef-en-main. - - [Livres](http://www.yiiframework.com/doc/) -* [Extensions](http://www.yiiframework.com/extensions/): + - [Livres](https://www.yiiframework.com/books) +* [Extensions](https://www.yiiframework.com/extensions/): Yii est fort d'une librairie de milliers d'extensions créées par les utilisateurs, qui peuvent être facilement ajoutées à votre application, rendant son développement encore plus facile et plus rapide. * Communauté - - Forum : - - Chat IRC : Les canal #yii sur le réseau freenode () + - Forum : + - Chat IRC : Les canal #yii sur le réseau Libera () - Slack chanel: - Gitter chat: - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide-fr/start-prerequisites.md b/docs/guide-fr/start-prerequisites.md index c760d12b38b..c02df9b79be 100644 --- a/docs/guide-fr/start-prerequisites.md +++ b/docs/guide-fr/start-prerequisites.md @@ -4,8 +4,8 @@ La courbe d'apprentissage de Yii n’est pas aussi raide que celle des autres fr ## PHP -Yii un framework (base structurée de développement) en PHP. C’est pourquoi vous devez vous assurer de [maîtriser ce langage en comprenant sa référence](https://secure.php.net/manual/fr/langref.php). -Lors de votre développement avec Yii, vous écrirez du code dans le style « orienté objet ». Vous devez donc être familiarisé avec les [Classes et Objets](https://secure.php.net/manual/fr/language.oop5.basic.php), ainsi qu'avec les [espaces de noms](https://secure.php.net/manual/fr/language.namespaces.php). +Yii un framework (base structurée de développement) en PHP. C’est pourquoi vous devez vous assurer de [maîtriser ce langage en comprenant sa référence](https://www.php.net/manual/fr/langref.php). +Lors de votre développement avec Yii, vous écrirez du code dans le style « orienté objet ». Vous devez donc être familiarisé avec les [Classes et Objets](https://www.php.net/manual/fr/language.oop5.basic.php), ainsi qu'avec les [espaces de noms](https://www.php.net/manual/fr/language.namespaces.php). ## Programmation orientée Objet diff --git a/docs/guide-fr/start-workflow.md b/docs/guide-fr/start-workflow.md index 2058b6ce950..545cd83085d 100644 --- a/docs/guide-fr/start-workflow.md +++ b/docs/guide-fr/start-workflow.md @@ -37,7 +37,7 @@ Structure de l'application Les répertoires et fichiers les plus importants de votre application sont (en supposant que le répertoire racine de l'application est `basic`) : -``` +```js basic/ chemin de base de l'application composer.json utilisé par Composer, décrit les information de paquets config/ contient les configurations de l'application et autres @@ -57,7 +57,7 @@ basic/ chemin de base de l'application Dans l'ensemble, les fichiers de l'application peuvent être séparés en deux types : ceux situés dans `basic/web` et ceux situés dans d'autres répertoires. Les premiers peuvent être atteints directement en HTTP (c'est à dire dans un navigateur), tandis que les seconds ne peuvent et ne doivent pas l'être. -Yii est mis en œuvre selon le modèle de conception [modèle-vue-contrôleur (MVC)](http://wikipedia.org/wiki/Model-view-controller), +Yii est mis en œuvre selon le modèle de conception [modèle-vue-contrôleur (MVC)](https://wikipedia.org/wiki/Model-view-controller), ce qui se reflète dans l'organisation des répertoires ci-dessus. Le répertoire `models` contient toutes les [classes modèles](structure-models.md), le répertoire `views` contient tous les [scripts de vue](structure-views.md), et le répertoire `controllers` contient toutes les [classes contrôleurs](structure-controllers.md). diff --git a/docs/guide-fr/structure-applications.md b/docs/guide-fr/structure-applications.md index 60bc43c6d0a..2d93660f1d9 100644 --- a/docs/guide-fr/structure-applications.md +++ b/docs/guide-fr/structure-applications.md @@ -234,7 +234,7 @@ La valeur par défaut de cette propriété est `en`, pour anglais. Vous devez c La valeur de cette propriété détermine des aspects variés de l'[internationalisation](tutorial-i18n.md) tels que la traduction des messages, le formatage des dates et des nombres, etc. Par exemple, l'objet graphique [[yii\jui\DatePicker]] utilise la valeur de cette propriété pour déterminer dans quelle langue le calendrier doit être affiché et comment les dates doivent être formatées. -La spécification de la langue par une [étiquette IETF d'identification de langue ](http://en.wikipedia.org/wiki/IETF_language_tag) est recommandée. Par exemple, `en` signifie anglais, tandis que `en-US` signifie anglais (États-Unis).. +La spécification de la langue par une [étiquette IETF d'identification de langue ](https://en.wikipedia.org/wiki/IETF_language_tag) est recommandée. Par exemple, `en` signifie anglais, tandis que `en-US` signifie anglais (États-Unis).. Pour plus d'informations sur cette propriété, reportez-vous à la section [Internationalisation](tutorial-i18n.md). @@ -306,7 +306,7 @@ Pour plus d'informations sur cette propriété, reportez-vous à la section [Int Cette propriété est fournie comme une manière alternative de définir le fuseau horaire par défaut au moment de l'exécution du script PHP. En configurant cette propriété, vous ne faites essentiellement qu'appeler la fonction PHP -[date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php). Par exemple : +[date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php). Par exemple : ```php [ diff --git a/docs/guide-fr/structure-assets.md b/docs/guide-fr/structure-assets.md index 1ea514dd90b..df87aee7b19 100644 --- a/docs/guide-fr/structure-assets.md +++ b/docs/guide-fr/structure-assets.md @@ -79,7 +79,7 @@ Chaque fichier JavaScript peut être spécifié dans l'un des formats suivants  Le chemin réel du fichier peut être déterminé en préfixant le chemin relatif avec le [[yii\web\AssetManager::basePath| chemin de base]], et l'URL réelle du fichier peut être déterminée en préfixant le chemin relatif avec l'[[yii\web\AssetManager::baseUrl|URL de base]]. - Une URL absolue représentant un fichier JavaScript externe. -Par exemple , `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` ou +Par exemple , `https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` ou `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. * [[yii\web\AssetBundle::depends|depends (dépendances)]]: un tableau listant les paquets de ressources dont ce paquet dépend (brièvement expliqué). @@ -201,12 +201,12 @@ class FontAwesomeAsset extends AssetBundle } ``` -L'exemple ci-dessus définit un paquet de ressources pour le [paquet "fontawesome"](http://fontawesome.io/). En spécifiant l'option de publication `only`, seuls les sous-dossiers `fonts` et `css` sont publiés. +L'exemple ci-dessus définit un paquet de ressources pour le [paquet "fontawesome"](https://fontawesome.com/). En spécifiant l'option de publication `only`, seuls les sous-dossiers `fonts` et `css` sont publiés. ### Installation des ressources Bower et NPM -La plupart des paquets JavaScript/CSS sont gérés par le gestionnaire de paquets [Bower](http://bower.io/) et/ou le gestionnaire de paquets [NPM](https://www.npmjs.org/). Dans le monde PHP, nous disposons de Composer, qui gère les dépendances, mais il est possible de charger des paquets Bower et NPM comme des paquets PHP en utilisant `composer.json`. +La plupart des paquets JavaScript/CSS sont gérés par le gestionnaire de paquets [Bower](https://bower.io/) et/ou le gestionnaire de paquets [NPM](https://www.npmjs.com/). Dans le monde PHP, nous disposons de Composer, qui gère les dépendances, mais il est possible de charger des paquets Bower et NPM comme des paquets PHP en utilisant `composer.json`. Pour cela, nous devons configurer quelque peu notre composer. Il y a deux options possibles : @@ -252,7 +252,7 @@ Comparé à asset-packagist, composer-asset-plugin ne nécessite aucun changemen composer global require "fxp/composer-asset-plugin:^1.4.1" ``` -Cette commande installe [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) globalement, ce qui permet de gérer les dépendances des paquets Bower et NPM via Composer. Après l'installation du greffon, tout projet de votre ordinateur prendra en charge les paquets Bower et NPM via `composer.json`. +Cette commande installe [composer asset plugin](https://github.com/fxpio/composer-asset-plugin) globalement, ce qui permet de gérer les dépendances des paquets Bower et NPM via Composer. Après l'installation du greffon, tout projet de votre ordinateur prendra en charge les paquets Bower et NPM via `composer.json`. Ajoutez les lignes suivantes au fichier `composer.json` de votre projet pour préciser les dossiers où seront installés les paquets, si vous voulez les publier en utilisant Yii : @@ -468,7 +468,7 @@ Si votre code dépend de jQuery, jQuery UI ou Bootstrap, vous devriez utiliser l ## Conversion de ressources -Au lieu d'écrire directement leur code CSS et/ou JavaScript, les développeurs l'écrivent souvent dans une syntaxe étendue et utilisent des outils spéciaux pour le convertir en CSS/JavaScript. Par exemple, pour le code CSS vous pouvez utiliser [LESS](http://lesscss.org/) ou [SCSS](http://sass-lang.com/); et pour JavaScript, vous pouvez utiliser [TypeScript](http://www.typescriptlang.org/). +Au lieu d'écrire directement leur code CSS et/ou JavaScript, les développeurs l'écrivent souvent dans une syntaxe étendue et utilisent des outils spéciaux pour le convertir en CSS/JavaScript. Par exemple, pour le code CSS vous pouvez utiliser [LESS](https://lesscss.org/) ou [SCSS](https://sass-lang.com/); et pour JavaScript, vous pouvez utiliser [TypeScript](http://www.typescriptlang.org/). Vous pouvez lister les fichiers de ressources écrits dans une syntaxe étendue dans les propriétés [[yii\web\AssetBundle::css|css]] et [[yii\web\AssetBundle::js|js]] d'un paquet de ressources. @@ -494,13 +494,13 @@ Lorsque vous enregistrez une tel paquet de ressources dans une vue, le [[yii\web Yii utilise l'extension du nom de fichier pour identifier dans quelle syntaxe une ressource est écrite. Par défaut, il reconnaît les syntaxes et les extensions de nom suivants : -- [LESS](http://lesscss.org/): `.less` -- [SCSS](http://sass-lang.com/): `.scss` -- [Stylus](http://learnboost.github.io/stylus/): `.styl` -- [CoffeeScript](http://coffeescript.org/): `.coffee` -- [TypeScript](http://www.typescriptlang.org/): `.ts` +- [LESS](https://lesscss.org/): `.less` +- [SCSS](https://sass-lang.com/): `.scss` +- [Stylus](https://stylus-lang.com/): `.styl` +- [CoffeeScript](https://coffeescript.org/): `.coffee` +- [TypeScript](https://www.typescriptlang.org/): `.ts` -Yii se fie aux outils de pré-traitement installés pour convertir les ressources. Par exemple, pour utiliser [LESS](http://lesscss.org/), vous devriez utiliser la commande de pré-traitement `lessc`. +Yii se fie aux outils de pré-traitement installés pour convertir les ressources. Par exemple, pour utiliser [LESS](https://lesscss.org/), vous devriez utiliser la commande de pré-traitement `lessc`. Vous pouvez personnaliser les commandes de pré-traitement et la syntaxe étendue prise en charge en configurant [[yii\web\AssetManager::converter]] comme ci-après : diff --git a/docs/guide-fr/structure-controllers.md b/docs/guide-fr/structure-controllers.md index 2970824a219..aa9fea4f1e7 100644 --- a/docs/guide-fr/structure-controllers.md +++ b/docs/guide-fr/structure-controllers.md @@ -1,7 +1,7 @@ Contrôleurs =========== -Les contrôleurs font partie du modèle d'architecture [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Modèle Vue Contrôleur). Ce sont des objets dont la classe étend [[yii\base\Controller]]. Ils sont chargés de traiter les requêtes et de générer les réponses. En particulier, après que l'objet [application](structure-applications.md) leur a passé le contrôle, ils analysent les données de la requête entrante, les transmettent aux [modèles](structure-models.md), injectent le résultat des modèles dans les [vues](structure-views.md) et, pour finir, génèrent les réponses sortantes. +Les contrôleurs font partie du modèle d'architecture [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Modèle Vue Contrôleur). Ce sont des objets dont la classe étend [[yii\base\Controller]]. Ils sont chargés de traiter les requêtes et de générer les réponses. En particulier, après que l'objet [application](structure-applications.md) leur a passé le contrôle, ils analysent les données de la requête entrante, les transmettent aux [modèles](structure-models.md), injectent le résultat des modèles dans les [vues](structure-views.md) et, pour finir, génèrent les réponses sortantes. ## Actions diff --git a/docs/guide-fr/structure-entry-scripts.md b/docs/guide-fr/structure-entry-scripts.md index 118b8a74378..e81ac22a2d4 100644 --- a/docs/guide-fr/structure-entry-scripts.md +++ b/docs/guide-fr/structure-entry-scripts.md @@ -57,9 +57,9 @@ De même, le code qui suit est le code du script de démarrage d'une application /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-fr/structure-extensions.md b/docs/guide-fr/structure-extensions.md index cbf06f8a7b3..3331b25fd91 100644 --- a/docs/guide-fr/structure-extensions.md +++ b/docs/guide-fr/structure-extensions.md @@ -59,7 +59,7 @@ Dans quelques cas rares, vous désirez installer quelques, ou toutes les, extens 2. Installer la classe *autoloader* procurée par les extensions, si elles en possèdent. 3. Télécharger et installer toutes les extensions dont vos extensions dépendent selon les instructions. -Si une extension ne possède pas de classe *autoloader* mais obéit à la [norme PSR-4](http://www.php-fig.org/psr/psr-4/), vous pouvez utiliser la classe *autoloader* procurée par Yii pour charger automatiquement les classes d'extension. Tout ce que vous avez à faire, c'est de déclarer un [alias racine](concept-aliases.md#defining-aliases) pour le dossier racine de l'extension. Par exemple, en supposant que vous avez installé une extension dans le dossier `vendor/mycompany/myext`, et que les classes d'extension sont sous l'espace de noms `myext`, alors vous pouvez inclure le code suivant dans la configuration de votre application : +Si une extension ne possède pas de classe *autoloader* mais obéit à la [norme PSR-4](https://www.php-fig.org/psr/psr-4/), vous pouvez utiliser la classe *autoloader* procurée par Yii pour charger automatiquement les classes d'extension. Tout ce que vous avez à faire, c'est de déclarer un [alias racine](concept-aliases.md#defining-aliases) pour le dossier racine de l'extension. Par exemple, en supposant que vous avez installé une extension dans le dossier `vendor/mycompany/myext`, et que les classes d'extension sont sous l'espace de noms `myext`, alors vous pouvez inclure le code suivant dans la configuration de votre application : ```php [ @@ -101,9 +101,9 @@ L'exemple suivant montre le fichier `composer.json` de l'extension `yiisoft/yii2 "license": "BSD-3-Clause", "support": { "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki/", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "authors": [ @@ -148,8 +148,8 @@ Losqu'un utilisateur exécute `composer install` pour installer une extension, l Bien sûr, votre extension dépend de Yii. C'est pourquoi, vous devez lister (`yiisoft/yii2`) dans l'entrée `require` dans `composer.json`. Si votre extension dépend aussi d'autres extensions ou bibliothèques de tierces parties, vous devez les lister également. Assurez-vous que vous de lister également les contraintes de versions appropriées (p. ex. `1.*`, `@stable`) pour chacun des paquets dont votre extension dépend. Utilisez des dépendances stables lorsque votre extension est publiée dans une version stable. -La plupart des paquets JavaScript/CSS sont gérés par [Bower](http://bower.io/) et/ou [NPM](https://www.npmjs.org/), -plutôt que par Composer. Yii utilise le [greffon *assets* de Composer(https://github.com/francoispluchino/composer-asset-plugin) pour activer la gestion de ce genre de paquets par Composer. Si votre extension dépend d'un paquet Bower, vous pouvez simplement lister la dépendance dans `composer.json` comme ceci : +La plupart des paquets JavaScript/CSS sont gérés par [Bower](https://bower.io/) et/ou [NPM](https://www.npmjs.com/), +plutôt que par Composer. Yii utilise le [greffon *assets* de Composer(https://github.com/fxpio/composer-asset-plugin) pour activer la gestion de ce genre de paquets par Composer. Si votre extension dépend d'un paquet Bower, vous pouvez simplement lister la dépendance dans `composer.json` comme ceci : ```json { @@ -193,7 +193,7 @@ Parce que les extensions sont prévues pour être utilisées par d'autres person #### Espaces de noms -Pour éviter les collisions de noms et rendre le chargement des classes de votre extension automatique, vous devez utiliser des espaces de noms et nommer les classes de votre extension en respectant la [norme PSR-4](http://www.php-fig.org/psr/psr-4/) ou la [norme PSR-0](http://www.php-fig.org/psr/psr-0/). +Pour éviter les collisions de noms et rendre le chargement des classes de votre extension automatique, vous devez utiliser des espaces de noms et nommer les classes de votre extension en respectant la [norme PSR-4](https://www.php-fig.org/psr/psr-4/) ou la [norme PSR-0](https://www.php-fig.org/psr/psr-0/). Vos noms de classe doivent commencer par `vendorName\extensionName`, où `extensionName` est similaire au nom du projet dans le nom du paquet sauf qu'il doit contenir le préfixe `yii2-`. Par exemple, pour l'extension `yiisoft/yii2-imagine`, nous utilisons l'espace de noms `yii\imagine` pour ses classes. @@ -278,7 +278,7 @@ Il est recommandé que créiez des cas de test variés pour tester votre extensi #### Numérotation des versions -Vous devriez donner à chacune des versions publiées de votre extension un numéro (p. ex. `1.0.1`). Nous recommandons de suivre la pratique de la [numérotation sémantique des versions](http://semver.org) lors de la détermination d'un numéro de version. +Vous devriez donner à chacune des versions publiées de votre extension un numéro (p. ex. `1.0.1`). Nous recommandons de suivre la pratique de la [numérotation sémantique des versions](https://semver.org) lors de la détermination d'un numéro de version. #### Publication @@ -286,7 +286,7 @@ Vous devriez donner à chacune des versions publiées de votre extension un num Pour permettre aux autres personnes de connaître votre extension, vous devez la publier. Si c'est la première fois que vous publiez l'extension, vous devez l'enregistrer sur un dépôt Composer tel que [Packagist](https://packagist.org/). Ensuite, tout ce que vous avez à faire, c'est de créer une balise de version (p. ex. `v1.0.1`) sur le dépôt VCS de votre extension et de notifier au dépôt Composer la nouvelle version. Les gens seront capables de trouver votre nouvelle version et, soit de l'installer, soit de la mettre à jour via le dépôt Composer. Dans les versions de votre extension, en plus des fichiers de code, vous devez envisager d'inclure ce qui suit par aider les gens à connaître votre extension et à l'utiliser : -* Un ficher *readme* (lisez-moi) dans le dossier racine du paquet : il doit décrire ce que fait votre extension, comment l'installer et l'utiliser. Nous vous recommandons de l'écrire dans le format [Markdown](http://daringfireball.net/projects/markdown/) et de nommer ce fichier `readme.md`. +* Un ficher *readme* (lisez-moi) dans le dossier racine du paquet : il doit décrire ce que fait votre extension, comment l'installer et l'utiliser. Nous vous recommandons de l'écrire dans le format [Markdown](https://daringfireball.net/projects/markdown/) et de nommer ce fichier `readme.md`. * Un fichier *changelog* (journal des modifications) dans le dossier racine du paquet : il liste les changements apportés dans chacune des versions. Ce fichier peut être écrit dans le format Markdown et nommé `changelog.md`. * Un fichier *upgrade* (mise à jour) dans le dossier racine du paquet : il donne les instructions sur la manière de mettre l'extension à jour en partant d'une version précédente. Ce fichier peut être écrit dans le format Markdown et nommé `upgrade.md`. * Tutorials, demos, screenshots, etc.: ces derniers sont nécessaires si votre extension fournit de nombreuses fonctionnalités qui ne peuvent être couvertes dans le fichier readme. @@ -294,7 +294,7 @@ Dans les versions de votre extension, en plus des fichiers de code, vous devez e > Info: les commentaires de votre code peuvent être écrits dans le format Markdown. L'extension `yiisoft/yii2-apidoc` vous fournit un outil pour générer une documentation d'API agréable et basée sur les commentaires de votre code. -> Info: bien que cela ne soit pas une exigence, nous suggérons que votre extension respecte un certain style de codage. Vous pouvez vous reporter au document [style du codage du noyau du framework](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style). +> Info: bien que cela ne soit pas une exigence, nous suggérons que votre extension respecte un certain style de codage. Vous pouvez vous reporter au document [style du codage du noyau du framework](https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md). ## Extensions du noyau @@ -303,23 +303,22 @@ Yii fournit les extensions du noyau suivantes (ou ["les extensions officielles"] - [yiisoft/yii2-apidoc](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc) : fournit un générateur d'API extensible et de haute performance. Elle est aussi utilisée pour générer l'API du noyau du framework. - [yiisoft/yii2-authclient](https://www.yiiframework.com/extension/yiisoft/yii2-authclient) : fournit un jeu de clients d'authentification courants tels que Facebook OAuth2 client, GitHub OAuth2 client. -- [yiisoft/yii2-bootstrap](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap) : fournit un jeu d'objets graphiques qui encapsulent les composants et les greffons de [Bootstrap](http://getbootstrap.com/). -- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception)(obsolète) : fournit la prise en charge des fonctionnalités de test basées sur [Codeception](http://codeception.com/). +- [yiisoft/yii2-bootstrap](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap) : fournit un jeu d'objets graphiques qui encapsulent les composants et les greffons de [Bootstrap](https://getbootstrap.com/). - [yiisoft/yii2-debug](https://www.yiiframework.com/extension/yiisoft/yii2-debug) : fournit la prise en charge du débogage des applications Yii. Lorsque cette extension est utilisée, une barre de débogage apparaît au pied de chacune des pages. Cette extension fournit aussi un jeu de pages autonomes pour afficher des informations de débogage plus détaillées. -- [yiisoft/yii2-elasticsearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch) : fournit la prise en charge d'[Elasticsearch](http://www.elasticsearch.org/). Elle inclut un moteur de requêtes/recherches de base et met en œuvre le motif [Active Record](db-active-record.md) qui permet de stocker des enregistrement actifs dans Elasticsearch. +- [yiisoft/yii2-elasticsearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch) : fournit la prise en charge d'[Elasticsearch](https://www.elastic.co/). Elle inclut un moteur de requêtes/recherches de base et met en œuvre le motif [Active Record](db-active-record.md) qui permet de stocker des enregistrement actifs dans Elasticsearch. - [yiisoft/yii2-faker](https://www.yiiframework.com/extension/yiisoft/yii2-faker) : fournit la prise en charge de [Faker](https://www.yiiframework.com/extension/fzaninotto/Faker) pour générer des données factices pour vous. - [yiisoft/yii2-gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii) : fournit un générateur de code basé sur le Web qui est hautement extensible et peut être utilisé pour générer rapidement des modèles, des formulaires, des modules, des requêtes CRUD, etc. - [yiisoft/yii2-httpclient](https://www.yiiframework.com/extension/yiisoft/yii2-httpclient) : provides an HTTP client. - [yiisoft/yii2-imagine](https://github.com/yiisoft/yii2-imagine) : fournit des fonctionnalités couramment utilisées de manipulation d'images basées sur [Imagine](https://www.yiiframework.com/extension/yiisoft/yii2-imagine). -- [yiisoft/yii2-jui](https://www.yiiframework.com/extension/yiisoft/yii2-jui) : fournit un jeu d'objets graphiques qui encapsulent les interactions et les objets graphiques de [JQuery UI](http://jqueryui.com/). -- [yiisoft/yii2-mongodb](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb) : fournit la prise en charge de [MongoDB](http://www.mongodb.org/). Elle inclut des fonctionnalités telles que les requêtes de base, les enregistrements actifs, les migrations, la mise en cache, la génération de code, etc. +- [yiisoft/yii2-jui](https://www.yiiframework.com/extension/yiisoft/yii2-jui) : fournit un jeu d'objets graphiques qui encapsulent les interactions et les objets graphiques de [JQuery UI](https://jqueryui.com/). +- [yiisoft/yii2-mongodb](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb) : fournit la prise en charge de [MongoDB](https://www.mongodb.com/). Elle inclut des fonctionnalités telles que les requêtes de base, les enregistrements actifs, les migrations, la mise en cache, la génération de code, etc. - [yiisoft/yii2-queue](https://www.yiiframework.com/extension/yiisoft/yii2-queue): fournit la prise en charge pour exécuter des tâches en asynchrone via des queues. Il prend en charge les queues en se basant sur, DB, Redis, RabbitMQ, AMQP, Beanstalk et Gearman. -- [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis) : fournit la prise en charge de [redis](http://redis.io/). Elle inclut des fonctionnalités telles que les requêtes de base, les enregistrements actifs, la mise en cache, etc. -- [yiisoft/yii2-shell](https://www.yiiframework.com/extension/yiisoft/yii2-shell): fournit un interprète de commandes (shell) basé sur [psysh](http://psysh.org/). -- [yiisoft/yii2-smarty](https://www.yiiframework.com/extension/yiisoft/yii2-smarty) : fournit un moteur de modèles basé sur [Smarty](http://www.smarty.net/). +- [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis) : fournit la prise en charge de [redis](https://redis.io/). Elle inclut des fonctionnalités telles que les requêtes de base, les enregistrements actifs, la mise en cache, etc. +- [yiisoft/yii2-shell](https://www.yiiframework.com/extension/yiisoft/yii2-shell): fournit un interprète de commandes (shell) basé sur [psysh](https://psysh.org/). +- [yiisoft/yii2-smarty](https://www.yiiframework.com/extension/yiisoft/yii2-smarty) : fournit un moteur de modèles basé sur [Smarty](https://www.smarty.net/). - [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx) : fournit la prise en charge de [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx). Elle inclut des fonctionnalités telles que les requêtes de base, les enregistrements actifs, la génération de code, etc. - [yiisoft/yii2-swiftmailer](https://www.yiiframework.com/extension/yiisoft/yii2-swiftmailer) : fournit les fonctionnalités d'envoi de courriels basées sur [swiftmailer](http://swiftmailer.org/). -- [yiisoft/yii2-twig](https://www.yiiframework.com/extension/yiisoft/yii2-twig) : fournit un moteur de modèles basé sur [Twig](http://twig.sensiolabs.org/). +- [yiisoft/yii2-twig](https://www.yiiframework.com/extension/yiisoft/yii2-twig) : fournit un moteur de modèles basé sur [Twig](https://twig.symfony.com/). Les extensions officielles suivantes sont valables pour les versions Yii 2.1 et plus récentes. Vous n'avez pas besoin de les installer car elles sont incluse dans le cœur du framework. @@ -328,7 +327,7 @@ Les extensions officielles suivantes sont valables pour les versions Yii 2.1 et - [yiisoft/yii2-jquery](https://www.yiiframework.com/extension/yiisoft/yii2-jquery): fournit une prise en charge de [jQuery](https://jquery.com/). - [yiisoft/yii2-maskedinput](https://www.yiiframework.com/extension/yiisoft/yii2-maskedinput): - fournit un composant graphique de saisie masqué basé sur [jQuery Input Mask plugin](http://robinherbots.github.io/Inputmask/). + fournit un composant graphique de saisie masqué basé sur [jQuery Input Mask plugin](https://robinherbots.github.io/Inputmask/). - [yiisoft/yii2-mssql](https://www.yiiframework.com/extension/yiisoft/yii2-mssql): fournit la prise en charge de [MSSQL](https://www.microsoft.com/sql-server/). - [yiisoft/yii2-oracle](https://www.yiiframework.com/extension/yiisoft/yii2-oracle): diff --git a/docs/guide-fr/structure-filters.md b/docs/guide-fr/structure-filters.md index 90e44889e9f..7b4a8737fc6 100644 --- a/docs/guide-fr/structure-filters.md +++ b/docs/guide-fr/structure-filters.md @@ -96,7 +96,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['create', 'update'], 'rules' => [ // autoriser les utilisateurs authentifiés @@ -117,7 +117,7 @@ Pour plus de détails sur le contrôle d'accès en général, reportez-vous à l ### Filtres de méthodes d'authentification Les filtres de méthodes d'authentification sont utilisés pour authentifier un utilisateur qui utilise des méthodes d'authentification variées comme -[HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication) ou [OAuth 2](http://oauth.net/2/). Les classes de filtre sont dans l'espace de noms `yii\filters\auth`. +[HTTP Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication) ou [OAuth 2](https://oauth.net/2/). Les classes de filtre sont dans l'espace de noms `yii\filters\auth`. L'exemple qui suit montre comment vous pouvez utiliser [[yii\filters\auth\HttpBasicAuth]] pour authentifier un utilisateur qui utilise un jeton d'accès basé sur la méthode *HTTP Basic Auth*. Notez qu'afin que cela fonctionne, votre [[yii\web\User::identityClass|classe *identity* de l'utilisateur]] doit implémenter l'interface [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]. @@ -128,7 +128,7 @@ public function behaviors() { return [ 'basicAuth' => [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ], ]; } @@ -151,7 +151,7 @@ public function behaviors() { return [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -174,7 +174,7 @@ use yii\web\Response; [ 'bootstrap' => [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -204,7 +204,7 @@ public function behaviors() { return [ [ - 'class' => HttpCache::className(), + 'class' => HttpCache::class, 'only' => ['index'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); @@ -230,11 +230,11 @@ public function behaviors() { return [ 'pageCache' => [ - 'class' => PageCache::className(), + 'class' => PageCache::class, 'only' => ['index'], 'duration' => 60, 'dependency' => [ - 'class' => DbDependency::className(), + 'class' => DbDependency::class, 'sql' => 'SELECT COUNT(*) FROM post', ], 'variations' => [ @@ -250,7 +250,7 @@ Reportez-vous à la section [Page Caching](caching-page.md) pour plus de détail ### [[yii\filters\RateLimiter|RateLimiter]] -*RateLimiter* met en œuvre un algorithme de limitation de débit basé sur l'[algorithme leaky bucket](http://en.wikipedia.org/wiki/Leaky_bucket). On l'utilise en premier lieu dans la mise en œuvre des API pleinement REST. Reportez-vous à la section [limitation de débit](rest-rate-limiting.md) pour plus de détails sur l'utilisation de ce filtre. +*RateLimiter* met en œuvre un algorithme de limitation de débit basé sur l'[algorithme leaky bucket](https://en.wikipedia.org/wiki/Leaky_bucket). On l'utilise en premier lieu dans la mise en œuvre des API pleinement REST. Reportez-vous à la section [limitation de débit](rest-rate-limiting.md) pour plus de détails sur l'utilisation de ce filtre. ### [[yii\filters\VerbFilter|VerbFilter]] @@ -264,7 +264,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'index' => ['get'], 'view' => ['get'], @@ -291,7 +291,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, ], ], parent::behaviors()); } @@ -318,7 +318,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], @@ -338,7 +338,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], diff --git a/docs/guide-fr/structure-models.md b/docs/guide-fr/structure-models.md index f6186a7baff..bf4f385a5d2 100644 --- a/docs/guide-fr/structure-models.md +++ b/docs/guide-fr/structure-models.md @@ -1,7 +1,7 @@ Modèles ======= -Les modèles font partie du modèle d'architecture [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Modèle Vue Contrôleur). +Les modèles font partie du modèle d'architecture [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Modèle Vue Contrôleur). Ces objets représentent les données à traiter, les règles et la logique de traitement. Vous pouvez créer des classes de modèle en étendant la classe [[yii\base\Model]] ou ses classe filles. La classe de base [[yii\base\Model]] prend en charge des fonctionnalités nombreuses et utiles : @@ -31,7 +31,7 @@ $model->name = 'example'; echo $model->name; ``` -Vous pouvez également accéder aux attributs comme aux éléments d'un tableau, grâce à la prise en charge de [ArrayAccess](https://secure.php.net/manual/en/class.arrayaccess.php) et [ArrayIterator](https://secure.php.net/manual/en/class.arrayiterator.php) +Vous pouvez également accéder aux attributs comme aux éléments d'un tableau, grâce à la prise en charge de [ArrayAccess](https://www.php.net/manual/en/class.arrayaccess.php) et [ArrayIterator](https://www.php.net/manual/en/class.arrayiterator.php) par la classe [[yii\base\Model]]: ```php diff --git a/docs/guide-fr/structure-modules.md b/docs/guide-fr/structure-modules.md index d04e02b4706..2e3f04e7cfc 100644 --- a/docs/guide-fr/structure-modules.md +++ b/docs/guide-fr/structure-modules.md @@ -8,7 +8,7 @@ Les modules sont des unités logicielles auto-suffisantes constituées de [modè Un module est organisé comme un dossier qui est appelé le [[yii\base\Module::basePath|dossier de base (*basePath*)]] du module. Dans ce dossier, se trouvent des sous-dossiers, tels que `controllers`, `models` et `views`, qui contiennent les contrôleurs, les modèles , les vues et d'autres parties de code, juste comme une application. L'exemple suivant présente le contenu d'un module : -``` +```js forum/ Module.php le fichier de classe du module controllers/ contient les fichiers de classe des contrôleurs diff --git a/docs/guide-fr/structure-overview.md b/docs/guide-fr/structure-overview.md index 0df348cbd1a..dd6e4ee94f2 100644 --- a/docs/guide-fr/structure-overview.md +++ b/docs/guide-fr/structure-overview.md @@ -2,7 +2,7 @@ Vue d'ensemble ======== Les applications Yii sont organisées suivant le modèle de conception -[model-view-controller (MVC)](http://wikipedia.org/wiki/Model-view-controller). Les [Modèles](structure-models.md) +[model-view-controller (MVC)](https://wikipedia.org/wiki/Model-view-controller). Les [Modèles](structure-models.md) représentent les données, la logique métier et les règles; les [vues](structure-views.md) sont les représentations visuelles des modèles, et les [contrôleurs](structure-controllers.md) prennent une entrée et la convertissent en commandes pour les [modèles](structure-models.md) et les [vues](structure-views.md). diff --git a/docs/guide-fr/structure-views.md b/docs/guide-fr/structure-views.md index baa60b99e25..8f90ccc2000 100644 --- a/docs/guide-fr/structure-views.md +++ b/docs/guide-fr/structure-views.md @@ -1,7 +1,7 @@ Vues ===== -Les vues font partie du modèle d'architecture [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Modèle Vue Contrôleur). +Les vues font partie du modèle d'architecture [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Modèle Vue Contrôleur). Elles sont chargées de présenter les données à l'utilisateur final. Dans une application Web, les vues sont ordinairement créées en termes de *modèles de vue* qui sont des script PHP contenant principalement du code HTML et du code PHP relatif à la présentation. Elles sont gérées par le [[yii\web\View|view]] [composant application](structure-application-components.md) qui fournit des méthodes d'usage courant pour faciliter la composition des vues et leur rendu. Par souci de simplicité, nous appellerons *vues* les modèles de vue et les fichiers de modèle de vue. @@ -42,7 +42,7 @@ En plus de `$this`, il peut aussi y avoir d'autres variables prédéfinies dans ### Sécurité -Lors de la création de vues qui génèrent des pages HTML, il est important que vous encodiez et/ou filtriez les données en provenance de l'utilisateur final avant des les présenter. Autrement, votre application serait sujette aux [attaques par injection de scripts (*cross-site scripting*)](http://en.wikipedia.org/wiki/Cross-site_scripting). +Lors de la création de vues qui génèrent des pages HTML, il est important que vous encodiez et/ou filtriez les données en provenance de l'utilisateur final avant des les présenter. Autrement, votre application serait sujette aux [attaques par injection de scripts (*cross-site scripting*)](https://en.wikipedia.org/wiki/Cross-site_scripting). Pour afficher du texte simple, commencez par l'encoder en appelant la méthode [[yii\helpers\Html::encode()]]. Par exemple, le code suivant encode le nom d'utilisateur (*username*) avant de l'afficher : @@ -435,7 +435,7 @@ Les composants View fournissent les fonctionnalités utiles suivantes relatives * [mise en cache de fragments](caching-fragment.md): vous permet de mettre en cache un fragment de votre page Web. * [gestion des scripts client](output-client-scripts.md): prend en charge l'enregistrement et le rendu de code CSS et JavaScript. * [gestion de paquets de ressources](structure-assets.md): prend en charge l'enregistrement et le rendu de [paquets de ressources](structure-assets.md). -* [moteurs de modèle alternatif](tutorial-template-engines.md): vous permet d'utiliser d'autres moteur de modèles tels que [Twig](http://twig.sensiolabs.org/) et [Smarty](http://www.smarty.net/). +* [moteurs de modèle alternatif](tutorial-template-engines.md): vous permet d'utiliser d'autres moteur de modèles tels que [Twig](https://twig.symfony.com/) et [Smarty](https://www.smarty.net/). Vous pouvez aussi utiliser les fonctionnalités suivantes qui, bien que mineures, sont néanmoins utiles, pour développer vos pages Web. @@ -497,14 +497,14 @@ $this->registerLinkTag([ 'title' => 'Live News for Yii', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` Le code suivant produit le résultat suivant : ```html - + ``` Comme avec [[yii\web\View::registerMetaTag()|registerMetaTag()]], vous pouvez spécifier un clé lors de l'appel de [[yii\web\View::registerLinkTag()|registerLinkTag()]] pour éviter de générer des liens identiques. diff --git a/docs/guide-fr/structure-widgets.md b/docs/guide-fr/structure-widgets.md index beef8372192..ececdee2600 100644 --- a/docs/guide-fr/structure-widgets.md +++ b/docs/guide-fr/structure-widgets.md @@ -52,7 +52,7 @@ use yii\helpers\Html; Notez que contrairement à la méthode [[yii\base\Widget::widget()]] qui retourne le résultat du rendu d'un objet graphique, la méthode [[yii\base\Widget::begin()]] retourne une instance de l'objet graphique que vous pouvez utiliser pour construire le contenu de l'objet d'interface. -> Note: quelques objets graphiques utilisent [la mise en tampon de sortie](https://secure.php.net/manual/en/book.outcontrol.php) +> Note: quelques objets graphiques utilisent [la mise en tampon de sortie](https://www.php.net/manual/en/book.outcontrol.php) > pour ajuster le contenu inclus quand la méthode [[yii\base\Widget::end()]] est appelée. > Pour cette raison, l'appel des méthodes [[yii\base\Widget::begin()]] et > [[yii\base\Widget::end()]] est attendu dans le même fichier de vue. diff --git a/docs/guide-fr/tutorial-i18n.md b/docs/guide-fr/tutorial-i18n.md index 0648f29471c..55109edaf98 100644 --- a/docs/guide-fr/tutorial-i18n.md +++ b/docs/guide-fr/tutorial-i18n.md @@ -10,8 +10,8 @@ Une *locale* est un jeu de paramètres qui définissent la langue de l'utilisate Elle est généralement identifiée par un identifiant (ID), lui-même constitué par un identifiant de langue et un identifiant de région. Par exemple, l'identifiant `en-US` représente la locale *anglais* pour la langue et *États-Unis* pour la région. -Pour assurer la cohérence, tous les identifiants utilisés par les application Yii doivent être présentés sous leur forme canonique `ll-CC`, où `ll` est un code à 2 ou 3 lettres pour la langue conforme à la norme [ISO-639](http://www.loc.gov/standards/iso639-2/) et `CC` est un code à deux lettres pour le pays conforme à la norme [ISO-3166](http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html). -Pour plus de détails sur les locales, reportez-vous à la [documentation du projet ICU](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept). +Pour assurer la cohérence, tous les identifiants utilisés par les application Yii doivent être présentés sous leur forme canonique `ll-CC`, où `ll` est un code à 2 ou 3 lettres pour la langue conforme à la norme [ISO-639](https://www.loc.gov/standards/iso639-2/) et `CC` est un code à deux lettres pour le pays conforme à la norme [ISO-3166](https://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html). +Pour plus de détails sur les locales, reportez-vous à la [documentation du projet ICU](https://unicode-org.github.io/icu/userguide/locale/#the-locale-concept). Dans Yii, nous utilisons souvent le mot « langue » pour faire référence à la locale. @@ -149,7 +149,7 @@ $price = 100; echo \Yii::t('app', 'Price: {0,number,currency}', $price); ``` -> Note: le formatage des valeurs de remplacement nécessite l'installation de [extension intl de PHP](https://secure.php.net/manual/en/intro.intl.php). +> Note: le formatage des valeurs de remplacement nécessite l'installation de [extension intl de PHP](https://www.php.net/manual/en/intro.intl.php). Vous pouvez utiliser, soit la forme raccourcie, soit la forme complète pour spécifier une valeur à remplacer avec un format : ``` @@ -163,7 +163,7 @@ forme complète : {name,type,style} echo Yii::t('app', "Example of string with ''-escaped characters'': '{' '}' '{test}' {count,plural,other{''count'' value is # '#{}'}}", ['count' => 3]); ``` -Le format complet est décrit dans la [documentation ICU](http://icu-project.org/apiref/icu4c/classMessageFormat.html). +Le format complet est décrit dans la [documentation ICU](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classMessageFormat.html). Dans ce qui suit, nous allons présenter quelques usages courants. @@ -192,7 +192,7 @@ $sum = 42; echo \Yii::t('app', 'Balance: {0,number,,000,000000}', $sum); ``` -Les caractères à utiliser dans les formats personnalisés sont présentés dans le document [ICU API reference](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html) à la section "Special Pattern Characters" (Caractères pour motifs spéciaux). +Les caractères à utiliser dans les formats personnalisés sont présentés dans le document [ICU API reference](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classDecimalFormat.html) à la section "Special Pattern Characters" (Caractères pour motifs spéciaux). La valeur de remplacement est toujours formatée en fonction de la locale cible c'est à dire que vous ne pouvez pas modifier les séparateurs de milliers et de décimales, les symboles monétaires, etc. sans modifier la locale de traduction. Si vous devez personnaliser ces éléments vous pouvez utiliser [[yii\i18n\Formatter::asDecimal()]] et [[yii\i18n\Formatter::asCurrency()]]. @@ -217,7 +217,7 @@ Vous pouvez aussi spécifier un motif personnalisé pour formater la date : echo \Yii::t('app', 'Today is {0,date,yyyy-MM-dd}', time()); ``` -Voir [Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +Voir [Formatting reference](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### Heure @@ -240,7 +240,7 @@ Vous pouvez aussi spécifier un motif personnalisé pour formater l'heure : echo \Yii::t('app', 'It is {0,date,HH:mm}', time()); ``` -Voir [Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +Voir [Formatting reference](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### Prononciation @@ -262,7 +262,7 @@ echo \Yii::t('app', 'I am {n,spellout,%spellout-ordinal} agent', ['n' => 47]); Notez qu'il ne doit pas y avoir d'espace après `spellout,` et avant `%`. Pour trouver une liste des options disponibles pour votre locale, reportez-vous à -"Numbering schemas, Spellout" à [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/). +"Numbering schemas, Spellout" à [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). #### Nombre ordinal @@ -283,7 +283,7 @@ echo \Yii::t('app', '{n,ordinal,%digits-ordinal-feminine}', ['n' => 471]); Notez qu'il ne doit pas y avoir d'espace après `ordinal,` et avant `%`. Pour trouver une liste des options disponibles pour votre locale, reportez-vous à -"Numbering schemas, Ordinal" à [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/). +"Numbering schemas, Ordinal" à [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). #### Durée @@ -304,7 +304,7 @@ echo \Yii::t('app', '{n,duration,%in-numerals}', ['n' => 471227]); Notez qu'il ne doit pas y avoir d'espace après `duration,` et avant `%`. Pour trouver une liste des options disponibles pour votre locale, reportez-vous à -"Numbering schemas, Duration" à [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/). +"Numbering schemas, Duration" à [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). #### Pluriel @@ -326,8 +326,8 @@ tandis que `one` correspond à `21` ou `101`: Здесь {n,plural,=0{котов нет} =1{есть один кот} one{# кот} few{# кота} many{# котов} other{# кота}}! ``` -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://cldr.unicode.org/index/cldr-spec/plural-rules). +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" à [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). +En alternative, vous pouvez vous reporter aux [rules reference at unicode.org](https://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. > @@ -350,7 +350,7 @@ echo Yii::t('app', 'You {likeCount,plural, // You and one other person liked this ``` -#### Sélection ordinale +#### Sélection ordinale L'argument `selectordinal` pour une valeur à remplacer numérique a pour but de choisir une chaîne de caractères basée sur les règles linguistiques de la locale cible pour les ordinaux. Ainsi,  @@ -374,8 +374,8 @@ echo Yii::t('app', 'You are the {n,selectordinal,one{#st} two{#nd} few{#rd} othe //Vous êtes le 3e visiteur ``` -Le format est assez proche de celui utilisé pour le pluriel. Pour connaître quels arguments utiliser pour une locale particulière, reportez-vous aux "Plural Rules, Ordinal" à [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). +Le format est assez proche de celui utilisé pour le pluriel. Pour connaître quels arguments utiliser pour une locale particulière, reportez-vous aux "Plural Rules, Ordinal" à [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). +En alternative, vous pouvez vous reporter aux [rules reference at unicode.org](https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html). #### Sélection @@ -637,9 +637,9 @@ Reportez-vous à la section [Formatage des données](output-formatting.md) pour ## Configuration de l'environnement PHP -Yii utilise l'[extension intl de PHP](https://secure.php.net/manual/en/book.intl.php) pour fournir la plupart de ses fonctionnalités d'internationalisation, telles que le formatage des dates et des nombres de la classe [[yii\i18n\Formatter]] et le formatage des messages de la classe [[yii\i18n\MessageFormatter]]. +Yii utilise l'[extension intl de PHP](https://www.php.net/manual/en/book.intl.php) pour fournir la plupart de ses fonctionnalités d'internationalisation, telles que le formatage des dates et des nombres de la classe [[yii\i18n\Formatter]] et le formatage des messages de la classe [[yii\i18n\MessageFormatter]]. Les deux classes fournissent un mécanisme de remplacement lorsque l'extension `intl` n'est pas installée. Néanmoins, l'implémentation du mécanisme de remplacement ne fonctionne bien que quand la langue cible est l'anglais. C'est pourquoi, il est fortement recommandé d'installer `intl` quand c'est nécessaire. -L'[extension intl de PHP](https://secure.php.net/manual/en/book.intl.php) est basée sur la [bibliothèque ICU](http://site.icu-project.org/) qui fournit la base de connaissances et les règles de formatage pour les différentes locales. Des versions différentes d'ICU peuvent conduire à des formatages différents des dates et des nombres. Pour être sûr que votre site Web donne les même résultats dans tous les environnements, il est recommandé d'installer la même version de l'extension `intl` (et par conséquent la même version d'ICU) dans tous les environnements. +L'[extension intl de PHP](https://www.php.net/manual/en/book.intl.php) est basée sur la [bibliothèque ICU](https://icu.unicode.org/) qui fournit la base de connaissances et les règles de formatage pour les différentes locales. Des versions différentes d'ICU peuvent conduire à des formatages différents des dates et des nombres. Pour être sûr que votre site Web donne les même résultats dans tous les environnements, il est recommandé d'installer la même version de l'extension `intl` (et par conséquent la même version d'ICU) dans tous les environnements. Pour savoir quelle version d'ICU est utilisée par PHP, vous pouvez exécuter le script suivant, qui vous restitue la version de PHP et d'ICU en cours d'utilisation. @@ -650,6 +650,6 @@ echo "ICU: " . INTL_ICU_VERSION . "\n"; echo "ICU Data: " . INTL_ICU_DATA_VERSION . "\n"; ``` -Il est également recommandé d'utiliser une version d'ICU supérieure ou égale à 48. Cela garantit que toutes les fonctionnalités décrites dans ce document sont utilisables. Par exemple, une version d'ICU inférieure à 49 ne prend pas en charge la valeur à remplacer `#` dans les règles de pluralisation. Reportez-vous à pour obtenir une liste complète des versions d'ICU disponibles. Notez que le numérotage des versions a changé après la version 4.8 (p. ex., ICU 4.8, ICU 49, ICU 50, etc.) +Il est également recommandé d'utiliser une version d'ICU supérieure ou égale à 48. Cela garantit que toutes les fonctionnalités décrites dans ce document sont utilisables. Par exemple, une version d'ICU inférieure à 49 ne prend pas en charge la valeur à remplacer `#` dans les règles de pluralisation. Reportez-vous à pour obtenir une liste complète des versions d'ICU disponibles. Notez que le numérotage des versions a changé après la version 4.8 (p. ex., ICU 4.8, ICU 49, ICU 50, etc.) -En outre, les informations dans la base de donnée des fuseaux horaires fournie par la bibliothèque ICU peuvent être surannées. Reportez-vous au [manuel d'ICU](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data) pour les détails sur la manière de mettre la base de données des fuseaux horaires à jour. Bien que la base de données des fuseaux horaires d'ICU soit utilisée pour le formatage, celle de PHP peut aussi être d'actualité. Vous pouvez la mettre à jour en installant la dernière version du [paquet `timezonedb` de pecl](https://pecl.php.net/package/timezonedb). +En outre, les informations dans la base de donnée des fuseaux horaires fournie par la bibliothèque ICU peuvent être surannées. Reportez-vous au [manuel d'ICU](https://unicode-org.github.io/icu/userguide/datetime/timezone/#updating-the-time-zone-data) pour les détails sur la manière de mettre la base de données des fuseaux horaires à jour. Bien que la base de données des fuseaux horaires d'ICU soit utilisée pour le formatage, celle de PHP peut aussi être d'actualité. Vous pouvez la mettre à jour en installant la dernière version du [paquet `timezonedb` de pecl](https://pecl.php.net/package/timezonedb). diff --git a/docs/guide-id/README.md b/docs/guide-id/README.md index 4fd9802ab87..999cc758660 100644 --- a/docs/guide-id/README.md +++ b/docs/guide-id/README.md @@ -1,7 +1,7 @@ Panduan Definitif Untuk Yii 2.0 =============================== -Tutorial ini dirilis di bawah [Persyaratan Dokumentasi Yii](http://www.yiiframework.com/doc/terms/). +Tutorial ini dirilis di bawah [Persyaratan Dokumentasi Yii](https://www.yiiframework.com/doc/terms/). Seluruh hak cipta dilindungi. @@ -179,14 +179,14 @@ Topik Khusus Widget ------- -* [GridView](http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) -* [ListView](http://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) -* [DetailView](http://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) -* [ActiveForm](http://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) -* [Pjax](http://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) -* [Menu](http://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) -* [LinkPager](http://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) -* [LinkSorter](http://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) +* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) +* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) +* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) +* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) +* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) +* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) +* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) +* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) * [Bootstrap Widgets](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide/README.md) * [JQuery UI Widgets](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md) diff --git a/docs/guide-id/intro-upgrade-from-v1.md b/docs/guide-id/intro-upgrade-from-v1.md index caca199e1d4..ea6c9a50106 100644 --- a/docs/guide-id/intro-upgrade-from-v1.md +++ b/docs/guide-id/intro-upgrade-from-v1.md @@ -1,5 +1,4 @@ -Upgrade dari Versi 1.1 -========================== +# Upgrade dari Versi 1.1 Ada banyak perbedaan antara versi 1.1 dan 2.0 karena Yii Framework benar-benar ditulis ulang di versi 2.0. Akibatnya, upgrade dari versi 1.1 tidak mudah seperti upgrade untuk versi minor. Dalam panduan ini Anda akan @@ -8,65 +7,53 @@ menemukan perbedaan utama antara dua versi. Jika Anda belum pernah menggunakan Yii 1.1 sebelumnya, Anda dapat dengan aman melewati bagian ini dan menuju ke "[Persiapan](start-installation.md)". Harap dicatat bahwa Yii 2.0 memperkenalkan lebih banyak fitur baru dari yang tercakup dalam ringkasan ini. Sangat dianjurkan -Anda membaca keseluruhan panduan definitif untuk mempelajari hal tersebut. Kemungkinannya adalah bahwa -beberapa fitur yang sebelumnya harus anda kembangkan sendiri kini menjadi bagian dari kode inti. +Anda membaca keseluruhan panduan definitif untuk mempelajari hal tersebut. Ada kemungkinan bahwa +beberapa fitur yang sebelumnya harus anda kembangkan sendiri, kini telah menjadi bagian dari kode inti. +## Instalasi -Instalasi ------------- +Yii 2.0 sepenuhnya menggunakan [composer](https://getcomposer.org/), yaitu dependency manager yang sudah diakui oleh PHP. -Yii 2.0 sepenuhnya menggunakan [composer](https://getcomposer.org/), yaitu dependency manager yang sudah diakui oleh PHP. Instalasi -dari kerangka inti serta ekstensi, ditangani melalui Composer. Silakan merujuk ke -bagian [Instalasi Yii](start-installation.md) untuk belajar cara menginstal Yii 2.0. Jika Anda menghendaki -membuat ekstensi baru, atau mengubah ekstensi 1.1 yang sudah ke ekstensi 2.0 yang kompatibel, silakan -merujuk panduan [Membuat Ekstensi](structure-extensions.md#menciptakan-ekstensi). +- Instalasi dari kerangka inti serta ekstensi, ditangani melalui Composer. +- Silakan merujuk ke bagian [Instalasi Yii](start-installation.md) untuk belajar cara menginstal Yii 2.0. +- Jika ingin membuat ekstensi baru, atau mengubah/memperbarui ekstensi 1.1 yang telah Anda buat ke ekstensi 2.0 (agar kompatibel), silakan merujuk pada panduan [Membuat Ekstensi](structure-extensions.md#menciptakan-ekstensi). +## Persyaratan PHP -Persyaratan PHP ----------------- +Yii 2.0 membutuhkan PHP 5.4 atau versi yang lebih tinggi, ini karena ada perubahan besar atas PHP versi 5.2 yang sebelumnya dibutuhkan oleh Yii 1.1. Akibatnya, ada banyak perbedaan pada tingkat bahasa yang harus Anda perhatikan. +Dibawah ini ringkasan perubahan utama mengenai PHP tersebut: -Yii 2.0 membutuhkan PHP 5.4 atau versi lebih tinggi, yang merupakan perbaikan besar atas PHP versi 5.2 yang dibutuhkan oleh Yii 1.1. -Akibatnya, ada banyak perbedaan pada tingkat bahasa yang harus Anda perhatikan. -Di bawah ini adalah ringkasan perubahan utama mengenai PHP: +- [Namespaces](https://www.php.net/manual/en/language.namespaces.php). +- [Anonymous fungsi](https://www.php.net/manual/en/functions.anonymous.php). +- Sintaks array pendek `[... elemen ...]` digunakan sebagai pengganti `array (... elemen ...)`. +- Tags echo pendek `<=` digunakan dalam tampilan file. Ini aman digunakan mulai dari PHP 5.4. +- [Class SPL dan interface](https://www.php.net/manual/en/book.spl.php). +- [Late Static Bindings](https://www.php.net/manual/en/language.oop5.late-static-bindings.php). +- [Tanggal dan Waktu](https://www.php.net/manual/en/book.datetime.php). +- [Traits](https://www.php.net/manual/en/language.oop5.traits.php). +- [Intl](https://www.php.net/manual/en/book.intl.php). Yii 2.0 menggunakan `ekstensi PHP intl` +   untuk mendukung fitur internasionalisasi. -- [Namespaces](https://secure.php.net/manual/en/language.namespaces.php). -- [Anonymous fungsi](https://secure.php.net/manual/en/functions.anonymous.php). -- Sintaks array pendek `[... elemen ...]` digunakan sebagai pengganti `array (... elemen ...)`. -- Tags echo pendek `<=` digunakan dalam tampilan file. Ini aman digunakan mulai dari PHP 5.4. -- [Class SPL dan interface](https://secure.php.net/manual/en/book.spl.php). -- [Late Static Bindings](https://secure.php.net/manual/en/language.oop5.late-static-bindings.php). -- [Tanggal dan Waktu](https://secure.php.net/manual/en/book.datetime.php). -- [Traits](https://secure.php.net/manual/en/language.oop5.traits.php). -- [Intl](https://secure.php.net/manual/en/book.intl.php). Yii 2.0 menggunakan `ekstensi PHP intl` -  untuk mendukung fitur internasionalisasi. +## Namespace - -Namespace ---------- - -Perubahan yang paling jelas dalam Yii 2.0 adalah penggunaan namespace. Hampir setiap kelas inti -menggunakan namespace, misalnya, `yii\web\Request`. Awalan "C" tidak lagi digunakan dalam nama kelas. -Skema penamaan sekarang mengikuti struktur direktori. Misalnya, `yii\web\Request` -menunjukkan bahwa file kelas yang sesuai adalah `web/Request.php` bawah folder framework Yii. +Perubahan yang paling terlihat jelas dalam Yii 2.0 adalah penggunaan namespace. Hampir setiap kelas inti +menggunakan namespace, misalnya, `yii\web\Request`. Awalan yang sebelumnya menggunakan huruf "C" tidak lagi +digunakan dalam nama kelas. Skema penamaan sekarang mengikuti struktur direktori. Misalnya, `yii\web\Request` +mengindikasikan bahwa file kelasnya adalah `web/Request.php` sesuai dengan lokasi folder framework Yii yang ada. (Anda dapat menggunakan setiap kelas inti tanpa menyertakannya secara eksplisit berkat Yiiclass loader.) - -Komponen dan Object --------------------- +## Komponen dan Object Yii 2.0 membagi kelas `CComponent` di 1.1 menjadi dua kelas: [[yii\base\BaseObject]] dan [[yii\base\Component]]. Class [[yii\base\BaseObject|BaseObject]] adalah class dasar ringan yang memungkinkan mendefinisikan [objek properti](concept-properties.md) -melalui getter dan setter. Class [[yii\base\Component|Component]] adalah perluasan dari [[yii\base\BaseObject|BaseObject]] dengan dukungan -[Event](concept-events.md) dan [behavior](concept-behaviors.md). +melalui getter dan setter. Class [[yii\base\Component|Component]] adalah perluasan(extends) dari [[yii\base\BaseObject|BaseObject]] dengan dukungan [Event](concept-events.md) dan [Behavior](concept-behaviors.md). -Jika class Anda tidak perlu fitur event atau behavior, Anda harus mempertimbangkan menggunakan +Jika class Anda tidak memerlukan fitur event atau behavior, Anda harus mempertimbangkan menggunakan [[yii\base\BaseObject|BaseObject]] sebagai class dasar. Hal ini biasanya terjadi untuk class yang mewakili struktur data dasar. - -Konfigurasi objek --------------------- +## Konfigurasi objek Class [[yii\base\BaseObject|BaseObject]] memperkenalkan cara seragam untuk mengkonfigurasi objek. Setiap class turunan dari [[yii\base\BaseObject|BaseObject]] harus menyatakan konstruktor (jika diperlukan) dengan cara berikut agar @@ -91,12 +78,12 @@ class MyClass extends \yii\base\BaseObject } ``` -Dalam contoh di atas, parameter terakhir dari konstruktor harus mengambil array konfigurasi -yang berisi pasangan nama-nilai untuk menginisialisasi properti pada akhir konstruktor. -Anda dapat menimpa method [[yii\base\BaseObject::init()|init()]] untuk melakukan pekerjaan inisialisasi yang harus dilakukan setelah -konfigurasi telah diterapkan. +Dalam contoh diatas, parameter terakhir dari konstruktor harus mengambil array konfigurasi (`$config`) +yang berisi pasangan nama-nilai `[key => value]` untuk meng-inisialisasi properti pada akhir konstruktor. +Anda dapat mengganti method [[yii\base\BaseObject::init()|init()]] untuk melakukan inisialisasi yang harus dilakukan setelah +konfigurasi diterapkan. -Dengan mengikuti konvensi ini, Anda akan dapat membuat dan mengkonfigurasi objek baru menggunakan array konfigurasi: +Dengan mengikuti ketentuan ini, Anda akan dapat membuat dan mengkonfigurasi objek baru menggunakan array konfigurasi: ```php $object = Yii::createObject([ @@ -106,33 +93,29 @@ $object = Yii::createObject([ ], [$param1, $param2]); ``` -Rincian lebih lanjut tentang konfigurasi dapat ditemukan di bagian [Konfigurasi](concept-configurations.md). - +Rincian lebih lanjut mengenai konfigurasi dapat ditemukan pada bagian [Konfigurasi](concept-configurations.md). -Event ------- +## Event Di Yii 1, event dibuat dengan mendefinisikan method `on` (misalnya,`onBeforeSave`). Di Yii 2, Anda sekarang dapat menggunakan semua nama sebagai event. -Anda memicu suatu event dengan memanggil method [[yii\base\Component::trigger()|trigger()]]: +Untuk memicu suatu event, Anda dapat melakukannya dengan memanggil method [[yii\base\Component::trigger()|trigger()]]: ```php $event = new \yii\base\Event; $component->trigger($eventName, $event); ``` -Untuk melampirkan penanganan event, mengunakan method [[yii\base\Component::on()|on()]]: +Untuk melekatkan/memasang handler pada suatu event, dapat dilakukan dengan mengunakan method [[yii\base\Component::on()|on()]]: ```php $component->on($eventName, $handler); -// To detach the handler, use: +// Untuk mematikannya dapat dilakukan dengan cara: // $component->off($eventName, $handler); ``` -Ada banyak pengembangan dari fitur event. Untuk lebih jelasnya, silakan lihat bagian [Event](concept-events.md). - +Ada banyak pengembangan dari fitur event. Untuk lebih jelasnya, silakan lihat pada bagian [Event](concept-events.md). -Path Alias ------------- +## Path Alias Yii 2.0 memperluas penggunaan alias path baik untuk file/direktori maupun URL. Yii 2.0 juga sekarang mensyaratkan nama alias dimulai dengan karakter `@`. @@ -146,34 +129,29 @@ Misalnya, karena `@yii` mengacu pada direktori instalasi Yii, class seperti `yii Jika Anda menggunakan librari pihak ketiga seperti Zend Framework. Anda dapat menentukan alias path `@Zend` yang mengacu pada direktori instalasi framework direktori. Setelah Anda selesai melakukannya, Yii akan dapat menload setiap class dalam librari Zend Framework. -Lebih jauh tentang alias path dapat ditemukan di bagian [Alias](concept-aliases.md). +Lebih jauh tentang alias path dapat pelajari pada bagian [Alias](concept-aliases.md). - -View ------ +## View Perubahan yang paling signifikan tentang view di Yii 2 adalah bahwa variabel khusus `$this` dalam sebuah view tidak lagi mengacu -controller saat ini atau widget. Sebaliknya, `$this` sekarang mengacu pada objek *view*, konsep baru -yang diperkenalkan di 2.0. Objek *view* adalah [[yii\web\View]], yang merupakan bagian view +controller saat ini atau widget. Sebaliknya, `$this` sekarang mengacu pada objek _view_, konsep baru +yang diperkenalkan di 2.0. Objek _view_ adalah [[yii\web\View]], yang merupakan bagian view dari pola MVC. Jika Anda ingin mengakses controller atau widget di tampilan, Anda dapat menggunakan `$this->context`. Untuk membuat tampilan parsial dalam view lain, Anda menggunakan `$this->render()`, tidak lagi `$this->renderPartial()`. -Panggilan untuk `render` juga sekarang harus secara eksplisit *di-echo)*, mengingat method `render()` sekarang mengembalikan nilai -yang dirender, bukan langsung menampilkannya. Sebagai contoh: +Panggilan untuk `render` juga sekarang harus secara eksplisit _di-echo)-kan_, mengingat method `render()` sekarang mengembalikan nilai yang dirender, bukan langsung menampilkannya. Sebagai contoh: ```php echo $this->render('_item', ['item' => $item]); ``` -Selain menggunakan PHP sebagai bahasa template utama, Yii 2.0 juga dilengkapi dengan dukungan resmi -dua mesin template populer: Smarty dan Twig. Mesin template Prado tidak lagi didukung. +Selain menggunakan PHP sebagai bahasa template utama, Yii 2.0 juga dilengkapi dengan dukungan resmi +dua _template engine_ populer: Smarty dan Twig. _Template engine_ Prado tidak lagi didukung. Untuk menggunakan mesin template ini, Anda perlu mengkonfigurasi komponen aplikasi `view` dengan menetapkan properti [[yii\base\View::$renderers|View::$renderers]]. Silakan merujuk ke bagian [Template Engine](tutorial-template-engines.md) untuk lebih jelasnya. - -Model ------- +## Model Yii 2.0 menggunakan [[yii\base\Model]] sebagai model dasar, mirip dengan `CModel` di 1.1. class `CFormModel` telah dibuang seluruhnya. Sebaliknya, di Yii 2 Anda harus memperluas [[yii\base\Model]] untuk membuat class model formulir. @@ -205,9 +183,7 @@ atribut `unsafe`. Untuk mempelajari lebih lanjut tentang model, silakan merujuk ke bagian [Model](structure-models.md). - -Controller ------------ +## Controller Yii 2.0 menggunakan [[yii\web\Controller]] sebagai kelas dasar controller, yang mirip dengan `CController` di Yii 1.1. [[Yii\base\Action]] adalah kelas dasar untuk kelas action. @@ -229,13 +205,11 @@ public function actionView($id) Silakan merujuk ke bagian [Controller](structure-controllers.md) untuk rincian lebih lanjut tentang controller. - -widget -------- +## widget Yii 2.0 menggunakan [[yii\base\Widget]] sebagai kelas dasar widget, mirip dengan `CWidget` di Yii 1.1. -Untuk mendapatkan dukungan yang lebih baik untuk kerangka di IDE, Yii 2.0 memperkenalkan sintaks baru untuk menggunakan widget. +Untuk mendapatkan dukungan yang lebih baik untuk kerangka di IDE, Yii 2.0 memperkenalkan sintaks baru untuk menggunakan widget. Metode statis [[yii\base\Widget::begin()|begin()]], [[yii\base\Widget::end()|end()]], dan [[yii\base\Widget::widget()|widget()]] mulai diperkenalkan, yang akan digunakan seperti: @@ -243,7 +217,7 @@ mulai diperkenalkan, yang akan digunakan seperti: use yii\widgets\Menu; use yii\widgets\ActiveForm; -// Note that you have to "echo" the result to display it +// Perlu diingat bahwa "echo" tetap diperlukan untuk menampilkan hasilnya echo Menu::widget(['items' => $items]); // Passing an array to initialize the object properties @@ -257,24 +231,20 @@ ActiveForm::end(); Silakan merujuk ke bagian [Widget](structure-widgets.md) untuk lebih jelasnya. +## Tema -Tema ------- - -Tema bekerja benar-benar berbeda di 2.0. Mereka sekarang berdasarkan mekanisme pemetaan path yang memetakan +Tema benar-benar bekerja secara berbeda di 2.0. Kini tema telah berdasarkan mekanisme pemetaan path yang memetakan file sumber ke file tema. Misalnya, jika peta path untuk tema adalah `['/web/views' => '/web/themes/basic']`, maka versi tema dari file view `/web/views/site/index.php` akan menjadi `/web/themes/basic/site/index.php`. Untuk alasan ini, tema sekarang bisa -diterapkan untuk setiap file view, bahkan view diberikan di luar controller atau widget. +diterapkan untuk setiap file view, bahkan view diberikan di luar controller ataupun widget. Juga, tidak ada lagi komponen `CThemeManager`. Sebaliknya, `theme` adalah properti dikonfigurasi dari komponen `view` -aplikasi. +pada aplikasi. Silakan merujuk ke bagian [Theming](output-theming.md) untuk lebih jelasnya. - -Aplikasi konsol --------------------- +## Aplikasi konsol (CLI) Aplikasi konsol sekarang diatur sebagai controller seperti pada aplikasi Web. kontroler konsol harus diperluas dari [[yii\console\Controller]], mirip dengan `CConsoleCommand` di 1.1. @@ -288,9 +258,7 @@ Yii 2.0 mendukung pembuatan informasi bantuan command secara otomatis berdasarka Silakan lihat bagian [Console Commands](tutorial-console.md) untuk lebih jelasnya. - -I18N ----- +## I18N Yii 2,0 menghilangkan formater tanggal dan angka terpasang bagian dari [PECL modul intl PHP](https://pecl.php.net/package/intl). @@ -300,9 +268,7 @@ sumber berdasarkan kategori pesan. Silakan merujuk ke bagian [Internasionalisasi](tutorial-i18n.md) untuk rincian lebih lanjut. - -Action Filter --------------- +## Action Filter Action Filter sekarang diimplementasikan melalui behavior. Untuk membuat baru, filter diperluas dari [[yii\base\ActionFilter]]. Untuk menggunakan filter, pasang Kelas filter untuk controller sebagai behavior. Misalnya, untuk menggunakan filter [[yii\filters\AccessControl]], @@ -324,11 +290,9 @@ public function behaviors() Silakan merujuk ke bagian [Filtering](structure-filters.md) untuk lebih jelasnya. +## Aset -Aset ------- - -Yii 2.0 memperkenalkan konsep baru yang disebut *bundel aset* yang menggantikan konsep paket script di Yii 1.1. +Yii 2.0 memperkenalkan konsep baru yang disebut _bundel aset_ yang menggantikan konsep paket script di Yii 1.1. Bundel aset adalah kumpulan file asset (misalnya file JavaScript, file CSS, file gambar, dll) dalam direktori. Setiap bundel aset direpresentasikan sebagai kelas turunan dari [[yii\web\AssetBundle]]. @@ -338,24 +302,21 @@ berisi referensi ke JavaScript dan file CSS yang ditentukan dalam bundel itu. Silakan merujuk ke bagian [Managing Aset](structure-assets.md) untuk lebih jelasnya. - -Helper -------- +## Helper Yii 2.0 memperkenalkan banyak helper umum untuk digunakan, termasuk. -* [[yii\helpers\Html]] -* [[yii\helpers\ArrayHelper]] -* [[yii\helpers\StringHelper]] -* [[yii\helpers\FileHelper]] -* [[yii\helpers\Json]] +- [[yii\helpers\Html]] +- [[yii\helpers\ArrayHelper]] +- [[yii\helpers\StringHelper]] +- [[yii\helpers\FileHelper]] +- [[yii\helpers\Json]] Silakan lihat bagian [Tinjauan Helper](helper-overview.md) untuk lebih jelasnya. -Formulir --------- +## Formulir -Yii 2.0 memperkenalkan konsep *field* untuk membangun formulir menggunakan [[yii\widgets\ActiveForm]]. Field +Yii 2.0 memperkenalkan konsep _field_ untuk membangun formulir menggunakan [[yii\widgets\ActiveForm]]. Field adalah wadah yang terdiri dari label, masukan, pesan kesalahan, dan atau teks petunjuk. Field diwakili sebagai objek [[yii\widgets\ActiveField|ActiveField]]. Menggunakan field, Anda dapat membangun formulir yang lebih bersih dari sebelumnya: @@ -372,9 +333,7 @@ Menggunakan field, Anda dapat membangun formulir yang lebih bersih dari sebelumn Silakan merujuk ke bagian [Membuat Formulir](input-forms.md) untuk lebih jelasnya. - -Query Builder -------------- +## Query Builder Dalam 1.1, query builder itu tersebar di antara beberapa kelas, termasuk `CDbCommand`, `CDbCriteria`, dan` CDbCommandBuilder`. Yii 2.0 merepresentasikan sebuah query DB sebagai objek [[yii\db\Query|Query]] @@ -396,9 +355,7 @@ Yang terbaik dari semua itu adalah, query builder juga dapat digunakan ketika be Silakan lihat bagian [Query Builder](db-query-builder.md) untuk lebih jelasnya. - -Active Record -------------- +## Active Record Yii 2.0 memperkenalkan banyak perubahan [Active Record](db-active-record.md). Dua yang paling jelas melibatkan query builder dan penanganan permintaan relasional. @@ -465,9 +422,7 @@ versi 2.0. Perhatikan bahwa ketika menambahkan parameter ke constructor Anda mun Ada banyak perubahan lain dan perangkat tambahan untuk Rekaman Aktif. Silakan merujuk ke bagian [Rekaman Aktif](db-active-record.md) untuk rincian lebih lanjut. - -Active Record Behaviors ------------------------ +## Active Record Behaviors Dalam 2.0, kami telah membuang kelas behavior dasar `CActiveRecordBehavior`. Jika Anda ingin membuat behavior Active Record, Anda akan harus memperluasnya langsung dari `yii\base\Behavior`. Jika kelas behavior perlu menanggapi beberapa event @@ -497,20 +452,16 @@ class MyBehavior extends Behavior } ``` - -Pengguna dan IdentityInterface --------------------------- +## Pengguna dan IdentityInterface Kelas `CWebUser` di 1.1 kini digantikan oleh [[yii\web\User]], dan sekarang tidak ada lagi Kelas `CUserIdentity`. Sebaliknya, Anda harus menerapkan [[yii\web\IdentityInterface]] yang jauh lebih mudah untuk digunakan. Template proyek lanjutan memberikan contoh seperti itu. -Silakan merujuk ke bagian [Otentikasi](security-authentication.md), [Otorisasi](security-authorization.md), -dan [Template Proyek Lanjutan](https://github.com/yiisoft/yii2-app-advanced/blob /master/docs/guide/README.md) untuk lebih jelasnya. +Silakan merujuk ke bagian [Otentikasi](security-authentication.md), [Otorisasi](security-authorization.md), +dan [Template Proyek Lanjutan](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md) untuk lebih jelasnya. - -Manajemen URL --------------- +## Manajemen URL Manajemen URL di Yii 2 mirip dengan yang di 1.1. Tambahan utamanya adalah, sekarang manajemen URL mendukung opsional parameter. Misalnya, jika Anda memiliki aturan dinyatakan sebagai berikut, maka akan cocok @@ -527,14 +478,12 @@ tujuan yang sama. Silakan merujuk ke bagian [docs manajer Url](runtime-routing.md) untuk lebih jelasnya. -Perubahan penting dalam konvensi penamaan untuk rute adalah bahwa nama-nama camelcase dari controller +Perubahan penting dalam konvensi penamaan untuk rute adalah bahwa nama-nama camelcase dari controller dan action sekarang dikonversi menjadi huruf kecil di mana setiap kata dipisahkan oleh hypen, misal controller id untuk `CamelCaseController` akan menjadi `camel-case`. Lihat bagian tentang [Kontroler ID](structure-controllers.md#controller-ids) dan [Action ID](structure-controllers.md#action-ids) untuk lebih jelasnya. +## Menggunakan Yii 1.1 dan 2.x bersama-sama -Menggunakan Yii 1.1 dan 2.x bersama-sama ------------------------------- - -Jika Anda memiliki warisan kode Yii 1.1 yang ingin Anda gunakan bersama-sama dengan Yii 2.0, silakan lihat +Jika Anda memiliki warisan kode Yii 1.1 yang ingin Anda gunakan bersama-sama dengan Yii 2.0, silakan lihat bagian [Menggunakan Yii 1.1 dan 2.0 Bersama](tutorial-yii-integration.md). diff --git a/docs/guide-id/intro-yii.md b/docs/guide-id/intro-yii.md index c6aea377854..2b1ae4c91cc 100644 --- a/docs/guide-id/intro-yii.md +++ b/docs/guide-id/intro-yii.md @@ -1,52 +1,46 @@ -Apa Itu Yii -=========== +# Apa Itu Yii -Yii adalah kerangka kerja PHP berkinerja tinggi, berbasis komponen yang digunakan untuk mengembangkan aplikasi web modern dengan cepat. -Nama Yii (diucapkan `Yee` atau `[ji:]`) yang berarti "sederhana dan berevolusi" dalam bahasa Cina. Hal ini dapat juga -dianggap sebagai singkatan **Yes It Is (Ya, Itu Dia)**! +Yii merupakan kerangka kerja berbasis komponen yang berkecepatan tinggi (high performance) yang digunakan untuk kasus +pengembangan yang cepat pada aplikasi Web Modern. Disebut Yii (diucapkan `Yee` atau `[ji:]`) yang berarti "sederhana dan +berevolusi" dalam bahasa Cina. Bisa juga dianggap sebagai (akronim) singkatan dari **Yes It Is (Ya, Itu Dia)**! +## Yii Paling Cocok Digunakan untuk Apa? -Yii Terbaik untuk Apa? ---------------------- +Yii adalah kerangka kerja pemrograman web yg umum(general), ini berarti kita bisa menggunakannya untuk membangun berbagai +macam aplikasi berbasis web menggunakan PHP. Karena merupakan arsitektur berbasis komponen yang mana memiliki dukungan +caching yang canggih, Yii sangat cocok untuk pengembangan aplikasi skala besar seperti web portal, forum, CMS, e-commerce, +REST API dan lain sebagainnya. -Yii adalah kerangka kerja pemrograman web umum, yang berarti bahwa hal itu dapat digunakan untuk mengembangkan semua jenis -aplikasi Web yang menggunakan PHP. Karena arsitektur berbasis komponen dan dukungan caching yang canggih, Yii sangat cocok untuk mengembangkan aplikasi skala besar seperti portal, forum, sistem manajemen konten (CMS), proyek e-commerce, layanan web REST, dan sebagainya. +## Bagaimana jika Yii Dibandingkan dengan Frameworks lain? +Jika Anda sudah familiar dengan framework lain, Anda mungkin akan bersyukur ketika membandingkan Yii dengan yang lain: -Bagaimana jika Yii Dibandingkan dengan Frameworks lain? -------------------------------------------- +- Seperti kebanyakan PHP framework, Yii mengimplementasikan pola arsitektur MVC (Model-View-Controller) dan mempromosikan kode organisasi berdasarkan pola itu. +- Yii mengambil filosofi bahwa kode harus ditulis dengan cara sederhana namun elegan. Yii tidak akan pernah mencoba untuk mendesain berlebihan terutama untuk mengikuti beberapa pola desain secara ketat. +- Yii adalah fullstack framework yang menyediakan banyak fitur teruji dan siap pakai seperti: query builder dan ActiveRecord baik untuk relasional maupun NoSQL database; dukungan pengembangan REST API; dukungan caching berlapis dan masih banyak lagi. +- Yii sangat extensible. Anda dapat menyesuaikan atau mengganti hampir setiap bagian dari kode inti Yii. Anda juga bisa mengambil keuntungan dari arsitektur ekstensi Yii yang solid untuk menggunakan atau mengembangkan ekstensi untuk disebarkan kembali. +- Kinerja tinggi (High performance) selalu menjadi tujuan utama dari Yii. -Jika Anda sudah akrab dengan framework lain, Anda mungkin menghargai pengetahuan bagaimana Yii dibandingkan: +Yii tidak dikerjakan oleh satu orang, Yii didukung oleh [tim pengembang inti yang kuat][yii_team], serta komunitas besar +profesional yang terus memberikan kontribusi bagi pengembangan Yii. Tim pengembang Yii terus mengamati perkembangan tren +terbaru Web, pada penerapan terbaik (best practices) serta fitur yang ditemukan dalam framework dan proyek lain. +Penerapan terbaik yang paling relevan dan fitur yang ditemukan di tempat lain secara teratur dimasukkan ke dalam kerangka inti +dan menampilkannya melalui antarmuka yang sederhana dan elegan. -- Seperti kebanyakan PHP framework, Yii mengimplementasikan pola arsitektur MVC (Model-View-Controller) dan mempromosikan kode organisasi berdasarkan pola itu. -- Yii mengambil filosofi bahwa kode harus ditulis dengan cara sederhana namun elegan. Yii tidak akan pernah mencoba untuk mendesain berlebihan terutama untuk mengikuti beberapa pola desain secara ketat. -- Yii adalah framework penuh yang menyediakan banyak fitur teruji dan siap pakai seperti: query builder dan ActiveRecord baik untuk relasional maupun NoSQL database; dukungan pengembangan API REST; dukungan caching banyak lapis dan masih banyak lagi. -- Yii sangat extensible. Anda dapat menyesuaikan atau mengganti hampir setiap bagian dari kode inti Yii. Anda juga bisa mengambil keuntungan dari arsitektur ekstensi Yii yang solid untuk menggunakan atau mengembangkan ekstensi untuk disebarkan kembali. -- Kinerja tinggi selalu menjadi tujuan utama dari Yii. +[yii_team]: https://www.yiiframework.com/team -Yii tidak dikerjakan oleh satu orang, Yii didukung oleh [tim pengembang inti yang kuat][about_yii], serta komunitas besar -profesional yang terus memberikan kontribusi bagi pengembangan Yii. Tim pengembang Yii -terus mengamati perkembangan tren terbaru Web, pada penerapan terbaik serta fitur yang -ditemukan dalam framework dan proyek lain. Penerapan terbaik yang paling relevan dan fitur yang ditemukan di tempat lain secara teratur -dimasukkan ke dalam kerangka inti dan menampakkannya melalui antarmuka yang sederhana dan elegan. - -[about_yii]: http://www.yiiframework.com/about/ - -Versi Yii ----------- +## Versi Yii Yii saat ini memiliki dua versi utama yang tersedia: 1.1 dan 2.0. Versi 1.1 adalah generasi lama dan sekarang dalam mode pemeliharaan. Versi 2.0 adalah penulisan ulang lengkap dari Yii, mengadopsi teknologi dan protokol terbaru, termasuk composer, PSR, namespace, trait, dan sebagainya. Versi 2.0 merupakan generasi framework yang sekarang dan terus menerima upaya pengembangan selama beberapa tahun ke depan. Panduan ini terutama tentang versi 2.0. - -Persyaratan dan Prasyarat --------------------------- +## Persyaratan dan Prasyarat Yii 2.0 memerlukan PHP 5.4.0 atau versi lebih tinggi. Anda dapat menemukan persyaratan yang lebih rinci untuk setiap fitur dengan menjalankan pengecek persyaratan yang diikutsertakan dalam setiap rilis Yii. Menggunakan Yii memerlukan pengetahuan dasar tentang pemrograman berorientasi objek (OOP), mengingat Yii adalah framework berbasis OOP murni. -Yii 2.0 juga memanfaatkan fitur terbaru dari PHP, seperti [namespace](https://secure.php.net/manual/en/language.namespaces.php) dan [traits](https://secure.php.net/manual/en/language.oop5.traits.php). +Yii 2.0 juga memanfaatkan fitur terbaru dari PHP, seperti [namespace](https://www.php.net/manual/en/language.namespaces.php) dan [traits](https://www.php.net/manual/en/language.oop5.traits.php). Memahami konsep-konsep ini akan membantu Anda lebih mudah memahami Yii 2.0. diff --git a/docs/guide-id/start-databases.md b/docs/guide-id/start-databases.md index dd77957be0f..e81ec91690d 100644 --- a/docs/guide-id/start-databases.md +++ b/docs/guide-id/start-databases.md @@ -49,7 +49,7 @@ Hingga saat ini, anda memiliki database bernama `yii2basic`, dan didalamnya terd Konfigurasi Koneksi Database --------------------------- -Sebelum melanjutkan, pastikan anda memasang ekstensi PHP [PDO](https://secure.php.net/manual/en/book.pdo.php) dan +Sebelum melanjutkan, pastikan anda memasang ekstensi PHP [PDO](https://www.php.net/manual/en/book.pdo.php) dan driver PDO untuk database yang anda gunakan (misal, `pdo_mysql` untuk MySQL). Ini adalah kebutuhan mendasar jika aplikasi anda menggunakan _relational database_. diff --git a/docs/guide-id/start-forms.md b/docs/guide-id/start-forms.md index 6cae6875d3c..7d3497f0c31 100644 --- a/docs/guide-id/start-forms.md +++ b/docs/guide-id/start-forms.md @@ -129,7 +129,7 @@ dimana form HTML akan ditampilkan, beserta informasi kegagalan pengiriman form t > Note: Pada contoh sederhana ini kita hanya me-_render_ halaman konfirmasi jika data yang dikirim tersebut valid. Pada prakteknya, anda harus pertimbangkan untuk menggunakan [[yii\web\Controller::refresh()|refresh()]] atau [[yii\web\Controller::redirect()|redirect()]] - untuk mencegah [permasalahan pengiriman form](http://en.wikipedia.org/wiki/Post/Redirect/Get). + untuk mencegah [permasalahan pengiriman form](https://en.wikipedia.org/wiki/Post/Redirect/Get). Membuat View diff --git a/docs/guide-id/start-hello.md b/docs/guide-id/start-hello.md index f20a0439eb4..12d227b50e7 100644 --- a/docs/guide-id/start-hello.md +++ b/docs/guide-id/start-hello.md @@ -88,7 +88,7 @@ disebut dalam tindakan, itu akan mencari file PHP bernama `views/ControllerID/Vi Perhatikan bahwa dalam kode di atas, parameter `message` adalah di-[[yii\helpers\Html::encode()|HTML-encoded]] sebelum dicetak. Hal ini diperlukan karena sebagai parameter yang berasal dari pengguna akhir, sangat rentan terhadap -[serangan Cross-site scripting (XSS)](http://en.wikipedia.org/wiki/Cross-site_scripting) dengan melekatkan +[serangan Cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) dengan melekatkan kode JavaScript berbahaya dalam parameter. Tentu, Anda dapat menempatkan lebih banyak konten di view `say`. konten dapat terdiri dari tag HTML, teks biasa, dan bahkan pernyataan PHP. diff --git a/docs/guide-id/start-installation.md b/docs/guide-id/start-installation.md index 802f5222384..88b1b61bb2a 100644 --- a/docs/guide-id/start-installation.md +++ b/docs/guide-id/start-installation.md @@ -44,7 +44,7 @@ composer global require "fxp/composer-asset-plugin:^1.4.1" composer create-project --prefer-dist yiisoft/yii2-app-basic basic ``` -Perintah pertama menginstal [komposer aset Plugin](https://github.com/francoispluchino/composer-asset-plugin/) +Perintah pertama menginstal [komposer aset Plugin](https://github.com/fxpio/composer-asset-plugin) yang memungkinkan mengelola bower dan paket npm melalui Composer. Anda hanya perlu menjalankan perintah ini sekali untuk semua. Perintah kedua menginstal Yii dalam sebuah direktori bernama `basic`. Anda dapat memilih nama direktori yang berbeda jika Anda ingin. @@ -67,7 +67,7 @@ Instalasi dari file Arsip Instalasi Yii dari file arsip melibatkan tiga langkah: -1. Download file arsip dari [yiiframework.com](http://www.yiiframework.com/download/). +1. Download file arsip dari [yiiframework.com](https://www.yiiframework.com/download/). 2. Uraikan file yang didownload ke folder yang bisa diakses web. 3. Memodifikasi `config/web.php` dengan memasukkan kunci rahasia untuk `cookieValidationKey`.    (Ini dilakukan secara otomatis jika Anda menginstal Yii menggunakan Composer): @@ -97,7 +97,7 @@ Memverifikasi Instalasi -------------------------- Setelah instalasi selesai, baik mengkonfigurasi web server Anda (lihat bagian berikutnya) atau menggunakan -[Built-in web server PHP] (https://secure.php.net/manual/en/features.commandline.webserver.php) dengan menjalankan berikut +[Built-in web server PHP] (https://www.php.net/manual/en/features.commandline.webserver.php) dengan menjalankan berikut konsol perintah sementara dalam proyek `web` direktori: ```bash @@ -131,7 +131,7 @@ persyaratan Yii. Anda dapat memeriksa apakah persyaratan minimumnya cocok dengan   ``` Anda harus mengkonfigurasi instalasi PHP Anda sehingga memenuhi persyaratan minimal Yii. Yang paling penting, Anda -harus memiliki PHP versi 5.4 atau lebih. Anda juga harus menginstal [PDO PHP Ekstensi](https://secure.php.net/manual/en/pdo.installation.php) +harus memiliki PHP versi 5.4 atau lebih. Anda juga harus menginstal [PDO PHP Ekstensi](https://www.php.net/manual/en/pdo.installation.php) dan driver database yang sesuai (seperti `pdo_mysql` untuk database MySQL), jika aplikasi Anda membutuhkan database. @@ -142,9 +142,9 @@ Konfigurasi Web Server   penggelaran itu untuk server produksi. Aplikasi yang diinstal sesuai dengan petunjuk di atas seharusnya bekerja dengan baik -pada [Apache HTTP server](http://httpd.apache.org/) atau [Nginx HTTP server](http://nginx.org/), pada +pada [Apache HTTP server](https://httpd.apache.org/) atau [Nginx HTTP server](https://nginx.org/), pada Windows, Mac OS X, atau Linux yang menjalankan PHP 5.4 atau lebih tinggi. Yii 2.0 juga kompatibel dengan facebook -[HHVM](http://hhvm.com/). Namun, ada beberapa kasus di mana HHVM berperilaku berbeda dari PHP asli, +[HHVM](https://hhvm.com/). Namun, ada beberapa kasus di mana HHVM berperilaku berbeda dari PHP asli, sehingga Anda harus mengambil beberapa perlakuan ekstra ketika menggunakan HHVM. Pada server produksi, Anda mungkin ingin mengkonfigurasi server Web Anda sehingga aplikasi dapat diakses @@ -187,7 +187,7 @@ DocumentRoot "path/to/basic/web" ### Konfigurasi Nginx yang Direkomendasikan -Untuk menggunakan [Nginx](http://wiki.nginx.org/), Anda harus menginstal PHP sebagai [FPM SAPI](https://secure.php.net/install.fpm). +Untuk menggunakan [Nginx](https://wiki.nginx.org/), Anda harus menginstal PHP sebagai [FPM SAPI](https://www.php.net/install.fpm). Anda dapat menggunakan konfigurasi Nginx berikut, menggantikan `path/to/basic/web` dengan path yang sebenarnya untuk `basic/web` dan `mysite.test` dengan hostname yang sebenarnya untuk server. diff --git a/docs/guide-id/start-looking-ahead.md b/docs/guide-id/start-looking-ahead.md index 854a0438715..9360b52f28b 100644 --- a/docs/guide-id/start-looking-ahead.md +++ b/docs/guide-id/start-looking-ahead.md @@ -9,27 +9,27 @@ kode secara otomatis. Menggunakan Gii dalam membuat kode, mengubah tugas-tugas p Bagian ini akan merangkum bacaan Yii yang tersedia untuk membantu anda menjadi lebih produktif dalam menggunakan framework ini. * Dokumentasi - - [Panduan Definitif](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [Panduan Definitif](https://www.yiiframework.com/doc-2.0/guide-README.html): Sesuai dengan judulnya, panduan ini merincikan bagaimana Yii seharusnya bekerja dan menyediakan petunjuk umum tentang menggunakan Yii. Panduan ini sangat-sangat penting, dan panduan ini yang harus anda baca sebelum menulis kode Yii. - - [Referensi Class](http://www.yiiframework.com/doc-2.0/index.html): + - [Referensi Class](https://www.yiiframework.com/doc-2.0/index.html): Ini menjelaskan bagaimana menggunakan semua class yang disediakan oleh Yii. Pada umumnya anda akan menggunakan ini ketika anda sedang menulis kode dan ingin memahami bagaimana penggunaan _class, method, property_. Sebaiknya anda membaca referensi class ini ketika anda memilik pemahaman dasar tentang seluruh bagian framework. - - [Artikel Wiki](http://www.yiiframework.com/wiki/?tag=yii2): + - [Artikel Wiki](https://www.yiiframework.com/wiki/?tag=yii2): Artikel wiki ditulis oleh para pengguna Yii berdasarkan pengalaman pribadi masing-masing. Kebanyakan dari artikel ini ditulis seperti layaknya panduan memasak, dan menunjukkan bagaimana menyelesaikan beberapa masalah dengan menggunakan Yii. Walaupun kualitas artikel-artikel ini mungkin tidak selengkap Panduan Definitif, tetapi artikel ini terkadang lebih bermanfaat karna membahas topik yang cukup luas dan mungkin mampu menyediakan solusi-solusi yang sederhana. - - [Buku](http://www.yiiframework.com/doc/) -* [Extensions](http://www.yiiframework.com/extensions/): + - [Buku](https://www.yiiframework.com/books) +* [Extensions](https://www.yiiframework.com/extensions/): Yang harus dibanggakan adalah Yii memiliki ribuan library extension yang dibuat oleh pengguna yang dapat dipasang di aplikasi anda dengan mudah, dan akan membuat pengembangan aplikasi anda lebih mudah dan cepat. * Komunitas - - Forum: - - IRC: Kanal #yii di freenode () + - Forum: + - IRC: Kanal #yii di Libera () - Gitter: - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide-id/start-prerequisites.md b/docs/guide-id/start-prerequisites.md new file mode 100644 index 00000000000..4dd5da292b0 --- /dev/null +++ b/docs/guide-id/start-prerequisites.md @@ -0,0 +1,18 @@ +# Apa yang perlu kamu ketahui + +Kurva pembelajaran Yii tidak setajam/sesulit kerangka kerja PHP lainnya, tapi masih ada beberapa hal yang harus kamu pelajari sebelum mulai menggunakan Yii + +## PHP + +Yii adalah kerangka kerja PHP jadi pastikan kamu telah [membaca dan memahami referensi dari bahasa ini](https://www.php.net/manual/en/langref.php). +Ketika membangun aplikasi menggunakan Yii, kamu akan menulis kode dengan gaya OOP (Bahasa Pemrograman Berbasis Objek), jadi pastikan juga kamu sudah cukup familiar dengan [Kelas and Objek](https://www.php.net/manual/en/language.oop5.basic.php) dan juga [namespaces](https://www.php.net/manual/en/language.namespaces.php). + +## Object oriented programming (Bahasa Pemrograman Berbasis Objek) + +Memahami dasar dari OOP sangat dibutuhkan. Jika kamu tidak cukup familiar dengan ini, silahkan pelajari salah satu dari banyak tutorial yang ada pada [tuts+ salah satunya](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762). + +Perlu dicatat juga bahwa semakin kompleks aplikasi yang Anda buat, akan semakin dalam juga konsep OOP yang harus dipelajari untuk dapat berhasil mengelola kompleksitas tersebut. + +## Command line and composer + +Yii secara umum menggunakan pengelolaan paket PHP standar, [Composer](https://getcomposer.org/) jadi pastikan bahwa kamu telah membaca dan memahami apa itu composer [panduan](https://getcomposer.org/doc/01-basic-usage.md). Jika kamu tidak cukup familiar menggunakan perintah baris (CLI), ini waktunya untuk coba mempelajari itu. Ketika Anda sudah mempelajari dasarnya, anda tidak akan mau lagi kerja tanpa menggunakan itu. diff --git a/docs/guide-id/start-workflow.md b/docs/guide-id/start-workflow.md index eaa19b566b6..666c378935a 100644 --- a/docs/guide-id/start-workflow.md +++ b/docs/guide-id/start-workflow.md @@ -43,7 +43,7 @@ Struktur aplikasi Direktori yang paling penting dan file dalam aplikasi Anda (dengan asumsi direktori root aplikasi adalah `basic`): -``` +```js basic/ path aplikasi dasar composer.json digunakan oleh Composer, package information config/ berisi konfigurasi aplikasi dan yang lain @@ -64,7 +64,7 @@ basic/ path aplikasi dasar Secara umum, file dalam aplikasi dapat dibagi menjadi dua jenis: mereka yang di bawah `basic/web` dan mereka yang di bawah direktori lain. Yang pertama dapat langsung diakses melalui HTTP (yaitu, di browser), sedangkan yang kedua tidak dapat dan tidak seharusnya boleh. -Yii mengimplementasikan pola arsitektur [model-view-controller (MVC)](http://wikipedia.org/wiki/Model-view-controller), +Yii mengimplementasikan pola arsitektur [model-view-controller (MVC)](https://wikipedia.org/wiki/Model-view-controller), yang tercermin dalam organisasi direktori di atas. Direktori `models` berisi semua [Model kelas](structure-models.md), direktori `views` berisi semua [view script] structure-views.md), dan direktori `controllers` mengandung semua [kelas kontroler](structure-controllers.md). @@ -99,4 +99,4 @@ Diagram berikut menunjukkan bagaimana aplikasi menangani permintaan. 8. Action memuat model data, mungkin dari database. 9. Aksi meyiapkan view, menyediakannya dengan model data. 10. Hasilnya diberikan dikembalikan ke komponen aplikasi [respon](runtime-responses.md). -11. Komponen respon mengirimkan hasil yang diberikan ke browser pengguna. \ No newline at end of file +11. Komponen respon mengirimkan hasil yang diberikan ke browser pengguna. diff --git a/docs/guide-id/structure-applications.md b/docs/guide-id/structure-applications.md index 1e46f7625a0..a8de8b2489b 100644 --- a/docs/guide-id/structure-applications.md +++ b/docs/guide-id/structure-applications.md @@ -274,7 +274,7 @@ termasuk penerjemahan pesan, format tanggal, format penomoran, dll. Sebagai cont akan menggunakan _property_ ini secara _default_ untuk menentukan bahasa apa yang digunakan pada kalender yang ditampilkan dan bagaimana format tanggal pada kalender tersebut. -Disarankan agar anda menentukan bahasa dalam format [Tag Bahasa IETF](http://en.wikipedia.org/wiki/IETF_language_tag). +Disarankan agar anda menentukan bahasa dalam format [Tag Bahasa IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Sebagai contoh, `en` berarti Bahasa Inggris, sedangkan `en-US` berarti Bahasa Inggris yang digunakan di Amerika Serikat. Informasi selengkapnya mengenai _property_ ini dapat dipelajari di bagian [Internasionalisasi](tutorial-i18n.md). @@ -346,7 +346,7 @@ _Property_ ini menentukan bahasa apa yang digunakan dalam menulis kode aplikasi. yang berarti Bahasa Inggris (Amerika Serikat). Anda sebaiknya menentukan _property_ ini jika teks pada kode anda bukanlah Bahasa Inggris. Seperti layaknya _property_ [language](#language), anda seharusnya menentukan _property_ ini dalam -format [Tag Bahasa IETF](http://en.wikipedia.org/wiki/IETF_language_tag). Sebagai contoh, `en` berarti Bahasa Inggris, +format [Tag Bahasa IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Sebagai contoh, `en` berarti Bahasa Inggris, sedangkan `en-US` berarti Bahasa Inggris (Amerika Serikat). Untuk informasi lebih lanjut mengenai _property_ ini bisa anda pelajari pada bagian [Internasionalisasi](tutorial-i18n.md). @@ -356,7 +356,7 @@ Untuk informasi lebih lanjut mengenai _property_ ini bisa anda pelajari pada bag _Property_ ini disediakan sebagai cara alternatif untuk menentukan zona waktu default dari _PHP runtime_. Dengan menentukan _property_ ini, pada dasarnya anda memanggil _function_ PHP -[date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php). Sebagi contoh: +[date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php). Sebagi contoh: ```php [ diff --git a/docs/guide-id/structure-entry-scripts.md b/docs/guide-id/structure-entry-scripts.md index 1c4e686cbf1..2280dcbfe72 100644 --- a/docs/guide-id/structure-entry-scripts.md +++ b/docs/guide-id/structure-entry-scripts.md @@ -57,9 +57,9 @@ Demikian juga dengan aplikasi konsol, kode berikut ini adalah kode yang terdapat /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-id/structure-overview.md b/docs/guide-id/structure-overview.md index dc7807aaf8d..f7cd7913a17 100644 --- a/docs/guide-id/structure-overview.md +++ b/docs/guide-id/structure-overview.md @@ -1,7 +1,7 @@ Tinjauan ======== -Aplikasi Yii diorganisir berdasarkan pola arsitektur [model-view-controller (MVC)](http://wikipedia.org/wiki/Model-view-controller). +Aplikasi Yii diorganisir berdasarkan pola arsitektur [model-view-controller (MVC)](https://wikipedia.org/wiki/Model-view-controller). [Model](structure-models.md) merepresentasikan data, pengaturan dan proses bisnis; [view](structure-views.md) adalah output yang merepresentasikan model; dan [controller](structure-controllers.md) mengelola input dan merubahnya menjadi perintah-perintah untuk [model](structure-models.md) dan [view](structure-views.md). diff --git a/docs/guide-it/README.md b/docs/guide-it/README.md index 53a001fc72a..c3a9718c00c 100644 --- a/docs/guide-it/README.md +++ b/docs/guide-it/README.md @@ -1,13 +1,13 @@ La guida definitiva a Yii 2.0 ============================= -Questa guida è rilasciata nei [termini della documentazione di Yii](http://www.yiiframework.com/doc/terms/). +Questa guida è rilasciata nei [termini della documentazione di Yii](https://www.yiiframework.com/doc/terms/). Tutti i diritti riservati. 2014 (c) Yii Software LLC. -Traduzione italiana a cura di Lorenzo Milesi ([yetopen.it](http://www.yetopen.it)). +Traduzione italiana a cura di Lorenzo Milesi ([yetopen.it](https://www.yetopen.it)). Introduzione diff --git a/docs/guide-it/intro-upgrade-from-v1.md b/docs/guide-it/intro-upgrade-from-v1.md index 6085a74177a..64afe828c53 100644 --- a/docs/guide-it/intro-upgrade-from-v1.md +++ b/docs/guide-it/intro-upgrade-from-v1.md @@ -28,15 +28,15 @@ Yii 2.0 richiede PHP 5.4 o superiore, il che è un passaggio notevole rispetto a Di conseguenza ci sono diverse differenze a livello di linguaggio a cui devi fare attenzione. Di seguito un riepilogo delle principali differenze relative a PHP: -- [Namespace](https://secure.php.net/manual/en/language.namespaces.php). -- [Funzioni anonime](https://secure.php.net/manual/en/functions.anonymous.php). +- [Namespace](https://www.php.net/manual/en/language.namespaces.php). +- [Funzioni anonime](https://www.php.net/manual/en/functions.anonymous.php). - La sintassi breve per gli array `[...elementi...]` è utilizzabile invece di `array(...elementi...)`. - Le tag brevi per le echo ` L'installazione da un archivio compresso comporta tre passaggi: -1. Scaricare l'archivio da [yiiframework.com](http://www.yiiframework.com/download/). +1. Scaricare l'archivio da [yiiframework.com](https://www.yiiframework.com/download/). 2. Scompattare l'archivio in una directory accessible via web. 3. Modificare il file `config/web.php` inserendo una chiave segreta per il parametro di configurazione `cookieValidationKey` (questa operazione viene fatta automaticamente se installi tramite Composer): @@ -106,7 +106,7 @@ di Yii. Puoi verificare le richieste in due modi: ``` Devi configurare la tua installazione di PHP in modo che soddisfi le richieste minime di Yii. E' molto importante che tu stia usando -PHP 5.4 o successivo. Devi inoltre installare le [estensioni PDO di PHP](https://secure.php.net/manual/en/pdo.installation.php) e un driver +PHP 5.4 o successivo. Devi inoltre installare le [estensioni PDO di PHP](https://www.php.net/manual/en/pdo.installation.php) e un driver di database di PDO (come ad esempio `pdo_mysql` per i database MySQL), se la tua applicazione richiede un database. @@ -116,8 +116,8 @@ Configurazione del webserver > Informazione: puoi saltare questa parte per ora se stai solo provando Yii e non hai intenzione di installarlo su un server di produzione. L'applicazione installata secondo le istruzioni sopra dovrebbe funzionare senza problemi su un server -[Apache](http://httpd.apache.org/) o [Nginx](http://nginx.org/), su Windows, Mac OS X, or Linux equipaggiati con PHP 5.4 o successivo. -Yii 2.0 è anche compatibile con le librerie [HHVM](http://hhvm.com/) di Facebook, tuttavia ci sono alcuni casi limite dove HHVM si +[Apache](https://httpd.apache.org/) o [Nginx](https://nginx.org/), su Windows, Mac OS X, or Linux equipaggiati con PHP 5.4 o successivo. +Yii 2.0 è anche compatibile con le librerie [HHVM](https://hhvm.com/) di Facebook, tuttavia ci sono alcuni casi limite dove HHVM si comporta diversamente dal PHP nativo, quindi devi avere maggiore cura se intendi usare HHVM. Su un server di produzione vorrai probabilmente che la tua applicazione sia accessibile tramite l'url @@ -160,7 +160,7 @@ DocumentRoot "path/to/basic/web" ### Configurazione consigliata di Nginx -Devi aver installato PHP con il demone [FPM](https://secure.php.net/install.fpm) per usare [Nginx](http://wiki.nginx.org/). +Devi aver installato PHP con il demone [FPM](https://www.php.net/install.fpm) per usare [Nginx](https://wiki.nginx.org/). 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. diff --git a/docs/guide-ja/README.md b/docs/guide-ja/README.md index fcc77e6156a..b86e3aaad98 100644 --- a/docs/guide-ja/README.md +++ b/docs/guide-ja/README.md @@ -1,7 +1,7 @@ Yii 2.0 決定版ガイド ==================== -このチュートリアルは [Yii ドキュメント許諾条件](http://www.yiiframework.com/doc/terms/) の下にリリースされています。 +このチュートリアルは [Yii ドキュメント許諾条件](https://www.yiiframework.com/doc/terms/) の下にリリースされています。 All Rights Reserved. diff --git a/docs/guide-ja/caching-data.md b/docs/guide-ja/caching-data.md index f0873614f9e..513fdc59466 100644 --- a/docs/guide-ja/caching-data.md +++ b/docs/guide-ja/caching-data.md @@ -57,7 +57,7 @@ $data = $cache->getOrSet($key, function () use ($user_id) { キャッシュ・コンポーネントは通常グローバルに設定しアクセスできるように [アプリケーション・コンポーネント](structure-application-components.md) として登録されます。 -以下のコードは、二台のキャッシュ・サーバを用いる [Memcached](http://memcached.org/) を使うように +以下のコードは、二台のキャッシュ・サーバを用いる [Memcached](https://memcached.org/) を使うように `cache` アプリケーション・コンポーネントを構成する方法を示すものです。 ```php @@ -103,7 +103,7 @@ $data = $cache->getOrSet($key, function () use ($user_id) { Yii はさまざまなキャッシュ・ストレージをサポートしています。以下がその概要です: -* [[yii\caching\ApcCache]]: PHP の [APC](https://secure.php.net/manual/ja/book.apc.php) 拡張モジュールを使用します。 +* [[yii\caching\ApcCache]]: PHP の [APC](https://www.php.net/manual/ja/book.apc.php) 拡張モジュールを使用します。 集中型の重厚なアプリケーションのキャッシュを扱うときには最速の一つとして考えることができます (例えば、サーバが一台で、専用のロード・バランサを持っていない、などの場合)。 * [[yii\caching\DbCache]]: キャッシュされたデータを格納するためにデータベースのテーブルを使用します。 @@ -120,17 +120,17 @@ Yii はさまざまなキャッシュ・ストレージをサポートしてい データを取得するために同じコード `Yii::$app->cache->get($key)` を使用できます。 * [[yii\caching\FileCache]]: キャッシュされたデータを保存するために通常のファイルを使用します。 これはページ・コンテントなど大きなかたまりのデータに特に適しています。 -* [[yii\caching\MemCache]]: PHP の [Memcache](https://secure.php.net/manual/ja/book.memcache.php) と - [Memcached](https://secure.php.net/manual/ja/book.memcached.php) 拡張モジュールを使用します。 +* [[yii\caching\MemCache]]: PHP の [Memcache](https://www.php.net/manual/ja/book.memcache.php) と + [Memcached](https://www.php.net/manual/ja/book.memcached.php) 拡張モジュールを使用します。 分散型のアプリケーションでキャッシュを扱うときには最速の一つとして考えることができます (例えば、複数台のサーバで、ロード・バランサがある、などの場合) 。 -* [[yii\redis\Cache]]: [Redis](http://redis.io/) の key-value ストアに基づいてキャッシュ・コンポーネントを実装しています。 +* [[yii\redis\Cache]]: [Redis](https://redis.io/) の key-value ストアに基づいてキャッシュ・コンポーネントを実装しています。 (Redis の バージョン 2.6.12 以降が必要とされます) 。 -* [[yii\caching\WinCache]]: PHP の [WinCache](http://iis.net/downloads/microsoft/wincache-extension) エクステンションを使用します。 - ([参照リンク](https://secure.php.net/manual/ja/book.wincache.php)) -* [[yii\caching\XCache]] _(非推奨)_: PHP の [XCache](http://xcache.lighttpd.net/) 拡張モジュールを使用します。 +* [[yii\caching\WinCache]]: PHP の [WinCache](https://iis.net/downloads/microsoft/wincache-extension) エクステンションを使用します。 + ([参照リンク](https://www.php.net/manual/ja/book.wincache.php)) +* [[yii\caching\XCache]] _(非推奨)_: PHP の [XCache](https://en.wikipedia.org/wiki/List_of_PHP_accelerators#XCache) 拡張モジュールを使用します。 * [[yii\caching\ZendDataCache]] _(非推奨)_: - キャッシュ・メディアとして [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) + キャッシュ・メディアとして [Zend Data Cache](https://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) を使用します。 @@ -310,7 +310,7 @@ $result = Customer::getDb()->cache(function ($db) { }); ``` -> Info: いくつかの DBMS (例えば [MySQL](http://dev.mysql.com/doc/refman/5.1/ja/query-cache.html)) +> Info: いくつかの DBMS (例えば [MySQL](https://dev.mysql.com/doc/refman/5.1/ja/query-cache.html)) もデータベース・サーバ・サイドのクエリ・キャッシュをサポートしています。 どちらのクエリ・キャッシュ・メカニズムを選んでも構いません。 前述した Yii のクエリ・キャッシュにはキャッシュの依存を柔軟に指定できるという利点があり、潜在的にはより効率的です。 diff --git a/docs/guide-ja/caching-http.md b/docs/guide-ja/caching-http.md index 3bd908c1f16..684a03020e2 100644 --- a/docs/guide-ja/caching-http.md +++ b/docs/guide-ja/caching-http.md @@ -107,7 +107,7 @@ ETag はリクエスト毎に再評価する必要があるため、負荷の高 の本来の目的を損なって不必要なオーバーヘッドが生じる場合があります。 ページのコンテントが変更されたときにキャッシュを無効化するための式は単純なものを指定するようにして下さい。 -> Note: [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4) に準拠して +> Note: [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4) に準拠して `Etag` と `Last-Modified` ヘッダの両方を設定した場合、 `HttpCache` はその両方とも送信します。 また、もし `If-None-Match` ヘッダと `If-Modified-Since` ヘッダの両方を送信した場合は前者のみが尊重されます。 @@ -131,7 +131,7 @@ Cache-Control: public, max-age=3600 この問題を防止するために、`HttpCache` はこれらのヘッダの送信をデフォルトで自動的に無効化します。 この動作を変更したい場合は [[yii\filters\HttpCache::sessionCacheLimiter]] プロパティを設定します。 このプロパティには `public`、`private`、`private_no_expire`、そして `nocache` などの文字列の値を使用することができます。 -これらの値についての説明は [session_cache_limiter()](https://secure.php.net/manual/ja/function.session-cache-limiter.php) +これらの値についての説明は [session_cache_limiter()](https://www.php.net/manual/ja/function.session-cache-limiter.php) を参照してください。 diff --git a/docs/guide-ja/concept-aliases.md b/docs/guide-ja/concept-aliases.md index c97e12679d5..fc91d52e63d 100644 --- a/docs/guide-ja/concept-aliases.md +++ b/docs/guide-ja/concept-aliases.md @@ -117,7 +117,7 @@ Yii では、一般的に使用されるファイルのパスと URL を簡単 - `@web`, 現在実行中のウェブ・アプリケーションのベース URL。これは、 [[yii\web\Request::baseUrl]] と同じ値を持ちます。 - `@vendor`, [[yii\base\Application::vendorPath|Composer のベンダー・ディレクトリ]] 。デフォルトは `@app/vendor` 。 - `@bower`, [bower パッケージ](http://bower.io/) が含まれるルート・ディレクトリ。デフォルトは `@vendor/bower` 。 -- `@npm`, [npm パッケージ](https://www.npmjs.org/) が含まれるルート・ディレクトリ。デフォルトは `@vendor/npm` 。 +- `@npm`, [npm パッケージ](https://www.npmjs.com/) が含まれるルート・ディレクトリ。デフォルトは `@vendor/npm` 。 `@yii` エイリアスは [エントリ・スクリプト](structure-entry-scripts.md) に `Yii.php` ファイルを読み込んだ時点で定義されます。 エイリアスの残りの部分は、アプリケーションのコンストラクタ内で、アプリケーションの [構成情報](concept-configurations.md) diff --git a/docs/guide-ja/concept-autoloading.md b/docs/guide-ja/concept-autoloading.md index e0298223597..36e1971857a 100644 --- a/docs/guide-ja/concept-autoloading.md +++ b/docs/guide-ja/concept-autoloading.md @@ -2,7 +2,7 @@ ========================== Yiiは、必要となるすべてのクラス・ファイルを特定してインクルードするにあたり、 -[クラスのオートローディング・メカニズム](https://secure.php.net/manual/ja/language.oop5.autoload.php) を頼りにします。 +[クラスのオートローディング・メカニズム](https://www.php.net/manual/ja/language.oop5.autoload.php) を頼りにします。 Yii は、[PSR-4 標準](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md) に準拠した、高性能なクラスのオートローダを提供しています。 このオートローダは、あなたが `Yii.php` ファイルをインクルードするときにインストールされます。 @@ -15,7 +15,7 @@ Yii オートローダを使用する Yii のクラス・オートローダを使用するには、クラスを作成して名前を付けるとき、次の二つの単純なルールに従わなければなりません: -* 各クラスは [名前空間](https://secure.php.net/manual/ja/language.namespaces.php) の下になければなりません (例 `foo\bar\MyClass`) +* 各クラスは [名前空間](https://www.php.net/manual/ja/language.namespaces.php) の下になければなりません (例 `foo\bar\MyClass`) * 各クラスは次のアルゴリズムで決定される個別のファイルに保存されなければなりません: ```php diff --git a/docs/guide-ja/concept-behaviors.md b/docs/guide-ja/concept-behaviors.md index d7c74a2c222..93534b53ef6 100644 --- a/docs/guide-ja/concept-behaviors.md +++ b/docs/guide-ja/concept-behaviors.md @@ -120,21 +120,21 @@ class User extends ActiveRecord { return [ // 無名ビヘイビア ビヘイビア・クラス名のみ - MyBehavior::className(), + MyBehavior::class, // 名前付きビヘイビア ビヘイビア・クラス名のみ - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // 無名ビヘイビア 構成情報配列 [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // 名前付きビヘイビア 構成情報配列 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ] @@ -153,14 +153,14 @@ class User extends ActiveRecord use app\components\MyBehavior; // ビヘイビア・オブジェクトをアタッチ -$component->attachBehavior('myBehavior1', new MyBehavior); +$component->attachBehavior('myBehavior1', new MyBehavior()); // ビヘイビア・クラスをアタッチ -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // 構成情報配列をアタッチ $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -170,8 +170,8 @@ $component->attachBehavior('myBehavior3', [ ```php $component->attachBehaviors([ - 'myBehavior1' => new MyBehavior, // 名前付きビヘイビア - MyBehavior::className(), // 無名ビヘイビア + 'myBehavior1' => new MyBehavior(), // 名前付きビヘイビア + MyBehavior::class, // 無名ビヘイビア ]); ``` @@ -179,10 +179,10 @@ $component->attachBehaviors([ ```php [ - 'as myBehavior2' => MyBehavior::className(), + 'as myBehavior2' => MyBehavior::class, 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -272,7 +272,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -329,7 +329,7 @@ $user->touch('login_time'); ビヘイビアとトレイトの比較 -------------------------- -ビヘイビアは、主となるクラスにそのプロパティやメソッドを「注入する」という点で [トレイト](https://secure.php.net/traits) +ビヘイビアは、主となるクラスにそのプロパティやメソッドを「注入する」という点で [トレイト](https://www.php.net/traits) に似ていますが、これらは多くの面で異なります。以下に説明するように、それらは互いに長所と短所を持っています。 それらは代替手段というよりも、むしろ相互補完関係のようなものです。 diff --git a/docs/guide-ja/concept-components.md b/docs/guide-ja/concept-components.md index 3392a204854..2e542ca40ba 100644 --- a/docs/guide-ja/concept-components.md +++ b/docs/guide-ja/concept-components.md @@ -76,7 +76,7 @@ class MyClass extends BaseObject $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // あるいは、また $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide-ja/concept-di-container.md b/docs/guide-ja/concept-di-container.md index 7e8c7eae5d1..8daac4fb214 100644 --- a/docs/guide-ja/concept-di-container.md +++ b/docs/guide-ja/concept-di-container.md @@ -448,7 +448,7 @@ $container->setDefinitions([ } ]); -$reader = $container->get('app\storage\DocumentsReader); +$reader = $container->get('app\storage\DocumentsReader'); // 構成情報に書かれている依存とともに DocumentReader オブジェクトが生成されます ``` @@ -481,7 +481,7 @@ $container->setDefinitions([ ] ]); -$reader = $container->get('app\storage\DocumentsReader); +$reader = $container->get('app\storage\DocumentsReader'); // 前の例と全く同じオブジェクトが生成されます ``` diff --git a/docs/guide-ja/concept-events.md b/docs/guide-ja/concept-events.md index 567624c1a97..f9515591732 100644 --- a/docs/guide-ja/concept-events.md +++ b/docs/guide-ja/concept-events.md @@ -13,7 +13,7 @@ Yiiはイベントをサポートするために、 [[yii\base\Component]] と イベント・ハンドラ ------------------ -イベント・ハンドラとは、アタッチされたイベントがトリガされたときに実行される [PHP コールバック](https://secure.php.net/manual/ja/language.types.callable.php) +イベント・ハンドラとは、アタッチされたイベントがトリガされたときに実行される [PHP コールバック](https://www.php.net/manual/ja/language.types.callable.php) です。次のコールバックのいずれも使用可能です: - 文字列で指定されたグローバル PHP 関数 (括弧を除く)、例えば `'trim'`。 @@ -211,7 +211,7 @@ use Yii; use yii\base\Event; use yii\db\ActiveRecord; -Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { +Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::debug(get_class($event->sender) . ' が挿入されました'); }); ``` @@ -229,11 +229,11 @@ Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ```php use yii\base\Event; -Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { +Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) { var_dump($event->sender); // "null" を表示 }); -Event::trigger(Foo::className(), Foo::EVENT_HELLO); +Event::trigger(Foo::class, Foo::EVENT_HELLO); ``` この場合、`$event->sender` は、オブジェクト・インスタンスではなく、`null` になることに注意してください。 @@ -245,10 +245,10 @@ Event::trigger(Foo::className(), Foo::EVENT_HELLO); ```php // $handler をデタッチ -Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); +Event::off(Foo::class, Foo::EVENT_HELLO, $handler); // Foo::EVENT_HELLO のすべてのハンドラをデタッチ -Event::off(Foo::className(), Foo::EVENT_HELLO); +Event::off(Foo::class, Foo::EVENT_HELLO); ``` @@ -304,10 +304,10 @@ Event::on('app\interfaces\DanceEventInterface', DanceEventInterface::EVENT_DANCE ```php // trigger event for Dog class -Event::trigger(Dog::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Dog::class, DanceEventInterface::EVENT_DANCE); // trigger event for Developer class -Event::trigger(Developer::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Developer::class, DanceEventInterface::EVENT_DANCE); ``` ただし、このインタフェイスを実装する全クラスのイベントをトリガすることは出来ない、ということに注意して下さい。 diff --git a/docs/guide-ja/db-active-record.md b/docs/guide-ja/db-active-record.md index 451cb3aebc6..801a182ae8a 100644 --- a/docs/guide-ja/db-active-record.md +++ b/docs/guide-ja/db-active-record.md @@ -1,7 +1,7 @@ アクティブ・レコード ==================== -[アクティブ・レコード](http://ja.wikipedia.org/wiki/Active_Record) は、データベースに保存されているデータにアクセスするために、 +[アクティブ・レコード](https://ja.wikipedia.org/wiki/Active_Record) は、データベースに保存されているデータにアクセスするために、 オブジェクト指向のインタフェイスを提供するものです。 アクティブ・レコード・クラスはデータベース・テーブルと関連付けられます。 アクティブ・レコードのインスタンスはそのテーブルの行に対応し、アクティブ・レコードのインスタンスの *属性* がその行にある特定のカラムの値を表現します。 @@ -473,8 +473,8 @@ $post->updateCounters(['view_count' => 1]); > HTML フォームでは全ての値が文字列として表現されるからです。 > 入力値が正しい型、例えば整数値となることを保証するために、`['attributeName', 'filter', 'filter' => 'intval']` のように > [検証フィルタ](input-validation.md#data-filtering) を適用することが出来ます。 -> このフィルタは、[intval()](https://secure.php.net/manual/ja/function.intval.php), [floatval()](https://secure.php.net/manual/ja/function.floatval.php), -> [boolval](https://secure.php.net/manual/ja/function.boolval.php) など、PHP の全てのタイプキャスト関数で動作します。 +> このフィルタは、[intval()](https://www.php.net/manual/ja/function.intval.php), [floatval()](https://www.php.net/manual/ja/function.floatval.php), +> [boolval](https://www.php.net/manual/ja/function.boolval.php) など、PHP の全てのタイプキャスト関数で動作します。 ### デフォルト属性値 @@ -689,7 +689,7 @@ try { ``` > Note: 上記のコードでは、PHP 5.x と PHP 7.x との互換性のために、二つの catch ブロックを持っています。 -> `\Exception` は PHP 7.0 以降では、[`\Throwable` インタフェイス](https://secure.php.net/manual/ja/class.throwable.php) を実装しています。 +> `\Exception` は PHP 7.0 以降では、[`\Throwable` インタフェイス](https://www.php.net/manual/ja/class.throwable.php) を実装しています。 > 従って、あなたのアプリケーションが PHP 7.0 以上しか使わない場合は、`\Exception` の部分を省略することが出来ます。 第二の方法は、トランザクションのサポートが必要な DB 操作を [[yii\db\ActiveRecord::transactions()]] @@ -789,9 +789,15 @@ use yii\behaviors\OptimisticLockBehavior; public function behaviors() { return [ - OptimisticLockBehavior::className(), + OptimisticLockBehavior::class, ]; } + +public function optimisticLock() +{ + return 'version'; +} + ``` > Note: [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] は、ユーザが正しいバージョン番号を送信したときにだけ > レコードが保存されるという事を保証します。そして、そのために、[[\yii\web\Request::getBodyParam()|getBodyParam()]] の結果を直接に解析します。 @@ -821,7 +827,7 @@ class Customer extends ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -831,7 +837,7 @@ class Order extends ActiveRecord public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -849,7 +855,7 @@ class Order extends ActiveRecord 上記の例では、リレーションの宣言において、顧客は複数の注文を持ち得るが、一方、注文は一人の顧客しか持たない、ということが容易に読み取れます。 - 関連するアクティブ・レコード・クラスの名前: [[yii\db\ActiveRecord::hasMany()|hasMany()]] または [[yii\db\ActiveRecord::hasOne()|hasOne()]] の最初のパラメータとして指定されます。 - クラス名を取得するのに `Xyz::className()` を呼ぶのが推奨されるプラクティスです。 + クラス名を取得するのに `Xyz::class` を呼ぶのが推奨されるプラクティスです。 そうすれば、IDE の自動補完のサポートを得ることことが出来るだけでなく、コンパイル段階でエラーを検出することが出来ます。 - 二つの型のデータ間のリンク: 二つの型のデータの関連付けに用いられるカラムを指定します。 配列の値は主たるデータ (リレーションを宣言しているアクティブ・レコード・クラスによって表されるデータ) のカラムであり、 @@ -859,6 +865,8 @@ class Order extends ActiveRecord 続けて書く、ということです。ご覧のように、`customer_id` は `Order` のプロパティであり、 `id` は`Customer` のプロパティです。 +> Warning: リレーション名としては `relation` は予約済みで使えません。これを使うと `ArgumentCountError` となります。 + ### リレーショナル・データにアクセスする @@ -927,7 +935,7 @@ class Customer extends ActiveRecord { public function getBigOrders($threshold = 100) { - return $this->hasMany(Order::className(), ['customer_id' => 'id']) + return $this->hasMany(Order::class, ['customer_id' => 'id']) ->where('subtotal > :threshold', [':threshold' => $threshold]) ->orderBy('id'); } @@ -962,7 +970,7 @@ class Order extends ActiveRecord { public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->viaTable('order_item', ['order_id' => 'id']); } } @@ -975,12 +983,12 @@ class Order extends ActiveRecord { public function getOrderItems() { - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } } @@ -1014,21 +1022,21 @@ class Customer extends ActiveRecord public function getPurchasedItems() { // 顧客の購入品目、すなわち、`Item` の 'id' カラムが OrderItem の 'item_id' に合致するもの - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } public function getOrderItems() { // 顧客の OrderItems、すなわち、`Order` の `id` カラムが `OrderItem` の 'order_id' に合致するもの - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']) + return $this->hasMany(OrderItem::class, ['order_id' => 'id']) ->via('orders'); } public function getOrders() { // 顧客の注文 - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1281,7 +1289,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -1289,7 +1297,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -1323,7 +1331,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); } } ``` @@ -1434,7 +1442,7 @@ class Customer extends \yii\db\ActiveRecord public function getComments() { // Customer は多くの Comment を持つ - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1449,7 +1457,7 @@ class Comment extends \yii\mongodb\ActiveRecord public function getCustomer() { // Comment は 一つの Customer を持つ - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } @@ -1533,7 +1541,7 @@ class Customer extends \yii\db\ActiveRecord { public function getActiveComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id'])->active(); + return $this->hasMany(Comment::class, ['customer_id' => 'id'])->active(); } } @@ -1544,7 +1552,7 @@ class Customer extends \yii\db\ActiveRecord { public function getComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1610,7 +1618,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1705,7 +1713,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1736,7 +1744,7 @@ class Customer extends \yii\db\ActiveRecord */ public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } /** diff --git a/docs/guide-ja/db-dao.md b/docs/guide-ja/db-dao.md index f55a6e38b3f..f1e09ed1d68 100644 --- a/docs/guide-ja/db-dao.md +++ b/docs/guide-ja/db-dao.md @@ -1,7 +1,7 @@ データベース・アクセス・オブジェクト ==================================== -[PDO](https://secure.php.net/manual/ja/book.pdo.php) の上に構築された Yii DAO (データベース・アクセス・オブジェクト) は、 +[PDO](https://www.php.net/manual/ja/book.pdo.php) の上に構築された Yii DAO (データベース・アクセス・オブジェクト) は、 リレーショナル・データベースにアクセスするためのオブジェクト指向 API を提供するものです。 これは、データベースにアクセスする他のもっと高度な方法、例えば [クエリ・ビルダ](db-query-builder.md) や [アクティブ・レコード](db-active-record.md) の基礎でもあります。 @@ -11,12 +11,12 @@ Yii DAO を使うときは、主として素の SQL と PHP 配列を扱う必 Yii 2.0 では、DAO は下記の DBMS のサポートを内蔵しています。 -- [MySQL](http://www.mysql.com/) +- [MySQL](https://www.mysql.com/) - [MariaDB](https://mariadb.com/) -- [SQLite](http://sqlite.org/) -- [PostgreSQL](http://www.postgresql.org/): バージョン 8.4 以上。 -- [CUBRID](http://www.cubrid.org/): バージョン 9.3 以上。 -- [Oracle](http://www.oracle.com/us/products/database/overview/index.html) +- [SQLite](https://sqlite.org/) +- [PostgreSQL](https://www.postgresql.org/): バージョン 8.4 以上。 +- [CUBRID](https://www.cubrid.org/): バージョン 9.3 以上。 +- [Oracle](https://www.oracle.com/database/) - [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): バージョン 2008 以上。 > Note: PHP 7 用の pdo_oci の新しいバージョンは、現在、ソース・コードとしてのみ存在します。 @@ -62,7 +62,7 @@ return [ DB 接続を構成するときは、つねに [[yii\db\Connection::dsn|dsn]] プロパティによってデータ・ソース名 (DSN) を指定しなければなりません。 DSN の形式はデータベースによってさまざまに異なります。 -詳細は [PHP マニュアル](https://secure.php.net/manual/ja/function.PDO-construct.php) を参照して下さい。下記にいくつかの例を挙げます。 +詳細は [PHP マニュアル](https://www.php.net/manual/ja/function.PDO-construct.php) を参照して下さい。下記にいくつかの例を挙げます。 * MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` * SQLite: `sqlite:/path/to/database/file` @@ -190,7 +190,7 @@ $post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status ->queryOne(); ``` -パラメータ・バインディングは [プリペアド・ステートメント](https://secure.php.net/manual/ja/mysqli.quickstart.prepared-statements.php) によって実装されています。 +パラメータ・バインディングは [プリペアド・ステートメント](https://www.php.net/manual/ja/mysqli.quickstart.prepared-statements.php) によって実装されています。 パラメータ・バインディングには、SQL インジェクション攻撃を防止する以外にも、SQL 文を一度だけ準備して異なるパラメータで複数回実行することにより、 パフォーマンスを向上させる効果もあります。例えば、 @@ -384,7 +384,7 @@ try { そして、`throw $e` が、まるでそれをキャッチしなかったかのように、例外を再スローしますので、通常のエラー処理プロセスがその例外の面倒を見ることになります。 > Note: 上記のコードでは、PHP 5.x と PHP 7.x との互換性のために、二つのcatch ブロックを持っています。 -> `\Exception` は PHP 7.0 以降では、[`\Throwable` インタフェイス](https://secure.php.net/manual/ja/class.throwable.php) を実装しています。 +> `\Exception` は PHP 7.0 以降では、[`\Throwable` インタフェイス](https://www.php.net/manual/ja/class.throwable.php) を実装しています。 > 従って、あなたのアプリケーションが PHP 7.0 以上しか使わない場合は、`\Exception` の部分を省略することが出来ます。 @@ -427,7 +427,7 @@ DBMS によっては、接続全体に対してのみ分離レベルの設定を すなわち、トランザクションを開始するときに、分離レベルを直接に指定することは出来ません。 この場合、トランザクションを開始した後に [[yii\db\Transaction::setIsolationLevel()]] を呼び出す必要があります。 -[分離レベル]: http://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%88%86%E9%9B%A2%E3%83%AC%E3%83%99%E3%83%AB +[分離レベル]: https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%88%86%E9%9B%A2%E3%83%AC%E3%83%99%E3%83%AB ### トランザクションを入れ子にする @@ -478,7 +478,7 @@ try { ## レプリケーションと読み書きの分離 多くの DBMS は、データベースの可用性とサーバのレスポンス・タイムを向上させるために、 -[データベース・レプリケーション](http://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3#.E3.83.87.E3.83.BC.E3.82.BF.E3.83.99.E3.83.BC.E3.82.B9) をサポートしています。 +[データベース・レプリケーション](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3#.E3.83.87.E3.83.BC.E3.82.BF.E3.83.99.E3.83.BC.E3.82.B9) をサポートしています。 データベース・レプリケーションによって、データはいわゆる *マスタ・サーバ* から *スレーブ・サーバ* に複製されます。 データの書き込みと更新はすべてマスタ・サーバ上で実行されなければなりませんが、データの読み出しはスレーブ・サーバ上でも可能です。 diff --git a/docs/guide-ja/db-migrations.md b/docs/guide-ja/db-migrations.md index 76cdf9d38ba..ca850633ee9 100644 --- a/docs/guide-ja/db-migrations.md +++ b/docs/guide-ja/db-migrations.md @@ -187,6 +187,22 @@ class m150101_185401_create_news_table extends Migration カラムの型を定義するために利用できる全てのメソッドのリストは、[[yii\db\SchemaBuilderTrait]] の API ドキュメントで参照することが出来ます。 +> Info: 生成されるファイルのパーミッションと所有者は現在の環境によって決定されます。 + これが原因でファイルにアクセス出来ない場合が生じ得ます。例えば、docker コンテナ内で作成されたマイグレーションのファイルをホストで編集するとそうなる場合があります。 + このような場合には MigrateController の `newFileMode` および/または `newFileOwnership` を変更することが出来ます。 + 例えば、アプリケーション設定で次のように設定します。 + ```php + [ + 'migrate' => [ + 'class' => 'yii\console\controllers\MigrateController', + 'newFileOwnership' => '1000:1000', # Default WSL user id + 'newFileMode' => 0660, + ], + ], + ]; + ``` ## マイグレーションを生成する diff --git a/docs/guide-ja/db-query-builder.md b/docs/guide-ja/db-query-builder.md index 02221ea1edd..a938a2f077f 100644 --- a/docs/guide-ja/db-query-builder.md +++ b/docs/guide-ja/db-query-builder.md @@ -155,7 +155,7 @@ $query->from(['u' => $subQuery]); #### プレフィックス また、デフォルトの [[yii\db\Connection::$tablePrefix|tablePrefix]] を適用することも出来ます。 -実装の仕方は ["データベース・アクセス・オブジェクト" ガイドの "テーブル名を引用符で囲む" のセクション](guide-db-dao.html#quoting-table-and-column-names) にあります。 +実装の仕方は ["データベース・アクセス・オブジェクト" ガイドの "テーブル名を引用符で囲む" のセクション](db-dao.md#quoting-table-and-column-names) にあります。 ### [[yii\db\Query::where()|where()]] @@ -540,14 +540,14 @@ $query->limit(10)->offset(20); ### [[yii\db\Query::join()|join()]] [[yii\db\Query::join()|join()]] メソッドは SQL クエリの `JOIN` 句を指定します。例えば、 - + ```php // ... LEFT JOIN `post` ON `post`.`user_id` = `user`.`id` $query->join('LEFT JOIN', 'post', 'post.user_id = user.id'); ``` [[yii\db\Query::join()|join()]] メソッドは、四つのパラメータを取ります。 - + - `$type`: 結合のタイプ、例えば、`'INNER JOIN'`、`'LEFT JOIN'`。 - `$table`: 結合されるテーブルの名前。 - `$on`: オプション。結合条件、すなわち、`ON` 句。 @@ -716,6 +716,9 @@ $query = (new \yii\db\Query()) ->all(); ``` +インデックス付けが働くためには、[[yii\db\Query::indexBy()|indexBy()]] メソッドに渡されるカラム名が結果セットに存在する必要があります。 +そのことを保証するのは開発者の責任です。 + 式の値によってインデックスするためには、[[yii\db\Query::indexBy()|indexBy()]] メソッドに無名関数を渡します。 ```php @@ -795,7 +798,7 @@ foreach ($query->each() as $username => $user) { #### MySQL におけるバッチ・クエリの制約 MySQL のバッチ・クエリの実装は PDO ドライバのライブラリに依存しています。デフォルトでは、MySQL のクエリは -[`バッファ・モード`](https://secure.php.net/manual/ja/mysqlinfo.concepts.buffering.php) で実行されます。 +[`バッファ・モード`](https://www.php.net/manual/ja/mysqlinfo.concepts.buffering.php) で実行されます。 このことが、カーソルを使ってデータを取得する目的を挫折させます。というのは、バッファ・モードでは、 ドライバによって結果セット全体がクライアントのメモリに読み込まれることを防止できないからです。 diff --git a/docs/guide-ja/glossary.md b/docs/guide-ja/glossary.md index 61ca7a4bb26..82a6a9769c5 100644 --- a/docs/guide-ja/glossary.md +++ b/docs/guide-ja/glossary.md @@ -58,7 +58,7 @@ Yii の場合は、パーミッションを設定すること、および、ソ ## namespace 名前空間 -名前空間は Yii 2 で積極的に使用されている [PHP 言語機能のひとつ](https://secure.php.net/manual/ja/language.namespaces.php) です。 +名前空間は Yii 2 で積極的に使用されている [PHP 言語機能のひとつ](https://www.php.net/manual/ja/language.namespaces.php) です。 # P diff --git a/docs/guide-ja/helper-array.md b/docs/guide-ja/helper-array.md index 40608ffab3a..2df340a6ff5 100644 --- a/docs/guide-ja/helper-array.md +++ b/docs/guide-ja/helper-array.md @@ -1,7 +1,7 @@ 配列ヘルパ ========== -[PHP の充実した配列関数](https://secure.php.net/manual/ja/book.array.php) への追加として、 +[PHP の充実した配列関数](https://www.php.net/manual/ja/book.array.php) への追加として、 Yii の配列ヘルパは、配列をさらに効率的に扱うことを可能にするスタティックなメソッドを提供しています。 @@ -118,7 +118,7 @@ $type = ArrayHelper::remove($array, 'type'); ## キーの存在をチェックする `ArrayHelper::keyExists` は、大文字と小文字を区別しないキーの比較をサポートすることを除いて、 -[array_key_exists](https://secure.php.net/manual/ja/function.array-key-exists.php) と同じ動作をします。例えば、 +[array_key_exists](https://www.php.net/manual/ja/function.array-key-exists.php) と同じ動作をします。例えば、 ```php $data1 = [ @@ -322,7 +322,7 @@ ArrayHelper::multisort($data, function($item) { 複数の値による並べ替えの場合は、並べ替えの順序の配列を渡して、値ごとに違う順序で並べ替えることが出来ます。 最後の引数は並べ替えのフラグで、 -PHP の [sort()](https://secure.php.net/manual/ja/function.sort.php) 関数に渡されるのと同じ値を取ることが出来ます。 +PHP の [sort()](https://www.php.net/manual/ja/function.sort.php) 関数に渡されるのと同じ値を取ることが出来ます。 ## 配列の型を検出する @@ -357,7 +357,7 @@ $decoded = ArrayHelper::htmlDecode($data); [[yii\helpers\ArrayHelper::merge()|ArrayHelper::merge()]] を使って、二つまたはそれ以上の配列を再帰的に一つの配列にマージすることが出来ます。 各配列に同じ文字列のキー値を持つ要素がある場合は、 -([array_merge_recursive()](https://secure.php.net/manual/ja/function.array-merge-recursive.php) とは違って)後のものが前のものを上書きします。 +([array_merge_recursive()](https://www.php.net/manual/ja/function.array-merge-recursive.php) とは違って)後のものが前のものを上書きします。 両方の配列が、同じキーを持つ配列型の要素を持っている場合は、再帰的なマージが実行されます。 添字型の要素については、後の配列の要素が前の配列の要素の後に追加されます。 [[yii\helpers\UnsetArrayValue]] オブジェクトを使って前の配列にある値を非設定に指定したり、 @@ -472,7 +472,7 @@ PHP は `in_array()` を提供していますが、これはサブセットや ` この種のチェックを助けるために、[[yii\helpers\ArrayHelper]] は [[yii\helpers\ArrayHelper::isIn()|isIn()]] および [[yii\helpers\ArrayHelper::isSubset()|isSubset()]] を -[in_array()](https://secure.php.net/manual/en/function.in-array.php) と同じシグニチャで提供しています。 +[in_array()](https://www.php.net/manual/en/function.in-array.php) と同じシグニチャで提供しています。 ```php // true diff --git a/docs/guide-ja/helper-html.md b/docs/guide-ja/helper-html.md index 14693f2f668..6f200dc4365 100644 --- a/docs/guide-ja/helper-html.md +++ b/docs/guide-ja/helper-html.md @@ -2,7 +2,7 @@ Html ヘルパ =========== 全てのウェブ・アプリケーションは大量の HTML マークアップを生成します。 -マークアップが静的な場合は、[PHP と HTML を一つのファイルに混ぜる](https://secure.php.net/manual/ja/language.basic-syntax.phpmode.php) ことによって効率よく生成することが可能ですが、マークアップを動的にするとなると、何らかの助けが無ければ、処理がトリッキーになってきます。 +マークアップが静的な場合は、[PHP と HTML を一つのファイルに混ぜる](https://www.php.net/manual/ja/language.basic-syntax.phpmode.php) ことによって効率よく生成することが可能ですが、マークアップを動的にするとなると、何らかの助けが無ければ、処理がトリッキーになってきます。 Yii はそのような手助けを Html ヘルパの形式で提供します。 これは、よく使われる HTML タグとそのオプションやコンテントを処理するための一連のスタティック・メソッドを提供するものです。 @@ -41,7 +41,7 @@ Yii はそのような手助けを Html ヘルパの形式で提供します。 その全ての場合において、いくつか追加の処理がなされることを知っておいてください。 - 値が `null` である場合は、対応する属性はレンダリングされません。 -- 値が真偽値である属性は、[真偽値属性 (boolean attributes)](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes) +- 値が真偽値である属性は、[真偽値属性 (boolean attributes)](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes) として扱われます。 - 属性の値は [[yii\helpers\Html::encode()|Html::encode()]] を使って HTML エンコードされます。 - 属性の値が配列である場合は、次のように処理されます。 @@ -147,8 +147,8 @@ Html::removeCssStyle($options, ['width', 'height']); ### コンテントをエンコードおよびデコードする コンテントが適切かつ安全に HTML として表示されるためには、コンテント内の特殊文字がエンコードされなければなりません。 -特殊文字のエンコードとデコードは、PHP では [htmlspecialchars](https://secure.php.net/manual/ja/function.htmlspecialchars.php) と -[htmlspecialchars_decode](https://secure.php.net/manual/ja/function.htmlspecialchars-decode.php) によって行われます。 +特殊文字のエンコードとデコードは、PHP では [htmlspecialchars](https://www.php.net/manual/ja/function.htmlspecialchars.php) と +[htmlspecialchars_decode](https://www.php.net/manual/ja/function.htmlspecialchars-decode.php) によって行われます。 これらのメソッドを直接使用する場合の問題は、文字エンコーディングと追加のフラグを毎回指定しなければならないことです。 フラグは毎回同じものであり、文字エンコーディングはセキュリティ問題を防止するためにアプリケーションのそれと一致すべきものですから、 Yii は二つのコンパクトかつ使いやすいメソッドを用意しました。 diff --git a/docs/guide-ja/helper-json.md b/docs/guide-ja/helper-json.md new file mode 100644 index 00000000000..98226c13575 --- /dev/null +++ b/docs/guide-ja/helper-json.md @@ -0,0 +1,25 @@ +Json ヘルパ +=========== + +Json ヘルパは JSON をエンコードおよびデコードする一連の静的メソッドを提供します。 +`[[yii\helpers\Json::encode()]]` メソッドはエンコード・エラーを処理しますが、 + `[[yii\web\JsExpression]]` オブジェクトの形式で表現された JavaScript の式はエンコードしません。 +既定ではエンコードは `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE` のオプションで行われます。 +詳細については [PHP:json_encode](https://www.php.net/manual/ja/function.json-encode.php) を参照して下さい。 + +## 整形出力 + +既定では `[[yii\helpers\Json::encode()]]` メソッドは整形されていない JSON (すなわち空白無しのもの) を出力します。 +人間にとって読みやすいものにするために、「整形出力 pretty printing」を ON にすることが出来ます。 + +> Note: 整形出力は開発中のデバッグには役立つでしょうが、製品環境では推奨されません。 +インスタンスごとに整形出力を有効にするためにはオプションを指定することが出来ます。すなわち : + +```php +$data = ['a' => 1, 'b' => 2]; +$json = yii\helpers\Json::encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); +``` +JSON ヘルパの整形出力をグローバルに有効にすることも出来ます。例えば、設定ファイルや index.php の中で : +```php +yii\helpers\Json::$prettyPrint = YII_DEBUG; // デバッグ・モードでは整形出力を使用 +``` diff --git a/docs/guide-ja/helper-overview.md b/docs/guide-ja/helper-overview.md index 9ae4e7df994..5e0818acdef 100644 --- a/docs/guide-ja/helper-overview.md +++ b/docs/guide-ja/helper-overview.md @@ -33,7 +33,7 @@ echo Html::encode('Test > test'); - HtmlPurifier - Imagine (yii2-imagine エクステンションによって提供) - Inflector -- Json +- [Json](helper-json.md) - Markdown - StringHelper - [Url ヘルパ](helper-url.md) diff --git a/docs/guide-ja/input-file-upload.md b/docs/guide-ja/input-file-upload.md index ffa6b733c41..669fd397f66 100644 --- a/docs/guide-ja/input-file-upload.md +++ b/docs/guide-ja/input-file-upload.md @@ -123,7 +123,7 @@ class SiteController extends Controller 最初に、モデル・クラスを修正して、`file` 検証規則に `maxFiles` オプションを追加して、アップロードを許可されるファイルの最大数を制限しなければなりません。 `maxFiles` を `0` に設定することは、同時にアップロード出来るファイル数に制限がないことを意味します。 同時にアップロードすることを許されるファイルの数は、また、PHP のディレクティブ -[`max_file_uploads`](https://secure.php.net/manual/ja/ini.core.php#ini.max-file-uploads) (デフォルト値は 20) によっても制限されます。 +[`max_file_uploads`](https://www.php.net/manual/ja/ini.core.php#ini.max-file-uploads) (デフォルト値は 20) によっても制限されます。 `upload()` メソッドも、アップロードされた複数のファイルを一つずつ保存するように修正しなければなりません。 ```php diff --git a/docs/guide-ja/input-forms.md b/docs/guide-ja/input-forms.md index 2e3f8ab96cf..07f0cf423a6 100644 --- a/docs/guide-ja/input-forms.md +++ b/docs/guide-ja/input-forms.md @@ -107,7 +107,7 @@ echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Ite > フォームおよびフォームの子要素は、フォームのプロパティと衝突するインプット名や id、たとえば `submit`、`length`、`method` などを使ってはなりません。 > 名前の衝突は訳の分らない失敗を生じさせることがあります。 -> 命名規則の完全なリストを知り、この問題についてあなたのマークアップをチェックするためには、[DOMLint](http://kangax.github.io/domlint/) を参照してください。 +> 命名規則の完全なリストを知り、この問題についてあなたのマークアップをチェックするためには、[DOMLint](https://kangax.github.io/domlint/) を参照してください。 フォームに HTML タグを追加するためには、素の HTML を使うか、または、上記の例の [[yii\helpers\Html::submitButton()|Html::submitButton()]] のように、 [[yii\helpers\Html|Html]] ヘルパ・クラスのメソッドを使うことが出来ます。 diff --git a/docs/guide-ja/input-validation.md b/docs/guide-ja/input-validation.md index 6850752d337..5847f003f45 100644 --- a/docs/guide-ja/input-validation.md +++ b/docs/guide-ja/input-validation.md @@ -469,7 +469,7 @@ class EntryForm extends Model { return [ [['name', 'email'], 'required'], - ['country', CountryValidator::className()], + ['country', CountryValidator::class], ['email', 'email'], ]; } diff --git a/docs/guide-ja/intro-upgrade-from-v1.md b/docs/guide-ja/intro-upgrade-from-v1.md index 8d64b2d90b6..53010f0da0e 100644 --- a/docs/guide-ja/intro-upgrade-from-v1.md +++ b/docs/guide-ja/intro-upgrade-from-v1.md @@ -29,15 +29,15 @@ Yii 2.0 は PHP 5.4 以上を必要とします。PHP 5.4 は、Yii 1.1 によ この結果として、注意を払うべき言語レベルでの違いが数多くあります。 以下は PHP に関する主要な変更点の要約です。 -- [名前空間](https://secure.php.net/manual/ja/language.namespaces.php)。 -- [無名関数](https://secure.php.net/manual/ja/functions.anonymous.php)。 +- [名前空間](https://www.php.net/manual/ja/language.namespaces.php)。 +- [無名関数](https://www.php.net/manual/ja/functions.anonymous.php)。 - 配列の短縮構文 `[...要素...]` が `array(...要素...)` の代りに使われています。 - 短縮形の echo タグ `registerJs( - [[yii\web\View::POS_HEAD|View::POS_HEAD]] - head セクション。 - [[yii\web\View::POS_BEGIN|View::POS_BEGIN]] - 開始の `` の直後。 - [[yii\web\View::POS_END|View::POS_END]] - 終了の `` の直前。 -- [[yii\web\View::POS_READY|View::POS_READY]] - [ドキュメントの `ready` イベント](http://learn.jquery.com/using-jquery-core/document-ready/) でコードを実行するための指定。 +- [[yii\web\View::POS_READY|View::POS_READY]] - [ドキュメントの `ready` イベント](https://learn.jquery.com/using-jquery-core/document-ready/) でコードを実行するための指定。 これを指定すると、[[yii\web\JqueryAsset|jQuery]] が自動的に登録され、コードは適切な jQuery コードの中に包まれます。これがデフォルトの位置指定です。 -- [[yii\web\View::POS_LOAD|View::POS_LOAD]] - [ドキュメントの `load` イベント](http://learn.jquery.com/using-jquery-core/document-ready/) でコードを実行するための指定。 +- [[yii\web\View::POS_LOAD|View::POS_LOAD]] - [ドキュメントの `load` イベント](https://learn.jquery.com/using-jquery-core/document-ready/) でコードを実行するための指定。 上記と同じく、これを指定すると、[[yii\web\JqueryAsset|jQuery]] が自動的に登録されます。 最後の引数は、スクリプトのコード・ブロックを一意に特定するために使われるスクリプトのユニークな ID です。同じ ID のスクリプトが既にある場合は、新しいものを追加するのでなく、 @@ -56,7 +56,7 @@ $this->registerJs( ```php $this->registerJsFile( '@web/js/main.js', - ['depends' => [\yii\web\JqueryAsset::className()]] + ['depends' => [\yii\web\JqueryAsset::class]] ); ``` @@ -95,7 +95,7 @@ CSS ファイルは次のようにして登録することが出来ます。 ```php $this->registerCssFile("@web/css/themes/black-and-white.css", [ - 'depends' => [\yii\bootstrap\BootstrapAsset::className()], + 'depends' => [\yii\bootstrap\BootstrapAsset::class], 'media' => 'print', ], 'css-print-theme'); ``` @@ -188,7 +188,7 @@ JS ); ``` -上記のサンプル・コードは、可読性を高めるために、PHP の [ヒアドキュメント構文](https://secure.php.net/manual/ja/language.types.string.php#language.types.string.syntax.heredoc) を使っています。 +上記のサンプル・コードは、可読性を高めるために、PHP の [ヒアドキュメント構文](https://www.php.net/manual/ja/language.types.string.php#language.types.string.syntax.heredoc) を使っています。 また、ヒアドキュメントは、たいていの IDE で、より良い構文ハイライトが可能になるので、 インライン JavaScript、特に一行に収まらないものを書くときに推奨される方法です。 変数 `$message` は PHP で生成され、[[yii\helpers\Json::htmlEncode|Json::htmlEncode]] のおかげで、適切な JS 構文の文字列を含むものになります。 diff --git a/docs/guide-ja/output-data-widgets.md b/docs/guide-ja/output-data-widgets.md index 712a5d6b26e..28946fe3393 100644 --- a/docs/guide-ja/output-data-widgets.md +++ b/docs/guide-ja/output-data-widgets.md @@ -777,4 +777,4 @@ yii gii/crud --controllerClass="backend\\controllers\PostController" \ さらに読むべき文書 ------------------ -- Arno Slatius による [Rendering Data in Yii 2 with GridView and ListView](http://www.sitepoint.com/rendering-data-in-yii-2-with-gridview-and-listview/)。 +- Arno Slatius による [Rendering Data in Yii 2 with GridView and ListView](https://www.sitepoint.com/rendering-data-in-yii-2-with-gridview-and-listview/)。 diff --git a/docs/guide-ja/output-formatting.md b/docs/guide-ja/output-formatting.md index 0014c1f6b09..951a1260bef 100644 --- a/docs/guide-ja/output-formatting.md +++ b/docs/guide-ja/output-formatting.md @@ -45,7 +45,7 @@ echo Yii::$app->formatter->format(0.125, ['percent', 2]); > フォーマッタは適切なツールではありません。 > 日付と数値についてユーザ入力を変換するためには、それぞれ、[[yii\validators\DateValidator]] と [[yii\validators\NumberValidator]] > を使うことが出来ます。機械が読み取れる日付と時刻のフォーマットの単純な相互変換には、PHP の -> [date()](https://secure.php.net/manual/ja/function.date.php) 関数で十分です。 +> [date()](https://www.php.net/manual/ja/function.date.php) 関数で十分です。 ## フォーマッタを構成する @@ -86,7 +86,7 @@ return [ グローバルにカスタマイズすることが出来ます。 日付と時刻のフォーマットは、[ICU 構文](http://userguide.icu-project.org/formatparse/datetime) によって指定することが出来ます。 -また、ICU 構文と区別するために `php:` という接頭辞を付けて、[PHP の date() 構文](https://secure.php.net/manual/ja/function.date.php) +また、ICU 構文と区別するために `php:` という接頭辞を付けて、[PHP の date() 構文](https://www.php.net/manual/ja/function.date.php) を使うことも出来ます。例えば、 ```php @@ -191,7 +191,7 @@ echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00 を使って調整することが出来ます。 更に高度な設定のためには、[[yii\i18n\Formatter::numberFormatterOptions]] と [[yii\i18n\Formatter::numberFormatterTextOptions]] -を使って、内部的に使用される [NumberFormatter クラス](https://secure.php.net/manual/ja/class.numberformatter.php) を構成することが出来ます。 +を使って、内部的に使用される [NumberFormatter クラス](https://www.php.net/manual/ja/class.numberformatter.php) を構成することが出来ます。 例えば、小数部の最大桁数と最小桁数を調整するためには、次のように [[yii\i18n\Formatter::numberFormatterOptions]] プロパティを構成します。 @@ -255,7 +255,7 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // 出力: 2014/01/01 デフォルトでは、現在のアクティブな [[yii\i18n\Formatter::locale|locale]] は [[yii\base\Application::language]] の値によって決定されます。 これは [[yii\i18n\Formatter::locale]] プロパティを明示的に指定することによってオーバーライドすることが出来ます。 -> Note: Yii のフォーマッタは、[PHP intl 拡張](https://secure.php.net/manual/ja/book.intl.php) に依存してデータのフォーマットの +> Note: Yii のフォーマッタは、[PHP intl 拡張](https://www.php.net/manual/ja/book.intl.php) に依存してデータのフォーマットの > ローカライズをサポートしています。PHP にコンパイルされた ICU ライブラリのバージョンによってフォーマットの結果が異なる場合がありますので、 > あなたの全ての環境で、同じ ICU バージョンを使うことが推奨されます。 > 詳細については、[PHP 環境を国際化のために設定する](tutorial-i18n.md#setup-environment) を参照してください。 diff --git a/docs/guide-ja/rest-authentication.md b/docs/guide-ja/rest-authentication.md index 4136aef146f..1273e2781b2 100644 --- a/docs/guide-ja/rest-authentication.md +++ b/docs/guide-ja/rest-authentication.md @@ -18,7 +18,7 @@ ほとんどのウェブ・サーバはクエリ・パラメータをサーバのログに記録するため、この手法は、 アクセス・トークンを HTTP ヘッダを使って送信することができない `JSONP` リクエストに応答するために主として使用されるべきです。 * [OAuth 2](http://oauth.net/2/): OAuth2 プロトコルに従って、 - アクセス・トークンはコンシューマによって権限付与サーバから取得され、[HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750) 経由で + アクセス・トークンはコンシューマによって権限付与サーバから取得され、[HTTP Bearer Tokens](https://datatracker.ietf.org/doc/html/rfc6750) 経由で API サーバに送信されます。 Yii は上記の全ての認証方法をサポートしています。新しい認証方法を作成することも簡単に出来ます。 @@ -57,7 +57,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -75,11 +75,11 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => CompositeAuth::className(), + 'class' => CompositeAuth::class, 'authMethods' => [ - HttpBasicAuth::className(), - HttpBearerAuth::className(), - QueryParamAuth::className(), + HttpBasicAuth::class, + HttpBearerAuth::class, + QueryParamAuth::class, ], ]; return $behaviors; diff --git a/docs/guide-ja/rest-controllers.md b/docs/guide-ja/rest-controllers.md index a17091ee302..377f9189987 100644 --- a/docs/guide-ja/rest-controllers.md +++ b/docs/guide-ja/rest-controllers.md @@ -69,7 +69,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -80,7 +80,7 @@ public function behaviors() コントローラに [CORS (クロス・オリジン・リソース共有)](structure-filters.md#cors) フィルタを追加するのは、上記の他のフィルタを追加するのより、若干複雑になります。 と言うのは、CORS フィルタは認証メソッドより前に適用されなければならないため、他のフィルタとは少し異なるアプローチが必要だからです。 また、ブラウザが認証クレデンシャルを送信する必要なく、リクエストが出来るかどうかを前もって安全に判断できるように、 -[CORS プリフライト・リクエスト](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests) +[CORS プリフライト・リクエスト](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests) の認証を無効にする必要もあります。 下記のコードは、[[yii\rest\ActiveController]] を拡張した既存のコントローラに [[yii\filters\Cors]] フィルタを追加するのに必要なコードを示しています。 @@ -98,7 +98,7 @@ public function behaviors() // CORS フィルタを追加する $behaviors['corsFilter'] = [ - 'class' => \yii\filters\Cors::className(), + 'class' => \yii\filters\Cors::class, ]; // 認証フィルタを再度追加する diff --git a/docs/guide-ja/rest-resources.md b/docs/guide-ja/rest-resources.md index 07d508c3ed8..09020bca275 100644 --- a/docs/guide-ja/rest-resources.md +++ b/docs/guide-ja/rest-resources.md @@ -140,7 +140,7 @@ public function extraFields() ## リンク -[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS) は、Hypermedia as the Engine of Application State (アプリケーション状態のエンジンとしてのハイパーメディア) の略称です。 +[HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) は、Hypermedia as the Engine of Application State (アプリケーション状態のエンジンとしてのハイパーメディア) の略称です。 HATEOAS は、RESTful API は自分が返すリソースについて、どのようなアクションがサポートされているかをクライアントが発見できるような情報を返すべきである、という概念です。 HATEOAS のキーポイントは、リソース・データが API によって提供されるときには、 関連する情報を一群のハイパーリンクによって返すべきである、ということです。 diff --git a/docs/guide-ja/runtime-bootstrapping.md b/docs/guide-ja/runtime-bootstrapping.md index 9b6de2b994d..976a4476339 100644 --- a/docs/guide-ja/runtime-bootstrapping.md +++ b/docs/guide-ja/runtime-bootstrapping.md @@ -37,8 +37,8 @@ 本番運用モードにおいては、[PHP OPCache] や [APC] など、バイトコード・キャッシュを有効にして、 PHP ファイルをインクルードして解析するのに要する時間を最小化してください。 -[PHP OPcache]: https://secure.php.net/manual/ja/book.opcache.php -[APC]: https://secure.php.net/manual/ja/book.apc.php +[PHP OPcache]: https://www.php.net/manual/ja/book.opcache.php +[APC]: https://www.php.net/manual/ja/book.apcu.php 大規模なアプリケーションには、多数の小さな構成情報ファイルに分割された、非常に複雑なアプリケーション [構成情報](concept-configurations.md) を持つものがあります。 そのような場合には、構成情報配列全体をキャッシュするという方法を考慮して下さい。 diff --git a/docs/guide-ja/runtime-requests.md b/docs/guide-ja/runtime-requests.md index 4725d41ce08..e8f5fb829ff 100644 --- a/docs/guide-ja/runtime-requests.md +++ b/docs/guide-ja/runtime-requests.md @@ -201,7 +201,7 @@ Yii アプリケーションに渡されるからです。 その場合、前者は `ipHeaders` で構成されているようにユーザの IP を読み出すために使用され、 後者は [[yii\web\Request::getIsSecureConnection()]] の結果を決定するために使用されます。 -2.0.31 以降、[RFC 7239](https://tools.ietf.org/html/rfc7239) の `Forwarded` ヘッダがサポートされています。 +2.0.31 以降、[RFC 7239](https://datatracker.ietf.org/doc/html/rfc7239) の `Forwarded` ヘッダがサポートされています。 有効にするためには、ヘッダ名を `secureHeaders` に追加する必要があります。 あなたのプロキシにそれを設定させることを忘れないで下さい。さもないと、エンド・ユーザが IP とプロトコルを盗み見ることが可能になります。 diff --git a/docs/guide-ja/runtime-responses.md b/docs/guide-ja/runtime-responses.md index cbbc10edadf..b63a61fb15f 100644 --- a/docs/guide-ja/runtime-responses.md +++ b/docs/guide-ja/runtime-responses.md @@ -230,11 +230,11 @@ public function actionDownload() この機能を使うために、[[yii\web\Response::xSendFile()]] を呼ぶことが出来ます。 次のリストは、よく使われるいくつかのウェブ・サーバにおいて `X-Sendfile` 機能を有効にする方法を要約するものです。 -- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile) -- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Lighttpd v1.5: [X-Sendfile](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Nginx: [X-Accel-Redirect](http://wiki.nginx.org/XSendfile) -- Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) +- Apache: [X-Sendfile](https://tn123.org/mod_xsendfile) +- Lighttpd v1.4: [X-LIGHTTPD-send-file](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Lighttpd v1.5: [X-Sendfile](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Nginx: [X-Accel-Redirect](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) +- Cherokee: [X-Sendfile and X-Accel-Redirect](https://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) ## レスポンスを送信する diff --git a/docs/guide-ja/runtime-sessions-cookies.md b/docs/guide-ja/runtime-sessions-cookies.md index 1a5cf03f53c..92eefef8b51 100644 --- a/docs/guide-ja/runtime-sessions-cookies.md +++ b/docs/guide-ja/runtime-sessions-cookies.md @@ -131,8 +131,8 @@ Yii は、また、さまざまなセッション・ストレージを実装す * [[yii\web\DbSession]]: セッション・データをデータベース・テーブルを使って保存する。 * [[yii\web\CacheSession]]: セッション・データを、構成された [キャッシュ・コンポーネント](caching-data.md#cache-components) の力を借りて、キャッシュを使って保存する。 -* [[yii\redis\Session]]: セッション・データを [redis](http://redis.io/) をストレージ媒体として使って保存する。 -* [[yii\mongodb\Session]]: セッション・データを [MongoDB](http://www.mongodb.org/) に保存する。 +* [[yii\redis\Session]]: セッション・データを [redis](https://redis.io/) をストレージ媒体として使って保存する。 +* [[yii\mongodb\Session]]: セッション・データを [MongoDB](https://www.mongodb.com/) に保存する。 これらのセッション・クラスは全て一連の同じ API メソッドをサポートします。 その結果として、セッションを使用するアプリケーション・コードを修正することなしに、セッション・ストレージ・クラスを切り替えることが出来ます。 @@ -374,20 +374,20 @@ return [ セキュリティを向上させるために、[[yii\web\Cookie::httpOnly]] および [[yii\web\Session::cookieParams]] の 'httponly' パラメータの デフォルト値は `true` に設定されています。 これによって、クライアント・サイド・スクリプトが保護されたクッキーにアクセスする危険が軽減されます (ブラウザがサポートしていれば)。 -詳細については、[httpOnly の wiki 記事](https://www.owasp.org/index.php/HttpOnly) を読んでください。 +詳細については、[httpOnly の wiki 記事](https://owasp.org/www-community/HttpOnly) を読んでください。 ### secure secure フラグの目的は、クッキーが平文で送信されることを防止することです。ブラウザが secure フラグをサポートしている場合、 リクエストが secure な接続 (TLS) によって送信される場合にのみクッキーがリクエストに含まれます。 -詳細については [Secure フラグの wiki 記事](https://www.owasp.org/index.php/SecureFlag) を参照して下さい。 +詳細については [Secure フラグの wiki 記事](https://owasp.org/www-community/controls/SecureCookieAttribute) を参照して下さい。 ### sameSite Yii 2.0.21 以降、[[yii\web\Cookie::sameSite]] 設定がサポートされています。これは PHP バージョン 7.3.0 以降を必要とします。 `sameSite` 設定の目的は CSRF (Cross-Site Request Forgery) 攻撃を防止することです。 ブラウザが `sameSite` 設定をサポートしている場合、指定されたポリシー ('Lax' または 'Strict') に従うクッキーだけが送信されます。 -詳細については [SameSite の wiki 記事](https://www.owasp.org/index.php/SameSite) を参照して下さい。 +詳細については [SameSite の wiki 記事](https://owasp.org/www-community/SameSite) を参照して下さい。 更なるセキュリティ強化のために、`sameSite` がサポートされていない PHP のバージョンで使われた場合には例外が投げられます。 この機能を PHP のバージョンに関わりなく使用する場合は、最初にバージョンをチェックして下さい。例えば、 ```php @@ -403,3 +403,4 @@ Yii 2.0.21 以降、[[yii\web\Cookie::sameSite]] 設定がサポートされて [PHP マニュアル](https://www.php.net/manual/ja/session.security.ini.php) で示されているように、`php.ini` にはセッションのセキュリティに関する重要な設定があります。 推奨される設定を必ず適用して下さい。特に、PHP インストールのデフォルトでは有効にされていない `session.use_strict_mode` を有効にして下さい。 +この設定は [[yii\web\Session::useStrictMode]] を使って設定することも出来ます。 diff --git a/docs/guide-ja/security-authentication.md b/docs/guide-ja/security-authentication.md index bb20efe823e..40ecc722b15 100644 --- a/docs/guide-ja/security-authentication.md +++ b/docs/guide-ja/security-authentication.md @@ -42,15 +42,16 @@ return [ 指定されたアクセス・トークンを使ってユーザ識別情報クラスのインスタンスを探します。 単一の秘密のトークンでユーザを認証する必要がある場合 (ステートレスな RESTful アプリケーションなどの場合) に、このメソッドが使用されます。 * [[yii\web\IdentityInterface::getId()|getId()]]: ユーザ識別情報クラスのインスタンスによって表されるユーザの ID を返します。 -* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: クッキー・ベースのログインを検証するのに使用されるキーを返します。 - このキーがログイン・クッキーに保存され、後でサーバ・サイドのキーと比較されて、 - ログイン・クッキーが有効であることが確認されます。 +* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: 自動ログインが有効にされている場合に、 + セッションと自動ログインを検証するキーを返します。 * [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]]: クッキー・ベースのログイン・キーを検証するロジックを実装します。 特定のメソッドが必要でない場合は、中身を空にして実装しても構いません。例えば、あなたのアプリケーションが純粋なステート・レス RESTful アプリケーションであるなら、 実装する必要があるのは [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] と [[yii\web\IdentityInterface::getId()|getId()]] だけであり、他のメソッドは全て中身を空にしておくことが出来ます。 +逆にあなたのアプリケーションがセッションのみの認証を使用する場合は、 +[[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] 以外の全てのメソッドを実装する必要があります。 次の例では、[[yii\web\User::identityClass|ユーザ識別情報クラス]] は、`user` データベース・テーブルと関連付けられた [アクティブ・レコード](db-active-record.md) クラスとして実装されています。 @@ -99,7 +100,7 @@ class User extends ActiveRecord implements IdentityInterface } /** - * @return string 現在のユーザの認証キー + * @return string|null 現在のユーザの認証キー */ public function getAuthKey() { @@ -108,7 +109,7 @@ class User extends ActiveRecord implements IdentityInterface /** * @param string $authKey - * @return bool 認証キーが現在のユーザに対して有効か否か + * @return bool|null 認証キーが現在のユーザに対して有効か否か */ public function validateAuthKey($authKey) { @@ -117,9 +118,8 @@ class User extends ActiveRecord implements IdentityInterface } ``` -前述のように、`getAuthKey()` と `validateAuthKey()` は、 -あなたのアプリケーションがクッキー・ベースのログイン機能を使用する場合にのみ実装する必要があります。 -この場合、次のコードを使って、各ユーザに対して認証キーを生成して、`user` テーブルに保存しておくことが出来ます。 +次のコードを使って、各ユーザに対して認証キーを生成して、 +`user` テーブルに保存しておくことが出来ます。 ```php class User extends ActiveRecord implements IdentityInterface diff --git a/docs/guide-ja/security-authorization.md b/docs/guide-ja/security-authorization.md index 84d1d023a1c..5e428433216 100644 --- a/docs/guide-ja/security-authorization.md +++ b/docs/guide-ja/security-authorization.md @@ -25,7 +25,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['login', 'logout', 'signup'], 'rules' => [ [ @@ -70,7 +70,7 @@ ACF による権限付与のプロセスにおいては、現在の実行コン ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, ... 'denyCallback' => function ($rule, $action) { throw new \Exception('このページにアクセスする権限がありません。'); @@ -129,7 +129,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['special-callback'], 'rules' => [ [ @@ -159,7 +159,7 @@ class SiteController extends Controller RBAC と他のもっと伝統的なアクセス制御スキーマとの比較に関する詳細については、 [Wiki 記事](http://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%99%E3%83%BC%E3%82%B9%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E5%BE%A1) を参照してください。 -Yii は、[NIST RBAC モデル](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf) に従って、一般的階層型 RBAC を実装しています。 +Yii は、[NIST RBAC モデル](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf) に従って、一般的階層型 RBAC を実装しています。 RBAC の機能は、[[yii\rbac\ManagerInterface|authManager]] [アプリケーション・コンポーネント](structure-application-components.md) を通じて提供されます。 RBAC を使用することには、二つの作業が含まれます。 @@ -538,7 +538,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'rules' => [ [ 'allow' => true, diff --git a/docs/guide-ja/security-best-practices.md b/docs/guide-ja/security-best-practices.md index 558967dc2cc..e5f121dc558 100644 --- a/docs/guide-ja/security-best-practices.md +++ b/docs/guide-ja/security-best-practices.md @@ -33,7 +33,7 @@ Yii においては、たいていの場合、同様のチェックを行うた このトピックについて更に読むべき文書: -- +- - @@ -46,9 +46,9 @@ JavaScript や SQL のコンテキストでは、対象となる文字は別の このトピックについて更に読むべき文書: -- -- -- +- +- +- SQL インジェクションを回避する @@ -117,7 +117,7 @@ $rowCount = $connection->createCommand($sql)->queryScalar(); このトピックについて更に読むべき文書: -- +- XSS を回避する @@ -151,7 +151,7 @@ HtmlPurifier の処理は非常に重いので、キャッシュを追加する このトピックについて更に読むべき文書: -- +- CSRF を回避する @@ -259,8 +259,8 @@ class ContactAction extends Action このトピックについて更に読むべき文書: -- -- +- +- ファイルの曝露を回避する @@ -288,8 +288,8 @@ class ContactAction extends Action このトピックについて更に読むべき文書: -- -- +- +- (A6 - Information Leakage and Improper Error Handling) TLS によるセキュアな接続を使う @@ -353,3 +353,29 @@ return [ > Note: 「ホスト・ヘッダ攻撃」に対する保護のためには、常に、フィルタの使用よりもウェブ・サーバの構成を優先すべきです。 [[yii\filters\HostControl]] は、サーバの構成が出来ない場合にだけ使うべきものです。 + +### SSL ピア検証を構成する + +SSL 証明書検証の問題、例えば : + +``` +cURL error 60: SSL certificate problem: unable to get local issuer certificate +``` + +または + +``` +stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed +``` + +を解決する方法については、典型的な誤解があります。SSL ピア検証を無効化するよう示唆する間違った情報が数多くありますが、決して従ってはいけません。 +そんなことをすれば、マン・イン・ザ・ミドル型の攻撃を可能にします。そうするのではなく、PHP を適切に構成すべきです。 + +1. [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem) をダウンロードする。 +2. php.ini に以下を追加する。 + ``` + openssl.cafile="/path/to/cacert.pem" + curl.cainfo="/path/to/cacert.pem". + ``` + +`cacert.pem` ファイルを最新に保つ必要があることに注意して下さい。 diff --git a/docs/guide-ja/security-passwords.md b/docs/guide-ja/security-passwords.md index 45b4f0caa11..f5be0859092 100644 --- a/docs/guide-ja/security-passwords.md +++ b/docs/guide-ja/security-passwords.md @@ -3,11 +3,11 @@ ほとんどの開発者はパスワードを平文テキストで保存してはいけないということを知っていますが、パスワードを `md5` や `sha1` でハッシュしてもまだ安全だと思っている開発者がたくさんいます。かつては、前述のハッシュ・アルゴリズムを使えば十分であった時もありましたが、 -現代のハードウェアをもってすれば、そのようなハッシュはブルート・フォース・アタックを使って非常に簡単に復元することが可能です。 +それらのハッシュや更に強力なハッシュでも、現代のハードウェアをもってすればブルート・フォース・アタックを使って非常に簡単にクラックすることが可能です。 最悪のシナリオ (アプリケーションに侵入された場合) であっても、ユーザのパスワードについて強化されたセキュリティを提供することが出来るように、 ブルート・フォース・アタックに対する耐性が強いハッシュ・アルゴリズムを使う必要があります。現在、最善の選択は `bcrypt` です。 -PHP では、[crypt 関数](https://secure.php.net/manual/ja/function.crypt.php) を使って `bcrypt` ハッシュを生成することが出来ます。 +PHP では、[crypt 関数](https://www.php.net/manual/ja/function.crypt.php) を使って `bcrypt` ハッシュを生成することが出来ます。 Yii は `crypt` を使ってハッシュを安全に生成し検証することを容易にするために、二つのヘルパ関数を提供しています。 ユーザが初めてパスワードを提供するとき (例えば、ユーザ登録の時) には、パスワードをハッシュする必要があります。 diff --git a/docs/guide-ja/start-databases.md b/docs/guide-ja/start-databases.md index 85ff7352906..a22fbaaaafc 100644 --- a/docs/guide-ja/start-databases.md +++ b/docs/guide-ja/start-databases.md @@ -51,7 +51,7 @@ INSERT INTO `country` VALUES ('US','United States',322976000); DB 接続を構成する ----------------- -先に進む前に、[PDO](https://secure.php.net/manual/en/book.pdo.php) PHP 拡張および使用しているデータベースの PDO ドライバ +先に進む前に、[PDO](https://www.php.net/manual/en/book.pdo.php) PHP 拡張および使用しているデータベースの PDO ドライバ (例えば、MySQL のための `pdo_mysql`) の両方をインストール済みであることを確認してください。 アプリケーションがリレーショナル・データベースを使う場合、これは基本的な必要条件です。 diff --git a/docs/guide-ja/start-forms.md b/docs/guide-ja/start-forms.md index fb22618dcff..12e55f102c2 100644 --- a/docs/guide-ja/start-forms.md +++ b/docs/guide-ja/start-forms.md @@ -129,7 +129,7 @@ class SiteController extends Controller その中で HTML フォームが (もし有れば) 検証エラーのメッセージとともに表示されます。 > Note: この簡単な例では、有効なデータ送信に対して単純に確認ページを表示しています。 - 実際の仕事では、[フォーム送信の諸問題](http://en.wikipedia.org/wiki/Post/Redirect/Get) を避けるために、 + 実際の仕事では、[フォーム送信の諸問題](https://en.wikipedia.org/wiki/Post/Redirect/Get) を避けるために、 [[yii\web\Controller::refresh()|refresh()]] または [[yii\web\Controller::redirect()|redirect()]] を使うことを考慮すべきです。 diff --git a/docs/guide-ja/start-hello.md b/docs/guide-ja/start-hello.md index cdf330d03b1..8806def5c61 100644 --- a/docs/guide-ja/start-hello.md +++ b/docs/guide-ja/start-hello.md @@ -88,7 +88,7 @@ use yii\helpers\Html; 上記のコードで `message` パラメータが出力される前に [[yii\helpers\Html::encode()|HTML-エンコード]] されていることに注意してください。 パラメータはエンド・ユーザから来るものであり、悪意のある JavaScript コードを埋め込まれて -[クロス・サイト・スクリプティング (XSS) 攻撃](http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) に使われうるものですから、 +[クロス・サイト・スクリプティング (XSS) 攻撃](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) に使われうるものですから、 脆弱性を防止するためにこうすることが必要です。 当然ながら、`say` ビューにはもっと多くのコンテントを入れても構いません。コンテントには、HTML タグ、平文テキスト、さらには PHP 文を含めることが出来ます。 diff --git a/docs/guide-ja/start-installation.md b/docs/guide-ja/start-installation.md index 0a53d4f84a0..e7b674cbd9b 100644 --- a/docs/guide-ja/start-installation.md +++ b/docs/guide-ja/start-installation.md @@ -85,7 +85,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic アーカイブ・ファイルから Yii をインストールするには、三つの手順を踏みます。 -1. [yiiframework.com](http://www.yiiframework.com/download/) からアーカイブ・ファイルをダウンロードします。 +1. [yiiframework.com](https://www.yiiframework.com/download/) からアーカイブ・ファイルをダウンロードします。 2. ダウンロードしたファイルをウェブ・アクセス可能なフォルダに展開します。 3. `config/web.php` ファイルを編集して、`cookieValidationKey` という構成情報の項目に秘密キーを入力します (Composer を使って Yii をインストールするときは、これは自動的に実行されます)。 @@ -114,9 +114,9 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic アセットをインストールする -------------------------- -Yii は、アセット (CSS および JavaScript) ライブラリのインストールについて [Bower](http://bower.io/) および/または [NPM](https://www.npmjs.org/) のパッケージに依存しています。 +Yii は、アセット (CSS および JavaScript) ライブラリのインストールについて [Bower](http://bower.io/) および/または [NPM](https://www.npmjs.com/) のパッケージに依存しています。 Yii はこれらのライブラリを取得するのに Composer を使って、PHP と CSS/JavaScript のパッケージ・バージョンを同時に解決できるようにしています。 -このことは、[asset-packagist.org](https://asset-packagist.org) または [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) を使用することによって達成されます。 +このことは、[asset-packagist.org](https://asset-packagist.org) または [composer asset plugin](https://github.com/fxpio/composer-asset-plugin) を使用することによって達成されます。 詳細は [アセットのドキュメント](structure-assets.md) を参照して下さい。 あなたは、アセットの管理をネイティブの Bower/NPM クライアントで行ったり、CND を使ったり、アセットのインストールを完全に避けたりしたいかも知れません。 @@ -140,7 +140,7 @@ Composer によるアセットのインストールを抑止するためには インストール完了後、あなたのウェブ・サーバを構成してください (次のセクションを参照してください)。 あるいは、プロジェクトの `web` ディレクトリで次のコマンドを実行して、 -[PHP の内蔵ウェブ・サーバ](https://secure.php.net/manual/ja/features.commandline.webserver.php) を使ってください。 +[PHP の内蔵ウェブ・サーバ](https://www.php.net/manual/ja/features.commandline.webserver.php) を使ってください。 ```bash php yii serve @@ -174,7 +174,7 @@ http://localhost:8080/ Yii の最低必要条件を満たすように PHP のインストールを構成しなければなりません。 最も重要なことは、PHP 5.4 以上でなければならないということです。最新の PHP 7 なら理想的です。 -また、アプリケーションがデータベースを必要とする場合は、[PDO PHP 拡張](https://secure.php.net/manual/ja/pdo.installation.php) および対応するデータベース・ドライバ (MySQL データベースのための `pdo_mysql` など) をインストールしなければなりません。 +また、アプリケーションがデータベースを必要とする場合は、[PDO PHP 拡張](https://www.php.net/manual/ja/pdo.installation.php) および対応するデータベース・ドライバ (MySQL データベースのための `pdo_mysql` など) をインストールしなければなりません。 ウェブ・サーバを構成する @@ -236,7 +236,7 @@ DocumentRoot "path/to/basic/web" ### 推奨される Nginx の構成 -[Nginx](http://wiki.nginx.org/) を使うためには、PHP を [FPM SAPI](https://secure.php.net/manual/ja/install.fpm.php) としてインストールしなければなりません。 +[Nginx](http://wiki.nginx.org/) を使うためには、PHP を [FPM SAPI](https://www.php.net/manual/ja/install.fpm.php) としてインストールしなければなりません。 下記の Nginx の設定を使うことができます。 `path/to/basic/web` の部分を `basic/web` の実際のパスに置き換え、`mysite.test` を実際のサーバのホスト名に置き換えてください。 diff --git a/docs/guide-ja/start-looking-ahead.md b/docs/guide-ja/start-looking-ahead.md index 9f0ef2056ad..bbdf9adec46 100644 --- a/docs/guide-ja/start-looking-ahead.md +++ b/docs/guide-ja/start-looking-ahead.md @@ -9,28 +9,28 @@ Gii をコード生成に使うと、ウェブ開発のプロセスの大部分 このセクションでは、Yii フレームワークを使うときの生産性を更に高めるために利用できるリソースについてまとめます。 * ドキュメント - - [決定版ガイド](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [決定版ガイド](https://www.yiiframework.com/doc-2.0/guide-README.html): 名前が示すように、このガイドは Yii がどのように動作すべきものかを正確に記述し、Yii を使用するについての全般的な手引きを提供するものです。 これは唯一の最も重要な Yii のチュートリアルであり、Yii のコードを少しでも書く前にあなたが読まなければならないものです。 - - [クラス・リファレンス](http://www.yiiframework.com/doc-2.0/index.html): + - [クラス・リファレンス](https://www.yiiframework.com/doc-2.0/index.html): これは Yii によって提供される全てのクラスの使用法を記述しています。 主として、コードを書いている時に、特定のクラス、メソッド、プロパティについて理解したい場合に読まれるべきものです。 クラス・リファレンスの使用は、フレームワーク全体の文脈的な理解が出来てからにするのが最善です。 - - [Wiki の記事](http://www.yiiframework.com/wiki/?tag=yii2): + - [Wiki の記事](https://www.yiiframework.com/wiki/?tag=yii2): Wiki の記事は、Yii のユーザが自身の経験に基づいて書いたものです。 ほとんどの記事は、料理本のレシピのように書かれており、特定の問題を Yii を使って解決する方法を示しています。 これらの記事の品質は決定版ガイドほどには良くないかもしれませんが、より広範なトピックをカバーしていることと、たいていは即座に使えるソリューションを提供してくれることにおいて有用なものです。 - - [書籍](http://www.yiiframework.com/doc/) -* [エクステンション](http://www.yiiframework.com/extensions/): + - [書籍](https://www.yiiframework.com/books/) +* [エクステンション](https://www.yiiframework.com/extensions/): Yii は、ユーザによって作られた数千におよぶエクステンションのライブラリを誇りとしています。 エクステンションはあなたのアプリケーションに簡単に組み込むことが出来、そうすることでアプリケーションの開発作業をより一層速くて簡単なものにします。 * コミュニティ - - フォーラム: - - IRC チャット: freenode ネットワーク () の #yii チャンネル + - フォーラム: + - IRC チャット: Libera ネットワーク () の #yii チャンネル - Slack チャンネル: - Gitter チャット: - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide-ja/start-prerequisites.md b/docs/guide-ja/start-prerequisites.md index ad6b5845a04..8aeac1fb64a 100644 --- a/docs/guide-ja/start-prerequisites.md +++ b/docs/guide-ja/start-prerequisites.md @@ -4,8 +4,8 @@ Yii の学習曲線は他の PHP フレームワークほど急峻ではあり ## PHP -Yii は PHP フレームワークですから、必ず [言語リファレンスを読んで理解する](https://secure.php.net/manual/ja/langref.php) ようにして下さい。 -Yii を使って開発するときはオブジェクト指向の流儀でコードを書くことになりますから、必ず、[クラスとオブジェクト](https://secure.php.net/manual/ja/language.oop5.basic.php) および [名前空間](https://secure.php.net/manual/ja/language.namespaces.php) には慣れ親しんでおいて下さい。 +Yii は PHP フレームワークですから、必ず [言語リファレンスを読んで理解する](https://www.php.net/manual/ja/langref.php) ようにして下さい。 +Yii を使って開発するときはオブジェクト指向の流儀でコードを書くことになりますから、必ず、[クラスとオブジェクト](https://www.php.net/manual/ja/language.oop5.basic.php) および [名前空間](https://www.php.net/manual/ja/language.namespaces.php) には慣れ親しんでおいて下さい。 ## オブジェクト指向プログラミング diff --git a/docs/guide-ja/start-workflow.md b/docs/guide-ja/start-workflow.md index 5a0a61293e4..f922b421f94 100644 --- a/docs/guide-ja/start-workflow.md +++ b/docs/guide-ja/start-workflow.md @@ -42,7 +42,7 @@ Yii のインストールが終ると、実際に動く Yii のアプリケー アプリケーションにとって最も重要なディレクトリとファイルは (アプリケーションのルート・ディレクトリが `basic` だと仮定すると) 以下の通りです。 -``` +```js basic/ アプリケーションのベース・パス composer.json Composer によって使用される。パッケージ情報を記述 config/ アプリケーションその他の構成情報を格納 diff --git a/docs/guide-ja/structure-applications.md b/docs/guide-ja/structure-applications.md index e8f369db35c..f509c21470c 100644 --- a/docs/guide-ja/structure-applications.md +++ b/docs/guide-ja/structure-applications.md @@ -356,7 +356,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; #### [[yii\base\Application::timeZone|timeZone]] このプロパティは、PHP ランタイムのデフォルト・タイム・ゾーンを設定する代替手段として提供されています。 -このプロパティを構成することによって、本質的には PHP 関数 [date_default_timezone_set()](https://secure.php.net/manual/ja/function.date-default-timezone-set.php) を呼び出すことになります。 +このプロパティを構成することによって、本質的には PHP 関数 [date_default_timezone_set()](https://www.php.net/manual/ja/function.date-default-timezone-set.php) を呼び出すことになります。 例えば、 ```php diff --git a/docs/guide-ja/structure-assets.md b/docs/guide-ja/structure-assets.md index f0f9083bb22..7a96e7b8467 100644 --- a/docs/guide-ja/structure-assets.md +++ b/docs/guide-ja/structure-assets.md @@ -79,7 +79,7 @@ class AppAsset extends AssetBundle 実際のファイルのパスは、この相対パスの前に [[yii\web\AssetManager::basePath]] を付けることによって決定されます。 また、実際の URL は、この相対パスの前に [[yii\web\AssetManager::baseUrl]] を付けることによって決定されます。 - 外部の JavaScript ファイルを表す絶対 URL。 - 例えば、`http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` や + 例えば、`https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` や `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` など。 * [[yii\web\AssetBundle::depends|depends]]: このバンドルが依存しているアセット・バンドルの名前をリストする配列です (バンドルの依存関係については、すぐ後で説明します)。 @@ -201,13 +201,13 @@ class FontAwesomeAsset extends AssetBundle } ``` -上記の例は、["fontawesome" パッケージ](http://fontawesome.io/) のためのアセット・バンドルを定義するものです。 +上記の例は、["fontawesome" パッケージ](https://fontawesome.com/) のためのアセット・バンドルを定義するものです。 発行オプション `only` を指定して、`fonts` と `css` サブ・ディレクトリだけが発行されるようにしています。 ### Bower と NPM のアセットのインストール -ほとんどの JavaScript/CSS パッケージは、[Bower](http://bower.io/) および/または [NPM](https://www.npmjs.org/) によって管理されています。 +ほとんどの JavaScript/CSS パッケージは、[Bower](https://bower.io/) および/または [NPM](https://www.npmjs.com/) によって管理されています。 PHP の世界には PHP の依存を管理する Composer がありますが、PHP のパッケージと全く同じように `composer.json` を使って Bower のパッケージも NPM のパッケージもロードすることが可能です。 @@ -257,7 +257,7 @@ asset-packagist と異なって、composer-asset-plugin はアプリケーショ composer global require "fxp/composer-asset-plugin:^1.4.1" ``` -このコマンドによって [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) がグローバルにインストールされ、 +このコマンドによって [composer asset plugin](https://github.com/fxpio/composer-asset-plugin) がグローバルにインストールされ、 Bower と NPM パッケージの依存関係を Composer によって管理することが出来るようになります。 プラグインがインストールされた後は、あなたのコンピュータ上の全てのプロジェクトが `composer.json` を通じて Bower と NPM パッケージをサポートすることが出来ます。 @@ -610,14 +610,14 @@ class AppAsset extends AssetBundle Yii はファイル名の拡張子を使って、アセットが使っている拡張構文を識別します。 デフォルトでは、下記の構文とファイル名拡張子を認識します。 -- [LESS](http://lesscss.org/): `.less` -- [SCSS](http://sass-lang.com/): `.scss` -- [Stylus](http://learnboost.github.io/stylus/): `.styl` -- [CoffeeScript](http://coffeescript.org/): `.coffee` -- [TypeScript](http://www.typescriptlang.org/): `.ts` +- [LESS](https://lesscss.org/): `.less` +- [SCSS](https://sass-lang.com/): `.scss` +- [Stylus](https://stylus-lang.com/): `.styl` +- [CoffeeScript](https://coffeescript.org/): `.coffee` +- [TypeScript](https://www.typescriptlang.org/): `.ts` Yii はインストールされたプリ・プロセッサ・ツールに頼ってアセットを変換します。 -例えば、[LESS](http://lesscss.org/) を使うためには、`lessc` プリ・プロセッサ・コマンドをインストールしなければなりません。 +例えば、[LESS](https://lesscss.org/) を使うためには、`lessc` プリ・プロセッサ・コマンドをインストールしなければなりません。 下記のように [[yii\web\AssetManager::converter]] を構成することで、 プリ・プロセッサ・コマンドとサポートされる拡張構文をカスタマイズすることが出来ます。 diff --git a/docs/guide-ja/structure-entry-scripts.md b/docs/guide-ja/structure-entry-scripts.md index 39e88403c68..45e600def34 100644 --- a/docs/guide-ja/structure-entry-scripts.md +++ b/docs/guide-ja/structure-entry-scripts.md @@ -57,9 +57,9 @@ $config = require __DIR__ . '/../config/web.php'; /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-ja/structure-extensions.md b/docs/guide-ja/structure-extensions.md index 7de1c538093..49d9a152937 100644 --- a/docs/guide-ja/structure-extensions.md +++ b/docs/guide-ja/structure-extensions.md @@ -75,7 +75,7 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) 2. もし有れば、エクステンションによって提供されているクラス・オートローダをインストールする。 3. 指示に従って、依存するエクステンションを全てダウンロードしインストールする。 -エクステンションがクラス・オートローダを持っていなくても、[PSR-4 標準](http://www.php-fig.org/psr/psr-4/) に従っている場合は、Yii によって提供されているクラス・オートローダを使ってエクステンションのクラスをオートロードすることが出来ます。 +エクステンションがクラス・オートローダを持っていなくても、[PSR-4 標準](https://www.php-fig.org/psr/psr-4/) に従っている場合は、Yii によって提供されているクラス・オートローダを使ってエクステンションのクラスをオートロードすることが出来ます。 必要なことは、エクステンションのルート・ディレクトリのための [ルート・エイリアス](concept-aliases.md#defining-aliases) を宣言することだけです。 例えば、エクステンションを `vendor/mycompany/myext` というディレクトリにインストールしたと仮定します。 そして、エクステンションのクラスは `myext` 名前空間の下にあるとします。 @@ -127,9 +127,9 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) "license": "BSD-3-Clause", "support": { "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki/", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "authors": [ @@ -184,8 +184,8 @@ Yii のアプリケーションは、このファイルによって、どんな それぞれの依存パッケージについて、適切なバージョン制約 (例えば `1.*` や `@stable`) を指定することも忘れてはなりません。 あなたのエクステンションを安定バージョンとしてリリースする場合は、安定した依存パッケージを使ってください。 -たいていの JavaScript/CSS パッケージは、Composer ではなく、[Bower](http://bower.io/) および/または [NPM](https://www.npmjs.org/) を使って管理されています。 -Yii は [Composer アセット・プラグイン](https://github.com/francoispluchino/composer-asset-plugin) を使って、この種のパッケージを Composer によって管理することを可能にしています。 +たいていの JavaScript/CSS パッケージは、Composer ではなく、[Bower](https://bower.io/) および/または [NPM](https://www.npmjs.com/) を使って管理されています。 +Yii は [Composer アセット・プラグイン](https://github.com/fxpio/composer-asset-plugin) を使って、この種のパッケージを Composer によって管理することを可能にしています。 あなたのエクステンションが Bower パッケージに依存している場合でも、次のように、 `composer.json` に依存パッケージをリストアップすることが簡単に出来ます。 @@ -240,7 +240,7 @@ Composer が Bower または NPM のパッケージをインストールする #### 名前空間 名前の衝突を避けて、エクステンションの中のクラスをオートロード可能にするために、名前空間を使うべきであり、 -エクステンションの中のクラスには [PSR-4 標準](http://www.php-fig.org/psr/psr-4/) または [PSR-0 標準](http://www.php-fig.org/psr/psr-0/) +エクステンションの中のクラスには [PSR-4 標準](https://www.php-fig.org/psr/psr-4/) または [PSR-0 標準](https://www.php-fig.org/psr/psr-0/) に従った名前を付けるべきです。 あなたのクラスの名前空間は `vendorName\extensionName` で始まるべきです。 @@ -351,7 +351,7 @@ Yii はテストのサポートを提供しており、それよって、単体 #### バージョン管理 エクステンションのリリースごとにバージョン番号 (例えば `1.0.1`) を付けるべきです。 -どのようなバージョン番号を付けるべきかを決定するときは、[セマンティック・バージョニング](http://semver.org) のプラクティスに従うことを推奨します。 +どのようなバージョン番号を付けるべきかを決定するときは、[セマンティック・バージョニング](https://semver.org) のプラクティスに従うことを推奨します。 #### リリース(公開) @@ -368,7 +368,7 @@ Composer レポジトリに新しいリリースについて通知するだけ * パッケージのルート・ディレクトリに readme ファイル: あなたのエクステンションが何をするものか、 そして、どのようにインストールして使うものかを説明するものです。 - [Markdown](http://daringfireball.net/projects/markdown/) 形式で書いて、`readme.md` という名前にすることを推奨します。 + [Markdown](https://daringfireball.net/projects/markdown/) 形式で書いて、`readme.md` という名前にすることを推奨します。 * パッケージのルート・ディレクトリに changelog ファイル: それぞれのリリースで何が変ったかを一覧表示するものです。 このファイルは Markdown 形式で書いて `changelog.md` と名付けることが出来ます。 * パッケージのルート・ディレクトリに upgrade ファイル: エクステンションの古いリリースからのアップグレード方法について説明するものです。 @@ -383,7 +383,7 @@ Composer レポジトリに新しいリリースについて通知するだけ `yiisoft/yii2-apidoc` エクステンションが、コードのコメントに基づいて綺麗な API ドキュメントを生成するツールを提供しています。 > Info: これは要求ではありませんが、あなたのエクステンションも一定のコーディング・スタイルを守るのが良いと思います。 - [コア・フレームワーク・コード・スタイル](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style) を参照してください。 + [コア・フレームワーク・コード・スタイル](https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md) を参照してください。 ## コア・エクステンション @@ -398,15 +398,13 @@ Yii は下記のコア・エクステンション (または ["公式エクス - [yiisoft/yii2-authclient](https://github.com/yiisoft/yii2-authclient): Facebook OAuth2 クライアント、GitHub OAuth2 クライアントなど、よく使われる一連の auth クライアントを提供します。 - [yiisoft/yii2-bootstrap](https://github.com/yiisoft/yii2-bootstrap): - [Bootstrap](http://getbootstrap.com/) のコンポーネントとプラグインをカプセル化した一連のウィジェットを提供します。 -- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception) (非推奨): - [Codeception](http://codeception.com/) に基づくテストのサポートを提供します。 + [Bootstrap](https://getbootstrap.com/) のコンポーネントとプラグインをカプセル化した一連のウィジェットを提供します。 - [yiisoft/yii2-debug](https://github.com/yiisoft/yii2-debug): Yii アプリケーションのデバッグのサポートを提供します。 このエクステンションが使われると、全てのページの末尾にデバッガ・ツールバーが表示されます。 このエクステンションは、より詳細なデバッグ情報を表示する一連のスタンドアロン・ページも提供します。 - [yiisoft/yii2-elasticsearch](https://github.com/yiisoft/yii2-elasticsearch): - [Elasticsearch](http://www.elasticsearch.org/) の使用に対するサポートを提供します。 + [Elasticsearch](https://www.elastic.co/) の使用に対するサポートを提供します。 基本的なクエリ/サーチのサポートを含むだけでなく、Elasticsearch にアクティブ・レコードを保存することを可能にする [アクティブ・レコード](db-active-record.md) パターンをも実装しています。 - [yiisoft/yii2-faker](https://github.com/yiisoft/yii2-faker): @@ -417,29 +415,29 @@ Yii は下記のコア・エクステンション (または ["公式エクス - [yiisoft/yii2-httpclient](https://github.com/yiisoft/yii2-httpclient): HTTP クライアントを提供します。 - [yiisoft/yii2-imagine](https://github.com/yiisoft/yii2-imagine): - [Imagine](http://imagine.readthedocs.org/) に基づいて、使われることの多い画像操作機能を提供します。 + [Imagine](https://imagine.readthedocs.org/) に基づいて、使われることの多い画像操作機能を提供します。 - [yiisoft/yii2-jui](https://github.com/yiisoft/yii2-jui): - [JQuery UI](http://jqueryui.com/) のインタラクションとウィジェットをカプセル化した一連のウィジェットを提供します。 + [JQuery UI](https://jqueryui.com/) のインタラクションとウィジェットをカプセル化した一連のウィジェットを提供します。 - [yiisoft/yii2-mongodb](https://github.com/yiisoft/yii2-mongodb): - [MongoDB](http://www.mongodb.org/) の使用に対するサポートを提供します。 + [MongoDB](https://www.mongodb.com/) の使用に対するサポートを提供します。 基本的なクエリ、アクティブ・レコード、マイグレーション、キャッシュ、コード生成などの機能を含みます。 - [yiisoft/yii2-queue](https://www.yiiframework.com/extension/yiisoft/yii2-queue): キューによるタスクの非同期実行のサポートを提供します。 データベース、Redis、RabbitMQ、AMQP、Beanstalk および Gearman によるキューをサポートしています。 - [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis): - [redis](http://redis.io/) の使用に対するサポートを提供します。 + [redis](https://redis.io/) の使用に対するサポートを提供します。 基本的なクエリ、アクティブ・レコード、キャッシュなどの機能を含みます。 - [yiisoft/yii2-shell](https://www.yiiframework.com/extension/yiisoft/yii2-shell): - [psysh](http://psysh.org/) に基づくイタラクティブなシェルを提供します。 + [psysh](https://psysh.org/) に基づくイタラクティブなシェルを提供します。 - [yiisoft/yii2-smarty](https://github.com/yiisoft/yii2-smarty): - [Smarty](http://www.smarty.net/) に基づいたテンプレート・エンジンを提供します。 + [Smarty](https://www.smarty.net/) に基づいたテンプレート・エンジンを提供します。 - [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx): [Sphinx](http://sphinxsearch.com) の使用に対するサポートを提供します。 基本的なクエリ、アクティブ・レコード、コード生成などの機能を含みます。 - [yiisoft/yii2-swiftmailer](https://github.com/yiisoft/yii2-swiftmailer): [swiftmailer](http://swiftmailer.org/) に基づいたメール送信機能を提供します。 - [yiisoft/yii2-twig](https://github.com/yiisoft/yii2-twig): - [Twig](http://twig.sensiolabs.org/) に基づいたテンプレート・エンジンを提供します。 + [Twig](https://twig.symfony.com/) に基づいたテンプレート・エンジンを提供します。 下記の公式エクステンションは Yii 2.1 以上のためのものです。 これらは、Yii 2.0 ではコア・フレームワークに含まれていますので、インストールする必要はありません。. @@ -449,7 +447,7 @@ Yii は下記のコア・エクステンション (または ["公式エクス - [yiisoft/yii2-jquery](https://www.yiiframework.com/extension/yiisoft/yii2-jquery): [jQuery](https://jquery.com/) のサポートを提供します。 - [yiisoft/yii2-maskedinput](https://www.yiiframework.com/extension/yiisoft/yii2-maskedinput): - [jQuery Input Mask plugin](http://robinherbots.github.io/Inputmask/) に基づいて、マスクト・インプットを提供します。 + [jQuery Input Mask plugin](https://robinherbots.github.io/Inputmask/) に基づいて、マスクト・インプットを提供します。 - [yiisoft/yii2-mssql](https://www.yiiframework.com/extension/yiisoft/yii2-mssql): [MSSQL](https://www.microsoft.com/sql-server/) を使うためのサポートを提供します。 - [yiisoft/yii2-oracle](https://www.yiiframework.com/extension/yiisoft/yii2-oracle): diff --git a/docs/guide-ja/structure-filters.md b/docs/guide-ja/structure-filters.md index 1eb078b3d6c..8cfd9236ff5 100644 --- a/docs/guide-ja/structure-filters.md +++ b/docs/guide-ja/structure-filters.md @@ -121,7 +121,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['create', 'update'], 'rules' => [ // 認証されたユーザに許可する @@ -157,7 +157,7 @@ public function behaviors() { return [ 'basicAuth' => [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ], ]; } @@ -183,7 +183,7 @@ public function behaviors() { return [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -210,7 +210,7 @@ use yii\web\Response; [ 'bootstrap' => [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -241,7 +241,7 @@ public function behaviors() { return [ [ - 'class' => HttpCache::className(), + 'class' => HttpCache::class, 'only' => ['index'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); @@ -269,11 +269,11 @@ public function behaviors() { return [ 'pageCache' => [ - 'class' => PageCache::className(), + 'class' => PageCache::class, 'only' => ['index'], 'duration' => 60, 'dependency' => [ - 'class' => DbDependency::className(), + 'class' => DbDependency::class, 'sql' => 'SELECT COUNT(*) FROM post', ], 'variations' => [ @@ -307,7 +307,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'index' => ['get'], 'view' => ['get'], @@ -339,7 +339,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, ], ], parent::behaviors()); } @@ -366,7 +366,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], @@ -387,7 +387,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], diff --git a/docs/guide-ja/structure-models.md b/docs/guide-ja/structure-models.md index 6eb85db4051..4993c6a5dac 100644 --- a/docs/guide-ja/structure-models.md +++ b/docs/guide-ja/structure-models.md @@ -37,8 +37,8 @@ echo $model->name; ``` また、配列の要素にアクセスするようして、属性にアクセスすることも出来ます。 -これは、[[yii\base\Model]] が [ArrayAccess インタフェイス](https://secure.php.net/manual/ja/class.arrayaccess.php) と -[Traversable インタフェイス](https://secure.php.net/manual/ja/class.traversable.php) をサポートしている恩恵です。 +これは、[[yii\base\Model]] が [ArrayAccess インタフェイス](https://www.php.net/manual/ja/class.arrayaccess.php) と +[Traversable インタフェイス](https://www.php.net/manual/ja/class.traversable.php) をサポートしている恩恵です。 ```php $model = new \app\models\ContactForm; @@ -198,7 +198,7 @@ class User extends ActiveRecord > Info: 上記の例と後続の例では、モデル・クラスは [[yii\db\ActiveRecord]] を拡張するものとなっています。 というのは、複数のシナリオを使用することは、通常は、[アクティブ・レコード](db-active-record.md) クラスで発生するからです。 -`seanarios()` メソッドは、キーがシナリオの名前であり、値が対応する *アクティブな属性* である配列を返します。 +`scenarios()` メソッドは、キーがシナリオの名前であり、値が対応する *アクティブな属性* である配列を返します。 アクティブな属性とは、[一括代入](#massive-assignment) することが出来て、[検証](#validation-rules) の対象になる属性です。 上記の例では、`login` シナリオにおいては `username` と `password` の属性がアクティブであり、 一方、`register` シナリオにおいては、`username` と `password` に加えて `email` もアクティブです。 @@ -477,8 +477,8 @@ public function fields() ]; } -// いくつかのフィールドを除外する方法。親の実装を継承しつつ、公開すべきでないフィールドは -// 除外したいときに適している。 +// いくつかのフィールドを除外する方法。親の実装を継承しつつ、公開すべきでないフィールドを +// 除外したいときに最適。 public function fields() { $fields = parent::fields(); diff --git a/docs/guide-ja/structure-modules.md b/docs/guide-ja/structure-modules.md index f94f2bdd28f..99a16445222 100644 --- a/docs/guide-ja/structure-modules.md +++ b/docs/guide-ja/structure-modules.md @@ -14,7 +14,7 @@ このディレクトリの中に、ちょうどアプリケーションの場合と同じように、`controllers`、`models`、`views` のようなサブ・ディレクトリが存在して、コントローラ、モデル、ビュー、その他のコードを収納しています。 次の例は、モジュール内の中身を示すものです。 -``` +```js forum/ Module.php モジュール・クラス・ファイル controllers/ コントローラ・クラス・ファイルを含む diff --git a/docs/guide-ja/structure-overview.md b/docs/guide-ja/structure-overview.md index b988955d777..50ac621d0d6 100644 --- a/docs/guide-ja/structure-overview.md +++ b/docs/guide-ja/structure-overview.md @@ -1,7 +1,7 @@ 概要 ==== -Yii のアプリケーションは [モデル・ビュー・コントローラ (MVC)](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャ・パターンに従って編成されています。 +Yii のアプリケーションは [モデル・ビュー・コントローラ (MVC)](https://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャ・パターンに従って編成されています。 [モデル](structure-models.md) は、データ、ビジネス・ロジック、規則を表現します。 [ビュー](structure-views.md) は、モデルの出力表現です。 そして [コントローラ](structure-controllers.md) は入力を受け取って、それを [モデル](structure-models.md) と [ビュー](structure-views.md) のためのコマンドに変換します。 diff --git a/docs/guide-ja/structure-views.md b/docs/guide-ja/structure-views.md index c2e4645c629..5b427ed0e26 100644 --- a/docs/guide-ja/structure-views.md +++ b/docs/guide-ja/structure-views.md @@ -1,7 +1,7 @@ ビュー ====== -ビューは [MVC](http://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。 +ビューは [MVC](https://ja.wikipedia.org/wiki/Model_View_Controller) アーキテクチャの一部を成すものです。 ビューはエンド・ユーザにデータを表示することに責任を持つコードです。 ウェブ・アプリケーションにおいては、ビューは、通常、*ビュー・テンプレート* の形式、すなわち、 主として HTML コードと表示目的の PHP コードを含む PHP スクリプト・ファイルとして作成されます。 @@ -51,7 +51,7 @@ $this->title = 'ログイン'; ### セキュリティ HTML ページを生成するビューを作成するときは、エンド・ユーザから受け取るデータを表示する前にエンコード および/または フィルタすることが重要です。 -そうしなければ、あなたのアプリケーションは [クロス・サイト・スクリプティング](http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) 攻撃を +そうしなければ、あなたのアプリケーションは [クロス・サイト・スクリプティング](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) 攻撃を こうむるおそれがあります。 プレーン・テキストを表示するためには、まず [[yii\helpers\Html::encode()]] を呼んでエンコードします。 @@ -544,7 +544,7 @@ Yii は舞台裏で二つのステップを踏んで、特定のコントロー * [フラグメント・キャッシュ](caching-fragment.md): ウェブ・ページの中の断片をキャッシュすることを可能にします。 * [クライアント・スクリプトの取り扱い](output-client-scripts.md): CSS と JavaScript の登録とレンダリングをサポートします。 * [アセット・バンドルの取り扱い](structure-assets.md): [アセット・バンドル](structure-assets.md) の登録とレンダリングをサポートします。 -* [代替のテンプレート・エンジン](tutorial-template-engines.md): [Twig](http://twig.sensiolabs.org/)、[Smarty](http://www.smarty.net/) など、 +* [代替のテンプレート・エンジン](tutorial-template-engines.md): [Twig](https://twig.symfony.com/)、[Smarty](https://www.smarty.net/) など、 他のテンプレート・エンジンを使用することを可能にします。 次に挙げるマイナーではあっても有用な諸機能は、ウェブ・ページを開発するときに頻繁に使用するでしょう。 @@ -616,14 +616,14 @@ $this->registerLinkTag([ 'title' => 'Yii ライブ・ニューズ', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` 上記のコードは、次の結果になります。 ```html - + ``` [[yii\web\View::registerMetaTag()|registerMetaTag()]] と同じように、[[yii\web\View::registerLinkTag()|registerLinkTag()]] を呼ぶときにキーを指定すると、 diff --git a/docs/guide-ja/structure-widgets.md b/docs/guide-ja/structure-widgets.md index 0d30b5a075f..2230ebbad91 100644 --- a/docs/guide-ja/structure-widgets.md +++ b/docs/guide-ja/structure-widgets.md @@ -67,7 +67,7 @@ use yii\helpers\Html; 返されたウィジェットのインスタンスを使って、ウィジェットのコンテントを構築することが出来ます。 > Note: いくつかのウィジェットは、[[yii\base\Widget::end()]] が呼ばれるときに囲んだコンテンツを調整するため、 -> [出力バッファリング](https://secure.php.net/manual/ja/book.outcontrol.php) を使用します。 +> [出力バッファリング](https://www.php.net/manual/ja/book.outcontrol.php) を使用します。 > この理由から、[[yii\base\Widget::begin()]] と [[yii\base\Widget::end()]] の呼び出しは、同じビュー・ファイルの中で発生するものと想定されています。 > この規則に従わない場合は、予期しない出力結果が生じ得ます。 diff --git a/docs/guide-ja/test-acceptance.md b/docs/guide-ja/test-acceptance.md index 0ca8ea241fe..5f0096defd8 100644 --- a/docs/guide-ja/test-acceptance.md +++ b/docs/guide-ja/test-acceptance.md @@ -6,8 +6,8 @@ 受入テストは Codeception フレームワークの助けを借りて実装されています。Codeception フレームワークには優れたドキュメントがありますので、参照して下さい。 -- [Codeception for Yii framework](http://codeception.com/for/yii) -- [Codeception Acceptance Tests](http://codeception.com/docs/03-AcceptanceTests) +- [Codeception for Yii framework](https://codeception.com/for/yii) +- [Codeception Acceptance Tests](https://codeception.com/docs/03-AcceptanceTests) ## ベーシック・テンプレート、アドバンスト・テンプレートのテストを実行する diff --git a/docs/guide-ja/test-environment-setup.md b/docs/guide-ja/test-environment-setup.md index c999bc0f664..4c62e24bfea 100644 --- a/docs/guide-ja/test-environment-setup.md +++ b/docs/guide-ja/test-environment-setup.md @@ -17,7 +17,7 @@ Yii 2 は [`Codeception`](https://github.com/Codeception/Codeception) テスト Codeception をインストールすることが出来ます。 ``` -composer require codeception/codeception -composer require codeception/specify -composer require codeception/verify +composer require --dev codeception/codeception +composer require --dev codeception/specify +composer require --dev codeception/verify ``` diff --git a/docs/guide-ja/test-fixtures.md b/docs/guide-ja/test-fixtures.md index 5f87cf75567..e7f1323f771 100644 --- a/docs/guide-ja/test-fixtures.md +++ b/docs/guide-ja/test-fixtures.md @@ -130,7 +130,7 @@ class UserProfileTest extends \Codeception\Test\Unit { return [ 'profiles' => [ - 'class' => UserProfileFixture::className(), + 'class' => UserProfileFixture::class, // フィクスチャ・データは tests/_data/user.php に配置されている 'dataFile' => codecept_data_dir() . 'user.php' ], diff --git a/docs/guide-ja/tutorial-core-validators.md b/docs/guide-ja/tutorial-core-validators.md index 100c1c1e51b..8379daf470b 100644 --- a/docs/guide-ja/tutorial-core-validators.md +++ b/docs/guide-ja/tutorial-core-validators.md @@ -82,7 +82,7 @@ public function rules() このバリデータが属性を検証するのに使用されるとき、このプロパティのデフォルト値はその属性の名前に接尾辞 `_repeat` を付けた名前になります。 例えば、検証される属性が `password` であれば、このプロパティのデフォルト値は `password_repeat` となります。 -- `compareValue`: 入力値が比較される定数値。 +- `compareValue`: 入力値が比較される定数値(または値を返すクロージャ)。 このプロパティと `compareAttribute` の両方が指定された場合は、このプロパティが優先されます。 - `operator`: 比較演算子。デフォルト値は `==` で、入力値が `compareAttribute` の値または `compareValue` と等しいことを検証することを意味します。 次の演算子がサポートされています。 @@ -139,10 +139,10 @@ compare バリデータは、文字列や数値を比較するためにしか使 [[yii\validators\DateValidator::timestampAttribute|timestampAttribute]] によって指定された属性に保存することも出来ます。 - `format`: 検証される値が従っているべき日付/時刻の書式。 - これには [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax) + これには [ICU manual](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax) で記述されている日付/時刻のパターンを使うことが出来ます。 あるいは、PHP の `Datetime` クラスによって認識される書式に接頭辞 `php:` を付けた文字列でも構いません。 - サポートされている書式については、 を参照してください。 + サポートされている書式については、 を参照してください。 このプロパティが設定されていないときは、`Yii::$app->formatter->dateFormat` の値を取ります。 - `timestampAttribute`: このバリデータが、入力された日付/時刻から変換した UNIX タイムスタンプを代入することが出来る属性の名前。 @@ -156,6 +156,7 @@ compare バリデータは、文字列や数値を比較するためにしか使 `timestampAttribute` を使う場合、入力値が UNIX タイムスタンプに変換されること、そして、UNIX タイムスタンプは定義により UTC であることに注意して下さい。 すなわち、[[yii\validators\DateValidator::timeZone|入力のタイム・ゾーン]] から UTC への変換が実行されます。 +(この動作は、2.0.39 以降では、[[yii\validators\DateValidator::$defaultTimeZone|$defaultTimeZone]] を設定して変更することが出来ます) - バージョン 2.0.4 以降では、タイムスタンプの [[yii\validators\DateValidator::$min|最小値]] または [[yii\validators\DateValidator::$max|最大値]] を指定することも出来ます。 @@ -191,8 +192,8 @@ compare バリデータは、文字列や数値を比較するためにしか使 このバリデータはデータを検証しません。 その代りに、検証される属性が空のときに、その属性にデフォルト値を割り当てます。 -- `value`: デフォルト値、または、デフォルト値を返す PHP コーラブル。 - 検証される属性が空のときにこのデフォルト値が割り当てられます。PHP コーラブルのシグニチャは、次のものでなければなりません。 +- `value`: デフォルト値、または、デフォルト値をコールバックとして返すクロージャ。 + 検証される属性が空のときにこの値が割り当てられます。クロージャのシグニチャは、次のものでなければなりません。 ```php function foo($model, $attribute) { @@ -270,24 +271,49 @@ function foo($model, $attribute) { ```php [ // a1 の入力値が a1 のカラムに存在する必要がある + // すなわち、a1 = 1 は、"a1" カラムに 1 の値が存在する場合に有効 ['a1', 'exist'], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => 'a1'], + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a1']], // a1 の入力値が a2 のカラムに存在する必要がある + // すなわち、a1 = 2 は、"a2" カラムに 2 の値が存在する場合に有効 ['a1', 'exist', 'targetAttribute' => 'a2'], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a2']], + + // a2 の入力値が a2 のカラムに存在する必要がある。a1 がエラー・メッセージを受ける + // すなわち、a2 = 2 は、"a2" カラムに 2 の値が存在する場合に有効 + ['a1', 'exist', 'targetAttribute' => ['a2']], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a2' => 'a2']], // a1 と a2 の両方が存在する必要がある。両者はともにエラー・メッセージを受け取る + // すなわち、a1 = 3, a2 = 4 は、"a1" カラムに 3, "a2" カラムに 4 が存在する場合に有効 [['a1', 'a2'], 'exist', 'targetAttribute' => ['a1', 'a2']], + // 以下と同義 + [['a1', 'a2'], 'exist', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a1 と a2 の両方が存在する必要がある。a1 のみがエラー・メッセージを受け取る + // すなわち、a1 = 5, a2 = 6 は、"a1" カラムに 5, "a2" カラムに 6 が存在する場合に有効 ['a1', 'exist', 'targetAttribute' => ['a1', 'a2']], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a2 の値が a2 のカラム、a1 の値が a3 のカラムに存在する必要がある。a1 がエラー・メッセージを受け取る + // すなわち、a1 = 7, a2 = 8 は、"a3" カラムに 7, "a2" カラムに 8 が存在する場合に有効 ['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a2' => 'a2', 'a1' => 'a3']], // a1 が存在する必要がある。a1 が配列である場合は、その全ての要素が存在する必要がある ['a1', 'exist', 'allowArray' => true], + // すなわち、a1 = 9 は、"a1" カラムに 9 が存在する場合に有効 + // a1 = [9, 10] は、"a1" カラムに 9 と 10 が存在する場合に有効 // type_id が ProductType クラスで定義されているテーブルの id カラムに存在する必要がある + // すなわち、type_id = 1 は ProductType のテーブルの "id" カラムに 1 が存在する場合に有効 ['type_id', 'exist', 'targetClass' => ProductType::class, 'targetAttribute' => ['type_id' => 'id']], // 同上。定義済みの "type" リレーションを使用。 @@ -310,9 +336,18 @@ function foo($model, $attribute) { 複数のカラムの存在を同時に検証するために配列を使うことが出来ます。 配列の値は存在を検証するのに使用される属性であり、配列のキーは入力値が検証される属性です。 キーと値が同じ場合は、値だけを指定することが出来ます。 + 検証されるモデルが ModelA であり、検証に使用されるモデルが ModelB であるとすると、 + 下記のように `targetAttribute` を構成することが出来ます。 + - `null` => ModelA の現在検証されている属性の値が ModelB の同名の属性の保存されている値に対してチェックされる + - `'a'` => ModelA の現在検証されている属性の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a' => 'a']` => 同上 + - `['a', 'b']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされ、 + 同時に、ModelA の属性 "b" の値が ModelB の属性 "b" の保存されている値に対してチェックされる + - `['a' => 'b']` => ModelA の属性 "a" の値が ModelB の属性 "b" の保存されている値に対してチェックされる +- `targetRelation`: バージョン 2.0.14 以降は簡便な `targetRelation` 属性が使えます。これは指定されたリレーションの定義によって `targetClass` と `targetAttribute` の属性をオーバーライドするものです。 - `filter`: 入力値の存在をチェックするのに使用される DB クエリに適用される追加のフィルタ。 - これには、文字列、または、追加のクエリ条件を表現する配列を使うことが出来ます - (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 + これには、追加のクエリ条件を表現する文字列または配列を使うことが出来ます (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 または、`function ($query)` というシグニチャを持つ無名関数でも構いません。 `$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。 - `allowArray`: 入力値が配列であることを許容するか否か。デフォルト値は `false`。 @@ -341,7 +376,7 @@ function foo($model, $attribute) { 特殊文字 `*` によるワイルドカードのマスクを使って、一群の MIME タイプに一致させることも出来ます。 例えば `image/*` は、`image/` で始まる全ての MIME タイプ (`image/jpeg`, `image/png` など) を通します。 MIME タイプ名は大文字と小文字を区別しません。デフォルト値は `null` であり、すべての MIME タイプが許可されることを意味します。 - MIME タイプの詳細については、[一般的なメディア・タイプ](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types) を参照してください。 + MIME タイプの詳細については、[一般的なメディア・タイプ](https://en.wikipedia.org/wiki/Media_type) を参照してください。 - `minSize`: アップロードされるファイルに要求される最小限のバイト数。デフォルト値は `null` であり、下限値が無いことを意味します。 - `maxSize`: アップロードされるファイルに許可される最大限のバイト数。デフォルト値は `null` であり、上限値が無いことを意味します。 - `maxFiles`: 指定された属性が保持しうる最大限のファイル数。 @@ -389,7 +424,7 @@ function foo($model, $attribute) { > Tip: 入力値をトリムしたい場合は、[trim](#trim) バリデータを直接使うことが出来ます。 > Tip: `filter` のコールバックに期待されるシグニチャを持つ PHP 関数が多数存在します。 -> 例えば、([intval](https://secure.php.net/manual/ja/function.intval.php) や [boolval](https://secure.php.net/manual/ja/function.boolval.php) +> 例えば、([intval](https://www.php.net/manual/ja/function.intval.php) や [boolval](https://www.php.net/manual/ja/function.boolval.php) > などを使って) 型キャストを適用し、属性が特定の型になるように保証したい場合は、 > それらの関数をクロージャで包む必要はなく、単にフィルタの関数名を指定するだけで十分です。 > @@ -638,19 +673,34 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている ```php [ // a1 の入力値が a1 のカラムにおいてユニークである必要がある + // すなわち、a1 = 1 は、"a1" カラムに 1 の値が存在しない場合に有効 ['a1', 'unique'], + // 以下と同義 + ['a1', 'unique', 'targetAttribute' => 'a1'], + ['a1', 'unique', 'targetAttribute' => ['a1' => 'a1']], // a1 の入力値が a2 のカラムにおいてユニークである必要がある + // すなわち、a1 = 2 は、"a2" カラムに 2 の値が存在しない場合に有効 ['a1', 'unique', 'targetAttribute' => 'a2'], + // 以下と同義 + ['a1', 'unique', 'targetAttribute' => ['a1' => 'a2']], // a1 と a2 の両方がユニークである必要がある。両者がともにエラー・メッセージを受け取る + // すなわち、a1 = 3, a2 = 4 は、"a1" カラムに 3 の値が存在せず、同時に、"a2" カラムに 4 の値が存在しない場合に有効 [['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2']], + // 以下と同義 + [['a1', 'a2'], 'unique', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a1 と a2 の両方がユニークである必要がある。a1 のみがエラー・メッセージを受け取る ['a1', 'unique', 'targetAttribute' => ['a1', 'a2']], // a2 の値が a2 のカラム、a1 の値が a3 のカラムにおいてユニークである必要がある。a1 がエラー・メッセージを受け取る + // すなわち、a1 = 5, a2 = 6 は、"a3" カラムに 5 の値が存在せず、同時に、"a2" カラムに 6 の値が存在しない場合に有効 ['a1', 'unique', 'targetAttribute' => ['a2', 'a1' => 'a3']], + + // type_id が ProductType クラスで定義されているテーブルの "id" カラムにおいてユニークである必要がある + // すなわち、type_id = 1 は ProductType のテーブルの "id" カラムに 1 が存在しない場合に有効 + ['type_id', 'unique', 'targetClass' => ProductType::class, 'targetAttribute' => 'id'], ] ``` @@ -665,10 +715,19 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている 複数のカラムのユニーク性を同時に検証するために配列を使うことが出来ます。 配列の値はユニーク性を検証するのに使用される属性であり、配列のキーはその入力値が検証される属性です。 キーと値が同じ場合は、値だけを指定することが出来ます。 -- `filter`: 入力値のユニーク性をチェックするのに使用される DB クエリに適用される追加のフィルタ。 - これには、文字列、または、追加のクエリ条件を表現する配列を使うことが出来ます - (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 - または、`function ($query)` というシグニチャを持つ無名関数でも構いません。`$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。 + 検証されるモデルが ModelA であり、検証に使用されるモデルが ModelB であるとすると、 + 下記のように `targetAttribute` を構成することが出来ます。 + - `null` => ModelA の現在検証されている属性の値が ModelB の同名の属性の保存されている値に対してチェックされる + - `'a'` => ModelA の現在検証されている属性の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a' => 'a']` => 同上 + - `['a', 'b']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされ、 + 同時に、ModelA の属性 "b" の値が ModelB の属性 "b" の保存されている値に対してチェックされる + - `['a' => 'b']` => ModelA の属性 "a" の値が ModelB の属性 "b" の保存されている値に対してチェックされる +- `filter`: 入力値がユニークであることをチェックするのに使用される DB クエリに適用される追加のフィルタ。 + これには、追加のクエリ条件を表現する文字列または配列を使うことが出来ます (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 + これは、または、`function ($query)` というシグニチャを持つ無名関数でも構いません。 + `$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。 ## [[yii\validators\UrlValidator|url]] diff --git a/docs/guide-ja/tutorial-docker.md b/docs/guide-ja/tutorial-docker.md index 5225d8eba7a..53864ab6144 100644 --- a/docs/guide-ja/tutorial-docker.md +++ b/docs/guide-ja/tutorial-docker.md @@ -5,14 +5,14 @@ Yii と Docker コンテナによって、開発用コンピュータと実運用サーバでソフトウェアのバージョンを全く同一にすること、迅速な配備、開発時におけるマルチ・サーバ・アーキテクチャのシミュレーションなど、数多くの問題を解決することが出来ます。 -Docker コンテナの詳細については、[docker.com](https://www.docker.com/what-docker) を参照して下さい。 +Docker コンテナの詳細については、[docker.com](https://www.docker.com/why-docker) を参照して下さい。 ## 必要なもの - `docker` - `docker-compose` -[ダウンロード・ページ](https://www.docker.com/community-edition) で Docker のツールを取得して下さい。 +[ダウンロード・ページ](https://www.docker.com/products/container-runtime) で Docker のツールを取得して下さい。 ## インストール diff --git a/docs/guide-ja/tutorial-i18n.md b/docs/guide-ja/tutorial-i18n.md index 5636fec1b9a..a54f7605961 100644 --- a/docs/guide-ja/tutorial-i18n.md +++ b/docs/guide-ja/tutorial-i18n.md @@ -21,7 +21,7 @@ Yii アプリケーションで使用される全てのロケール ID は、一 `ll-CC` の形式に正規化されなければなりません。 ここで `ll` は [ISO-639](http://www.loc.gov/standards/iso639-2/) に従った小文字二つまたは三つの言語コードであり、 `CC` は [ISO-3166](http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html) に従った二文字の国コードです。 -ロケールに関する更なる詳細は [ICU プロジェクトのドキュメント](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept) +ロケールに関する更なる詳細は [ICU プロジェクトのドキュメント](https://unicode-org.github.io/icu/userguide/locale/#the-locale-concept) に述べられています。 ### 言語 @@ -241,7 +241,7 @@ $price = 100; echo \Yii::t('app', 'Price: {0,number,currency}', $price); ``` -> Note: パラメータのフォーマットには、[intl PHP 拡張](https://secure.php.net/manual/ja/intro.intl.php) のインストールが必要です。 +> Note: パラメータのフォーマットには、[intl PHP 拡張](https://www.php.net/manual/ja/intro.intl.php) のインストールが必要です。 プレースホルダにフォーマット規則を指定するためには、短い構文または完全な構文のどちらかを使うことが出来ます。 @@ -256,7 +256,7 @@ echo \Yii::t('app', 'Price: {0,number,currency}', $price); echo Yii::t('app', "Example of string with ''-escaped characters'': '{' '}' '{test}' {count,plural,other{''count'' value is # '#{}'}}", ['count' => 3]); +``` -このようなプレースホルダを指定する方法についての完全な説明は、[ICU ドキュメント](http://icu-project.org/apiref/icu4c/classMessageFormat.html)を参照してください。以下では、よくある使用方法をいくつか示します。 +このようなプレースホルダを指定する方法についての完全な説明は、[ICU ドキュメント](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classMessageFormat.html)を参照してください。以下では、よくある使用方法をいくつか示します。 #### 数値 @@ -290,7 +290,7 @@ echo \Yii::t('app', 'Balance: {0,number,,000,000000}', $sum); ``` カスタムフォーマットで使用される文字については、 -[ICU API リファレンス](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html) の "Special Pattern Characters" +[ICU API リファレンス](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classDecimalFormat.html) の "Special Pattern Characters" のセクションに記述されています。 数値は常に翻訳先のロケールに従ってフォーマットされます。 @@ -326,7 +326,7 @@ echo \Yii::t('app', 'Today is {0,date,yyyy-MM-dd}', time()); // 日本語出力: '今日は 2015-01-07 です。' ``` -[書式のリファレンス](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +[書式のリファレンス](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### 時刻 @@ -357,7 +357,7 @@ echo \Yii::t('app', 'It is {0,date,HH:mm}', time()); // 日本語出力: '現在 22:37 です。' ``` -[書式のリファレンス](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +[書式のリファレンス](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### 綴り @@ -385,7 +385,7 @@ echo \Yii::t('app', 'I am {n,spellout,%spellout-ordinal} agent', ['n' => 47]); 'spellout,' と '%' の間に空白を入れてはならないことに注意してください。 あなたが使用しているロケールで利用可能なオプションのリストについては、 -[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Spellout" を参照してください。 +[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) の "Numbering schemas, Spellout" を参照してください。 #### 序数 @@ -407,7 +407,7 @@ echo \Yii::t('app', '{n,ordinal,%digits-ordinal-feminine}', ['n' => 471]); 'ordinal,' と '%' の間に空白を入れてはならないことに注意してください。 あなたが使用しているロケールで利用可能なオプションのリストについては、 -[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Ordinal" を参照してください。 +[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) の "Numbering schemas, Ordinal" を参照してください。 > Note: 上記のソース・メッセージを、プレースホルダのスタイルを守って日本語に翻訳すると、'あなたはこのサイトの{n,ordinal}の訪問者です' となります。 > しかし、その出力結果は、'あなたはこのサイトの第42の訪問者です' となり、意味は通じますが、日本語としては若干不自然なものになります。 @@ -435,7 +435,7 @@ echo \Yii::t('app', '{n,duration,%in-numerals}', ['n' => 471227]); 'duration,' と '%' の間に空白を入れてはならないことに注意してください。 あなたが使用しているロケールで利用可能なオプションのリストについては、 -[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Numbering schemas, Duration" を参照してください。 +[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) の "Numbering schemas, Duration" を参照してください。 > Note: このソース・メッセージを 'あなたはこのサイトに既に{n,duration}の間滞在しています' と翻訳した場合の出力結果は、'あなたはこのサイトに既に47の間滞在しています' となります。 > これも、プレースホルダのスタイルも含めて全体を翻訳し直す方が良いでしょう。 @@ -466,7 +466,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" を参照してください。 +特定のロケールに対してどんな引数を指定すべきかを学ぶためには、[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) の "Plural Rules, Cardinal" を参照してください。 あるいは、その代りに、[unicode.org の規則のリファレンス](http://cldr.unicode.org/index/cldr-spec/plural-rules) を参照することも出来ます。 > Note: 上記のロシア語のメッセージのサンプルは、主として翻訳メッセージとして使用されるものです。 @@ -500,7 +500,7 @@ echo Yii::t('app', 'You {likeCount,plural, > 横着をして、`{n, plural, ...}` を `{n, number}` に置き換えても、多分、大きな問題は生じないでしょう。 -#### 序数選択肢 +#### 序数選択肢 パラメータのタイプとして `selectordinal` を使うと、翻訳先ロケールの言語規則に基づいて序数のための文字列を選択することが出来ます。 @@ -518,8 +518,8 @@ echo Yii::t('app', 'You are the {n,selectordinal,one{#st} two{#nd} few{#rd} othe ``` フォーマットは複数形で使われるものと非常に近いものです。 -特定のロケールに対してどんな引数を指定すべきかを学ぶためには、[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) の "Plural Rules, Ordinal" を参照してください。 -あるいは、その代りに、[unicode.org の規則のリファレンス](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html) を参照することも出来ます。 +特定のロケールに対してどんな引数を指定すべきかを学ぶためには、[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) の "Plural Rules, Ordinal" を参照してください。 +あるいは、その代りに、[unicode.org の規則のリファレンス](https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html) を参照することも出来ます。 #### 選択肢 @@ -794,23 +794,18 @@ class TranslationEventHandler ## 数値と日付の値を書式設定する -詳細は [データ・フォーマッタ](output-formatting.md) のセクションを参照してください。 - - -## 日付と数値をフォーマットする - 詳細は [データのフォーマット](output-formatting.md) のセクションを参照して下さい。 ## PHP 環境をセットアップする -Yii は、[[yii\i18n\Formatter]] クラスの数値や日付の書式設定や、[[yii\i18n\MessageFormatter]] を使うメッセージのフォーマッティングなど、ほとんどの国際化機能を提供するために [PHP intl 拡張](https://secure.php.net/manual/ja/book.intl.php) を使います。 +Yii は、[[yii\i18n\Formatter]] クラスの数値や日付の書式設定や、[[yii\i18n\MessageFormatter]] を使うメッセージのフォーマッティングなど、ほとんどの国際化機能を提供するために [PHP intl 拡張](https://www.php.net/manual/ja/book.intl.php) を使います。 この二つのクラスは、`intl` がインストールされていない場合に備えて基本的な機能を提供するフォールバックを実装しています。 だだし、このフォールバックの実装は、英語がターゲット言語である場合にのみ十分に機能するものす。 従って、国際化機能が必要とされる場合は、`intl` をインストールすることが強く推奨されます。 -[PHP intl 拡張](https://secure.php.net/manual/ja/book.intl.php) は、さまざまに異なる全てのロケールについて知識と書式の規則を提供する -[ICU ライブラリ](http://site.icu-project.org/) に基礎を置いています。 +[PHP intl 拡張](https://www.php.net/manual/ja/book.intl.php) は、さまざまに異なる全てのロケールについて知識と書式の規則を提供する +[ICU ライブラリ](https://icu.unicode.org/) に基礎を置いています。 ICU のバージョンが異なると、日付や数値のフォーマットの結果も異なる場合があります。 あなたのウェブ・サイトが全ての環境で同じ出力をすることを保証するためには、 全ての環境において同じバージョンの PHP intl 拡張 (従って同じバージョンの ICU) をインストールすることが推奨されます。 @@ -826,10 +821,10 @@ echo "ICU Data: " . INTL_ICU_DATA_VERSION . "\n"; さらに、バージョン 49 以上の ICU を使用する事も推奨されます。そうすることによって、このドキュメントで説明されている全ての機能を使うことが出来るようになります。 例えば、49 未満の ICU は、複数形規則における `#` プレースホルダをサポートしていません。 -入手できる ICU バージョン については、 を参照してください。 +入手できる ICU バージョン については、 を参照してください。 バージョン番号の採番方式が 4.8 リリースの後に変更されたことに注意してください (すなわち、ICU 4.8、ICU 49、ICU 50、等々となっています)。 これに加えて、ICU ライブラリとともに出荷されるタイム・ゾーン・データベースの情報も古くなっている可能性があります。 -タイム・ゾーン・データベースの更新に関する詳細は [ICU マニュアル](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data) を参照してください。 +タイム・ゾーン・データベースの更新に関する詳細は [ICU マニュアル](https://unicode-org.github.io/icu/userguide/datetime/timezone/#updating-the-time-zone-data) を参照してください。 出力の書式設定には ICU タイム・ゾーン・データベースが使用されますが、PHP によって使われるタイム・ゾーン・データベースも影響する可能性があります。 PHP のタイム・ゾーン・データベースは、[`timezonedb` pecl パッケージ](https://pecl.php.net/package/timezonedb) の最新版をインストールすることによって更新することが出来ます。 diff --git a/docs/guide-ja/tutorial-performance-tuning.md b/docs/guide-ja/tutorial-performance-tuning.md index 8efb7cee269..b1c49308465 100644 --- a/docs/guide-ja/tutorial-performance-tuning.md +++ b/docs/guide-ja/tutorial-performance-tuning.md @@ -11,7 +11,7 @@ PHP 環境を正しく構成することは非常に重要です。最大のパフォーマンスを得るためには、 - 最新の安定した PHP バージョンを使うこと。使用する PHP のメジャー・リリースを上げると、顕著なパフォーマンスの改善がもたらされることがあります。 -- [Opcache](https://secure.php.net/opcache) (PHP 5.5 以降) または [APC](https://secure.php.net/apc) (PHP 5.4) を使って、 +- [Opcache](https://www.php.net/opcache) (PHP 5.5 以降) または [APC](https://www.php.net/manual/en/book.apcu.php) (PHP 5.4) を使って、 バイト・コード・キャッシュを有効にすること。 バイト・コード・キャッシュによって、リクエストが入ってくるたびに PHP スクリプトを解析してインクルードする時間の浪費を避けることが出来ます。 - [`realpath()` キャッシュをチューニングする](https://github.com/samdark/realpath_cache_tuner). @@ -132,7 +132,7 @@ CREATE TABLE session ( ただし、キャッシュ・ストレージの中には、容量の上限に達したときにキャッシュされたデータをフラッシュするものがあることに注意してください。 この理由により、主として容量の上限が無い種類のキャッシュ・ストレージを使用すべきです。 -あなたのサーバに [Redis](http://redis.io/) がある場合は、[[yii\redis\Session]] によって redis +あなたのサーバに [Redis](https://redis.io/) がある場合は、[[yii\redis\Session]] によって redis をセッション・ストレージとして使用することを強く推奨します。 @@ -217,8 +217,8 @@ composer dumpautoload -o - [Yii のデバッグ・ツールバーとデバッガ](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide-ja/README.md) - [Blackfire](https://blackfire.io/) -- [XHProf](https://secure.php.net/manual/ja/book.xhprof.php) -- [XDebug プロファイラ](http://xdebug.org/docs/profiler) +- [XHProf](https://www.php.net/manual/ja/book.xhprof.php) +- [XDebug プロファイラ](https://xdebug.org/docs/profiler) ## アプリケーションをスケーラブルなものにする覚悟を決める diff --git a/docs/guide-ja/tutorial-start-from-scratch.md b/docs/guide-ja/tutorial-start-from-scratch.md index 6f55e4fb474..fd65cb2dace 100644 --- a/docs/guide-ja/tutorial-start-from-scratch.md +++ b/docs/guide-ja/tutorial-start-from-scratch.md @@ -42,7 +42,7 @@ git clone git@github.com:yiisoft/yii2-app-basic.git ---------------- テンプレートが定義できたら、それを基に Git レポジトリを作成して、ファイルをそこにプッシュします。 -あなたのテンプレートをオープンソース化するつもりなら、レポジトリをホストするのには [Github](http://github.com) が最適の場所です。 +あなたのテンプレートをオープンソース化するつもりなら、レポジトリをホストするのには [Github](https://github.com) が最適の場所です。 テンプレートを共同作業に使わないつもりであれば、どんな Git レポジトリサイトでも構いません。 次に、Composer のためにパッケージを登録する必要があります。パブリックなテンプレートであれば、パッケージは [Packagist](https://packagist.org/) に登録すべきです。 diff --git a/docs/guide-ja/tutorial-template-engines.md b/docs/guide-ja/tutorial-template-engines.md index 9f7dd9e042d..d57c7a2d0e3 100644 --- a/docs/guide-ja/tutorial-template-engines.md +++ b/docs/guide-ja/tutorial-template-engines.md @@ -1,7 +1,7 @@ テンプレートエンジンを使う ========================== -デフォルトでは、Yii は PHP をテンプレート言語として使いますが、[Twig](http://twig.sensiolabs.org/) や +デフォルトでは、Yii は PHP をテンプレート言語として使いますが、[Twig](https://twig.symfony.com/) や [Smarty](http://www.smarty.net/) などの他のレンダリング・エンジンをサポートするように Yii を構成することが出来ます。 `view` コンポーネントがビューのレンダリングに責任を持っています。 diff --git a/docs/guide-ja/tutorial-yii-integration.md b/docs/guide-ja/tutorial-yii-integration.md index 5b73fbdda66..18fcebd040d 100644 --- a/docs/guide-ja/tutorial-yii-integration.md +++ b/docs/guide-ja/tutorial-yii-integration.md @@ -93,7 +93,7 @@ Bower および NPM のパッケージのインストールを阻止する特別 Composer に関する更なる情報や、インストールの過程で出現しうる問題に対する解決方法については、 一般的な [Composer によるインストール](start-installation.md#installing-via-composer) のセクションを参照してください。 -そうでない場合は、Yii のリリースを [ダウンロード](http://www.yiiframework.com/download/) して、 +そうでない場合は、Yii のリリースを [ダウンロード](https://www.yiiframework.com/download/) して、 `BasePath/vendor` ディレクトリに解凍してください。 次に、サードパーティのシステムのエントリ・スクリプトを修正します。次のコードをエントリ・スクリプトの先頭に追加してください。 diff --git a/docs/guide-pl/README.md b/docs/guide-pl/README.md index 0001c16c4d9..1e057c178b3 100644 --- a/docs/guide-pl/README.md +++ b/docs/guide-pl/README.md @@ -1,7 +1,7 @@ Przewodnik po Yii 2.0 ===================== -Ten poradnik udostępniony jest na [Warunkach dokumentacji Yii](http://www.yiiframework.com/doc/terms/). +Ten poradnik udostępniony jest na [Warunkach dokumentacji Yii](https://www.yiiframework.com/doc/terms/). Wszelkie prawa zastrzeżone. @@ -18,6 +18,7 @@ Wstęp Pierwsze kroki -------------- +* [Co musisz wiedzieć](start-prerequisites.md) * [Instalacja Yii](start-installation.md) * [Uruchamianie aplikacji](start-workflow.md) * [Witaj świecie](start-hello.md) @@ -40,7 +41,7 @@ Struktura aplikacji * [Moduły](structure-modules.md) * [Filtry](structure-filters.md) * [Widżety](structure-widgets.md) -* [Assety (Assets)](structure-assets.md) +* [Zasoby (Assets)](structure-assets.md) * [Rozszerzenia](structure-extensions.md) @@ -62,12 +63,12 @@ Kluczowe koncepcje * [Komponenty](concept-components.md) * [Właściwości](concept-properties.md) -* [Eventy](concept-events.md) -* [Behaviory](concept-behaviors.md) +* [Zdarzenia (Events)](concept-events.md) +* [Zachowania (Behaviors)](concept-behaviors.md) * [Konfiguracje](concept-configurations.md) * [Aliasy](concept-aliases.md) * [Autoładowanie klas](concept-autoloading.md) -* [Lokator usług](concept-service-locator.md) +* [Lokator usług (Service Locator)](concept-service-locator.md) * [Kontener wstrzykiwania zależności (DI Container)](concept-di-container.md) @@ -78,10 +79,10 @@ Praca z bazami danych * [Konstruktor kwerend](db-query-builder.md): Zapytania do bazy danych z użyciem warstwy abstrakcyjnej. * [Active Record](db-active-record.md): Active Record ORM, otrzymywanie i manipulacja rekordami oraz definiowanie relacji. * [Migracje](db-migrations.md): Użycie systemu kontroli wersji bazy danych do pracy z wieloma środowiskami. -* [Sphinx](https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide/README.md) -* [Redis](https://github.com/yiisoft/yii2-redis/blob/master/docs/guide/README.md) -* [MongoDB](https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide/README.md) -* [ElasticSearch](https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md) +* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide) +* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide) +* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide) +* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide) Odbieranie danych od użytkowników @@ -115,7 +116,7 @@ Bezpieczeństwo * [Autoryzacja](security-authorization.md) * [Praca z hasłami](security-passwords.md) * [Kryptografia](security-cryptography.md) -* [Klienty autoryzacji](security-auth-clients.md) +* [Klienty autoryzacji](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide) * [Bezpieczeństwo w praktyce](security-best-practices.md) @@ -146,9 +147,9 @@ Webserwisy z wykorzystaniem REST Narzędzia wspomagające tworzenie aplikacji ------------------------------------------ -* [Pasek debugowania i debuger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md) -* [Generowanie kodu przy użyciu Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md) -* [Generowanie dokumentacji API](https://github.com/yiisoft/yii2-apidoc) +* [Pasek debugowania i debuger](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide) +* [Generowanie kodu przy użyciu Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide) +* [Generowanie dokumentacji API](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc) Testowanie @@ -165,10 +166,11 @@ Testowanie Tematy specjalne ---------------- -* [Szablon zaawansowanej aplikacji](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md) +* [Szablon zaawansowanej aplikacji](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide) * [Tworzenie aplikacji od podstaw](tutorial-start-from-scratch.md) * [Komendy konsolowe](tutorial-console.md) -* [Podstawowe walidatory](tutorial-core-validators.md) +* [Wbudowane walidatory](tutorial-core-validators.md) +* [Docker](tutorial-docker.md) * [Internacjonalizacja](tutorial-i18n.md) * [Wysyłanie poczty](tutorial-mailing.md) * [Poprawianie wydajności](tutorial-performance-tuning.md) @@ -181,16 +183,16 @@ Tematy specjalne Widżety ------- -* [GridView](http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) -* [ListView](http://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) -* [DetailView](http://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) -* [ActiveForm](http://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) -* [Pjax](http://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) -* [Menu](http://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) -* [LinkPager](http://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) -* [LinkSorter](http://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) -* [Widżety Bootstrapowe](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide/README.md) -* [Widżety jQuery UI](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md) +* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) +* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) +* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) +* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) +* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) +* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) +* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) +* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) +* [Widżety Bootstrapowe](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide) +* [Widżety jQuery UI](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide) Klasy pomocnicze @@ -199,6 +201,7 @@ Klasy pomocnicze * [Przegląd](helper-overview.md) * [ArrayHelper](helper-array.md) * [Html](helper-html.md) +* [Json](helper-json.md) * [Url](helper-url.md) diff --git a/docs/guide-pl/caching-http.md b/docs/guide-pl/caching-http.md index 293b35e874b..668c98082f0 100644 --- a/docs/guide-pl/caching-http.md +++ b/docs/guide-pl/caching-http.md @@ -105,7 +105,7 @@ Dla przykładu, ETag może być zmieniony dla strony w momencie, gdy użyty na n Zasobożerne generowanie ETagów może przekreślić cały zysk z użycia `HttpCache` i wprowadzić niepotrzebny narzut, ponieważ muszą być one określane przy każdym żądaniu. Z tego powodu należy używać jak najprostszych metod generujących. -> Note: Aby spełnić wymagania [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4), +> Note: Aby spełnić wymagania [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4), `HttpCache` przesyła zarówno nagłówek `ETag`, jak i `Last-Modified`, jeśli oba są skonfigurowane. Jeśli klient wysyła nagłówek `If-None-Match` razem z `If-Modified-Since`, tylko pierwszy z nich jest brany pod uwagę. @@ -126,7 +126,7 @@ w `session.cache_limiter` w ustawieniach PHP INI. Mogą one kolidować z funkcjo aby temu zapobiec, `HttpCache` blokuje to automatyczne wysyłanie. Jeśli jednak chcesz zmienić to zachowanie, powinieneś skonfigurować właściwość [[yii\filters\HttpCache::sessionCacheLimiter]]. Powinna ona przyjmować wartość zawierającą łańcuch znaków `public`, `private`, `private_no_expire` i `nocache`. Szczegóły dotyczące tego zapisu znajdziesz w dokumentacji PHP dla -[session_cache_limiter()](https://secure.php.net/manual/pl/function.session-cache-limiter.php). +[session_cache_limiter()](https://www.php.net/manual/pl/function.session-cache-limiter.php). ## Korzyści dla SEO diff --git a/docs/guide-pl/concept-aliases.md b/docs/guide-pl/concept-aliases.md index 63a9bac41ea..81b8f7ae5c8 100644 --- a/docs/guide-pl/concept-aliases.md +++ b/docs/guide-pl/concept-aliases.md @@ -109,8 +109,8 @@ Yii predefiniuje zestaw aliasów do łatwego wskazywania często używanych ści [skrypt wejścia](structure-entry-scripts.md). - `@web`, bazowy adres URL aktualnie używanej aplikacji Web. Wskazuje na tą samą wartość co [[yii\web\Request::baseUrl]]. - `@vendor`, [[yii\base\Application::vendorPath|folder pakietów composera]]. Domyślnie wskazuje na `@app/vendor`. -- `@bower`, bazowy folder zawierający [pakiety bowera](http://bower.io/). Domyślnie wskazuje na `@vendor/bower`. -- `@npm`, bazowy folder zawierający [pakiety npm](https://www.npmjs.org/). Domyślnie wskazuje na `@vendor/npm`. +- `@bower`, bazowy folder zawierający [pakiety bowera](https://bower.io/). Domyślnie wskazuje na `@vendor/bower`. +- `@npm`, bazowy folder zawierający [pakiety npm](https://www.npmjs.com/). Domyślnie wskazuje na `@vendor/npm`. Alias `@yii` jest definiowany poprzez dołączenie pliku `Yii.php` w [skrypcie wejścia](structure-entry-scripts.md). Pozostałe aliasy są definiowane w konstruktorze aplikacji podczas ładowania [konfiguracji](concept-configurations.md). diff --git a/docs/guide-pl/concept-autoloading.md b/docs/guide-pl/concept-autoloading.md index 857af6af0d4..9210895b4fd 100644 --- a/docs/guide-pl/concept-autoloading.md +++ b/docs/guide-pl/concept-autoloading.md @@ -1,7 +1,7 @@ Autoładowanie klas ================== -Yii opiera się na [mechanizmie automatycznego ładowania klas](https://secure.php.net/manual/pl/language.oop5.autoload.php) służącym do +Yii opiera się na [mechanizmie automatycznego ładowania klas](https://www.php.net/manual/pl/language.oop5.autoload.php) służącym do zlokalizowania i dołączenia wszystkich wymaganych plików klas. Wbudowany wysoce wydajny autoloader klas, zgodny ze [standardem PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md), jest instalowany po załączeniu pliku `Yii.php`. @@ -15,7 +15,7 @@ Korzystanie z autoloadera Yii Aby skorzystać z autoloadera klas Yii, powinieneś przestrzegać dwóch prostych zasad tworzenia i nazywania własnych klas: -* Każda klasa musi znajdować się w [przestrzeni nazw](https://secure.php.net/manual/pl/language.namespaces.php) (np. `foo\bar\MyClass`) +* Każda klasa musi znajdować się w [przestrzeni nazw](https://www.php.net/manual/pl/language.namespaces.php) (np. `foo\bar\MyClass`) * Każda klasa musi być zapisana jako oddzielny plik, do którego ścieżka określona jest poniższym algorytmem: ```php diff --git a/docs/guide-pl/concept-behaviors.md b/docs/guide-pl/concept-behaviors.md index 622c2c130cc..0441594e088 100644 --- a/docs/guide-pl/concept-behaviors.md +++ b/docs/guide-pl/concept-behaviors.md @@ -124,21 +124,21 @@ class User extends ActiveRecord { return [ // anonimowy behavior, tylko nazwa klasy behavioru - MyBehavior::className(), + MyBehavior::class, // imienny behavior, tylko nazwa klasy behavioru - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // anonimowy behavior, tablica konfiguracyjna [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // imienny behavior, tablica konfiguracyjna 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -162,11 +162,11 @@ use app\components\MyBehavior; $component->attachBehavior('myBehavior1', new MyBehavior); // załącz klasę behavioru -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // załącz tablicę konfiguracyjną $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -177,7 +177,7 @@ Możesz załączyć wiele behaviorów jednocześnie, korzystając z metody [[yii ```php $component->attachBehaviors([ 'myBehavior1' => new MyBehavior, // imienny behavior - MyBehavior::className(), // anonimowy behavior + MyBehavior::class, // anonimowy behavior ]); ``` @@ -185,10 +185,10 @@ Możliwe jest również załączenie behaviorów poprzez [konfigurację](concept ```php [ - 'as myBehavior2' => MyBehavior::className(), // zwróć uwagę na konstrukcję "as nazwaBehavioru" + 'as myBehavior2' => MyBehavior::class, // zwróć uwagę na konstrukcję "as nazwaBehavioru" 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -279,7 +279,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -337,7 +337,7 @@ Poniżej znajdziesz kilka behaviorów wbudowanych lub też dostępnych w zewnęt Różnice pomiędzy behaviorami a traitami --------------------------------------- -Pomimo że behaviory są podobne do [traitów](https://secure.php.net/traits) w taki sposób, że również "wstrzykują" swoje +Pomimo że behaviory są podobne do [traitów](https://www.php.net/traits) w taki sposób, że również "wstrzykują" swoje właściwości i metody do klasy, struktury te różnią się w wielu aspektach. Obie mają swoje wady i zalety, jak opisano to poniżej, i powinny być raczej traktowane jako swoje uzupełnienia, a nie alternatywy. diff --git a/docs/guide-pl/concept-components.md b/docs/guide-pl/concept-components.md index 7fa2fc9c6e2..ed0a3d49626 100644 --- a/docs/guide-pl/concept-components.md +++ b/docs/guide-pl/concept-components.md @@ -73,7 +73,7 @@ Postępowanie zgodnie z tymi zasadami zapewni [konfigurowalność](concept-confi $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // lub alternatywnie $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide-pl/db-active-record.md b/docs/guide-pl/db-active-record.md index 81d1226d51b..ac9a3930523 100644 --- a/docs/guide-pl/db-active-record.md +++ b/docs/guide-pl/db-active-record.md @@ -1,7 +1,7 @@ Active Record ============= -[Active Record](http://en.wikipedia.org/wiki/Active_record_pattern) zapewnia zorientowany obiektowo interfejs dostępu i manipulacji danymi +[Active Record](https://en.wikipedia.org/wiki/Active_record_pattern) zapewnia zorientowany obiektowo interfejs dostępu i manipulacji danymi zapisanymi w bazie danych. Klasa typu Active Record jest powiązana z tabelą bazodanową, a instacja tej klasy odpowiada pojedynczemu wierszowi w tabeli - *atrybut* obiektu Active Record reprezentuje wartość konkretnej kolumny w tym wierszu. Zamiast pisać bezpośrednie kwerendy bazy danych, można skorzystać z atrybutów i metod klasy Active Record. @@ -31,7 +31,7 @@ Yii zapewnia wsparcie Active Record dla następujących typów relacyjnych baz d * SQLite 2 i 3: poprzez [[yii\db\ActiveRecord]] * Microsoft SQL Server 2008 lub nowszy: poprzez [[yii\db\ActiveRecord]] * Oracle: poprzez [[yii\db\ActiveRecord]] -* CUBRID 9.3 lub nowszy: poprzez [[yii\db\ActiveRecord]] (zwróć uwagę, że z powodu [błędu](http://jira.cubrid.org/browse/APIS-658) +* CUBRID 9.3 lub nowszy: poprzez [[yii\db\ActiveRecord]] (zwróć uwagę, że z powodu [błędu](https://jira.cubrid.org/browse/APIS-658) w rozszerzeniu PDO cubrid, umieszczanie wartości w cudzysłowie nie będzie działać, zatem wymagane jest zainstalowanie CUBRID 9.3 zarówno jako klienta jak i serwer) * Sphinx: poprzez [[yii\sphinx\ActiveRecord]], wymaga rozszerzenia `yii2-sphinx` @@ -438,8 +438,8 @@ Jeśli chcesz sprawdzić wartość atrybutu sprzed ostatniej zmiany, możesz wyw > ma tą samą wartość, ale jest innego typu. Taka sytuacja zdarza się często, kiedy model jest aktualizowany danymi pochodzącymi z formularza > HTML, gdzie każda wartość jest reprezentowana jako string. > Aby upewnić się, że wartości będą odpowiednich typów, np. integer, możesz zaaplikować [filtr walidacji](input-validation.md#data-filtering): -> `['attributeName', 'filter', 'filter' => 'intval']`. Działa on z wszystkimi funkcjami PHP rzutującymi typy jak [intval()](https://secure.php.net/manual/en/function.intval.php), -> [floatval()](https://secure.php.net/manual/en/function.floatval.php), [boolval](https://secure.php.net/manual/en/function.boolval.php), itp... +> `['attributeName', 'filter', 'filter' => 'intval']`. Działa on z wszystkimi funkcjami PHP rzutującymi typy jak [intval()](https://www.php.net/manual/en/function.intval.php), +> [floatval()](https://www.php.net/manual/en/function.floatval.php), [boolval](https://www.php.net/manual/en/function.boolval.php), itp... ### Domyślne wartości atrybutów @@ -613,7 +613,7 @@ try { ``` > Note: w powyższym kodzie znajdują się dwa bloki catch dla kompatybilności -> z PHP 5.x i PHP 7.x. `\Exception` implementuje [interfejs `\Throwable`](https://secure.php.net/manual/en/class.throwable.php) +> z PHP 5.x i PHP 7.x. `\Exception` implementuje [interfejs `\Throwable`](https://www.php.net/manual/en/class.throwable.php) > od PHP 7.0, zatem można pominąć część z `\Exception`, jeśli Twoja aplikacja używa tylko PHP 7.0 lub wyższego. Drugi sposób polega na utworzeniu listy operacji bazodanowych, które wymagają transakcji za pomocą metody [[yii\db\ActiveRecord::transactions()|transactions()]]. @@ -719,7 +719,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -727,7 +727,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -744,7 +744,7 @@ Deklarując relację powinno się zwrócić uwagę na następujące dane: klient może mieć wiele zamówień, podczas gdy zamówienie ma tylko jednego klienta. - nazwę powiązanej klasy Active Record: określoną jako pierwszy argument w [[yii\db\ActiveRecord::hasMany()|hasMany()]] lub [[yii\db\ActiveRecord::hasOne()|hasOne()]]. - Rekomendowany sposób uzyskania nazwy klasy to wywołanie `Xyz::className()`, dzięki czemu możemy posiłkować się wsparciem autouzupełniania IDE + Rekomendowany sposób uzyskania nazwy klasy to wywołanie `Xyz::class`, dzięki czemu możemy posiłkować się wsparciem autouzupełniania IDE i wykrywaniem błędów na poziomie kompilacji. - powiązanie pomiędzy dwoma rodzajami danych: określone jako kolumna(y), poprzez którą dane nawiązują relację. Wartości tablicy są kolumnami głównych danych (reprezentowanymi przez klasę Active Record, w której deklaruje się relacje), a klucze tablicy są @@ -818,7 +818,7 @@ class Customer extends ActiveRecord { public function getBigOrders($threshold = 100) { - return $this->hasMany(Order::className(), ['customer_id' => 'id']) + return $this->hasMany(Order::class, ['customer_id' => 'id']) ->where('subtotal > :threshold', [':threshold' => $threshold]) ->orderBy('id'); } @@ -852,7 +852,7 @@ class Order extends ActiveRecord { public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->viaTable('order_item', ['order_id' => 'id']); } } @@ -865,12 +865,12 @@ class Order extends ActiveRecord { public function getOrderItems() { - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } } @@ -1123,7 +1123,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -1131,7 +1131,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -1163,7 +1163,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); } } ``` @@ -1267,7 +1267,7 @@ class Customer extends \yii\db\ActiveRecord public function getComments() { // klient posiada wiele komentarzy - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1282,7 +1282,7 @@ class Comment extends \yii\mongodb\ActiveRecord public function getCustomer() { // komentarz jest przypisany do jednego klienta - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } @@ -1365,7 +1365,7 @@ class Customer extends \yii\db\ActiveRecord { public function getActiveComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id'])->active(); + return $this->hasMany(Comment::class, ['customer_id' => 'id'])->active(); } } @@ -1376,7 +1376,7 @@ class Customer extends \yii\db\ActiveRecord { public function getComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1440,7 +1440,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1534,7 +1534,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1565,7 +1565,7 @@ class Customer extends \yii\db\ActiveRecord */ public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } /** diff --git a/docs/guide-pl/db-migrations.md b/docs/guide-pl/db-migrations.md index dfefdfcb735..0c559bca170 100644 --- a/docs/guide-pl/db-migrations.md +++ b/docs/guide-pl/db-migrations.md @@ -661,7 +661,7 @@ w `safeDown()` najpierw kasujemy wiersz, a potem usuwamy tabelę. > Note: Nie wszystkie silniki baz danych wspierają transakcje i nie wszystkie rodzaje komend bazodanowych można umieszczać w transakcjach. Dla przykładu, zapoznaj się z rozdziałem dokumentacji MySQL - [Statements That Cause an Implicit Commit](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). W przypadku + [Statements That Cause an Implicit Commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). W przypadku braku możliwości skorzystania z transakcji, powinieneś użyć `up()` i `down()`. diff --git a/docs/guide-pl/glossary.md b/docs/guide-pl/glossary.md index 68df708f906..406f7808437 100644 --- a/docs/guide-pl/glossary.md +++ b/docs/guide-pl/glossary.md @@ -92,7 +92,7 @@ Pakiet opisuje listę powiązanych zasobów wraz z plikiem konfiguracyjnym defin ## przestrzeń nazw -Przestrzeń nazw jest [funkcjonalnością języka PHP](https://secure.php.net/manual/pl/language.namespaces.php), aktywnie wykorzystywaną w Yii 2. +Przestrzeń nazw jest [funkcjonalnością języka PHP](https://www.php.net/manual/pl/language.namespaces.php), aktywnie wykorzystywaną w Yii 2. # R diff --git a/docs/guide-pl/input-forms.md b/docs/guide-pl/input-forms.md index 4120f612ab9..60b11d25fca 100644 --- a/docs/guide-pl/input-forms.md +++ b/docs/guide-pl/input-forms.md @@ -99,7 +99,7 @@ Odnosząc się do [dokumentacji jQuery](https://api.jquery.com/submit), istnieje > Formularz i jego elementy podrzędne powinny nie używać nazw pól lub nazw identyfikatorów które tworzą konflikt z właściwościami formularza, > takich jak `submit`, `length` lub `method`. Konflikty nazw mogą powodować mylące błędy. -> Kompletna lista zasad oraz walidator znaczników dla tych problemów znajduje się na stronie [DOMLint](http://kangax.github.io/domlint). +> Kompletna lista zasad oraz walidator znaczników dla tych problemów znajduje się na stronie [DOMLint](https://kangax.github.io/domlint). Dodatkowe tagi HTML mogą zostać dodane do formularza używając czystego HTML'a lub używając metody z klasy pomocniczej - [[yii\helpers\Html|Html]], tak jak było to zrobione w przykładzie wyżej z [[yii\helpers\Html::submitButton()|submitButton()]]. diff --git a/docs/guide-pl/input-validation.md b/docs/guide-pl/input-validation.md index 7327a66ac05..bc3b76aa2c1 100644 --- a/docs/guide-pl/input-validation.md +++ b/docs/guide-pl/input-validation.md @@ -430,7 +430,7 @@ class EntryForm extends Model { return [ [['name', 'email'], 'required'], - ['country', CountryValidator::className()], + ['country', CountryValidator::class], ['email', 'email'], ]; } diff --git a/docs/guide-pl/intro-upgrade-from-v1.md b/docs/guide-pl/intro-upgrade-from-v1.md index c528225a20a..c1fe16cbe90 100644 --- a/docs/guide-pl/intro-upgrade-from-v1.md +++ b/docs/guide-pl/intro-upgrade-from-v1.md @@ -28,15 +28,15 @@ Yii 2.0 wymaga PHP w wersji 5.4 lub nowszej, która została znacząco ulepszona Z tego też powodu już na poziomie samego języka pojawiło się sporo różnic, na które należy zwrócić uwagę. Poniżej znajdziesz krótkie podsumowanie głównych różnic dotyczących PHP: -- [Przestrzenie nazw](https://secure.php.net/manual/pl/language.namespaces.php). -- [Funkcje anonimowe](https://secure.php.net/manual/pl/functions.anonymous.php). +- [Przestrzenie nazw](https://www.php.net/manual/pl/language.namespaces.php). +- [Funkcje anonimowe](https://www.php.net/manual/pl/functions.anonymous.php). - Skrócona składnia zapisu tablic `[...elementy...]` używana zamiast `array(...elementy...)`. - Krótkie tagi echo `registerJsFile('http://example.com/js/main.js', ['depends' => [\yii\web\JqueryAsset::className()]]); +$this->registerJsFile('http://example.com/js/main.js', ['depends' => [\yii\web\JqueryAsset::class]]); ``` Argumenty dla metod [[yii\web\View::registerCssFile()|registerCssFile()]] są podobne do [[yii\web\View::registerJsFile()|registerJsFile()]]. @@ -73,7 +73,7 @@ Jeśli chcesz się upewnić, że jest tylko jeden tag `style`, użyj trzeciego a ```php $this->registerCssFile("http://example.com/css/themes/black-and-white.css", [ - 'depends' => [BootstrapAsset::className()], + 'depends' => [BootstrapAsset::class], 'media' => 'print', ], 'css-print-theme'); ``` @@ -86,4 +86,4 @@ Kod powyżej doda link w sekcji `head` strony do pliku CSS. * Ostatni argument określa ID identyfikujące ten plik CSS. W przypadku jego braku, zostanie użyty do tego celu adres URL pliku CSS. Jest mocno wskazane używanie [assetów](structure-assets.md) do rejestrowania zewnętrznych plików CSS. Użycie ich pozwala Ci na łączenie i kompresowanie -wielu plików CSS, które jest wręcz niezbędne na stronach internetowych o dużym natężeniu ruchu. \ No newline at end of file +wielu plików CSS, które jest wręcz niezbędne na stronach internetowych o dużym natężeniu ruchu. diff --git a/docs/guide-pl/rest-versioning.md b/docs/guide-pl/rest-versioning.md index 836b01f308b..25e9d9fe8e1 100644 --- a/docs/guide-pl/rest-versioning.md +++ b/docs/guide-pl/rest-versioning.md @@ -8,7 +8,7 @@ pełną wsteczną kompatybilność (BC = backward compatibility), kiedy to tylko może nie spełniać BC, należy wprowadzić ją w nowej wersji API, z kolejnym numerem. Istniejące klienty mogą wciąż używać starej, działającej wersji API, a nowe lub uaktualnione klienty mogą otrzymać nową funkcjonalność oferowaną przez kolejną wersję API. -> Tip: Zapoznaj się z [Wersjonowaniem semantycznym](http://semver.org/lang/pl/), aby uzyskać więcej informacji na temat nazewnictwa +> Tip: Zapoznaj się z [Wersjonowaniem semantycznym](https://semver.org/lang/pl/), aby uzyskać więcej informacji na temat nazewnictwa numerów wersji. Jedną z często spotykanych implementacji wersjonowania API jest dodawanie numeru wersji w adresach URL API. diff --git a/docs/guide-pl/runtime-bootstrapping.md b/docs/guide-pl/runtime-bootstrapping.md index 841ab6fdf87..e923316b78b 100644 --- a/docs/guide-pl/runtime-bootstrapping.md +++ b/docs/guide-pl/runtime-bootstrapping.md @@ -30,8 +30,8 @@ we [właściwości bootstrapowej](structure-applications.md#bootstrap), aby nowe W środowisku produkcyjnym zaleca się zastosowanie pamięci podręcznej kodu, takiej jak [PHP OPcache] lub [APC], aby zminimalizować czas konieczny do załadowania i przetworzenia plików PHP. -[PHP OPcache]: https://secure.php.net/manual/en/intro.opcache.php -[APC]: https://secure.php.net/manual/en/book.apc.php +[PHP OPcache]: https://www.php.net/manual/en/intro.opcache.php +[APC]: https://www.php.net/manual/en/book.apcu.php Niektóre duże aplikacje posiadają bardzo skomplikowaną [konfigurację](concept-configurations.md), składającą się z wielu mniejszych plików konfiguracyjnych. W takim przypadku zalecane jest zapisanie w pamięci całej wynikowej tablicy konfiguracji i załadowanie jej stamtąd bezpośrednio przed utworzeniem instancji aplikacji diff --git a/docs/guide-pl/start-databases.md b/docs/guide-pl/start-databases.md index 97386382036..0a365845a4e 100644 --- a/docs/guide-pl/start-databases.md +++ b/docs/guide-pl/start-databases.md @@ -49,7 +49,7 @@ W tym miejscu masz już utworzoną bazę danych o nazwie `yii2basic`, posiadają Konfiguracja połączenia z bazą danych --------------------------- -Przed przystąpieniem do tej części, upewnij się, że masz zainstalowane rozszerzenie [PDO](https://secure.php.net/manual/en/book.pdo.php) oraz sterownik PDO dla bazy danych której używasz +Przed przystąpieniem do tej części, upewnij się, że masz zainstalowane rozszerzenie [PDO](https://www.php.net/manual/en/book.pdo.php) oraz sterownik PDO dla bazy danych której używasz (np. `pdo_mysql` dla MySQL). Jest to podstawowe wymaganie, jeśli Twoja aplikacja używa relacyjnej bazy danych. diff --git a/docs/guide-pl/start-forms.md b/docs/guide-pl/start-forms.md index 7a76ad5f61f..b550f1d7d3c 100644 --- a/docs/guide-pl/start-forms.md +++ b/docs/guide-pl/start-forms.md @@ -123,7 +123,7 @@ Jeśli nie zostały wysłane żadne dane lub dane zawierają błędy, zostanie w > Note: W tym prostym przykładzie po prostu renderujemy stronę z potwierdzeniem prawidłowego przesłania danych. > W praktyce powinieneś rozważyć użycie [[yii\web\Controller::refresh()|refresh()]] lub [[yii\web\Controller::redirect()|redirect()]], aby uniknąć -> [problemów z ponownym przesłaniem formularza](http://en.wikipedia.org/wiki/Post/Redirect/Get). +> [problemów z ponownym przesłaniem formularza](https://en.wikipedia.org/wiki/Post/Redirect/Get). Tworzenie widoku diff --git a/docs/guide-pl/start-hello.md b/docs/guide-pl/start-hello.md index 9c80421635c..c6040b37ca6 100644 --- a/docs/guide-pl/start-hello.md +++ b/docs/guide-pl/start-hello.md @@ -76,7 +76,7 @@ Widok `say` powinien być zapisany w pliku `views/site/say.php`. Kiedy wywołana wg schematu `views/ControllerID/ViewName.php`. Zauważ, że w powyższym kodzie parametr `message` jest przetworzony za pomocą metody [[yii\helpers\Html::encode()|encode()]] przed wyświetleniem go. Jest to konieczne w przypadku -parametrów pochodzących od użytkownika, wrażliwych na ataki [XSS](http://en.wikipedia.org/wiki/Cross-site_scripting) przez podanie złośliwego kodu JavaScript. +parametrów pochodzących od użytkownika, wrażliwych na ataki [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) przez podanie złośliwego kodu JavaScript. Naturalnie możesz umieścić więcej zawartości w widoku `say`. Zawartość może zawierać tagi HTML, czysty tekst, a nawet kod PHP. Tak naprawdę, widok `say` jest tylko skryptem PHP, który jest wywoływany przez metodę [[yii\web\Controller::render()|render()]]. @@ -122,4 +122,4 @@ W tym prostym przykładzie nie został zaangażowany żaden model, ponieważ dan Nauczyłeś się też czegoś o routingu w Yii, który działa jak most pomiędzy żądaniami użytkownika a akcjami kontrolerów. -W następnej sekcji nauczysz się jak utworzyć model oraz dodać nową stronę zawierającą formularz HTML. \ No newline at end of file +W następnej sekcji nauczysz się jak utworzyć model oraz dodać nową stronę zawierającą formularz HTML. diff --git a/docs/guide-pl/start-installation.md b/docs/guide-pl/start-installation.md index 37c253e128e..f96e60740dd 100644 --- a/docs/guide-pl/start-installation.md +++ b/docs/guide-pl/start-installation.md @@ -2,28 +2,30 @@ Instalacja Yii ============== Yii możesz zainstalować na dwa sposoby, korzystając z [Composera](https://getcomposer.org/) lub pobierając plik archiwum. -Preferowanym sposobem jest ten pierwszy, ponieważ pozwala na instalację i aktualizację dodatkowych [rozszerzeń](structure-extensions.md) oraz samego Yii przy użyciu -zaledwie jednej komendy. +Preferowanym sposobem jest ten pierwszy, ponieważ pozwala na instalację i aktualizację dodatkowych +[rozszerzeń](structure-extensions.md) oraz samego Yii przy użyciu zaledwie jednej komendy. Standardowa instalacja Yii skutkuje pobraniem i wstępnym skonfigurowaniem frameworka wraz z szablonem projektu. Szablon projektu jest aplikacją Yii zawierającą podstawowe funkcjonalności, takie jak logowanie, formularz kontaktowy itp. -Struktura jego kodu została stworzona w oparciu o zalecany sposób pisania aplikacji opartych na Yii, dlatego może służyć jako dobry punkt wyjściowy dla stworzenia -Twojego bardziej zaawansowanego projektu. +Struktura jego kodu została stworzona w oparciu o zalecany sposób pisania aplikacji opartych na Yii, dlatego może służyć +jako dobry punkt wyjściowy dla stworzenia Twojego bardziej zaawansowanego projektu. -W tej oraz kilku kolejnych sekcjach opiszemy jak zainstalować Yii z tak zwanym "podstawowym szablonem projektu" oraz jak zaimplementować w nim nowe funkcjonalności. -Oprócz podstawowego, Yii dostarcza również drugi, [zaawansowany szablon projektu](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md), +W tej oraz kilku kolejnych sekcjach opiszemy jak zainstalować Yii z tak zwanym "podstawowym szablonem projektu" oraz jak +zaimplementować w nim nowe funkcjonalności. Oprócz podstawowego, Yii dostarcza również drugi, +[zaawansowany szablon projektu](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md), przystosowany dla programistów tworzących wielowarstwowe aplikacje. -> Info: Podstawowy szablon projektu jest odpowiedni dla 90% aplikacji webowych. Główną różnicą, w porównaniu do zaawansowanego szablonu projektu, jest organizacja kodu. -> Jeśli dopiero zaczynasz swoją przygodę z Yii, zalecamy zapoznać się z podstawowym szablonem, ze względu na jego prostotę oraz funkcjonalność. +> Info: Podstawowy szablon projektu jest odpowiedni dla 90% aplikacji webowych. Główną różnicą, w porównaniu do + zaawansowanego szablonu projektu, jest organizacja kodu. Jeśli dopiero zaczynasz swoją przygodę z Yii, zalecamy + zapoznać się z podstawowym szablonem, ze względu na jego prostotę oraz funkcjonalność. Instalacja z użyciem Composera ------------------------------ ### Instalacja Composera -Jeśli nie posiadasz jeszcze Composera, to możesz go zainstalować korzystając z instrukcji zamieszczonej na stronie [getcomposer.org](https://getcomposer.org/download/). -W systemach operacyjnych Linux i Mac OS X należy wywołać następujące komendy: +Jeśli nie posiadasz jeszcze Composera, to możesz go zainstalować korzystając z instrukcji zamieszczonej na stronie +[getcomposer.org](https://getcomposer.org/download/). W systemach operacyjnych Linux i Mac OS X należy wywołać następujące komendy: ```bash curl -sS https://getcomposer.org/installer | php @@ -44,32 +46,27 @@ pamiętaj, żeby odpowiednio zmodyfikować podane tu przykładowe komendy. Jeśli jesteś już posiadaczem Composera, upewnij się, że jest on zaktualizowany do najnowszej wersji (komenda `composer self-update`). > Note: Podczas instalacji Yii, Composer będzie potrzebował pobrać sporo informacji z API serwisu Github. -> Ilość zapytań zależy od liczby powiązanych wtyczek, rozszerzeń i modułów, których wymaga Twoja aplikacja, i może być większa niż -> **limit zapytań API GitHuba**. Jeśli faktycznie tak będzie, Composer może poprosić o Twoje dane logowania w serwisie Github, aby uzyskać -> token dostępowy API Githuba. Przy szybkim łączu napotkanie limitu może nastąpić szybciej niż Composer jest w stanie obsłużyć zapytania, -> zatem zalecane jest skonfigurowanie tokenu dostępowego przed instalacją Yii. -> Instrukcja opisująca jak tego dokonać znajduje się w -> [dokumentacji Composera dotyczącej tokenów API Githuba](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens). + Ilość zapytań zależy od liczby powiązanych wtyczek, rozszerzeń i modułów, których wymaga Twoja aplikacja, i może być + większa niż **limit zapytań API GitHuba**. Jeśli faktycznie tak będzie, Composer może poprosić o Twoje dane logowania + w serwisie Github, aby uzyskać token dostępowy API Githuba. Przy szybkim łączu napotkanie limitu może nastąpić szybciej + niż Composer jest w stanie obsłużyć zapytania, zatem zalecane jest skonfigurowanie tokenu dostępowego przed instalacją Yii. + Instrukcja opisująca jak tego dokonać znajduje się w + [dokumentacji Composera dotyczącej tokenów API Githuba](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens). ### Installing Yii Teraz możesz przejść już do instalacji samego Yii, wywołując poniższe komendy w katalogu dostępnym z poziomu sieci web: ```bash -composer global require "fxp/composer-asset-plugin:^1.4.1" composer create-project --prefer-dist yiisoft/yii2-app-basic basic ``` -Pierwsza komenda instaluje [wtyczkę Composer Asset Plugin](https://github.com/francoispluchino/composer-asset-plugin), która pozwala na zarządzanie zasobami -[Bowera](http://bower.io) oraz [NPM](https://www.npmjs.com) z użyciem samego Composera. -Komendę tę wystarczy wywołać raz i od tej pory wtyczka będzie zainstalowana globalnie i dostępna dla każdej kolejnej instalacji Yii. -Druga komenda instaluje Yii w katalogu `basic`. Jeśli chcesz, możesz podać katalog o innej nazwie. +Komenda ta zainstaluje najnowszą stabilną wersję szablonu aplikacji Yii w katalogu `basic`. Możesz oczywiście wybrać +inną nazwę. -> Info: Jeśli komenda `composer create-project` zwróci błąd, upewnij się, czy Composer Asset Plugin jest poprawnie zainstalowany. -> Możesz to zrobić wywołując komendę `composer global show`, która powinna wyświetlić wpis (pośród innych możliwych) `fxp/composer-asset-plugin`. -> Aby sprawdzić, czy przypadkiem nie napotkałeś na jeden z częstych błędów, zerknij również do -> [dokumentacji Composera w sekcji Rozwiązywania problemów](https://getcomposer.org/doc/articles/troubleshooting.md). -> Kiedy uporasz się już z błędem, możesz wznowić przerwaną instalację uruchamiając komendę `composer update` w folderze `basic`. +> Info: Jeśli komenda `composer create-project` zwróci błąd, sprawdź, czy przypadkiem nie jest on już opisany + w [dokumentacji Composera w sekcji Rozwiązywania problemów](https://getcomposer.org/doc/articles/troubleshooting.md). + Kiedy uporasz się już z błędem, możesz wznowić przerwaną instalację uruchamiając komendę `composer update` w folderze `basic`. > Tip: Jeśli chcesz zainstalować najnowszą wersję deweloperską Yii, użyj poniższej komendy, która dodaje > [opcję stabilności](https://getcomposer.org/doc/04-schema.md#minimum-stability): @@ -78,14 +75,15 @@ Druga komenda instaluje Yii w katalogu `basic`. Jeśli chcesz, możesz podać ka > composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic > ``` > -> Pamiętaj, że wersja deweloperska Yii nie powinna być używana w wersjach produkcyjnych Twojej aplikacji, ponieważ mogą wystąpić w niej niespodziewane błędy. +> Pamiętaj, że wersja deweloperska Yii nie powinna być używana w wersjach produkcyjnych Twojej aplikacji, ponieważ mogą +> wystąpić w niej niespodziewane błędy. Instalacja z pliku archiwum --------------------------- Instalacja Yii z pliku archiwum składa się z trzech kroków: -1. Pobranie pliku archiwum z [yiiframework.com](http://www.yiiframework.com/download/). +1. Pobranie pliku archiwum z [yiiframework.com](https://www.yiiframework.com/download/). 2. Rozpakowanie pliku archiwum do katalogu dostępnego z poziomu sieci web. 3. Zmodyfikowanie pliku `config/web.php` przez dodanie sekretnego klucza do elementu konfiguracji `cookieValidationKey` (jest to wykonywane automatycznie, jeśli instalujesz Yii używając Composera): @@ -99,28 +97,58 @@ Inne opcje instalacji --------------------- Powyższe instrukcje pokazują, jak zainstalować Yii oraz utworzyć podstawową, gotową do uruchomienia aplikację web. -To podejście jest dobrym punktem startowym dla większości projektów, zarówno małych jak i dużych. Jest to szczególnie korzystne, gdy zaczynasz naukę Yii. +To podejście jest dobrym punktem startowym dla większości projektów, zarówno małych jak i dużych. Jest to szczególnie +korzystne, gdy zaczynasz naukę Yii. Dostępne są również inne opcje instalacji: * Jeśli chcesz zainstalować wyłącznie framework i samemu zbudować aplikację, zapoznaj się z rozdziałem [Tworzenie aplikacji od podstaw](tutorial-start-from-scratch.md). * Jeśli chcesz utworzyć bardziej zaawansowaną aplikację, przystosowaną do programowania dla wielu środowisk, - powinienieś rozważyć instalację [zaawansowanego szablonu aplikacji](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md). + powinienieś rozważyć instalację + [zaawansowanego szablonu aplikacji](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md). + + +Instalowanie zasobów +-------------------- + +Yii używa menadżerów pakietów [Bower](https://bower.io/) i/lub [NPM](https://www.npmjs.com/) do instalacji bibliotek +zasobów (CSS i JavaScript). Proces pobierania tych bibliotek korzysta z Composera, pozwalając na rozwiązywanie zależności +pakietów PHP i CSS/JavaScript w tym samym czasie, za pomocą serwisu [asset-packagist.org](https://asset-packagist.org) +lub wtyczki [composer asset plugin](https://github.com/fxpio/composer-asset-plugin). +Po więcej informacji sięgnij do sekcji [dokumentacji Zasobów](structure-assets.md). + +Możesz, rzecz jasna, również zarządzać swoimi zasobami za pomocą natywnego klienta Bower/NPM, korzystać z CDN, albo też +całkowicie zrezygnować z instalacji zasobów. Aby zablokować automatyczne pobieranie zasobów podczas używania Composera, +dodaj poniższe linie w pliku '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: w przypadku zablokowania instalacji zasobów przez Composera, odpowiedzialność za ich instalację i rozwiązywanie + zależności spada na Ciebie. Przygotuj się na potencjalne niezgodności w plikach zasobów pochodzących z różnych rozszerzeń. + + Weryfikacja instalacji ---------------------- Po zakończeniu instalacji, skonfiguruj swój serwer (zobacz następną sekcję) lub użyj -[wbudowanego serwera PHP](https://secure.php.net/manual/en/features.commandline.webserver.php), +[wbudowanego serwera PHP](https://www.php.net/manual/en/features.commandline.webserver.php), uruchamiając poniższą komendę w konsoli z poziomu folderu `web` w projekcie: ```bash php yii serve ``` -> Note: Domyślnym portem, na którym serwer HTTP nasłuchuje, jest 8080. Jeśli jednak ten port jest już w użyciu lub też chcesz obsłużyć wiele aplikacji w ten sposób, -możesz podać inny numer portu, dodając argument --port: +> Note: Domyślnym portem, na którym serwer HTTP nasłuchuje, jest 8080. Jeśli jednak ten port jest już w użyciu lub też + chcesz obsłużyć wiele aplikacji w ten sposób, możesz podać inny numer portu, dodając argument --port: ```bash php yii serve --port=8888 @@ -134,10 +162,11 @@ http://localhost:8080/ ![Poprawna instalacja Yii](images/start-app-installed.png) -Powinienieś zobaczyć stronę z napisem "Congratulations!" ("Gratulacje!"). Jeśli nie, sprawdź czy zainstalowane elementy środowiska spełniają wymagania Yii. -Możesz sprawdzić minimalne wymagania na dwa sposoby: +Powinienieś zobaczyć stronę z napisem "Congratulations!" ("Gratulacje!"). Jeśli nie, sprawdź, czy zainstalowane elementy +środowiska spełniają wymagania Yii. Możesz sprawdzić minimalne wymagania na dwa sposoby: -* Skopiuj plik `/requirements.php` do `/web/requirements.php`, a następnie przejdź do przeglądarki i uruchom go przechodząc pod adres `http://localhost/requirements.php` +* Skopiuj plik `/requirements.php` do `/web/requirements.php`, a następnie przejdź do przeglądarki i uruchom go + przechodząc pod adres `http://localhost/requirements.php` * Lub też uruchom następujące komendy: ```bash @@ -145,9 +174,10 @@ Możesz sprawdzić minimalne wymagania na dwa sposoby: php requirements.php ``` -Powinienieś skonfigurować swoją instalację PHP tak, aby spełniała minimalne wymogi Yii. Najważniejszym z nich jest posiadanie PHP w wersji 5.4 lub wyższej. -Powinienieś również zainstalować [rozszerzenie PDO](https://secure.php.net/manual/en/pdo.installation.php) oraz odpowiedni sterownik bazy danych (np. `pdo_mysql` dla bazy danych -MySQL), jeśli Twoja aplikacja potrzebuje bazy danych. +Powinienieś skonfigurować swoją instalację PHP tak, aby spełniała minimalne wymogi Yii. Najważniejszym z nich jest +posiadanie PHP w wersji 5.4 lub wyższej. Powinienieś również zainstalować +[rozszerzenie PDO](https://www.php.net/manual/en/pdo.installation.php) oraz odpowiedni sterownik bazy danych +(np. `pdo_mysql` dla bazy danych MySQL), jeśli Twoja aplikacja potrzebuje bazy danych. Konfigurowanie serwerów WWW @@ -156,26 +186,24 @@ Konfigurowanie serwerów WWW > Info: Możesz pominąć tą sekcję, jeśli tylko testujesz Yii, bez zamiaru zamieszczania aplikacji na serwerze produkcyjnym. Aplikacja zainstalowana według powyższych instrukcji powinna działać bezproblemowo zarówno na -[serwerze HTTP Apache](http://httpd.apache.org) jak i [serwerze HTTP Nginx](http://nginx.org), na systemie -operacyjnym Windows, Mac OS X oraz Linux, posiadającym zainstalowane PHP 5.4 lub wyższe. -Yii 2.0 jest również kompatybilne z [facebookowym HHVM](http://hhvm.com). -Są jednak przypadki, gdzie Yii zachowuje się inaczej w HHVM niż w natywnym PHP, dlatego powinieneś zachować -szczególną ostrożność używając HHVM. - -Na serwerze produkcyjnym możesz skonfigurować swój host tak, aby aplikacja była dostępna pod adresem `http://www.example.com/index.php` zamiast -`http://www.example.com/basic/web/index.php`. -Taka konfiguracja wymaga wskazania głównego katalogu serwera jako katalogu `basic/web`. -Jeśli chcesz ukryć `index.php` w adresie URL, skorzystaj z informacji opisanych w dziale -[routing i tworzenie adresów URL](runtime-routing.md). +[serwerze HTTP Apache](https://httpd.apache.org) jak i [serwerze HTTP Nginx](https://nginx.org), na systemie +operacyjnym Windows, Mac OS X oraz Linux, posiadającym zainstalowane PHP 5.4 lub nowsze. Yii 2.0 jest również kompatybilne +z [facebookowym HHVM](https://hhvm.com), są jednak przypadki, gdzie Yii zachowuje się inaczej w HHVM niż w natywnym PHP, +dlatego powinieneś zachować szczególną ostrożność używając HHVM. + +Na serwerze produkcyjnym możesz skonfigurować swój host tak, aby aplikacja była dostępna pod adresem +`http://www.example.com/index.php` zamiast `http://www.example.com/basic/web/index.php`. Taka konfiguracja wymaga wskazania +głównego katalogu serwera jako katalogu `basic/web`. Jeśli chcesz ukryć `index.php` w adresie URL, skorzystaj z informacji +opisanych w dziale [routing i tworzenie adresów URL](runtime-routing.md). W tej sekcji dowiesz się, jak skonfigurować Twój serwer Apache lub Nginx, aby osiągnąć te cele. -> Info: Ustawiając `basic/web` jako główny katalog serwera unikasz niechcianego dostępu użytkowników końcowych do prywatnego kodu oraz wrażliwych plików aplikacji, które są -> przechowywane w katalogu `basic`. -> Zablokowanie dostępu do tych folderów jest jednym z wymogów bezpieczeństwa aplikacji. +> Info: Ustawiając `basic/web` jako główny katalog serwera, unikasz niechcianego dostępu użytkowników końcowych do + prywatnego kodu oraz wrażliwych plików aplikacji, które są przechowywane w katalogu `basic`. Zablokowanie dostępu do + tych folderów jest jednym z wymogów bezpieczeństwa aplikacji. -> Info: W przypadku, gdy Twoja aplikacja działa na wspólnym środowisku hostingowym, gdzie nie masz dostępu do modyfikowania konfiguracji serwera, nadal możesz zmienić strukturę -> aplikacji dla lepszej ochrony. -> Po więcej informacji zajrzyj do działu [Współdzielone środowisko hostingowe](tutorial-shared-hosting.md). +> Info: W przypadku, gdy Twoja aplikacja działa na wspólnym środowisku hostingowym, gdzie nie masz dostępu do modyfikowania + konfiguracji serwera, nadal możesz zmienić strukturę aplikacji dla lepszej ochrony. Po więcej informacji zajrzyj do + działu [Współdzielone środowisko hostingowe](tutorial-shared-hosting.md). ### Zalecane ustawienia Apache @@ -189,9 +217,14 @@ DocumentRoot "path/to/basic/web" # użyj mod_rewrite do wsparcia "ładnych URLi" RewriteEngine on + + # jeśli $showScriptName jest ustawione na false w UrlManager, nie pozwalaj na dostęp do URLi za pomocą nazwy skryptu + RewriteRule ^index.php/ - [L,R=404] + # Jeśli katalog lub plik istnieje, użyj go bezpośrednio RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d + # W innym przypadku przekieruj żądanie na index.php RewriteRule . index.php @@ -201,9 +234,9 @@ DocumentRoot "path/to/basic/web" ### Zalecane ustawienia Nginx -Aby użyć [Nginx](http://wiki.nginx.org/) powinienieś zainstalować PHP jako [FPM SAPI](https://secure.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.test` aktualną nazwą hosta. +Aby użyć [Nginx](https://wiki.nginx.org/) powinienieś zainstalować PHP jako [FPM SAPI](https://www.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.test` aktualną nazwą hosta. ```nginx server { @@ -231,7 +264,7 @@ server { #} #error_page 404 /404.html; - # deny accessing php files for the /assets directory + # zablokuj dostęp do plików php w folderze /assets location ~ ^/assets/.*\.php$ { deny all; } @@ -255,3 +288,96 @@ aby zapobiec wielu zbędnym wywołaniom `stat()`. Należy również pamiętać, że podczas pracy na serwerze HTTPS musisz dodać `fastcgi_param HTTPS on;`, aby Yii prawidłowo wykrywało, że połączenie jest bezpieczne. + +### Zalecane ustawienia NGINX Unit + +Możesz uruchomić aplikacje oparte na Yii korzystając z [NGINX Unit](https://unit.nginx.org/) z modułem języka PHP. Poniżej +znajdziesz przykładową konfigurację. + +```json +{ + "listeners": { + "*:80": { + "pass": "routes/yii" + } + }, + + "routes": { + "yii": [ + { + "match": { + "uri": [ + "!/assets/*", + "*.php", + "*.php/*" + ] + }, + + "action": { + "pass": "applications/yii/direct" + } + }, + { + "action": { + "share": "/path/to/app/web/", + "fallback": { + "pass": "applications/yii/index" + } + } + } + ] + }, + + "applications": { + "yii": { + "type": "php", + "user": "www-data", + "targets": { + "direct": { + "root": "/path/to/app/web/" + }, + + "index": { + "root": "/path/to/app/web/", + "script": "index.php" + } + } + } + } +} +``` + +Możesz również [skonfigurować](https://unit.nginx.org/configuration/#php) swoje środowisko PHP lub przygotować +spersonalizowany plik `php.ini` w tej samej konfiguracji. + +### Konfiguracja IIS + +Zalecane jest hostowanie aplikacji na wirtualnym hoście (strona Web), gdzie podstawowa ścieżka dokumentów wskazuje na folder +`path/to/app/web` i strona Web jest skonfigurowana do uruchamiania PHP. W folderze `web` musisz umieścić plik `web.config` +(`path/to/app/web/web.config`). Zawartość tego pliku powinna wyglądać jak poniżej: + +```xml + + + + + + + + + + + + + + + + + + +``` +Sprawdź również poniższe oficjalne poradniki firmy Microsoft, opisujące jak poprawnie skonfigurować PHP dla IIS: +1. [Jak uruchomić swoją pierwszą stronę Web na IIS](https://docs.microsoft.com/en-us/iis/manage/creating-websites/scenario-build-a-static-website-on-iis) +2. [Konfiguracja strony Web PHP dla IIS](https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configure-a-php-website-on-iis) diff --git a/docs/guide-pl/start-looking-ahead.md b/docs/guide-pl/start-looking-ahead.md index ea6403acce2..abc95615abb 100644 --- a/docs/guide-pl/start-looking-ahead.md +++ b/docs/guide-pl/start-looking-ahead.md @@ -9,26 +9,26 @@ rozwoju Twojej aplikacji w tak proste zadanie, jak uzupełnienie formularza. Ta sekcja podsumuje dostępne zasoby Yii, które pomogą Ci być bardziej produktywnym podczas używania frameworka. * Dokumentacja - - [Przewodnik po Yii](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [Przewodnik po Yii](https://www.yiiframework.com/doc-2.0/guide-README.html): Jak sama nazwa wskazuje, jest to przewodnik, który opisuje jak działa Yii oraz dostarcza generalnych porad o użyciu Yii. Jest jednym z najważniejszych poradników, które powinieneś przeczytać przed napisaniem kodu w Yii. - - [Dokumentacja klas](http://www.yiiframework.com/doc-2.0/index.html): + - [Dokumentacja klas](https://www.yiiframework.com/doc-2.0/index.html): Określa korzystanie z każdej klasy dostarczonej przez Yii. Powinna być stosowana głównie przy pisaniu kodu oraz chęci zrozumienia, jak działa poszczególna klasa, metoda lub właściwość. Najlepiej używać jej po zrozumieniu działania całego frameworka. - - [Artykuły Wiki](http://www.yiiframework.com/wiki/?tag=yii2): + - [Artykuły Wiki](https://www.yiiframework.com/wiki/?tag=yii2): Artykuły w Wiki są pisane przez użytkowników Yii i są oparte na ich doświadczeniu. Większość z nich jest pisana w stylu przepisów kucharskich, pokazując jak rozwiązać poszczególne problemy używając Yii. Chociaż jakość tych artykułów może nie być tak dobra jak przewodnik, są one bardzo użyteczne oraz mogą dostarczać gotowych do użycia rozwiązań. - - [Książki](http://www.yiiframework.com/doc/) -* [Rozszerzenia](http://www.yiiframework.com/extensions/): + - [Książki](https://www.yiiframework.com/books) +* [Rozszerzenia](https://www.yiiframework.com/extensions/): Yii może pochwalić się biblioteką tysięcy rozszerzeń użytkowników, które mogą być łatwo zainstalowane w Twojej aplikacji, dzięki czemu tworzenie Twojej aplikacji jest jeszcze prostsze i szybsze. * Społeczność - - Forum: - - IRC chat: Kanał #yii w sieci freenode () + - Forum: + - IRC chat: Kanał #yii w sieci Libera () - GitHub: - Facebook: - Twitter: - LinkedIn: - - StackOverflow: + - StackOverflow: diff --git a/docs/guide-pl/start-workflow.md b/docs/guide-pl/start-workflow.md index 5d073c73680..3e2ebc2ec57 100644 --- a/docs/guide-pl/start-workflow.md +++ b/docs/guide-pl/start-workflow.md @@ -36,7 +36,7 @@ Struktura aplikacji Najważniejsze katalogi oraz pliki w Twojej aplikacji to (zakładając, że główny katalog aplikacji to `basic`): -``` +```js basic/ bazowa ścieżka aplikacji composer.json plik używany przez Composer, opisuje informacje paczek config/ zawiera wszystkie konfiguracje, w tym aplikacji @@ -57,7 +57,7 @@ basic/ bazowa ścieżka aplikacji Ogólnie pliki aplikacji mogą zostać podzielone na dwa typy: pliki w katalogu `basic/web` oraz pliki w innych katalogach. Dostęp do pierwszego typu można uzyskać przez HTTP (np. przez przeglądarkę), podczas gdy reszta nie może, i nie powinna być, dostępna publicznie. -Yii implementuje wzór architektoniczny [model-widok-kontroler (MVC)](http://wikipedia.org/wiki/Model-view-controller), który jest odzwierciedleniem przedstawionej wyżej organizacji +Yii implementuje wzór architektoniczny [model-widok-kontroler (MVC)](https://wikipedia.org/wiki/Model-view-controller), który jest odzwierciedleniem przedstawionej wyżej organizacji katalogów. Katalog `models` zawiera wszystkie [klasy modeli](structure-models.md), katalog `views` zawiera wszystkie [skrypty widoków](structure-views.md) oraz katalog `controllers` zawiera wszystkie [klasy kontrolerów](structure-controllers.md). @@ -90,4 +90,4 @@ Poniższy schemat pokazuje jak aplikacja przetwarza żądania. 8. Akcja wczytuje model danych, prawdopodobnie z bazy danych. 9. Akcja renderuje widok, dostarczając mu model danych. 10. Wynik zwracany jest do komponentu [odpowiedzi](runtime-responses.md) aplikacji. -11. Komponent odpowiedzi wysyła wynik do przeglądarki użytkownika. \ No newline at end of file +11. Komponent odpowiedzi wysyła wynik do przeglądarki użytkownika. diff --git a/docs/guide-pl/structure-entry-scripts.md b/docs/guide-pl/structure-entry-scripts.md index 2abca2dcd3c..d99b85e48ae 100644 --- a/docs/guide-pl/structure-entry-scripts.md +++ b/docs/guide-pl/structure-entry-scripts.md @@ -56,9 +56,9 @@ Podobnie poniżej kod skryptu wejściowego dla aplikacji konsolowej: /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-pl/test-acceptance.md b/docs/guide-pl/test-acceptance.md index 96abf66b7d5..967aff1ce97 100644 --- a/docs/guide-pl/test-acceptance.md +++ b/docs/guide-pl/test-acceptance.md @@ -3,7 +3,7 @@ Testy akceptacyjne > Uwaga: Ta sekcja jest w trakcie tworzenia. -- [Testy akceptacyjne Codeception](http://codeception.com/docs/03-AcceptanceTests) +- [Testy akceptacyjne Codeception](https://codeception.com/docs/03-AcceptanceTests) Uruchamianie testów akceptacyjnych dla podstawowego i zaawansowanego szablonu projektu -------------------------------------------------------------------------------------- diff --git a/docs/guide-pl/test-functional.md b/docs/guide-pl/test-functional.md index bd1413c2b13..434ef3d8aae 100644 --- a/docs/guide-pl/test-functional.md +++ b/docs/guide-pl/test-functional.md @@ -3,9 +3,9 @@ Testy funkcjonalne > Uwaga: Ta sekcja jest w trakcie tworzenia. -- [Testy funkcjonalne Codeception](http://codeception.com/docs/04-FunctionalTests) +- [Testy funkcjonalne Codeception](https://codeception.com/docs/04-FunctionalTests) Uruchamianie testów funkcjonalnych dla podstawowego i zaawansowanego szablonu projektu -------------------------------------------------------------------------------------- -Prosimy o zapoznanie się z instrukcjami dostępnymi w plikach `apps/advanced/tests/README.md` i `apps/basic/tests/README.md`. \ No newline at end of file +Prosimy o zapoznanie się z instrukcjami dostępnymi w plikach `apps/advanced/tests/README.md` i `apps/basic/tests/README.md`. diff --git a/docs/guide-pl/test-unit.md b/docs/guide-pl/test-unit.md index c5d196349a2..77e0ae892f8 100644 --- a/docs/guide-pl/test-unit.md +++ b/docs/guide-pl/test-unit.md @@ -10,8 +10,8 @@ Testy jednostkowe są zazwyczaj tworzone przez osoby, które piszą klasy poddaw Testy jednostkowe w Yii są oparte o PHPUnit oraz, opcjonalnie, Codeception, zatem zalecane jest, aby zapoznać się z ich dokumentacją: -- [PHPUnit (dokumentacja zaczyna się w rozdziale 2)](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html). -- [Testy jednostkowe Codeception](http://codeception.com/docs/05-UnitTests). +- [PHPUnit (dokumentacja zaczyna się w rozdziale 2)](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html). +- [Testy jednostkowe Codeception](https://codeception.com/docs/05-UnitTests). Uruchamianie testów jednostkowych dla podstawowego i zaawansowanego szablonu projektu ------------------------------------------------------------------------------------- diff --git a/docs/guide-pl/tutorial-start-from-scratch.md b/docs/guide-pl/tutorial-start-from-scratch.md index 838fbcb7291..c47c8c4c289 100644 --- a/docs/guide-pl/tutorial-start-from-scratch.md +++ b/docs/guide-pl/tutorial-start-from-scratch.md @@ -39,7 +39,7 @@ Na samym końcu zmodyfikuj plik README, aby pasował do szablonu. Tworzenie paczki ---------------- -Nowy szablon umieść w odpowiadającym mu repozytorium Git. Jeśli zamierzasz udostępnić go jako open source, [Github](http://github.com) jest najlepszym miejscem do tego celu. +Nowy szablon umieść w odpowiadającym mu repozytorium Git. Jeśli zamierzasz udostępnić go jako open source, [Github](https://github.com) jest najlepszym miejscem do tego celu. Jeśli jednak nie przewidujesz współpracy z innymi nad swoim szablonem, dowolne repozytorium Git będzie odpowiednie. Następnie należy zarejestrować swoją paczkę dla Composera. Dla publicznie dostępnych szablonów paczkę należy zarejestrować w serwisie [Packagist](https://packagist.org/). diff --git a/docs/guide-pl/tutorial-template-engines.md b/docs/guide-pl/tutorial-template-engines.md index 2c87fedefe5..88d9923af70 100644 --- a/docs/guide-pl/tutorial-template-engines.md +++ b/docs/guide-pl/tutorial-template-engines.md @@ -2,7 +2,7 @@ Silniki szablonów ================= Yii domyślnie używa PHP jako języka szablonów, ale nic nie stoi na przeszkodzie, aby skonfigurować wsparcie dla innych silników renderujących widok, -takich jak [Twig](http://twig.sensiolabs.org/) lub [Smarty](http://www.smarty.net/), dostępnych w postaci rozszerzeń. +takich jak [Twig](https://twig.symfony.com/) lub [Smarty](https://www.smarty.net/), dostępnych w postaci rozszerzeń. Komponent `view` jest odpowiedzialny za renderowanie widoków. Aby dodać niestandardowy silnik szablonów, należy skonfigurować komponent jak poniżej: @@ -45,4 +45,4 @@ Po zapisaniu pliku można zainstalować rozszerzenia uruchamiając komendę `com Szczegóły na temat każdego z powyższych silników szablonów dostępne są w ich dokumentacjach: - [Przewodnik po Twig](https://github.com/yiisoft/yii2-twig/tree/master/docs/guide) -- [Przewodnik po Smarty](https://github.com/yiisoft/yii2-smarty/tree/master/docs/guide) \ No newline at end of file +- [Przewodnik po Smarty](https://github.com/yiisoft/yii2-smarty/tree/master/docs/guide) diff --git a/docs/guide-pt-BR/README.md b/docs/guide-pt-BR/README.md index 3b008cf8d47..9406a8facbd 100644 --- a/docs/guide-pt-BR/README.md +++ b/docs/guide-pt-BR/README.md @@ -1,7 +1,7 @@ Guia Definitivo para Yii 2.0 ============================ -Esse tutorial está disponível sob os [termos da documentação do Yii](http://www.yiiframework.com/doc/terms/). +Esse tutorial está disponível sob os [termos da documentação do Yii](https://www.yiiframework.com/doc/terms/). Todos os Direitos Reservados. diff --git a/docs/guide-pt-BR/caching-data.md b/docs/guide-pt-BR/caching-data.md index 1de83e05c03..9fe3fb57a8c 100644 --- a/docs/guide-pt-BR/caching-data.md +++ b/docs/guide-pt-BR/caching-data.md @@ -30,7 +30,7 @@ if ($data === false) { O cache de dados se baseia nos, então chamados, *Componentes de Cache* que representam vários armazenamentos de cache, como memória, arquivos, bancos de dados. -Componentes de Cache são normalmente registrados como [componentes de aplicação](structure-application-components.md) para que possam ser globalmente configuráveis e acessíveis. O código a seguir exibe como configurar o componente de aplicação `cache` para usar [memcached](http://memcached.org/) com dois servidores de cache: +Componentes de Cache são normalmente registrados como [componentes de aplicação](structure-application-components.md) para que possam ser globalmente configuráveis e acessíveis. O código a seguir exibe como configurar o componente de aplicação `cache` para usar [memcached](https://memcached.org/) com dois servidores de cache: ```php 'components' => [ @@ -75,7 +75,7 @@ Por exemplo, você pode modificar a configuração acima para usar [[yii\caching Yii suporta uma ampla gama de sistemas de cache. A seguir um resumo: -* [[yii\caching\ApcCache]]: usa a extensão do PHP [APC](https://secure.php.net/manual/en/book.apc.php). Esta opção pode ser +* [[yii\caching\ApcCache]]: usa a extensão do PHP [APC](https://www.php.net/manual/en/book.apcu.php). Esta opção pode ser considerada a mais rápida ao se implementar o cache de uma aplicação densa e centralizada (por exemplo, um servidor, sem balanceadores de carga dedicados, etc.). * [[yii\caching\DbCache]]: usa uma tabela no banco de dados para armazenar os dados em cache. Para usar este cache @@ -89,16 +89,16 @@ Yii suporta uma ampla gama de sistemas de cache. A seguir um resumo: `Yii::$app->cache` possa ser `null`. * [[yii\caching\FileCache]]: usa arquivos para armazenar os dados em cache. Este é particularmente indicado para armazenar grandes quantidades de dados como o conteúdo da página. -* [[yii\caching\MemCache]]: usa o [memcache](https://secure.php.net/manual/en/book.memcache.php) do PHP e as extensões - [memcached](https://secure.php.net/manual/en/book.memcached.php). Esta opção pode ser considerada a mais rápida +* [[yii\caching\MemCache]]: usa o [memcache](https://www.php.net/manual/en/book.memcache.php) do PHP e as extensões + [memcached](https://www.php.net/manual/en/book.memcached.php). Esta opção pode ser considerada a mais rápida ao se implementar o cache em aplicações distribuídas (ex., vários servidores, balanceadores de carga, etc.) * [[yii\redis\Cache]]: implementa um componente de cache baseado em armazenamento chave-valor - [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](https://secure.php.net/manual/en/book.wincache.php)). -* [[yii\caching\XCache]] _(deprecated)_: usa a extensão PHP [XCache](http://xcache.lighttpd.net/). + [Redis](https://redis.io/) (requer redis versão 2.6.12 ou mais recente). +* [[yii\caching\WinCache]]: usa a extensão PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) + ([veja também](https://www.php.net/manual/en/book.wincache.php)). +* [[yii\caching\XCache]] _(deprecated)_: usa a extensão PHP [XCache](https://en.wikipedia.org/wiki/List_of_PHP_accelerators#XCache). * [[yii\caching\ZendDataCache]] _(deprecated)_: usa - [Cache de Dados Zend](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) + [Cache de Dados Zend](https://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) como o meio de cache subjacente. @@ -259,7 +259,7 @@ $resultado = Cliente::getDb()->cache(function ($bd) { }); ``` -> Informação: Alguns SGBDs (ex., [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) +> Informação: Alguns SGBDs (ex., [MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html)) também suportam o cache de consulta no servidor. Você pode escolher usá-lo ao invés do mecanismo de cache de consulta. O cache de consulta descrito acima tem a vantagem de poder especificar dependências de cache flexíveis diff --git a/docs/guide-pt-BR/caching-http.md b/docs/guide-pt-BR/caching-http.md index 56195207078..0f7b6cd83b8 100644 --- a/docs/guide-pt-BR/caching-http.md +++ b/docs/guide-pt-BR/caching-http.md @@ -102,7 +102,7 @@ Por exemplo, um ETag pode ser invalidado se o site tiver sido alterado para um n Gerações muito complexas de ETags podem contrariar o propósito de se usar `HttpCache` e introduzir despesas desnecessárias ao processamento, já que eles precisam ser reavaliados a cada requisição. Tente encontrar uma expressão simples que invalida o cache se o conteúdo da página for modificado. -> Observação: Em concordância com a [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4), o +> Observação: Em concordância com a [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4), o `HttpCache` enviará os cabeçalhos `ETag` e `Last-Modified` se ambos forem assim configurados. E se o cliente enviar ambos o cabeçalhos `If-None-Match` e `If-Modified-Since`, apenas o primeiro será respeitado. @@ -124,7 +124,7 @@ como especificado na configuração `session.cache_limiter` do PHP.INI. Estes ca desabilitar o cache que você deseja do `HttpCache`. Para prevenir-se deste problema, por padrão, o `HttpCache` desabilitará o envio destes cabeçalhos automaticamente. Se você quiser modificar estes comportamentos, deve configurar a propriedade [[yii\filters\HttpCache::sessionCacheLimiter]]. A propriedade pode receber um valor string, como: `public`, `private`, `private_no_expire` e `nocache`. Por favor, consulte o manual do -PHP sobre [session_cache_limiter()](https://secure.php.net/manual/en/function.session-cache-limiter.php) +PHP sobre [session_cache_limiter()](https://www.php.net/manual/en/function.session-cache-limiter.php) para mais explicações sobre estes valores. diff --git a/docs/guide-pt-BR/concept-aliases.md b/docs/guide-pt-BR/concept-aliases.md index 2494eb1dd9a..6b6e0ae42b9 100644 --- a/docs/guide-pt-BR/concept-aliases.md +++ b/docs/guide-pt-BR/concept-aliases.md @@ -102,7 +102,7 @@ O Yii já predefine uma gama de aliases para referenciar facilmente caminhos de - `@vendor`, o [[yii\base\Application::vendorPath|caminho da pasta vendor do Composer]]. Seu padrão é `@app/vendor`. - `@bower`, o caminho raiz que contém os [pacotes bower](http://bower.io/). Seu padrão é `@vendor/bower`. -- `@npm`, o caminho raiz que contém [pacotes npm](https://www.npmjs.org/). Seu padrão é `@vendor/npm`. +- `@npm`, o caminho raiz que contém [pacotes npm](https://www.npmjs.com/). Seu padrão é `@vendor/npm`. O alias `@yii` é definido quando você inclui o arquivo `Yii.php` em seu [script de entrada](structure-entry-scripts.md). O resto dos aliases são definidos no construtor da aplicação ao aplicar a [configuração](concept-configurations.md) da aplicação. diff --git a/docs/guide-pt-BR/concept-autoloading.md b/docs/guide-pt-BR/concept-autoloading.md index 280d92e419f..75aac87710f 100644 --- a/docs/guide-pt-BR/concept-autoloading.md +++ b/docs/guide-pt-BR/concept-autoloading.md @@ -1,7 +1,7 @@ Autoloading de Classes ================= -O Yii baseia-se no [mecanismo de autoloading de classe](https://secure.php.net/manual/en/language.oop5.autoload.php) para localizar e incluir todos os arquivos de classe necessários. Ele fornece um autoloader de alto desempenho que é compatível com o +O Yii baseia-se no [mecanismo de autoloading de classe](https://www.php.net/manual/pt_BR/language.oop5.autoload.php) para localizar e incluir todos os arquivos de classe necessários. Ele fornece um autoloader de alto desempenho que é compatível com o [PSR-4 standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md). O autoloader é instalado quando o arquivo `Yii.php` é incluído. > Observação: Para simplificar a descrição, nesta seção, nós falaremos apenas sobre autoloading de classe. No entanto, tenha em mente que o conteúdo que estamos descrevendo aqui se aplica a autoloading de interfaces e traits também. @@ -12,7 +12,7 @@ Usando o Autoloader do Yii Para fazer uso da autoloader de classe do Yii, você deve seguir duas regras simples ao criar e nomear suas classes: -* Cada classe deve estar debaixo de um [namespace](https://secure.php.net/manual/en/language.namespaces.php) (exemplo. `foo\bar\MyClass`) +* Cada classe deve estar debaixo de um [namespace](https://www.php.net/manual/en/language.namespaces.php) (exemplo. `foo\bar\MyClass`) * Cada classe deve ser salvo em um arquivo individual cujo caminho é determinado pelo seguinte algoritmo: ```php diff --git a/docs/guide-pt-BR/concept-behaviors.md b/docs/guide-pt-BR/concept-behaviors.md index 75869fffc1d..86d06326585 100644 --- a/docs/guide-pt-BR/concept-behaviors.md +++ b/docs/guide-pt-BR/concept-behaviors.md @@ -111,21 +111,21 @@ class User extends ActiveRecord { return [ // behavior anônimo, somente o nome da classe - MyBehavior::className(), + MyBehavior::class, // behavior nomeado, somente o nome da classe - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // behavior anônimo, array de configuração [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // behavior nomeado, array de configuração 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ] @@ -145,11 +145,11 @@ use app\components\MyBehavior; $component->attachBehavior('myBehavior1', new MyBehavior); // anexando uma classe behavior -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // anexando através de um array de configuração $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -160,7 +160,7 @@ Você pode anexar vários behaviors de uma só vez usando o método [[yii\base\C ```php $component->attachBehaviors([ 'myBehavior1' => new MyBehavior, // um behavior nomeado - MyBehavior::className(), // um behavior anônimo + MyBehavior::class, // um behavior anônimo ]); ``` @@ -168,10 +168,10 @@ Você também pode anexar behaviors através de [configurações](concept-config ```php [ - 'as myBehavior2' => MyBehavior::className(), + 'as myBehavior2' => MyBehavior::class, 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -255,7 +255,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -291,7 +291,7 @@ $user->touch('login_time'); Comparando Behaviors com Traits ---------------------- -Apesar de behaviors serem semelhantes a [traits](https://secure.php.net/traits) em que ambos "injetam" suas propriedades e métodos para a classe principal, eles diferem em muitos aspectos. Tal como explicado abaixo, ambos têm prós e contras. Eles funcionam mais como complemento um do outro. +Apesar de behaviors serem semelhantes a [traits](https://www.php.net/traits) em que ambos "injetam" suas propriedades e métodos para a classe principal, eles diferem em muitos aspectos. Tal como explicado abaixo, ambos têm prós e contras. Eles funcionam mais como complemento um do outro. ### Razões para usar Behaviors diff --git a/docs/guide-pt-BR/concept-components.md b/docs/guide-pt-BR/concept-components.md index 56684d1c7c8..1950698e9b1 100644 --- a/docs/guide-pt-BR/concept-components.md +++ b/docs/guide-pt-BR/concept-components.md @@ -68,7 +68,7 @@ Seguindo essas orientações fará com que seus componentes sejam [configurávei $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // alternatively $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide-pt-BR/concept-di-container.md b/docs/guide-pt-BR/concept-di-container.md index cb511ae3f42..4f2e9cc9346 100644 --- a/docs/guide-pt-BR/concept-di-container.md +++ b/docs/guide-pt-BR/concept-di-container.md @@ -1,7 +1,7 @@ Container de Injeção de Dependência ============================== -Um container de injeção de dependência (DI) é um objeto que sabe como instanciar e configurar objetos e todas as suas dependências. O [artigo do Martin](http://martinfowler.com/articles/injection.html) explica bem porque o container de DI é útil. Aqui vamos explicar principalmente a utilização do container de DI fornecido pelo Yii. +Um container de injeção de dependência (DI) é um objeto que sabe como instanciar e configurar objetos e todas as suas dependências. O [artigo do Martin](https://martinfowler.com/articles/injection.html) explica bem porque o container de DI é útil. Aqui vamos explicar principalmente a utilização do container de DI fornecido pelo Yii. Injeção de Dependência @@ -317,7 +317,7 @@ Resumo ------- Ambas as injeção de dependência e [service locator](concept-service-locator.md) são padrões de projetos conhecidos que permitem a construção de software com alta coesão e baixo acoplamento. É altamente recomendável que você leia o -[Artigo do Martin](http://martinfowler.com/articles/injection.html) para obter uma compreensão mais profunda da injeção de dependência e service locator. +[Artigo do Martin](https://martinfowler.com/articles/injection.html) para obter uma compreensão mais profunda da injeção de dependência e service locator. O Yii implementa o [service locator](concept-service-locator.md) no topo da injeção dependência container (DI). Quando um service locator tenta criar uma nova instância de objeto, ele irá encaminhar a chamada para o container de DI. diff --git a/docs/guide-pt-BR/concept-events.md b/docs/guide-pt-BR/concept-events.md index 84ca7daaa3d..df33873fbd4 100644 --- a/docs/guide-pt-BR/concept-events.md +++ b/docs/guide-pt-BR/concept-events.md @@ -9,7 +9,7 @@ Se sua classe precisar disparar eventos, ela deverá estender de [[yii\base\Comp Manipuladores de Evento -------------- -Um manipulador de evento é uma função [Callback do PHP] (https://secure.php.net/manual/en/language.types.callable.php) que é executada quando o evento é disparado. Você pode usar qualquer um dos seguintes callbacks: +Um manipulador de evento é uma função [Callback do PHP] (https://www.php.net/manual/en/language.types.callable.php) que é executada quando o evento é disparado. Você pode usar qualquer um dos seguintes callbacks: - uma função global do PHP especificada como uma string (sem parênteses), por exemplo, `'trim'`; - Um método do objeto especificado como um array, informando o objeto e um nome do método como uma string (sem parênteses), por exemplo `[$object, 'methodName']`; - Um método estático da classe especificado como um array informando o nome da classe e nome do método como string (sem parênteses), por exemplo, `['ClassName', 'methodName']`; @@ -191,7 +191,7 @@ use Yii; use yii\base\Event; use yii\db\ActiveRecord; -Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { +Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::debug(get_class($event->sender) . ' is inserted'); }); ``` @@ -205,11 +205,11 @@ Você pode disparar um evento de *nível de classe* chamando o método estático ```php use yii\base\Event; -Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { +Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) { var_dump($event->sender); // displays "null" }); -Event::trigger(Foo::className(), Foo::EVENT_HELLO); +Event::trigger(Foo::class, Foo::EVENT_HELLO); ``` Note que, neste caso, `$event->sender` refere-se ao nome da classe acionando o evento em vez de uma instância do objeto. @@ -220,10 +220,10 @@ Para desvincular um manipulador de evento de nível de classe, chame [[yii\base\ ```php // desvincula $handler -Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); +Event::off(Foo::class, Foo::EVENT_HELLO, $handler); // Desvincula todos os manipuladores de Foo::EVENT_HELLO -Event::off(Foo::className(), Foo::EVENT_HELLO); +Event::off(Foo::class, Foo::EVENT_HELLO); ``` diff --git a/docs/guide-pt-BR/db-active-record.md b/docs/guide-pt-BR/db-active-record.md index 5139cc68645..db330813276 100644 --- a/docs/guide-pt-BR/db-active-record.md +++ b/docs/guide-pt-BR/db-active-record.md @@ -1,7 +1,7 @@ Active Record ============= -O [Active Record](http://en.wikipedia.org/wiki/Active_record_pattern) fornece uma interface orientada a objetos para acessar e manipular dados armazenados em bancos de dados. Uma classe Active Record está associado a uma tabela da base de dados, uma instância do Active Record corresponde a uma linha desta tabela, e um *atributo* desta instância representa o valor de uma coluna desta linha. Em vez de escrever instruções SQL a mão, você pode acessar os atributos do Active Record e chamar os métodos do Active Record para acessar e manipular os dados armazenados nas tabelas do banco de dados. +O [Active Record](https://en.wikipedia.org/wiki/Active_record_pattern) fornece uma interface orientada a objetos para acessar e manipular dados armazenados em bancos de dados. Uma classe Active Record está associado a uma tabela da base de dados, uma instância do Active Record corresponde a uma linha desta tabela, e um *atributo* desta instância representa o valor de uma coluna desta linha. Em vez de escrever instruções SQL a mão, você pode acessar os atributos do Active Record e chamar os métodos do Active Record para acessar e manipular os dados armazenados nas tabelas do banco de dados. Por exemplo, assumindo que `Customer` é uma classe Active Record que está associada com a tabela `customer` e `name` é uma coluna desta tabela. Você pode escrever o seguinte código para inserir uma nova linha na tabela `customer`: @@ -576,7 +576,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -584,7 +584,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -596,7 +596,7 @@ Cada método de relação deve ser nomeado como `getXyz`. Nós chamamos de `xyz` Ao declarar uma relação, você deve especificar as seguintes informações: - A multiplicidade da relação: especificada chamando tanto o método [[yii\db\ActiveRecord::hasMany()|hasMany()]] quanto o método [[yii\db\ActiveRecord::hasOne()|hasOne()]]. No exemplo acima você pode facilmente ler nas declarações de relação que um `customer` tem vários `orders` enquanto uma `order` só tem um `customer`. -- O nome da classe Active Record relacionada: especificada no primeiro parâmetro dos métodos [[yii\db\ActiveRecord::hasMany()|hasMany()]] e [[yii\db\ActiveRecord::hasOne()|hasOne()]]. Uma prática recomendada é chamar `Xyz::className()` para obter o nome da classe para que você possa receber suporte do preenchimento automático de IDEs bem como detecção de erros. +- O nome da classe Active Record relacionada: especificada no primeiro parâmetro dos métodos [[yii\db\ActiveRecord::hasMany()|hasMany()]] e [[yii\db\ActiveRecord::hasOne()|hasOne()]]. Uma prática recomendada é chamar `Xyz::class` para obter o nome da classe para que você possa receber suporte do preenchimento automático de IDEs bem como detecção de erros. - A ligação entre os dois tipos de dados: especifica a(s) coluna(s) por meio do qual os dois tipos de dados se relacionam. Os valores do array são as colunas da tabela primária (representada pela classe Active Record que você declarou as relações), enquanto as chaves do array são as colunas da tabela relacionada. Uma regra fácil de lembrar é, como você pode ver no exemplo acima, você escreve a coluna que pertence ao Active Record relacionado diretamente ao lado dele. Você pode ver que `customer_id` é uma propriedade de `Order` e `id` é uma propriedade de `Customer`. @@ -654,7 +654,7 @@ class Customer extends ActiveRecord { public function getBigOrders($threshold = 100) { - return $this->hasMany(Order::className(), ['customer_id' => 'id']) + return $this->hasMany(Order::class, ['customer_id' => 'id']) ->where('subtotal > :threshold', [':threshold' => $threshold]) ->orderBy('id'); } @@ -683,7 +683,7 @@ class Order extends ActiveRecord { public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->viaTable('order_item', ['order_id' => 'id']); } } @@ -696,12 +696,12 @@ class Order extends ActiveRecord { public function getOrderItems() { - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } } @@ -892,7 +892,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -900,7 +900,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -930,7 +930,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); } } ``` @@ -1023,7 +1023,7 @@ class Customer extends \yii\db\ActiveRecord public function getComments() { // a customer tem muitos comments - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1038,7 +1038,7 @@ class Comment extends \yii\mongodb\ActiveRecord public function getCustomer() { // um comment tem um customer - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } @@ -1106,7 +1106,7 @@ class Customer extends \yii\db\ActiveRecord { public function getActiveComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id'])->active(); + return $this->hasMany(Comment::class, ['customer_id' => 'id'])->active(); } } @@ -1166,7 +1166,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` diff --git a/docs/guide-pt-BR/db-migrations.md b/docs/guide-pt-BR/db-migrations.md index 49601285f59..8ec42df6f41 100644 --- a/docs/guide-pt-BR/db-migrations.md +++ b/docs/guide-pt-BR/db-migrations.md @@ -104,7 +104,7 @@ class m150101_185401_criar_tabela_noticias extends \yii\db\Migration ``` > Observação: Nem todas as migrações são reversíveis. Por exemplo, se o método `up()` deleta um registro de uma tabela, - você possivelmente mente não será capaz de recuperar este registro com o método `down()`. Em alguns casos, você pode ter + você possivelmente não será capaz de recuperar este registro com o método `down()`. Em alguns casos, você pode ter tido muita preguiça e não ter implementado o método `down()`, porque não é muito comum reverter migrações de dados. Neste caso, você deve retornar `false` no método `down()` para indicar que a migração não é reversível. @@ -169,7 +169,7 @@ Observe que normalmente quando você realiza múltiplas operações em `safeUp() em `safeDown()`. No exemplo acima nós primeiramente criamos a tabela e depois inserimos uma túpla em `safeUp()`; enquanto em `safeDown()` nós primeiramente apagamos o registro e depois eliminamos a tabela. -> Observação: Nem todos os SGBDs suportam transações. E algumas requisições de banco não podem ser encapsuladas em uma transação. Para alguns exemplos, referir a [commit implícito](http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html). Se este for o caso, implemente os métodos `up()` e `down()`. +> Observação: Nem todos os SGBDs suportam transações. E algumas requisições de banco não podem ser encapsuladas em uma transação. Para alguns exemplos, referir a [commit implícito](https://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html). Se este for o caso, implemente os métodos `up()` e `down()`. ### Métodos de Acesso ao Banco de Dados diff --git a/docs/guide-pt-BR/helper-overview.md b/docs/guide-pt-BR/helper-overview.md new file mode 100644 index 00000000000..eb28ed04c84 --- /dev/null +++ b/docs/guide-pt-BR/helper-overview.md @@ -0,0 +1,80 @@ +Helpers +======= + +> Observação: Esta seção está em desenvolvimento. + +O Yii oferece muitas classes que ajudam a simplificar as tarefas comuns de codificação, como manipulação de string ou de array, +geração de código HTML, e assim por diante. Essas classes helpers (auxiliares) são organizadas no namespace `yii\helpers` e +são todas classes estáticas (o que significa que contêm apenas propriedades e métodos estáticos e não devem ser instanciadas). + +Você usa uma classe helper chamando diretamente um de seus métodos estáticos, como o seguinte: + +```php +use yii\helpers\Html; + +echo Html::encode('Test > test'); +``` + +> Observação: Para oferecer suporte à [personalização de classes helper](#customizing-helper-classes), o Yii divide cada classe helper principal + em duas classes: uma classe base (ex. `BaseArrayHelper`) e uma classe concreta (ex. `ArrayHelper`). + Ao usar um helper, você deve usar apenas a versão concreta e nunca a classe base. + + +Principais Classes Helper +------------------- + +As seguintes classes helper são fornecidas nas versões Yii: + +- [ArrayHelper](helper-array.md) +- Console +- FileHelper +- FormatConverter +- [Html](helper-html.md) +- HtmlPurifier +- Imagine (fornecido pela extensão yii2-imagine) +- Inflector +- [Json](helper-json.md) +- Markdown +- StringHelper +- [Url](helper-url.md) +- VarDumper + + +Personalização de Classes Helper +-------------------------- + +Para personalizar uma classe helper principal (ex. [[yii\helpers\ArrayHelper]]), você deve criar uma nova classe que +estende da classe base correspondente ao helper (ex. [[yii\helpers\BaseArrayHelper]]) e nomear a sua classe da mesma +forma que a classe concreta correspondente (ex. [[yii\helpers\ArrayHelper]]), Essa classe será então configurada para +substituir a implementação original da estrutura. + +O exemplo a seguir mostra como personalizar o método [[yii\helpers\ArrayHelper::merge()|merge()]] da classe +[[yii\helpers\ArrayHelper]]: + +```php + HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -60,11 +60,11 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => CompositeAuth::className(), + 'class' => CompositeAuth::class, 'authMethods' => [ - HttpBasicAuth::className(), - HttpBearerAuth::className(), - QueryParamAuth::className(), + HttpBasicAuth::class, + HttpBearerAuth::class, + QueryParamAuth::class, ], ]; return $behaviors; diff --git a/docs/guide-pt-BR/rest-controllers.md b/docs/guide-pt-BR/rest-controllers.md index cabbff5bfe1..d2bedec4c79 100644 --- a/docs/guide-pt-BR/rest-controllers.md +++ b/docs/guide-pt-BR/rest-controllers.md @@ -51,7 +51,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } diff --git a/docs/guide-pt-BR/rest-quick-start.md b/docs/guide-pt-BR/rest-quick-start.md index c2937b320f3..58647459955 100644 --- a/docs/guide-pt-BR/rest-quick-start.md +++ b/docs/guide-pt-BR/rest-quick-start.md @@ -7,7 +7,7 @@ O Yii fornece um conjunto de ferramentas para simplificar a tarefa de implementa * Negociação de formato do Response (suporte JSON e XML por padrão); * Serialização de objeto configurável com suporte a campos de saída selecionáveis; * Formatação adequada para a coleção e dados e validação de erros; -* Suporte a [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS); +* Suporte a [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS); * Roteamento eficiente com verificação dos verbs (métodos) HTTP; * Construído com suporte aos métodos `OPTIONS` e `HEAD`; * Autenticação e autorização; diff --git a/docs/guide-pt-BR/rest-resources.md b/docs/guide-pt-BR/rest-resources.md index 8e55f5467e3..89166878529 100644 --- a/docs/guide-pt-BR/rest-resources.md +++ b/docs/guide-pt-BR/rest-resources.md @@ -117,7 +117,7 @@ o request com `http://localhost/users?fields=id,email&expand=profile` pode retor ## Links -[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS) é uma abreviação de “Hypermedia as the Engine of Application State”, que promove as APIs Restfull retornarem informações para permitir aos clientes descobrirem quais ações são suportadas pelos recursos retornados. O sentido de HATEOAS é retornar um conjunto de hiperlinks em relação às informações quando os recursos de dados são servidos pelas APIs. +[HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) é uma abreviação de “Hypermedia as the Engine of Application State”, que promove as APIs Restfull retornarem informações para permitir aos clientes descobrirem quais ações são suportadas pelos recursos retornados. O sentido de HATEOAS é retornar um conjunto de hiperlinks em relação às informações quando os recursos de dados são servidos pelas APIs. Suas classes de recursos podem suportar HATEOAS implementando a interface [[yii\web\Linkable]]. Esta interface contém um único método [[yii\web\Linkable::getLinks()|getLinks()]] que deve retornar uma lista de [[yii\web\Link|links]]. Tipicamente, você deve retornar pelo menos o link `self` representando a URL para o mesmo objeto de recurso. Por exemplo: diff --git a/docs/guide-pt-BR/rest-response-formatting.md b/docs/guide-pt-BR/rest-response-formatting.md index 9215d2aa5a5..84081026d13 100644 --- a/docs/guide-pt-BR/rest-response-formatting.md +++ b/docs/guide-pt-BR/rest-response-formatting.md @@ -3,7 +3,7 @@ Formatando Respostas Ao manipular uma requisição da API RESTful, a aplicação normalmente realiza as seguintes etapas que estão relacionadas com a formatação da resposta: -1. Determinar diversos fatores que podem afetar o formato da resposta, tais como tipo de mídia, idioma, versão, etc. Este processo também é conhecido como [negociação de conteúdo (*content negotiation*)](http://en.wikipedia.org/wiki/Content_negotiation). +1. Determinar diversos fatores que podem afetar o formato da resposta, tais como tipo de mídia, idioma, versão, etc. Este processo também é conhecido como [negociação de conteúdo (*content negotiation*)](https://en.wikipedia.org/wiki/Content_negotiation). 2. Converter objetos de recursos em arrays, como descrito na seção [Recursos](rest-resources.md). Isto é feito por [[yii\rest\Serializer]]. 3. Converte arrays em uma string no formato como determinado pela etapa de negociação de conteúdo. Isto é feito pelos [[yii\web\ResponseFormatterInterface|formatadores de respostas]] registrados na propriedade [[yii\web\Response::formatters|formatters]] do [componente de aplicação](structure-application-components.md) `response`. diff --git a/docs/guide-pt-BR/rest-versioning.md b/docs/guide-pt-BR/rest-versioning.md index ceb16f5c6c1..5acd5e3d26b 100644 --- a/docs/guide-pt-BR/rest-versioning.md +++ b/docs/guide-pt-BR/rest-versioning.md @@ -3,9 +3,9 @@ Versionamento Uma boa API é *versionada*: Mudanças e novos recursos são implementados em novas versões da API em vez de alterar continuamente apenas uma versão. Diferente de aplicações Web, com a qual você tem total controle do código de ambos os lados cliente e servidor, APIs são destinadas a ser utilizadas por clientes além de seu controle. Por esta razão, a compatibilidade (BC) entre as APIs deve ser mantida sempre que possível. Se uma mudança que pode quebrar esta compatibilidade é necessária, você deve introduzi-la em uma nova versão de API e subir o número da versão. Os clientes existentes podem continuar a usar a versão antiga da API; e os clientes novos ou atualizados podem obter a nova funcionalidade na nova versão da API. -> Dica: Consulte o artigo [Semantic Versioning](http://semver.org/) para obter mais informações sobre como projetar números de versão da API. +> Dica: Consulte o artigo [Semantic Versioning](https://semver.org/) para obter mais informações sobre como projetar números de versão da API. -Uma maneira comum de implementar versionamento de API é incorporar o número da versão nas URLs da API. Por exemplo, `http://example.com/v1/users` representa o terminal `/users` da API versão 1. +Uma maneira comum de implementar versionamento de API é incorporar o número da versão nas URLs da API. Por exemplo, `https://example.com/v1/users` representa o terminal `/users` da API versão 1. Outro método de versionamento de API, que tem sido muito utilizado recentemente, é colocar o número da versão nos cabeçalhos das requisições HTTP. Isto é tipicamente feito através do cabeçalho `Accept`: diff --git a/docs/guide-pt-BR/runtime-bootstrapping.md b/docs/guide-pt-BR/runtime-bootstrapping.md index fa3c41d3e28..61a1af298af 100644 --- a/docs/guide-pt-BR/runtime-bootstrapping.md +++ b/docs/guide-pt-BR/runtime-bootstrapping.md @@ -44,8 +44,8 @@ regras de URL possam ter efeito antes que sejam usados para resolver as requisi No modo de produção, habilite um cache de bytecode, como o [PHP OPcache] ou [APC], para minimizar o tempo necessário para a inclusão e análise os arquivos PHP. -[PHP OPcache]: https://secure.php.net/manual/en/intro.opcache.php -[APC]: https://secure.php.net/manual/en/book.apc.php +[PHP OPcache]: https://www.php.net/manual/pt_BR/intro.opcache.php +[APC]: https://www.php.net/manual/pt_BR/book.apcu.php Algumas aplicações de larga escala possuem [configurações](concept-configurations.md) complexas, que são divididos em vários arquivos menores. Se este for o caso, diff --git a/docs/guide-pt-BR/runtime-sessions-cookies.md b/docs/guide-pt-BR/runtime-sessions-cookies.md index 74eacbbc0e6..c715241fd53 100644 --- a/docs/guide-pt-BR/runtime-sessions-cookies.md +++ b/docs/guide-pt-BR/runtime-sessions-cookies.md @@ -120,8 +120,8 @@ A classe padrão [[yii\web\Session]] armazena dados da sessão como arquivos no * [[yii\web\DbSession]]: armazena dados de sessão em uma tabela no banco de dados. * [[yii\web\CacheSession]]: armazena dados de sessão em um cache com a ajuda de um [cache component](caching-data.md#cache-components) configurado. -* [[yii\redis\Session]]: armazena dados de sessão utilizando [redis](http://redis.io/) como meio de armazenamento. -* [[yii\mongodb\Session]]: armazena dados de sessão em um [MongoDB](http://www.mongodb.org/). +* [[yii\redis\Session]]: armazena dados de sessão utilizando [redis](https://redis.io/) como meio de armazenamento. +* [[yii\mongodb\Session]]: armazena dados de sessão em um [MongoDB](https://www.mongodb.com/). Todas essas classes de sessão suportam o mesmo conjunto de métodos da API. Como resultado, você pode mudar para uma classe de armazenamento de sessão diferente, sem a necessidade de modificar o código da aplicação que usa sessões. @@ -268,7 +268,7 @@ unset($cookies['language']); Além das propriedades [[yii\web\Cookie::name|name]], [[yii\web\Cookie::value|value]] mostradas nos exemplos acima, a classe [[yii\web\Cookie]] também define outras propriedades para representar plenamente todas as informações de cookie disponíveis, tal como [[yii\web\Cookie::domain|domain]], [[yii\web\Cookie::expire|expire]]. Você pode configurar essas propriedades conforme necessário para preparar um cookie e, em seguida, adicioná-lo à coleção de cookie da resposta. -> Observação: Para melhor segurança, o valor padrão de [[yii\web\Cookie::httpOnly]] é definido para `true`. Isso ajuda a reduzir o risco de um script do lado do cliente acessar o cookie protegido (se o browser suporta-lo). Você pode ler o [httpOnly wiki article](https://www.owasp.org/index.php/HttpOnly) para mais detalhes. +> Observação: Para melhor segurança, o valor padrão de [[yii\web\Cookie::httpOnly]] é definido para `true`. Isso ajuda a reduzir o risco de um script do lado do cliente acessar o cookie protegido (se o browser suporta-lo). Você pode ler o [httpOnly wiki article](https://owasp.org/www-community/HttpOnly) para mais detalhes. ### Validação de Cookie diff --git a/docs/guide-pt-BR/security-authorization.md b/docs/guide-pt-BR/security-authorization.md index 721aaf4552e..9f312bafffd 100644 --- a/docs/guide-pt-BR/security-authorization.md +++ b/docs/guide-pt-BR/security-authorization.md @@ -20,7 +20,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['login', 'logout', 'signup'], 'rules' => [ [ @@ -59,7 +59,7 @@ Você pode personalizar este behavior configurando a propriedade [[yii\filters\ ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, ... 'denyCallback' => function ($rule, $action) { throw new \Exception('Você não está autorizado a acessar esta página'); @@ -103,7 +103,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['special-callback'], 'rules' => [ [ @@ -131,7 +131,7 @@ class SiteController extends Controller Controle de Acesso Baseado em Role (RBAC) fornece um simples porém poderoso controle de acesso centralizado. Por favor, consulte [Wikipedia](http://en.wikipedia.org/wiki/Role-based_access_control) para obter detalhes sobre comparação de RBAC com outros sistemas de controle de acesso mais tradicionais. -Yii implementa um RBAC Hierárquico genérico, conforme [NIST RBAC model](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf). Ele fornece as funcionalidades RBAC através do [componente de aplicação](structure-application-components.md) [[yii\rbac\ManagerInterface|authManager]]. +Yii implementa um RBAC Hierárquico genérico, conforme [NIST RBAC model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf). Ele fornece as funcionalidades RBAC através do [componente de aplicação](structure-application-components.md) [[yii\rbac\ManagerInterface|authManager]]. O uso do RBAC divide-se em duas partes. A primeira parte é construir os dados de autorização RBAC, e a segunda parte é usar os dados de autorização para executar verificação de acesso em locais onde ela é necessária. diff --git a/docs/guide-pt-BR/start-databases.md b/docs/guide-pt-BR/start-databases.md index fdcf236eb6f..8aa6ee658bf 100644 --- a/docs/guide-pt-BR/start-databases.md +++ b/docs/guide-pt-BR/start-databases.md @@ -55,7 +55,7 @@ Configurando uma Conexão de BD ------------------------------ Antes de prosseguir, certifique-se de que você possui instalados tanto a -extensão [PDO](https://secure.php.net/manual/en/book.pdo.php) do PHP quanto o driver +extensão [PDO](https://www.php.net/manual/en/book.pdo.php) do PHP quanto o driver PDO para o gerenciador de banco de dados que você está usando (por exemplo, `pdo_mysql` para o MySQL). Este é um requisito básico se a sua aplicação usa um banco de dados relacional. diff --git a/docs/guide-pt-BR/start-forms.md b/docs/guide-pt-BR/start-forms.md index a62381ca147..3fa43f65e41 100644 --- a/docs/guide-pt-BR/start-forms.md +++ b/docs/guide-pt-BR/start-forms.md @@ -175,7 +175,7 @@ use yii\widgets\ActiveForm; A view usa um poderoso [widget](structure-widgets.md) chamado [[yii\widgets\ActiveForm|ActiveForm]] para construir o formulário HTML. Os métodos `begin()` e `end()` do widget renderizam as tags de abertura e de fechamento do formulário. -Entre as duas chamadas de métido, campos são criados pelo +Entre as duas chamadas de método, campos são criados pelo método [[yii\widgets\ActiveForm::field()|field()]]. O primeiro campo é para o nome e o segundo é para o e-mail. Após os campos, o método [[yii\helpers\Html::submitButton()]] é chamado para criar um botão de envio do formulário (submit). diff --git a/docs/guide-pt-BR/start-hello.md b/docs/guide-pt-BR/start-hello.md index 927c89f07c9..f23d75a59d8 100644 --- a/docs/guide-pt-BR/start-hello.md +++ b/docs/guide-pt-BR/start-hello.md @@ -92,7 +92,7 @@ o arquivo PHP em `views/IDdoController/NomeDaView.php`. Perceba que no código acima o parâmetro `mensagem` é [[yii\helpers\Html::encode()|codificado como HTML]] antes de ser impresso. Isso é necessário, já que o parâmetro vem de um usuário final, -tornando-o vulnerável a [ataques de cross-site scripting (XSS)](http://en.wikipedia.org/wiki/Cross-site_scripting) +tornando-o vulnerável a [ataques de cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) por embutir código JavaScript malicioso no parâmetro. Naturalmente, você pode colocar mais conteúdo na view `cumprimentar`. O conteúdo pode consistir diff --git a/docs/guide-pt-BR/start-installation.md b/docs/guide-pt-BR/start-installation.md index c670e07f580..3be27958b83 100644 --- a/docs/guide-pt-BR/start-installation.md +++ b/docs/guide-pt-BR/start-installation.md @@ -86,7 +86,7 @@ Instalando a partir de um Arquivo Compactado ----------------- -Yii utiliza os pacotes [Bower](http://bower.io/) e/ou [NPM](https://www.npmjs.org/) para a instalação das bibliotecas de recursos estáticos (CSS and JavaScript). +Yii utiliza os pacotes [Bower](https://bower.io/) e/ou [NPM](https://www.npmjs.com/) para a instalação das bibliotecas de recursos estáticos (CSS and JavaScript). Ele usa composer para obter essa bibliotecas, permitindo que versões de pacotes PHP, CSS e Javascrtip possam ser definidas/instaladas ao mesmo tempo. -Isto é possível por usar ou [asset-packagist.org](https://asset-packagist.org) ou [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/). +Isto é possível por usar ou [asset-packagist.org](https://asset-packagist.org) ou [composer asset plugin](https://github.com/fxpio/composer-asset-plugin). Por favor, consulta a [documentação sobre Assets](structure-assets.md) para mais detalhes. Você pode querer gerenciar assets através de clientes nativos do Bower ou NPM, pode querer utilizar CDNs ou até evitar completamente a instalação de recursos estáticos. @@ -145,7 +145,7 @@ Verificando a Instalação ------------------------ Após a instalação ser concluída, você pode tanto configurar seu servidor web (veja na próxima seção) como usar o -[servidor web embutido do PHP](https://secure.php.net/manual/pt_BR/features.commandline.webserver.php) executando o seguinte comando de console no diretório `web`: +[servidor web embutido do PHP](https://www.php.net/manual/pt_BR/features.commandline.webserver.php) executando o seguinte comando de console no diretório `web`: ```bash php yii serve @@ -177,7 +177,7 @@ Você deverá ver a página de parabenização acima em seu navegador. Se não a ``` Você deve configurar sua instalação PHP de forma a atingir os requisitos mínimos do Yii. A versão mínima do PHP que você deve ter é a 5.4. Mas o ideal seria utilizar a versão mais recente, PHP 7. -Se sua aplicação precisa de um banco de dados, você também deve instalar a [Extensão PDO PHP](https://secure.php.net/manual/pt_BR/pdo.installation.php) e o driver de banco de dados correspondente (tal como `pdo_mysql` para bancos de dados MySQL). +Se sua aplicação precisa de um banco de dados, você também deve instalar a [Extensão PDO PHP](https://www.php.net/manual/pt_BR/pdo.installation.php) e o driver de banco de dados correspondente (tal como `pdo_mysql` para bancos de dados MySQL). Configurando Servidores Web @@ -186,9 +186,9 @@ Configurando Servidores Web > Info: Você pode pular essa subseção por enquanto se estiver fazendo somente um test drive do Yii sem a intenção de publicá-lo em um servidor de produção. A aplicação instalada de acordo com as instruções acima deve funcionar imediatamente -com um [Servidor HTTP Apache](http://httpd.apache.org/) ou um [Servidor HTTP Nginx](http://nginx.org/), +com um [Servidor HTTP Apache](https://httpd.apache.org/) ou um [Servidor HTTP Nginx](https://nginx.org/), no Windows, Mac OS X ou Linux usando PHP 5.4 ou superior. O Yii 2.0 também é compatível -com o [HHVM](http://hhvm.com/) do Facebook. No entanto, existem alguns casos extremos em que o HHVM se comporta diferentemente do PHP nativo, então você terá que ter um cuidado extra quando usar o HHVM. +com o [HHVM](https://hhvm.com/) do Facebook. No entanto, existem alguns casos extremos em que o HHVM se comporta diferentemente do PHP nativo, então você terá que ter um cuidado extra quando usar o HHVM. Em um servidor de produção, você pode querer configurar o seu servidor Web de modo que a aplicação possa ser acessada pela URL `http://www.example.com/index.php` @@ -242,7 +242,7 @@ DocumentRoot "caminho/para/basico/web" ### Configuração do Nginx Recomendada -Para usar o [Nginx](http://wiki.nginx.org/), você deve ter instalado o PHP como um [FPM SAPI](https://secure.php.net/install.fpm). Use a seguinte configuração do Nginx, +Para usar o [Nginx](https://wiki.nginx.org/), você deve ter instalado o PHP como um [FPM SAPI](https://www.php.net/install.fpm). Use a seguinte configuração do Nginx, substituindo `caminho/para/basico/web` com o caminho real para `basico/web` e `mysite.test` com o nome de host real a servir. ```nginx diff --git a/docs/guide-pt-BR/start-looking-ahead.md b/docs/guide-pt-BR/start-looking-ahead.md index 11cc12ef3aa..d0ad41ce863 100644 --- a/docs/guide-pt-BR/start-looking-ahead.md +++ b/docs/guide-pt-BR/start-looking-ahead.md @@ -11,28 +11,28 @@ Web uma tarefa tão simples quanto preencher alguns formulários. Esta seção resume recursos Yii disponíveis que o ajudarão a ser mais produtivo usando o framework. * Documentação - - [O Guia Definitivo](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [O Guia Definitivo](https://www.yiiframework.com/doc-2.0/guide-README.html): Conforme o nome indica, o guia define precisamente como o Yii deve funcionar e fornece orientações gerais sobre como usá-lo. É o tutorial mais importante e que você deveria ler antes de escrever qualquer código Yii. - - [A Referência de Classes](http://www.yiiframework.com/doc-2.0/index.html): + - [A Referência de Classes](https://www.yiiframework.com/doc-2.0/index.html): Especifica o uso de todas as classes fornecidas pelo Yii. Deve ser principalmente usada quando você estiver escrevendo código e quiser entender o uso de uma classe, método ou propriedade específicos. O uso da referência de classes é idealmente melhor somente depois de um entendimento contextual do framework como um todo. - - [Os Artigos Wiki](http://www.yiiframework.com/wiki/?tag=yii2): + - [Os Artigos Wiki](https://www.yiiframework.com/wiki/?tag=yii2): Os artigos wiki são escritos por usuários do Yii baseados em suas próprias experiências. A maioria deles são escritos como receitas de bolo e mostram como resolver problemas específicos usando o Yii. Ainda que a qualidade desses artigos possa não ser tão boa quanto a do Guia Definitivo, eles são úteis porque são abrangem assuntos adicionais e frequentemente fornecem soluções prontas para serem usadas. - - [Livros](http://www.yiiframework.com/doc/) -* [Extensões](http://www.yiiframework.com/extensions/): + - [Livros](https://www.yiiframework.com/books) +* [Extensões](https://www.yiiframework.com/extensions/): O Yii ostenta uma biblioteca de milhares de extensões contribuídas por usuários que podem facilmente ser plugadas em suas aplicações, tornando o seu desenvolvimento ainda mais rápido e mais fácil. * Comunidade - - Fórum: - - Chat IRC: O canal #yii na rede freenode () + - Fórum: + - Chat IRC: O canal #yii na rede Libera () - Canal Slack: - Chat Gitter: - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: \ No newline at end of file + - Stackoverflow: diff --git a/docs/guide-pt-BR/start-prerequisites.md b/docs/guide-pt-BR/start-prerequisites.md index 3128b8d6a2c..2feb18e79fd 100644 --- a/docs/guide-pt-BR/start-prerequisites.md +++ b/docs/guide-pt-BR/start-prerequisites.md @@ -4,8 +4,8 @@ A curva de aprendizado no Yii não é tão íngreme como em outros frameworks PH ## PHP -Yii é um framework PHP. Portanto, certifique-se de [ler e entender a referência da linguagem](https://secure.php.net/manual/pt_BR/langref.php). -Quando estiver desenvolvendo com Yii, você estará escrevendo código orientado a objetos, então, certifique-se de que está familiarizado tanto com [Classes e Objetos](https://secure.php.net/manual/pt_BR/language.oop5.basic.php) como com [namespaces](https://secure.php.net/manual/pt_BR/language.namespaces.php). +Yii é um framework PHP. Portanto, certifique-se de [ler e entender a referência da linguagem](https://www.php.net/manual/pt_BR/langref.php). +Quando estiver desenvolvendo com Yii, você estará escrevendo código orientado a objetos, então, certifique-se de que está familiarizado tanto com [Classes e Objetos](https://www.php.net/manual/pt_BR/language.oop5.basic.php) como com [namespaces](https://www.php.net/manual/pt_BR/language.namespaces.php). ## Programação orientada a objetos diff --git a/docs/guide-pt-BR/start-workflow.md b/docs/guide-pt-BR/start-workflow.md index 1ff74a8f878..ae7025c6d4e 100644 --- a/docs/guide-pt-BR/start-workflow.md +++ b/docs/guide-pt-BR/start-workflow.md @@ -42,7 +42,7 @@ Estrutura da Aplicação Os diretórios e arquivos mais importantes em sua aplicação, assumindo que o diretório raiz dela é o `basico`, são: -``` +```js basico/ caminho base de sua aplicação composer.json usado pelo Composer, descreve informações de pacotes config/ contém as configurações da aplicação e outras @@ -63,7 +63,7 @@ basico/ caminho base de sua aplicação Em geral, os arquivos na aplicação podem ser divididos em dois tipos: aqueles em `basico/web` e aqueles em outros diretórios. Os primeiros podem ser acessados diretamente via HTTP (ou seja, em um navegador), enquanto os demais não podem e deveriam ser acessados. -O Yii implementa o padrão de arquitetura [modelo-visão-controlador (MVC)](http://wikipedia.org/wiki/Model-view-controller), +O Yii implementa o padrão de arquitetura [modelo-visão-controlador (MVC)](https://wikipedia.org/wiki/Model-view-controller), que se reflete na organização de diretórios acima. O diretório `models` contém todas as [classes de modelos](structure-models.md), o diretório `views` contém todos os [scripts de visões](structure-views.md), e o diretório `controllers` contém diff --git a/docs/guide-pt-BR/structure-applications.md b/docs/guide-pt-BR/structure-applications.md index 64075d9f915..8821be51cfe 100644 --- a/docs/guide-pt-BR/structure-applications.md +++ b/docs/guide-pt-BR/structure-applications.md @@ -302,7 +302,7 @@ exemplo, o widget [[yii\jui\DatePicker]] usará o valor dessa propriedade por padrão para determinar em qual idioma o calendário deverá ser exibido e como a data deve ser formatada. -Recomenda-se que você especifique um idioma em termos de um [código de idioma IETF](http://en.wikipedia.org/wiki/IETF_language_tag). +Recomenda-se que você especifique um idioma em termos de um [código de idioma IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Por exenplo, `en` corresponde ao inglês, enquanto `en-US` significa inglês dos Estados Unidos. @@ -385,7 +385,7 @@ configurar essa propriedade se o conteúdo do texto no seu código não estiver em inglês. Conforme a propriedade [language](#language), você deve configurar essa propriedade -em termos de um [código de idioma IETF](http://en.wikipedia.org/wiki/IETF_language_tag). +em termos de um [código de idioma IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Por exemplo, `en` corresponde ao inglês, enquanto `en-US` significa inglês dos Estados Unidos. @@ -398,7 +398,7 @@ Mais detalhes sobre essa propriedade podem ser encontrados na seção Essa propriedade é disponibilizada como uma maneira alternativa de definir a timezone do PHP em tempo de execução. Ao confiugrar essa propriedade, você está essencialmente chamando a função -[date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php) +[date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php) do PHP. Por exemplo: ```php diff --git a/docs/guide-pt-BR/structure-assets.md b/docs/guide-pt-BR/structure-assets.md index 304e7f0950b..c070de917e1 100644 --- a/docs/guide-pt-BR/structure-assets.md +++ b/docs/guide-pt-BR/structure-assets.md @@ -96,7 +96,7 @@ O bundle depende de outros dois bundles: [[yii\web\YiiAsset]] e arquivo pode ser determinado pela precedência do [[yii\web\AssetManager::baseUrl]] no caminho relativo. - uma URL absoluta representando um arquivo JavaScript externo. Por exemplo, - `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` ou + `https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` ou `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. * [[yii\web\AssetBundle::css|css]]: uma array listando os arquivos CSS contidos neste bundle. O formato deste array é igual ao que foi mencionado no @@ -250,14 +250,14 @@ class FontAwesomeAsset extends AssetBundle ``` O exemplo anterior define um asset bundle para o -[pacode de "fontawesome"](http://fontawesome.io/). Ao especificar a opção de +[pacode de "fontawesome"](https://fontawesome.com/). Ao especificar a opção de publicação `beforeCopy`, apenas os subdiretórios `fonts` e `css` serão publicados. ### Assets do Bower e NPM -A maioria dos pacotes JavaScript/CSS são gerenciados pelo [Bower](http://bower.io/) -e/ou [NPM](https://www.npmjs.org/). +A maioria dos pacotes JavaScript/CSS são gerenciados pelo [Bower](https://bower.io/) +e/ou [NPM](https://www.npmjs.com/). Se sua aplicação ou extensão estiver usando um destes pacotes, é recomendado que você siga os passos a seguir para gerenciar os assets na biblioteca: @@ -506,8 +506,8 @@ conforme descrito na subseção [Personalizando os Asset Bundles](#customizing-a Ao invés de escrever diretamente códigos CSS e/ou JavaScript, os desenvolvedores geralmente os escrevem em alguma sintaxe estendida e usam ferramentas especiais para converte-los em CSS/JavaScript. Por exemplo, para o código CSS você pode -usar [LESS](http://lesscss.org/) ou [SCSS](http://sass-lang.com/); e para o -JavaScript você pode usar o [TypeScript](http://www.typescriptlang.org/). +usar [LESS](https://lesscss.org/) ou [SCSS](https://sass-lang.com/); e para o +JavaScript você pode usar o [TypeScript](https://www.typescriptlang.org/). Você pode listar os arquivos de asset em sintaxe estendida nas propriedades [[yii\web\AssetBundle::css|css]] e [[yii\web\AssetBundle::js|js]] de um asset @@ -542,14 +542,14 @@ O Yii usa as extensões dos nomes de arquivos para identificar se é um asset co sintaxe estendida. Por padrão, o Yii reconhecerá as seguintes sintaxes e extensões de arquivos: -- [LESS](http://lesscss.org/): `.less` -- [SCSS](http://sass-lang.com/): `.scss` -- [Stylus](http://learnboost.github.io/stylus/): `.styl` -- [CoffeeScript](http://coffeescript.org/): `.coffee` -- [TypeScript](http://www.typescriptlang.org/): `.ts` +- [LESS](https://lesscss.org/): `.less` +- [SCSS](https://sass-lang.com/): `.scss` +- [Stylus](https://stylus-lang.com/): `.styl` +- [CoffeeScript](https://coffeescript.org/): `.coffee` +- [TypeScript](https://www.typescriptlang.org/): `.ts` O Yii conta com ferramentas de pré-processamento instalados para converter os -assets. Por exemplo, para usar o [LESS](http://lesscss.org/) você deve instalar +assets. Por exemplo, para usar o [LESS](https://lesscss.org/) você deve instalar o comando de pré-processamento `lessc`. Você pode personalizar os comandos de pré-processamento e o da sintaxe estendida @@ -581,7 +581,7 @@ de asset fonte e pelo caminho do arquivo de asset de destino. > Informação: Existem outros modos de trabalhar com assets em sintaxe estendida, além do descrito acima. Por exemplo, você pode usar ferramentas de compilação - tais como o [grunt](http://gruntjs.com/) para monitorar e automatizar a conversão + tais como o [grunt](https://gruntjs.com/) para monitorar e automatizar a conversão de assets em sintaxe estendidas. Neste caso, você deve listar os arquivos de CSS/JavaScript resultantes nos asset bundles ao invés dos arquivos originais. @@ -795,7 +795,7 @@ conforme descrito na última subseção. > Informação: O uso do comando `asset` não é a única opção para automatizar o processo de combinação e compressão de asset. Você pode usar a excelente - ferramenta chamada [grunt](http://gruntjs.com/) para atingir o mesmo objetivo. + ferramenta chamada [grunt](https://gruntjs.com/) para atingir o mesmo objetivo. ### Agrupando Asset Bundles diff --git a/docs/guide-pt-BR/structure-entry-scripts.md b/docs/guide-pt-BR/structure-entry-scripts.md index 1b887f0616a..d615fec3add 100644 --- a/docs/guide-pt-BR/structure-entry-scripts.md +++ b/docs/guide-pt-BR/structure-entry-scripts.md @@ -62,9 +62,9 @@ do console: /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-pt-BR/structure-extensions.md b/docs/guide-pt-BR/structure-extensions.md index 336099307d8..4fee19c41f0 100644 --- a/docs/guide-pt-BR/structure-extensions.md +++ b/docs/guide-pt-BR/structure-extensions.md @@ -91,7 +91,7 @@ Para fazer isto, você deve: 3. fazer o download e instalar todas as extensões dependentes que foi instruído. Se uma extensão não tiver uma classe autoloader seguindo a -[norma PSR-4](http://www.php-fig.org/psr/psr-4/), você pode usar a classe +[norma PSR-4](https://www.php-fig.org/psr/psr-4/), você pode usar a classe autoloader fornecida pelo Yii para carregar automaticamente as classes de extensão. Tudo o que você precisa fazer é declarar uma [alias root](concept-aliases.md#defining-aliases) para o diretório root da @@ -153,9 +153,9 @@ O exemplo a seguir mostra o arquivo `composer.json` para a extensão `yiisoft/yi "license": "BSD-3-Clause", "support": { "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki/", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "authors": [ @@ -219,9 +219,9 @@ de listar as constantes de versões apropriadas (por exemplo, `1.*`, `@stable`) para cada pacote dependente. Utilize dependências estáveis quando sua extensão estiver em uma versão estável. -A maioria dos pacotes JavaScript/CSS são gerenciados pelo [Bower](http://bower.io/) -e/ou pelo [NPM](https://www.npmjs.org/), ao invés do Composer. O Yii usa o -[plugin de asset do Composer](https://github.com/francoispluchino/composer-asset-plugin) +A maioria dos pacotes JavaScript/CSS são gerenciados pelo [Bower](https://bower.io/) +e/ou pelo [NPM](https://www.npmjs.com/), ao invés do Composer. O Yii usa o +[plugin de asset do Composer](https://github.com/fxpio/composer-asset-plugin) para habilitar a gerência destes tipos de pacotes através do Composer. Se sua extensão depender do pacote do Bower, você pode simplesmente listar a dependência no `composer.json` conforme o exemplo a seguir: @@ -286,8 +286,8 @@ alta qualidade. Para evitar conflitos de nomes e criar classes autocarregáveis em sua extensão, você deve usar namespaces e nomear as classes seguindo o -[padrão PSR-4](http://www.php-fig.org/psr/psr-4/) ou o -[padrão PSR-0](http://www.php-fig.org/psr/psr-0/). +[padrão PSR-4](https://www.php-fig.org/psr/psr-4/) ou o +[padrão PSR-0](https://www.php-fig.org/psr/psr-0/). Seus namespaces de classes devem iniciar com `vendorName\extensionName`, onde a `extensionName` é semelhante ao nome da extensão, exceto que ele não deve conter @@ -422,7 +422,7 @@ por favor, consulte a seção [Testing](test-overview.md). #### Versionamento Você deve dar para cada liberação de sua extensão um numero de versão (por exemplo, -`1.0.1`). Recomendamos que você siga a prática [versionamento semântico](http://semver.org) +`1.0.1`). Recomendamos que você siga a prática [versionamento semântico](https://semver.org) ao determinar qual número de versão será usado. @@ -444,7 +444,7 @@ a sua extensão: * Um arquivo readme no diretório root do pacote: descreve o que sua extensão faz e como faz para instalá-lo e usá-lo. Recomendamos que você escreva no formato - [Markdown](http://daringfireball.net/projects/markdown/) e o nome do arquivo + [Markdown](https://daringfireball.net/projects/markdown/) e o nome do arquivo como `readme.md`. * Um arquivo changelog no diretório root do pacote: lista quais mudanças foram feitas em cada versão. O arquivo pode ser escrito no formato Markdown e @@ -465,7 +465,7 @@ a sua extensão: > Informação: Embora não seja um requisito, sugerimos que sua extensão se conforme a determinados estilos de codificação. Você pode consultar o - [estilo de codificação do framework](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style). + [estilo de codificação do framework](https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md). ## Extensões Nativas @@ -482,16 +482,14 @@ e podem ser facilmente instalados como descrito na subseção [Usando Extensões client, GitHub OAuth2 client. - [yiisoft/yii2-bootstrap](https://github.com/yiisoft/yii2-bootstrap): fornece um conjunto de widgets que encapsulam os componentes e plug-ins do - [Bootstrap](http://getbootstrap.com/). -- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception): - fornece suporte a testes baseados no [Codeception](http://codeception.com/). + [Bootstrap](https://getbootstrap.com/). - [yiisoft/yii2-debug](https://github.com/yiisoft/yii2-debug): fornece suporte a depuração para aplicações Yii. Quando esta extensão é usada, uma barra de ferramenta de depuração aparecerá na parte inferior de cada página. A extensão também fornece um conjunto de páginas independentes para exibir mais detalhes das informações de depuração. - [yiisoft/yii2-elasticsearch](https://github.com/yiisoft/yii2-elasticsearch): - fornece suporte para o uso de [Elasticsearch](http://www.elasticsearch.org/). + fornece suporte para o uso de [Elasticsearch](https://www.elastic.co/). Este inclui suporte a consultas/pesquisas básicas e também implementa o padrão [Active Record](db-active-record.md) que permite que você armazene os active records no Elasticsearch. @@ -505,23 +503,23 @@ e podem ser facilmente instalados como descrito na subseção [Usando Extensões provides an HTTP client. - [yiisoft/yii2-imagine](https://github.com/yiisoft/yii2-imagine): fornece funções de manipulação de imagens comumente utilizados com base no - [Imagine](http://imagine.readthedocs.org/). + [Imagine](https://imagine.readthedocs.org/). - [yiisoft/yii2-jui](https://github.com/yiisoft/yii2-jui): fornece um conjunto de widgets que encapsulam as interações e widgets do - [JQuery UI](http://jqueryui.com/). + [JQuery UI](https://jqueryui.com/). - [yiisoft/yii2-mongodb](https://github.com/yiisoft/yii2-mongodb): - fornece suporte para o uso do [MongoDB](http://www.mongodb.org/). Este inclui + fornece suporte para o uso do [MongoDB](https://www.mongodb.com/). Este inclui recursos como consultas básicas, Active Record, migrations, cache, geração de códigos, etc. - [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis): - fornece suporte para o uso do [redis](http://redis.io/). Este inclui recursos + fornece suporte para o uso do [redis](https://redis.io/). Este inclui recursos como consultas básicas, Active Record, cache, etc. - [yiisoft/yii2-smarty](https://github.com/yiisoft/yii2-smarty): - fornece um motor de template baseado no [Smarty](http://www.smarty.net/). + fornece um motor de template baseado no [Smarty](https://www.smarty.net/). - [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx): - fornece suporte para o uso do [Sphinx](http://sphinxsearch.com). Este inclui + fornece suporte para o uso do [Sphinx](https://sphinxsearch.com). Este inclui recursos como consultas básicas, Active Record, geração de códigos, etc. - [yiisoft/yii2-swiftmailer](https://github.com/yiisoft/yii2-swiftmailer): - fornece recursos para envio de e-mails baseados no [swiftmailer](http://swiftmailer.org/). + fornece recursos para envio de e-mails baseados no [swiftmailer](https://swiftmailer.org/). - [yiisoft/yii2-twig](https://github.com/yiisoft/yii2-twig): - fornece um motor de template baseado no [Twig](http://twig.sensiolabs.org/). + fornece um motor de template baseado no [Twig](https://twig.symfony.com/). diff --git a/docs/guide-pt-BR/structure-filters.md b/docs/guide-pt-BR/structure-filters.md index 409f213af90..6ae35f1dad1 100644 --- a/docs/guide-pt-BR/structure-filters.md +++ b/docs/guide-pt-BR/structure-filters.md @@ -140,7 +140,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['create', 'update'], 'rules' => [ // permite aos usuários autenticados @@ -163,8 +163,8 @@ a seção [Autorização](security-authorization.md). O método de autenticação por filtros são usados para autenticar um usuário usando vários métodos, tais como -[HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication), -[OAuth 2](http://oauth.net/2/). Todas estas classes de filtros estão localizadas +[HTTP Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication), +[OAuth 2](https://oauth.net/2/). Todas estas classes de filtros estão localizadas sob o namespace `yii\filters\auth`. O exemplo a seguir mostra como você pode usar o filtro @@ -180,7 +180,7 @@ public function behaviors() { return [ 'basicAuth' => [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ], ]; } @@ -208,7 +208,7 @@ public function behaviors() { return [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -238,7 +238,7 @@ use yii\web\Response; [ 'bootstrap' => [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -270,7 +270,7 @@ public function behaviors() { return [ [ - 'class' => HttpCache::className(), + 'class' => HttpCache::class, 'only' => ['index'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); @@ -301,11 +301,11 @@ public function behaviors() { return [ 'pageCache' => [ - 'class' => PageCache::className(), + 'class' => PageCache::class, 'only' => ['index'], 'duration' => 60, 'dependency' => [ - 'class' => DbDependency::className(), + 'class' => DbDependency::class, 'sql' => 'SELECT COUNT(*) FROM post', ], 'variations' => [ @@ -323,7 +323,7 @@ detalhes sobre o uso do PageCache. ### [[yii\filters\RateLimiter|RateLimiter]] O filtro RateLimiter implementa um limitador de acesso baseado no -[algoritmo do balde furado (leaky bucket)](http://en.wikipedia.org/wiki/Leaky_bucket). +[algoritmo do balde furado (leaky bucket)](https://en.wikipedia.org/wiki/Leaky_bucket). É usado principalmente na implementação de APIs RESTful. Por favor, consulte a seção [Limitador de Acesso](rest-rate-limiting.md) para mais detalhes sobre o uso deste filtro. @@ -343,7 +343,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'index' => ['get'], 'view' => ['get'], @@ -380,7 +380,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, ], ], parent::behaviors()); } @@ -414,7 +414,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], @@ -436,7 +436,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], diff --git a/docs/guide-pt-BR/structure-models.md b/docs/guide-pt-BR/structure-models.md index 372d6a5c521..6516a6c3681 100644 --- a/docs/guide-pt-BR/structure-models.md +++ b/docs/guide-pt-BR/structure-models.md @@ -1,7 +1,7 @@ Models (Modelos) ================ -Os models (modelos) fazem parte da arquitetura [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). +Os models (modelos) fazem parte da arquitetura [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). Eles representam os dados, as regras e a lógica de negócio. Você pode criar uma classe model estendendo de [[yii\base\Model]] ou de seus filhos. @@ -43,8 +43,8 @@ echo $model->name; ``` Você também pode acessar os atributos como elementos de um array, graças ao suporte -de [ArrayAccess](https://secure.php.net/manual/en/class.arrayaccess.php) e -[ArrayIterator](https://secure.php.net/manual/en/class.arrayiterator.php) pelo +de [ArrayAccess](https://www.php.net/manual/en/class.arrayaccess.php) e +[ArrayIterator](https://www.php.net/manual/en/class.arrayiterator.php) pelo [[yii\base\Model]]: ```php diff --git a/docs/guide-pt-BR/structure-modules.md b/docs/guide-pt-BR/structure-modules.md index 9186321108b..73de5703082 100644 --- a/docs/guide-pt-BR/structure-modules.md +++ b/docs/guide-pt-BR/structure-modules.md @@ -20,7 +20,7 @@ controllers (controladores), models (modelos), views (visões) e outros códigos assim como em uma aplicação. O exemplo a seguir mostra o conteúdo dentro de um módulo: -``` +```js forum/ Module.php o arquivo da classe do módulo controllers/ contém os arquivos da classe controller diff --git a/docs/guide-pt-BR/structure-overview.md b/docs/guide-pt-BR/structure-overview.md index 7d97bbe4660..d9e10e4e3ff 100644 --- a/docs/guide-pt-BR/structure-overview.md +++ b/docs/guide-pt-BR/structure-overview.md @@ -2,7 +2,7 @@ Visão Geral =========== As aplicações do Yii são organizadas de acordo com o padrão de projeto -[model-view-controller (MVC)](http://pt.wikipedia.org/wiki/MVC) +[model-view-controller (MVC)](https://pt.wikipedia.org/wiki/MVC) (modelo-visão-controlador). Os [models](structure-models.md) representam dados, lógica e regras de negócio; as [views](structure-views.md) são a representação da saída dos modelos; e os [controllers](structure-controllers.md) recebem entradas diff --git a/docs/guide-pt-BR/structure-views.md b/docs/guide-pt-BR/structure-views.md index e92a4191f5c..b84f65dd1cd 100644 --- a/docs/guide-pt-BR/structure-views.md +++ b/docs/guide-pt-BR/structure-views.md @@ -1,7 +1,7 @@ Visões (Views) =========== -As views fazem parte da arquitetura [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). +As views fazem parte da arquitetura [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). São a parte do código responsável por apresentar dados aos usuários finais. Em um aplicação Web, views geralmente são criadas em termos de *view templates* (modelos de view) que são arquivos PHP contendo principalmente códigos HTML e @@ -61,7 +61,7 @@ desencadeiam a [renderização da view ](#rendering-views). Ao criar views que geram páginas HTML, é importante que você codifique e/ou filtre os dados que vêm de usuários antes de exibí-los. Caso contrário, sua aplicação poderá estar sujeita a um ataque de -[cross-site scripting](http://en.wikipedia.org/wiki/Cross-site_scripting). +[cross-site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting). Para exibir um texto simples, codifique-o antes por chamar o método [[yii\helpers\Html::encode()]]. Por exemplo, o código a seguir codifica o nome do @@ -606,7 +606,7 @@ Componentes de view fornecem úteis recursos relacionados. Cada um deles está d fragmento de uma página. * [manipulação de client scripts](output-client-scripts.md): permite que você registre e renderize CSS e JavaScript. * [manipulando asset bundle](structure-assets.md): permite que você registre e renderize [recursos estáticos (asset bundles)](structure-assets.md). -* [template engines alternativos](tutorial-template-engines.md): permite que você use outros template engines, tais como o [Twig](http://twig.sensiolabs.org/) +* [template engines alternativos](tutorial-template-engines.md): permite que você use outros template engines, tais como o [Twig](https://twig.symfony.com/) e [Smarty](http://www.smarty.net/). Você também pode usar os seguintes recursos que, embora simples, são úteis quando estiver desenvolvendo suas páginas. @@ -681,14 +681,14 @@ $this->registerLinkTag([ 'title' => 'Notícias sobre o Yii', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` O código acima resultará em ```html - + ``` Assim como no método [[yii\web\View::registerMetaTag()|registerMetaTags()]], diff --git a/docs/guide-pt-BR/translators.json b/docs/guide-pt-BR/translators.json index 869dde556f4..cc52faec676 100644 --- a/docs/guide-pt-BR/translators.json +++ b/docs/guide-pt-BR/translators.json @@ -5,6 +5,7 @@ "Gustavo G. Andrade", "Jan Silva", "Lucas Barros", + "Raphael de Almeida", "Sidney da Silva Lins", "Wanderson Bragança" -] \ No newline at end of file +] diff --git a/docs/guide-pt-BR/tutorial-core-validators.md b/docs/guide-pt-BR/tutorial-core-validators.md index d685b2acf09..650afc8ae04 100644 --- a/docs/guide-pt-BR/tutorial-core-validators.md +++ b/docs/guide-pt-BR/tutorial-core-validators.md @@ -92,7 +92,7 @@ Este validador compara o valor de entrada especificado com um outro e certifica Este validador verifica se o valor de entrada é uma data, hora ou data e hora em um formato adequado. Opcionalmente, pode converter o valor de entrada para um UNIX timestamp ou outro formato legível e armazená-lo em um atributo especificado via [[yii\validators\DateValidator::timestampAttribute|timestampAttribute]]. -- `format`: o formato date/time que o valor que está sendo validado deve ter. Este pode ser um padrão de data e hora conforme descrito no [ICU manual] (http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). Alternativamente esta pode ser uma string com o prefixo `php:` representando um formato que pode ser reconhecido pela classe PHP `Datetime`. Por favor, consulte para formatos suportados. Se isso não for definido, ele terá o valor de `Yii::$app->formatter->dateFormat`. Consulte a [[yii\validators\DateValidator::$format|documentação da API]] para mais detalhes. +- `format`: o formato date/time que o valor que está sendo validado deve ter. Este pode ser um padrão de data e hora conforme descrito no [ICU manual] (https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax). Alternativamente esta pode ser uma string com o prefixo `php:` representando um formato que pode ser reconhecido pela classe PHP `Datetime`. Por favor, consulte para formatos suportados. Se isso não for definido, ele terá o valor de `Yii::$app->formatter->dateFormat`. Consulte a [[yii\validators\DateValidator::$format|documentação da API]] para mais detalhes. - `timestampAttribute`: o nome do atributo para que este validador possa atribuir o UNIX timestamp convertido a partir da entrada de data / hora. Este pode ser o mesmo atributo que está sendo validado. Se este for o caso, valor original será substituído pelo valor timestamp após a validação. Veja a seção ["Manipulando Datas com DatePicker"] (https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/topics-date-picker.md) para exemplos de uso. @@ -238,7 +238,7 @@ Você pode usar este validador para validar uma ou várias colunas (ex., a combi Este validador verifica se o dados de entrada é um arquivo válido. - `extensions`: uma lista de extensões de arquivos que são permitidos para upload. Pode ser utilizado tanto um array quanto uma string constituída de extensões de arquivos separados por espaços ou por vírgulas (Ex. "gif, jpg"). Os nomes das extensões são case-insensitive. O padrão é `null`, significa que todas as extensões são permitidas. -- `mimeTypes`: uma lista de tipos de arquivos MIME que são permitidos no upload. Pode ser utilizado tanto um array quanto uma string constituída de tipos MIME separados por espaços ou por virgulas (ex. "image/jpeg, image/png"). Os nomes dos tipos MIME são case-insensitivo. O padrão é `null`, significa que todos os tipos MIME são permitidos. Para mais detalhes, consulte o artigo [common media types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types). +- `mimeTypes`: uma lista de tipos de arquivos MIME que são permitidos no upload. Pode ser utilizado tanto um array quanto uma string constituída de tipos MIME separados por espaços ou por virgulas (ex. "image/jpeg, image/png"). Os nomes dos tipos MIME são case-insensitivo. O padrão é `null`, significa que todos os tipos MIME são permitidos. Para mais detalhes, consulte o artigo [common media types](https://en.wikipedia.org/wiki/Media_type). - `minSize`: o número mínimo de bytes exigido para o arquivo carregado. O padrão é `null`, significa não ter limite mínimo. - `maxSize`: o número máximo de bytes exigido para o arquivo carregado. O padrão é `null`, significa não ter limite máximo. - `maxFiles`: o número máximo de arquivos que o atributo pode receber. O padrão é 1, ou seja, a entrada de dados deve ser composto de um único arquivo. Se o `maxFiles` for maior que 1, então a entrada de dados deve ser composto por um array constituído de no máximo `maxFiles` arquivos. @@ -270,8 +270,8 @@ Este validador não valida dados. Em vez disso, aplica um filtro no valor de ent > Dica: Se você quiser trimar valores de entrada, você deve utilizar o validador [trim](#trim). > Dica: Existem várias funções PHP que tem a assinatura esperada para o callback do `filter`. -> Por exemplo, para aplicar a conversão de tipos (usando por exemplo [intval](https://secure.php.net/manual/en/function.intval.php), -> [boolval](https://secure.php.net/manual/en/function.boolval.php), ...) para garantir um tipo específico para um atributo, +> Por exemplo, para aplicar a conversão de tipos (usando por exemplo [intval](https://www.php.net/manual/en/function.intval.php), +> [boolval](https://www.php.net/manual/en/function.boolval.php), ...) para garantir um tipo específico para um atributo, > você pode simplesmente especificar os nomes das funções do filtro sem a necessidade de envolvê-los em um closure: > > ```php diff --git a/docs/guide-pt-BR/tutorial-yii-integration.md b/docs/guide-pt-BR/tutorial-yii-integration.md index d318b99b2e1..75d233cc9c5 100644 --- a/docs/guide-pt-BR/tutorial-yii-integration.md +++ b/docs/guide-pt-BR/tutorial-yii-integration.md @@ -34,7 +34,7 @@ Se a biblioteca não foi lançada como um pacote Composer, você deve seguir as Se uma biblioteca possui o seu próprio carregador automático, você pode instalá-la no [script de entrada](structure-entry-scripts.md) de sua aplicação. Recomenda-se que a instalação seja feita antes de incluir o arquivo `Yii.php`. Isto porque a classe autoloader Yii pode ter precedência nas classes de carregamento automático da biblioteca a ser instalada. -Se uma biblioteca não oferece um carregador automático de classe, mas seus nomes seguem o padrão [PSR-4](http://www.php-fig.org/psr/psr-4/), você pode usar a classe de autoloader do Yii para carregar as classes. Tudo que você precisa fazer é apenas declarar um [alias](concept-aliases.md#defining-aliases) para cada namespace raiz utilizados em suas classes. Por exemplo, suponha que você tenha instalado uma biblioteca no diretório `vendor/foo/bar` e as classes de bibliotecas estão sob o namespace raiz `xyz`. Você pode incluir o seguinte código na configuração da sua aplicação: +Se uma biblioteca não oferece um carregador automático de classe, mas seus nomes seguem o padrão [PSR-4](https://www.php-fig.org/psr/psr-4/), você pode usar a classe de autoloader do Yii para carregar as classes. Tudo que você precisa fazer é apenas declarar um [alias](concept-aliases.md#defining-aliases) para cada namespace raiz utilizados em suas classes. Por exemplo, suponha que você tenha instalado uma biblioteca no diretório `vendor/foo/bar` e as classes de bibliotecas estão sob o namespace raiz `xyz`. Você pode incluir o seguinte código na configuração da sua aplicação: ```php [ @@ -70,11 +70,11 @@ Se o sistema em questão utilizar o Composer para gerenciar suas dependências, composer require yiisoft/yii2 composer install -O primeiro comando instala o [Composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) +O primeiro comando instala o [Composer asset plugin](https://github.com/fxpio/composer-asset-plugin) que permite gerenciar o bower e dependências de pacotes npm através do Composer. Mesmo que você apenas queira utilizar a camada de banco de dados ou outros recursos não-ativos relacionados do Yii, isto é necessário para instalar o pacote Composer do Yii. Veja também a seção [sobre a instalação do Yii](start-installation.md#installing-via-composer) para obter mais informações do Composer e solução para os possíveis problemas que podem surgir durante a instalação. -Caso contrário, você pode fazer o [download](http://www.yiiframework.com/download/) do Yii e descompactá-lo no diretório `BasePath/vendor`. +Caso contrário, você pode fazer o [download](https://www.yiiframework.com/download/) do Yii e descompactá-lo no diretório `BasePath/vendor`. Em seguida, você deve modificar o script de entrada do sistema de terceiros incluindo o seguinte código no início: diff --git a/docs/guide-ru/README.md b/docs/guide-ru/README.md index 71f4d9ff21c..9cff24a678b 100644 --- a/docs/guide-ru/README.md +++ b/docs/guide-ru/README.md @@ -1,7 +1,7 @@ Полное руководство по Yii 2.0 ============================= -Данное руководство выпущено в соответствии с [положениями о документации Yii](http://www.yiiframework.com/doc/terms/). +Данное руководство выпущено в соответствии с [положениями о документации Yii](https://www.yiiframework.com/doc/terms/). All Rights Reserved. @@ -181,14 +181,14 @@ All Rights Reserved. Виджеты ------- -* [GridView](http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) -* [ListView](http://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) -* [DetailView](http://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) -* [ActiveForm](http://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) -* [Pjax](http://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) -* [Menu](http://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) -* [LinkPager](http://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) -* [LinkSorter](http://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) +* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) +* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) +* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) +* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) +* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) +* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) +* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) +* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) * [Виджеты Bootstrap](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide-ru/README.md) * [Виджеты Jquery UI](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide-ru/README.md) diff --git a/docs/guide-ru/caching-data.md b/docs/guide-ru/caching-data.md index 1dab06a2b80..4ceee3fb3ab 100644 --- a/docs/guide-ru/caching-data.md +++ b/docs/guide-ru/caching-data.md @@ -53,7 +53,7 @@ $data = $cache->getOrSet($key, function () use ($user_id) { Кэширование данных опирается на *компоненты кэширования*, которые представляют различные хранилища, такие как память, файлы и базы данных. -Кэш-компоненты, как правило, зарегистрированы в качестве [компонентов приложения](structure-application-components.md), так что их можно настраивать и обращаться к ним глобально. Следующий код показывает, как настроить компонент приложения `cache` для использования [Memcached](http://memcached.org/) с двумя серверами: +Кэш-компоненты, как правило, зарегистрированы в качестве [компонентов приложения](structure-application-components.md), так что их можно настраивать и обращаться к ним глобально. Следующий код показывает, как настроить компонент приложения `cache` для использования [Memcached](https://memcached.org/) с двумя серверами: ```php 'components' => [ @@ -95,15 +95,15 @@ $data = $cache->getOrSet($key, function () use ($user_id) { Yii поддерживает множество хранилищ кэша: -* [[yii\caching\ApcCache]]: использует расширение PHP [APC](https://secure.php.net/manual/en/book.apc.php). Эта опция считается самой быстрой при работе с кэшем в «толстом» централизованном приложении (т.е. один сервер, без выделенного балансировщика нагрузки и т.д.); +* [[yii\caching\ApcCache]]: использует расширение PHP [APC](https://www.php.net/manual/en/book.apcu.php). Эта опция считается самой быстрой при работе с кэшем в «толстом» централизованном приложении (т.е. один сервер, без выделенного балансировщика нагрузки и т.д.); * [[yii\caching\DbCache]]: использует таблицу базы данных для хранения кэшированных данных. Чтобы использовать этот кэш, вы должны создать таблицу так, как это описано в [[yii\caching\DbCache::cacheTable]]; * [[yii\caching\DummyCache]]: является кэшем-пустышкой, не реализующим реального кэширования. Смысл этого компонента в упрощении кода, проверяющего наличие кэша. Вы можете использовать данный тип кэша и переключиться на реальное кэширование позже. Примеры: использование при разработке; если сервер не поддерживает кэш. Для извлечения данных в этом случае используется один и тот же код `Yii::$app->cache->get($key)`. При этом можно не беспокоиться, что `Yii::$app->cache` может быть `null`; * [[yii\caching\FileCache]]: использует обычные файлы для хранения кэшированных данных. Замечательно подходит для кэширования больших кусков данных, таких как содержимое страницы; -* [[yii\caching\MemCache]]: использует расширения PHP [memcache](https://secure.php.net/manual/en/book.memcache.php) и [memcached](https://secure.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) ([смотрите также](https://secure.php.net/manual/en/book.wincache.php)); -* [[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). +* [[yii\caching\MemCache]]: использует расширения PHP [memcache](https://www.php.net/manual/en/book.memcache.php) и [memcached](https://www.php.net/manual/en/book.memcached.php). Этот вариант может рассматриваться как самый быстрый при работе в распределенных приложениях (например, с несколькими серверами, балансировкой нагрузки и так далее); +* [[yii\redis\Cache]]: реализует компонент кэша на основе [Redis](https://redis.io/), хранилища ключ-значение (требуется Redis версии 2.6.12 или выше); +* [[yii\caching\WinCache]]: использует расширение PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) ([смотрите также](https://www.php.net/manual/en/book.wincache.php)); +* [[yii\caching\XCache]] _(deprecated)_: использует расширение PHP [XCache](https://en.wikipedia.org/wiki/List_of_PHP_accelerators#XCache); +* [[yii\caching\ZendDataCache]] _(deprecated)_: использует [Zend Data Cache](https://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm). > Tip: Вы можете использовать разные способы хранения кэша в одном приложении. Общая стратегия заключается в использовании памяти под хранение небольших часто используемых данных (например, статистические данные). Для больших и реже используемых данных (например, содержимое страницы) лучше использовать файлы или базу данных. @@ -249,10 +249,10 @@ $result = Customer::getDb()->cache(function ($db) { }); ``` -> Info: Некоторые СУБД (например, [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) поддерживают кэширование запросов любого механизма на стороне сервера БД. КЗ описано разделом выше. Оно имеет безусловное преимущество, поскольку, благодаря ему, можно указать гибкие зависимости кэша и это более эффективно. +> Info: Некоторые СУБД (например, [MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html)) поддерживают кэширование запросов любого механизма на стороне сервера БД. КЗ описано разделом выше. Оно имеет безусловное преимущество, поскольку, благодаря ему, можно указать гибкие зависимости кэша и это более эффективно. -### Очистка кэша +### Очистка кэша Для очистки всего кэша, вы можете вызвать [[yii\caching\Cache::flush()]]. diff --git a/docs/guide-ru/caching-http.md b/docs/guide-ru/caching-http.md index d0ae15a2d3a..9d25e163073 100644 --- a/docs/guide-ru/caching-http.md +++ b/docs/guide-ru/caching-http.md @@ -89,7 +89,7 @@ ETags позволяет применять более сложные и/или Ресурсоёмкая генерация ETag может противоречить цели использования `HttpCache` и внести излишнюю нагрузку, т.к. он должен пересоздаваться при каждом запросе. Попробуйте найти простое выражение, которое инвалидирует кэш, если содержание страницы было изменено. -> Note: В соответствии с [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4), +> Note: В соответствии с [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4), `HttpCache` будет отправлять как `ETag` заголовок, так и `Last-Modified` заголовок, если они оба были настроены. И если клиент отправляет как `If-None-Match` заголовок, так и `If-Modified-Since` заголовок, то только первый из них будет принят. @@ -104,7 +104,7 @@ Cache-Control: public, max-age=3600 ## Ограничитель кэша сессий -Когда на странице используются сессии, PHP автоматически отправляет некоторые связанные с кэшем HTTP заголовки, определённые в настройке `session.cache_limiter` в php.ini. Эти заголовки могут вмешиваться или отключать кэширование, которое вы ожидаете от `HttpCache`. Чтобы предотвратить эту проблему, по умолчанию `HttpCache` будет автоматически отключать отправку этих заголовков. Если вы хотите изменить это поведение, вы должны настроить свойство [[yii\filters\HttpCache::sessionCacheLimiter]]. Это свойство может принимать строковое значение, включая `public`, `private`, `private_no_expire` и `nocache`. Пожалуйста, обратитесь к руководству PHP о [session_cache_limiter()](https://secure.php.net/manual/en/function.session-cache-limiter.php) +Когда на странице используются сессии, PHP автоматически отправляет некоторые связанные с кэшем HTTP заголовки, определённые в настройке `session.cache_limiter` в php.ini. Эти заголовки могут вмешиваться или отключать кэширование, которое вы ожидаете от `HttpCache`. Чтобы предотвратить эту проблему, по умолчанию `HttpCache` будет автоматически отключать отправку этих заголовков. Если вы хотите изменить это поведение, вы должны настроить свойство [[yii\filters\HttpCache::sessionCacheLimiter]]. Это свойство может принимать строковое значение, включая `public`, `private`, `private_no_expire` и `nocache`. Пожалуйста, обратитесь к руководству PHP о [session_cache_limiter()](https://www.php.net/manual/en/function.session-cache-limiter.php) для объяснения этих значений. diff --git a/docs/guide-ru/concept-autoloading.md b/docs/guide-ru/concept-autoloading.md index f24e01674cc..f3394b45110 100644 --- a/docs/guide-ru/concept-autoloading.md +++ b/docs/guide-ru/concept-autoloading.md @@ -2,7 +2,7 @@ ================= Поиск и подключение файлов классов в Yii реализовано при помощи -[автозагрузки классов](https://secure.php.net/manual/ru/language.oop5.autoload.php). Фреймворк предоставляет свой быстрый +[автозагрузки классов](https://www.php.net/manual/ru/language.oop5.autoload.php). Фреймворк предоставляет свой быстрый совместимый с [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md) автозагрузчик, который устанавливается в момент подключения `Yii.php`. @@ -14,7 +14,7 @@ При использовании автозагрузчика классов Yii следует соблюдать два простых правила создания и именования классов: -* Каждый класс должен принадлежать [пространству имён](https://secure.php.net/manual/ru/language.namespaces.php) +* Каждый класс должен принадлежать [пространству имён](https://www.php.net/manual/ru/language.namespaces.php) (то есть `foo\bar\MyClass`). * Каждый класс должен находиться в отдельном файле, путь к которому определятся следующим правилом: diff --git a/docs/guide-ru/concept-behaviors.md b/docs/guide-ru/concept-behaviors.md index de7126df509..555b13a6920 100644 --- a/docs/guide-ru/concept-behaviors.md +++ b/docs/guide-ru/concept-behaviors.md @@ -126,21 +126,21 @@ class User extends ActiveRecord { return [ // анонимное поведение, прикрепленное по имени класса - MyBehavior::className(), + MyBehavior::class, // именованное поведение, прикрепленное по имени класса - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // анонимное поведение, сконфигурированное с использованием массива [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // именованное поведение, сконфигурированное с использованием массива 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ] @@ -164,11 +164,11 @@ use app\components\MyBehavior; $component->attachBehavior('myBehavior1', new MyBehavior); // прикрепляем по имени класса поведения -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // прикрепляем используя массив конфигураций $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -180,7 +180,7 @@ $component->attachBehavior('myBehavior3', [ ```php $component->attachBehaviors([ 'myBehavior1' => new MyBehavior, // именованное поведение - MyBehavior::className(), // анонимное поведение + MyBehavior::class, // анонимное поведение ]); ``` @@ -188,10 +188,10 @@ $component->attachBehaviors([ ```php [ - 'as myBehavior2' => MyBehavior::className(), + 'as myBehavior2' => MyBehavior::class, 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -280,7 +280,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -332,7 +332,7 @@ $user->touch('login_time'); - [[yii\behaviors\AttributeBehavior]] - автоматически задаёт указанное значение одному или нескольким атрибутам ActiveRecord при срабатывании определённых событий. - [yii2tech\ar\softdelete\SoftDeleteBehavior](https://github.com/yii2tech/ar-softdelete) - предоставляет методы для - «мягкого» удаления и воосстановления ActiveRecord. То есть выставляет статус или флаг, который показывает, что + «мягкого» удаления и восстановления ActiveRecord. То есть выставляет статус или флаг, который показывает, что запись удалена. - [yii2tech\ar\position\PositionBehavior](https://github.com/yii2tech/ar-position) - позволяет управлять порядком записей через специальные методы. Информация сохраняется в целочисленном поле. @@ -341,7 +341,7 @@ $user->touch('login_time'); Сравнение с трейтами --------------------------------------------------- -Несмотря на то, что поведения схожи с [трейтами](https://secure.php.net/manual/ru/language.oop5.traits.php) тем, что +Несмотря на то, что поведения схожи с [трейтами](https://www.php.net/manual/ru/language.oop5.traits.php) тем, что "внедряют" свои свойства и методы в основной класс, они имеют множество отличий. Они оба имеют свои плюсы и минусы, и, скорее, дополняют друг друга, а не заменяют. diff --git a/docs/guide-ru/concept-components.md b/docs/guide-ru/concept-components.md index b76a2637d83..05c91df1554 100644 --- a/docs/guide-ru/concept-components.md +++ b/docs/guide-ru/concept-components.md @@ -77,7 +77,7 @@ class MyClass extends BaseObject $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // альтернативный способ $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide-ru/concept-di-container.md b/docs/guide-ru/concept-di-container.md index 5ad53617611..80c2c723d86 100644 --- a/docs/guide-ru/concept-di-container.md +++ b/docs/guide-ru/concept-di-container.md @@ -2,7 +2,7 @@ ============================== Контейнер внедрения зависимостей — это объект, который знает, как создать и настроить экземпляр класса и зависимых от него объектов. -[Статья Мартина Фаулера](http://martinfowler.com/articles/injection.html) хорошо объясняет, почему контейнер внедрения зависимостей является полезным. Здесь, преимущественно, будет объясняться использование контейнера внедрения зависимостей, предоставляемого в Yii. +[Статья Мартина Фаулера](https://martinfowler.com/articles/injection.html) хорошо объясняет, почему контейнер внедрения зависимостей является полезным. Здесь, преимущественно, будет объясняться использование контейнера внедрения зависимостей, предоставляемого в Yii. Внедрение зависимостей @@ -509,7 +509,7 @@ class HotelController extends Controller Как dependency injection, так и [service locator](concept-service-locator.md) являются популярными паттернами проектирования, которые позволяют создавать программное обеспечение в слабосвязанной и более тестируемой манере. Мы настоятельно рекомендуем к прочтению -[статью Мартина Фаулера](http://martinfowler.com/articles/injection.html), для более глубокого понимания dependency injection и service locator. +[статью Мартина Фаулера](https://martinfowler.com/articles/injection.html), для более глубокого понимания dependency injection и service locator. Yii реализует свой [service locator](concept-service-locator.md) поверх контейнера внедрения зависимостей. Когда service locator пытается создать новый экземпляр объекта, он перенаправляет вызов на контейнер внедрения зависимостей. diff --git a/docs/guide-ru/concept-events.md b/docs/guide-ru/concept-events.md index f9eb47d0dcb..9c75b3109d1 100644 --- a/docs/guide-ru/concept-events.md +++ b/docs/guide-ru/concept-events.md @@ -9,7 +9,7 @@ Обработчики событий -------------- -Обработчик события - это [callback-функция PHP](https://secure.php.net/manual/ru/language.types.callable.php), которая выполняется при срабатывании события, к которому она присоединена. Можно использовать следующие callback-функции: +Обработчик события - это [callback-функция PHP](https://www.php.net/manual/ru/language.types.callable.php), которая выполняется при срабатывании события, к которому она присоединена. Можно использовать следующие callback-функции: - глобальную функцию PHP, указав строку с именем функции (без скобок), например, `'trim'`; - метод объекта, указав массив, содержащий строки с именами объекта и метода (без скобок), например, `[$object, 'methodName']`; @@ -187,7 +187,7 @@ use Yii; use yii\base\Event; use yii\db\ActiveRecord; -Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { +Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::debug(get_class($event->sender) . ' добавлен'); }); ``` @@ -201,11 +201,11 @@ Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ```php use yii\base\Event; -Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { +Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) { var_dump($event->sender); // выводит "null" }); -Event::trigger(Foo::className(), Foo::EVENT_HELLO); +Event::trigger(Foo::class, Foo::EVENT_HELLO); ``` Обратите внимание, что в данном случае `$event->sender` имеет значение `null` вместо экзепляра класса, который инициировал событие. @@ -216,10 +216,10 @@ Event::trigger(Foo::className(), Foo::EVENT_HELLO); ```php // отсоединение $handler -Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); +Event::off(Foo::class, Foo::EVENT_HELLO, $handler); // отсоединяются все обработчики Foo::EVENT_HELLO -Event::off(Foo::className(), Foo::EVENT_HELLO); +Event::off(Foo::class, Foo::EVENT_HELLO); ``` Обработчики событий на уровне интерфейсов @@ -274,10 +274,10 @@ Event::on('app\interfaces\DanceEventInterface', DanceEventInterface::EVENT_DANCE ```php // trigger event for Dog class -Event::trigger(Dog::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Dog::class, DanceEventInterface::EVENT_DANCE); // trigger event for Developer class -Event::trigger(Developer::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Developer::class, DanceEventInterface::EVENT_DANCE); ``` Однако невозможно инициализировать событие во всех классах, которые реализуют интерфейс: diff --git a/docs/guide-ru/db-active-record.md b/docs/guide-ru/db-active-record.md index 2602fd600b4..33479f3bce5 100644 --- a/docs/guide-ru/db-active-record.md +++ b/docs/guide-ru/db-active-record.md @@ -1,7 +1,7 @@ Active Record ============= -[Active Record](http://ru.wikipedia.org/wiki/ActiveRecord) обеспечивает объектно-ориентированный интерфейс для доступа +[Active Record](https://ru.wikipedia.org/wiki/ActiveRecord) обеспечивает объектно-ориентированный интерфейс для доступа и манипулирования данными, хранящимися в базах данных. Класс Active Record соответствует таблице в базе данных, объект Active Record соответствует строке этой таблицы, а *атрибут* объекта Active Record представляет собой значение отдельного столбца строки. Вместо непосредственного написания SQL-выражений вы сможете получать доступ к атрибутам @@ -689,7 +689,7 @@ try { ``` > Note: в коде выше ради совместимости с PHP 5.x и PHP 7.x использованы два блока catch. -> `\Exception` реализует интерфейс [`\Throwable` interface](https://secure.php.net/manual/ru/class.throwable.php) +> `\Exception` реализует интерфейс [`\Throwable` interface](https://www.php.net/manual/ru/class.throwable.php) > начиная с PHP 7.0. Если вы используете только PHP 7 и новее, можете пропустить блок с `\Exception`. Второй способ заключается в том, чтобы перечислить операции с базой данных, которые требуют тразнакционного выполнения, @@ -809,7 +809,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -817,7 +817,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -834,7 +834,7 @@ class Order extends ActiveRecord что покупатель может иметь много заказов в то время, как заказ может быть сделан лишь одним покупателем. - название связного Active Record класса: указывается в качестве первого параметра для метода [[yii\db\ActiveRecord::hasMany()|hasMany()]] или для метода [[yii\db\ActiveRecord::hasOne()|hasOne()]]. Рекомендуется - использовать код `Xyz::className()`, чтобы получить строку с именем класса, при этом вы сможете воспользоваться + использовать код `Xyz::class`, чтобы получить строку с именем класса, при этом вы сможете воспользоваться возможностями авто-дополнения кода, встроенного в IDE, а также получите обработку ошибок на этапе компиляции. - связь между двумя типами данных: указываются столбцы с помощью которых два типа данных связаны. Значения массива - это столбцы основного объекта данных (представлен классом Active Record, в котором объявляется связь), в то время как @@ -844,6 +844,7 @@ class Order extends ActiveRecord указывается сразу после указания самого класса Active Record. Вы видите, что `customer_id` - это свойство класса `Order`, а `id` - свойство класса `Customer`. +> Warning: Имя связи `relation` зарезервировано. Его использование приведёт к ошибке `ArgumentCountError`. ### Доступ к связным данным @@ -874,14 +875,14 @@ SQL-выражения. Для принудительного повторног операции: `unset($customer->orders)`. > Note: Несмотря на то, что эта концепция выглядит похожей на концепцию [свойств объектов](concept-properties.md), - между ними есть важное различие. Для обычных свойств объектов значения свойств имеют тот же тип, который возвращает - геттер. Однако метод получения связных данных возвращает объект [[yii\db\ActiveQuery]], в то время как доступ к - свойству связи возвращает объект [[yii\db\ActiveRecord]] или массив таких объектов. - ```php - $customer->orders; // массив объектов `Order` - $customer->getOrders(); // объект ActiveQuery - ``` - Это полезно при тонкой настройке запросов к связным данным, что будет описано в следующем разделе. +> между ними есть важное различие. Для обычных свойств объектов значения свойств имеют тот же тип, который возвращает +> геттер. Однако метод получения связных данных возвращает объект [[yii\db\ActiveQuery]], в то время как доступ к +> свойству связи возвращает объект [[yii\db\ActiveRecord]] или массив таких объектов. +> ```php +> $customer->orders; // массив объектов `Order` +> $customer->getOrders(); // объект ActiveQuery +> ``` +> Это полезно при тонкой настройке запросов к связным данным, что будет описано в следующем разделе. ### Динамические запросы связных данных @@ -910,7 +911,7 @@ class Customer extends ActiveRecord { public function getBigOrders($threshold = 100) { - return $this->hasMany(Order::className(), ['customer_id' => 'id']) + return $this->hasMany(Order::class, ['customer_id' => 'id']) ->where('subtotal > :threshold', [':threshold' => $threshold]) ->orderBy('id'); } @@ -931,7 +932,7 @@ $orders = $customer->bigOrders; ### Связывание посредством промежуточной таблицы При проектировании баз данных, когда между двумя таблицами имеется кратность связи many-to-many, обычно вводится -[промежуточная таблица](http://en.wikipedia.org/wiki/Junction_table). Например, таблицы `order` и `item` могут быть +[промежуточная таблица](https://en.wikipedia.org/wiki/Junction_table). Например, таблицы `order` и `item` могут быть связаны посредством промежуточной таблицы с названием `order_item`. Один заказ будет соотноситься с несколькими товарами, в то время как один товар будет также соотноситься с несколькими заказами. @@ -946,7 +947,7 @@ class Order extends ActiveRecord { public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->viaTable('order_item', ['order_id' => 'id']); } } @@ -959,12 +960,12 @@ class Order extends ActiveRecord { public function getOrderItems() { - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } } @@ -1235,7 +1236,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -1243,7 +1244,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -1277,7 +1278,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); } } ``` @@ -1390,7 +1391,7 @@ class Customer extends \yii\db\ActiveRecord public function getComments() { // у покупателя может быть много комментариев - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1405,7 +1406,7 @@ class Comment extends \yii\mongodb\ActiveRecord public function getCustomer() { // комментарий принадлежит одному покупателю - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } @@ -1485,7 +1486,7 @@ class Customer extends \yii\db\ActiveRecord { public function getActiveComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id'])->active(); + return $this->hasMany(Comment::class, ['customer_id' => 'id'])->active(); } } @@ -1556,7 +1557,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1652,7 +1653,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1683,7 +1684,7 @@ class Customer extends \yii\db\ActiveRecord */ public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } /** diff --git a/docs/guide-ru/db-dao.md b/docs/guide-ru/db-dao.md index 9fbeae164eb..ae7275bad61 100644 --- a/docs/guide-ru/db-dao.md +++ b/docs/guide-ru/db-dao.md @@ -1,7 +1,7 @@ Объекты доступа к данным (DAO) ============================== -Построенные поверх [PDO](https://secure.php.net/manual/ru/book.pdo.php), Yii DAO (объекты доступа к данным) обеспечивают +Построенные поверх [PDO](https://www.php.net/manual/ru/book.pdo.php), Yii DAO (объекты доступа к данным) обеспечивают объектно-ориентированный API для доступа к реляционным базам данных. Это основа для других, более продвинутых, методов доступа к базам данных, включая [построитель запросов](db-query-builder.md) и [active record](db-active-record.md). @@ -12,12 +12,12 @@ Yii DAO из коробки поддерживает следующие базы данных: -- [MySQL](http://www.mysql.com/) +- [MySQL](https://www.mysql.com/) - [MariaDB](https://mariadb.com/) -- [SQLite](http://sqlite.org/) -- [PostgreSQL](http://www.postgresql.org/): версии 8.4 или выше. -- [CUBRID](http://www.cubrid.org/): версии 9.3 или выше. -- [Oracle](http://www.oracle.com/us/products/database/overview/index.html) +- [SQLite](https://sqlite.org/) +- [PostgreSQL](https://www.postgresql.org/): версии 8.4 или выше. +- [CUBRID](https://www.cubrid.org/): версии 9.3 или выше. +- [Oracle](https://www.oracle.com/database/) - [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): версии 2008 или выше. @@ -62,7 +62,7 @@ return [ > Tip: Вы можете настроить несколько компонентов подключения, если в вашем приложении используется несколько баз данных. При настройке подключения, вы должны обязательно указывать Имя Источника Данных (DSN) через параметр [[yii\db\Connection::dsn|dsn]]. -Формат DSN отличается для разных баз данных. Дополнительное описание смотрите в [справочнике PHP](https://secure.php.net/manual/ru/pdo.construct.php). +Формат DSN отличается для разных баз данных. Дополнительное описание смотрите в [справочнике PHP](https://www.php.net/manual/ru/pdo.construct.php). Ниже представлены несколько примеров: * MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` @@ -174,7 +174,7 @@ $post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status ->queryOne(); ``` -Привязка переменных реализована через [подготавливаемые запросы](https://secure.php.net/manual/ru/mysqli.quickstart.prepared-statements.php). +Привязка переменных реализована через [подготавливаемые запросы](https://www.php.net/manual/ru/mysqli.quickstart.prepared-statements.php). Помимо предотвращения атак путём SQL инъекций, это увеличивает производительность, так как запрос подготавливается один раз, а потом выполняется много раз с разными параметрами. Например, @@ -338,7 +338,7 @@ try { ``` > Note: в коде выше ради совместимости с PHP 5.x и PHP 7.x использованы два блока catch. -> `\Exception` реализует интерфейс [`\Throwable` interface](https://secure.php.net/manual/ru/class.throwable.php) +> `\Exception` реализует интерфейс [`\Throwable` interface](https://www.php.net/manual/ru/class.throwable.php) > начиная с PHP 7.0. Если вы используете только PHP 7 и новее, можете пропустить блок с `\Exception`. При вызове метода [[yii\db\Connection::beginTransaction()|beginTransaction()]], будет запущена новая транзакция. @@ -435,7 +435,7 @@ try { ## Репликация и разделение запросов на чтение и запись -Многие СУБД поддерживают [репликацию баз данных](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) +Многие СУБД поддерживают [репликацию баз данных](https://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) для лучшей доступности базы данных и уменьшения времени ответа сервера. С репликацией базы данных, данные копируются из *master servers* на *slave servers*. Все вставки и обновления должны происходить на основном сервере, хотя чтение может производится и с подчинённых серверов. diff --git a/docs/guide-ru/db-migrations.md b/docs/guide-ru/db-migrations.md index 24d1091f227..b35823a0634 100644 --- a/docs/guide-ru/db-migrations.md +++ b/docs/guide-ru/db-migrations.md @@ -591,7 +591,7 @@ class m150101_185401_create_news_table extends Migration а затем вставили строку в `safeUp()`; а в `safeDown()` мы сначала удаляем строку и затем удаляем таблицу. > Note: Не все СУБД поддерживают транзакции. И некоторые запросы к базам данных не могут быть введены в транзакции. -Для различных примеров, пожалуйста, обратитесь к [негласным обязательствам](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). +Для различных примеров, пожалуйста, обратитесь к [негласным обязательствам](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). В этом случае вместо этих методов вы должны реализовать методы `up()` и `down()`. ### Методы доступа к базе данных diff --git a/docs/guide-ru/db-query-builder.md b/docs/guide-ru/db-query-builder.md index 5db7896eef3..89d049cf9ec 100644 --- a/docs/guide-ru/db-query-builder.md +++ b/docs/guide-ru/db-query-builder.md @@ -149,7 +149,7 @@ $query->from(['u' => $subQuery]); #### Префиксы Также может применяться [[yii\db\Connection::$tablePrefix|tablePrefix]] по умолчанию. Подробное описание смотрите -в подразделе [«Экранирование имён таблиц и столбцов» раздела «Объекты доступа к данным (DAO)»](guide-db-dao.html#quoting-table-and-column-names). +в подразделе [«Экранирование имён таблиц и столбцов» раздела «Объекты доступа к данным (DAO)»](db-dao.md#quoting-table-and-column-names). ### [[yii\db\Query::where()|where()]] @@ -363,7 +363,7 @@ $query->filterWhere([ ### [[yii\db\Query::orderBy()|orderBy()]] Метод [[yii\db\Query::orderBy()|orderBy()]] определяет фрагмент `ORDER BY` SQL выражения. Например, - + ```php // ... ORDER BY `id` ASC, `name` DESC $query->orderBy([ @@ -460,14 +460,14 @@ $query->limit(10)->offset(20); ### [[yii\db\Query::join()|join()]] Метод [[yii\db\Query::join()|join()]] определяет фрагмент `JOIN` SQL запроса. - + ```php // ... LEFT JOIN `post` ON `post`.`user_id` = `user`.`id` $query->join('LEFT JOIN', 'post', 'post.user_id = user.id'); ``` Метод [[yii\db\Query::join()|join()]] принимает четыре параметра: - + - `$type`: тип объединения, например, `'INNER JOIN'`, `'LEFT JOIN'`. - `$table`: имя таблицы, которая должна быть присоединена. - `$on`: необязательное условие объединения, то есть фрагмент `ON`. Пожалуйста, обратитесь к документации для diff --git a/docs/guide-ru/glossary.md b/docs/guide-ru/glossary.md index a3c8b9d7c6d..a44ff2a44c5 100644 --- a/docs/guide-ru/glossary.md +++ b/docs/guide-ru/glossary.md @@ -54,7 +54,7 @@ Bundle, известный как пакет в Yii 1.1, относится к ## namespace -Пространство имен ссылка на [PHP language feature](https://secure.php.net/manual/en/language.namespaces.php) который активно используется в Yii 2. +Пространство имен ссылка на [PHP language feature](https://www.php.net/manual/en/language.namespaces.php) который активно используется в Yii 2. # P diff --git a/docs/guide-ru/helper-array.md b/docs/guide-ru/helper-array.md index 0397416849a..e0219c637a2 100644 --- a/docs/guide-ru/helper-array.md +++ b/docs/guide-ru/helper-array.md @@ -1,6 +1,6 @@ ArrayHelper =========== -Вдобавок к [богатому набору функций](https://secure.php.net/manual/ru/book.array.php) для работы с массивами, которые есть в самом PHP, хелпер Yii Array предоставляет свои статические функции - возможно они могут быть вам полезны. +Вдобавок к [богатому набору функций](https://www.php.net/manual/ru/book.array.php) для работы с массивами, которые есть в самом PHP, хелпер Yii Array предоставляет свои статические функции - возможно они могут быть вам полезны. ## Получение значений @@ -110,7 +110,7 @@ $type = ArrayHelper::remove($array, 'type'); ## Проверка наличия ключей -`ArrayHelper::keyExists` работает так же, как и стандартный [array_key_exists](https://secure.php.net/manual/ru/function.array-key-exists.php), +`ArrayHelper::keyExists` работает так же, как и стандартный [array_key_exists](https://www.php.net/manual/ru/function.array-key-exists.php), но также может проверять ключи без учёта регистра: ```php @@ -245,7 +245,7 @@ ArrayHelper::multisort($data, function($item) { ``` Третий аргумент определяет способ сортировки – от большего к меньшему или от меньшего к большему. В случае, если мы сортируем по одному ключу, передаем `SORT_ASC` или `SORT_DESC`. Если сортировка осуществляется по нескольким ключам, вы можете назначить направление сортировки для каждого из них с помощью массива. -Последний аргумент – это флаг, который используется в стандартной функции PHP `sort()`. Посмотреть его возможные значения можно [тут](https://secure.php.net/manual/ru/function.sort.php). +Последний аргумент – это флаг, который используется в стандартной функции PHP `sort()`. Посмотреть его возможные значения можно [тут](https://www.php.net/manual/ru/function.sort.php). ## Определение типа массива @@ -335,7 +335,7 @@ $data = ArrayHelper::toArray($posts, [ Для таких случаев [[yii\helpers\ArrayHelper]] предоставляет [[yii\helpers\ArrayHelper::isIn()|isIn()]] и [[yii\helpers\ArrayHelper::isSubset()|isSubset()]]. Методы принимают такие же параметры, что и -[in_array()](https://secure.php.net/manual/ru/function.in-array.php). +[in_array()](https://www.php.net/manual/ru/function.in-array.php). ```php // true diff --git a/docs/guide-ru/helper-html.md b/docs/guide-ru/helper-html.md index 5ffb14c8676..23291a292d3 100644 --- a/docs/guide-ru/helper-html.md +++ b/docs/guide-ru/helper-html.md @@ -2,7 +2,7 @@ Html-помощник ============= Каждое веб-приложение формирует большое количество HTML-разметки. Если разметка статическая, её можно эффективно -сформировать [смешиванием PHP и HTML в одном файле](https://secure.php.net/manual/ru/language.basic-syntax.phpmode.php), но +сформировать [смешиванием PHP и HTML в одном файле](https://www.php.net/manual/ru/language.basic-syntax.phpmode.php), но когда разметка динамическая, становится сложно формировать её без дополнительной помощи. Yii предоставляет такую помощь в виде Html-помощника, который обеспечивает набор статических методов для обработки часто-используемых HTML тэгов, их атрибутов и содержимого. @@ -45,7 +45,7 @@ Html-помощник - Если значение равно `null`, соответствующий атрибут не будет выведен. - Атрибуты, значения которых имеют тип boolean, будут интерпретированы как - [логические атрибуты](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes). + [логические атрибуты](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes). - Значения атрибутов будут экранированы с использованием метода [[yii\helpers\Html::encode()|Html::encode()]]. - Если в качестве значения атрибута передан массив, он будет обработан следующим образом: @@ -155,8 +155,8 @@ Html::removeCssStyle($options, ['width', 'height']); ### Экранирование контента Для корректного и безопасного отображения контента специальные символы в HTML-коде должны быть экранированы. В чистом -PHP это осуществляется с помощью функций [htmlspecialchars](https://secure.php.net/manual/ru/function.htmlspecialchars.php) -и [htmlspecialchars_decode](https://secure.php.net/manual/ru/function.htmlspecialchars-decode.php). Проблема использования +PHP это осуществляется с помощью функций [htmlspecialchars](https://www.php.net/manual/ru/function.htmlspecialchars.php) +и [htmlspecialchars_decode](https://www.php.net/manual/ru/function.htmlspecialchars-decode.php). Проблема использования этих функций заключается в том, что приходится указывать кодировку и дополнительные флаги во время каждого вызова. Поскольку флаги всё время одинаковы, а кодировка остаётся одной и той же в пределах приложения, Yii в целях безопасности предоставляет два компактных и простых в использовании метода: diff --git a/docs/guide-ru/input-file-upload.md b/docs/guide-ru/input-file-upload.md index eb9a667477e..5dd78ee8aad 100644 --- a/docs/guide-ru/input-file-upload.md +++ b/docs/guide-ru/input-file-upload.md @@ -123,7 +123,7 @@ class SiteController extends Controller Сначала нужно добавить в правило валидации `file` параметр `maxFiles` для ограничения максимального количества загружаемых одновременно файлов. Установка `maxFiles` равным `0` означает снятие ограничений на количество файлов, которые могут быть загружены одновременно. Максимально разрешенное количество одновременно закачиваемых файлов -также ограничивается директивой PHP [`max_file_uploads`](https://secure.php.net/manual/ru/ini.core.php#ini.max-file-uploads), +также ограничивается директивой PHP [`max_file_uploads`](https://www.php.net/manual/ru/ini.core.php#ini.max-file-uploads), и по умолчанию равно 20. Метод `upload()` нужно изменить для сохранения загруженных файлов по одному. ```php diff --git a/docs/guide-ru/input-forms.md b/docs/guide-ru/input-forms.md index 08e332e4aef..c2863607a7d 100644 --- a/docs/guide-ru/input-forms.md +++ b/docs/guide-ru/input-forms.md @@ -90,7 +90,7 @@ echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Ite Имена элементов форм следует выбирать, учитывая, что могут возникнуть конфликты. Подробнее об этом в [документации jQuery](https://api.jquery.com/submit/): -> Имена и идентификаторы форм и их элементов не должны совпадать с элементами форм, такими как `submit`, `length` или `method`. Конфликты имен могут вызывать трудно диагностируемые ошибки. Подробнее о способах избегания подобных проблем смотрите [DOMLint](http://kangax.github.io/domlint/). +> Имена и идентификаторы форм и их элементов не должны совпадать с элементами форм, такими как `submit`, `length` или `method`. Конфликты имен могут вызывать трудно диагностируемые ошибки. Подробнее о способах избегания подобных проблем смотрите [DOMLint](https://kangax.github.io/domlint/). Дополнительные HTML-элементы можно добавить к форме, используя обычный HTML или методы из класса помощника [[yii\helpers\Html|Html]], как это было сделано с помощью [[yii\helpers\Html::submitButton()|Html::submitButton()]] в примере, приведённом выше. diff --git a/docs/guide-ru/input-validation.md b/docs/guide-ru/input-validation.md index ff4a435268c..9d3fa0b644e 100644 --- a/docs/guide-ru/input-validation.md +++ b/docs/guide-ru/input-validation.md @@ -556,7 +556,7 @@ JS; ### Отложенная валидация Если Вам необходимо выполнить асинхронную проверку на стороне клиента, вы можете создавать -[Deferred objects](http://api.jquery.com/category/deferred-object/). Например, чтобы выполнить +[Deferred objects](https://api.jquery.com/category/deferred-object/). Например, чтобы выполнить пользовательские AJAX проверки, вы можете использовать следующий код: ```php diff --git a/docs/guide-ru/intro-upgrade-from-v1.md b/docs/guide-ru/intro-upgrade-from-v1.md index af2239a12bf..7dbb7e18e66 100644 --- a/docs/guide-ru/intro-upgrade-from-v1.md +++ b/docs/guide-ru/intro-upgrade-from-v1.md @@ -28,16 +28,16 @@ Yii 2.0 широко использует [Composer](https://getcomposer.org/), версией 5.2, которая использовалась Yii 1.1. Таким образом, существует много различий в языке, которые вы должны принимать во внимание: -- [Пространства имён](https://secure.php.net/manual/ru/language.namespaces.php); -- [Анонимные функции](https://secure.php.net/manual/ru/functions.anonymous.php); +- [Пространства имён](https://www.php.net/manual/ru/language.namespaces.php); +- [Анонимные функции](https://www.php.net/manual/ru/functions.anonymous.php); - Использование короткого синтаксиса для массивов: `[...элементы...]` вместо `array(...элементы...)`; - Использование короткого echo `registerJs( - [[yii\web\View::POS_HEAD|View::POS_HEAD]] в `` - [[yii\web\View::POS_BEGIN|View::POS_BEGIN]] сразу после открытия тега `` - [[yii\web\View::POS_END|View::POS_END]] сразу после закрытия тега `` -- [[yii\web\View::POS_READY|View::POS_READY]] для выполнения кода сразу после того, как DOM полностью загрузился. Этому соответствует [событие `ready`](http://learn.jquery.com/using-jquery-core/document-ready/). При этом автоматически зарегистрируется [[yii\web\JqueryAsset|jQuery]]. Код будет обёрнут в соответствующий код jQuery. `POS_READY` является позицией по умолчанию. -- [[yii\web\View::POS_LOAD|View::POS_LOAD]] для выполнения кода после того, как DOM полностью загрузился (включая картинки). [Событие `load`](http://learn.jquery.com/using-jquery-core/document-ready/). Так же, как и выше, при этом автоматически зарегистрируется [[yii\web\JqueryAsset|jQuery]] +- [[yii\web\View::POS_READY|View::POS_READY]] для выполнения кода сразу после того, как DOM полностью загрузился. Этому соответствует [событие `ready`](https://learn.jquery.com/using-jquery-core/document-ready/). При этом автоматически зарегистрируется [[yii\web\JqueryAsset|jQuery]]. Код будет обёрнут в соответствующий код jQuery. `POS_READY` является позицией по умолчанию. +- [[yii\web\View::POS_LOAD|View::POS_LOAD]] для выполнения кода после того, как DOM полностью загрузился (включая картинки). [Событие `load`](https://learn.jquery.com/using-jquery-core/document-ready/). Так же, как и выше, при этом автоматически зарегистрируется [[yii\web\JqueryAsset|jQuery]] Последний аргумент — это уникальный ID, который используется для идентификации блока со скриптом. При повторной регистрации происходит замена существующего скрипта на новый. Если вы не зададите ID, вместо него будет использоваться сам код. Это помогает избежать регистрации одного и того же кода несколько раз. @@ -46,7 +46,7 @@ $this->registerJs( ```php $this->registerJsFile( '@web/js/main.js', - ['depends' => [\yii\web\JqueryAsset::className()]] + ['depends' => [\yii\web\JqueryAsset::class]] ); ``` @@ -80,7 +80,7 @@ body { background: #f00; } ```php $this->registerCssFile("@web/css/themes/black-and-white.css", [ - 'depends' => [\yii\bootstrap\BootstrapAsset::className()], + 'depends' => [\yii\bootstrap\BootstrapAsset::class], 'media' => 'print', ], 'css-print-theme'); ``` @@ -156,7 +156,7 @@ JS ); ``` -Приведенный выше пример кода использует PHP [синтаксис Heredoc](https://secure.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) для лучшей читаемости. Это также обеспечивает лучшую подсветку синтаксиса в большинстве IDE, поэтому это предпочтительный способ написания встроенного JavaScript, особенно полезный для кода, более длинного чем однострочный. Переменная `$message` создается PHP и благодаря [[yii\helpers\Json::htmlEncode|Json::htmlEncode]] содержит строку в допустимом синтаксисе JS, которую можно вставить в JavaScript код, чтобы поместить динамическую строку в вызов функции `alert()`. +Приведенный выше пример кода использует PHP [синтаксис Heredoc](https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) для лучшей читаемости. Это также обеспечивает лучшую подсветку синтаксиса в большинстве IDE, поэтому это предпочтительный способ написания встроенного JavaScript, особенно полезный для кода, более длинного чем однострочный. Переменная `$message` создается PHP и благодаря [[yii\helpers\Json::htmlEncode|Json::htmlEncode]] содержит строку в допустимом синтаксисе JS, которую можно вставить в JavaScript код, чтобы поместить динамическую строку в вызов функции `alert()`. > Note: При использовании Heredoc, будьте осторожны с именами переменных в коде JS, поскольку переменные, начинающиеся с `$`, могут интерпретироваться как переменные PHP, которые будут заменены их содержимым. > jQuery функция в форме `$(` или `$.` не интерпретируется как переменная PHP и может безопасно использоваться. @@ -170,4 +170,4 @@ JS > - Обработчик `data-confirm` > - Обработчик `data-method` > - Фильтрация скриптов -> - Обработка перенаправления \ No newline at end of file +> - Обработка перенаправления diff --git a/docs/guide-ru/output-formatting.md b/docs/guide-ru/output-formatting.md index 811f4bb9420..ddbcf8d7cf1 100644 --- a/docs/guide-ru/output-formatting.md +++ b/docs/guide-ru/output-formatting.md @@ -32,7 +32,7 @@ Formatter может быть использован двумя различны ``` Все данные, отображаемые через компонент formatter, будут локализованы, если -[расширение PHP intl](https://secure.php.net/manual/ru/book.intl.php) было установлено. Для этого вы можете настроить свойство +[расширение PHP intl](https://www.php.net/manual/ru/book.intl.php) было установлено. Для этого вы можете настроить свойство [[yii\i18n\Formatter::locale|locale]]. Если оно не было настроено, то в качестве локали будет использован [[yii\base\Application::language|язык приложения]]. Подробнее смотрите в разделе «[интернационализация](tutorial-i18n.md)». Компонент форматирования будет выбирать корректный формат для даты и чисел в соответствии с локалью, включая имена @@ -51,7 +51,7 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: 1 январ ``` > Обратите внимание, что форматирование может различаться между различными версиями библиотеки ICU, собранных с PHP, -> а также на основе того установлено ли [расширение PHP intl](https://secure.php.net/manual/ru/book.intl.php) или нет. +> а также на основе того установлено ли [расширение PHP intl](https://www.php.net/manual/ru/book.intl.php) или нет. > Таким образом, чтобы гарантировать, что ваш сайт будет одинаково отображать данные во всех окружениях рекомендуется > установить расширение PHP intl во всех окружениях и проверить, что версия библиотеки ICU совпадает. > См. также: [Настройка PHP окружения для интернационализации](tutorial-i18n.md#setup-environment). @@ -112,10 +112,10 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: 1 январ - `long` будет отображать `6 October 2014` и `15:58:42 GMT` соответственно и - `full` будет отображать `Monday, 6 October 2014` и `15:58:42 GMT` соответственно. -Дополнительно вы можете задать специальный формат, используя синтаксис, заданный [ICU Project](http://site.icu-project.org/), +Дополнительно вы можете задать специальный формат, используя синтаксис, заданный [ICU Project](https://icu.unicode.org/), который описан в руководстве ICU по следующему адресу: . Также вы можете использовать синтаксис, который распознаётся -PHP-функцией [date()](https://secure.php.net/manual/ru/function.date.php), используя строку с префиксом `php:`. +PHP-функцией [date()](https://www.php.net/manual/ru/function.date.php), используя строку с префиксом `php:`. ```php // ICU форматирование @@ -145,7 +145,7 @@ echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00 > Note: Поскольку правила для часовых поясов принимаются различными правительствами и могут часто меняться, > вероятно, информация в базе данных часовых поясов на вашем сервере не самая свежая. -> Как обновить базу вы можете узнать из [руководства ICU](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data). +> Как обновить базу вы можете узнать из [руководства ICU](https://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data). > Смотрите также: [Настройка вашего PHP окружения для интернационализации](tutorial-i18n.md#setup-environment). Форматирование чисел @@ -170,7 +170,7 @@ echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00 [[yii\i18n\Formatter::thousandSeparator|тысячного разделителя]], которые были заданы в соответствии с локалью. Для более сложной конфигурации [[yii\i18n\Formatter::numberFormatterOptions]] и [[yii\i18n\Formatter::numberFormatterTextOptions]] -могут быть использованы для настройки внутренне используемого [класса NumberFormatter](https://secure.php.net/manual/ru/class.numberformatter.php). +могут быть использованы для настройки внутренне используемого [класса NumberFormatter](https://www.php.net/manual/ru/class.numberformatter.php). Например, чтобы настроить максимальное и минимальное количество знаков после запятой, вы можете настроить свойство [[yii\i18n\Formatter::numberFormatterOptions]] как в примере ниже: diff --git a/docs/guide-ru/output-pagination.md b/docs/guide-ru/output-pagination.md index 59dac20f77c..2545528f487 100644 --- a/docs/guide-ru/output-pagination.md +++ b/docs/guide-ru/output-pagination.md @@ -31,7 +31,7 @@ function actionIndex() } ``` -Затем в представлении мы выводим модели для текущей страницы и передаем объект постраничного разделение данных в элемент нумерации страниц: +Затем в представлении мы выводим модели для текущей страницы и передаем объект постраничного разделения данных в элемент нумерации страниц: ```php foreach ($models as $model) { diff --git a/docs/guide-ru/rest-authentication.md b/docs/guide-ru/rest-authentication.md index b4ef119e8de..03c9932ddc1 100644 --- a/docs/guide-ru/rest-authentication.md +++ b/docs/guide-ru/rest-authentication.md @@ -10,15 +10,15 @@ Есть различные способы отправки токена доступа: -* [HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication): токен доступа +* [HTTP Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication): токен доступа отправляется как имя пользователя. Такой подход следует использовать только в том случае, когда токен доступа может быть безопасно сохранен на стороне пользователя API. Например, если API используется программой, запущенной на сервере. * Параметр запроса: токен доступа отправляется как параметр запроса в URL-адресе API, т.е. примерно таким образом: `https://example.com/users?access-token=xxxxxxxx`. Так как большинство веб-серверов сохраняют параметры запроса в своих логах, такой подход следует применять только при работе с `JSONP`-запросами, которые не могут отправлять токены доступа в HTTP-заголовках. -* [OAuth 2](http://oauth.net/2/): токен доступа выдается пользователю API сервером авторизации - и отправляется API-серверу через [HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750), +* [OAuth 2](https://oauth.net/2/): токен доступа выдается пользователю API сервером авторизации + и отправляется API-серверу через [HTTP Bearer Tokens](https://datatracker.ietf.org/doc/html/rfc6750), в соответствии с протоколом OAuth2. Yii поддерживает все выше перечисленные методы аутентификации. Вы также можете легко создавать новые методы аутентификации. @@ -57,7 +57,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -75,11 +75,11 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => CompositeAuth::className(), + 'class' => CompositeAuth::class, 'authMethods' => [ - HttpBasicAuth::className(), - HttpBearerAuth::className(), - QueryParamAuth::className(), + HttpBasicAuth::class, + HttpBearerAuth::class, + QueryParamAuth::class, ], ]; return $behaviors; diff --git a/docs/guide-ru/rest-controllers.md b/docs/guide-ru/rest-controllers.md index a8e45033b95..4dfff0da310 100644 --- a/docs/guide-ru/rest-controllers.md +++ b/docs/guide-ru/rest-controllers.md @@ -70,7 +70,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } diff --git a/docs/guide-ru/rest-resources.md b/docs/guide-ru/rest-resources.md index 5d530a6913f..3564aa40cef 100644 --- a/docs/guide-ru/rest-resources.md +++ b/docs/guide-ru/rest-resources.md @@ -2,7 +2,7 @@ ========= RESTful API строятся вокруг доступа к *ресурсам* и управления ими. Вы можете думать о ресурсах как -о [моделях](structure-models.md) из [MVC](http://ru.wikipedia.org/wiki/Model-View-Controller). +о [моделях](structure-models.md) из [MVC](https://ru.wikipedia.org/wiki/Model-View-Controller). Хотя не существует никаких ограничений на то, как представить ресурс, в Yii ресурсы обычно представляются как объекты [[yii\base\Model]] или дочерние классы (например [[yii\db\ActiveRecord]]), потому как: @@ -127,7 +127,7 @@ public function extraFields() ## Ссылки -Согласно [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), расшифровывающемуся как Hypermedia as the Engine of Application State, +Согласно [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS), расшифровывающемуся как Hypermedia as the Engine of Application State, RESTful API должны возвращать достаточно информации для того, чтобы клиенты могли определить возможные действия над ресурсами. Ключевой момент HATEOAS заключается в том, чтобы возвращать вместе с данными набора гиперссылок, указывающих на связанную с ресурсом информацию. @@ -154,6 +154,7 @@ class User extends ActiveRecord implements Linkable ``` При отправке ответа объект `User` содержит поле `_links`, значение которого — ссылки, связанные с объектом: + ``` { "id": 100, diff --git a/docs/guide-ru/rest-versioning.md b/docs/guide-ru/rest-versioning.md index dd0462ce736..5a45dc266e8 100644 --- a/docs/guide-ru/rest-versioning.md +++ b/docs/guide-ru/rest-versioning.md @@ -8,7 +8,7 @@ API используются клиентами, код которых вы не продолжать использовать старую, совместимую с ними версию API. Новые или обновлённые клиенты могут использовать новую версию. -> Tip: Чтобы узнать больше о выборе версий обратитесь к [Semantic Versioning](http://semver.org/). +> Tip: Чтобы узнать больше о выборе версий обратитесь к [Semantic Versioning](https://semver.org/). Общей практикой при реализации версионирования API является включение номера версии в URL-адрес вызова API-метода. Например, `http://example.com/v1/users` означает вызов API `/users` версии 1. Другой способ версионирования API, diff --git a/docs/guide-ru/runtime-bootstrapping.md b/docs/guide-ru/runtime-bootstrapping.md index 95f43e8686f..0222473af58 100644 --- a/docs/guide-ru/runtime-bootstrapping.md +++ b/docs/guide-ru/runtime-bootstrapping.md @@ -30,8 +30,8 @@ В производственном режиме включите байткод кэшеры, такие как [PHP OPcache] или [APC], для минимизации времени подключения и парсинг php файлов. -[PHP OPcache]: https://secure.php.net/manual/ru/intro.opcache.php -[APC]: https://secure.php.net/manual/ru/book.apc.php +[PHP OPcache]: https://www.php.net/manual/ru/intro.opcache.php +[APC]: https://www.php.net/manual/ru/book.apcu.php Некоторые большие приложения могут иметь сложную [конфигурацию](concept-configurations.md), которая разделена на несколько мелких файлов. Если это тот самый случай, возможно вам стоит кэшировать весь конфигурационный файл и загружать его прямо из кэша до создания объекта diff --git a/docs/guide-ru/runtime-responses.md b/docs/guide-ru/runtime-responses.md index b06b7094a18..bbf2ffd2660 100644 --- a/docs/guide-ru/runtime-responses.md +++ b/docs/guide-ru/runtime-responses.md @@ -229,11 +229,11 @@ public function actionDownload() методом [[yii\web\Response::xSendFile()]]. Далее приведены ссылки на то, как включить `X-Sendfile` для популярных Web-серверов: -- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile) -- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Lighttpd v1.5: [X-Sendfile](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Nginx: [X-Accel-Redirect](http://wiki.nginx.org/XSendfile) -- Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) +- Apache: [X-Sendfile](https://tn123.org/mod_xsendfile) +- Lighttpd v1.4: [X-LIGHTTPD-send-file](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Lighttpd v1.5: [X-Sendfile](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Nginx: [X-Accel-Redirect](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) +- Cherokee: [X-Sendfile and X-Accel-Redirect](https://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) ## Отправка ответа diff --git a/docs/guide-ru/runtime-sessions-cookies.md b/docs/guide-ru/runtime-sessions-cookies.md index 62364e10904..c23960d09b2 100644 --- a/docs/guide-ru/runtime-sessions-cookies.md +++ b/docs/guide-ru/runtime-sessions-cookies.md @@ -120,8 +120,8 @@ $session['captcha.lifetime'] = 3600; * [[yii\web\DbSession]]: сохраняет данные сессии в базе данных. * [[yii\web\CacheSession]]: хранение данных сессии в предварительно сконфигурированном компоненте кэша [кэш](caching-data.md#cache-components). -* [[yii\redis\Session]]: хранение данных сессии в [redis](http://redis.io/). -* [[yii\mongodb\Session]]: хранение сессии в [MongoDB](http://www.mongodb.org/). +* [[yii\redis\Session]]: хранение данных сессии в [redis](https://redis.io/). +* [[yii\mongodb\Session]]: хранение сессии в [MongoDB](https://www.mongodb.com/). Все эти классы поддерживают одинаковый набор методов API. В результате вы можете переключаться между различными хранилищами сессий без модификации кода приложения. @@ -261,7 +261,7 @@ unset($cookies['language']); Кроме свойств [[yii\web\Cookie::name|name]] и [[yii\web\Cookie::value|value]], класс [[yii\web\Cookie]] также предоставляет ряд свойств для получения информации о куках: [[yii\web\Cookie::domain|domain]], [[yii\web\Cookie::expire|expire]]. Эти свойства можно сконфигурировать и затем добавить куку в коллекцию для HTTP-ответа. -> Note: Для большей безопасности значение свойства [[yii\web\Cookie::httpOnly]] по умолчанию установлено в `true`. Это уменьшает риски доступа к защищенной куке на клиентской стороне (если браузер поддерживает такую возможность). Вы можете обратиться к [httpOnly wiki](https://www.owasp.org/index.php/HttpOnly) для дополнительной информации. +> Note: Для большей безопасности значение свойства [[yii\web\Cookie::httpOnly]] по умолчанию установлено в `true`. Это уменьшает риски доступа к защищенной куке на клиентской стороне (если браузер поддерживает такую возможность). Вы можете обратиться к [httpOnly wiki](https://owasp.org/www-community/HttpOnly) для дополнительной информации. ### Валидация кук diff --git a/docs/guide-ru/security-authorization.md b/docs/guide-ru/security-authorization.md index d32d72efc65..7872d94b1be 100644 --- a/docs/guide-ru/security-authorization.md +++ b/docs/guide-ru/security-authorization.md @@ -25,7 +25,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['login', 'logout', 'signup'], 'rules' => [ [ @@ -68,7 +68,7 @@ class SiteController extends Controller ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'denyCallback' => function ($rule, $action) { throw new \Exception('У вас нет доступа к этой странице'); } @@ -122,7 +122,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['special-callback'], 'rules' => [ [ @@ -153,7 +153,7 @@ class SiteController extends Controller Пожалуйста, обратитесь к [Wikipedia](https://ru.wikipedia.org/wiki/%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%BE%D0%BC_%D0%BD%D0%B0_%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B5_%D1%80%D0%BE%D0%BB%D0%B5%D0%B9) для получения информации о сравнении RBAC с другими, более традиционными, системами контроля доступа. -Yii реализует общую иерархическую RBAC, следуя [NIST RBAC model](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf). +Yii реализует общую иерархическую RBAC, следуя [NIST RBAC model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf). Обеспечивается функциональность RBAC через [компонент приложения](structure-application-components.md) [[yii\rbac\ManagerInterface|authManager]]. Использование RBAC состоит из двух частей. Первая часть — это создание RBAC данных авторизации, и вторая часть — это @@ -447,7 +447,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'rules' => [ [ 'allow' => true, diff --git a/docs/guide-ru/security-best-practices.md b/docs/guide-ru/security-best-practices.md index 7a84629368b..e5e881b379a 100644 --- a/docs/guide-ru/security-best-practices.md +++ b/docs/guide-ru/security-best-practices.md @@ -177,8 +177,8 @@ CSRF - это аббревиатура для межсайтинговой по Далее по теме читайте: -- -- +- +- (A6 - Information Leakage and Improper Error Handling) Использование безопасного подключения через TLS diff --git a/docs/guide-ru/security-cryptography.md b/docs/guide-ru/security-cryptography.md index befef8bcae8..83e932babe1 100644 --- a/docs/guide-ru/security-cryptography.md +++ b/docs/guide-ru/security-cryptography.md @@ -45,6 +45,7 @@ $data = Yii::$app->getSecurity()->decryptByPassword($encryptedData, $secretKey); Есть ситуации, в которых вам нужно убедиться, что ваши данные не были изменены третьей стороной или даже повреждены каким-либо образом. Yii обеспечивает простой способ для подтверждения целостности данных в виде двух вспомогательных функций. Префикс данных генерируются из секретного ключа и данных: + ```php // $secretKey нашего приложения или пользователя, $genuineData полученые из надежного источника $data = Yii::$app->getSecurity()->hashData($genuineData, $secretKey); diff --git a/docs/guide-ru/security-passwords.md b/docs/guide-ru/security-passwords.md index 8861e1d8c63..749776b3499 100644 --- a/docs/guide-ru/security-passwords.md +++ b/docs/guide-ru/security-passwords.md @@ -7,7 +7,7 @@ Для того, чтобы обеспечить повышенную безопасность паролей ваших пользователей даже в худшем случае (ваше приложение взломано), нужно использовать алгоритм шифрования, устойчивый к атаке перебором. Лучший вариант в текущий -момент `bcrypt`. В PHP вы можете использовать хеши `bcrypt` через [функцию crypt](https://secure.php.net/manual/en/function.crypt.php). +момент `bcrypt`. В PHP вы можете использовать хеши `bcrypt` через [функцию crypt](https://www.php.net/manual/en/function.crypt.php). Yii обеспечивает две вспомогательные функции, которые упрощают использование функции `crypt` для генерации и проверки пароля. diff --git a/docs/guide-ru/start-databases.md b/docs/guide-ru/start-databases.md index 18d65496a0a..9889d89c3cf 100644 --- a/docs/guide-ru/start-databases.md +++ b/docs/guide-ru/start-databases.md @@ -45,7 +45,7 @@ INSERT INTO `country` VALUES ('US','United States',322976000); Настраиваем подключение к БД ------------------------------------------------------------------------- -Перед продолжением убедитесь, что у вас установлены PHP-расширение [PDO](https://secure.php.net/manual/ru/book.pdo.php) и драйвер PDO для используемой вами базы данных (например, `pdo_mysql` для MySQL). Это базовое требование в случае использования вашим приложением реляционной базы данных. +Перед продолжением убедитесь, что у вас установлены PHP-расширение [PDO](https://www.php.net/manual/ru/book.pdo.php) и драйвер PDO для используемой вами базы данных (например, `pdo_mysql` для MySQL). Это базовое требование в случае использования вашим приложением реляционной базы данных. После того, как они установлены, откройте файл `config/db.php` и измените параметры на верные для вашей базы данных. По умолчанию этот файл содержит следующее: ```php diff --git a/docs/guide-ru/start-hello.md b/docs/guide-ru/start-hello.md index e4398e70fc0..88050ddbaf6 100644 --- a/docs/guide-ru/start-hello.md +++ b/docs/guide-ru/start-hello.md @@ -80,7 +80,7 @@ use yii\helpers\Html; Стоит отметить, что в коде выше параметр `message` [[yii\helpers\Html::encode()|экранируется для HTML]] перед выводом. Это обязательно так как параметр приходит от пользователя, который может попытаться провести -[XSS атаку](http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D1%8B%D0%B9_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3) +[XSS атаку](https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D1%8B%D0%B9_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3) путём вставки зловредного JavaScript кода. Вы можете дополнить представление `say` HTML тегами, текстом или кодом PHP. Фактически, представление `say` является diff --git a/docs/guide-ru/start-installation.md b/docs/guide-ru/start-installation.md index 40b22e81ba7..4d12c27890d 100644 --- a/docs/guide-ru/start-installation.md +++ b/docs/guide-ru/start-installation.md @@ -72,7 +72,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic Установка Yii из архива состоит из трёх шагов: -1. Скачайте архив с [yiiframework.com](http://www.yiiframework.com/download/); +1. Скачайте архив с [yiiframework.com](https://www.yiiframework.com/download/); 2. Распакуйте скачанный архив в папку, доступную из Web. 3. В файле `config/web.php` добавьте секретный ключ в значение `cookieValidationKey` (при установке через Composer это происходит автоматически): @@ -122,7 +122,7 @@ php requirements.php Для корректной работы фреймворка вам необходима установка PHP, соответствующая его минимальным требованиям. Основное требование — PHP версии 5.4 и выше. Если ваше приложение работает с базой данных, необходимо установить -[расширение PHP PDO](https://secure.php.net/manual/ru/pdo.installation.php) и соответствующий драйвер +[расширение PHP PDO](https://www.php.net/manual/ru/pdo.installation.php) и соответствующий драйвер (например, `pdo_mysql` для MySQL). @@ -132,9 +132,9 @@ php requirements.php > Info: можете пропустить этот подраздел если вы только начали знакомиться с фреймворком и пока не разворачиваете его на рабочем сервере. -Приложение, установленное по инструкциям, приведённым выше, будет работать сразу как с [Apache](http://httpd.apache.org/), -так и с [Nginx](http://nginx.org/) под Windows и Linux с установленным PHP 5.4 и выше. Yii 2.0 также совместим с -[HHVM](http://hhvm.com/). Тем не менее, в некоторых случаях поведение при работе с HHVM отличается от обычного PHP. +Приложение, установленное по инструкциям, приведённым выше, будет работать сразу как с [Apache](https://httpd.apache.org/), +так и с [Nginx](https://nginx.org/) под Windows и Linux с установленным PHP 5.4 и выше. Yii 2.0 также совместим с +[HHVM](https://hhvm.com/). Тем не менее, в некоторых случаях поведение при работе с HHVM отличается от обычного PHP. Будьте внимательны. На рабочем сервере вам наверняка захочется изменить URL приложения с `http://www.example.com/basic/web/index.php` @@ -174,7 +174,7 @@ DocumentRoot "path/to/basic/web" ### Рекомендуемые настройки Nginx -PHP должен быть установлен как [FPM SAPI](https://secure.php.net/manual/ru/install.fpm.php) для [Nginx](http://wiki.nginx.org/). +PHP должен быть установлен как [FPM SAPI](https://www.php.net/manual/ru/install.fpm.php) для [Nginx](https://wiki.nginx.org/). Используйте следующие параметры Nginx и не забудьте заменить `path/to/basic/web` на корректный путь к `basic/web` и `mysite.test` на ваше имя хоста. diff --git a/docs/guide-ru/start-looking-ahead.md b/docs/guide-ru/start-looking-ahead.md index 9872ae0e356..d10becc34b1 100644 --- a/docs/guide-ru/start-looking-ahead.md +++ b/docs/guide-ru/start-looking-ahead.md @@ -22,11 +22,11 @@ Причём качество этих статей может быть таким же хорошим, как в Подробном руководстве. Они полезны тем, что охватывают более широкие темы и часто могут предоставить вам готовые решения для дальнейшего использования. - Книги -* [Расширения](http://www.yiiframework.com/extensions/): +* [Расширения](https://www.yiiframework.com/extensions/): Yii гордится библиотекой из тысяч внесённых пользователями расширений, которые могут быть легко подключены в ваши приложения и сделать разработку приложений ещё быстрее и проще. * Сообщество - - [Форум](http://www.yiiframework.com/forum/) + - [Форум](https://forum.yiiframework.com/) - [Чат Gitter](https://gitter.im/yiisoft/yii2/rus) - [GitHub](https://github.com/yiisoft/yii2) - [Facebook](https://www.facebook.com/groups/yiitalk/) diff --git a/docs/guide-ru/start-workflow.md b/docs/guide-ru/start-workflow.md index 2357de2714d..6537d7772ca 100644 --- a/docs/guide-ru/start-workflow.md +++ b/docs/guide-ru/start-workflow.md @@ -35,7 +35,7 @@ Ниже приведен список основных директорий и файлов вашего приложения (считаем, что приложение установлено в директорию `basic`): -``` +```js basic/ корневой каталог приложения composer.json используется Composer'ом, содержит описание приложения config/ конфигурационные файлы @@ -55,7 +55,7 @@ basic/ корневой каталог приложения В целом, приложение Yii можно разделить на две категории файлов: расположенные в `basic/web` и расположенные в других директориях. Первая категория доступна через Web (например, браузером), вторая не доступна извне и не должна быть доступной т.к. содержит служебную информацию. -В Yii реализован [архитектурный паттерн MVC](http://ru.wikipedia.org/wiki/Model-View-Controller), +В Yii реализован [архитектурный паттерн MVC](https://ru.wikipedia.org/wiki/Model-View-Controller), которая соответствует структуре директорий приложения. В директории `models` находятся [Модели](structure-models.md), в `views` расположены [Виды](structure-views.md), а в каталоге `controllers` все [Контроллеры](structure-controllers.md) приложения. diff --git a/docs/guide-ru/structure-applications.md b/docs/guide-ru/structure-applications.md index df5238ddbe1..b769cc8477a 100644 --- a/docs/guide-ru/structure-applications.md +++ b/docs/guide-ru/structure-applications.md @@ -268,7 +268,7 @@ if (YII_ENV_DEV) { использует данное свойство для определения по умолчанию языка, на котором должен быть отображен календарь и формат данных для календаря. -Рекомендуется что вы будете указывать язык в рамках стандарта [IETF](http://en.wikipedia.org/wiki/IETF_language_tag). +Рекомендуется что вы будете указывать язык в рамках стандарта [IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Например, для английского языка используется `en`, в то время как для английского в США - `en-US`. Более детальная информация приведена в разделе [Интернационализация](tutorial-i18n.md). @@ -339,7 +339,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; "Английский" (США). Вы должны настроить данное свойство соответствующим образом, если содержимое в вашем коде является не английским языком. -Аналогично свойству [language](#language), вы должны указать данное свойство в рамках стандарта [IETF](http://en.wikipedia.org/wiki/IETF_language_tag). +Аналогично свойству [language](#language), вы должны указать данное свойство в рамках стандарта [IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Например, для английского языка используется `en`, в то время как для английского в США - `en-US`. Более детальная информация приведена в разделе [Интернационализация](tutorial-i18n.md). @@ -349,7 +349,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; Данное свойство предоставляет альтернативный способ установки временной зоны в процессе работы приложения. Путем указания данного свойства, вы по существу вызываете PHP функцию -[date_default_timezone_set()](https://secure.php.net/manual/ru/function.date-default-timezone-set.php). Например, +[date_default_timezone_set()](https://www.php.net/manual/ru/function.date-default-timezone-set.php). Например, ```php [ diff --git a/docs/guide-ru/structure-assets.md b/docs/guide-ru/structure-assets.md index aa4c412f637..6ac1731ea85 100644 --- a/docs/guide-ru/structure-assets.md +++ b/docs/guide-ru/structure-assets.md @@ -46,7 +46,7 @@ class AppAsset extends AssetBundle * [[yii\web\AssetBundle::js|js]]: массив, перечисляющий JavaScript файлы, содержащиеся в данном комплекте. Заметьте, что только прямая косая черта (forward slash - "/") может быть использована, как разделитель директорий. Каждый JavaScript файл может быть задан в одном из следующих форматов: - относительный путь, представленный локальным JavaScript файлом (например `js/main.js`). Актуальный путь файла может быть определён путём добавления [[yii\web\AssetManager::basePath]] к относительному пути, и актуальный URL файла может быть определён путём добавления [[yii\web\AssetManager::baseUrl]] к относительному пути. - абсолютный URL, представленный внешним JavaScript файлом. Например, - `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` или + `https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` или `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. * [[yii\web\AssetBundle::css|css]]: массив, перечисляющий CSS файлы, содержащиеся в данном комплекте. Формат этого массива такой же, как и у [[yii\web\AssetBundle::js|js]]. * [[yii\web\AssetBundle::depends|depends]]: массив, перечисляющий имена комплектов ресурсов, от которых зависит данный комплект. @@ -162,11 +162,11 @@ class FontAwesomeAsset extends AssetBundle } ``` -В выше указанном примере определён комплект ресурсов для [пакета "fontawesome"](http://fontawesome.io/). Задан параметр публикации `beforeCopy`, здесь только `fonts` и `css` поддиректории будут опубликованы. +В выше указанном примере определён комплект ресурсов для [пакета "fontawesome"](https://fontawesome.com/). Задан параметр публикации `beforeCopy`, здесь только `fonts` и `css` поддиректории будут опубликованы. ### Установка ресурсов Bower и NPM -Большинство JavaScript/CSS пакетов управляются [Bower](http://bower.io/) и/или [NPM](https://www.npmjs.org/). +Большинство JavaScript/CSS пакетов управляются [Bower](https://bower.io/) и/или [NPM](https://www.npmjs.com/). В мире PHP мы испольуем Composer для управления зависимостями, но он не позволяет устанавливать пакеты Bower и NPM, просто указывая их в `composer.json`. Чтобы получить такую возможность, нужно немного настроить Composer. Существует два варианта: @@ -215,7 +215,7 @@ $config = [ composer global require "fxp/composer-asset-plugin:^1.4.1" ``` -Эта команда устанавливает [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) глобально, +Эта команда устанавливает [composer asset plugin](https://github.com/fxpio/composer-asset-plugin) глобально, что позволит устанавливать зависимости из Bower и NPM. После установки все проекты на вашем комьютере будут поддерживать установку Bower и NPM пакетов, описанных в `composer.json`. @@ -485,7 +485,7 @@ return [ ## Преобразование Ресурсов -Вместо того, чтобы напрямую писать CSS и/или JavaScript код, разработчики часто пишут его в некотором расширенном синтаксисе и используют специальные инструменты конвертации в CSS/JavaScript. Например, для CSS кода можно использовать [LESS](http://lesscss.org/) или [SCSS](http://sass-lang.com/); а для JavaScript можно использовать [TypeScript](http://www.typescriptlang.org/). +Вместо того, чтобы напрямую писать CSS и/или JavaScript код, разработчики часто пишут его в некотором расширенном синтаксисе и используют специальные инструменты конвертации в CSS/JavaScript. Например, для CSS кода можно использовать [LESS](https://lesscss.org/) или [SCSS](https://sass-lang.com/); а для JavaScript можно использовать [TypeScript](https://www.typescriptlang.org/). Можно перечислить файлы ресурсов в расширенном синтаксисе в [[yii\web\AssetBundle::css|css]] и [[yii\web\AssetBundle::js|js]] свойствах из комплекта ресурсов. Например, @@ -511,13 +511,13 @@ class AppAsset extends AssetBundle Yii использует имена расширений файлов для идентификации расширенного синтаксиса внутри ресурса. По умолчанию признаны следующие синтаксисы и имена расширений файлов: -- [LESS](http://lesscss.org/): `.less` -- [SCSS](http://sass-lang.com/): `.scss` -- [Stylus](http://learnboost.github.io/stylus/): `.styl` -- [CoffeeScript](http://coffeescript.org/): `.coffee` -- [TypeScript](http://www.typescriptlang.org/): `.ts` +- [LESS](https://lesscss.org/): `.less` +- [SCSS](https://sass-lang.com/): `.scss` +- [Stylus](https://stylus-lang.com/): `.styl` +- [CoffeeScript](https://coffeescript.org/): `.coffee` +- [TypeScript](https://www.typescriptlang.org/): `.ts` -Yii ориентируется на установленные инструменты конвертации ресурсов препроцессора. Например, используя [LESS](http://lesscss.org/), Вы должны установить команду `lessc` препроцессора. +Yii ориентируется на установленные инструменты конвертации ресурсов препроцессора. Например, используя [LESS](https://lesscss.org/), Вы должны установить команду `lessc` препроцессора. Вы можете настроить команды препроцессора и поддерживать расширенный синтаксис сконфигурировав [[yii\web\AssetManager::converter]] следующим образом: @@ -541,7 +541,7 @@ return [ Ключи массива - это имена расширений файлов (без ведущей точки), а значения массива - это образующийся файл ресурса имён расширений и команд для выполнения конвертации ресурса. Маркеры `{from}` и `{to}` в командах будут заменены соответственно исходным путём файла ресурсов и путём назначения файла ресурсов. > Note: Существуют другие способы работы с ресурсами расширенного синтаксиса, кроме того, который указан выше. -Например, Вы можете использовать инструменты построения, такие как [grunt](http://gruntjs.com/) для отслеживания и автоматической конвертации ресурсов расширенного синтаксиса. В этом случае, Вы должны перечислить конечные CSS/JavaScript файлы в комплекте ресурсов вместо исходных файлов. +Например, Вы можете использовать инструменты построения, такие как [grunt](https://gruntjs.com/) для отслеживания и автоматической конвертации ресурсов расширенного синтаксиса. В этом случае, Вы должны перечислить конечные CSS/JavaScript файлы в комплекте ресурсов вместо исходных файлов. ## Объединение и Сжатие Ресурсов @@ -697,7 +697,7 @@ yii asset assets.php config/assets-prod.php > Для справки: Команда `asset` является не единственной опцией для автоматического процесса объединения и сжатия ресурсов. - Вы можете также использовать такой замечательный инструмент запуска приложений как [grunt](http://gruntjs.com/) для достижения той же цели. + Вы можете также использовать такой замечательный инструмент запуска приложений как [grunt](https://gruntjs.com/) для достижения той же цели. ### Группировка Комплектов Ресурсов diff --git a/docs/guide-ru/structure-entry-scripts.md b/docs/guide-ru/structure-entry-scripts.md index 71fbf54ebd9..a04daeeabe5 100644 --- a/docs/guide-ru/structure-entry-scripts.md +++ b/docs/guide-ru/structure-entry-scripts.md @@ -57,9 +57,9 @@ $config = require __DIR__ . '/../config/web.php'; /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-ru/structure-extensions.md b/docs/guide-ru/structure-extensions.md index 038cf761764..6728999b26e 100644 --- a/docs/guide-ru/structure-extensions.md +++ b/docs/guide-ru/structure-extensions.md @@ -77,7 +77,7 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) 2. установить автозагрузчики классов, предоставляемые расширениями, если таковые имеются. 3. загрузить и установить все зависимые расширения в соответствии с инструкциями. -Если расширение не имеет автозагрузчика классов, но следует [стандарту PSR-4](http://www.php-fig.org/psr/psr-4/), то вы +Если расширение не имеет автозагрузчика классов, но следует [стандарту PSR-4](https://www.php-fig.org/psr/psr-4/), то вы можете использовать автозагрузчик классов, предоставленный Yii для загрузки классов расширений. Всё, что вам нужно сделать, это объявить [псевдоним](concept-aliases.md#defining-aliases) для корневого каталога расширения. Например, если вы установили расширение в директорию `vendor/mycompany/myext` и классы расширения находятся в пространстве имён @@ -130,9 +130,9 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) "license": "BSD-3-Clause", "support": { "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki/", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "authors": [ @@ -223,7 +223,7 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) #### Пространства имён Во избежание конфликтов имён, а также для того, чтобы ваши классы были автозагружаемыми, вы должны следовать -[стандарту PSR-4](http://www.php-fig.org/psr/psr-4/) или [стандарту PSR-0](http://www.php-fig.org/psr/psr-0/) в +[стандарту PSR-4](https://www.php-fig.org/psr/psr-4/) или [стандарту PSR-0](https://www.php-fig.org/psr/psr-0/) в использовании пространств имён и названии классов вашего расширения. Пространства имён в ваших классах должны начинаться с `имяРазработчика\названиеРасширения`, где `названиеРасширения` @@ -338,7 +338,7 @@ class MyBootstrapClass implements BootstrapInterface #### Версионирование Вы можете давать каждому выпуску вашего расширения номер версии (например, `1.0.1`). Мы рекомендуем вам придерживаться -практик [семантического версионирования](http://semver.org) при определении, какой номер версии должен использоваться. +практик [семантического версионирования](https://semver.org) при определении, какой номер версии должен использоваться. #### Публикация @@ -353,7 +353,7 @@ class MyBootstrapClass implements BootstrapInterface которые помогут людям изучить и использовать ваше расширение: * Файл readme в корневой директории пакета: он описывает, что ваше расширение делает, а также как его установить и - использовать. Мы рекомендуем вам написать его в формате [Markdown](http://daringfireball.net/projects/markdown/) и + использовать. Мы рекомендуем вам написать его в формате [Markdown](https://daringfireball.net/projects/markdown/) и дать ему название `readme.md`. * Файл changelog в корневой директории пакета: он описывает, какие изменения произошли в каждом выпуске. Этот файл может быть написан в формате Markdown и назван `changelog.md`. @@ -369,7 +369,7 @@ class MyBootstrapClass implements BootstrapInterface предоставляет инструмент для генерации документации API на основе ваших комментариев. > Info: Пока это не обязательно, но мы всё-таки рекомендуем вам придерживаться определённого стиля кодирования. - Вы можете обратиться к [стилю кодирования фреймворка](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style). + Вы можете обратиться к [стилю кодирования фреймворка](https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md). ## Базовые расширения @@ -385,15 +385,13 @@ Yii предоставляет следующие базовые расшире предоставляет набор наиболее часто используемых клиентов авторизации, таких, как Facebook OAuth2 клиент и GitHub OAuth2 клиент. - [yiisoft/yii2-bootstrap](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap): - предоставляет набор виджетов, которые являются компонентами и плагинами [Bootstrap](http://getbootstrap.com/). -- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception) (deprecated): - предоставляет поддержку тестирования, основанного на [Codeception](http://codeception.com/). + предоставляет набор виджетов, которые являются компонентами и плагинами [Bootstrap](https://getbootstrap.com/). - [yiisoft/yii2-debug](https://www.yiiframework.com/extension/yiisoft/yii2-debug): предоставляет поддержку отладки в приложениях Yii. Когда это расширение используется, отладочная панель появится в нижней части каждой страницы. Это расширение также предоставляет набор отдельных страниц для отображения более подробной отладочной информации. - [yiisoft/yii2-elasticsearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch): - предоставляет поддержку использования [Elasticsearch](http://www.elasticsearch.org/). Оно включает в себя поддержку + предоставляет поддержку использования [Elasticsearch](https://www.elastic.co/). Оно включает в себя поддержку основных поисковых запросов, а также реализует шаблон проектирования [Active Record](db-active-record.md), который позволяет хранить записи Active Record в Elasticsearch. - [yiisoft/yii2-faker](https://github.com/yiisoft/yii2-faker): @@ -405,21 +403,21 @@ Yii предоставляет следующие базовые расшире предоставляет HTTP клиент. - [yiisoft/yii2-imagine](https://github.com/yiisoft/yii2-imagine): предоставляет часто используемые функции для работы с изображениями, основанные на библиотеке - [Imagine](http://imagine.readthedocs.org/). + [Imagine](https://imagine.readthedocs.org/). - [yiisoft/yii2-jui](https://github.com/yiisoft/yii2-jui): - предоставляет набор виджетов, основанный на взаимодействиях и виджетах [JQuery UI](http://jqueryui.com/). + предоставляет набор виджетов, основанный на взаимодействиях и виджетах [JQuery UI](https://jqueryui.com/). - [yiisoft/yii2-mongodb](https://github.com/yiisoft/yii2-mongodb): - предоставляет поддержку использования [MongoDB](http://www.mongodb.org/). Оно включает такие возможности, как + предоставляет поддержку использования [MongoDB](https://www.mongodb.com/). Оно включает такие возможности, как базовые запросы, Active Record, миграции, кэширование, генерация кода и т.д. - [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis): - предоставляет поддержку использования [redis](http://redis.io/). Оно включает такие возможности, как базовые запросы, + предоставляет поддержку использования [redis](https://redis.io/). Оно включает такие возможности, как базовые запросы, Active Record, кэширование и т.д. - [yiisoft/yii2-smarty](https://github.com/yiisoft/yii2-smarty): - предоставляет шаблонизатор, основанный на [Smarty](http://www.smarty.net/). + предоставляет шаблонизатор, основанный на [Smarty](https://www.smarty.net/). - [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx): - предоставляет поддержку использования [Sphinx](http://sphinxsearch.com). Оно включает такие возможности, как базовые + предоставляет поддержку использования [Sphinx](https://sphinxsearch.com). Оно включает такие возможности, как базовые запросы, Active Record, генерация кода и т.д. - [yiisoft/yii2-swiftmailer](https://github.com/yiisoft/yii2-swiftmailer): - предоставляет возможности отправки email, основанные на [swiftmailer](http://swiftmailer.org/). + предоставляет возможности отправки email, основанные на [swiftmailer](https://swiftmailer.org/). - [yiisoft/yii2-twig](https://github.com/yiisoft/yii2-twig): - предоставляет шаблонизатор, основанный на [Twig](http://twig.sensiolabs.org/). + предоставляет шаблонизатор, основанный на [Twig](https://twig.symfony.com/). diff --git a/docs/guide-ru/structure-filters.md b/docs/guide-ru/structure-filters.md index fcc630835f5..957af264ade 100644 --- a/docs/guide-ru/structure-filters.md +++ b/docs/guide-ru/structure-filters.md @@ -118,7 +118,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['create', 'update'], 'rules' => [ // разрешаем аутентифицированным пользователям @@ -139,7 +139,7 @@ public function behaviors() ### Фильтр метода аутентификации Фильтр метода аутентификации используется для аутентификации пользователя различными способами, такими как -[HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication), [OAuth 2](http://oauth.net/2/). +[HTTP Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication), [OAuth 2](https://oauth.net/2/). Классы данных фильтров находятся в пространстве имён `yii\filters\auth`. Следующий пример показывает, как использовать [[yii\filters\auth\HttpBasicAuth]] для аутентификации пользователя с помощью @@ -154,7 +154,7 @@ public function behaviors() { return [ 'basicAuth' => [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ], ]; } @@ -180,7 +180,7 @@ public function behaviors() { return [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -206,7 +206,7 @@ use yii\web\Response; [ 'bootstrap' => [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -236,7 +236,7 @@ public function behaviors() { return [ [ - 'class' => HttpCache::className(), + 'class' => HttpCache::class, 'only' => ['index'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); @@ -264,11 +264,11 @@ public function behaviors() { return [ 'pageCache' => [ - 'class' => PageCache::className(), + 'class' => PageCache::class, 'only' => ['index'], 'duration' => 60, 'dependency' => [ - 'class' => DbDependency::className(), + 'class' => DbDependency::class, 'sql' => 'SELECT COUNT(*) FROM post', ], 'variations' => [ @@ -302,7 +302,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'index' => ['get'], 'view' => ['get'], @@ -334,7 +334,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, ], ], parent::behaviors()); } @@ -365,7 +365,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], @@ -387,7 +387,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], diff --git a/docs/guide-ru/structure-models.md b/docs/guide-ru/structure-models.md index b2452dc7bd4..2706a31c1fb 100644 --- a/docs/guide-ru/structure-models.md +++ b/docs/guide-ru/structure-models.md @@ -1,7 +1,7 @@ Модели ====== -Модели являются частью архитектуры [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Модель-Вид-Контроллер). Они представляют собой объекты бизнес данных, правил и логики. +Модели являются частью архитектуры [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Модель-Вид-Контроллер). Они представляют собой объекты бизнес данных, правил и логики. Вы можете создавать классы моделей путём расширения класса [[yii\base\Model]] или его дочерних классов. Базовый класс [[yii\base\Model]] поддерживает много полезных функций: @@ -29,7 +29,7 @@ $model->name = 'example'; echo $model->name; ``` -Также возможно получить доступ к атрибутам как к элементам массива, спасибо поддержке [ArrayAccess](https://secure.php.net/manual/ru/class.arrayaccess.php) и [Traversable](https://secure.php.net/manual/ru/class.traversable.php) +Также возможно получить доступ к атрибутам как к элементам массива, спасибо поддержке [ArrayAccess](https://www.php.net/manual/ru/class.arrayaccess.php) и [Traversable](https://www.php.net/manual/ru/class.traversable.php) в [[yii\base\Model]]: ```php diff --git a/docs/guide-ru/structure-modules.md b/docs/guide-ru/structure-modules.md index 8b1fce134f6..a8fc39ab042 100644 --- a/docs/guide-ru/structure-modules.md +++ b/docs/guide-ru/structure-modules.md @@ -10,7 +10,7 @@ директории приложения, в этой директории существуют поддиректории `controllers`, `models`, `views` и другие, в которых размещаются контроллеры, модели, представления и другие элементы. В следующем примере показано примерное содержимое модуля: -``` +```js forum/ Module.php файл класса модуля controllers/ содержит файлы классов контроллеров diff --git a/docs/guide-ru/structure-overview.md b/docs/guide-ru/structure-overview.md index c1560813e26..575597b1915 100644 --- a/docs/guide-ru/structure-overview.md +++ b/docs/guide-ru/structure-overview.md @@ -1,7 +1,7 @@ Обзор ===== -Yii приложения организованы согласно шаблону проектирования [модель-представление-контроллер (MVC)](http://ru.wikipedia.org/wiki/Model-View-Controller). +Yii приложения организованы согласно шаблону проектирования [модель-представление-контроллер (MVC)](https://ru.wikipedia.org/wiki/Model-View-Controller). [Модели](structure-models.md) представляют собой данные, бизнес логику и бизнес правила; [представления](structure-views.md) отвечают за отображение информации, в том числе и на основе данных, полученных из моделей; [контроллеры](structure-controllers.md) принимают входные данные от пользователя и преобразовывают их в понятный для [моделей](structure-models.md) формат и команды, а также отвечают за отображение diff --git a/docs/guide-ru/structure-views.md b/docs/guide-ru/structure-views.md index 8012681318c..c2903821691 100644 --- a/docs/guide-ru/structure-views.md +++ b/docs/guide-ru/structure-views.md @@ -468,7 +468,7 @@ Yii определяет какой шаблон использовать для * [работа с клиентскими скриптами](output-client-scripts.md): Поддерживает регистрацию и рендеринг CSS и Javascript. * [управление связками](structure-assets.md): позволяет регистрацию и управление [связками клиентского кода](structure-assets.md). * [альтернативные движки шаблонов](tutorial-template-engines.md): позволяет использовать другие шаблонные движки, такие как - [Twig](http://twig.sensiolabs.org/), [Smarty](http://www.smarty.net/). + [Twig](https://twig.symfony.com/), [Smarty](https://www.smarty.net/). Также удобно пользоваться мелкими, но удобными фичами при разработке веб страниц, которые приведены ниже. @@ -539,14 +539,14 @@ $this->registerLinkTag([ 'title' => 'Сводка новостей по Yii', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` Этот код выведет ```html - + ``` Как и в случае с [[yii\web\View::registerMetaTag()|registerMetaTag()]], вы можете указать ключ вторым параметром при вызове diff --git a/docs/guide-ru/test-acceptance.md b/docs/guide-ru/test-acceptance.md index 0ad6975f6b5..0f810746891 100644 --- a/docs/guide-ru/test-acceptance.md +++ b/docs/guide-ru/test-acceptance.md @@ -5,8 +5,8 @@ Приемочное тестирование реализуется с помощью фреймворка Codeception, который имеет отличную документацию: -- [Codeception for Yii framework](http://codeception.com/for/yii) -- [Codeception Acceptance Tests](http://codeception.com/docs/03-AcceptanceTests) +- [Codeception for Yii framework](https://codeception.com/for/yii) +- [Codeception Acceptance Tests](https://codeception.com/docs/03-AcceptanceTests) Запуск тестов в шаблонах проектов basic и advanced -------------------------------------------------- diff --git a/docs/guide-ru/test-environment-setup.md b/docs/guide-ru/test-environment-setup.md index a85c61243be..b6e530a64ac 100644 --- a/docs/guide-ru/test-environment-setup.md +++ b/docs/guide-ru/test-environment-setup.md @@ -51,9 +51,10 @@ Changed current directory to ### Настройка веб-сервера Apache Если вы используете Apache и настроили его как описано в разделе «[Установка Yii](start-installation.md)», то для тестов вам необходимо создать отдельный виртуальный хост который будет работать с той же папкой, но использовать входной скрипт `index-test.php`: + ``` - DocumentRoot "path/to/basic/webb" + DocumentRoot "path/to/basic/web" ServerName mysite-test Order Allow,Deny @@ -67,5 +68,6 @@ Changed current directory to ``` + Так мы укажем веб серверу перенаправлять все запросы на скрипт `index-test.php`. > Note: Обратите внимание, что здесь мы указываем параметр `DirectoryIndex`, помимо тех параметров, которые были указаны для первого хоста. Это сделано с той целью, чтобы при обращении к главной странице по адресу `mysite-test` также использовался бы скрипт `index-test.php`. diff --git a/docs/guide-ru/test-fixtures.md b/docs/guide-ru/test-fixtures.md index 56a054ccb09..1e419ec019b 100644 --- a/docs/guide-ru/test-fixtures.md +++ b/docs/guide-ru/test-fixtures.md @@ -107,7 +107,7 @@ class UserProfileFixture extends ActiveFixture Использование фикстур --------------------- -Если вы используете [Codeception](http://codeception.com/) для тестирования вашего кода, вам следует рассмотреть вопрос +Если вы используете [Codeception](https://codeception.com/) для тестирования вашего кода, вам следует рассмотреть вопрос об использовании расширения `yii2-codeception`, которое имеет встроенную поддержку загрузки фикстур и доступа к ним. Если вы используете другой фреймворк для тестирования, вы можете использовать [[yii\test\FixtureTrait]] в ваших тестах для этих целей. @@ -128,7 +128,7 @@ class UserProfileTest extends DbTestCase public function fixtures() { return [ - 'profiles' => UserProfileFixture::className(), + 'profiles' => UserProfileFixture::class, ]; } diff --git a/docs/guide-ru/test-functional.md b/docs/guide-ru/test-functional.md index 3c2fbf7fae8..8ce956bacef 100644 --- a/docs/guide-ru/test-functional.md +++ b/docs/guide-ru/test-functional.md @@ -3,7 +3,7 @@ > Note: Данный раздел находится в разработке. -- [Codeception Functional Tests](http://codeception.com/docs/04-FunctionalTests) +- [Codeception Functional Tests](https://codeception.com/docs/04-FunctionalTests) Запуск функциональных тестов для шаблонов проектов basic и advanced ------------------------------------------------------------------- diff --git a/docs/guide-ru/test-unit.md b/docs/guide-ru/test-unit.md index 868f50205ad..a7c0ec2abe4 100644 --- a/docs/guide-ru/test-unit.md +++ b/docs/guide-ru/test-unit.md @@ -9,8 +9,8 @@ Модульное тестирование в Yii использует PHPUnit и, опционально, Codeception. Рекомендуется проверить его документацию: -- [Документация PHPUnit начиная с главы 2](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html). -- [Codeception Unit Tests](http://codeception.com/docs/05-UnitTests). +- [Документация PHPUnit начиная с главы 2](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html). +- [Codeception Unit Tests](https://codeception.com/docs/05-UnitTests). Запуск тестов шаблонов проектов basic и advanced ------------------------------------------------ diff --git a/docs/guide-ru/tutorial-core-validators.md b/docs/guide-ru/tutorial-core-validators.md index b3659846821..9d2110c6d10 100644 --- a/docs/guide-ru/tutorial-core-validators.md +++ b/docs/guide-ru/tutorial-core-validators.md @@ -115,9 +115,9 @@ public function rules() описанном здесь: [[yii\validators\DateValidator::timestampAttribute|timestampAttribute]]. - `format`: формат даты/времени, согласно которому должна быть сделана проверка. - Значение может быть паттерном, описанным в [руководстве ICU](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax) + Значение может быть паттерном, описанным в [руководстве ICU](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax) или форматом PHP префиксированным `php:`. Формат должен приниматься классом `Datetime`. Подробнее о нём можно - прочитать в [руководстве PHP по date_create_from_format()](https://secure.php.net/manual/ru/datetime.createfromformat.php). + прочитать в [руководстве PHP по date_create_from_format()](https://www.php.net/manual/ru/datetime.createfromformat.php). Если значение не задано, используется `Yii::$app->formatter->dateFormat`. Подробнее читайте в [[yii\validators\DateValidator::$format|документации по API]]. - `timestampAttribute`: имя атрибута, которому данный валидатор может присваивать значение UNIX timestamp, diff --git a/docs/guide-ru/tutorial-i18n.md b/docs/guide-ru/tutorial-i18n.md index d010588353c..44f233ff19d 100644 --- a/docs/guide-ru/tutorial-i18n.md +++ b/docs/guide-ru/tutorial-i18n.md @@ -46,10 +46,10 @@ return [ ``` Формат для установки языка/локали: `ll-CC`, где `ll` — это двух или трёхбуквенный код языка в нижнем регистре в -соответствии со стандартом [ISO-639](http://www.loc.gov/standards/iso639-2/), а `CC` — это код страны в соответствии +соответствии со стандартом [ISO-639](https://www.loc.gov/standards/iso639-2/), а `CC` — это код страны в соответствии со стандартом [ISO-3166](https://ru.wikipedia.org/wiki/ISO_3166-1#Список_кодов_по_ISO_3166). -> Note: больше информации о синтаксисе и концепции локалей можно получить в [документации проекта ICU](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept). +> Note: больше информации о синтаксисе и концепции локалей можно получить в [документации проекта ICU](https://unicode-org.github.io/icu/userguide/locale/#the-locale-concept). Перевод сообщений -------------------------------------------------------- @@ -134,11 +134,11 @@ echo \Yii::t('app', 'Balance: {0}', $sum); ### Указатели с расширенным форматированием -Чтобы использовать расширенные возможности, вам необходимо установить и включить [PHP-расширение intl](https://secure.php.net/manual/ru/intro.intl.php). +Чтобы использовать расширенные возможности, вам необходимо установить и включить [PHP-расширение intl](https://www.php.net/manual/ru/intro.intl.php). После этого вам станет доступен расширенный синтаксис указателей, а также сокращённая запись `{placeholderName, argumentType}`, эквивалентная форме `{placeholderName, argumentType, argumentStyle}`, позволяющая определять стиль форматирования. -Полная документация доступна на [сайте ICU](http://icu-project.org/apiref/icu4c/classMessageFormat.html), но далее в +Полная документация доступна на [сайте ICU](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classMessageFormat.html), но далее в документации будут приведены примеры использования расширенных возможностей интернационализации. #### Числа @@ -162,7 +162,7 @@ $sum = 42; echo \Yii::t('app', 'Balance: {0, number, ,000,000000}', $sum); ``` -[Описание форматирования](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html). +[Описание форматирования](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classDecimalFormat.html). #### Даты @@ -182,7 +182,7 @@ echo \Yii::t('app', 'Today is {0, date, short}', time()); echo \Yii::t('app', 'Today is {0, date,yyyy-MM-dd}', time()); ``` -[Описание форматирования](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +[Описание форматирования](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### Время @@ -202,7 +202,7 @@ echo \Yii::t('app', 'It is {0, time, short}', time()); echo \Yii::t('app', 'It is {0, date,HH:mm}', time()); ``` -[Описание форматирования](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +[Описание форматирования](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### Числа прописью @@ -268,7 +268,7 @@ for an argument: U_ARGUMENT_TYPE_MISMATCH": ``` Подробная документация о формах склонений для различных языков доступна на сайте -[unicode.org](http://cldr.unicode.org/index/cldr-spec/plural-rules). +[unicode.org](https://cldr.unicode.org/index/cldr-spec/plural-rules). #### Вариации @@ -554,13 +554,13 @@ class TranslationEventHandler Настройка PHP-окружения ------------------------------------------------------------ -Для работы с большей частью функций интернационализации Yii использует [PHP-расширение intl](https://secure.php.net/manual/ru/book.intl.php). +Для работы с большей частью функций интернационализации Yii использует [PHP-расширение intl](https://www.php.net/manual/ru/book.intl.php). Например, это расширение используют классы, отвечающие за форматирование чисел и дат [[yii\i18n\Formatter]] и за форматирование строк [[yii\i18n\MessageFormatter]]. Оба класса поддерживают базовый функционал даже в том случае, если расширение `intl` не установлено. Однако этот запасной вариант более или менее будет работать только для сайтов на английском языке, хотя даже для них большая часть широких возможностей расширения `intl` не будет доступна, поэтому его установка настоятельно рекомендуется. -[PHP-расширение intl](https://secure.php.net/manual/ru/book.intl.php) основано на [библиотеке ICU](http://site.icu-project.org/), которая +[PHP-расширение intl](https://www.php.net/manual/ru/book.intl.php) основано на [библиотеке ICU](https://icu.unicode.org/), которая описывает правила форматирования для различных локалей. Поэтому следует помнить, что форматирование чисел и дат вместе с синтаксисом форматирования может отличаться в зависимости от версии библиотеки ICU, которая была скомпилирована в вашем дистрибутиве PHP. @@ -577,7 +577,7 @@ echo "ICU: " . INTL_ICU_VERSION . "\n"; ``` Чтобы иметь доступ ко всем возможностям, описанным в документации, мы рекомендуем использовать ICU версии 49 или новее. -В более ранних версиях отсутствует указатель `#` в правилах склонений. На сайте +В более ранних версиях отсутствует указатель `#` в правилах склонений. На сайте вы можете ознакомиться со списком доступных версий ICU. Обратите внимание, что схема нумерации версий изменилась после версии 4.8 и последовательность версий выглядит так: ICU 4.8, ICU 49, ICU 50, ICU 51 и так далее. diff --git a/docs/guide-ru/tutorial-performance-tuning.md b/docs/guide-ru/tutorial-performance-tuning.md index fa9162bad3a..3de45ee9f27 100644 --- a/docs/guide-ru/tutorial-performance-tuning.md +++ b/docs/guide-ru/tutorial-performance-tuning.md @@ -11,7 +11,7 @@ Хорошо сконфигурированное окружение PHP очень важно. Для получения максимальной производительности, - Используйте последнюю стабильную версию PHP. Мажорные релизы PHP могут принести значительные улучшения производительности. -- Включите кеширование байткода в [Opcache](https://secure.php.net/manual/ru/book.opcache.php) (PHP 5.5 и старше) или [APC](http://secure.php.net/manual/ru/book.apc.php) +- Включите кеширование байткода в [Opcache](https://www.php.net/manual/ru/book.opcache.php) (PHP 5.5 и старше) или [APC](https://www.php.net/manual/ru/book.apc.php) (PHP 5.4 и более ранние версии). Кеширование байткода позволяет избежать затрат времени на обработку и подключение PHP скриптов при каждом входящем запросе. @@ -130,7 +130,7 @@ CREATE TABLE session ( хранилища кеша могут *сбрасывать* закешированные данные при достижении лимитов хранилища. По этой причине, вы должны в основном использовать хранилища кеша, которые не имеют таких лимитов. -Если на вашем сервере установлен [Redis](http://redis.io/), настоятельно рекомендуется выбрать его в качестве +Если на вашем сервере установлен [Redis](https://redis.io/), настоятельно рекомендуется выбрать его в качестве хранилища сессий используя [[yii\redis\Session]]. @@ -212,5 +212,5 @@ composer dumpautoload -o Следующие инструменты для профилирования могут оказаться полезными: - [Отладочный тулбар Yii и отладчик](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md) -- [Профайлер XDebug](http://xdebug.org/docs/profiler) -- [XHProf](https://secure.php.net/manual/en/book.xhprof.php) +- [Профайлер XDebug](https://xdebug.org/docs/profiler) +- [XHProf](https://www.php.net/manual/en/book.xhprof.php) diff --git a/docs/guide-ru/tutorial-start-from-scratch.md b/docs/guide-ru/tutorial-start-from-scratch.md index 9e59d594566..233482d8c26 100644 --- a/docs/guide-ru/tutorial-start-from-scratch.md +++ b/docs/guide-ru/tutorial-start-from-scratch.md @@ -19,7 +19,7 @@ git clone git@github.com:yiisoft/yii2-app-basic.git ``` -Затем необходимо подождать, чтобы репозитарии загрузился на ваш компьютер. С внесенными изменениями шаблон должен быть "запушен"(push) обратно, затем вы можете удалить `.git` директорию и весь загруженный контент на вашем компьютере. +Затем необходимо подождать, чтобы репозитарий загрузился на ваш компьютер. Поскольку измененный шаблон не должен быть "запушен" (push) обратно, вы можете удалить из загруженного директорию `.git` со всем её содержимым. Измените файлы ------------ @@ -35,7 +35,7 @@ git clone git@github.com:yiisoft/yii2-app-basic.git Создание пакета -------------- -Создайте Git репозитарий из созданного шаблона, и запушьте(push) его. Если вы собираетесь сделать ваш шаблон с открытым исходным кодом, [Github](http://github.com) - это лучшее место, чтобы разместить его. Если вы собираетесь сохранить ваш шаблон для личных целей, используйте любой Git, предназначенный для этих целей. +Создайте Git репозитарий из созданного шаблона, и запушьте(push) его. Если вы собираетесь сделать ваш шаблон с открытым исходным кодом, [Github](https://github.com) - это лучшее место, чтобы разместить его. Если вы собираетесь сохранить ваш шаблон для личных целей, используйте любой Git, предназначенный для этих целей. Затем, вам необходимо зарегистрировать ваш пакет в Composer. Пакет с публичным шаблоном должен быть зарегистрирован на [Packagist](https://packagist.org/). Для приватных шаблонов, зарегистрировать шаблона немного сложнее. Для получения инструкции загляните в [Composer documentation](https://getcomposer.org/doc/05-repositories.md#hosting-your-own). diff --git a/docs/guide-ru/tutorial-template-engines.md b/docs/guide-ru/tutorial-template-engines.md index e69bb5f17cc..1d07331328f 100644 --- a/docs/guide-ru/tutorial-template-engines.md +++ b/docs/guide-ru/tutorial-template-engines.md @@ -2,7 +2,7 @@ ====================== По умолчанию, Yii использует PHP в шаблонах, но вы можете настроить Yii на поддержку других шаблонизаторов, таких как -[Twig](http://twig.sensiolabs.org/) или [Smarty](http://www.smarty.net/), которые доступны в расширениях. +[Twig](https://twig.symfony.com/) или [Smarty](https://www.smarty.net/), которые доступны в расширениях. Компонент `view`, отвественный за генерацию видов. Вы можете добавить шаблонизатор с помощью перенастройки поведения компонента: diff --git a/docs/guide-ru/tutorial-yii-integration.md b/docs/guide-ru/tutorial-yii-integration.md index 6df394f094a..1911919c76a 100644 --- a/docs/guide-ru/tutorial-yii-integration.md +++ b/docs/guide-ru/tutorial-yii-integration.md @@ -34,7 +34,7 @@ require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; Если библиотека использует собственный автозагрузчик классов, его можно подключить во [входном скрипте](structure-entry-scripts.md) приложения. Желательно подключить его до того, как подключается файл `Yii.php`, чтобы при автоматической загрузке классов у автозагрузчика классов Yii был приоритет. -Если библиотека не поставляется с автозагрузчиком классов, но конвенция именования ее классов соответствует [PSR-4](http://www.php-fig.org/psr/psr-4/), для загрузки ее классов можно использовать автозагрузчик Yii. Для этого достаточно для каждого корневого пространства имен, которые используются в ее классах, объявить [корневой псевдоним](concept-aliases.md#defining-aliases). Предположим, что библиотека установлена в директорию `vendor/foo/bar`, а ее классы объявлены в корневом пространстве имен `xyz`. В конфигурации приложения можно использовать следующий код: +Если библиотека не поставляется с автозагрузчиком классов, но конвенция именования ее классов соответствует [PSR-4](https://www.php-fig.org/psr/psr-4/), для загрузки ее классов можно использовать автозагрузчик Yii. Для этого достаточно для каждого корневого пространства имен, которые используются в ее классах, объявить [корневой псевдоним](concept-aliases.md#defining-aliases). Предположим, что библиотека установлена в директорию `vendor/foo/bar`, а ее классы объявлены в корневом пространстве имен `xyz`. В конфигурации приложения можно использовать следующий код: ```php [ @@ -71,10 +71,10 @@ composer require yiisoft/yii2 [ресурсов](structure-assets.md), вы можете установить специальный пакет, который предотвращает загрузку Bower и NPM пакетов. Смотрите [cebe/assetfree-yii2](https://github.com/cebe/assetfree-yii2) для деталей. -Первая команда устанавливает [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/), который позволяет управлять зависимостями пакетов bower и npm через Composer. Даже если вы хотите воспользоваться слоем абстракции баз данных или другими элементами Yii, не связанными с ресурсами, этот плагин все равно придется установить, так как без него не установится пакет Yii. +Первая команда устанавливает [composer asset plugin](https://github.com/fxpio/composer-asset-plugin), который позволяет управлять зависимостями пакетов bower и npm через Composer. Даже если вы хотите воспользоваться слоем абстракции баз данных или другими элементами Yii, не связанными с ресурсами, этот плагин все равно придется установить, так как без него не установится пакет Yii. В разделе [об установке Yii](start-installation.md#installing-via-composer) более подробно описана работа с Composer и даны решения проблем, которые могут возникнуть при установке. -Также можно [скачать](http://www.yiiframework.com/download/) файл релиза Yii и распаковать его в директорию `BasePath/vendor`. +Также можно [скачать](https://www.yiiframework.com/download/) файл релиза Yii и распаковать его в директорию `BasePath/vendor`. Далее следует изменить входной скрипт сторонней системы, поместив в его начало следующий код: diff --git a/docs/guide-tr/README.md b/docs/guide-tr/README.md index 03e7b38eab7..5e2061cfbf6 100644 --- a/docs/guide-tr/README.md +++ b/docs/guide-tr/README.md @@ -1,7 +1,7 @@ Yii 2.0 için Açıklayıcı Rehber ============================== -Bu döküman, [Yii Dökümantasyon Koşulları](http://www.yiiframework.com/doc/terms/) altında yayınlandı. +Bu döküman, [Yii Dökümantasyon Koşulları](https://www.yiiframework.com/doc/terms/) altında yayınlandı. Tüm hakları saklıdır. diff --git a/docs/guide-tr/intro-yii.md b/docs/guide-tr/intro-yii.md index 330cad30944..7807853affc 100644 --- a/docs/guide-tr/intro-yii.md +++ b/docs/guide-tr/intro-yii.md @@ -19,7 +19,7 @@ Eğer zaten başka bir kütüphane ailesine dahilseniz, Yii'yi karşılaştırma - Yii son derece genişletilebilir. Neredeyse her bir çekirdek kodunu kişiselleştirebilir veya değiştirebilirsiniz. Yeniden dağıtılabilir uzantıları kullanmak veya geliştirmek için Yii'nin katı uzantı mimarisinden de yararlanabilirsiniz. - Yüksek performans her zaman Yii'nin öncelikli hedefidir. -Yii tek kişilik bir gösteri değildir, [güçlü çekirdek geliştirici ekibi](http://www.yiiframework.com/team/) ve Yii'nin gelişimine sürekli katkıda bulunan büyük bir profesyonel geliştirici topluluğu tarafından da destekleniyor. Yii geliştirici ekibi, en yeni Web geliştirme teknikleri ile diğer kütüphaneler ve projelerde bulunan en iyi uygulamalara ve özelliklere yakından göz atmaktadır. Basit ve zarif arayüzler aracılığıyla, başka yerde bulunan en uygun, en iyi uygulamalar ve özellikler, düzenli olarak çekirdek kütüphaneye dahil edilir. +Yii tek kişilik bir gösteri değildir, [güçlü çekirdek geliştirici ekibi](https://www.yiiframework.com/team/) ve Yii'nin gelişimine sürekli katkıda bulunan büyük bir profesyonel geliştirici topluluğu tarafından da destekleniyor. Yii geliştirici ekibi, en yeni Web geliştirme teknikleri ile diğer kütüphaneler ve projelerde bulunan en iyi uygulamalara ve özelliklere yakından göz atmaktadır. Basit ve zarif arayüzler aracılığıyla, başka yerde bulunan en uygun, en iyi uygulamalar ve özellikler, düzenli olarak çekirdek kütüphaneye dahil edilir. Yii'nin Sürümleri @@ -34,4 +34,4 @@ Gereksinimler ve Önkoşullar Yii 2.0, PHP 5.4.0 veya üstü sürüm gerektirir ve PHP 7'nin en son sürümü ile en iyi şekilde çalışır. Her bir Yii sürümünde yer alan gereksinim denetleyicisini çalıştırarak, daha ayrıntılı gereksinimleri ayrı ayrı özellikler için bulabilirsiniz. -Yii OOP temelli bir kütüphane olduğu için Yii'yi kullanmak, nesne yönelimli programlama (OOP) hakkında temel bilgi gerektirir. Yii 2.0 ayrıca PHP'nin [namespaceler](https://secure.php.net/manual/en/language.namespaces.php) ve [traitler](https://secure.php.net/manual/en/language.oop5.traits.php) gibi son özelliklerinden de yararlanır. Bu kavramları anlamak, Yii 2.0'ı daha kolay anlamanıza yardımcı olacaktır. +Yii OOP temelli bir kütüphane olduğu için Yii'yi kullanmak, nesne yönelimli programlama (OOP) hakkında temel bilgi gerektirir. Yii 2.0 ayrıca PHP'nin [namespaceler](https://www.php.net/manual/en/language.namespaces.php) ve [traitler](https://www.php.net/manual/en/language.oop5.traits.php) gibi son özelliklerinden de yararlanır. Bu kavramları anlamak, Yii 2.0'ı daha kolay anlamanıza yardımcı olacaktır. diff --git a/docs/guide-tr/start-prerequisites.md b/docs/guide-tr/start-prerequisites.md index 82da68bf236..7755c2fda13 100644 --- a/docs/guide-tr/start-prerequisites.md +++ b/docs/guide-tr/start-prerequisites.md @@ -4,7 +4,7 @@ Yii'yi öğrenmesi, diğer PHP kütüphaneleri kadar zor olmasada, yine de başl ## PHP -Yii bir PHP kütüphanesidir, bu yüzden [PHP Dil Başvuru Kılavuzunu](https://secure.php.net/manual/tr/langref.php) okuduğunuzdan ve anladığınızdan emin olun. Yii ile geliştirirken, nesne yönelimli bir şekilde kod yazacaksınız, bu yüzden [Sınıflar ve Nesneler](https://secure.php.net/manual/tr/language.oop5.basic.php) gibi [ad alanları](https://secure.php.net/manual/en/language.namespaces.php)na aşina olduğunuzdan emin olun. +Yii bir PHP kütüphanesidir, bu yüzden [PHP Dil Başvuru Kılavuzunu](https://www.php.net/manual/tr/langref.php) okuduğunuzdan ve anladığınızdan emin olun. Yii ile geliştirirken, nesne yönelimli bir şekilde kod yazacaksınız, bu yüzden [Sınıflar ve Nesneler](https://www.php.net/manual/tr/language.oop5.basic.php) gibi [ad alanları](https://www.php.net/manual/en/language.namespaces.php)na aşina olduğunuzdan emin olun. ## Nesne Yönelimli Programlama (OOP) diff --git a/docs/guide-uk/README.md b/docs/guide-uk/README.md index c44f93736bf..6eeb96c8b2a 100644 --- a/docs/guide-uk/README.md +++ b/docs/guide-uk/README.md @@ -1,7 +1,7 @@ Повний посібник з Yii 2.0 ========================= -Даний посібник випущено відповідно до [положень про документацію Yii](http://www.yiiframework.com/doc/terms/). +Даний посібник випущено відповідно до [положень про документацію Yii](https://www.yiiframework.com/doc/terms/). All Rights Reserved. @@ -129,7 +129,7 @@ All Rights Reserved. Веб-сервіси RESTful ------------------- -* **TBD** [Швидкий старт](rest-quick-start.md) +* [Швидкий старт](rest-quick-start.md) * **TBD** [Ресурси](rest-resources.md) * **TBD** [Контролери](rest-controllers.md) * **TBD** [Маршрутизація](rest-routing.md) diff --git a/docs/guide-uk/concept-aliases.md b/docs/guide-uk/concept-aliases.md index cebb6911a1c..9aba4b618f6 100644 --- a/docs/guide-uk/concept-aliases.md +++ b/docs/guide-uk/concept-aliases.md @@ -112,8 +112,8 @@ $cache = new FileCache([ - `@webroot`, коренева веб-директорія поточного веб-додатку. Визначається на основі директорії розташування [вхідного скрипта](structure-entry-scripts.md). - `@web`, базовий URL поточного додатку. Має таке ж значення, як і [[yii\web\Request::baseUrl]]. - `@vendor`, [[yii\base\Application::vendorPath|директорія vendor Composer]]. За замовчуванням `@app/vendor`. -- `@bower`, директорія, що містить [пакунки Bower](http://bower.io/). За замовчуванням `@vendor/bower`. -- `@npm`, директорія, що містить [пакунки NPM](https://www.npmjs.org/). За замовчуванням `@vendor/npm`. +- `@bower`, директорія, що містить [пакунки Bower](https://bower.io/). За замовчуванням `@vendor/bower`. +- `@npm`, директорія, що містить [пакунки NPM](https://www.npmjs.com/). За замовчуванням `@vendor/npm`. Псевдонім `@yii` задається в момент підключення файлу `Yii.php` у [вхідному скрипті](structure-entry-scripts.md). Решта псевдонімів задаються в конструкторі додатка в момент застосування [конфигурації](concept-configurations.md). diff --git a/docs/guide-uk/concept-autoloading.md b/docs/guide-uk/concept-autoloading.md index 7c2c3d8ff6c..f8efe38d33f 100644 --- a/docs/guide-uk/concept-autoloading.md +++ b/docs/guide-uk/concept-autoloading.md @@ -2,7 +2,7 @@ ======================= Пошук і підключення файлів класів в Yii реалізовано за допомогою -[автозавантаження класів](https://secure.php.net/manual/ru/language.oop5.autoload.php). +[автозавантаження класів](https://www.php.net/manual/ru/language.oop5.autoload.php). Фреймворк надає власний швидкісний автозавантажувач, що сумісний з [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md), який встановлюється в момент підключення файлу `Yii.php`. @@ -16,7 +16,7 @@ Для використання автозавантажувача класів Yii слід дотримуватися два простих правила створення і іменування класів: -* Кожен клас повинен належати до [простору імен](https://secure.php.net/manual/en/language.namespaces.php) (наприклад, `foo\bar\MyClass`) +* Кожен клас повинен належати до [простору імен](https://www.php.net/manual/en/language.namespaces.php) (наприклад, `foo\bar\MyClass`) * Кожен клас повинен знаходитися в окремому файлі, шлях до якого визначаться наступним правилом: ```php diff --git a/docs/guide-uk/intro-upgrade-from-v1.md b/docs/guide-uk/intro-upgrade-from-v1.md index 308bcf27817..7a3e79ee3c6 100644 --- a/docs/guide-uk/intro-upgrade-from-v1.md +++ b/docs/guide-uk/intro-upgrade-from-v1.md @@ -30,16 +30,16 @@ Yii 2.0 використовує PHP 5.4 або вище, який включа яка використовувалася Yii 1.1. Таким чином, існує багато відмінностей у мові, які ви повинні приймати до уваги. Нижче наведені основні зміни в PHP: -- [Простори імен](https://secure.php.net/manual/en/language.namespaces.php); -- [Анонімні функції](https://secure.php.net/manual/en/functions.anonymous.php); +- [Простори імен](https://www.php.net/manual/en/language.namespaces.php); +- [Анонімні функції](https://www.php.net/manual/en/functions.anonymous.php); - Використання короткого синтаксису для масивів: `[...елементи...]` замість `array(...елементи...)`; - Використання тегів ` + +По-перше, створимо клас контролера `app\controllers\UserController`: + +```php +namespace app\controllers; + +use yii\rest\ActiveController; + +class UserController extends ActiveController +{ + public $modelClass = 'app\models\User'; +} +``` + +Клас контролера успадковується від [[yii\rest\ActiveController]]. Ми задали [[yii\rest\ActiveController::modelClass|modelClass]] +як `app\models\User`, цим вказавши контролеру, до якої моделі йому необхідно звертатися для редагування чи +вибірки даних. + + +## Налаштування правил URL + +Далі змінимо налаштування компонента `urlManager` у конфігурації додатку: + +```php +'urlManager' => [ + 'enablePrettyUrl' => true, + 'enableStrictParsing' => true, + 'showScriptName' => false, + 'rules' => [ + ['class' => 'yii\rest\UrlRule', 'controller' => 'user'], + ], +] +``` + +Установи вище додають правило для контролера `user`, яке надає доступ до даних користувача через красиві URL та логічні методи запитів HTTP. + + +## Увімкнення JSON на прийом даних + +Для того, щоб API міг приймати дані у форматі JSON, налаштуйтє [[yii\web\Request::$parsers|parsers]] властивість у компонента `request` [application component](structure-application-components.md) на використання [[yii\web\JsonParser]] JSON даних на вході: + +```php +'request' => [ + 'parsers' => [ + 'application/json' => 'yii\web\JsonParser', + ] +] +``` + +> Note: Конфігурація, наведена вище, необов'язкова. Без наведеної вище конфігурації, API зможе визначити лише + `application/x-www-form-urlencoded` и `multipart/form-data` формати. + + +## Пробуємо + +Ось так просто ми створили RESTful API для доступу до даних користувача. API нашого сервісу зараз включає в себе: + +* `GET /users`: отримання посторінкового списку всіх користувачів; +* `HEAD /users`: отримання метаданих лістингу користувачів; +* `POST /users`: створення нового користувача; +* `GET /users/123`: отримання інформації щодо конкретного користувача з id рівним 123; +* `HEAD /users/123`: отримання метаданих за конкретним користувачем з id рівним 123; +* `PATCH /users/123` та `PUT /users/123`: редагування інформації щодо користувача з id рівним 123; +* `DELETE /users/123`: видалення користувача з id рівним 123; +* `OPTIONS /users`: отримання підтримуваних методів, за якими можна звернутися до `/users`; +* `OPTIONS /users/123`: отримання підтримуваних методів, за якими можна звернутися до `/users/123`. + +Пробуємо отримати відповіді по API використовуючи `curl`: + +``` +$ curl -i -H "Accept:application/json" "http://localhost/users" + +HTTP/1.1 200 OK +Date: Sun, 02 Mar 2014 05:31:43 GMT +Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y +X-Powered-By: PHP/5.4.20 +X-Pagination-Total-Count: 1000 +X-Pagination-Page-Count: 50 +X-Pagination-Current-Page: 1 +X-Pagination-Per-Page: 20 +Link: ; rel=self, + ; rel=next, + ; rel=last +Transfer-Encoding: chunked +Content-Type: application/json; charset=UTF-8 + +[ + { + "id": 1, + ... + }, + { + "id": 2, + ... + }, + ... +] +``` + +Спробуйте змінити заголовок допустимого формату ресурсу на `application/xml` і у відповідь ви отримаєте результат у форматі XML: + +``` +$ curl -i -H "Accept:application/xml" "http://localhost/users" + +HTTP/1.1 200 OK +Date: Sun, 02 Mar 2014 05:31:43 GMT +Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y +X-Powered-By: PHP/5.4.20 +X-Pagination-Total-Count: 1000 +X-Pagination-Page-Count: 50 +X-Pagination-Current-Page: 1 +X-Pagination-Per-Page: 20 +Link: ; rel=self, + ; rel=next, + ; rel=last +Transfer-Encoding: chunked +Content-Type: application/xml + + + + + 1 + ... + + + 2 + ... + + ... + +``` + +> Tip: Ви можете отримати доступ до API через веб-браузер, ввівши адресу `http://localhost/users`. Але в цьому випадку +для передачі певних заголовків вам, швидше за все, потрібні додаткові плагіни для браузера. + +Якщо уважно подивитися результат відповіді, то можна виявити, що в заголовках є інформація про загальну кількість записів, +кількості сторінок і т. д. Тут також можна виявити посилання на інші сторінки, як, наприклад, +`http://localhost/users?page=2`. Перейшовши по ній, можна отримати другу сторінку даних користувачів. + +Використовуючи параметри `fields` та `expand` в URL, можна вказати, які поля мають бути включені до результату. Наприклад, +за адресою `http://localhost/users?fields=id,email` ми отримаємо інформацію щодо користувачів, яка міститиме +тільки `id` та `email`. + +> Info: Ви, напевно, помітили, що при зверненні до `http://localhost/users` ми отримуємо інформацію з полями, +> які небажано показувати, такими як `password_hash` та `auth_key`. Ви можете і повинні видалити ці поля, як описано у +> розділі «[Ресурси](rest-resources.md)». + +Додатково ви можете відсортувати колекції як `http://localhost/users?sort=email` або +`http://localhost/users?sort=-email`. Фільтрування колекцій як `http://localhost/users?filter[id]=10` або +`http://localhost/users?filter[email][like]=gmail.com` можлива при використанні +фільтрів даних. Докладніше у розділі [Resources](rest-resources.md#filtering-collections). + +## Резюме + +Використовуючи Yii, як RESTful API фреймворк, ми реалізуємо точки входу API як дії контролерів. +Контролер використовується для організації дій, що належать до певного типу ресурсу. + +Ресурси представлені як моделі даних, які успадковуються від класу [[yii\base\Model]]. +Якщо потрібна робота з базами даних (як із реляційними, так і з NoSQL), рекомендується використовувати для представлення +ресурсів [[yii\db\ActiveRecord|ActiveRecord]]. + +Ви можете використовувати [[yii\rest\UrlRule]] для спрощення маршрутизації точок входу API. + +Хоча це не обов'язково, рекомендується відокремлювати RESTful APIs додаток від основного веб-додатку. Такий поділ +легше підтримувати. diff --git a/docs/guide-uk/start-databases.md b/docs/guide-uk/start-databases.md index 53c73be72dd..dbbb4789e82 100644 --- a/docs/guide-uk/start-databases.md +++ b/docs/guide-uk/start-databases.md @@ -50,7 +50,7 @@ INSERT INTO `country` VALUES ('US','United States',322976000); Налаштування підключення до БД ------------------------------ -Перш ніж продовжити, переконайтеся, що у вас встановлено розширення PHP [PDO](https://secure.php.net/manual/en/book.pdo.php) +Перш ніж продовжити, переконайтеся, що у вас встановлено розширення PHP [PDO](https://www.php.net/manual/en/book.pdo.php) та драйвер PDO для вашої БД (наприклад `pdo_mysql` для MySQL). Це є основною вимогою, якщо ваш додаток використовує реляційну базу даних. diff --git a/docs/guide-uk/start-forms.md b/docs/guide-uk/start-forms.md index f859bfae51d..a957fb7697a 100644 --- a/docs/guide-uk/start-forms.md +++ b/docs/guide-uk/start-forms.md @@ -130,7 +130,7 @@ HTML-формою та повідомленнями про присутні по > Note: У цьому дуже простому прикладі ми просто відобразили сторінку підтвердження відправлення даних. На практиці, ви повинні розглянути використання [[yii\web\Controller::refresh()|refresh()]] або [[yii\web\Controller::redirect()|redirect()]] -для уникнення [проблеми повторного відправлення даних форми](http://en.wikipedia.org/wiki/Post/Redirect/Get). +для уникнення [проблеми повторного відправлення даних форми](https://en.wikipedia.org/wiki/Post/Redirect/Get). Створення представлення diff --git a/docs/guide-uk/start-hello.md b/docs/guide-uk/start-hello.md index dae433bcf7b..25cc4912539 100644 --- a/docs/guide-uk/start-hello.md +++ b/docs/guide-uk/start-hello.md @@ -22,9 +22,9 @@ параметр `message` із запиту і відображає його значення користувачу. Якщо в запиті відсутній параметр `message`, то дія буде відображати "Привіт". -> Інформація: [Дії](structure-controllers.md#creating-actions) являються об’єктами, на які користувач може посилатись для -виконання. Дії згруповані в [контролери](structure-controllers.md). Результатом виконання -дії є відповідь, яку отримує користувач. +> Info: [Дії](structure-controllers.md#creating-actions) являються об’єктами, на які користувач може посилатись для + виконання. Дії згруповані в [контролери](structure-controllers.md). Результатом виконання + дії є відповідь, яку отримує користувач. Дії повинні оголошуватись в [контролерах](structure-controllers.md). Для простоти, ви можете оголосити дію `say` в уже наявному контролері `SiteController`, який визначений @@ -88,7 +88,7 @@ use yii\helpers\Html; Варто зазначити, що у вищезазначеному коді параметр `message` [[yii\helpers\Html::encode()|екранується для HTML]] перед відображенням. Це обов’язково, бо параметр приходить від користувача, котрий може спробувати провести -[XSS атаку](http://uk.wikipedia.org/wiki/%D0%9C%D1%96%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D0%B8%D0%B9_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%96%D0%BD%D0%B3), +[XSS атаку](https://uk.wikipedia.org/wiki/%D0%9C%D1%96%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D0%B8%D0%B9_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%96%D0%BD%D0%B3), шляхом вставки небезпечного JavaScript кода. Ви можете доповнити представлення `say` HTML-тегами, текстом або кодом PHP. diff --git a/docs/guide-uk/start-installation.md b/docs/guide-uk/start-installation.md index 7fdbf46dd0b..96ff70732e4 100644 --- a/docs/guide-uk/start-installation.md +++ b/docs/guide-uk/start-installation.md @@ -44,7 +44,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic ``` -Перша команда встановить [плагін ресурсів composer (composer-asset-plugin)](https://github.com/francoispluchino/composer-asset-plugin/), +Перша команда встановить [плагін ресурсів composer (composer-asset-plugin)](https://github.com/fxpio/composer-asset-plugin), що дозволить керувати залежностями пакунків Bower та NPM за допомогою Composer. Цю команду потрібно виконати лише один раз. Друга команда встановить Yii у директорію під назвою `basic`. За бажанням, ви можете обрати інше ім’я для директорії. @@ -69,7 +69,7 @@ Встановлення Yii з архіву складається з трьох кроків: -1. Завантажте архів за адресою [yiiframework.com](http://www.yiiframework.com/download/); +1. Завантажте архів за адресою [yiiframework.com](https://www.yiiframework.com/download/); 2. Розпакуйте архів в директорію, доступну через Web. 3. Відредагуйте файл конфігурації `config/web.php` - необхідно ввести таємний ключ до пункту `cookieValidationKey` (це виконується автоматично при вставленні Yii через Composer): @@ -99,7 +99,7 @@ ---------------------- Після успішного встановлення ви можете налаштувати свій веб-сервер (див. наступний розділ) -або використати [вбудований веб-сервер PHP](https://secure.php.net/manual/en/features.commandline.webserver.php), +або використати [вбудований веб-сервер PHP](https://www.php.net/manual/en/features.commandline.webserver.php), виконавши наступну консольну команду із директорії `web`: ```bash @@ -136,7 +136,7 @@ http://localhost:8080/ ``` Необхідно налаштувати PHP таким чином, щоб він відповідав мінімальним вимогам Yii. Основна вимога — PHP версії 5.4 або вище. -Якщо ваш додаток працює з базою даних, необхідно встановити [розширення PHP PDO](https://secure.php.net/manual/en/pdo.installation.php) +Якщо ваш додаток працює з базою даних, необхідно встановити [розширення PHP PDO](https://www.php.net/manual/en/pdo.installation.php) та відповідний драйвер (наприклад, `pdo_mysql` для MySQL). @@ -147,9 +147,9 @@ http://localhost:8080/ і не розгортаєте його на робочому сервері. Додаток, встановлений за інструкціями, наведеними вище, буде працювати одразу як -з [Apache HTTP server](http://httpd.apache.org/), так і з [Nginx HTTP server](http://nginx.org/) на +з [Apache HTTP server](https://httpd.apache.org/), так і з [Nginx HTTP server](https://nginx.org/) на Windows, Mac OS X чи Linux із встановленим PHP 5.4 або вище. Yii 2.0 також сумісний із віртуальною машиною Фейсбука -[HHVM](http://hhvm.com/), однак є деякі крайні випадки, де HHVM поводиться інакше, +[HHVM](https://hhvm.com/), однак є деякі крайні випадки, де HHVM поводиться інакше, ніж рідний PHP, тому ви повинні бути дуже уважними при використанні HHVM. На робочому сервері вам напевно захочеться змінити URL додатку з `http://www.example.com/basic/web/index.php` @@ -191,7 +191,7 @@ DocumentRoot "path/to/basic/web" ### Рекомендовані налаштування Nginx -Для використання [Nginx](http://wiki.nginx.org/) вам потрібно встановити PHP як [FPM SAPI](https://secure.php.net/install.fpm). +Для використання [Nginx](https://wiki.nginx.org/) вам потрібно встановити PHP як [FPM SAPI](https://www.php.net/install.fpm). Використовуйте наступні параметри Nginx, замінивши `path/to/basic/web` на коректний шлях до `basic/web`, а `mysite.test` на актуальний домен. diff --git a/docs/guide-uk/start-looking-ahead.md b/docs/guide-uk/start-looking-ahead.md index a1f072eb283..a39c4ce86e6 100644 --- a/docs/guide-uk/start-looking-ahead.md +++ b/docs/guide-uk/start-looking-ahead.md @@ -9,26 +9,26 @@ У цьому розділі зібрані ресурси пов’язані з Yii, які допоможуть вам бути більш продуктивними при використанні фреймворку. * Документація - - [Докладний Посібник](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [Докладний Посібник](https://www.yiiframework.com/doc-2.0/guide-README.html): Як випливає з назви, посібник точно визначає, як Yii повинен працювати і дає вам загальні вказівки щодо його застосування. Це найважливіший Yii підручник, з яким ви маєте ознайомитись, перш ніж писати Yii код. - - [Довідник класів](http://www.yiiframework.com/doc-2.0/index.html): + - [Довідник класів](https://www.yiiframework.com/doc-2.0/index.html): Визначає використання кожного класу, представленого в Yii. Ним слід користуватися, коли ви пишете код і хочете розібратися у використанні конкретного класу, методу, властивості. Довідник класів найкраще використовувати після контекстного розуміння всього фреймворку. - - [Wiki-статті](http://www.yiiframework.com/wiki/?tag=yii2): + - [Wiki-статті](https://www.yiiframework.com/wiki/?tag=yii2): Wiki-статті написані користувачами Yii на основі їх власного досвіду. Більшість з них написані як рецепти з куховарської книги, які показують, як вирішити конкретні проблеми, використовуючи Yii. Варто зауважити, що якість даних статей може бути не такою гарною, як у Докладному Посібнику, але вони корисні тим, що охоплюють ширші теми і часто можуть забезпечити готовими рішеннями для подальшого використання. - - [Книги](http://www.yiiframework.com/doc/) -* [Розширення](http://www.yiiframework.com/extensions/): + - [Книги](https://www.yiiframework.com/books) +* [Розширення](https://www.yiiframework.com/extensions/): Yii пишається бібліотекою із тисяч розширень, внесених користувачами, які можуть бути легко підключені у ваші додатки та зробити розробку додатків ще швидшим і простішим. * Спільнота - - Форум: - - Чат IRC: Канал #yii мережі freenode () + - Форум: + - Чат IRC: Канал #yii мережі Libera () - Чат Gitter: - GitHub: - Фейсбук: - Твіттер: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide-uk/start-workflow.md b/docs/guide-uk/start-workflow.md index ce378f7e5bf..97b59965f9a 100644 --- a/docs/guide-uk/start-workflow.md +++ b/docs/guide-uk/start-workflow.md @@ -39,7 +39,7 @@ Нижче наведений перелік основних директорій і файлів вашого додатку (вважаємо, що додаток встановлений в директорію `basic`): -``` +```js basic/ базова директорія додатка composer.json використовується Composer'ом, містить опис додатку config/ містить конфігураційні файли @@ -60,7 +60,7 @@ basic/ базова директорія додатка В цілому, додаток Yii можна розділити на дві категорії файлів: розміщенні в `basic/web` і розміщенні в інших директоріях. Перша категорія доступна через HTTP (наприклад, браузером), друга недоступна зовні, та і не повинна бути, оскільки містить службову інформацію. -В Yii реалізований шаблон проектування [модель-представлення-контролер (MVC)](http://uk.wikipedia.org/wiki/Model-View-Controller), +В Yii реалізований шаблон проектування [модель-представлення-контролер (MVC)](https://uk.wikipedia.org/wiki/Model-View-Controller), що відображається на вищезазначеній структурі директорій додатка. В директорії `models` знаходяться всі класи [моделей](structure-models.md), у `views` розміщені всі скрипти [представлень](structure-views.md), а в директорії `controllers` всі класи [контролерів](structure-controllers.md) додатка. diff --git a/docs/guide-uk/structure-applications.md b/docs/guide-uk/structure-applications.md index 4db7787cf4a..b935ff79242 100644 --- a/docs/guide-uk/structure-applications.md +++ b/docs/guide-uk/structure-applications.md @@ -274,7 +274,7 @@ Yii встановлює відповідність між ідентифіка використовує значення даної властивості для визначення мови, на якій має бути зображений календар і який формат дати повинен бути. -Рекомендується вказувати мову у рамках стандарту [IETF](http://en.wikipedia.org/wiki/IETF_language_tag). +Рекомендується вказувати мову у рамках стандарту [IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Наприклад, для англійської мови використовується `en`, в той час як для англійської в США - `en-US`. Більш детальна інформація про цю властивість може бути знайдена у розділі [Інтернаціоналізація](tutorial-i18n.md). @@ -346,7 +346,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; є не англійська мова. Аналогічно властивості [language](#language), ви повинні вказати дану властивість у рамках стандарту -[IETF](http://en.wikipedia.org/wiki/IETF_language_tag). Наприклад, для англійської мови +[IETF](https://en.wikipedia.org/wiki/IETF_language_tag). Наприклад, для англійської мови використовується `en`, в той час як для англійської в США - `en-US`. Більш детальна інформація про цю властивість може бути знайдена у розділі [Інтернаціоналізація](tutorial-i18n.md). @@ -356,7 +356,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; Дана властивість надає альтернативний спосіб встановлення часової зони за замовчуванням у процесі роботи додатка. Таким чином, вказуючи дану властивість, ви, по суті, викликаєте PHP-функцію -[date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php). Наприклад, +[date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php). Наприклад, ```php [ diff --git a/docs/guide-uk/structure-controllers.md b/docs/guide-uk/structure-controllers.md index 374abf963d1..88cb383f7f4 100644 --- a/docs/guide-uk/structure-controllers.md +++ b/docs/guide-uk/structure-controllers.md @@ -1,7 +1,7 @@ Контролери ========== -Контролери є частиною архітектури [MVC](http://uk.wikipedia.org/wiki/Модель-вид-контролер). Це об’єкти класів, +Контролери є частиною архітектури [MVC](https://uk.wikipedia.org/wiki/Модель-вид-контролер). Це об’єкти класів, успадкованих від [[yii\base\Controller]] та відповідають за обробку запитів і генерування відповідей. Зокрема, після отримання контролю від [додатків](structure-applications.md), контролери проаналізують вхідні дані, передадуть їх у [моделі](structure-models.md), додадуть результати моделі у diff --git a/docs/guide-uk/structure-entry-scripts.md b/docs/guide-uk/structure-entry-scripts.md index c15bf3a08f8..1f3145e3085 100644 --- a/docs/guide-uk/structure-entry-scripts.md +++ b/docs/guide-uk/structure-entry-scripts.md @@ -57,9 +57,9 @@ $config = require __DIR__ . '/../config/web.php'; /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-uk/structure-models.md b/docs/guide-uk/structure-models.md index fa354c20b52..2bbaa9c7a04 100644 --- a/docs/guide-uk/structure-models.md +++ b/docs/guide-uk/structure-models.md @@ -1,7 +1,7 @@ Моделі ====== -Моделі є частиною архітектури [MVC](http://uk.wikipedia.org/wiki/Модель-вид-контролер). +Моделі є частиною архітектури [MVC](https://uk.wikipedia.org/wiki/Модель-вид-контролер). Це об’єкти, які представляють бізнес-дані, бізнес-правила та бізнес-логіку. Ви можете створювати класи моделей шляхом розширення класу [[yii\base\Model]] або його нащадків. Базовий клас @@ -37,7 +37,7 @@ echo $model->name; ``` Ви також можете отримувати доступ до атрибутів як до елементів масиву, завдяки підтримці -[ArrayAccess](https://secure.php.net/manual/en/class.arrayaccess.php) та [ArrayIterator](https://secure.php.net/manual/en/class.arrayiterator.php) +[ArrayAccess](https://www.php.net/manual/en/class.arrayaccess.php) та [ArrayIterator](https://www.php.net/manual/en/class.arrayiterator.php) у класі [[yii\base\Model]]: ```php diff --git a/docs/guide-uk/structure-overview.md b/docs/guide-uk/structure-overview.md index b61630eacf9..27e98b5e8fb 100644 --- a/docs/guide-uk/structure-overview.md +++ b/docs/guide-uk/structure-overview.md @@ -1,7 +1,7 @@ Огляд ===== -Додатки Yii організовані згідно архітектурного шаблону [Модель-Представлення-Контролер (MVC)](http://uk.wikipedia.org/wiki/Модель-вид-контролер). +Додатки Yii організовані згідно архітектурного шаблону [Модель-Представлення-Контролер (MVC)](https://uk.wikipedia.org/wiki/Модель-вид-контролер). [Моделі](structure-models.md) являють собою дані, бізнес-логіку та бізнес-правила; [представлення](structure-views.md) відповідають за відображення даних моделей; [контролери](structure-controllers.md) приймають вхідні дані від користувача і перетворюють їх у команди для diff --git a/docs/guide-uk/structure-views.md b/docs/guide-uk/structure-views.md index 272c5c98bac..c529593f680 100644 --- a/docs/guide-uk/structure-views.md +++ b/docs/guide-uk/structure-views.md @@ -1,7 +1,7 @@ Представлення ============= -Представлення є частиною архітектури [MVC](http://uk.wikipedia.org/wiki/Модель-вид-контролер). +Представлення є частиною архітектури [MVC](https://uk.wikipedia.org/wiki/Модель-вид-контролер). Це код, який відповідає за відображення даних кінцевим користувачам. У веб-додатку представлення зазвичай створені у вигляді *шаблонів представлень*, які є файлами скриптів PHP, що містять переважно HTML-код та презентаційний PHP-код. Управління ними здійснюється за допомогою [компонента додатку](structure-application-components.md) [[yii\web\View|view]], який надає часто використовувані методи @@ -545,7 +545,7 @@ class PostController extends Controller * [опрацювання клієнтських скриптів](output-client-scripts.md): підтримує реєстрацію та формування CSS та JavaScript; * [опрацювання колекції ресурсів](structure-assets.md): підтримує реєстрацію та формування [колекцій ресурсів](structure-assets.md); * [альтернативні шаблонізатори](tutorial-template-engines.md): дозволяє використовувати інші шаблонізатори, такі як - [Twig](http://twig.sensiolabs.org/), [Smarty](http://www.smarty.net/). + [Twig](https://twig.symfony.com/), [Smarty](https://www.smarty.net/). Ви також можете часто використовувати наступні другорядні, але корисні, можливості в процесі розробки веб-сторінок. @@ -616,14 +616,14 @@ $this->registerLinkTag([ 'title' => 'Свіжі новини про Yii', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` Результатом вищенаведеного коду буде ```html - + ``` Подібно до [[yii\web\View::registerMetaTag()|registerMetaTags()]], ви можете визначати ключ під час виклику diff --git a/docs/guide-uk/tutorial-console.md b/docs/guide-uk/tutorial-console.md index 468201da477..b2afa0b8c92 100644 --- a/docs/guide-uk/tutorial-console.md +++ b/docs/guide-uk/tutorial-console.md @@ -98,11 +98,11 @@ exit($exitCode); оновлення ваших тестових баз даних, які налаштовані кожна в окремому наборі тестів. Для динамічної зміни конфігурації просто вкажіть потрібний файл конфігурації додатка за допомогою опції `appconfig`, коли виконуєте команду: -```bash + +``` yii --appconfig=path/to/config.php ... ``` - Створення власних консольних команд ----------------------------------- diff --git a/docs/guide-uk/tutorial-start-from-scratch.md b/docs/guide-uk/tutorial-start-from-scratch.md index 1b1d0ff8ca9..7c921b78fd4 100644 --- a/docs/guide-uk/tutorial-start-from-scratch.md +++ b/docs/guide-uk/tutorial-start-from-scratch.md @@ -43,7 +43,7 @@ git clone git@github.com:yiisoft/yii2-app-basic.git ---------------- З визначенням шаблону, створіть Git репозиторій та завантажте туди свої файли. Якщо ви, збираєтесь використовувати свій шаблон, -як *open source*, то [Github](http://github.com) є кращим місцем для його розташування. +як *open source*, то [Github](https://github.com) є кращим місцем для його розташування. Якщо ви не бажаєте публічно розміщувати свій шаблон, то підійде будь-який сайт сервісу Git. Далі, вам необхідно зареєструвати свій Composer пакет. Для публічних шаблонів, ваш пакет необхідно зареєструвати diff --git a/docs/guide-uk/tutorial-template-engines.md b/docs/guide-uk/tutorial-template-engines.md index 4527c6d0590..e6af4b57656 100644 --- a/docs/guide-uk/tutorial-template-engines.md +++ b/docs/guide-uk/tutorial-template-engines.md @@ -2,7 +2,7 @@ =========================== За замовчуванням, Yii використовує PHP в якості мови шаблонів, але ви можете налаштувати Yii для підтримки інших шаблонізаторів, -таких як [Twig](http://twig.sensiolabs.org/) або [Smarty](http://www.smarty.net/), які доступні в якості розширеннь. +таких як [Twig](https://twig.symfony.com/) або [Smarty](https://www.smarty.net/), які доступні в якості розширеннь. Компонент `View` відповідає за рендиренг видів. Ви можете додати користувальницький шаблон, шляхом зміни конфігурації поведінки цього компонента: diff --git a/docs/guide-uk/tutorial-yii-integration.md b/docs/guide-uk/tutorial-yii-integration.md index ccd4edc4a76..d2dfff73a87 100644 --- a/docs/guide-uk/tutorial-yii-integration.md +++ b/docs/guide-uk/tutorial-yii-integration.md @@ -43,7 +43,7 @@ require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; як буде підключено файл `Yii.php`, щоб автозавантажувач Yii мав приорітет при автоматичному завантаженні класів. Якщо бібліотека не надає автозавантажувача класів, але іменування її класів відповідає -[PSR-4](http://www.php-fig.org/psr/psr-4/) - ви можете використовувати автозавантажувач Yii для завантаження її класів. +[PSR-4](https://www.php-fig.org/psr/psr-4/) - ви можете використовувати автозавантажувач Yii для завантаження її класів. Все, що вам потрібно зробити, це тільки оголосити [системний псевдонім](concept-aliases.md#defining-aliases) для кожного кореневого простору імен, що використовується в цих класах. Для прикаду, припустимо, що ви хочете встановити бібліотеку в каталог `vendor/foo/bar`, і класи бібліотеки знаходяться в кориневому просторі імен `xyz`. @@ -89,7 +89,7 @@ Yii::$classMap['Class2'] = 'path/to/Class2.php'; composer install ``` -Перша команда встановлює [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/), +Перша команда встановлює [composer asset plugin](https://github.com/fxpio/composer-asset-plugin), який дозволяє керувати залежностями пакунків Bower і NPM через Composer. Навіть якщо ви захочете використовувати тільки прошарки бази даних або інші, не повʼязані ресурсами, можливості Yii, вам все-одно необхідно встановити даний пакунок composer. @@ -111,7 +111,7 @@ Yii::$classMap['Class2'] = 'path/to/Class2.php'; Дивіться також загальний [розділ про встановлення Yii](start-installation.md#installing-via-composer), для отримання додаткової інформації про Composer та проблеми, які можуть виникнути під час встановлення. -В іншому випадку, ви можете [завантажити](http://www.yiiframework.com/download/) файли релізу Yii і розархівувати його +В іншому випадку, ви можете [завантажити](https://www.yiiframework.com/download/) файли релізу Yii і розархівувати його в каталог `BasePath/vendor`. Далі вам необхідно змінити вхідний скрипт сторонньої системи помістивши на його початок наступний код: diff --git a/docs/guide-uz/README.md b/docs/guide-uz/README.md index 16315917dff..97142c12d02 100644 --- a/docs/guide-uz/README.md +++ b/docs/guide-uz/README.md @@ -1,7 +1,7 @@ Yii 2.0 bo'yicha to'liq qo'llanma ================================= -Ushbu qo'llanma [Yii qo'llanmalarining holati](http://www.yiiframework.com/doc/terms/) bilan mos holda yo'lga qo'yildi. +Ushbu qo'llanma [Yii qo'llanmalarining holati](https://www.yiiframework.com/doc/terms/) bilan mos holda yo'lga qo'yildi. All Rights Reserved. @@ -201,4 +201,4 @@ Xelperlar * **TBD** [ArrayHelper](helper-array.md) * **TBD** [Html](helper-html.md) * **TBD** [Url](helper-url.md) -* **TBD** [Security](helper-security.md) \ No newline at end of file +* **TBD** [Security](helper-security.md) diff --git a/docs/guide-uz/blocktypes.json b/docs/guide-uz/blocktypes.json new file mode 100644 index 00000000000..e94cf5bb7fb --- /dev/null +++ b/docs/guide-uz/blocktypes.json @@ -0,0 +1,3 @@ +{ + "Info:": "Ma'lumot uchun:" +} diff --git a/docs/guide-uz/intro-upgrade-from-v1.md b/docs/guide-uz/intro-upgrade-from-v1.md index 791fc28fbb7..6a4911f4976 100644 --- a/docs/guide-uz/intro-upgrade-from-v1.md +++ b/docs/guide-uz/intro-upgrade-from-v1.md @@ -25,16 +25,16 @@ Yii 2.0 talqin Yii 1.1 talqinda qo'llanilgan PHP 5.2 ga nisbatan ancha yaxshilan Shu tufayli siz nazarda tutishingiz kerak bo'lgan tildagi ko'p o'zgarishlar mavjud. Quyida PHP ning asosiy o'zgarishlari keltirilgan: -- [Nomlar sohasi](https://secure.php.net/manual/ru/language.namespaces.php); -- [Anonim funksiyalar](https://secure.php.net/manual/ru/functions.anonymous.php); +- [Nomlar sohasi](https://www.php.net/manual/ru/language.namespaces.php); +- [Anonim funksiyalar](https://www.php.net/manual/ru/functions.anonymous.php); - Massivlar uchun qisqa sintaksisni qo'llash: `[...elementlar...]` ni `array(...элементы...)` o'rniga; - Qisqartirilgan teglarni qo'llash ` ------------------------------------------------------------------------- -Ishni boshlashdan oldin sizda [PDO](https://secure.php.net/manual/ru/book.pdo.php) kengaytmasi o'rnatilganiga amin bo'ling va PDO-boshqaruvchisi ma'lumotlar ombori bilan boshqara olishingiz uchun(misol uchun, `pdo_mysql` MYSql uchun). Bu siz aloqali ma'lumtolar ombori bilan ishlashingiz uchun assosiy talablardir. +Ishni boshlashdan oldin sizda [PDO](https://www.php.net/manual/ru/book.pdo.php) kengaytmasi o'rnatilganiga amin bo'ling va PDO-boshqaruvchisi ma'lumotlar ombori bilan boshqara olishingiz uchun(misol uchun, `pdo_mysql` MYSql uchun). Bu siz aloqali ma'lumtolar ombori bilan ishlashingiz uchun assosiy talablardir. Endi esa, hammasini o'rnatib bo'lganingizdan so'ng, `config/db.php` oching va sozlamalarni o`zingizni ma'lumotlar omboringiz sozlamalariga o'zgartiring. Boshlanish sozlamalar quydagichadir: ```php @@ -64,7 +64,7 @@ Fayl `config/db.php` — oddiy [sozlamalar](concept-configurations.md) vositasid Ma'lumotlar omboriga yuqoridagi sozlamalar sozlab bo'lgandan so'ng ulanish, undan foydalanish uchun `Yii::$app->db` orqali amalga oshiriladi. -> Ma'lumot uchun: fayl `config/db.php` ilovaning assosiy sozlama fayli orqali ulanadi `config/web.php`, +> Info: fayl `config/db.php` ilovaning assosiy sozlama fayli orqali ulanadi `config/web.php`, u esa [web-ilova](structure-applications.md) nusxasini sozlamalarini o'z ichiga oladi. qo'shimcha ma'lumot uchun, iltimos, ushbu [Sozlamalar](concept-configurations.md) bo'limga ko'rib chiqing. @@ -94,7 +94,7 @@ class Country extends ActiveRecord `Country` klassi [[yii\db\ActiveRecord]]ni kengaytirmoqda. Siz uning ichida bir satr kod ham yozmasligingiz mumkin! Yuqoridagi kod assosida Yii o'zi ma'lumotlar omboridagi jadval va klass orasida aloqa yasaydi. -> Ma'lumot uchun: Agar ma'lumotlar omboridagi nom va klassnomi orasida bir xillikni saqlash imkoni bo'lmasa siz klassga aynan jadal ismini [[yii\db\ActiveRecord::tableName()]] usuli orqali yozishingiz mumkin. +> Info: Agar ma'lumotlar omboridagi nom va klassnomi orasida bir xillikni saqlash imkoni bo'lmasa siz klassga aynan jadal ismini [[yii\db\ActiveRecord::tableName()]] usuli orqali yozishingiz mumkin. `Country` klassini ishlatganingizda, siz osonlikcha `country` jadvalidagi ma'lumotlar bilan boshqarishingiz mumkin, misol uchun pastdagi qatorlarda shuni ko'rishingiz mumkin: @@ -115,7 +115,7 @@ $country->name = 'U.S.A.'; $country->save(); ``` -> Ma'lumot uchun: Active Record — bu ma'lumotlar ombori bilan ishlash uchun juda ham mukammal vosita hisoblanadi. +> Info: Active Record — bu ma'lumotlar ombori bilan ishlash uchun juda ham mukammal vosita hisoblanadi. Yana ko'oproq ma'lumotni siz [Active Record](db-active-record.md) bo'limida topishingiz mumkin. Qo'shimcha tariqasida, siz yana boshqa yanada past qism vositasi [Data Access Objects](db-dao.md)dan foydalanishingiz mumkin. diff --git a/docs/guide-uz/start-forms.md b/docs/guide-uz/start-forms.md index 79e507891c5..df1752f305c 100644 --- a/docs/guide-uz/start-forms.md +++ b/docs/guide-uz/start-forms.md @@ -97,7 +97,7 @@ usuli ishlatilayapti. Agar hammasi yaxshi o'tsa, amal `entry-confirm` ko'rinishini qaytaradi, u esa foydalanuvchi tomonidan kiritilgan ma'lumotlarini ko'rsatadi. Aks holda esa `entry` ko'rinishi qaytariladi, u esa HTML-shaklni va xatolarni chiqarib beradi, agar ular bor bo'lsa. -> Ma'lumot uchun: `Yii::$app` yagona global xossasi Yiining nusxasini o'z ichiga oladi +> Info: `Yii::$app` yagona global xossasi Yiining nusxasini o'z ichiga oladi [ilova](structure-applications.md) (singleton). Bir vaqtni o'zida u [Service Locator](concept-service-locator.md) ham hisoblanadi, undan esa quydagi komponentlar bilan foydalanish mumkin `request`, `response`, `db` va boshqa. Yuqorida ko'rsatilgan kodda `$_POST` massivini qabul qilish uchun biz `request` komponentini ishlatdik. @@ -186,7 +186,7 @@ Moydonlar uchun yasalgan yorlig'lar xossalar nomlari assosida quydagi usul `fiel field($model, 'email')->label('Sizning elektron qutingiz') ?> ``` -> Ma'lumot uchun: Yiida juda ham ko'p vidjetlar bor, ular sizga tez va murakkab ko'rinishlarni yasashga yordam beradi. +> Info: Yiida juda ham ko'p vidjetlar bor, ular sizga tez va murakkab ko'rinishlarni yasashga yordam beradi. Vijetlarni yasash judda oson va sodda ekanligini keyin (oldinda) bilishingiz mumkin. Ko'rinishdagi narsalarni ko'p narsani vijetlarga chiqarsa bo'ladi, nimaga? keyinchalik ham boshqa joylarda ishlatish uchun, bu esa ishni soddalashtiradi. diff --git a/docs/guide-uz/start-hello.md b/docs/guide-uz/start-hello.md index 76f40a40d6b..6b55482a2ce 100644 --- a/docs/guide-uz/start-hello.md +++ b/docs/guide-uz/start-hello.md @@ -20,7 +20,7 @@ Amal yaratish Bizning vazifamiz uchun so'rovdan `message` parametrini o'qiydigan va uning qiymatini foydalanuvchiga ko'rsatadigan `say` deb ataladigan [amal](structure-controllers.md) kerak. Agar so'rovda `message` parametri bo'lmasa, [amal](structure-controllers.md) o'z novbatida "Salom" matnini qaytaradi. -> Malumot uchun: [amal](structure-controllers.md) to'g'ridan-to'g'ri foydalanuvchi tomonidan boshqarilishi va [nazoratchilar](structure-controllers.md) ichida guruhlarga bo'linishi mumkin. Amal natijasi foydalanuvchiga qaytariladi. +> Info: [amal](structure-controllers.md) to'g'ridan-to'g'ri foydalanuvchi tomonidan boshqarilishi va [nazoratchilar](structure-controllers.md) ichida guruhlarga bo'linishi mumkin. Amal natijasi foydalanuvchiga qaytariladi. Amallar [nazoratchilar](structure-controllers.md) (tomonidan) ichida e'lon qilinadi. Oddiylik uchun siz mavjud bo'lgan SiteController nazoratchisi ichida `say` amalini yaratishingiz mumkin, Ushbu nazoratchi fayli `controllers/SiteControllers.php` yo'li bo`yicha joylashgan @@ -45,7 +45,7 @@ class SiteController extends Controller Quyidagi kodda `say` amali `SiteController` sinfi (klassi) `actionSay` usuli (metodi) e'lon qilinmoqda. Yii amallari usullari (metodlari) oldidan `action` qo'shiladi bu oddiy usullarni (metodlarni) ajratish uchun prefiksidan foydalanadi. -> Malumot uchun: Amalar nomlari kichik harflar berilishi kerak.Agar identifikator (nom) bir necha so'zdan iborat bo'lsa, ular +> Info: Amalar nomlari kichik harflar berilishi kerak.Agar identifikator (nom) bir necha so'zdan iborat bo'lsa, ular chiziq (minus -) bilan ajiraladi, yani `create-comment`. Amallar usullarining (metodlar) nomlari defislarni olib tashlash yo'li bilan olinib, har bir so'zni katta harfga aylantiradi va `action` prefiksi qo'shadi. Misol uchun, amal nomi `create-comment` quydagi usullga to'g'ri keladi `actionCreateComment`. @@ -72,7 +72,7 @@ use yii\helpers\Html; , u quydagi yo'l bo'yicha ko'rinish topishga harakat qiladi `views/ControllerID/ViewName.php`. Aytib o'tish keraki yuqorida kodda `message` [[yii\helpers\Html::encode()|HTML himoyasi]] orqali filtrlanadi. -Buni ishlatish shartdir chunki ma'lumot foydalanuvchidan kirib kelmoqda, u esa o'z yo'lida [XSS ziyon](http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D1%8B%D0%B9_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3) +Buni ishlatish shartdir chunki ma'lumot foydalanuvchidan kirib kelmoqda, u esa o'z yo'lida [XSS ziyon](https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D1%8B%D0%B9_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3) o'tkazishi o'tkazishi mumkin Javascript-skripti orqali. Siz `say` ko'rinishi HTML teglar, matn yoki PHP-kod bilan to'ldirishingiz mumkin. Aslini olganda `say` skripti [[yii\web\Controller::render()|render()]] orqali chaqirilayotgan sodda PHP-skript bo'lib chiqayotganini ko'rishimiz mumkin. Skript tomonidan shakilangan ma'lumot esa foydalanuvchiga qaytariladi. @@ -92,14 +92,14 @@ http://hostname/index.php?r=site%2Fsay&message=Salom+dunyo Sizga "Salom, dunyo" matni chiqishi kerak. Header (yuqori bo'lim) va Footer (pastki bo'lim) hamma sahifalardek chiqadi. Agar siz `message` kiritmasangiz, siz «Salom» matnini ko'rishingiz mumkin. Bunaqa mantiq chiqishi sababi shundagi, `actionSay` usuli (metod)dagi `message` parametri oldindan "Salom" matni berilgan. -> Ma'lumot uchun: Yangi sahifa hamma ishlatayotgan Header (yuqori bo'limi) va Footer (pastki bo'lim) ishlatadi, chunki +> Info: Yangi sahifa hamma ishlatayotgan Header (yuqori bo'limi) va Footer (pastki bo'lim) ishlatadi, chunki [[yii\web\Controller::render()|render()]] usuli `say` ko'rinishini o'zi [maketga](structure-views.md) `views/layouts/main.php` topib qo'yadi. Parametr `r` qo'shimcha tushuncha ta'lab qiladi. U [yo'nalishlar (route)](runtime-routing.md) bilan bo'liqdir va nomi boyicha kerakli amalni topib chiqaradi. Uning formati `ControllerID/ActionID`. Web-ilova so'rovni qabul qilishni boshlaganida u `r` paraterni tekshirishni boshlaydi va `ControllerID` ni ishlatadi, va nomi bo'yicha so'ralayotgan nazoratchini topib, `ActionID` bo'yicha shu topilgan nazoratchi ichidan so'raloyotgan amalni topib chiqaradi. Bizning misolimiz bo'yicha `site/say` so'rovi boyicha `SiteController` nazoratchisi ichidan `say` amalini chiqaradi. Natijada esa, so'rovni qabul qilish `SiteController::actionSay()` topshiriladi. -> Ma'lumot uchun: Nazoratchilar ham hudi amalar kabi web-ilovada yagona nomga (identifikator) ega. +> Info: Nazoratchilar ham hudi amalar kabi web-ilovada yagona nomga (identifikator) ega. Nazoratchilar nomlash tartibi hudi amalardaqadir. Klasslar nomlari So'larga bo'linib defizlar orqali aniqlanadi, so'zlarni birinchi katta harf bilan yozib o'tib va oxiriga `Controller` qo'shib qidirishni boshlaydi. Misol uchun, nazoratchi `post-comment` nomi `PostCommentController` klassiga teng bo`ladi. diff --git a/docs/guide-uz/start-installation.md b/docs/guide-uz/start-installation.md index b3c33f5df24..77248878ff9 100644 --- a/docs/guide-uz/start-installation.md +++ b/docs/guide-uz/start-installation.md @@ -39,7 +39,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic Ushbu buyruq Yining oxirgi ishlaydigan versiyasini `basic` katalogiga o'rnatadi. Agar xohlasangiz, boshqa katalog nomini tanlashingiz mumkin. -> Ma'lumot uchun: Agar `composer create-project` buyrug'i yaxshi ishlamasa , Composer hujjatining ["Muammo bartaraf qilish"](https://getcomposer.org/doc/articles/troubleshooting.md) bo'limiga murojaat qiling . Yozib otilgan boshqa odatiy xatolar mavjud. Xatolikni bartaraf qilganingizdan so'ng, `basic` katalogda `composer update` ishga tushiring. +> Info: Agar `composer create-project` buyrug'i yaxshi ishlamasa , Composer hujjatining ["Muammo bartaraf qilish"](https://getcomposer.org/doc/articles/troubleshooting.md) bo'limiga murojaat qiling . Yozib otilgan boshqa odatiy xatolar mavjud. Xatolikni bartaraf qilganingizdan so'ng, `basic` katalogda `composer update` ishga tushiring. > Maslahat: Agar siz Yii ning eng so`ngi tekshirilmagan taxririni o'rnatmoqchi bo'lsangiz, [stability](https://getcomposer.org/doc/04-schema.md#minimum-stability) sozlamasini ozgartirib quydagi quyidagi buyruqni ishlatishingiz mumkin:: > @@ -55,7 +55,7 @@ Arxivdan o'rnatish Yining arxivdan o'rnatilishi uch bosqichdan iborat: -1. Yiiframework.com dan [arxivni](http://www.yiiframework.com/download/) yuklab oling. +1. Yiiframework.com dan [arxivni](https://www.yiiframework.com/download/) yuklab oling. 2. Yuklangan arxivni Internetdan kirib boladigan katalogiga tashlab, arxivni oching. 3. `config/web.php` `cookieValidationKey` (Composer orqali o'rnatilganda, bu avtomatik tarzda amalga oshiriladi) uchun maxsus kalitni qo'shing: @@ -97,22 +97,22 @@ cd basic php requirements.php ``` -Freymvork to'g'ri ishlashi uchun PHPni minimal talablarga javob beradigan tarzda sozlashingiz kerak. Asosiy talablardan biri bu PHP versiyasi 5.4 va undan yuqori bolishi kerak. Agar veb-ilovangiz ma'lumotlar bazasi bilan ishlayotgan bo'lsa , [PHP PDO kengaytmasini](https://secure.php.net/manual/ru/pdo.installation.php) va tegishli drayverni (masalan, MySQL uchun pdo_mysql ) o'rnatishingiz kerak. +Freymvork to'g'ri ishlashi uchun PHPni minimal talablarga javob beradigan tarzda sozlashingiz kerak. Asosiy talablardan biri bu PHP versiyasi 5.4 va undan yuqori bolishi kerak. Agar veb-ilovangiz ma'lumotlar bazasi bilan ishlayotgan bo'lsa , [PHP PDO kengaytmasini](https://www.php.net/manual/ru/pdo.installation.php) va tegishli drayverni (masalan, MySQL uchun pdo_mysql ) o'rnatishingiz kerak. Web-server sozlamasi ----------------------- -> Ma'lumot uchun:Agar siz faqatgina freymvork bilan tanishishni boshlagan bo'lsangiz va uni ish serveriga joylashtirmagan bo'lsangiz, ushbu bo'limni o'tkazib yuborishingiz mumkin. +> Info: Agar siz faqatgina freymvork bilan tanishishni boshlagan bo'lsangiz va uni ish serveriga joylashtirmagan bo'lsangiz, ushbu bo'limni o'tkazib yuborishingiz mumkin. -Yuqoridagi ko'rsatmalarga muvofiq o'rnatilgan ilovalar Windows va Linux ostida PHP 5.4 va undan yuqori taxrirlarda o'rnatilgan [Apache](http://httpd.apache.org/) va [Nginx](http://nginx.org/) bilan ishlaydi.Yii 2.0 [HHVM](http://hhvm.com/) bilan ham mos keladi. Etiborli bo'ling, ba'zi hollarda, HHVM bilan ishlashda odatdagi PHPdan farq qiladi. +Yuqoridagi ko'rsatmalarga muvofiq o'rnatilgan ilovalar Windows va Linux ostida PHP 5.4 va undan yuqori taxrirlarda o'rnatilgan [Apache](https://httpd.apache.org/) va [Nginx](https://nginx.org/) bilan ishlaydi.Yii 2.0 [HHVM](https://hhvm.com/) bilan ham mos keladi. Etiborli bo'ling, ba'zi hollarda, HHVM bilan ishlashda odatdagi PHPdan farq qiladi. Ish serverida siz `http://www.example.com/basic/web/index.php` dan `http://www.example.com/index.php` manziliga dastur URL manzilini o'zgartirishni xohlasangiz. Buni amalga oshirish uchun veb-server parametrlarida ildiz katalogini `basic/web` ga o'zgartiring. Bundan tashqari, ["URL sozlamalari"](runtime-routing.md) qismidagi malumotga ko'ra, `index.php` yashirishi mumkin. Keyinchalik Apache va Nginx ni qanday sozlashni ko'rsatamiz. -> Ma'lumot uchun: Veb-serverning `basic/web` ildiz katalogini o'rnatib, siz ruxsat berilmagan kirish kodidan va `basic/web` sahifadagi ma'lumotlardan himoya qilasiz. Bu ilovani yanada xavfsiz holga keltiradi. +> Info: Veb-serverning `basic/web` ildiz katalogini o'rnatib, siz ruxsat berilmagan kirish kodidan va `basic/web` sahifadagi ma'lumotlardan himoya qilasiz. Bu ilovani yanada xavfsiz holga keltiradi. -> Ma'lumot uchun: Agar dastur veb-server sozlamalariga kirish imkoni bo'lmagan hosting bilan ishlayotgan bo'lsa, siz ["Birgalikda Hosting ustida ishlash"](tutorial-shared-hosting.md) bo'limida ko'rsatilganidek, ilovaning tuzilishini o'zgartirishingiz mumkin. +> Info: Agar dastur veb-server sozlamalariga kirish imkoni bo'lmagan hosting bilan ishlayotgan bo'lsa, siz ["Birgalikda Hosting ustida ishlash"](tutorial-shared-hosting.md) bo'limida ko'rsatilganidek, ilovaning tuzilishini o'zgartirishingiz mumkin. ### Ta'vsiya etilgan Apache sozlamalari @@ -139,7 +139,7 @@ DocumentRoot "path/to/basic/web" ### Tavsiya etilgan Nginx sozlamalari -PHP Nginx uchun [FPM SAPI](https://secure.php.net/manual/ru/install.fpm.php) sifatida o'rnatilishi kerak. Quyidagi [Nginx](http://wiki.nginx.org/) sozlamalaridan foydalaning va `basic/web` va `mysite.test` to'g'ri manzilini hostname-ga almashtirishni va `path/to/basic/web` ni almashtirishni unutmang. +PHP Nginx uchun [FPM SAPI](https://www.php.net/manual/ru/install.fpm.php) sifatida o'rnatilishi kerak. Quyidagi [Nginx](https://wiki.nginx.org/) sozlamalaridan foydalaning va `basic/web` va `mysite.test` to'g'ri manzilini hostname-ga almashtirishni va `path/to/basic/web` ni almashtirishni unutmang. ``` server { diff --git a/docs/guide-uz/start-looking-ahead.md b/docs/guide-uz/start-looking-ahead.md index 1512d9f7568..72bca6a9e7f 100644 --- a/docs/guide-uz/start-looking-ahead.md +++ b/docs/guide-uz/start-looking-ahead.md @@ -18,11 +18,11 @@ avtomatik tarzda kod yaratishni o'rgandingiz, bu esa HTML-shaklni to'ldirishdek Shuni aytish keraki ularning sifati qo'lanmadagi yozilgan ma'lumotdaqa yaxshi yoritilib berilgani ham bor Ularni shunisi yaxshiki ular mavzuni to'liq va amaliy yoritib berib sizga tayyor yechim berishi ham mumkin - Kitoblar -* [Kengaytmalar](http://www.yiiframework.com/extensions/): +* [Kengaytmalar](https://www.yiiframework.com/extensions/): Yiining foydalanuvchilar tomonidan yaratilgan minglab kengaytmalar ombori bor ular ilovangizga ulashingiz va ishlanmani juda ham tez oborishingizga yordam beradi * Jamoa - - [Forum](http://www.yiiframework.com/forum/) + - [Forum](https://forum.yiiframework.com/) - [Chat Gitter](https://gitter.im/yiisoft/yii2/rus) - [GitHub](https://github.com/yiisoft/yii2) - [Facebook](https://www.facebook.com/groups/yiitalk/) diff --git a/docs/guide-uz/start-workflow.md b/docs/guide-uz/start-workflow.md index d66ab54de40..0474373e750 100644 --- a/docs/guide-uz/start-workflow.md +++ b/docs/guide-uz/start-workflow.md @@ -3,7 +3,7 @@ Ilovani ishga tushirish `http://hostname/basic/web/index.php` o'rnatganingizdan so'ng, asosiy dastur `http://hostname/basic/web/index.php` URL manzilida yoki `http://hostname/index.php` orqali Veb-server sozlamalariga qarab mavjud bo'ladi. Ushbu bo'lim - kodni tashkil qilishning umumiy ta'rifi, o'rnatilgan funksionallik va murojaatlar bilan ishlash. -> Ma'lumot uchun: Ushbu qo'llanmada Yii `basic/web` katalogiga o'rnatilganini inobatga oladi va u o'z navbatida veb-server sozlamalaridagi ildiz katalogi sifatida o'rnatiladi. Natijada `http://hostname/index.php` URL manziliga kirish orqali `basic/web` joylashgan ilovaga kirishingiz mumkin. Boshlang'ich konfiguratsiya jarayonida batafsil ma'lumotni [Yii-ni o'rnatish bo'limida](start-installation.md) topishingiz mumkin. +> Info: Ushbu qo'llanmada Yii `basic/web` katalogiga o'rnatilganini inobatga oladi va u o'z navbatida veb-server sozlamalaridagi ildiz katalogi sifatida o'rnatiladi. Natijada `http://hostname/index.php` URL manziliga kirish orqali `basic/web` joylashgan ilovaga kirishingiz mumkin. Boshlang'ich konfiguratsiya jarayonida batafsil ma'lumotni [Yii-ni o'rnatish bo'limida](start-installation.md) topishingiz mumkin. Freymvorkdan farqli o'laroq, dastur o'rnatilgandan so'ng, u sizniki bolib qoladi. Siz o`zingizni kodingizni o'zingiz xohlagan tarzda o'zgartirishingiz mumkin. @@ -28,7 +28,7 @@ Yii web-ilovasi tuzilmasi Quyidagida veb-ilovaning tuzilmasi asosiy kataloglari va fayllari ro'yxati berilgan (ilovaning `basic` katalogga o'rnatilgan deb hisoblaymiz): -``` +```js basic/ ilovaning ildiz katalogi composer.json Composer ishlatadigan fayl config/ Sozlamalar (konfiguratsion) fayl @@ -48,7 +48,7 @@ basic/ ilovaning ildiz katalogi Umuman olganda, Yii ilovasini ikki `basic/web` faylga bo'lish mumkin: `basic/web` joylashgan faylar va boshqa kataloglarda joylashgan faylar. Birinchisi `(basic/web)` internet orqali kirganda ochilishi kerak, ikkinchisi internet orqali ko'rinishi kerak bo'lmagan faylar, chunki ular ish faylari. -Yii-da [MVC-arxetekturasi](http://ru.wikipedia.org/wiki/Model-View-Controller) asosida faylar va kataloglar joylashgan. [models](structure-models.md)katalogida Modellar mavjud , [Ko'rishlar](structure-views.md) ko'rinishlarda joylashgan va barcha dastur [Nazoratchilar](structure-controllers.md) katalogida. +Yii-da [MVC-arxetekturasi](https://ru.wikipedia.org/wiki/Model-View-Controller) asosida faylar va kataloglar joylashgan. [models](structure-models.md)katalogida Modellar mavjud , [Ko'rishlar](structure-views.md) ko'rinishlarda joylashgan va barcha dastur [Nazoratchilar](structure-controllers.md) katalogida. Quyidagi diagrammada dasturning ichki tuzilmasi ko'rsatilgan. diff --git a/docs/guide-vi/README.md b/docs/guide-vi/README.md index 0524c90cdec..a38ba36f7c3 100644 --- a/docs/guide-vi/README.md +++ b/docs/guide-vi/README.md @@ -1,7 +1,7 @@ The Definitive Guide to Yii 2.0 =============================== -Các hướng dẫn được phát hành theo [Các điều khoản về tài liệu Yii](http://www.yiiframework.com/doc/terms/). +Các hướng dẫn được phát hành theo [Các điều khoản về tài liệu Yii](https://www.yiiframework.com/doc/terms/). Tất cả bản quyền đã được bảo hộ (All Rights Reserved). diff --git a/docs/guide-vi/blocktypes.json b/docs/guide-vi/blocktypes.json new file mode 100644 index 00000000000..0808dfeb71b --- /dev/null +++ b/docs/guide-vi/blocktypes.json @@ -0,0 +1,3 @@ +{ + "Info:": "Lưu ý:" +} diff --git a/docs/guide-vi/intro-upgrade-from-v1.md b/docs/guide-vi/intro-upgrade-from-v1.md index ba1625904ab..2dad26ab734 100644 --- a/docs/guide-vi/intro-upgrade-from-v1.md +++ b/docs/guide-vi/intro-upgrade-from-v1.md @@ -28,15 +28,15 @@ Yii 2.0 yêu cầu PHP 5.4 trở lên, đó là một cải tiến rất lớn s Như được liệt kê dưới, có nhiều sự khác biệt về cấp độ ngôn ngữ mà bạn nên chú ý. Dưới đây là tóm tắt về những thay đổi lớn liên quan đến PHP: -- [Namespaces](http://php.net/manual/en/language.namespaces.php). -- [Hàm ẩn danh (Anonymous functions)](http://php.net/manual/en/functions.anonymous.php). +- [Namespaces](https://php.net/manual/en/language.namespaces.php). +- [Hàm ẩn danh (Anonymous functions)](https://php.net/manual/en/functions.anonymous.php). - Cú pháp khai báo mảng ngắn `[...elements...]` được dùng thay cho cú pháp kiểu `array(...elements...)`. - Thẻ echo ngắn ` --------------------------- -Trước tiên, hãy chắc chắn rằng bạn đã cài 2 gói PHP [PDO](https://secure.php.net/manual/en/book.pdo.php) và +Trước tiên, hãy chắc chắn rằng bạn đã cài 2 gói PHP [PDO](https://www.php.net/manual/en/book.pdo.php) và PDO driver dành cho các CSDL mà đang sử dụng(ví dụ `pdo_mysql` cho MySQL). Đối với các CSDL quan hệ thì những gói này cần phải có. diff --git a/docs/guide-vi/start-forms.md b/docs/guide-vi/start-forms.md index 00046d98e05..7fdf1d93e16 100644 --- a/docs/guide-vi/start-forms.md +++ b/docs/guide-vi/start-forms.md @@ -127,7 +127,7 @@ Nếu không có lỗi gì, action sẽ trả về (render) view tên là `entry > Lưu ý: ở bài hướng dẫn này, chúng ta chỉ xác nhận trang khi có dũ liệu hợp lệ. Bài thực hành này, bạn cần lưu ý việc sử dụng các phương thức [[yii\web\Controller::refresh()|refresh()]] hoặc [[yii\web\Controller::redirect()|redirect()]] - nhằm để tránh [form resubmission problems](http://en.wikipedia.org/wiki/Post/Redirect/Get). + nhằm để tránh [form resubmission problems](https://en.wikipedia.org/wiki/Post/Redirect/Get). Tạo Views diff --git a/docs/guide-vi/start-hello.md b/docs/guide-vi/start-hello.md index eb44e55cf44..408dd3d1401 100644 --- a/docs/guide-vi/start-hello.md +++ b/docs/guide-vi/start-hello.md @@ -22,7 +22,7 @@ Với nhiệm vụ tạo ra thông điệp "Hello", bạn sẽ tạo một [act sẽ lấy các tham số `message` từ request và hiển thị thông điệp trở lại user. Nếu request không cung cấp tham số `message`, action sẽ mặc định hiển thị thông điệp "Hello". -> Lưu ý: [Hành động (Actions)](structure-controllers.md#creating-actions) là người dùng cuối có thể truy cập các đối tượng và thực hiện trực tiếp. +> Info: [Hành động (Actions)](structure-controllers.md#creating-actions) là người dùng cuối có thể truy cập các đối tượng và thực hiện trực tiếp. Các Actions được nằm trong [bộ điều khiển (controllers)](structure-controllers.md). Các kết quả của một action là người sử dụng cuối cùng nhận được các thông điệp. @@ -86,7 +86,7 @@ Bạn cần lưu trữ view `say` nằm ở đường dẫn `views/site/say.php` Lưu ý rằng, đoạn code trên, biến `message` đã được phương thức [[yii\helpers\Html::encode()|HTML-encoded]] mã hóa trước khi được in ra. Việc mã hóa là cần thiết khi gửi các tham số tới user, các tham số này có thể bị tấn công qua -[XSS (cross-site scripting)](http://en.wikipedia.org/wiki/Cross-site_scripting) đây là kỹ thuật tấn công bằng cách chèn chèn các +[XSS (cross-site scripting)](https://en.wikipedia.org/wiki/Cross-site_scripting) đây là kỹ thuật tấn công bằng cách chèn chèn các thẻ HTML hoặc đoạn mã JavaScript độc hại. Tất nhiên, bạn có thể thêm các nội dung ở view `say`.Nội dung bao gồm các thẻ HTML, dữ liệu văn bản, và cũng có thể là các câu lệnh PHP. @@ -111,7 +111,7 @@ URL này sẽ trả về một trang và hiển thị lời chào "Hello World". Nếu bạn không nhập tham số `message` vào URL, bạn chỉ xem thấy mỗi dòng "Hello" được hiển thị. Bởi vì tham số `message` được thông qua phương thức `actionSay()`, và mỗi khi tham số này không được nhập, thì giá trị mặc đinh `"Hello"` sẽ được thay thế. -> Lưu ý: Trang này có cùng phần header và footer như những trang khác là bởi vì phương thức [[yii\web\Controller::render()|render()]] +> Info: Trang này có cùng phần header và footer như những trang khác là bởi vì phương thức [[yii\web\Controller::render()|render()]] sẽ tự động nhúng nội dung của view `say` vào một [layout](structure-views.md#layouts) layout này nằm ở `views/layouts/main.php`. Tham số `r` ở trên URL sẽ được giải thích thêm. Nó là chuẩn cho bộ định tuyến [route](runtime-routing.md), mỗi ứng dụng sẽ cung cấp ID @@ -120,7 +120,7 @@ theo cùng request đó, sử dụng `ControllerID` để xác định lớp đi xác dịnh `ActionID` cần được khởi tạo để xử lý công việc. Trong ví dụ này, route `site/say` sẽ gán (ám chỉ tới) bộ điều khiển `SiteController` và action `say`. Điều này sẽ có kết quả là, phương thức `SiteController::actionSay()` sẽ được gọi để xử lý các request. -> Lưu ý: Giống như actions, ứng dụng sử dụng các định danh ID để nhận diện các controller. Các Controller ID +> Info: Giống như actions, ứng dụng sử dụng các định danh ID để nhận diện các controller. Các Controller ID có quy tắc đặt tên giống với các action IDs. Tên của controller được chuyển đổi từ các controller IDs bằng việc loại bỏ dấu gạch ngang từ đinh danh ID, tận dụng các chữ cái đầu tiên trong mỗi từ, và từ đứng trước `Controller`. Ví dụ, bộ điều khiển controller ID có tên là `post-comment` sẽ tương ứng diff --git a/docs/guide-vi/start-installation.md b/docs/guide-vi/start-installation.md index 60ced474549..c59ccf91e6f 100644 --- a/docs/guide-vi/start-installation.md +++ b/docs/guide-vi/start-installation.md @@ -1,7 +1,7 @@ Cài đặt Yii ============== -Bạn có thể cài đặt Yii theo hai cách, dùng trình quản lý gói [Composer](http://getcomposer.org/) hoặc tải toàn bộ mã nguồn Yii về. +Bạn có thể cài đặt Yii theo hai cách, dùng trình quản lý gói [Composer](https://getcomposer.org/) hoặc tải toàn bộ mã nguồn Yii về. Cách thứ nhất thường được khuyến khích dùng hơn, vì nó cho phép bạn cài đặt thêm các [Gói mở rộng (extensions)](structure-extensions.md) hoặc cập nhật Yii đơn giản chỉ mới một dòng lệnh. Mặc định, sau khi cài đặt Yii sẽ cung cấp cho bạn một số tính năng cơ bản, như đăng nhập (login), form liên hệ (contact form), vv. @@ -38,7 +38,7 @@ Sau khi cài đặt Composer, bạn có thể cài đặt Yii bằng cách chạ composer global require "fxp/composer-asset-plugin:^1.4.1" composer create-project --prefer-dist yiisoft/yii2-app-basic basic -Câu lệnh đầu tiên sẽ cài đặt [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) +Câu lệnh đầu tiên sẽ cài đặt [composer asset plugin](https://github.com/fxpio/composer-asset-plugin) và cho phép Composer có thể quản lý những package dependencies của bower và npm. Câu lệnh này chỉ cần chạy một lần. Câu lệnh thứ hai sẽ cài đặt phiên bản Yii có tên là `basic`. Bạn có thể chọn một tên thư mục khác nếu bạn muốn. @@ -59,7 +59,7 @@ Cài đặt từ tập tin lưu trữ > Lưu ý: Lưu ý: Nếu bạn chỉ là chạy thử ứng dụng Yii thay vì được triển khai(deploying) trong một môi trường sản xuất, bạn có thể bỏ qua phần này. -Các ứng dụng được cài đặt theo phương pháp trên, được chạy trong Windows, Max OS X, Linux hoặc máy chủ [Apache HTTP](http://httpd.apache.org/) -hoặc [Nginx HTTP server](http://nginx.org/) và PHP phiên bản 5.4 hoặc cao hơn đều có thể được chạy trực tiếp. Yii 2.0 cũng tương thích với HHVM, -do [HHVM](http://hhvm.com/)của Facebook và PHP tiêu chuẩn trên các khía cạnh trong một vài nơi một với trường hợp hơi khác nhau, +Các ứng dụng được cài đặt theo phương pháp trên, được chạy trong Windows, Max OS X, Linux hoặc máy chủ [Apache HTTP](https://httpd.apache.org/) +hoặc [Nginx HTTP server](https://nginx.org/) và PHP phiên bản 5.4 hoặc cao hơn đều có thể được chạy trực tiếp. Yii 2.0 cũng tương thích với HHVM, +do [HHVM](https://hhvm.com/)của Facebook và PHP tiêu chuẩn trên các khía cạnh trong một vài nơi một với trường hợp hơi khác nhau, khi sử dụng HHVM đòi hỏi ít thay đổi. Trong môi trường máy chủ sản xuất, bạn có thể cấu hình máy chủ để ứng dụng có thể truy cập thông qua URL http://www.example.com/index.php @@ -161,7 +161,7 @@ DocumentRoot "path/to/basic/web" ### Các khuyến nghị khi cấu hình Nginx -Để sử dụng [Nginx](http://wiki.nginx.org/), bạn cần phải cài đặt [FPM SAPI](https://secure.php.net/install.fpm). +Để sử dụng [Nginx](https://wiki.nginx.org/), bạn cần phải cài đặt [FPM SAPI](https://www.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` và `mysite.test` thay thế bằng tên máy chủ thực tế để cung cấp dịch vụ. diff --git a/docs/guide-vi/start-looking-ahead.md b/docs/guide-vi/start-looking-ahead.md index 1c0a86c8f52..1a170e5a776 100644 --- a/docs/guide-vi/start-looking-ahead.md +++ b/docs/guide-vi/start-looking-ahead.md @@ -9,24 +9,24 @@ các chức năng tương tự. Trong phần này sẽ tổng hợp những tài nguyên về tìm hiểu Yii framework. * Tài liệu tham khảo - - [Giới thiệu tổng quan](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [Giới thiệu tổng quan](https://www.yiiframework.com/doc-2.0/guide-README.html): Như tiêu đề, các hướng dẫn sẽ cung cấp tổng quan về sử dụng Yii và cách thức Yii hoạt động . Đây là các hướng dẫn quan trọng để bắt đầu với Yii, vì vậy bạn cần tìm hiểu trước khi đi sâu và viết code về Yii. - - [Thông tin chi tiết Class](http://www.yiiframework.com/doc-2.0/index.html): + - [Thông tin chi tiết Class](https://www.yiiframework.com/doc-2.0/index.html): Phần này sẽ mô tả và cách dùng các class được cung cấp bởi Yii. Phần này là quan trọng khi bạn viết code và muốn hiểu về cách dùng từng phần trong lớp, phương thức, các thuộc tính. Tham khảo cách dùng các lớp sẽ giúp bạn hiểu sâu về từng phần trong framework. - - [Các bài hướng dẫn khác](http://www.yiiframework.com/wiki/?tag=yii2): + - [Các bài hướng dẫn khác](https://www.yiiframework.com/wiki/?tag=yii2): Các bài hướng dẫn được viết bởi những người có kinh nghiệm về lập trình Yii. Hầu hết trong số đó, được viết theo những kinh nghiệm lập trình lâu năm. , và đưa ra các giải pháp về từng phần, vấn đề khi lập trình Yii. Các bài viết có thể không chi tiết và dễ hiểu như phần giới thiệu, tuy nhiên các bài viết có những chủ đề rộng hơn và thường có những ví dụ và giải pháp với các vấn đề lập trình. - - [Sách](http://www.yiiframework.com/doc/) -* [Extensions](http://www.yiiframework.com/extensions/): + - [Sách](https://www.yiiframework.com/books) +* [Extensions](https://www.yiiframework.com/extensions/): Yii tự hào có một thư viện của hàng ngàn các phần mở rộng với sự đóng góp lớn của cộng động, bạn có thể dễ dàng tích hợp vào các ứng dụng của bạn, do đó làm cho phát triển ứng dụng của bạn nhanh hơn và dễ dàng hơn. * Cộng dồng - - Diễn đàn: - - IRC chat: The #yii channel on the freenode network () + - Diễn đàn: + - IRC chat: The #yii channel on the Libera () - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide-vi/start-prerequisites.md b/docs/guide-vi/start-prerequisites.md new file mode 100644 index 00000000000..642c53e0508 --- /dev/null +++ b/docs/guide-vi/start-prerequisites.md @@ -0,0 +1,19 @@ +# Những gì bạn cần biết + +Quá trình học Yii không quá khó cũng như các framework PHP khác nhưng vẫn có một số điều bạn nên học trước khi bắt đầu với Yii. + +## PHP + +Yii là một framework PHP nên hãy đảm bảo bạn đã [đọc và hiểu ngôn ngữ của nó](https://www.php.net/manual/en/langref.php). +Khi phát triển với Yii, bạn sẽ viết code theo hướng đối tượng, vì vậy hãy đảm bảo rằng bạn đã quen với [Classes và Objects](https://www.php.net/manual/en/language.oop5.basic.php) cũng như [namespaces](https://www.php.net/manual/en/language.namespaces.php). + +## Lập trình hướng đối tượng + +Hiểu cơ bản về lập trình hướng đối tượng là bắt buộc. Nếu bạn không biết, hãy học theo những hướng dẫn trên google, youtube, chẳng hạn như [the one from tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762). + +Lưu ý rằng ứng dụng của bạn càng phức tạp thì các khái niệm OOP nâng cao hơn mà bạn nên học để thành công quản lý sự phức tạp đó. + +## Command line và composer + +Yii sử dụng rộng rãi trình quản lý gói PHP tiêu chuẩn de-facto, [Composer](https://getcomposer.org/) vì vậy hãy chắc chắn rằng bạn đọc +và hiểu [hướng dẫn](https://getcomposer.org/doc/01-basic-usage.md) của nó. Nếu bạn không quen với việc sử dụng command line thì đã đến lúc bắt đầu thử. Khi bạn học những cái cơ bản mà bạn sẽ không bao giờ muốn làm việc nếu thiếu nó. diff --git a/docs/guide-vi/start-workflow.md b/docs/guide-vi/start-workflow.md index 7768b06d71c..f9c3afc6955 100644 --- a/docs/guide-vi/start-workflow.md +++ b/docs/guide-vi/start-workflow.md @@ -37,7 +37,7 @@ Cấu trúc ứng dụng (Application Structure) + ``` Giống như phương thức [[yii\web\View::registerMetaTag()|registerMetaTag()]], bạn có thể chỉ định từ khóa khi gọi phương thức diff --git a/docs/guide-zh-CN/README.md b/docs/guide-zh-CN/README.md index ddb2baa1737..9a73e090c21 100644 --- a/docs/guide-zh-CN/README.md +++ b/docs/guide-zh-CN/README.md @@ -1,7 +1,7 @@ Yii 2.0 权威指南 =============================== -本教程的发布遵循 [Yii 文档使用许可](http://www.yiiframework.com/doc/terms/)。 +本教程的发布遵循 [Yii 文档使用许可](https://www.yiiframework.com/doc/terms/)。 版权所有。 @@ -183,14 +183,14 @@ RESTful Web 服务(RESTful Web Services) 小部件(Widgets) --------------- -* [GridView](http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) -* [ListView](http://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) -* [DetailView](http://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) -* [ActiveForm](http://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) -* [Pjax](http://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) -* [Menu](http://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) -* [LinkPager](http://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) -* [LinkSorter](http://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) +* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html) +* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html) +* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html) +* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform) +* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html) +* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html) +* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html) +* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html) * [Bootstrap Widgets](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide-zh-CN/README.md) * [jQuery UI Widgets](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide-zh-CN/README.md) diff --git a/docs/guide-zh-CN/caching-data.md b/docs/guide-zh-CN/caching-data.md index a2bc1b7f481..94516abf01e 100644 --- a/docs/guide-zh-CN/caching-data.md +++ b/docs/guide-zh-CN/caching-data.md @@ -57,7 +57,7 @@ $data = $cache->getOrSet($key, function () use ($user_id) { 缓存组件通常注册为应用程序组件,这样它们就可以 在全局进行配置与访问。如下代码演示了如何配置应用程序组件 -`cache` 使用两个 [memcached](http://memcached.org/) +`cache` 使用两个 [memcached](https://memcached.org/) 服务器: ```php @@ -103,7 +103,7 @@ $data = $cache->getOrSet($key, function () use ($user_id) { Yii 支持一系列缓存存储器,概况如下: -* [[yii\caching\ApcCache]]:使用 PHP [APC](https://secure.php.net/manual/en/book.apc.php) 扩展。 +* [[yii\caching\ApcCache]]:使用 PHP [APC](https://www.php.net/manual/en/book.apcu.php) 扩展。 这个选项可以认为是集中式应用程序环境中 (例如:单一服务器,没有独立的负载均衡器等)最快的缓存方案。 * [[yii\caching\DbCache]]:使用一个数据库的表存储缓存数据。要使用这个缓存, @@ -120,17 +120,17 @@ Yii 支持一系列缓存存储器,概况如下: `Yii::$app->cache` 可能是 `null`。 * [[yii\caching\FileCache]]:使用标准文件存储缓存数据。 这个特别适用于缓存大块数据,例如一个整页的内容。 -* [[yii\caching\MemCache]]:使用 PHP [memcache](https://secure.php.net/manual/en/book.memcache.php) - 和 [memcached](https://secure.php.net/manual/en/book.memcached.php) 扩展。 +* [[yii\caching\MemCache]]:使用 PHP [memcache](https://www.php.net/manual/en/book.memcache.php) + 和 [memcached](https://www.php.net/manual/en/book.memcached.php) 扩展。 这个选项被看作分布式应用环境中(例如:多台服务器,有负载均衡等) 最快的缓存方案。 -* [[yii\redis\Cache]]:实现了一个基于 [Redis](http://redis.io/) 键值对存储器的缓存组件 +* [[yii\redis\Cache]]:实现了一个基于 [Redis](https://redis.io/) 键值对存储器的缓存组件 (需要 redis 2.6.12 及以上版本的支持 )。 -* [[yii\caching\WinCache]]:使用 PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension) - ([另可参考](https://secure.php.net/manual/en/book.wincache.php))扩展. -* [[yii\caching\XCache]]:使用 PHP [XCache](http://xcache.lighttpd.net/)扩展。 +* [[yii\caching\WinCache]]:使用 PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) + ([另可参考](https://www.php.net/manual/en/book.wincache.php))扩展. +* [[yii\caching\XCache]]:使用 PHP [XCache](https://en.wikipedia.org/wiki/List_of_PHP_accelerators#XCache)扩展。 * [[yii\caching\ZendDataCache]]:使用 - [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend- server.htm#data_cache_component.htm) + [Zend Data Cache](https://files.zend.com/help/Zend-Server-6/zend- server.htm#data_cache_component.htm) 作为底层缓存媒介。 @@ -310,7 +310,7 @@ $result = Customer::getDb()->cache(function ($db) { }); ``` -> Info: 有些 DBMS (例如:[MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) +> Info: 有些 DBMS (例如:[MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html)) 也支持数据库服务器端的查询缓存。 你可以选择使用任一查询缓存机制。 上文所述的查询缓存的好处在于你可以指定更灵活的缓存依赖因此可能更加高效。 @@ -418,7 +418,7 @@ $result = $db->cache(function ($db) { 则会导致缓存失败。 -### 缓存冲刷 +### 缓存冲刷 当你想让所有的缓存数据失效时,可以调用 [[yii\caching\Cache::flush()]]。 diff --git a/docs/guide-zh-CN/caching-http.md b/docs/guide-zh-CN/caching-http.md index 71e81cc5f8b..3722807c8cf 100644 --- a/docs/guide-zh-CN/caching-http.md +++ b/docs/guide-zh-CN/caching-http.md @@ -107,7 +107,7 @@ ETag 相比 `Last-Modified` 能实现更复杂和更精确的缓存策略。 因为响应每一次请求都需要重新计算 Etag。 请试着找出一个最简单的表达式去触发 Etag 失效。 -> Note: 为了遵循 [RFC 7232(HTTP 1.1 协议)](http://tools.ietf.org/html/rfc7232#section-2.4), +> Note: 为了遵循 [RFC 7232(HTTP 1.1 协议)](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4), 如果同时配置了 `ETag` 和 `Last-Modified` 头,`HttpCache` 将会同时发送它们。 并且如果客户端同时发送 `If-None-Match` 头和 `If-Modified-Since` 头, 则只有前者会被接受。 @@ -131,7 +131,7 @@ Cache-Control: public, max-age=3600 为了避免此问题,默认情况下 `HttpCache` 禁止自动发送这些头。 想改变这一行为,可以配置 [[yii\filters\HttpCache::sessionCacheLimiter]] 属性。 该属性接受一个字符串值,包括 `public`,`private`,`private_no_expire`,和 `nocache`。 -请参考 PHP 手册中的[缓存限制器](https://secure.php.net/manual/en/function.session-cache-limiter.php) +请参考 PHP 手册中的[缓存限制器](https://www.php.net/manual/en/function.session-cache-limiter.php) 了解这些值的含义。 diff --git a/docs/guide-zh-CN/concept-aliases.md b/docs/guide-zh-CN/concept-aliases.md index 816eb8d4c18..e2f1a4214d6 100644 --- a/docs/guide-zh-CN/concept-aliases.md +++ b/docs/guide-zh-CN/concept-aliases.md @@ -117,7 +117,7 @@ Yii 预定义了一系列别名来简化常用路径和 URL 的使用: - `@web`,当前运行的Web应用程序的 base URL。它的值与 [[yii\web\Request::baseUrl]] 相同。 - `@vendor`,[[yii\base\Application::vendorPath|Composer vendor 目录]]。 - `@bower`,包含 [bower 包](http://bower.io/) 的根目录。默认为 `@vendor/bower`。 -- `@npm`,包含 [npm 包](https://www.npmjs.org/) 的根目录。默认为 `@vendor/npm`。 +- `@npm`,包含 [npm 包](https://www.npmjs.com/) 的根目录。默认为 `@vendor/npm`。 `@yii` 别名是在[入口脚本](structure-entry-scripts.md)里包含 `Yii.php` 文件时定义的, 其他的别名都是在[配置应用](concept-configurations.md)的时候, diff --git a/docs/guide-zh-CN/concept-autoloading.md b/docs/guide-zh-CN/concept-autoloading.md index 2ac47a6cfa3..0069f2258cb 100644 --- a/docs/guide-zh-CN/concept-autoloading.md +++ b/docs/guide-zh-CN/concept-autoloading.md @@ -1,7 +1,7 @@ 类自动加载(Autoloading) ====================== -Yii 依靠[类自动加载机制](https://secure.php.net/manual/en/language.oop5.autoload.php)来定位和包含所需的类文件。 +Yii 依靠[类自动加载机制](https://www.php.net/manual/zh/language.oop5.autoload.php)来定位和包含所需的类文件。 它提供一个高性能且完美支持[PSR-4 标准](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md) 的自动加载器。 该自动加载器会在引入框架文件 `Yii.php` 时安装好。 diff --git a/docs/guide-zh-CN/concept-behaviors.md b/docs/guide-zh-CN/concept-behaviors.md index 7b206f4dd48..96c84d7bd0a 100644 --- a/docs/guide-zh-CN/concept-behaviors.md +++ b/docs/guide-zh-CN/concept-behaviors.md @@ -120,21 +120,21 @@ class User extends ActiveRecord { return [ // 匿名行为,只有行为类名 - MyBehavior::className(), + MyBehavior::class, // 命名行为,只有行为类名 - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // 匿名行为,配置数组 [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // 命名行为,配置数组 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ] @@ -156,11 +156,11 @@ use app\components\MyBehavior; $component->attachBehavior('myBehavior1', new MyBehavior); // 附加行为类 -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // 附加配置数组 $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -171,7 +171,7 @@ $component->attachBehavior('myBehavior3', [ ```php $component->attachBehaviors([ 'myBehavior1' => new MyBehavior, // 命名行为 - MyBehavior::className(), // 匿名行为 + MyBehavior::class, // 匿名行为 ]); ``` @@ -179,10 +179,10 @@ $component->attachBehaviors([ ```php [ - 'as myBehavior2' => MyBehavior::className(), + 'as myBehavior2' => MyBehavior::class, 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -272,7 +272,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -329,7 +329,7 @@ $user->touch('login_time'); 比较行为与 Traits ---------------------- -虽然行为类似于 [traits](https://secure.php.net/traits),它们都将自己的属性和方法“注入”到主类中, +虽然行为类似于 [traits](https://www.php.net/traits),它们都将自己的属性和方法“注入”到主类中, 但它们在许多方面有所不同。如下所述,他们都有优点和缺点。 它们更像互补类而非替代类。 diff --git a/docs/guide-zh-CN/concept-components.md b/docs/guide-zh-CN/concept-components.md index 3b8b82a9a2f..30eb34aa6c3 100644 --- a/docs/guide-zh-CN/concept-components.md +++ b/docs/guide-zh-CN/concept-components.md @@ -76,7 +76,7 @@ class MyClass extends BaseObject $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // 方法二: $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide-zh-CN/concept-di-container.md b/docs/guide-zh-CN/concept-di-container.md index 511cb80f38b..81ebff6bbb5 100644 --- a/docs/guide-zh-CN/concept-di-container.md +++ b/docs/guide-zh-CN/concept-di-container.md @@ -427,7 +427,7 @@ $container->setDefinitions([ } ]); -$reader = $container->get('app\storage\DocumentsReader); +$reader = $container->get('app\storage\DocumentsReader'); // 将按照配置中的描述创建 DocumentReader 对象及其依赖关系 ``` @@ -465,7 +465,7 @@ $container->setDefinitions([ ] ]); -$reader = $container->get('app\storage\DocumentsReader); +$reader = $container->get('app\storage\DocumentsReader'); // 将与前面示例中的行为完全相同。 ``` diff --git a/docs/guide-zh-CN/concept-events.md b/docs/guide-zh-CN/concept-events.md index 030fe41401c..e2ad8515ee4 100644 --- a/docs/guide-zh-CN/concept-events.md +++ b/docs/guide-zh-CN/concept-events.md @@ -13,7 +13,7 @@ Yii 引入了名为 [[yii\base\Component]] 的基类以支持事件。 事件处理器(Event Handlers) ------------------------- -事件处理器是一个[PHP 回调函数](https://secure.php.net/manual/en/language.types.callable.php), +事件处理器是一个[PHP 回调函数](https://www.php.net/manual/en/language.types.callable.php), 当它所附加到的事件被触发时它就会执行。可以使用以下回调函数之一: - 字符串形式指定的 PHP 全局函数,如 `'trim'` ; @@ -211,7 +211,7 @@ use Yii; use yii\base\Event; use yii\db\ActiveRecord; -Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { +Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::debug(get_class($event->sender) . ' is inserted'); }); ``` @@ -229,11 +229,11 @@ Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ```php use yii\base\Event; -Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { +Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) { var_dump($event->sender); // 显示 "null" }); -Event::trigger(Foo::className(), Foo::EVENT_HELLO); +Event::trigger(Foo::class, Foo::EVENT_HELLO); ``` 注意这种情况下 `$event->sender` 指向触发事件的类名而不是对象实例。 @@ -245,10 +245,10 @@ Event::trigger(Foo::className(), Foo::EVENT_HELLO); ```php // 移除 $handler -Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); +Event::off(Foo::class, Foo::EVENT_HELLO, $handler); // 移除 Foo::EVENT_HELLO 事件的全部处理器 -Event::off(Foo::className(), Foo::EVENT_HELLO); +Event::off(Foo::class, Foo::EVENT_HELLO); ``` @@ -304,10 +304,10 @@ Event::on('app\interfaces\DanceEventInterface', DanceEventInterface::EVENT_DANCE ```php // trigger event for Dog class -Event::trigger(Dog::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Dog::class, DanceEventInterface::EVENT_DANCE); // trigger event for Developer class -Event::trigger(Developer::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Developer::class, DanceEventInterface::EVENT_DANCE); ``` 但是请注意, 你不能让所有实现这个接口的类都触发事件: diff --git a/docs/guide-zh-CN/db-active-record.md b/docs/guide-zh-CN/db-active-record.md index c14cd807eb8..6cac68139c0 100644 --- a/docs/guide-zh-CN/db-active-record.md +++ b/docs/guide-zh-CN/db-active-record.md @@ -473,8 +473,8 @@ Active Record 自动维护脏属性列表。 它保存所有属性的旧值, > 其中每个值都表示为一个字符串类型。 > 为了确保正确的类型,比如,整型需要用[过滤验证器](input-validation.md#data-filtering): > `['attributeName', 'filter', 'filter' => 'intval']`。其他 PHP 类型转换函数一样适用,像 -> [intval()](https://secure.php.net/manual/en/function.intval.php), [floatval()](https://secure.php.net/manual/en/function.floatval.php), -> [boolval](https://secure.php.net/manual/en/function.boolval.php),等等 +> [intval()](https://www.php.net/manual/en/function.intval.php), [floatval()](https://www.php.net/manual/en/function.floatval.php), +> [boolval](https://www.php.net/manual/en/function.boolval.php),等等 ### 默认属性值(Default Attribute Values) @@ -689,7 +689,7 @@ try { ``` > Tip: 在上面的代码中,我们有两个catch块用于兼容 -> PHP 5.x 和 PHP 7.x。 `\Exception` 继承于 [`\Throwable` interface](https://secure.php.net/manual/en/class.throwable.php) +> PHP 5.x 和 PHP 7.x。 `\Exception` 继承于 [`\Throwable` interface](https://www.php.net/manual/en/class.throwable.php) > 由于 PHP 7.0 的改动,如果您的应用程序仅使用 PHP 7.0 及更高版本,您可以跳过 `\Exception` 部分。 第二种方法是在 [[yii\db\ActiveRecord::transactions()]] 方法中列出需要事务支持的 DB 操作。 @@ -789,9 +789,15 @@ use yii\behaviors\OptimisticLockBehavior; public function behaviors() { return [ - OptimisticLockBehavior::className(), + OptimisticLockBehavior::class, ]; } + +public function optimisticLock() +{ + return 'version'; +} + ``` > Note: 因为 [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] 仅仅在保存记录的时候被确认, > 如果用户提交的有效版本号被直接解析 :[[\yii\web\Request::getBodyParam()|getBodyParam()]], @@ -821,7 +827,7 @@ class Customer extends ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -831,7 +837,7 @@ class Order extends ActiveRecord public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -849,7 +855,7 @@ class Order extends ActiveRecord 一个客户可以有很多订单,而每个订单只有一个客户。 - 相关联 Active Record 类名:用来指定为 [[yii\db\ActiveRecord::hasMany()|hasMany()]] 或者 [[yii\db\ActiveRecord::hasOne()|hasOne()]] 方法的第一个参数。 - 推荐的做法是调用 `Xyz::className()` 来获取类名称的字符串,以便您 + 推荐的做法是调用 `Xyz::class` 来获取类名称的字符串,以便您 可以使用 IDE 的自动补全,以及让编译阶段的错误检测生效。 - 两组数据的关联列:用以指定两组数据相关的列(hasOne()/hasMany() 的第二个参数)。 数组的值填的是主数据的列(当前要声明关联的 Active Record 类为主数据), @@ -927,7 +933,7 @@ class Customer extends ActiveRecord { public function getBigOrders($threshold = 100) // 老司机的提醒:$threshold 参数一定一定要给个默认值 { - return $this->hasMany(Order::className(), ['customer_id' => 'id']) + return $this->hasMany(Order::class, ['customer_id' => 'id']) ->where('subtotal > :threshold', [':threshold' => $threshold]) ->orderBy('id'); } @@ -962,7 +968,7 @@ class Order extends ActiveRecord { public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->viaTable('order_item', ['order_id' => 'id']); } } @@ -975,12 +981,12 @@ class Order extends ActiveRecord { public function getOrderItems() { - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } } @@ -1014,21 +1020,21 @@ class Customer extends ActiveRecord public function getPurchasedItems() { // 客户的商品,将 Item 中的 'id' 列与 OrderItem 中的 'item_id' 相匹配 - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } public function getOrderItems() { // 客户订单中的商品,将 `Order` 的 'id' 列和 OrderItem 的 'order_id' 列相匹配 - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']) + return $this->hasMany(OrderItem::class, ['order_id' => 'id']) ->via('orders'); } public function getOrders() { // 见上述列子 - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1281,7 +1287,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -1289,7 +1295,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -1323,7 +1329,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); } } ``` @@ -1434,7 +1440,7 @@ class Customer extends \yii\db\ActiveRecord public function getComments() { // 一个 customer 有很多条评论(comments) - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1449,7 +1455,7 @@ class Comment extends \yii\mongodb\ActiveRecord public function getCustomer() { // 一条评论对应一位 customer - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } @@ -1533,7 +1539,7 @@ class Customer extends \yii\db\ActiveRecord { public function getActiveComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id'])->active(); + return $this->hasMany(Comment::class, ['customer_id' => 'id'])->active(); } } @@ -1544,7 +1550,7 @@ class Customer extends \yii\db\ActiveRecord { public function getComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1610,7 +1616,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1705,7 +1711,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1736,7 +1742,7 @@ class Customer extends \yii\db\ActiveRecord */ public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } /** diff --git a/docs/guide-zh-CN/db-dao.md b/docs/guide-zh-CN/db-dao.md index 228a96c5e88..22baef3256d 100644 --- a/docs/guide-zh-CN/db-dao.md +++ b/docs/guide-zh-CN/db-dao.md @@ -11,12 +11,12 @@ DAO提供了简单高效的SQL查询,可以用在与数据库交互的各个 Yii DAO 支持下列现成的数据库: -- [MySQL](http://www.mysql.com/) +- [MySQL](https://www.mysql.com/) - [MariaDB](https://mariadb.com/) -- [SQLite](http://sqlite.org/) -- [PostgreSQL](http://www.postgresql.org/):版本 8.4 或更高 -- [CUBRID](http://www.cubrid.org/):版本 9.3 或更高。 -- [Oracle](http://www.oracle.com/us/products/database/overview/index.html) +- [SQLite](https://sqlite.org/) +- [PostgreSQL](https://www.postgresql.org/):版本 8.4 或更高 +- [CUBRID](https://www.cubrid.org/):版本 9.3 或更高。 +- [Oracle](https://www.oracle.com/database/) - [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx):版本 2008 或更高。 > Info: 在Yii 2.1及更高版本中,DAO 支持 CUBRID,Oracle 和 MSSQL @@ -68,7 +68,7 @@ return [ 配置数据库连接时, 你应该总是通过 [[yii\db\Connection::dsn|dsn]] 属性来指明它的数据源名称 (DSN) 。 不同的数据库有着不同的 DSN 格式。 -请参考 [PHP manual](https://secure.php.net/manual/en/function.PDO-construct.php) 来获得更多细节。下面是一些例子: +请参考 [PHP manual](https://www.php.net/manual/en/pdo.construct.php) 来获得更多细节。下面是一些例子: * MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` * SQLite: `sqlite:/path/to/database/file` @@ -184,7 +184,7 @@ $post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status ->queryOne(); ``` -绑定参数是通过 [预处理语句](https://secure.php.net/manual/en/mysqli.quickstart.prepared-statements.php) 实现的。 +绑定参数是通过 [预处理语句](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php) 实现的。 除了防止 SQL 注入攻击,它也可以通过一次预处理 SQL 语句, 使用不同参数多次执行,来提升性能。例如: @@ -421,7 +421,7 @@ Yii 为四个最常用的隔离级别提供了常量: 因此,你不能在开启事务时直接指定隔离级别。 你必须在事务开始后再调用 [[yii\db\Transaction::setIsolationLevel()]]。 -[隔离级别]: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels +[隔离级别]: https://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels ### 嵌套事务(Nesting Transactions) @@ -471,7 +471,7 @@ try { ## 复制和读写分离(Replication and Read-Write Splitting) -许多数据库支持[数据库复制](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication)来获得更好的数据库可用性, +许多数据库支持[数据库复制](https://en.wikipedia.org/wiki/Replication_(computing)#Database_replication)来获得更好的数据库可用性, 以及更快的服务器响应时间。通过数据库复制功能, 数据从所谓的主服务器被复制到从服务器。所有的写和更新必须发生在主服务器上, 而读可以发生在从服务器上。 diff --git a/docs/guide-zh-CN/db-query-builder.md b/docs/guide-zh-CN/db-query-builder.md index 0dfa3dd507f..53ac0f56c9b 100644 --- a/docs/guide-zh-CN/db-query-builder.md +++ b/docs/guide-zh-CN/db-query-builder.md @@ -155,7 +155,7 @@ $query->from(['u' => $subQuery]); #### 前缀 `from` 还可以应用默认的 [[yii\db\Connection::$tablePrefix|tablePrefix]] 前缀,实现细节请参考 -[“数据库访问对象指南”的“Quoting Tables”章节](guide-db-dao.html#quoting-table-and-column-names). +[“数据库访问对象指南”的“Quoting Tables”章节](db-dao.md#quoting-table-and-column-names). ### [[yii\db\Query::where()|where()]] @@ -539,14 +539,14 @@ $query->limit(10)->offset(20); ### [[yii\db\Query::join()|join()]] [[yii\db\Query::join()|join()]] 是用来指定 SQL 语句当中的 `JOIN` 子句的。例如, - + ```php // ... LEFT JOIN `post` ON `post`.`user_id` = `user`.`id` $query->join('LEFT JOIN', 'post', 'post.user_id = user.id'); ``` [[yii\db\Query::join()|join()]] 带有四个参数: - + - `$type`:连接类型,例如,`'INNER JOIN'`,`'LEFT JOIN'`。 - `$table`:将要连接的表名称。 - `$on`:可选的,连接条件,即 `ON` 片段。有关指定条件的详细信息,请参阅 [where()](#where)。 @@ -771,7 +771,7 @@ foreach ($query->each() as $username => $user) { #### MySQL中批量查询的局限性(Limitations of batch query in MySQL) -MySQL 是通过 PDO 驱动库实现批量查询的。默认情况下,MySQL 查询是 [`带缓存的`](https://secure.php.net/manual/en/mysqlinfo.concepts.buffering.php), +MySQL 是通过 PDO 驱动库实现批量查询的。默认情况下,MySQL 查询是 [`带缓存的`](https://www.php.net/manual/en/mysqlinfo.concepts.buffering.php), 这违背了使用游标(cursor)获取数据的目的, 因为它不阻止驱动程序将整个结果集加载到客户端的内存中。 diff --git a/docs/guide-zh-CN/helper-array.md b/docs/guide-zh-CN/helper-array.md index c458e4ad7bf..0aafaaa1c0e 100644 --- a/docs/guide-zh-CN/helper-array.md +++ b/docs/guide-zh-CN/helper-array.md @@ -1,7 +1,7 @@ 数组助手类(ArrayHelper) ====================== -除了 [PHP 中丰富的数组函数集](https://secure.php.net/manual/zh/book.array.php), +除了 [PHP 中丰富的数组函数集](https://www.php.net/manual/zh/book.array.php), Yii 数组助手类提供了额外的静态方法,让你更高效地处理数组。 @@ -117,7 +117,7 @@ $type = ArrayHelper::remove($array, 'type'); ## 检查键名的存在(Checking Existence of Keys) -`ArrayHelper::keyExists` 工作原理和 [array_key_exists](https://secure.php.net/manual/en/function.array-key-exists.php) 差不多,除了 +`ArrayHelper::keyExists` 工作原理和 [array_key_exists](https://www.php.net/manual/en/function.array-key-exists.php) 差不多,除了 它还可支持大小写不敏感的键名比较,比如: ```php @@ -321,7 +321,7 @@ ArrayHelper::multisort($data, function($item) { 各个键指定不同的顺序。 最后一个参数(译者注:第四个参数)是PHP的排序标识(sort flag),可使用的值和调用 PHP -[sort()](https://secure.php.net/manual/zh/function.sort.php) 函数时传递的值一样。 +[sort()](https://www.php.net/manual/zh/function.sort.php) 函数时传递的值一样。 ## 检测数组类型(Detecting Array Types) @@ -356,7 +356,7 @@ $decoded = ArrayHelper::htmlDecode($data); 您可以使用 [[yii\helpers\ArrayHelper::merge()|ArrayHelper::merge()]] 将两个或多个数组合并成一个递归的数组。 如果每个数组都有一个具有相同字符串键值的元素,则后者将覆盖前者 -(不同于 [array_merge_recursive()](https://secure.php.net/manual/en/function.array-merge-recursive.php))。 +(不同于 [array_merge_recursive()](https://www.php.net/manual/en/function.array-merge-recursive.php))。 如果两个数组都有一个数组类型的元素并且具有相同的键,则将执行递归合并。 对于整数键的元素,来自后一个数组的元素将被附加到前一个数组。 您可以使用 [[yii\helpers\UnsetArrayValue]] 对象来取消前一个数组的值或 diff --git a/docs/guide-zh-CN/helper-html.md b/docs/guide-zh-CN/helper-html.md index 2e4007f1f37..664d9523f28 100644 --- a/docs/guide-zh-CN/helper-html.md +++ b/docs/guide-zh-CN/helper-html.md @@ -2,7 +2,7 @@ Html 帮助类(Html helper) ======================= 任何一个 web 应用程序会生成很多 HTMl 超文本标记。如果超文本标记是静态的, -那么[将 PHP 和 HTML 混合在一个文件里](https://secure.php.net/manual/en/language.basic-syntax.phpmode.php) +那么[将 PHP 和 HTML 混合在一个文件里](https://www.php.net/manual/en/language.basic-syntax.phpmode.php) 这种做法是非常高效的。但是,如果这些超文本标记是动态生成的,那么如果没有额外的辅助工具,这个过程将会变得复杂。 Yii 通过 HTML 帮助类来提供生成超文本标记的方法。这个帮助类包含有一系列的用于处理通用的 HTML 标签和其属性以及内容的静态方法。 @@ -42,7 +42,7 @@ Yii 提供了一系列的静态方法来操作标签配置并基于这些配置 - 如果一个值为 null ,那么对应的属性将不会被渲染。 - 如果是布尔类型的值的属性,将会被当做 - [布尔属性](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes) 来处理。 + [布尔属性](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes) 来处理。 - 属性的值将会用 [[yii\helpers\Html::encode()|Html::encode()]] 方法进行 HTML 转码处理。 - 如果一个属性的值是一个数组,那么它将会被如下处理: @@ -147,8 +147,8 @@ Html::removeCssStyle($options, ['width', 'height']); ### 标签内容的转码和解码(Encoding and Decoding Content) 为了让内容能够正确安全的显示,一些 HTML 特殊字符应该被转码。在 PHP 中, -这个操作由 [htmlspecialchars](https://secure.php.net/manual/en/function.htmlspecialchars.php) 和 -[htmlspecialchars_decode](https://secure.php.net/manual/en/function.htmlspecialchars-decode.php) 完成。 +这个操作由 [htmlspecialchars](https://www.php.net/manual/en/function.htmlspecialchars.php) 和 +[htmlspecialchars_decode](https://www.php.net/manual/en/function.htmlspecialchars-decode.php) 完成。 直接使用这些方法的问题是,你总是需要指定转码所需的额外标志。由于标志一般总是不变的,而内容转码的过程为了避免一些安全问题, 需要和应用的默认过程匹配, Yii 提供了两个简单可用的对 PHP 原生方法的封装: diff --git a/docs/guide-zh-CN/input-file-upload.md b/docs/guide-zh-CN/input-file-upload.md index 27e40039897..5532d42a867 100644 --- a/docs/guide-zh-CN/input-file-upload.md +++ b/docs/guide-zh-CN/input-file-upload.md @@ -123,7 +123,7 @@ class SiteController extends Controller 首先你得调整模型类,在 `file` 验证规则里增加一个 `maxFiles` 选项,用以限制一次上传文件的最大数量。 `upload()`方法也得修改,以便一个一个地保存上传的文件。将 `maxFiles` 设置为 `0` 意味着可以同时上传的文件数量没有限制。 允许同时上传的文件的最大数量也受到 PHP 指令 -[`max_file_uploads`](https://secure.php.net/manual/en/ini.core.php#ini.max-file-uploads)的限制, +[`max_file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads)的限制, 默认为20。还应该更新 `upload()` 方法以逐个保存上传的文件。 ```php diff --git a/docs/guide-zh-CN/input-forms.md b/docs/guide-zh-CN/input-forms.md index 039a6c2ed84..62314c95b2f 100644 --- a/docs/guide-zh-CN/input-forms.md +++ b/docs/guide-zh-CN/input-forms.md @@ -107,7 +107,7 @@ echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Ite > 表单和它们的子元素不应该使用与表单的属性冲突的 input name 或 id, > 例如 `submit`,`length`,或者 `method`。 -> 要检查你的标签是否存在这些问题,一个完整的规则列表详见 [DOMLint](http://kangax.github.io/domlint/)。 +> 要检查你的标签是否存在这些问题,一个完整的规则列表详见 [DOMLint](https://kangax.github.io/domlint/)。 额外的 HTML 标签可以使用纯 HTML 或者 [[yii\helpers\Html|Html]]-辅助类中的方法来添加到表单中,就如上面例子中的 [[yii\helpers\Html::submitButton()|Html::submitButton()]]。 @@ -127,7 +127,7 @@ echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Ite > } > ``` -创建下拉列表 +创建下拉列表 ------------ 有三种类型的列表: diff --git a/docs/guide-zh-CN/input-validation.md b/docs/guide-zh-CN/input-validation.md index 6ba0ae9c691..9940f328b99 100644 --- a/docs/guide-zh-CN/input-validation.md +++ b/docs/guide-zh-CN/input-validation.md @@ -465,7 +465,7 @@ class EntryForm extends Model { return [ [['name', 'email'], 'required'], - ['country', CountryValidator::className()], + ['country', CountryValidator::class], ['email', 'email'], ]; } diff --git a/docs/guide-zh-CN/intro-upgrade-from-v1.md b/docs/guide-zh-CN/intro-upgrade-from-v1.md index 42aa2b9b9a9..a2c3a9a3928 100644 --- a/docs/guide-zh-CN/intro-upgrade-from-v1.md +++ b/docs/guide-zh-CN/intro-upgrade-from-v1.md @@ -29,15 +29,15 @@ Yii 2.0 需要 PHP 5.4 或更高版本,该版本相对于 Yii 1.1 所需求的 因此在语言层面上有很多的值得注意的不同之处。 下面是 PHP 层的主要变化汇总: -- [命名空间](https://secure.php.net/manual/zh/language.namespaces.php) -- [匿名函数](https://secure.php.net/manual/zh/functions.anonymous.php) +- [命名空间](https://www.php.net/manual/zh/language.namespaces.php) +- [匿名函数](https://www.php.net/manual/zh/functions.anonymous.php) - 数组短语法 `[...元素...]` 用于取代 `array(...元素...)` - 视图文件中的短格式 echo 标签 `registerJs( - [[yii\web\View::POS_HEAD|View::POS_HEAD]] 用在 HEAD 部分。 - [[yii\web\View::POS_BEGIN|View::POS_BEGIN]] 用在 `` 标签的右边。 - [[yii\web\View::POS_END|View::POS_END]] 用在 `` 标签的左边。 -- [[yii\web\View::POS_READY|View::POS_READY]] 为了在 [`ready` 事件](http://learn.jquery.com/using-jquery-core/document-ready/) 中执行代码。 +- [[yii\web\View::POS_READY|View::POS_READY]] 为了在 [`ready` 事件](https://learn.jquery.com/using-jquery-core/document-ready/) 中执行代码。 这里将自动注册 [[yii\web\JqueryAsset|jQuery]] 并将代码包装到适当的 jQuery 代码中。这是默认位置。 -- [[yii\web\View::POS_LOAD|View::POS_LOAD]] 为了在 [`load` 事件](http://learn.jquery.com/using-jquery-core/document-ready/) 中执行代码。 +- [[yii\web\View::POS_LOAD|View::POS_LOAD]] 为了在 [`load` 事件](https://learn.jquery.com/using-jquery-core/document-ready/) 中执行代码。 与上面相同,这也将自动注册 [[yii\web\JqueryAsset|jQuery]]。 最后一个参数是一个唯一的脚本 ID,主要是用于标识一段代码块,在添加一段新的代码块时,如果当前页面已经存在同样 ID 代码块时,那么将会被新的替换。 @@ -56,7 +56,7 @@ $this->registerJs( ```php $this->registerJsFile( '@web/js/main.js', - ['depends' => [\yii\web\JqueryAsset::className()]] + ['depends' => [\yii\web\JqueryAsset::class]] ); ``` @@ -95,7 +95,7 @@ body { background: #f00; } ```php $this->registerCssFile("@web/css/themes/black-and-white.css", [ - 'depends' => [\yii\bootstrap\BootstrapAsset::className()], + 'depends' => [\yii\bootstrap\BootstrapAsset::class], 'media' => 'print', ], 'css-print-theme'); ``` @@ -189,7 +189,7 @@ JS ``` 上面的示例代码使用 PHP -[Heredoc 语法](https://secure.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) 以获得更好的可读性。 +[Heredoc 语法](https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) 以获得更好的可读性。 这也可以在大多数 IDE 中实现更好的语法突出显示,因此它是编写内联 JavaScript 的首选方式,对于长于单行的代码尤其有用。变量 `$message` 是在 PHP 中创建的,感谢 [[yii\helpers\Json::htmlEncode|Json::htmlEncode]] 它包含有效 JS 语法中的字符串,可以将其插入到 JavaScript 代码中以放置 函数中的动态字符串调用 `alert()`。 diff --git a/docs/guide-zh-CN/output-data-widgets.md b/docs/guide-zh-CN/output-data-widgets.md index 2cbfaf5d06e..0fc2e00d48c 100644 --- a/docs/guide-zh-CN/output-data-widgets.md +++ b/docs/guide-zh-CN/output-data-widgets.md @@ -776,4 +776,4 @@ yii gii/crud --controllerClass="backend\\controllers\PostController" \ 延伸阅读 --------------- -- [Rendering Data in Yii 2 with GridView and ListView](http://www.sitepoint.com/rendering-data-in-yii-2-with-gridview-and-listview/) by Arno Slatius. +- [Rendering Data in Yii 2 with GridView and ListView](https://www.sitepoint.com/rendering-data-in-yii-2-with-gridview-and-listview/) by Arno Slatius. diff --git a/docs/guide-zh-CN/output-formatting.md b/docs/guide-zh-CN/output-formatting.md index de1f4f2b1f9..d27841da950 100644 --- a/docs/guide-zh-CN/output-formatting.md +++ b/docs/guide-zh-CN/output-formatting.md @@ -45,7 +45,7 @@ echo Yii::$app->formatter->format(0.125, ['percent', 2]); > 不要使用这个组件, > 而应该使用 [[yii\validators\DateValidator]] 和 [[yii\validators\NumberValidator]] 进行用户输入格式化 > 对于机器可读的日期和时间格式之间的简单转换, -> PHP 方法 [date()](https://secure.php.net/manual/en/function.date.php) 就足够了。 +> PHP 方法 [date()](https://www.php.net/manual/en/function.date.php) 就足够了。 ## 配置 Formatter(Configuring Formatter) @@ -86,7 +86,7 @@ return [ [[yii\i18n\Formatter::timeFormat|timeFormat]], 和 [[yii\i18n\Formatter::datetimeFormat|datetimeFormat]] 即可。 同时,你还可以配置它使用 [ICU syntax](http://userguide.icu-project.org/formatparse/datetime), -同时你也可以配置它使用 [PHP date() 语法](https://secure.php.net/manual/en/function.date.php),只需要加上 `php:` 前缀即可。 +同时你也可以配置它使用 [PHP date() 语法](https://www.php.net/manual/en/function.date.php),只需要加上 `php:` 前缀即可。 例如, ```php @@ -175,7 +175,7 @@ echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00 如果你想要进行更高级的配置, 可以使用 [[yii\i18n\Formatter::numberFormatterOptions]] 和 [[yii\i18n\Formatter::numberFormatterTextOptions]], -[NumberFormatter class](https://secure.php.net/manual/en/class.numberformatter.php) 来进行格式化。 +[NumberFormatter class](https://www.php.net/manual/en/class.numberformatter.php) 来进行格式化。 例如,为了调整小数部分的最大值和最小值,你可以配置 [[yii\i18n\Formatter::numberFormatterOptions]] 如下: ```php @@ -235,7 +235,7 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // output: 1 января 2014 默认配置下,当前 [[yii\i18n\Formatter::locale|locale]] 决定于 [[yii\base\Application::language]]. 你可以覆盖 [[yii\i18n\Formatter::locale]] 属性来满足不同的需要。 -> Note: Yii formatter 依赖 [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) +> Note: Yii formatter 依赖 [PHP intl extension](https://www.php.net/manual/en/book.intl.php) > 来进行本地数据格式化 > 因为不同的 ICU 库可能会导致不同的输出,所以请在你的所有机器上保持 ICU 库的一致性。 > 请参阅 [Setting up your PHP environment for internationalization](tutorial-i18n.md#setup-environment)。 diff --git a/docs/guide-zh-CN/rest-authentication.md b/docs/guide-zh-CN/rest-authentication.md index 570d2f2d3a4..1b46c062ccb 100644 --- a/docs/guide-zh-CN/rest-authentication.md +++ b/docs/guide-zh-CN/rest-authentication.md @@ -18,7 +18,7 @@ 由于大多数服务器都会保存请求参数到日志, 这种方式应主要用于`JSONP` 请求,因为它不能使用HTTP头来发送access token * [OAuth 2](http://oauth.net/2/):使用者从认证服务器上获取基于 OAuth2 协议的 access token, - 然后通过 [HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750) + 然后通过 [HTTP Bearer Tokens](https://datatracker.ietf.org/doc/html/rfc6750) 发送到 API 服务器。 Yii 支持上述的认证方式,你也可很方便的创建新的认证方式。 @@ -57,7 +57,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -75,11 +75,11 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => CompositeAuth::className(), + 'class' => CompositeAuth::class, 'authMethods' => [ - HttpBasicAuth::className(), - HttpBearerAuth::className(), - QueryParamAuth::className(), + HttpBasicAuth::class, + HttpBearerAuth::class, + QueryParamAuth::class, ], ]; return $behaviors; diff --git a/docs/guide-zh-CN/rest-controllers.md b/docs/guide-zh-CN/rest-controllers.md index 739043b5223..d202a3a90fc 100644 --- a/docs/guide-zh-CN/rest-controllers.md +++ b/docs/guide-zh-CN/rest-controllers.md @@ -69,7 +69,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -80,7 +80,7 @@ public function behaviors() 将 [Cross-Origin Resource Sharing](structure-filters.md#cors) 过滤器添加到控制器比添加到上述其他过滤器中要复杂一些, 因为必须在认证方法之前应用 CORS 过滤器, 因此与其他过滤器相比,需要一些稍微不同的方式来实现。 -并且还要为 [CORS Preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests) 禁用身份验证, +并且还要为 [CORS Preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests) 禁用身份验证, 这样浏览器就可以安全地确定是否可以事先做出请求, 而无需发送身份验证凭据。 下面显示了将 [[yii\filters\Cors]] 过滤器添加到从 [[yii\rest\ActiveController]] 扩展的控制器所需的代码: @@ -98,7 +98,7 @@ public function behaviors() // add CORS filter $behaviors['corsFilter'] = [ - 'class' => \yii\filters\Cors::className(), + 'class' => \yii\filters\Cors::class, ]; // re-add authentication filter diff --git a/docs/guide-zh-CN/rest-resources.md b/docs/guide-zh-CN/rest-resources.md index 311cae806de..cf5cacd50d1 100644 --- a/docs/guide-zh-CN/rest-resources.md +++ b/docs/guide-zh-CN/rest-resources.md @@ -140,7 +140,7 @@ public function extraFields() ## 链接 -[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), +[HATEOAS](https://en.wikipedia.org/wiki/HATEOAS), 是 Hypermedia as the Engine of Application State的缩写, 提升 RESTful API 应返回允许终端用户访问的资源操作的信息, HATEOAS 的目的是在API中返回包含相关链接信息的资源数据。 diff --git a/docs/guide-zh-CN/runtime-bootstrapping.md b/docs/guide-zh-CN/runtime-bootstrapping.md index e0429381301..95b4eeae67c 100644 --- a/docs/guide-zh-CN/runtime-bootstrapping.md +++ b/docs/guide-zh-CN/runtime-bootstrapping.md @@ -37,8 +37,8 @@ 在生产环境中,可以开启字节码缓存,比如 APC, 来进一步最小化加载和解析 PHP 文件所需的时间。 -[PHP OPcache]: https://secure.php.net/manual/en/intro.opcache.php -[APC]: https://secure.php.net/manual/en/book.apc.php +[PHP OPcache]: https://www.php.net/manual/zh/intro.opcache.php +[APC]: https://www.php.net/manual/zh/book.apcu.php 一些大型应用都包含有非常复杂的应用[配置](concept-configurations.md), 它们会被分割到许多更小的配置文件中。 diff --git a/docs/guide-zh-CN/runtime-responses.md b/docs/guide-zh-CN/runtime-responses.md index f3ad62c5d7c..70bf28f1cb3 100644 --- a/docs/guide-zh-CN/runtime-responses.md +++ b/docs/guide-zh-CN/runtime-responses.md @@ -230,11 +230,11 @@ Web 应用可在服务器发送文件前结束,为使用该功能, 可调用 [[yii\web\Response::xSendFile()]], 如下简要列出一些常用 Web 服务器如何启用 `X-Sendfile` 功能: -- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile) -- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Lighttpd v1.5: [X-Sendfile](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Nginx: [X-Accel-Redirect](http://wiki.nginx.org/XSendfile) -- Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) +- Apache: [X-Sendfile](https://tn123.org/mod_xsendfile) +- Lighttpd v1.4: [X-LIGHTTPD-send-file](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Lighttpd v1.5: [X-Sendfile](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Nginx: [X-Accel-Redirect](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) +- Cherokee: [X-Sendfile and X-Accel-Redirect](https://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) ## 发送响应 diff --git a/docs/guide-zh-CN/runtime-sessions-cookies.md b/docs/guide-zh-CN/runtime-sessions-cookies.md index 9022547c5a0..b825260a24e 100644 --- a/docs/guide-zh-CN/runtime-sessions-cookies.md +++ b/docs/guide-zh-CN/runtime-sessions-cookies.md @@ -131,8 +131,8 @@ Yii 提供以下 session 类实现不同的 session 存储方式: * [[yii\web\DbSession]]:存储 session 数据在数据表中 * [[yii\web\CacheSession]]:存储 session 数据到缓存中,缓存和配置中的[缓存组件](caching-data.md#cache-components)相关 -* [[yii\redis\Session]]:存储 session 数据到以 [redis](http://redis.io/) 作为存储媒介中 -* [[yii\mongodb\Session]]:存储 session 数据到 [MongoDB](http://www.mongodb.org/)。 +* [[yii\redis\Session]]:存储 session 数据到以 [redis](https://redis.io/) 作为存储媒介中 +* [[yii\mongodb\Session]]:存储 session 数据到 [MongoDB](https://www.mongodb.com/)。 所有这些 session 类支持相同的 API 方法集,因此, 切换到不同的 session 存储介质不需要修改项目使用 session 的代码。 @@ -334,7 +334,7 @@ unset($cookies['language']); > Note: 为安全起见 [[yii\web\Cookie::httpOnly]] 被设置为 true, 这可减少客户端脚本访问受保护 cookie(如果浏览器支持)的风险, - 更多详情可阅读 [httpOnly wiki article](https://www.owasp.org/index.php/HttpOnly)。 + 更多详情可阅读 [httpOnly wiki article](https://owasp.org/www-community/HttpOnly)。 ### Cookie 验证 diff --git a/docs/guide-zh-CN/security-authorization.md b/docs/guide-zh-CN/security-authorization.md index 0a1e7a75e43..3fa0e302826 100644 --- a/docs/guide-zh-CN/security-authorization.md +++ b/docs/guide-zh-CN/security-authorization.md @@ -25,7 +25,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['login', 'logout', 'signup'], 'rules' => [ [ @@ -70,7 +70,7 @@ ACF 自顶向下逐一检查存取规则,直到找到一个与当前 ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, ... 'denyCallback' => function ($rule, $action) { throw new \Exception('You are not allowed to access this page'); @@ -129,7 +129,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['special-callback'], 'rules' => [ [ @@ -159,7 +159,7 @@ class SiteController extends Controller 详细的关于 RBAC 和诸多传统的存取控制方案对比的详情,请参阅 [Wikipedia](http://en.wikipedia.org/wiki/Role-based_access_control)。 -Yii 实现了通用的分层的 RBAC,遵循的模型是 [NIST RBAC model](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf). +Yii 实现了通用的分层的 RBAC,遵循的模型是 [NIST RBAC model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf). 它通过 [[yii\rbac\ManagerInterface|authManager]] [application component](structure-application-components.md) 提供 RBAC 功能。 使用 RBAC 涉及到两部分工作。第一部分是建立授权数据, @@ -538,7 +538,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'rules' => [ [ 'allow' => true, diff --git a/docs/guide-zh-CN/security-best-practices.md b/docs/guide-zh-CN/security-best-practices.md index 24b016a5bdd..3864ef9efe2 100644 --- a/docs/guide-zh-CN/security-best-practices.md +++ b/docs/guide-zh-CN/security-best-practices.md @@ -33,7 +33,7 @@ if (!in_array($sortBy, ['title', 'created_at', 'status'])) { 进一步阅读该主题: -- +- - @@ -46,9 +46,9 @@ Yii 提供了大量的工具来在不同的上下文执行转义。 进一步阅读该话题: -- -- -- +- +- +- 避免 SQL 注入 @@ -117,7 +117,7 @@ $rowCount = $connection->createCommand($sql)->queryScalar(); 进一步阅读该话题: -- +- 防止 XSS 攻击 @@ -151,7 +151,7 @@ XSS 或者跨站脚本发生在输出 HTML 到浏览器时,输出内容没有 进一步阅读该话题: -- +- 防止 CSRF 攻击 @@ -255,7 +255,7 @@ class ContactAction extends Action 进一步阅读该话题: -- +- 防止文件暴露 @@ -283,8 +283,8 @@ class ContactAction extends Action 进一步阅读该话题: -- -- +- +- (A6 - Information Leakage and Improper Error Handling) 使用 TLS 上的安全连接 diff --git a/docs/guide-zh-CN/security-passwords.md b/docs/guide-zh-CN/security-passwords.md index da126e5e3b6..d13e024da4e 100644 --- a/docs/guide-zh-CN/security-passwords.md +++ b/docs/guide-zh-CN/security-passwords.md @@ -7,7 +7,7 @@ 为了即使在最糟糕的情况下(你的应用程序被破解了)也能给用户密码提供增强的安全性, 你需要使用一个能够对抗暴力破解攻击的哈希算法。目前最好的选择是 `bcrypt`。在 PHP 中, -你可以通过 [crypt 函数](https://secure.php.net/manual/en/function.crypt.php) 生成 `bcrypt` 哈希。 +你可以通过 [crypt 函数](https://www.php.net/manual/en/function.crypt.php) 生成 `bcrypt` 哈希。 Yii 提供了两个帮助函数以让使用 `crypt` 来进行安全的哈希密码生成和验证更加容易。 当一个用户为第一次使用,提供了一个密码时(比如:注册时),密码就需要被哈希化。 diff --git a/docs/guide-zh-CN/start-databases.md b/docs/guide-zh-CN/start-databases.md index ad89a596d6a..435fd8494d0 100644 --- a/docs/guide-zh-CN/start-databases.md +++ b/docs/guide-zh-CN/start-databases.md @@ -51,7 +51,7 @@ INSERT INTO `country` VALUES ('US','United States',278357000); 配置数据库连接 --------------------------- -开始之前,请确保你已经安装了 PHP [PDO](https://secure.php.net/manual/en/book.pdo.php) +开始之前,请确保你已经安装了 PHP [PDO](https://www.php.net/manual/en/book.pdo.php) 扩展和你所使用的数据库的 PDO 驱动(例如 MySQL 的 `pdo_mysql`)。 对于使用关系型数据库来讲,这是基本要求。 diff --git a/docs/guide-zh-CN/start-forms.md b/docs/guide-zh-CN/start-forms.md index ec988992286..a1e5a4d3d99 100644 --- a/docs/guide-zh-CN/start-forms.md +++ b/docs/guide-zh-CN/start-forms.md @@ -130,7 +130,7 @@ class SiteController extends Controller > Note: 在这个简单例子里我们只是呈现了有效数据的确认页面。 实践中你应该考虑使用 [[yii\web\Controller::refresh()|refresh()]] - 或 [[yii\web\Controller::redirect()|redirect()]] 去避免[表单重复提交问题](http://en.wikipedia.org/wiki/Post/Redirect/Get)。 + 或 [[yii\web\Controller::redirect()|redirect()]] 去避免[表单重复提交问题](https://en.wikipedia.org/wiki/Post/Redirect/Get)。 创建视图 diff --git a/docs/guide-zh-CN/start-hello.md b/docs/guide-zh-CN/start-hello.md index 0f576ca347d..b60c95ad4e4 100644 --- a/docs/guide-zh-CN/start-hello.md +++ b/docs/guide-zh-CN/start-hello.md @@ -89,7 +89,7 @@ use yii\helpers\Html; 注意以上代码,`message` 参数在输出之前被 [[yii\helpers\Html::encode()|HTML-encoded]] 方法处理过。 这很有必要,当参数来自于最终用户时,参数中可能隐含的恶意 JavaScript 代码会导致 -[跨站脚本(XSS)攻击](http://en.wikipedia.org/wiki/Cross-site_scripting)。 +[跨站脚本(XSS)攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。 当然了,你大概会在 `say` 视图里放入更多内容。内容可以由 HTML 标签,纯文本, 甚至 PHP 语句组成。实际上 `say` 视图就是一个由 [[yii\web\Controller::render()|render()]] 执行的 PHP 脚本。 diff --git a/docs/guide-zh-CN/start-installation.md b/docs/guide-zh-CN/start-installation.md index 4144f8e2de5..c505cfdf3a3 100644 --- a/docs/guide-zh-CN/start-installation.md +++ b/docs/guide-zh-CN/start-installation.md @@ -85,7 +85,7 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic 通过归档文件安装 Yii 包括三个步骤: -1. 从 [yiiframework.com](http://www.yiiframework.com/download/) 下载归档文件。 +1. 从 [yiiframework.com](https://www.yiiframework.com/download/) 下载归档文件。 2. 将下载的文件解压缩到 Web 访问的文件夹中。 3. 修改 `config/web.php` 文件,给 `cookieValidationKey` 配置项 添加一个密钥(若你通过 Composer 安装,则此步骤会自动完成): @@ -114,9 +114,9 @@ composer create-project --prefer-dist yiisoft/yii2-app-basic basic 安装 Assets ----------- -Yii依靠 [Bower](http://bower.io/) 和/或 [NPM](https://www.npmjs.org/) 软件包来安装 asset(CSS 和 JavaScript)库。 +Yii依靠 [Bower](http://bower.io/) 和/或 [NPM](https://www.npmjs.com/) 软件包来安装 asset(CSS 和 JavaScript)库。 它使用Composer来获取这些库,允许 PHP 和 CSS/JavaScript 包版本同时解析。 -这可以通过使用 [asset-packagist.org](https://asset-packagist.org) 或 [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) 来实现。 +这可以通过使用 [asset-packagist.org](https://asset-packagist.org) 或 [composer asset plugin](https://github.com/fxpio/composer-asset-plugin) 来实现。 有关更多详细信息,请参阅 [Assets 文档](structure-assets.md)。 您可能希望通过本地 Bower/NPM 客户端管理您的 assets,使用 CDN 或完全避免 assets 的安装。 @@ -139,7 +139,7 @@ Yii依靠 [Bower](http://bower.io/) 和/或 [NPM](https://www.npmjs.org/) 软件 ------------ 当安装完成之后, -或配置你的Web服务器(看下面的文章)或使用[内置Web Server](https://secure.php.net/manual/en/features.commandline.webserver.php), +或配置你的Web服务器(看下面的文章)或使用[内置Web Server](https://www.php.net/manual/en/features.commandline.webserver.php), 当在项目 `web` 目录下可以通过下面的命令: ```bash @@ -173,7 +173,7 @@ http://localhost:8080/ ``` 你需要配置好 PHP 安装环境,使其符合 Yii 的最小需求。主要是需要 PHP 5.4 或 以上版本。 -如果应用需要用到数据库,那还要安装 [PDO PHP 扩展](https://secure.php.net/manual/zh/pdo.installation.php) +如果应用需要用到数据库,那还要安装 [PDO PHP 扩展](https://www.php.net/manual/zh/pdo.installation.php) 和相应的数据库驱动(例如访问 MySQL 数据库所需的 `pdo_mysql`)。 @@ -234,7 +234,7 @@ DocumentRoot "path/to/basic/web" ### 推荐使用的 Nginx 配置 -为了使用 [Nginx](http://wiki.nginx.org/),你应该已经将 PHP 安装为 [FPM SAPI](https://secure.php.net/install.fpm) 了。 +为了使用 [Nginx](http://wiki.nginx.org/),你应该已经将 PHP 安装为 [FPM SAPI](https://www.php.net/install.fpm) 了。 你可以使用如下 Nginx 配置,将 `path/to/basic/web` 替换为实际的 `basic/web` 目录, `mysite.local` 替换为实际的主机名以提供服务。 diff --git a/docs/guide-zh-CN/start-looking-ahead.md b/docs/guide-zh-CN/start-looking-ahead.md index 02bbb6c8460..c8b1b1550b1 100644 --- a/docs/guide-zh-CN/start-looking-ahead.md +++ b/docs/guide-zh-CN/start-looking-ahead.md @@ -22,15 +22,15 @@ 但它们往往覆盖了更广泛的话题,并常常提供解决方案, 所以它们也很有用。 - 书籍 -* [扩展](http://www.yiiframework.com/extensions/):Yii 拥有数以千计用户提供的扩展,这些扩展能非常方便的插入到应用中, +* [扩展](https://www.yiiframework.com/extensions/):Yii 拥有数以千计用户提供的扩展,这些扩展能非常方便的插入到应用中, 使你的应用开发过程更加方便快捷。 * 社区 - - 官方论坛: - - IRC 聊天室:Freenode 网络上的 #yii 频道 () + - 官方论坛: + - IRC 聊天室:Libera 网络上的 #yii 频道 () - Slack chanel: - Gitter chat: - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide-zh-CN/start-prerequisites.md b/docs/guide-zh-CN/start-prerequisites.md index 3a7368b1b96..9ed6a5f9ad9 100644 --- a/docs/guide-zh-CN/start-prerequisites.md +++ b/docs/guide-zh-CN/start-prerequisites.md @@ -4,8 +4,8 @@ Yii 的学习曲线并不像其他 PHP 框架那样陡峭,但仍然需要一 ## PHP -Yii 是一个 PHP 框架,因此请确保您 [阅读并理解语言参考](https://secure.php.net/manual/zh/langref.php)。 -用 Yii 进行开发时,您将以面向对象的方式编写代码,因此请确保您熟悉[类与对象](https://secure.php.net/manual/en/language.oop5.basic.php)以及[命名空间](https://secure.php.net/manual/en/language.namespaces.php)。 +Yii 是一个 PHP 框架,因此请确保您 [阅读并理解语言参考](https://www.php.net/manual/zh/langref.php)。 +用 Yii 进行开发时,您将以面向对象的方式编写代码,因此请确保您熟悉[类与对象](https://www.php.net/manual/en/language.oop5.basic.php)以及[命名空间](https://www.php.net/manual/en/language.namespaces.php)。 ## 面向对象编程(Object oriented programming) diff --git a/docs/guide-zh-CN/start-workflow.md b/docs/guide-zh-CN/start-workflow.md index fc3628dceef..2ba8d445c24 100644 --- a/docs/guide-zh-CN/start-workflow.md +++ b/docs/guide-zh-CN/start-workflow.md @@ -42,7 +42,7 @@ 应用中最重要的目录和文件(假设应用根目录是 `basic`): -``` +```js basic/ 应用根目录 composer.json Composer 配置文件, 描述包信息 config/ 包含应用配置及其它配置 diff --git a/docs/guide-zh-CN/structure-applications.md b/docs/guide-zh-CN/structure-applications.md index 2f56ec24acd..3fa407b4535 100644 --- a/docs/guide-zh-CN/structure-applications.md +++ b/docs/guide-zh-CN/structure-applications.md @@ -356,7 +356,7 @@ $width = \Yii::$app->params['thumbnail.size'][0]; #### [[yii\base\Application::timeZone|timeZone]] 该属性提供一种方式修改 PHP 运行环境中的默认时区,配置该属性本质上就是调用 PHP 函数 -[date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php), +[date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php), 例如: ```php diff --git a/docs/guide-zh-CN/structure-assets.md b/docs/guide-zh-CN/structure-assets.md index 822bebd2779..e7bf7e091be 100644 --- a/docs/guide-zh-CN/structure-assets.md +++ b/docs/guide-zh-CN/structure-assets.md @@ -201,13 +201,13 @@ class FontAwesomeAsset extends AssetBundle } ``` -上述的代码为 ["fontawesome" package](http://fontawesome.io/) 定义了资源包。 +上述的代码为 ["fontawesome" package](https://fontawesome.com/) 定义了资源包。 通过配置发布选项的 only 下标,只有 `fonts` 和 `css` 子目录会发布。 ### Bower 和 NPM 资源安装 -大多数 JavaScript/CSS 包使用 [Bower](http://bower.io/) 或 [NPM](https://www.npmjs.org/) 来管理。 +大多数 JavaScript/CSS 包使用 [Bower](http://bower.io/) 或 [NPM](https://www.npmjs.com/) 来管理。 在 PHP 中,我们用 Composer 来管理 PHP 依赖。像 PHP 包一样, 也可以使用 `composer.json` 管理 Bower 和 NPM 包。 @@ -257,7 +257,7 @@ $config = [ composer global require "fxp/composer-asset-plugin:^1.4.1" ``` -这个命令会全局安装 [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) 插件, +这个命令会全局安装 [composer asset plugin](https://github.com/fxpio/composer-asset-plugin) 插件, 以便使用 Composer 来管理对 Bower 和 NPM 包的依赖。 在这个插件安装后, 你计算机上的每个项目都可以通过 `composer.json` 来管理 Bower 和 NPM 包。 @@ -608,14 +608,14 @@ class AppAsset extends AssetBundle Yii 使用文件扩展名来表示资源使用哪种扩展语法, 默认可以识别如下语法和文件扩展名: -- [LESS](http://lesscss.org/):`.less` -- [SCSS](http://sass-lang.com/):`.scss` -- [Stylus](http://learnboost.github.io/stylus/):`.styl` -- [CoffeeScript](http://coffeescript.org/):`.coffee` -- [TypeScript](http://www.typescriptlang.org/):`.ts` +- [LESS](https://lesscss.org/):`.less` +- [SCSS](https://sass-lang.com/):`.scss` +- [Stylus](https://stylus-lang.com/):`.styl` +- [CoffeeScript](https://coffeescript.org/):`.coffee` +- [TypeScript](https://www.typescriptlang.org/):`.ts` Yii 依靠安装的预处理工具来转换资源,例如, -为使用 [LESS](http://lesscss.org/),应安装 `lessc` 预处理命令。 +为使用 [LESS](https://lesscss.org/),应安装 `lessc` 预处理命令。 可配置 [[yii\web\AssetManager::converter]] 自定义预处理命令和支持的扩展语法, 如下所示: diff --git a/docs/guide-zh-CN/structure-entry-scripts.md b/docs/guide-zh-CN/structure-entry-scripts.md index 4ed6adb77e0..d89c98809c4 100644 --- a/docs/guide-zh-CN/structure-entry-scripts.md +++ b/docs/guide-zh-CN/structure-entry-scripts.md @@ -57,9 +57,9 @@ $config = require __DIR__ . '/../config/web.php'; /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide-zh-CN/structure-extensions.md b/docs/guide-zh-CN/structure-extensions.md index dfae19aea69..f80e6466c00 100644 --- a/docs/guide-zh-CN/structure-extensions.md +++ b/docs/guide-zh-CN/structure-extensions.md @@ -75,7 +75,7 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) 2. 如果有,则安装扩展提供的自动加载器。 3. 按指导说明下载和安装所有依赖的扩展。 -如果扩展没有提供类的自动加载器,但也遵循了 [PSR-4 standard](http://www.php-fig.org/psr/psr-4/) +如果扩展没有提供类的自动加载器,但也遵循了 [PSR-4 standard](https://www.php-fig.org/psr/psr-4/) 标准,那么你可以使用 Yii 提供的类自动加载器来加载扩展类。 你需要做的仅仅是为扩展的根目录声明一个 [root alias](concept-aliases.md#defining-aliases)。 例如,假设在 `vendor/mycompany/myext` 目录中安装了一个扩展,并且扩展类的命名空间为 `myext` , @@ -127,9 +127,9 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) "license": "BSD-3-Clause", "support": { "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki/", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "authors": [ @@ -184,8 +184,8 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) 确定你也为每一个依赖的包列出了适当的版本约束条件 (比如 `1.*`, `@stable`) 。 当你发布一个稳定版本时,你所依赖的包也应当使用稳定版本。 -大多数 JavaScript/CSS 包是用 [Bower](http://bower.io/) 来管理的,而非 Composer。你可使用 -[Composer asset 插件](https://github.com/francoispluchino/composer-asset-plugin) 使之可以 +大多数 JavaScript/CSS 包是用 [Bower](https://bower.io/) 来管理的,而非 Composer。你可使用 +[Composer asset 插件](https://github.com/fxpio/composer-asset-plugin) 使之可以 通过 Composer 来管理这类包。如果你的扩展依赖 Bower 软件包,你可以如下例所示那样简单地 在 `composer.json` 文件的依赖中列出它。 @@ -240,8 +240,8 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120) #### 命名空间 为避免冲突以及使你的扩展中的类能被自动加载,你的类应当使用命名空间, -并使类的命名符合 [PSR-4 standard](http://www.php-fig.org/psr/psr-4/) 或者 -[PSR-0 standard](http://www.php-fig.org/psr/psr-0/) 标准。 +并使类的命名符合 [PSR-4 standard](https://www.php-fig.org/psr/psr-4/) 或者 +[PSR-0 standard](https://www.php-fig.org/psr/psr-0/) 标准。 你的类的命名空间应以 `vendorName\extensionName` 起始,其中 `extensionName` 和项目名相同,除了它没有 `yii2-` 前缀外。例如,对 `yiisoft/yii2-imagine` 扩展 @@ -351,7 +351,7 @@ Yii 提供了测试支持,使你更容易写单元测试、验收测试和功 #### 版本控制 你应该为每一个扩展定一个版本号(如 `1.0.1`)。我们推荐你命名版本号时参照 -[semantic versioning](http://semver.org) 决定用什么样的版本号。 +[semantic versioning](https://semver.org) 决定用什么样的版本号。 #### 发布 @@ -367,7 +367,7 @@ Yii 提供了测试支持,使你更容易写单元测试、验收测试和功 帮助其他人了解和使用你的扩展: * 根目录下的 readme 文件:它描述你的扩展是干什么的以及如何安装和使用。 - 我们推荐你用 [Markdown](http://daringfireball.net/projects/markdown/) 的格式 + 我们推荐你用 [Markdown](https://daringfireball.net/projects/markdown/) 的格式 来写并将文件命名为 `readme.md`。 * 根目录下的修改日志文件:它列举每个版本的发布做了哪些更改。该文件可以用 Markdown 根式 编写并命名为 `changelog.md`。 @@ -383,7 +383,7 @@ Yii 提供了测试支持,使你更容易写单元测试、验收测试和功 代码注释生成漂亮的 API 文档。 > Info: 虽然不做要求,我们还是建议你的扩展遵循某个编码规范。 - 你可以参照 [core framework code style](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style)。 + 你可以参照 [core framework code style](https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md)。 ## 核心扩展 @@ -398,15 +398,13 @@ Yii 提供了下列核心扩展,由 Yii 开发团队开发和维护。这些 - [yiisoft/yii2-authclient](https://github.com/yiisoft/yii2-authclient): 提供了一套常用的认证客户端,例如 Facebook OAuth2 客户端、GitHub OAuth2 客户端。 - [yiisoft/yii2-bootstrap](https://github.com/yiisoft/yii2-bootstrap): - 提供了一套挂件,封装了 [Bootstrap](http://getbootstrap.com/) 的组件和插件。 -- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception): - 提供了基于 [Codeception](http://codeception.com/) 的测试支持。 + 提供了一套挂件,封装了 [Bootstrap](https://getbootstrap.com/) 的组件和插件。 - [yiisoft/yii2-debug](https://github.com/yiisoft/yii2-debug): 提供了对 Yii 应用的调试支持。当使用该扩展是, 在每个页面的底部将显示一个调试工具条。 该扩展还提供了一个独立的页面,以显示更详细的调试信息。 - [yiisoft/yii2-elasticsearch](https://github.com/yiisoft/yii2-elasticsearch): - 提供对 [Elasticsearch](http://www.elasticsearch.org/) 的使用支持。它包含基本的查询/搜索支持, + 提供对 [Elasticsearch](https://www.elastic.co/) 的使用支持。它包含基本的查询/搜索支持, 并实现了 [Active Record](db-active-record.md) 模式让你可以将活动记录 存储在 Elasticsearch 中。 - [yiisoft/yii2-faker](https://github.com/yiisoft/yii2-faker): @@ -417,29 +415,29 @@ Yii 提供了下列核心扩展,由 Yii 开发团队开发和维护。这些 - [yiisoft/yii2-httpclient](https://github.com/yiisoft/yii2-httpclient): 提供 HTTP 客户端。 - [yiisoft/yii2-imagine](https://github.com/yiisoft/yii2-imagine): - 提供了基于 [Imagine](http://imagine.readthedocs.org/) 的常用图像处理功能。 + 提供了基于 [Imagine](https://imagine.readthedocs.org/) 的常用图像处理功能。 - [yiisoft/yii2-jui](https://github.com/yiisoft/yii2-jui): - 提供了一套封装 [JQuery UI](http://jqueryui.com/) 的挂件以及它们的交互。 + 提供了一套封装 [JQuery UI](https://jqueryui.com/) 的挂件以及它们的交互。 - [yiisoft/yii2-mongodb](https://github.com/yiisoft/yii2-mongodb): - 提供了对 [MongoDB](http://www.mongodb.org/) 的使用支持。它包含基本 + 提供了对 [MongoDB](https://www.mongodb.com/) 的使用支持。它包含基本 的查询、活动记录、数据迁移、缓存、代码生成等特性。 - [yiisoft/yii2-queue](https://www.yiiframework.com/extension/yiisoft/yii2-queue): 通过队列异步提供运行任务的支持。 它支持基于 DB,Redis,RabbitMQ,AMQP,Beanstalk 和 Gearman 的队列。 - [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis): - 提供了对 [redis](http://redis.io/) 的使用支持。它包含基本的 + 提供了对 [redis](https://redis.io/) 的使用支持。它包含基本的 查询、活动记录、缓存等特性。 - [yiisoft/yii2-shell](https://www.yiiframework.com/extension/yiisoft/yii2-shell): - 提供基于 [psysh](http://psysh.org/) 的交互式 shell。 + 提供基于 [psysh](https://psysh.org/) 的交互式 shell。 - [yiisoft/yii2-smarty](https://github.com/yiisoft/yii2-smarty): - 提供了一个基于 [Smarty](http://www.smarty.net/) 的模板引擎。 + 提供了一个基于 [Smarty](https://www.smarty.net/) 的模板引擎。 - [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx): - 提供了对 [Sphinx](http://sphinxsearch.com) 的使用支持。它包含基本的 + 提供了对 [Sphinx](https://sphinxsearch.com) 的使用支持。它包含基本的 查询、活动记录、代码生成等特性。 - [yiisoft/yii2-swiftmailer](https://github.com/yiisoft/yii2-swiftmailer): 提供了基于 [swiftmailer](http://swiftmailer.org/) 的邮件发送功能。 - [yiisoft/yii2-twig](https://github.com/yiisoft/yii2-twig): - 提供了一个基于 [Twig](http://twig.sensiolabs.org/) 的模板引擎。 + 提供了一个基于 [Twig](https://twig.symfony.com/) 的模板引擎。 以下官方扩展适用于 Yii 2.1 及以上版本。 您不需要为 Yii 2.0 安装它们,因为它们包含在核心框架中。 @@ -449,7 +447,7 @@ Yii 提供了下列核心扩展,由 Yii 开发团队开发和维护。这些 - [yiisoft/yii2-jquery](https://www.yiiframework.com/extension/yiisoft/yii2-jquery): 为 [jQuery](https://jquery.com/) 提供支持。 - [yiisoft/yii2-maskedinput](https://www.yiiframework.com/extension/yiisoft/yii2-maskedinput): - 提供基于 [jQuery Input Mask plugin](http://robinherbots.github.io/Inputmask/) 的格式化输入小部件。 + 提供基于 [jQuery Input Mask plugin](https://robinherbots.github.io/Inputmask/) 的格式化输入小部件。 - [yiisoft/yii2-mssql](https://www.yiiframework.com/extension/yiisoft/yii2-mssql): 提供对使用 [MSSQL](https://www.microsoft.com/sql-server/) 的支持。 - [yiisoft/yii2-oracle](https://www.yiiframework.com/extension/yiisoft/yii2-oracle): diff --git a/docs/guide-zh-CN/structure-filters.md b/docs/guide-zh-CN/structure-filters.md index 3fc25ea7a92..58ed3a58727 100644 --- a/docs/guide-zh-CN/structure-filters.md +++ b/docs/guide-zh-CN/structure-filters.md @@ -121,7 +121,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['create', 'update'], 'rules' => [ // 允许认证用户 @@ -157,7 +157,7 @@ public function behaviors() { return [ 'basicAuth' => [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ], ]; } @@ -183,7 +183,7 @@ public function behaviors() { return [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -210,7 +210,7 @@ use yii\web\Response; [ 'bootstrap' => [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -241,7 +241,7 @@ public function behaviors() { return [ [ - 'class' => HttpCache::className(), + 'class' => HttpCache::class, 'only' => ['index'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); @@ -269,11 +269,11 @@ public function behaviors() { return [ 'pageCache' => [ - 'class' => PageCache::className(), + 'class' => PageCache::class, 'only' => ['index'], 'duration' => 60, 'dependency' => [ - 'class' => DbDependency::className(), + 'class' => DbDependency::class, 'sql' => 'SELECT COUNT(*) FROM post', ], 'variations' => [ @@ -307,7 +307,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'index' => ['get'], 'view' => ['get'], @@ -339,7 +339,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, ], ], parent::behaviors()); } @@ -366,7 +366,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], @@ -387,7 +387,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], diff --git a/docs/guide-zh-CN/structure-models.md b/docs/guide-zh-CN/structure-models.md index bdded5ecb81..1309d973458 100644 --- a/docs/guide-zh-CN/structure-models.md +++ b/docs/guide-zh-CN/structure-models.md @@ -37,8 +37,8 @@ echo $model->name; ``` 也可像访问数组单元项一样访问属性,这要感谢[[yii\base\Model]]支持 -[ArrayAccess 数组访问](https://secure.php.net/manual/en/class.arrayaccess.php) -和 [ArrayIterator 数组迭代器](https://secure.php.net/manual/en/class.arrayiterator.php): +[ArrayAccess 数组访问](https://www.php.net/manual/en/class.arrayaccess.php) +和 [ArrayIterator 数组迭代器](https://www.php.net/manual/en/class.arrayiterator.php): ```php $model = new \app\models\ContactForm; diff --git a/docs/guide-zh-CN/structure-modules.md b/docs/guide-zh-CN/structure-modules.md index 7c245fb873c..25c4d575c03 100644 --- a/docs/guide-zh-CN/structure-modules.md +++ b/docs/guide-zh-CN/structure-modules.md @@ -14,7 +14,7 @@ 在该目录中有子目录如 `controllers`,`models`,`views` 分别为对应控制器,模型,视图和其他代码,和应用非常类似。 如下例子显示一个模型的目录结构: -``` +```js forum/ Module.php 模块类文件 controllers/ 包含控制器类文件 diff --git a/docs/guide-zh-CN/structure-overview.md b/docs/guide-zh-CN/structure-overview.md index 7401f16e5db..186659cfd49 100644 --- a/docs/guide-zh-CN/structure-overview.md +++ b/docs/guide-zh-CN/structure-overview.md @@ -1,7 +1,7 @@ 总览 ======== -Yii 应用参照[模型-视图-控制器 (MVC)](http://wikipedia.org/wiki/Model-view-controller) +Yii 应用参照[模型-视图-控制器 (MVC)](https://wikipedia.org/wiki/Model-view-controller) 设计模式来组织。 [模型](structure-models.md)代表数据、业务逻辑和规则; [视图](structure-views.md)展示模型的输出;[控制器](structure-controllers.md) 接受出入并将其转换为[模型](structure-models.md)和[视图](structure-views.md)命令。 diff --git a/docs/guide-zh-CN/structure-views.md b/docs/guide-zh-CN/structure-views.md index eb161e30e5c..7f6fa3d8998 100644 --- a/docs/guide-zh-CN/structure-views.md +++ b/docs/guide-zh-CN/structure-views.md @@ -1,7 +1,7 @@ 视图 ===== -视图是 [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) 模式中的一部分。 +视图是 [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) 模式中的一部分。 它是展示数据到终端用户的代码,在网页应用中, 根据*视图模板*来创建视图,视图模板为PHP脚本文件, 主要包含HTML代码和展示类PHP代码,通过[[yii\web\View|view]]应用组件来管理, @@ -52,7 +52,7 @@ $this->title = 'Login'; 当创建生成HTML页面的视图时,在显示之前将用户输入数据进行转码和过滤非常重要, 否则,你的应用可能会被 -[跨站脚本](http://en.wikipedia.org/wiki/Cross-site_scripting) 攻击。 +[跨站脚本](https://en.wikipedia.org/wiki/Cross-site_scripting) 攻击。 要显示纯文本,先调用 [[yii\helpers\Html::encode()]] 进行转码, 例如如下代码将用户名在显示前先转码: @@ -545,7 +545,7 @@ class PostController extends Controller - [客户脚本处理](output-client-scripts.md): 支持CSS 和 JavaScript 注册和渲染; - [资源包处理](structure-assets.md): 支持 [资源包](structure-assets.md)的注册和渲染; - [模板引擎](tutorial-template-engines.md): 允许你使用其他模板引擎,如 - [Twig](http://twig.sensiolabs.org/), [Smarty](http://www.smarty.net/)。 + [Twig](https://twig.symfony.com/), [Smarty](https://www.smarty.net/)。 开发Web页面时,也可能频繁使用以下实用的小特性。 @@ -616,14 +616,14 @@ $this->registerLinkTag([ 'title' => 'Live News for Yii', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` 上述代码会转换成 ```html - + ``` 和 [[yii\web\View::registerMetaTag()|registerMetaTags()]] 类似, diff --git a/docs/guide-zh-CN/structure-widgets.md b/docs/guide-zh-CN/structure-widgets.md index 606b0416b95..79cc680c6de 100644 --- a/docs/guide-zh-CN/structure-widgets.md +++ b/docs/guide-zh-CN/structure-widgets.md @@ -67,7 +67,7 @@ use yii\helpers\Html; 注意和调用 [[yii\base\Widget::widget()]] 返回渲染结果不同, 调用 [[yii\base\Widget::begin()]] 方法返回一个可组建小部件内容的小部件实例。 -> Note: 当调用 [[yii\base\Widget::end()]] 的时候,一些小部件将使用 [输出缓冲](https://secure.php.net/manual/en/book.outcontrol.php) +> Note: 当调用 [[yii\base\Widget::end()]] 的时候,一些小部件将使用 [输出缓冲](https://www.php.net/manual/en/book.outcontrol.php) > 来调整封闭的内容。因此,当调用 [[yii\base\Widget::begin()]] 和 > [[yii\base\Widget::end()]] 时,最好在同一个视图文件里。 > 不遵循这个规则可能会导致意外的输出。 diff --git a/docs/guide-zh-CN/test-acceptance.md b/docs/guide-zh-CN/test-acceptance.md index bd6092340c1..c7ee7eea984 100644 --- a/docs/guide-zh-CN/test-acceptance.md +++ b/docs/guide-zh-CN/test-acceptance.md @@ -6,8 +6,8 @@ 验证测试是在 Codeception 框架的帮助下实现的,该框架有一个很好的文档: -- [Codeception for Yii framework](http://codeception.com/for/yii) -- [Codeception Acceptance Tests](http://codeception.com/docs/03-AcceptanceTests) +- [Codeception for Yii framework](https://codeception.com/for/yii) +- [Codeception Acceptance Tests](https://codeception.com/docs/03-AcceptanceTests) ## 运行基本和高级模板测试 diff --git a/docs/guide-zh-CN/test-fixtures.md b/docs/guide-zh-CN/test-fixtures.md index b89d5472a3c..edaf5fb7710 100644 --- a/docs/guide-zh-CN/test-fixtures.md +++ b/docs/guide-zh-CN/test-fixtures.md @@ -130,7 +130,7 @@ class UserProfileTest extends \Codeception\Test\Unit { return [ 'profiles' => [ - 'class' => UserProfileFixture::className(), + 'class' => UserProfileFixture::class, // fixture data located in tests/_data/user.php 'dataFile' => codecept_data_dir() . 'user.php' ], diff --git a/docs/guide-zh-CN/tutorial-core-validators.md b/docs/guide-zh-CN/tutorial-core-validators.md index 294d15ee695..91e684c32bf 100644 --- a/docs/guide-zh-CN/tutorial-core-validators.md +++ b/docs/guide-zh-CN/tutorial-core-validators.md @@ -139,9 +139,9 @@ public function rules() [[yii\validators\DateValidator::timestampAttribute|timestampAttribute]] 所指定的属性里。 - `format`:被验证值的日期/时间格式。 - 这里的值可以是 [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax) 中定义的日期时间格式。 + 这里的值可以是 [ICU manual](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax) 中定义的日期时间格式。 另外还可以设置以 `php:` 开头的字符串,用来表示PHP可以识别的日期时间格式。 - `Datetime` 日期时间类。请参考 获取更多支持的格式。 + `Datetime` 日期时间类。请参考 获取更多支持的格式。 如果没有设置,默认值将使用 `Yii::$app->formatter->dateFormat` 中的值。 请参考 [[yii\validators\DateValidator::$format|API 文档]] 以获取更详细的说明。 @@ -341,7 +341,7 @@ function foo($model, $attribute) { MIME 的字符串 (如 "image/jpeg, image/png")。 Mime 类型名是大小写不敏感的。默认为 null, 意味着所有 MIME 类型都被接受。 - 请参考 [common media types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types) 获取更多详细内容。 + 请参考 [common media types](https://en.wikipedia.org/wiki/Media_type) 获取更多详细内容。 - `minSize`:上传文件所需最少多少 Byte 的大小。默认为 null,代表没有下限。 - `maxSize`:上传文件所需最多多少 Byte 的大小。默认为 null,代表没有上限。 - `maxFiles`:给定属性最多能承载多少个文件。 @@ -389,8 +389,8 @@ function foo($model, $attribute) { > Tip: 如果你只是想要用 trim 处理下输入值,你可以直接用 [trim](#trim) 验证器的。 > Tip: 有许多的PHP方法结构和 `filter` 需要的结构一致。 -> 比如使用类型转换方法 ([intval](https://secure.php.net/manual/en/function.intval.php), -> [boolval](https://secure.php.net/manual/en/function.boolval.php), ...) 来确保属性为指定的类型, +> 比如使用类型转换方法 ([intval](https://www.php.net/manual/en/function.intval.php), +> [boolval](https://www.php.net/manual/en/function.boolval.php), ...) 来确保属性为指定的类型, > 你可以简单的设置这些方法名而不是重新定义一个匿名函数: > > ```php diff --git a/docs/guide-zh-CN/tutorial-docker.md b/docs/guide-zh-CN/tutorial-docker.md index e4fb89a9819..98caa80f9f3 100644 --- a/docs/guide-zh-CN/tutorial-docker.md +++ b/docs/guide-zh-CN/tutorial-docker.md @@ -5,14 +5,14 @@ Yii 和 Docker 容器可以解决许多问题,例如在开发人员计算机和服务器上具有相同的软件版本,在开发时快速部署或模拟多服务器体系结构。 -您可以在 [docker.com](https://www.docker.com/what-docker) 上阅读有关Docker容器的更多信息。 +您可以在 [docker.com](https://www.docker.com/why-docker) 上阅读有关Docker容器的更多信息。 ## 要求 - `docker` - `docker-compose` -访问[下载页面](https://www.docker.com/community-edition)获取 Docker 工具。 +访问[下载页面](https://www.docker.com/products/container-runtime)获取 Docker 工具。 ## 安装 diff --git a/docs/guide-zh-CN/tutorial-i18n.md b/docs/guide-zh-CN/tutorial-i18n.md index ec17c2136e8..16ea7e12534 100644 --- a/docs/guide-zh-CN/tutorial-i18n.md +++ b/docs/guide-zh-CN/tutorial-i18n.md @@ -22,7 +22,7 @@ Yii 提供的国际化功能支持全方位信息翻译, [ISO-639](http://www.loc.gov/standards/iso639-2/) 和 `CC` 是两个字母的国别代码 [ISO-3166](http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html)。 有关区域设置的更多细节可以看 -[ICU 项目文档](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept)。 +[ICU 项目文档](https://unicode-org.github.io/icu/userguide/locale/#the-locale-concept)。 ### 语言(Language) @@ -231,7 +231,7 @@ $price = 100; echo \Yii::t('app', 'Price: {0, number, currency}', $price); ``` -> Note: 参数的格式化需要安装 [intl PHP 扩展](https://secure.php.net/manual/en/intro.intl.php)。 +> Note: 参数的格式化需要安装 [intl PHP 扩展](https://www.php.net/manual/en/intro.intl.php)。 可以使用缩写的形式或完整的形式来格式化占位符: @@ -246,7 +246,7 @@ full form: {PlaceholderName, ParameterType, ParameterStyle} echo Yii::t('app', "Example of string with ''-escaped characters'': '{' '}' '{test}' {count,plural,other{''count'' value is # '#{}'}}", ['count' => 3]); ``` -请参阅 [ICU 文档](http://icu-project.org/apiref/icu4c/classMessageFormat.html) +请参阅 [ICU 文档](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classMessageFormat.html) 关于如何指定这样的占位符的说明。接下来我们会展示一些常用的使用方法。 @@ -274,7 +274,7 @@ echo \Yii::t('app', 'Balance: {0, number, ,000,000000}', $sum); ``` 自定义格式中使用的字符可以在“特殊模式字符”一节的 -[ICU API 参考](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html) +[ICU API 参考](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classDecimalFormat.html) 中找到。 @@ -302,7 +302,7 @@ echo \Yii::t('app', 'Today is {0, date, short}', time()); echo \Yii::t('app', 'Today is {0, date, yyyy-MM-dd}', time()); ``` -[格式化参考](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details)。 +[格式化参考](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details)。 #### 时间(Time) @@ -325,7 +325,7 @@ echo \Yii::t('app', 'It is {0, time, short}', time()); echo \Yii::t('app', 'It is {0, date, HH:mm}', time()); ``` -[格式化参考](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details)。 +[格式化参考](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details)。 #### 拼写(Spellout) @@ -347,7 +347,7 @@ echo \Yii::t('app', 'I am {n,spellout,%spellout-ordinal} agent', ['n' => 47]); 请注意,在 `spellout,` 之后和 `%` 之前不应该有空格。 要获取可用于您正在使用的语言环境的选项列表,请查看 -[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) 上的“编号模式,拼写”。 +[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) 上的“编号模式,拼写”。 #### 序数词(Ordinal) @@ -368,7 +368,7 @@ echo \Yii::t('app', '{n,ordinal,%digits-ordinal-feminine}', ['n' => 471]); 请注意,在 `ordinal,` 之后和 `%` 之前不应该有空格。 要获取可用于您正在使用的语言环境的选项列表,请查看 -[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) 上的“编号模式,序号”。 +[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) 上的“编号模式,序号”。 #### 持续时间(Duration) @@ -389,7 +389,7 @@ echo \Yii::t('app', '{n,duration,%in-numerals}', ['n' => 471227]); 请注意,在 `duration,` 之后和 `%` 之前不应该有空格。 要获取您正在使用的区域设置的可用选项列表,请查看 -[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) 上的“编号模式,持续时间”。 +[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) 上的“编号模式,持续时间”。 #### 复数(Plural) @@ -441,7 +441,7 @@ echo Yii::t('app', 'You {likeCount,plural, // You and one other person liked this ``` -#### 序数选择(Ordinal selection) +#### 序数选择(Ordinal selection) `selectordinal` 的参数类型旨在为您所翻译的语言环境选择一个基于语序规则的字符串: 一个基于语序规则的字符串: @@ -460,8 +460,8 @@ echo Yii::t('app', 'You are the {n,selectordinal,one{#st} two{#nd} few{#rd} othe ``` 格式与复数使用的格式非常接近。 要了解您应为特定语言环境指定哪些参数,请参阅 -[http://intl.rmcreative.ru/](http://intl.rmcreative.ru/) 上的“复数规则,序数”。 -或者,您可以参考 [unicode.org上的规则参考](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)。 +[https://intl.rmcreative.ru/](https://intl.rmcreative.ru/) 上的“复数规则,序数”。 +或者,您可以参考 [unicode.org上的规则参考](https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html)。 #### 选择(Selection) @@ -738,13 +738,13 @@ class TranslationEventHandler ## 设置 PHP 环境(Setting Up PHP Environment) -Yii 使用 [PHP intl 扩展](https://secure.php.net/manual/en/book.intl.php) 来提供大多数 I18N 的功能, +Yii 使用 [PHP intl 扩展](https://www.php.net/manual/en/book.intl.php) 来提供大多数 I18N 的功能, 如日期和数字格式的 [[yii\i18n\Formatter]] 类和消息格式的 [[yii\i18n\MessageFormatter]] 类。 当 `intl` 扩展没有安装时,两者会提供一个回调机制。然而,该回调机制只适用于目标语言是英语的情况下。 因此,当 I18N 对你来说必不可少时,强烈建议你安装 `intl`。 -[PHP intl 扩展](https://secure.php.net/manual/en/book.intl.php) 是基于对于所有不同的语言环境 -提供格式化规则的 [ICU库](http://site.icu-project.org/)。 +[PHP intl 扩展](https://www.php.net/manual/en/book.intl.php) 是基于对于所有不同的语言环境 +提供格式化规则的 [ICU库](https://icu.unicode.org/)。 不同版本的 ICU 中可能会产生不同日期和数值格式的结果。 为了确保你的网站在所有环境产生相同的结果, 建议你安装与 `intl` 扩展相同的版本(和 ICU 同一版本)。 @@ -760,10 +760,10 @@ echo "ICU Data: " . INTL_ICU_DATA_VERSION . "\n"; 此外,还建议你所使用的 ICU 版本应等于或大于 49 的版本。这确保了可以使用本文档描述的所有功能。例如, 低于 49 版本的 ICU 不支持使用 `#` 占位符来实现复数规则。 -请参阅 获取可用 ICU 版本的完整列表。 +请参阅 获取可用 ICU 版本的完整列表。 注意,版本编号在 4.8 之后发生了变化(如 ICU4.8,ICU49,50 ICU 等)。 另外,ICU 库中时区数据库的信息可能过时。要更新时区数据库时详情请参阅 -[ICU 手册](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data) 。 +[ICU 手册](https://unicode-org.github.io/icu/userguide/datetime/timezone/#updating-the-time-zone-data) 。 而对于 ICU 输出格式使用的时区数据库,PHP 用的时区数据库可能跟它有关。 你可以通过安装 [pecl package `timezonedb`](https://pecl.php.net/package/timezonedb) 的最新版本来更新它。 diff --git a/docs/guide-zh-CN/tutorial-performance-tuning.md b/docs/guide-zh-CN/tutorial-performance-tuning.md index 76849debff7..559270dd7a3 100644 --- a/docs/guide-zh-CN/tutorial-performance-tuning.md +++ b/docs/guide-zh-CN/tutorial-performance-tuning.md @@ -11,8 +11,8 @@ 一个好的 PHP 环境是非常重要的。为了得到最大的性能, - 使用最新稳定版本的 PHP。 PHP 的主要版本可能带来显著的性能提升。 -- 启用字节码缓存 [Opcache](https://secure.php.net/opcache)(PHP 5.5或更高版本) - 或 [APC](https://secure.php.net/apc) +- 启用字节码缓存 [Opcache](https://www.php.net/opcache)(PHP 5.5或更高版本) + 或 [APC](https://www.php.net/manual/en/book.apcu.php) (PHP 5.4或更早版本)。字节码缓存省去了每次解析和加载 PHP 脚本所带来的开销。 - [Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner). @@ -130,9 +130,9 @@ CREATE TABLE session ( 你也可以通过使用缓存来存储会话数据 [[yii\web\CacheSession]] 。 理论上讲,你可以使用只要支持[数据缓存](caching-data.md#supported-cache-storage)。 但是请注意,某些缓存的存储当达到存储限制会清除缓存数据。出于这个原因,你应主要在不存在存储限制时才使用这些缓存存储。 -如果你的服务器支持 [Redis](http://redis.io/),强烈建议你通过使用 [[yii\redis\Session]] 来作为会话存储。 +如果你的服务器支持 [Redis](https://redis.io/),强烈建议你通过使用 [[yii\redis\Session]] 来作为会话存储。 -如果您的服务器上有 [Redis](http://redis.io/), +如果您的服务器上有 [Redis](https://redis.io/), 强烈建议您使用 [[yii\redis\Session]] 作为会话存储。 @@ -217,9 +217,9 @@ composer dumpautoload -o - [Yii debug toolbar and debugger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md) - [Blackfire](https://blackfire.io/) -- [XHProf](https://secure.php.net/manual/en/book.xhprof.php) -- [XDebug profiler](http://xdebug.org/docs/profiler) +- [XHProf](https://www.php.net/manual/en/book.xhprof.php) +- [XDebug profiler](https://xdebug.org/docs/profiler) ## 准备扩展应用程序 -当没有任何帮助时,您可以尝试使您的应用程序可扩展。[Configuring a Yii2 Application for an Autoscaling Stack](https://github.com/samdark/yii2-cookbook/blob/master/book/scaling.md) 中提供了一个很好的介绍。有关进一步阅读,请参阅 [Web apps performance and scaling](http://thehighload.com/). +当没有任何帮助时,您可以尝试使您的应用程序可扩展。[Configuring a Yii2 Application for an Autoscaling Stack](https://github.com/samdark/yii2-cookbook/blob/master/book/scaling.md) 中提供了一个很好的介绍。有关进一步阅读,请参阅 [Web apps performance and scaling](https://thehighload.com/). diff --git a/docs/guide-zh-CN/tutorial-start-from-scratch.md b/docs/guide-zh-CN/tutorial-start-from-scratch.md index 76d608ec067..5bac9dd9c68 100644 --- a/docs/guide-zh-CN/tutorial-start-from-scratch.md +++ b/docs/guide-zh-CN/tutorial-start-from-scratch.md @@ -42,7 +42,7 @@ git clone git@github.com:yiisoft/yii2-app-basic.git -------------------------------- 模板调整好后,通过其创建一个 Git 仓库并提交你的代码。 -如果你希望将你的应用程序模板开源,[Github](http://github.com) 将是最好的托管服务。 +如果你希望将你的应用程序模板开源,[Github](https://github.com) 将是最好的托管服务。 如果你不喜欢其他的人来跟你一起协作,你可以使用任意的 Git 仓库服务。 接下来,你需要为 Composer 注册你的 package。对于公有的模板,你可以将 package 注册到 [Packagist](https://packagist.org/)。对于私有的模板, diff --git a/docs/guide-zh-CN/tutorial-template-engines.md b/docs/guide-zh-CN/tutorial-template-engines.md index ac6e3b3f77c..a77422f8f8c 100644 --- a/docs/guide-zh-CN/tutorial-template-engines.md +++ b/docs/guide-zh-CN/tutorial-template-engines.md @@ -2,7 +2,7 @@ ==================================== 默认情况下,Yii 使用 PHP 作为其默认的模板引擎语言,但是,你可以配置 Yii 以扩展的方式支持其他的渲染引擎, -比如 [Twig](http://twig.sensiolabs.org/) 或 [Smarty](http://www.smarty.net/)等。 +比如 [Twig](https://twig.symfony.com/) 或 [Smarty](https://www.smarty.net/)等。 组件 `view` 就是用于渲染视图的。 你可以重新配置这个组件的行为以增加一个自定义的模板引擎。 diff --git a/docs/guide-zh-CN/tutorial-yii-integration.md b/docs/guide-zh-CN/tutorial-yii-integration.md index 684ce960a72..f068f3a951a 100644 --- a/docs/guide-zh-CN/tutorial-yii-integration.md +++ b/docs/guide-zh-CN/tutorial-yii-integration.md @@ -93,7 +93,7 @@ composer require yiisoft/yii2 有关 Composer 的更多信息以及安装过程中可能出现的问题的解决方案,另请参见 [关于安装 Yii 的部分](start-installation.md#installing-via-composer)。 -不然的话,你可以[下载](http://www.yiiframework.com/download/) Yii 的发布包, +不然的话,你可以[下载](https://www.yiiframework.com/download/) Yii 的发布包, 并把它解压到对应系统的 `BasePath/vendor` 目录内。 之后,你需要修改该第三方应用的入口脚本,在开头位置添加 Yii 的引入代码: diff --git a/docs/guide-zh-CN/yii2-redis.md b/docs/guide-zh-CN/yii2-redis.md deleted file mode 100644 index 858d4fd1f23..00000000000 --- a/docs/guide-zh-CN/yii2-redis.md +++ /dev/null @@ -1,256 +0,0 @@ -# yii2-redis 扩展详解 - - -## 简介 - -yii2-redis 扩展为 Yii2 框架提供了 redis 键值存储支持。包括缓存(Cache)、会话存储处理(Session),并实现了 ActiveRecord 模式,允许您将活动记录存储在 redis 中。 - -#### 相关链接 -- [yii2-redis 扩展网址:https://github.com/yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis) - - -## 安装扩展 - -在 Yii2 项目根目录,执行以下命令安装: -``` -$ composer require yiisoft/yii2-redis -``` - -也可以先在 composer.json 文件中声明如下依赖: -``` -"yiisoft/yii2-redis": "~2.0.0" -``` - -再执行下面命令安装: -``` -$ composer update -``` - - -## 基本使用 - -继续阅读请确保已安装并开启了 redis 服务,安装请参考[《Redis 安装》](http://mayanlong.com/archives/2016/359.html)。 - -#### 1. 配置 - -在组件中添加如下配置: -```php -'components' => [ - 'redis' => [ - 'class' => 'yii\redis\Connection', - 'hostname' => 'localhost', - 'port' => 6379, - 'database' => 0, - ], -] -``` - -#### 2. 示例 - -下面代码演示了 redis 最基本的 string 类型的使用: -```php -// 获取 redis 组件 -$redis = Yii::$app->redis; - -// 判断 key 为 username 的是否有值,有则打印,没有则赋值 -$key = 'username'; -if ($val = $redis->get($key)) { - var_dump($val); -} else { - $redis->set($key, 'marko'); - $redis->expire($key, 5); -} -``` - -这个类中(`yii\redis\Connection`)提供了操作 redis 所有的数据类型和服务(String、Hash、List、Set、SortedSet、HyperLogLog、GEO、Pub/Sub、Transaction、Script、Connection、Server)所需要的方法,并且和 redis 中的方法同名,如果不清楚可以直接到该类中查看。 - - -## 缓存组件 - -该扩展中的 `yii\redis\Cache` 实现了 Yii2 中的缓存相关接口,所以我们也可以用 redis 来存储缓存,且用法和原来一样。 - -#### 1. 配置 - -修改组件中 cache 的 class 为 `yii\redis\Cache` 即可,配置如下: -```php -'components' => [ - 'cache' => [ - // 'class' => 'yii\caching\FileCache', - 'class' => 'yii\redis\Cache', - ], -], -``` - -如果没有配置过 redis 组件,需要在 cache 组件下配置 redis 服务相关参数,完整配置如下: -```php -'components' => [ - 'cache' => [ - // 'class' => 'yii\caching\FileCache', - 'class' => 'yii\redis\Cache', - 'redis' => [ - 'hostname' => 'localhost', - 'port' => 6379, - 'database' => 0, - ], - ], -], -``` - -#### 2. 示例 - -下面代码演示了缓存的基本使用: -```php -// 获取 cache 组件 -$cache = Yii::$app->cache; - -// 判断 key 为 username 的缓存是否存在,有则打印,没有则赋值 -$key = 'username'; -if ($cache->exists($key)) { - var_dump($cache->get($key)); -} else { - $cache->set($key, 'marko', 60); -} -``` - -使用文件缓存(FileCache)时,缓存是存储在 runtime/cache 目录下;使用 redis 缓存后,缓存将存储在 redis 数据库中,性能将大大提高。 - - -## 会话组件 - -该扩展中的 `yii\redis\Session` 实现了 Yii2 中的会话相关接口,所以我们也可以用 redis 来存储会话信息,且用法和原来一样。 - -#### 1. 配置 - -修改组件 session 的配置,指定 class 为 `yii\redis\Session` 即可,配置如下: -```php -'components' => [ - 'session' => [ - 'name' => 'advanced-frontend', - 'class' => 'yii\redis\Session' - ], -], -``` - -如果没有配置过 redis 组件,需要在 session 组件下配置 redis 服务相关参数,完整配置如下: -```php -'components' => [ - 'session' => [ - 'name' => 'advanced-frontend', - 'class' => 'yii\redis\Session', - 'redis' => [ - 'hostname' => 'localhost', - 'port' => 6379, - 'database' => 0, - ], - ], -], -``` - -#### 2. 使用 - -在开发过程中,切记一定不要使用 PHP 原生的 $_SESSION 去操作,而要使用 Yii 提供的 session 组件,获取方式如下: -```php -$session = Yii::$app->session; -``` - - -## ActiveRecord - -该扩展中的 `yii\redis\ActiveRecord` 实现了 Yii2 中的 ActiveRecord 相关接口,所以我们可以使用 AR 的方式操作 redis 数据库。关于如何使用 Yii 的 ActiveRecord,请阅读权威指南中有关 [ActiveRecord](http://www.yiichina.com/doc/guide/2.0/db-active-record) 的基础文档。 - -定义 redis ActiveRecord 类,我们的模型需要继承 `yii\redis\ActiveRecord`,并至少实现 `attributes()` 方法来定义模型的属性。 - -主键可以通过 `yii\redis\ActiveRecord::primaryKey()` 定义,如果未指定,则默认为 id。 primaryKey 必须在 attributes() 方法定义的属性中,如果没有指定主键,请确保 id 在属性中。 - -下面定义一个 Customer 模型来演示: -```php -class Customer extends \yii\redis\ActiveRecord -{ - /** - * 主键 默认为 id - * - * @return array|string[] - */ - public static function primaryKey() - { - return ['id']; - } - - /** - * 模型对应记录的属性列表 - * - * @return array - */ - public function attributes() - { - return ['id', 'name', 'age', 'phone', 'status', 'created_at', 'updated_at']; - } - - /** - * 定义和其它模型的关系 - * - * @return \yii\db\ActiveQueryInterface - */ - public function getOrders() - { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); - } - -} -``` - -使用示例: -```php -// 使用 AR 方式新增一条记录 -$customer = new Customer(); -$customer->name = 'marko'; -$customer->age = 18; -$customer->phone = 13888888888; -$customer->status = 1; -$customer->save(); -echo $customer->id; - -// 使用 AR 查询 -$customer = Customer::findOne($customer->id); -$customer = Customer::find()->where(['status' => 1])->all(); -``` - -redis ActiveRecord 的一般用法与权威指南中数据库的 ActiveRecord 用法非常相似。它们支持相同的接口和方法,除了以下限制: -- 由于 redis 不支持 sql,查询方法仅限于使用以下方法:where(),limit(),offset(),orderBy() 和 indexBy()。 【 orderBy() 尚未实现:[#1305](https://github.com/yiisoft/yii2/issues/1305))】 -- 由于 redis 没有表的概念,因此不能通过表定义关联关系,只能通过其它记录来定义关系。 - - -## 直接使用命令 - -直接使用 redis 连接,就可以使用 redis 提供的很多有用的命令。配置好 redis 后,用以下方式获取 redis 组件: - -```php -$redis = Yii::$app->redis; -``` - -然后就可以执行命令了,最通用的方法是使用 executeCommand 方法: - -```php -$result = $redis->executeCommand('hmset', ['test_collection', 'key1', 'val1', 'key2', 'val2']); -``` - -支持的每个命令都有一些快捷方式,可以按照如下方式使用: - -```php -$result = $redis->hmset('test_collection', 'key1', 'val1', 'key2', 'val2'); -``` - -有关可用命令及其参数的列表,请参阅 redis 命令: -- [redis 命令英文版:http://redis.io/commands](http://redis.io/commands) -- [redis 命令中文版:http://redisdoc.com](http://redisdoc.com) - - - - - - - - - - - diff --git a/docs/guide/README.md b/docs/guide/README.md index a802d3024e3..92fe901fb4c 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -1,7 +1,7 @@ The Definitive Guide to Yii 2.0 =============================== -This tutorial is released under the [Terms of Yii Documentation](http://www.yiiframework.com/doc/terms/). +This tutorial is released under the [Terms of Yii Documentation](https://www.yiiframework.com/doc/terms/). All Rights Reserved. @@ -136,6 +136,7 @@ RESTful Web Services * [Quick Start](rest-quick-start.md) * [Resources](rest-resources.md) * [Controllers](rest-controllers.md) +* [Filtering Collections](rest-filtering-collections.md) * [Routing](rest-routing.md) * [Response Formatting](rest-response-formatting.md) * [Authentication](rest-authentication.md) @@ -201,5 +202,6 @@ Helpers * [Helpers Overview](helper-overview.md) * [ArrayHelper](helper-array.md) * [Html](helper-html.md) +* [Json](helper-json.md) * [Url](helper-url.md) diff --git a/docs/guide/caching-data.md b/docs/guide/caching-data.md index 61e208f9c73..f17b4a07c8c 100644 --- a/docs/guide/caching-data.md +++ b/docs/guide/caching-data.md @@ -58,7 +58,7 @@ such as memory, files, databases. Cache components are usually registered as [application components](structure-application-components.md) so that they can be globally configurable and accessible. The following code shows how to configure the `cache` application component to use -[memcached](http://memcached.org/) with two cache servers: +[memcached](https://memcached.org/) with two cache servers: ```php 'components' => [ @@ -103,7 +103,7 @@ For example, you can modify the above configuration to use [[yii\caching\ApcCach Yii supports a wide range of cache storage. The following is a summary: -* [[yii\caching\ApcCache]]: uses PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. This option can be +* [[yii\caching\ApcCache]]: uses PHP [APC](https://www.php.net/manual/en/book.apcu.php) extension. This option can be considered as the fastest one when dealing with cache for a centralized thick application (e.g. one server, no dedicated load balancers, etc.). * [[yii\caching\DbCache]]: uses a database table to store cached data. To use this cache, you must @@ -120,17 +120,17 @@ Yii supports a wide range of cache storage. The following is a summary: `Yii::$app->cache` might be `null`. * [[yii\caching\FileCache]]: uses standard files to store cached data. This is particularly suitable to cache large chunk of data, such as page content. -* [[yii\caching\MemCache]]: uses PHP [memcache](https://secure.php.net/manual/en/book.memcache.php) - and [memcached](https://secure.php.net/manual/en/book.memcached.php) extensions. This option can be considered as +* [[yii\caching\MemCache]]: uses PHP [memcache](https://www.php.net/manual/en/book.memcache.php) + and [memcached](https://www.php.net/manual/en/book.memcached.php) extensions. This option can be considered as the fastest one when dealing with cache in a distributed applications (e.g. with several servers, load balancers, etc.) -* [[yii\redis\Cache]]: implements a cache component based on [Redis](http://redis.io/) key-value store +* [[yii\redis\Cache]]: implements a cache component based on [Redis](https://redis.io/) key-value store (redis version 2.6.12 or higher is required). -* [[yii\caching\WinCache]]: uses PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension) - ([see also](https://secure.php.net/manual/en/book.wincache.php)) extension. -* [[yii\caching\XCache]] _(deprecated)_: uses PHP [XCache](http://xcache.lighttpd.net/) extension. +* [[yii\caching\WinCache]]: uses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) + ([see also](https://www.php.net/manual/en/book.wincache.php)) extension. +* [[yii\caching\XCache]] _(deprecated)_: uses PHP [XCache](https://en.wikipedia.org/wiki/List_of_PHP_accelerators#XCache) extension. * [[yii\caching\ZendDataCache]] _(deprecated)_: uses - [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) + [Zend Data Cache](https://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) as the underlying caching medium. @@ -310,7 +310,7 @@ $result = Customer::getDb()->cache(function ($db) { }); ``` -> Info: Some DBMS (e.g. [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) +> Info: Some DBMS (e.g. [MySQL](https://dev.mysql.com/doc/refman/5.6/en/query-cache.html)) also support query caching on the DB server-side. You may choose to use either query caching mechanism. The query caching described above has the advantage that you may specify flexible cache dependencies and are potentially more efficient. @@ -418,7 +418,7 @@ of each entry to be 1MB. Therefore, if the size of a query result exceeds this l the caching will fail. -## Cache Flushing +## Cache Flushing When you need to invalidate all the stored cache data, you can call [[yii\caching\Cache::flush()]]. diff --git a/docs/guide/caching-http.md b/docs/guide/caching-http.md index 6cca6822aed..58dfb88f810 100644 --- a/docs/guide/caching-http.md +++ b/docs/guide/caching-http.md @@ -107,7 +107,7 @@ Expensive ETag generation may defeat the purpose of using `HttpCache` and introd since they need to be re-evaluated on every request. Try to find a simple expression that invalidates the cache if the page content has been modified. -> Note: In compliance to [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4), +> Note: In compliance to [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4), `HttpCache` will send out both `ETag` and `Last-Modified` headers if they are both configured. And if the client sends both of the `If-None-Match` header and the `If-Modified-Since` header, only the former will be respected. @@ -131,7 +131,7 @@ that you want from `HttpCache`. To prevent this problem, by default `HttpCache` these headers automatically. If you want to change this behavior, you should configure the [[yii\filters\HttpCache::sessionCacheLimiter]] property. The property can take a string value, including `public`, `private`, `private_no_expire`, and `nocache`. Please refer to the PHP manual about -[session_cache_limiter()](https://secure.php.net/manual/en/function.session-cache-limiter.php) +[session_cache_limiter()](https://www.php.net/manual/en/function.session-cache-limiter.php) for explanations about these values. diff --git a/docs/guide/concept-aliases.md b/docs/guide/concept-aliases.md index aa37e4f69b5..955468f9050 100644 --- a/docs/guide/concept-aliases.md +++ b/docs/guide/concept-aliases.md @@ -116,8 +116,8 @@ Yii predefines a set of aliases to easily reference commonly used file paths and containing the [entry script](structure-entry-scripts.md). - `@web`, the base URL of the currently running Web application. It has the same value as [[yii\web\Request::baseUrl]]. - `@vendor`, the [[yii\base\Application::vendorPath|Composer vendor directory]]. Defaults to `@app/vendor`. -- `@bower`, the root directory that contains [bower packages](http://bower.io/). Defaults to `@vendor/bower`. -- `@npm`, the root directory that contains [npm packages](https://www.npmjs.org/). Defaults to `@vendor/npm`. +- `@bower`, the root directory that contains [bower packages](https://bower.io/). Defaults to `@vendor/bower`. +- `@npm`, the root directory that contains [npm packages](https://www.npmjs.com/). Defaults to `@vendor/npm`. The `@yii` alias is defined when you include the `Yii.php` file in your [entry script](structure-entry-scripts.md). The rest of the aliases are defined in the application constructor when applying the application diff --git a/docs/guide/concept-autoloading.md b/docs/guide/concept-autoloading.md index a6d0294eca6..05f539e0139 100644 --- a/docs/guide/concept-autoloading.md +++ b/docs/guide/concept-autoloading.md @@ -1,7 +1,7 @@ Class Autoloading ================= -Yii relies on the [class autoloading mechanism](https://secure.php.net/manual/en/language.oop5.autoload.php) +Yii relies on the [class autoloading mechanism](https://www.php.net/manual/en/language.oop5.autoload.php) to locate and include all required class files. It provides a high-performance class autoloader that is compliant with the [PSR-4 standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md). The autoloader is installed when you include the `Yii.php` file. @@ -15,7 +15,7 @@ Using the Yii Autoloader To make use of the Yii class autoloader, you should follow two simple rules when creating and naming your classes: -* Each class must be under a [namespace](https://secure.php.net/manual/en/language.namespaces.php) (e.g. `foo\bar\MyClass`) +* Each class must be under a [namespace](https://www.php.net/manual/en/language.namespaces.php) (e.g. `foo\bar\MyClass`) * Each class must be saved in an individual file whose path is determined by the following algorithm: ```php diff --git a/docs/guide/concept-behaviors.md b/docs/guide/concept-behaviors.md index 6811df732cf..ea085c80b6c 100644 --- a/docs/guide/concept-behaviors.md +++ b/docs/guide/concept-behaviors.md @@ -2,7 +2,7 @@ Behaviors ========= Behaviors are instances of [[yii\base\Behavior]], or of a child class. Behaviors, also known -as [mixins](http://en.wikipedia.org/wiki/Mixin), allow you to enhance the functionality +as [mixins](https://en.wikipedia.org/wiki/Mixin), allow you to enhance the functionality of an existing [[yii\base\Component|component]] class without needing to change the class's inheritance. Attaching a behavior to a component "injects" the behavior's methods and properties into the component, making those methods and properties accessible as if they were defined in the component class itself. Moreover, a behavior can respond to the [events](concept-events.md) triggered by the component, which allows behaviors to also customize the normal @@ -120,21 +120,21 @@ class User extends ActiveRecord { return [ // anonymous behavior, behavior class name only - MyBehavior::className(), + MyBehavior::class, // named behavior, behavior class name only - 'myBehavior2' => MyBehavior::className(), + 'myBehavior2' => MyBehavior::class, // anonymous behavior, configuration array [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], // named behavior, configuration array 'myBehavior4' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ] @@ -153,14 +153,14 @@ To attach a behavior dynamically, call the [[yii\base\Component::attachBehavior( use app\components\MyBehavior; // attach a behavior object -$component->attachBehavior('myBehavior1', new MyBehavior); +$component->attachBehavior('myBehavior1', new MyBehavior()); // attach a behavior class -$component->attachBehavior('myBehavior2', MyBehavior::className()); +$component->attachBehavior('myBehavior2', MyBehavior::class); // attach a configuration array $component->attachBehavior('myBehavior3', [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ]); @@ -170,8 +170,8 @@ You may attach multiple behaviors at once using the [[yii\base\Component::attach ```php $component->attachBehaviors([ - 'myBehavior1' => new MyBehavior, // a named behavior - MyBehavior::className(), // an anonymous behavior + 'myBehavior1' => new MyBehavior(), // a named behavior + MyBehavior::class, // an anonymous behavior ]); ``` @@ -179,10 +179,10 @@ You may also attach behaviors through [configurations](concept-configurations.md ```php [ - 'as myBehavior2' => MyBehavior::className(), + 'as myBehavior2' => MyBehavior::class, 'as myBehavior3' => [ - 'class' => MyBehavior::className(), + 'class' => MyBehavior::class, 'prop1' => 'value1', 'prop2' => 'value2', ], @@ -272,7 +272,7 @@ class User extends ActiveRecord { return [ [ - 'class' => TimestampBehavior::className(), + 'class' => TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'], ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'], @@ -329,7 +329,7 @@ There are several built-in and external behaviors available: Comparing Behaviors with Traits ---------------------- -While behaviors are similar to [traits](https://secure.php.net/traits) in that they both "inject" their +While behaviors are similar to [traits](https://www.php.net/traits) in that they both "inject" their properties and methods to the primary class, they differ in many aspects. As explained below, they both have pros and cons. They are more like complements to each other rather than alternatives. diff --git a/docs/guide/concept-components.md b/docs/guide/concept-components.md index 4aa1f448265..309bd032fe9 100644 --- a/docs/guide/concept-components.md +++ b/docs/guide/concept-components.md @@ -76,7 +76,7 @@ Following these guidelines will make your components [configurable](concept-conf $component = new MyClass(1, 2, ['prop1' => 3, 'prop2' => 4]); // alternatively $component = \Yii::createObject([ - 'class' => MyClass::className(), + 'class' => MyClass::class, 'prop1' => 3, 'prop2' => 4, ], [1, 2]); diff --git a/docs/guide/concept-di-container.md b/docs/guide/concept-di-container.md index b771a3d1750..b48790a647b 100644 --- a/docs/guide/concept-di-container.md +++ b/docs/guide/concept-di-container.md @@ -2,7 +2,7 @@ Dependency Injection Container ============================== A dependency injection (DI) container is an object that knows how to instantiate and configure objects and -all their dependent objects. [Martin Fowler's article](http://martinfowler.com/articles/injection.html) has well +all their dependent objects. [Martin Fowler's article](https://martinfowler.com/articles/injection.html) has well explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii. @@ -484,7 +484,7 @@ $container->setDefinitions([ ] ]); -$reader = $container->get('app\storage\DocumentsReader); +$reader = $container->get('app\storage\DocumentsReader'); // Will behave exactly the same as in the previous example. ``` @@ -544,7 +544,7 @@ Summary Both dependency injection and [service locator](concept-service-locator.md) are popular design patterns that allow building software in a loosely-coupled and more testable fashion. We highly recommend you to read -[Martin's article](http://martinfowler.com/articles/injection.html) to get a deeper understanding of +[Martin's article](https://martinfowler.com/articles/injection.html) to get a deeper understanding of dependency injection and service locator. Yii implements its [service locator](concept-service-locator.md) on top of the dependency injection (DI) container. diff --git a/docs/guide/concept-events.md b/docs/guide/concept-events.md index b89c9807eb5..c8743d6c9d4 100644 --- a/docs/guide/concept-events.md +++ b/docs/guide/concept-events.md @@ -13,7 +13,7 @@ events, it should extend from [[yii\base\Component]], or from a child class. Event Handlers -------------- -An event handler is a [PHP callback](https://secure.php.net/manual/en/language.types.callable.php) that gets executed +An event handler is a [PHP callback](https://www.php.net/manual/en/language.types.callable.php) that gets executed when the event it is attached to is triggered. You can use any of the following callbacks: - a global PHP function specified as a string (without parentheses), e.g., `'trim'`; @@ -211,7 +211,7 @@ use Yii; use yii\base\Event; use yii\db\ActiveRecord; -Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { +Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::debug(get_class($event->sender) . ' is inserted'); }); ``` @@ -229,11 +229,11 @@ handlers only. For example: ```php use yii\base\Event; -Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event) { +Event::on(Foo::class, Foo::EVENT_HELLO, function ($event) { var_dump($event->sender); // displays "null" }); -Event::trigger(Foo::className(), Foo::EVENT_HELLO); +Event::trigger(Foo::class, Foo::EVENT_HELLO); ``` Note that, in this case, `$event->sender` is `null` instead of an object instance. @@ -245,10 +245,10 @@ To detach a class-level event handler, call [[yii\base\Event::off()]]. For examp ```php // detach $handler -Event::off(Foo::className(), Foo::EVENT_HELLO, $handler); +Event::off(Foo::class, Foo::EVENT_HELLO, $handler); // detach all handlers of Foo::EVENT_HELLO -Event::off(Foo::className(), Foo::EVENT_HELLO); +Event::off(Foo::class, Foo::EVENT_HELLO); ``` @@ -304,10 +304,10 @@ You can trigger the event of those classes: ```php // trigger event for Dog class -Event::trigger(Dog::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Dog::class, DanceEventInterface::EVENT_DANCE); // trigger event for Developer class -Event::trigger(Developer::className(), DanceEventInterface::EVENT_DANCE); +Event::trigger(Developer::class, DanceEventInterface::EVENT_DANCE); ``` But please notice, that you can not trigger all the classes, that implement the interface: diff --git a/docs/guide/db-active-record.md b/docs/guide/db-active-record.md index ca3e19fdb59..e87727469bb 100644 --- a/docs/guide/db-active-record.md +++ b/docs/guide/db-active-record.md @@ -1,7 +1,7 @@ Active Record ============= -[Active Record](http://en.wikipedia.org/wiki/Active_record_pattern) provides an object-oriented interface +[Active Record](https://en.wikipedia.org/wiki/Active_record_pattern) provides an object-oriented interface for accessing and manipulating data stored in databases. An Active Record class is associated with a database table, an Active Record instance corresponds to a row of that table, and an *attribute* of an Active Record instance represents the value of a particular column in that row. Instead of writing raw SQL statements, @@ -473,8 +473,8 @@ If you are interested in the attribute values prior to their most recent modific > HTML forms where every value is represented as a string. > To ensure the correct type for e.g. integer values you may apply a [validation filter](input-validation.md#data-filtering): > `['attributeName', 'filter', 'filter' => 'intval']`. This works with all the typecasting functions of PHP like -> [intval()](https://secure.php.net/manual/en/function.intval.php), [floatval()](https://secure.php.net/manual/en/function.floatval.php), -> [boolval](https://secure.php.net/manual/en/function.boolval.php), etc... +> [intval()](https://www.php.net/manual/en/function.intval.php), [floatval()](https://www.php.net/manual/en/function.floatval.php), +> [boolval](https://www.php.net/manual/en/function.boolval.php), etc... ### Default Attribute Values @@ -532,7 +532,7 @@ that will be encoded by [QueryBuilder](db-query-builder.md) to an PgSQL string r You can also use conditions for JSON columns: ```php -$query->andWhere(['=', 'json', new ArrayExpression(['foo' => 'bar']) +$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) @@ -689,7 +689,7 @@ try { ``` > Note: in the above code we have two catch-blocks for compatibility -> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](https://secure.php.net/manual/en/class.throwable.php) +> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](https://www.php.net/manual/en/class.throwable.php) > since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher. The second way is to list the DB operations that require transactional support in the [[yii\db\ActiveRecord::transactions()]] @@ -789,9 +789,15 @@ use yii\behaviors\OptimisticLockBehavior; public function behaviors() { return [ - OptimisticLockBehavior::className(), + OptimisticLockBehavior::class, ]; } + +public function optimisticLock() +{ + return 'version'; +} + ``` > Note: Because [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] will ensure the record is only saved > if user submits a valid version number by directly parsing [[\yii\web\Request::getBodyParam()|getBodyParam()]], it @@ -821,7 +827,7 @@ class Customer extends ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -831,7 +837,7 @@ class Order extends ActiveRecord public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -849,7 +855,7 @@ While declaring a relation, you should specify the following information: declarations that a customer has many orders while an order only has one customer. - the name of the related Active Record class: specified as the first parameter to either [[yii\db\ActiveRecord::hasMany()|hasMany()]] or [[yii\db\ActiveRecord::hasOne()|hasOne()]]. - A recommended practice is to call `Xyz::className()` to get the class name string so that you can receive + A recommended practice is to call `Xyz::class` to get the class name string so that you can receive IDE auto-completion support as well as error detection at compiling stage. - the link between the two types of data: specifies the column(s) through which the two types of data are related. The array values are the columns of the primary data (represented by the Active Record class that you are declaring @@ -859,6 +865,7 @@ While declaring a relation, you should specify the following information: Active Record directly next to it. You see there that `customer_id` is a property of `Order` and `id` is a property of `Customer`. +> Warning: Relation name `relation` is reserved. When used it will produce `ArgumentCountError`. ### Accessing Relational Data @@ -927,7 +934,7 @@ class Customer extends ActiveRecord { public function getBigOrders($threshold = 100) { - return $this->hasMany(Order::className(), ['customer_id' => 'id']) + return $this->hasMany(Order::class, ['customer_id' => 'id']) ->where('subtotal > :threshold', [':threshold' => $threshold]) ->orderBy('id'); } @@ -962,7 +969,7 @@ class Order extends ActiveRecord { public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->viaTable('order_item', ['order_id' => 'id']); } } @@ -975,12 +982,12 @@ class Order extends ActiveRecord { public function getOrderItems() { - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + return $this->hasMany(OrderItem::class, ['order_id' => 'id']); } public function getItems() { - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } } @@ -1014,21 +1021,21 @@ class Customer extends ActiveRecord public function getPurchasedItems() { // customer's items, matching 'id' column of `Item` to 'item_id' in OrderItem - return $this->hasMany(Item::className(), ['id' => 'item_id']) + return $this->hasMany(Item::class, ['id' => 'item_id']) ->via('orderItems'); } public function getOrderItems() { // customer's order items, matching 'id' column of `Order` to 'order_id' in OrderItem - return $this->hasMany(OrderItem::className(), ['order_id' => 'id']) + return $this->hasMany(OrderItem::class, ['order_id' => 'id']) ->via('orders'); } public function getOrders() { // same as above - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1281,7 +1288,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } @@ -1289,7 +1296,7 @@ class Order extends ActiveRecord { public function getCustomer() { - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } ``` @@ -1323,7 +1330,7 @@ class Customer extends ActiveRecord { public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); } } ``` @@ -1434,7 +1441,7 @@ class Customer extends \yii\db\ActiveRecord public function getComments() { // a customer has many comments - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1449,7 +1456,7 @@ class Comment extends \yii\mongodb\ActiveRecord public function getCustomer() { // a comment has one customer - return $this->hasOne(Customer::className(), ['id' => 'customer_id']); + return $this->hasOne(Customer::class, ['id' => 'customer_id']); } } @@ -1533,7 +1540,7 @@ class Customer extends \yii\db\ActiveRecord { public function getActiveComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id'])->active(); + return $this->hasMany(Comment::class, ['customer_id' => 'id'])->active(); } } @@ -1544,7 +1551,7 @@ class Customer extends \yii\db\ActiveRecord { public function getComments() { - return $this->hasMany(Comment::className(), ['customer_id' => 'id']); + return $this->hasMany(Comment::class, ['customer_id' => 'id']); } } @@ -1610,7 +1617,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1705,7 +1712,7 @@ class Customer extends \yii\db\ActiveRecord public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } } ``` @@ -1736,7 +1743,7 @@ class Customer extends \yii\db\ActiveRecord */ public function getOrders() { - return $this->hasMany(Order::className(), ['customer_id' => 'id']); + return $this->hasMany(Order::class, ['customer_id' => 'id']); } /** diff --git a/docs/guide/db-dao.md b/docs/guide/db-dao.md index 98351e88536..81026ddf48b 100644 --- a/docs/guide/db-dao.md +++ b/docs/guide/db-dao.md @@ -1,7 +1,7 @@ Database Access Objects ======================= -Built on top of [PDO](https://secure.php.net/manual/en/book.pdo.php), Yii DAO (Database Access Objects) provides an +Built on top of [PDO](https://www.php.net/manual/en/book.pdo.php), Yii DAO (Database Access Objects) provides an object-oriented API for accessing relational databases. It is the foundation for other more advanced database access methods, including [query builder](db-query-builder.md) and [active record](db-active-record.md). @@ -11,12 +11,12 @@ you have to take extra effort to create a database-agnostic application. In Yii 2.0, DAO supports the following databases out of the box: -- [MySQL](http://www.mysql.com/) +- [MySQL](https://www.mysql.com/) - [MariaDB](https://mariadb.com/) -- [SQLite](http://sqlite.org/) -- [PostgreSQL](http://www.postgresql.org/): version 8.4 or higher -- [CUBRID](http://www.cubrid.org/): version 9.3 or higher. -- [Oracle](http://www.oracle.com/us/products/database/overview/index.html) +- [SQLite](https://sqlite.org/) +- [PostgreSQL](https://www.postgresql.org/): version 8.4 or higher +- [CUBRID](https://www.cubrid.org/): version 9.3 or higher. +- [Oracle](https://www.oracle.com/database/) - [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): version 2008 or higher. > Note: New version of pdo_oci for PHP 7 currently exists only as the source code. Follow @@ -61,7 +61,7 @@ You can then access the DB connection via the expression `Yii::$app->db`. > Tip: You can configure multiple DB application components if your application needs to access multiple databases. When configuring a DB connection, you should always specify its Data Source Name (DSN) via the [[yii\db\Connection::dsn|dsn]] -property. The format of DSN varies for different databases. Please refer to the [PHP manual](https://secure.php.net/manual/en/function.PDO-construct.php) +property. The format of DSN varies for different databases. Please refer to the [PHP manual](https://www.php.net/manual/en/pdo.construct.php) for more details. Below are some examples: * MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` @@ -190,7 +190,7 @@ $post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status ->queryOne(); ``` -Parameter binding is implemented via [prepared statements](https://secure.php.net/manual/en/mysqli.quickstart.prepared-statements.php). +Parameter binding is implemented via [prepared statements](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php). Besides preventing SQL injection attacks, it may also improve performance by preparing a SQL statement once and executing it multiple times with different parameters. For example, @@ -384,7 +384,7 @@ the changes made by the queries prior to that failed query in the transaction. ` exception as if we had not caught it, so the normal error handling process will take care of it. > Note: in the above code we have two catch-blocks for compatibility -> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](https://secure.php.net/manual/en/class.throwable.php) +> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](https://www.php.net/manual/en/class.throwable.php) > since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher. diff --git a/docs/guide/db-migrations.md b/docs/guide/db-migrations.md index cbc9ef5d7ef..44f87aa7893 100644 --- a/docs/guide/db-migrations.md +++ b/docs/guide/db-migrations.md @@ -187,6 +187,22 @@ class m150101_185401_create_news_table extends Migration A list of all available methods for defining the column types is available in the API documentation of [[yii\db\SchemaBuilderTrait]]. +> Info: The generated file permissions and ownership will be determined by the current environment. This might lead to + inaccessible files. This could, for example, happen when the migration is created within a docker container + and the files are edited on the host. In this case the `newFileMode` and/or `newFileOwnership` of the MigrateController + can be changed. E.g. in the application config: + ```php + [ + 'migrate' => [ + 'class' => 'yii\console\controllers\MigrateController', + 'newFileOwnership' => '1000:1000', # Default WSL user id + 'newFileMode' => 0660, + ], + ], + ]; + ``` ## Generating Migrations @@ -669,7 +685,7 @@ in `safeDown()`. In the above example we first create the table and then insert in `safeDown()` we first delete the row and then drop the table. > Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples, - please refer to [implicit commit](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). If this is the case, + please refer to [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). If this is the case, you should still implement `up()` and `down()`, instead. diff --git a/docs/guide/db-query-builder.md b/docs/guide/db-query-builder.md index 696ae05a27d..f2d4248479c 100644 --- a/docs/guide/db-query-builder.md +++ b/docs/guide/db-query-builder.md @@ -155,7 +155,7 @@ $query->from(['u' => $subQuery]); #### Prefixes Also a default [[yii\db\Connection::$tablePrefix|tablePrefix]] can be applied. Implementation instructions -are in the ["Quoting Tables" section of the "Database Access Objects" guide](guide-db-dao.html#quoting-table-and-column-names). +are in the ["Quoting Tables" section of the "Database Access Objects" guide](db-dao.md#quoting-table-and-column-names). ### [[yii\db\Query::where()|where()]] @@ -298,7 +298,7 @@ the operator can be one of the following: should be applied. Note that when using an escape mapping (or the third operand is not provided), the values will be automatically enclosed within a pair of percentage characters. - > Note: When using PostgreSQL you may also use [`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) + > Note: When using PostgreSQL you may also use [`ilike`](https://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) > instead of `like` for case-insensitive matching. - `or like`: similar to the `like` operator except that `OR` is used to concatenate the `LIKE` @@ -716,6 +716,9 @@ $query = (new \yii\db\Query()) ->all(); ``` +The column which name is passed into [[yii\db\Query::indexBy()|indexBy()]] method must be present in the result set in order +for indexing to work - it is up to the developer to take care of it. + To index by expression values, pass an anonymous function to the [[yii\db\Query::indexBy()|indexBy()]] method: ```php @@ -795,7 +798,7 @@ foreach ($query->each() as $username => $user) { #### Limitations of batch query in MySQL MySQL implementation of batch queries relies on the PDO driver library. By default, MySQL queries are -[`buffered`](https://secure.php.net/manual/en/mysqlinfo.concepts.buffering.php). This defeats the purpose +[`buffered`](https://www.php.net/manual/en/mysqlinfo.concepts.buffering.php). This defeats the purpose of using the cursor to get the data, because it doesn't prevent the whole result set from being loaded into the client's memory by the driver. diff --git a/docs/guide/glossary.md b/docs/guide/glossary.md index 3c0c7c01dc8..c93fa8cdf49 100644 --- a/docs/guide/glossary.md +++ b/docs/guide/glossary.md @@ -52,7 +52,7 @@ Module is a sub-application which contains MVC elements by itself, such as model ## namespace -Namespace refers to a [PHP language feature](https://secure.php.net/manual/en/language.namespaces.php) which is actively used in Yii 2. +Namespace refers to a [PHP language feature](https://www.php.net/manual/en/language.namespaces.php) which is actively used in Yii 2. # P diff --git a/docs/guide/helper-array.md b/docs/guide/helper-array.md index 698b8e795b3..19c3c03ad5f 100644 --- a/docs/guide/helper-array.md +++ b/docs/guide/helper-array.md @@ -1,7 +1,7 @@ ArrayHelper =========== -Additionally to the [rich set of PHP array functions](https://secure.php.net/manual/en/book.array.php), the Yii array helper provides +Additionally to the [rich set of PHP array functions](https://www.php.net/manual/en/book.array.php), the Yii array helper provides extra static methods allowing you to deal with arrays more efficiently. @@ -117,7 +117,7 @@ After executing the code `$array` will contain `['options' => [1, 2]]` and `$typ ## Checking Existence of Keys -`ArrayHelper::keyExists` works the same way as [array_key_exists](https://secure.php.net/manual/en/function.array-key-exists.php) +`ArrayHelper::keyExists` works the same way as [array_key_exists](https://www.php.net/manual/en/function.array-key-exists.php) except that it also supports case-insensitive key comparison. For example, ```php @@ -322,7 +322,7 @@ Third argument is direction. In case of sorting by a single key it could be eith sort direction. Last argument is PHP sort flag that could take the same values as the ones passed to -PHP [sort()](https://secure.php.net/manual/en/function.sort.php). +PHP [sort()](https://www.php.net/manual/en/function.sort.php). ## Detecting Array Types @@ -357,7 +357,7 @@ Encoding will use application charset and could be changed via third argument. You can use [[yii\helpers\ArrayHelper::merge()|ArrayHelper::merge()]] to merge two or more arrays into one recursively. If each array has an element with the same string key value, the latter will overwrite the former -(different from [array_merge_recursive()](https://secure.php.net/manual/en/function.array-merge-recursive.php)). +(different from [array_merge_recursive()](https://www.php.net/manual/en/function.array-merge-recursive.php)). Recursive merging will be conducted if both arrays have an element of array type and are having the same key. For integer-keyed elements, the elements from the latter array will be appended to the former array. You can use [[yii\helpers\UnsetArrayValue]] object to unset value from previous array or @@ -472,7 +472,7 @@ While PHP offers `in_array()`, this does not support subsets or `\Traversable` o To aid these kinds of tests, [[yii\helpers\ArrayHelper]] provides [[yii\helpers\ArrayHelper::isIn()|isIn()]] and [[yii\helpers\ArrayHelper::isSubset()|isSubset()]] with the same signature as -[in_array()](https://secure.php.net/manual/en/function.in-array.php). +[in_array()](https://www.php.net/manual/en/function.in-array.php). ```php // true diff --git a/docs/guide/helper-html.md b/docs/guide/helper-html.md index 1c411e76ce1..aba121a72ab 100644 --- a/docs/guide/helper-html.md +++ b/docs/guide/helper-html.md @@ -2,7 +2,7 @@ Html helper =========== Every web application generates lots of HTML markup. If the markup is static, it can be done efficiently by -[mixing PHP and HTML in a single file](https://secure.php.net/manual/en/language.basic-syntax.phpmode.php), but when it is +[mixing PHP and HTML in a single file](https://www.php.net/manual/en/language.basic-syntax.phpmode.php), but when it is generated dynamically it starts to get tricky to handle it without extra help. Yii provides such help in the form of an Html helper, which provides a set of static methods for handling commonly used HTML tags, their options, and their content. @@ -42,7 +42,7 @@ know about: - If a value is `null`, the corresponding attribute will not be rendered. - Attributes whose values are of boolean type will be treated as - [boolean attributes](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes). + [boolean attributes](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributess). - The values of attributes will be HTML-encoded using [[yii\helpers\Html::encode()|Html::encode()]]. - If the value of an attribute is an array, it will be handled as follows: @@ -147,8 +147,8 @@ method accepts an array of properties to remove. If it's a single property, it c ### Encoding and Decoding Content In order for content to be displayed properly and securely in HTML, special characters in the content should be encoded. -In PHP this is done with [htmlspecialchars](https://secure.php.net/manual/en/function.htmlspecialchars.php) and -[htmlspecialchars_decode](https://secure.php.net/manual/en/function.htmlspecialchars-decode.php). The issue with using +In PHP this is done with [htmlspecialchars](https://www.php.net/manual/en/function.htmlspecialchars.php) and +[htmlspecialchars_decode](https://www.php.net/manual/en/function.htmlspecialchars-decode.php). The issue with using these methods directly is that you have to specify encoding and extra flags all the time. Since these flags are the same all the time and the encoding should match the one of the application in order to prevent security issues, Yii provides two compact and simple-to-use methods: diff --git a/docs/guide/helper-json.md b/docs/guide/helper-json.md new file mode 100644 index 00000000000..60d99ac1823 --- /dev/null +++ b/docs/guide/helper-json.md @@ -0,0 +1,26 @@ +Json Helper +========== + +Json helper provides a set of static methods for encoding and decoding JSON. +It handles encoding errors and the `[[yii\helpers\Json::encode()]]` method will not encode a JavaScript expression that is represented in +terms of a `[[yii\web\JsExpression]]` object. +By default, encoding is done with the `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE` options. +Please see [PHP:json_encode](https://www.php.net/manual/en/function.json-encode.php) for more information. + +## Pretty Print + +By default the `[[yii\helpers\Json::encode()]]` method will output unformatted JSON (e.g. without whitespaces). +To make it more readable for humans you can turn on "pretty printing". + +> Note: Pretty Print can useful for debugging during development but is not recommended in a production environment. + +To enable pretty print in a single instance you can specify it as an option. E.g. + +```php +$data = ['a' => 1, 'b' => 2]; +$json = yii\helpers\Json::encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); +``` +You can also enable pretty printing of the JSON helper globally. For example in your config for or index.php: +```php +yii\helpers\Json::$prettyPrint = YII_DEBUG; // use "pretty" output in debug mode +``` diff --git a/docs/guide/helper-overview.md b/docs/guide/helper-overview.md index f6f85c357a3..087b7657f53 100644 --- a/docs/guide/helper-overview.md +++ b/docs/guide/helper-overview.md @@ -33,7 +33,7 @@ The following core helper classes are provided in the Yii releases: - HtmlPurifier - Imagine (provided by yii2-imagine extension) - Inflector -- Json +- [Json](helper-json.md) - Markdown - StringHelper - [Url](helper-url.md) diff --git a/docs/guide/input-file-upload.md b/docs/guide/input-file-upload.md index 4f254e677cc..aa2ea2c550a 100644 --- a/docs/guide/input-file-upload.md +++ b/docs/guide/input-file-upload.md @@ -123,7 +123,7 @@ You can also upload multiple files at once, with some adjustments to the code li First you should adjust the model class by adding the `maxFiles` option in the `file` validation rule to limit the maximum number of files allowed to upload. Setting `maxFiles` to `0` means there is no limit on the number of files that can be uploaded simultaneously. The maximum number of files allowed to be uploaded simultaneously is also limited -with PHP directive [`max_file_uploads`](https://secure.php.net/manual/en/ini.core.php#ini.max-file-uploads), +with PHP directive [`max_file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads), which defaults to 20. The `upload()` method should also be updated to save the uploaded files one by one. ```php diff --git a/docs/guide/input-forms.md b/docs/guide/input-forms.md index 2160aed8336..990fd667e1b 100644 --- a/docs/guide/input-forms.md +++ b/docs/guide/input-forms.md @@ -107,7 +107,7 @@ are some reserved names that can cause conflicts: > Forms and their child elements should not use input names or ids that conflict with properties of a form, > such as `submit`, `length`, or `method`. Name conflicts can cause confusing failures. -> For a complete list of rules and to check your markup for these problems, see [DOMLint](http://kangax.github.io/domlint/). +> For a complete list of rules and to check your markup for these problems, see [DOMLint](https://kangax.github.io/domlint/). Additional HTML tags can be added to the form using plain HTML or using the methods from the [[yii\helpers\Html|Html]]-helper class like it is done in the above example with [[yii\helpers\Html::submitButton()|Html::submitButton()]]. diff --git a/docs/guide/input-tabular-input.md b/docs/guide/input-tabular-input.md index 8bfee0d83c6..5a2e0824f9d 100644 --- a/docs/guide/input-tabular-input.md +++ b/docs/guide/input-tabular-input.md @@ -30,8 +30,6 @@ Let's start with the controller action: namespace app\controllers; -use Yii; -use yii\base\Model; use yii\web\Controller; use app\models\Setting; @@ -43,11 +41,13 @@ class SettingsController extends Controller { $settings = Setting::find()->indexBy('id')->all(); - if (Model::loadMultiple($settings, Yii::$app->request->post()) && Model::validateMultiple($settings)) { - foreach ($settings as $setting) { - $setting->save(false); + if ($this->request->isPost) { + if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) { + foreach ($settings as $setting) { + $setting->save(false); + } + return $this->redirect('index'); } - return $this->redirect('index'); } return $this->render('update', ['settings' => $settings]); @@ -71,10 +71,12 @@ use yii\widgets\ActiveForm; $form = ActiveForm::begin(); -foreach ($settings as $index => $setting) { - echo $form->field($setting, "[$index]value")->label($setting->name); +foreach ($settings as $id => $setting) { + echo $form->field($setting, "[$id]value")->label($setting->name); } +echo Html::submitButton('Save'); + ActiveForm::end(); ``` @@ -88,20 +90,29 @@ Creating new records is similar to updating, except the part, where we instantia ```php public function actionCreate() { - $count = count(Yii::$app->request->post('Setting', [])); - $settings = [new Setting()]; - for($i = 1; $i < $count; $i++) { - $settings[] = new Setting(); + $settings = []; + if ($this->request->isPost) { + $count = count($this->request->post($setting->tableName())) - 1; + for ($i = 0; $i < $count; $i++) { + $settings[$i] = new Setting(); + } + if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) { + foreach ($settings as $setting) { + $setting->save(false); + } + return $this->redirect('index'); + } } + $settings[] = new Setting(); - // ... + return $this->render('create', ['settings' => $settings]); } ``` Here we create an initial `$settings` array containing one model by default so that always at least one text field will be visible in the view. Additionally we add more models for each line of input we may have received. -In the view you can use javascript to add new input lines dynamically. +In the view you can use JavaScript to add new input lines dynamically. ### Combining Update, Create and Delete on one page diff --git a/docs/guide/input-validation.md b/docs/guide/input-validation.md index 30f51372e69..f02ffd2bfee 100644 --- a/docs/guide/input-validation.md +++ b/docs/guide/input-validation.md @@ -469,7 +469,7 @@ class EntryForm extends Model { return [ [['name', 'email'], 'required'], - ['country', CountryValidator::className()], + ['country', CountryValidator::class], ['email', 'email'], ]; } @@ -748,7 +748,7 @@ JS; ### Deferred Validation -If you need to perform asynchronous client-side validation, you can create [Deferred objects](http://api.jquery.com/category/deferred-object/). +If you need to perform asynchronous client-side validation, you can create [Deferred objects](https://api.jquery.com/category/deferred-object/). For example, to perform a custom AJAX validation, you can use the following code: ```php diff --git a/docs/guide/intro-upgrade-from-v1.md b/docs/guide/intro-upgrade-from-v1.md index 7ebb99e4311..aecfd9f8526 100644 --- a/docs/guide/intro-upgrade-from-v1.md +++ b/docs/guide/intro-upgrade-from-v1.md @@ -29,15 +29,15 @@ Yii 2.0 requires PHP 5.4 or above, which is a huge improvement over PHP version As a result, there are many differences on the language level that you should pay attention to. Below is a summary of the major changes regarding PHP: -- [Namespaces](https://secure.php.net/manual/en/language.namespaces.php). -- [Anonymous functions](https://secure.php.net/manual/en/functions.anonymous.php). +- [Namespaces](https://www.php.net/manual/en/language.namespaces.php). +- [Anonymous functions](https://www.php.net/manual/en/functions.anonymous.php). - Short array syntax `[...elements...]` is used instead of `array(...elements...)`. - Short echo tags ``. - [[yii\web\View::POS_END|View::POS_END]] for right before closing ``. -- [[yii\web\View::POS_READY|View::POS_READY]] for executing code on the [document `ready` event](http://learn.jquery.com/using-jquery-core/document-ready/). +- [[yii\web\View::POS_READY|View::POS_READY]] for executing code on the [document `ready` event](https://learn.jquery.com/using-jquery-core/document-ready/). This will automatically register [[yii\web\JqueryAsset|jQuery]] and wrap the code into the appropriate jQuery code. This is the default position. - [[yii\web\View::POS_LOAD|View::POS_LOAD]] for executing code on the - [document `load` event](http://learn.jquery.com/using-jquery-core/document-ready/). Same as the above, this will also register [[yii\web\JqueryAsset|jQuery]] automatically. + [document `load` event](https://learn.jquery.com/using-jquery-core/document-ready/). Same as the above, this will also register [[yii\web\JqueryAsset|jQuery]] automatically. The last argument is a unique script ID that is used to identify the script code block and replace an existing one with the same ID instead of adding a new one. If you don't provide it, the JS code itself will be used as the ID. It is used to avoid registration of the same code muliple times. @@ -56,7 +56,7 @@ An external script can be added like the following: ```php $this->registerJsFile( '@web/js/main.js', - ['depends' => [\yii\web\JqueryAsset::className()]] + ['depends' => [\yii\web\JqueryAsset::class]] ); ``` @@ -95,7 +95,7 @@ A CSS file can be registered using the following: ```php $this->registerCssFile("@web/css/themes/black-and-white.css", [ - 'depends' => [\yii\bootstrap\BootstrapAsset::className()], + 'depends' => [\yii\bootstrap\BootstrapAsset::class], 'media' => 'print', ], 'css-print-theme'); ``` @@ -189,7 +189,7 @@ JS ``` The above example code uses PHP -[Heredoc syntax](https://secure.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) for better readability. This also enables better syntax highlighting in most IDEs so it is the +[Heredoc syntax](https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) for better readability. This also enables better syntax highlighting in most IDEs so it is the preferred way of writing inline JavaScript, especially useful for code that is longer than a single line. The variable `$message` is created in PHP and thanks to [[yii\helpers\Json::htmlEncode|Json::htmlEncode]] it contains the string in valid JS syntax, which can be inserted into the JavaScript code to place the dynamic string in the function call to `alert()`. diff --git a/docs/guide/output-formatting.md b/docs/guide/output-formatting.md index 9cd7e4102ce..7db8ec9d36a 100644 --- a/docs/guide/output-formatting.md +++ b/docs/guide/output-formatting.md @@ -45,7 +45,7 @@ echo Yii::$app->formatter->format(0.125, ['percent', 2]); > the formatter is not the right tool for that. > To convert user input for date and number values you may use [[yii\validators\DateValidator]] and [[yii\validators\NumberValidator]] > respectively. For simple conversion between machine readable date and time formats, -> the PHP [date()](https://secure.php.net/manual/en/function.date.php)-function is enough. +> the PHP [date()](https://www.php.net/manual/en/function.date.php)-function is enough. ## Configuring Formatter @@ -75,7 +75,7 @@ The formatter supports the following output formats that are related with date a - [[yii\i18n\Formatter::asDate()|date]]: the value is formatted as a date, e.g. `January 01, 2014`. - [[yii\i18n\Formatter::asTime()|time]]: the value is formatted as a time, e.g. `14:23`. - [[yii\i18n\Formatter::asDatetime()|datetime]]: the value is formatted as date and time, e.g. `January 01, 2014 14:23`. -- [[yii\i18n\Formatter::asTimestamp()|timestamp]]: the value is formatted as a [unix timestamp](http://en.wikipedia.org/wiki/Unix_time), e.g. `1412609982`. +- [[yii\i18n\Formatter::asTimestamp()|timestamp]]: the value is formatted as a [unix timestamp](https://en.wikipedia.org/wiki/Unix_time), e.g. `1412609982`. - [[yii\i18n\Formatter::asRelativeTime()|relativeTime]]: the value is formatted as the time interval between a date and now in human readable form e.g. `1 hour ago`. - [[yii\i18n\Formatter::asDuration()|duration]]: the value is formatted as a duration in human readable format. e.g. `1 day, 2 minutes`. @@ -86,7 +86,7 @@ and [[yii\i18n\Formatter::asDatetime()|datetime]] methods can be customized glob [[yii\i18n\Formatter::datetimeFormat|datetimeFormat]]. You can specify date and time formats using the [ICU syntax](http://userguide.icu-project.org/formatparse/datetime). -You can also use the [PHP date() syntax](https://secure.php.net/manual/en/function.date.php) with a prefix `php:` to differentiate +You can also use the [PHP date() syntax](https://www.php.net/manual/en/function.date.php) with a prefix `php:` to differentiate it from ICU syntax. For example, ```php @@ -174,7 +174,7 @@ The format for number formatting can be adjusted using the [[yii\i18n\Formatter: active [[yii\i18n\Formatter::locale|locale]]. For more advanced configuration, [[yii\i18n\Formatter::numberFormatterOptions]] and [[yii\i18n\Formatter::numberFormatterTextOptions]] -can be used to configure the [NumberFormatter class](https://secure.php.net/manual/en/class.numberformatter.php) used internally +can be used to configure the [NumberFormatter class](https://www.php.net/manual/en/class.numberformatter.php) used internally to implement the formatter. For example, to adjust the maximum and minimum value of fraction digits, you can configure the [[yii\i18n\Formatter::numberFormatterOptions]] property like the following: @@ -235,7 +235,7 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // output: 1 января 2014 By default, the currently active [[yii\i18n\Formatter::locale|locale]] is determined by the value of [[yii\base\Application::language]]. You may override it by setting the [[yii\i18n\Formatter::locale]] property explicitly. -> Note: The Yii formatter relies on the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) to support +> Note: The Yii formatter relies on the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) to support > localized data formatting. Because different versions of the ICU library compiled with PHP may cause different > formatting results, it is recommended that you use the same ICU version for all your environments. For more details, > please refer to [Setting up your PHP environment for internationalization](tutorial-i18n.md#setup-environment). diff --git a/docs/guide/rest-authentication.md b/docs/guide/rest-authentication.md index 39a6516d84c..87487b52e70 100644 --- a/docs/guide/rest-authentication.md +++ b/docs/guide/rest-authentication.md @@ -10,15 +10,15 @@ via HTTPS to prevent man-in-the-middle (MitM) attacks**. There are different ways to send an access token: -* [HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication): the access token +* [HTTP Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication): the access token is sent as the username. This should only be used when an access token can be safely stored on the API consumer side. For example, the API consumer is a program running on a server. * Query parameter: the access token is sent as a query parameter in the API URL, e.g., `https://example.com/users?access-token=xxxxxxxx`. Because most Web servers will keep query parameters in server logs, this approach should be mainly used to serve `JSONP` requests which cannot use HTTP headers to send access tokens. -* [OAuth 2](http://oauth.net/2/): the access token is obtained by the consumer from an authorization - server and sent to the API server via [HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750), +* [OAuth 2](https://oauth.net/2/): the access token is obtained by the consumer from an authorization + server and sent to the API server via [HTTP Bearer Tokens](https://datatracker.ietf.org/doc/html/rfc6750), according to the OAuth2 protocol. Yii supports all of the above authentication methods. You can also easily create new authentication methods. @@ -57,7 +57,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -75,11 +75,11 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => CompositeAuth::className(), + 'class' => CompositeAuth::class, 'authMethods' => [ - HttpBasicAuth::className(), - HttpBearerAuth::className(), - QueryParamAuth::className(), + HttpBasicAuth::class, + HttpBearerAuth::class, + QueryParamAuth::class, ], ]; return $behaviors; diff --git a/docs/guide/rest-controllers.md b/docs/guide/rest-controllers.md index 321fa2ecf9e..8de69c32291 100644 --- a/docs/guide/rest-controllers.md +++ b/docs/guide/rest-controllers.md @@ -69,7 +69,7 @@ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ]; return $behaviors; } @@ -80,7 +80,7 @@ public function behaviors() Adding the [Cross-Origin Resource Sharing](structure-filters.md#cors) filter to a controller is a bit more complicated than adding other filters described above, because the CORS filter has to be applied before authentication methods and thus needs a slightly different approach compared to other filters. Also authentication has to be disabled for the -[CORS Preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests) +[CORS Preflight requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests) so that a browser can safely determine whether a request can be made beforehand without the need for sending authentication credentials. The following shows the code that is needed to add the [[yii\filters\Cors]] filter to an existing controller that extends from [[yii\rest\ActiveController]]: @@ -98,7 +98,7 @@ public function behaviors() // add CORS filter $behaviors['corsFilter'] = [ - 'class' => \yii\filters\Cors::className(), + 'class' => \yii\filters\Cors::class, ]; // re-add authentication filter diff --git a/docs/guide/rest-filtering-collections.md b/docs/guide/rest-filtering-collections.md new file mode 100644 index 00000000000..ab9c7b92ead --- /dev/null +++ b/docs/guide/rest-filtering-collections.md @@ -0,0 +1,191 @@ +Filtering Collections +===================== + +Resource collection can be filtered using [[yii\data\DataFilter]] component since 2.0.13. It allows validating and +building the filter conditions passed via request, and, with the help of its extended version [[yii\data\ActiveDataFilter]], +using them in a format suitable for [[yii\db\QueryInterface::where()]]. + + +## Configuring Data Provider For Filtering + +As mentioned in the [Collections](rest-resources.md#collections) section, we can use +[Data Provider](output-data-providers#data-providers) to output sorted and paginated list of resources. We can also use +it to filter that list. + +```php +$filter = new ActiveDataFilter([ + 'searchModel' => 'app\models\PostSearch', +]); + +$filterCondition = null; +// You may load filters from any source. For example, +// if you prefer JSON in request body, +// use Yii::$app->request->getBodyParams() below: +if ($filter->load(Yii::$app->request->get())) { + $filterCondition = $filter->build(); + if ($filterCondition === false) { + // Serializer would get errors out of it + return $filter; + } +} + +$query = Post::find(); +if ($filterCondition !== null) { + $query->andWhere($filterCondition); +} + +return new ActiveDataProvider([ + 'query' => $query, +]); +``` + +`PostSearch` model serves the purpose of defining which properties and values are allowed for filtering: + +```php +use yii\base\Model; + +class PostSearch extends Model +{ + public $id; + public $title; + + public function rules() + { + return [ + ['id', 'integer'], + ['title', 'string', 'min' => 2, 'max' => 200], + ]; + } +} +``` + +Instead of preparing the standalone model for search rules you can use [[yii\base\DynamicModel]] if you don't need any +special business logic there. + +```php +$filter = new ActiveDataFilter([ + 'searchModel' => (new DynamicModel(['id', 'title'])) + ->addRule(['id'], 'integer') + ->addRule(['title'], 'string', ['min' => 2, 'max' => 200]), +]); +``` + +Defining `searchModel` is required in order to control the filter conditions allowed to the end user. + + +## Filtering Request + +End user is usually expected to provide optional filtering conditions in the request by one or more of the allowed +methods (which should be explicitly stated in the API documentation). For example, if filtering is handled via POST +method using JSON it can be something similar to: + +```json +{ + "filter": { + "id": {"in": [2, 5, 9]}, + "title": {"like": "cheese"} + } +} +``` + +The above conditions are: +- `id` must be either 2, 5, or 9 **AND** +- `title` must contain the word `cheese`. + +The same conditions sent as a part of GET query are: + +``` +?filter[id][in][]=2&filter[id][in][]=5&filter[id][in][]=9&filter[title][like]=cheese +``` + +You can change the default `filter` key word by setting [[yii\data\DataFilter::$filterAttributeName]]. + + +## Filter Control Keywords + +The default list of allowed filter control keywords is as the following: + +| filter control | translates to | +|:--------------:|:-------------:| +| `and` | `AND` | +| `or` | `OR` | +| `not` | `NOT` | +| `lt` | `<` | +| `gt` | `>` | +| `lte` | `<=` | +| `gte` | `>=` | +| `eq` | `=` | +| `neq` | `!=` | +| `in` | `IN` | +| `nin` | `NOT IN` | +| `like` | `LIKE` | + +You can expand that list by expanding option [[yii\data\DataFilter::$filterControls]], for example you could provide +several keywords for the same filter build key, creating multiple aliases like: + +```php +[ + 'eq' => '=', + '=' => '=', + '==' => '=', + '===' => '=', + // ... +] +``` + +Keep in mind that any unspecified keyword will not be recognized as a filter control and will be treated as an attribute +name - you should avoid conflicts between control keywords and attribute names (for example: in case you have control +keyword `like` and an attribute named `like`, specifying condition for such attribute will be impossible). + +> Note: while specifying filter controls take actual data exchange format, which your API uses, in mind. + Make sure each specified control keyword is valid for the format. For example, in XML tag name can start + only with a letter character, thus controls like `>`, `=`, or `$gt` will break the XML schema. + +> Note: When adding new filter control word make sure to check whether you need also to update + [[yii\data\DataFilter::$conditionValidators]] and/or [[yii\data\DataFilter::$operatorTypes]] in order to achieve + expected query result based on the complication of the operator and the way it should work. + + +## Handling The Null Values + +While it is easy to use `null` inside the JSON statement, it is not possible to send it using the GET query without +confusing the literal `null` with the string `"null"`. Since 2.0.40 you can use [[yii\data\DataFilter::$nullValue]] +option to configure the word that will be used as a replacement for literal `null` (by default it's `"NULL"`). + + +## Aliasing Attributes + +Whether you want to alias the attribute with another name or to filter the joined DB table you can use +[[yii\data\DataFilter::$attributeMap]] to set the map of aliases: + +```php +[ + 'carPart' => 'car_part', // carPart will be used to filter car_part property + 'authorName' => '{{author}}.[[name]]', // authorName will be used to filter name property of joined author table +] +``` + +## Configuring Filters For `ActiveController` + +[[yii\rest\ActiveController]] comes with the handy set of common REST actions that you can easily configure to use +filters as well through [[yii\rest\IndexAction::$dataFilter]] property. One of the possible ways of doing so is to use +[[yii\rest\ActiveController::actions()]]: + +```php +public function actions() +{ + $actions = parent::actions(); + + $actions['index']['dataFilter'] = [ + 'class' => \yii\data\ActiveDataFilter::class, + 'attributeMap' => [ + 'clockIn' => 'clock_in', + ], + 'searchModel' => (new DynamicModel(['id', 'clockIn']))->addRule(['id', 'clockIn'], 'integer', ['min' => 1]), + ]; + + return $actions; +} +``` + +Now your collection (accessed through `index` action) can be filtered by `id` and `clockIn` properties. diff --git a/docs/guide/rest-quick-start.md b/docs/guide/rest-quick-start.md index 3e5fe4c4724..32ccd6ad68a 100644 --- a/docs/guide/rest-quick-start.md +++ b/docs/guide/rest-quick-start.md @@ -9,7 +9,7 @@ In particular, Yii supports the following features about RESTful APIs: * Customizable object serialization with support for selectable output fields; * Proper formatting of collection data and validation errors; * Collection pagination, filtering and sorting; -* Support for [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS); +* Support for [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS); * Efficient routing with proper HTTP verb check; * Built-in support for the `OPTIONS` and `HEAD` verbs; * Authentication and authorization; @@ -190,11 +190,47 @@ For example, the URL `http://localhost/users?fields=id,email` will only return t > such as `password_hash`, `auth_key`. You certainly do not want these to appear in your API result. > You can and should remove these fields from result as described in the [Resources](rest-resources.md) section. -Addionally, you can sort collections like `http://localhost/users?sort=email` or +Additionally, you can sort collections like `http://localhost/users?sort=email` or `http://localhost/users?sort=-email`. Filtering collections like `http://localhost/users?filter[id]=10` or `http://localhost/users?filter[email][like]=gmail.com` could be implemented using -data filters. See [Resources](rest-resources.md#filtering-collections) section for details. +data filters. See [Filtering Collections](rest-filtering-collections.md) section for details. +## Customizing Pagination and Sorting in the list + +In order to change the default [pagination](output-pagination.md) and [sorting](output-sorting.md) of the model list +you can configure the [[yii\rest\IndexAction]] in your controller. For example: + +```php + [ + 'pagination' => [ + 'pageSize' => 10, + ], + 'sort' => [ + 'defaultOrder' => [ + 'created_at' => SORT_DESC, + ], + ], + ], + ]); + } +} +``` + +Please see [Extending ActiveController](rest-controllers#extending-active-controller) for more information on how to +configure actions of the ActiveController. ## Summary diff --git a/docs/guide/rest-resources.md b/docs/guide/rest-resources.md index 164cbf5429b..c681e4d2385 100644 --- a/docs/guide/rest-resources.md +++ b/docs/guide/rest-resources.md @@ -140,7 +140,7 @@ the request with `http://localhost/users?fields=id,email&expand=profile` may ret ## Links -[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), an abbreviation for Hypermedia as the Engine of Application State, +[HATEOAS](https://en.wikipedia.org/wiki/HATEOAS), an abbreviation for Hypermedia as the Engine of Application State, promotes that RESTful APIs should return information that allows clients to discover actions supported for the returned resources. The key of HATEOAS is to return a set of hyperlinks with relation information when resource data are served by the APIs. @@ -251,11 +251,3 @@ will also include the pagination information by the following HTTP headers: Since collection in REST APIs is a data provider, it shares all data provider features i.e. pagination and sorting. An example may be found in the [Quick Start](rest-quick-start.md#trying-it-out) section. - -### Filtering collections - -Since version 2.0.13 Yii provides a facility to filter collections. An example can be found in the -[Quick Start](rest-quick-start.md#trying-it-out) guide. In case you're implementing an endpoint yourself, -filtering could be done as described in -[Filtering Data Providers using Data Filters](output-data-providers.md#filtering-data-providers-using-data-filters) -section of Data Providers guide. diff --git a/docs/guide/rest-response-formatting.md b/docs/guide/rest-response-formatting.md index bfc5955744a..f6c4a23d6bf 100644 --- a/docs/guide/rest-response-formatting.md +++ b/docs/guide/rest-response-formatting.md @@ -5,7 +5,7 @@ When handling a RESTful API request, an application usually takes the following with response formatting: 1. Determine various factors that may affect the response format, such as media type, language, version, etc. - This process is also known as [content negotiation](http://en.wikipedia.org/wiki/Content_negotiation). + This process is also known as [content negotiation](https://en.wikipedia.org/wiki/Content_negotiation). 2. Convert resource objects into arrays, as described in the [Resources](rest-resources.md) section. This is done by [[yii\rest\Serializer]]. 3. Convert arrays into a string in the format as determined by the content negotiation step. This is diff --git a/docs/guide/rest-versioning.md b/docs/guide/rest-versioning.md index 946f2f901a3..4a90c3e57ca 100644 --- a/docs/guide/rest-versioning.md +++ b/docs/guide/rest-versioning.md @@ -5,7 +5,7 @@ A good API is *versioned*: changes and new features are implemented in new versi code, APIs are meant to be used by clients beyond your control. For this reason, backward compatibility (BC) of the APIs should be maintained whenever possible. If a change that may break BC is necessary, you should introduce it in new version of the API, and bump up the version number. Existing clients can continue to use the old, working version of the API; and new or upgraded clients can get the new functionality in the new API version. -> Tip: Refer to [Semantic Versioning](http://semver.org/) +> Tip: Refer to [Semantic Versioning](https://semver.org/) for more information on designing API version numbers. One common way to implement API versioning is to embed the version number in the API URLs. diff --git a/docs/guide/runtime-bootstrapping.md b/docs/guide/runtime-bootstrapping.md index 970f5674799..dd8d880fb00 100644 --- a/docs/guide/runtime-bootstrapping.md +++ b/docs/guide/runtime-bootstrapping.md @@ -37,8 +37,8 @@ before they are used to resolve requests. In production mode, enable a bytecode cache, such as [PHP OPcache] or [APC], to minimize the time needed for including and parsing PHP files. -[PHP OPcache]: https://secure.php.net/manual/en/intro.opcache.php -[APC]: https://secure.php.net/manual/en/book.apc.php +[PHP OPcache]: https://www.php.net/manual/en/intro.opcache.php +[APC]: https://www.php.net/manual/en/book.apcu.php Some large applications have very complex application [configurations](concept-configurations.md) which are divided into many smaller configuration files. If this is the case, consider caching diff --git a/docs/guide/runtime-requests.md b/docs/guide/runtime-requests.md index bce3c3c2423..c11d52a78ce 100644 --- a/docs/guide/runtime-requests.md +++ b/docs/guide/runtime-requests.md @@ -201,7 +201,7 @@ except the `X-ProxyUser-Ip` and `Front-End-Https` headers in case the request is In that case the former is used to retrieve the user IP as configured in `ipHeaders` and the latter will be used to determine the result of [[yii\web\Request::getIsSecureConnection()]]. -Since 2.0.31 [RFC 7239](https://tools.ietf.org/html/rfc7239) `Forwarded` header is supported. In order to enable +Since 2.0.31 [RFC 7239](https://datatracker.ietf.org/doc/html/rfc7239) `Forwarded` header is supported. In order to enable it you need to add header name to `secureHeaders`. Make sure your proxy is setting it, otherwise end user would be able to spoof IP and protocol. diff --git a/docs/guide/runtime-responses.md b/docs/guide/runtime-responses.md index 6705f4c67bc..9e8efd075e6 100644 --- a/docs/guide/runtime-responses.md +++ b/docs/guide/runtime-responses.md @@ -230,10 +230,10 @@ can terminate earlier while the Web server is sending the file. To use this feat the [[yii\web\Response::xSendFile()]]. The following list summarizes how to enable the `X-Sendfile` feature for some popular Web servers: -- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile) -- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Lighttpd v1.5: [X-Sendfile](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) -- Nginx: [X-Accel-Redirect](http://wiki.nginx.org/XSendfile) +- Apache: [X-Sendfile](https://tn123.org/mod_xsendfile) +- Lighttpd v1.4: [X-LIGHTTPD-send-file](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Lighttpd v1.5: [X-Sendfile](https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file) +- Nginx: [X-Accel-Redirect](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) - Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile) diff --git a/docs/guide/runtime-sessions-cookies.md b/docs/guide/runtime-sessions-cookies.md index 384b62b3b8e..4d7c2678fe5 100644 --- a/docs/guide/runtime-sessions-cookies.md +++ b/docs/guide/runtime-sessions-cookies.md @@ -131,8 +131,8 @@ session classes implementing different session storage: * [[yii\web\DbSession]]: stores session data in a database table. * [[yii\web\CacheSession]]: stores session data in a cache with the help of a configured [cache component](caching-data.md#cache-components). -* [[yii\redis\Session]]: stores session data using [redis](http://redis.io/) as the storage medium. -* [[yii\mongodb\Session]]: stores session data in a [MongoDB](http://www.mongodb.org/). +* [[yii\redis\Session]]: stores session data using [redis](https://redis.io/) as the storage medium. +* [[yii\mongodb\Session]]: stores session data in a [MongoDB](https://www.mongodb.com/). All these session classes support the same set of API methods. As a result, you can switch to a different session storage class without the need to modify your application code that uses sessions. @@ -374,20 +374,20 @@ Both [[yii\web\Cookie]] and [[yii\web\Session]] support the following security f For better security, the default value of [[yii\web\Cookie::httpOnly]] and the 'httponly' parameter of [[yii\web\Session::cookieParams]] is set to `true`. This helps mitigate the risk of a client-side script accessing the protected cookie (if the browser supports it). -You may read the [HttpOnly wiki article](https://www.owasp.org/index.php/HttpOnly) for more details. +You may read the [HttpOnly wiki article](https://owasp.org/www-community/HttpOnly) for more details. ### secure The purpose of the secure flag is to prevent cookies from being sent in clear text. If the browser supports the secure flag it will only include the cookie when the request is sent over a secure (TLS) connection. -You may read the [SecureFlag wiki article](https://www.owasp.org/index.php/SecureFlag) for more details. +You may read the [SecureFlag wiki article](https://owasp.org/www-community/controls/SecureCookieAttribute) for more details. ### sameSite Starting with Yii 2.0.21 the [[yii\web\Cookie::sameSite]] setting is supported. It requires PHP version 7.3.0 or higher. The purpose of the `sameSite` setting is to prevent CSRF (Cross-Site Request Forgery) attacks. If the browser supports the `sameSite` setting it will only include the cookie according to the specified policy ('Lax' or 'Strict'). -You may read the [SameSite wiki article](https://www.owasp.org/index.php/SameSite) for more details. +You may read the [SameSite wiki article](https://owasp.org/www-community/SameSite) for more details. For better security, an exception will be thrown if `sameSite` is used with an unsupported version of PHP. To use this feature across different PHP versions check the version first. E.g. ```php diff --git a/docs/guide/security-authentication.md b/docs/guide/security-authentication.md index 4c7790b919b..b353d048be4 100644 --- a/docs/guide/security-authentication.md +++ b/docs/guide/security-authentication.md @@ -42,15 +42,16 @@ the following methods: an instance of the identity class using the specified access token. This method is used when you need to authenticate a user by a single secret token (e.g. in a stateless RESTful application). * [[yii\web\IdentityInterface::getId()|getId()]]: it returns the ID of the user represented by this identity instance. -* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: it returns a key used to verify cookie-based login. - The key is stored in the login cookie and will be later compared with the server-side version to make - sure the login cookie is valid. +* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: it returns a key used to validate session and auto-login in + case it is enabled. * [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]]: it implements the logic for verifying - the cookie-based login key. + authentication key. If a particular method is not needed, you may implement it with an empty body. For example, if your application is a pure stateless RESTful application, you would only need to implement [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] -and [[yii\web\IdentityInterface::getId()|getId()]] while leaving all other methods with an empty body. +and [[yii\web\IdentityInterface::getId()|getId()]] while leaving all other methods with an empty body. Or if your +application uses session only authentication, you would need to implement all the methods except +[[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]. In the following example, an [[yii\web\User::identityClass|identity class]] is implemented as an [Active Record](db-active-record.md) class associated with the `user` database table. @@ -99,7 +100,7 @@ class User extends ActiveRecord implements IdentityInterface } /** - * @return string current user auth key + * @return string|null current user auth key */ public function getAuthKey() { @@ -108,7 +109,7 @@ class User extends ActiveRecord implements IdentityInterface /** * @param string $authKey - * @return bool if auth key is valid for current user + * @return bool|null if auth key is valid for current user */ public function validateAuthKey($authKey) { @@ -117,9 +118,8 @@ class User extends ActiveRecord implements IdentityInterface } ``` -As explained previously, you only need to implement `getAuthKey()` and `validateAuthKey()` if your application -uses cookie-based login feature. In this case, you may use the following code to generate an auth key for each -user and store it in the `user` table: +You may use the following code to generate an auth key for each +user and then store it in the `user` table: ```php class User extends ActiveRecord implements IdentityInterface diff --git a/docs/guide/security-authorization.md b/docs/guide/security-authorization.md index aee2570f2e0..52ebc4be3fe 100644 --- a/docs/guide/security-authorization.md +++ b/docs/guide/security-authorization.md @@ -25,7 +25,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['login', 'logout', 'signup'], 'rules' => [ [ @@ -70,7 +70,7 @@ You may customize this behavior by configuring the [[yii\filters\AccessControl:: ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, ... 'denyCallback' => function ($rule, $action) { throw new \Exception('You are not allowed to access this page'); @@ -129,7 +129,7 @@ class SiteController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['special-callback'], 'rules' => [ [ @@ -156,10 +156,10 @@ class SiteController extends Controller ## Role Based Access Control (RBAC) Role-Based Access Control (RBAC) provides a simple yet powerful centralized access control. Please refer to -the [Wikipedia](http://en.wikipedia.org/wiki/Role-based_access_control) for details about comparing RBAC +the [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) for details about comparing RBAC with other more traditional access control schemes. -Yii implements a General Hierarchical RBAC, following the [NIST RBAC model](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf). +Yii implements a General Hierarchical RBAC, following the [NIST RBAC model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf). It provides the RBAC functionality through the [[yii\rbac\ManagerInterface|authManager]] [application component](structure-application-components.md). Using RBAC involves two parts of work. The first part is to build up the RBAC authorization data, and the second @@ -281,7 +281,7 @@ build the hierarchy itself won't be different. You can use [migrations](db-migrations.md) to initialize and modify hierarchy via APIs offered by `authManager`. -Create new migration using `./yii migrate/create init_rbac` then impement creating a hierarchy: +Create new migration using `./yii migrate/create init_rbac` then implement creating a hierarchy: ```php [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'rules' => [ [ 'allow' => true, diff --git a/docs/guide/security-best-practices.md b/docs/guide/security-best-practices.md index 03549d49d59..1fb59e467e6 100644 --- a/docs/guide/security-best-practices.md +++ b/docs/guide/security-best-practices.md @@ -33,7 +33,7 @@ In Yii, most probably you'll use [form validation](input-validation.md) to do al Further reading on the topic: -- +- - @@ -46,9 +46,9 @@ contexts. Further reading on the topic: -- -- -- +- +- +- Avoiding SQL injections @@ -117,7 +117,7 @@ You can get details about the syntax in [Quoting Table and Column Names](db-dao. Further reading on the topic: -- +- Avoiding XSS @@ -151,7 +151,7 @@ Note that HtmlPurifier processing is quite heavy so consider adding caching. Further reading on the topic: -- +- Avoiding CSRF @@ -259,8 +259,8 @@ class ContactAction extends Action Further reading on the topic: -- -- +- +- Avoiding file exposure @@ -288,8 +288,8 @@ details possible. If you absolutely need it check twice that access is properly Further reading on the topic: -- -- +- +- (A6 - Information Leakage and Improper Error Handling) Using secure connection over TLS @@ -330,7 +330,7 @@ or explicitly set or filter the value by setting the [[yii\web\Request::setHostI For more information about the server configuration, please refer to the documentation of your webserver: -- Apache 2: +- Apache 2: - Nginx: If you don't have access to the server configuration, you can setup [[yii\filters\HostControl]] filter at @@ -353,3 +353,29 @@ return [ > Note: you should always prefer web server configuration for 'host header attack' protection instead of the filter usage. [[yii\filters\HostControl]] should be used only if server configuration setup is unavailable. + +### Configuring SSL peer validation + +There is a typical misconception about how to solve SSL certificate validation issues such as: + +``` +cURL error 60: SSL certificate problem: unable to get local issuer certificate +``` + +or + +``` +stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed +``` + +Many sources wrongly suggest disabling SSL peer verification. That should not be ever done since it enables +man-in-the middle type of attacks. Instead, PHP should be configured properly: + +1. Download [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem). +2. Add the following to your php.ini: + ``` + openssl.cafile="/path/to/cacert.pem" + curl.cainfo="/path/to/cacert.pem". + ``` + +Note that the `cacert.pem` file should be kept up to date. diff --git a/docs/guide/security-passwords.md b/docs/guide/security-passwords.md index 68d19505788..327ccced5a0 100644 --- a/docs/guide/security-passwords.md +++ b/docs/guide/security-passwords.md @@ -3,11 +3,11 @@ Working with Passwords Most developers know that passwords cannot be stored in plain text, but many developers believe it's still safe to hash passwords using `md5` or `sha1`. There was a time when using the aforementioned hashing algorithms was sufficient, -but modern hardware makes it possible to reverse such hashes and even stronger ones very quickly using brute force attacks. +but modern hardware makes it possible to crack such hashes and even stronger ones very quickly using brute force attacks. In order to provide increased security for user passwords, even in the worst case scenario (your application is breached), you need to use a hashing algorithm that is resilient against brute force attacks. The best current choice is `bcrypt`. -In PHP, you can create a `bcrypt` hash using the [crypt function](https://secure.php.net/manual/en/function.crypt.php). Yii provides +In PHP, you can create a `bcrypt` hash using the [crypt function](https://www.php.net/manual/en/function.crypt.php). Yii provides two helper functions which make using `crypt` to securely generate and verify hashes easier. When a user provides a password for the first time (e.g., upon registration), the password needs to be hashed: diff --git a/docs/guide/start-databases.md b/docs/guide/start-databases.md index 111f79e819b..4b0c41ca281 100644 --- a/docs/guide/start-databases.md +++ b/docs/guide/start-databases.md @@ -51,7 +51,7 @@ At this point, you have a database named `yii2basic`, and within it a `country` Configuring a DB Connection --------------------------- -Before proceeding, make sure you have installed both the [PDO](https://secure.php.net/manual/en/book.pdo.php) PHP extension and +Before proceeding, make sure you have installed both the [PDO](https://www.php.net/manual/en/book.pdo.php) PHP extension and the PDO driver for the database you are using (e.g. `pdo_mysql` for MySQL). This is a basic requirement if your application uses a relational database. diff --git a/docs/guide/start-forms.md b/docs/guide/start-forms.md index 3cba0c56a7b..ea4aaa90173 100644 --- a/docs/guide/start-forms.md +++ b/docs/guide/start-forms.md @@ -130,7 +130,7 @@ be rendered, wherein the HTML form will be shown, along with any validation erro > Note: In this very simple example we just render the confirmation page upon valid data submission. In practice, you should consider using [[yii\web\Controller::refresh()|refresh()]] or [[yii\web\Controller::redirect()|redirect()]] - to avoid [form resubmission problems](http://en.wikipedia.org/wiki/Post/Redirect/Get). + to avoid [form resubmission problems](https://en.wikipedia.org/wiki/Post/Redirect/Get). Creating Views diff --git a/docs/guide/start-hello.md b/docs/guide/start-hello.md index c99bf55630a..8a44845f246 100644 --- a/docs/guide/start-hello.md +++ b/docs/guide/start-hello.md @@ -88,7 +88,7 @@ is called in an action, it will look for a PHP file named as `views/ControllerID Note that in the above code, the `message` parameter is [[yii\helpers\Html::encode()|HTML-encoded]] before being printed. This is necessary as the parameter comes from an end user, making it vulnerable to -[cross-site scripting (XSS) attacks](http://en.wikipedia.org/wiki/Cross-site_scripting) by embedding +[cross-site scripting (XSS) attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) by embedding malicious JavaScript code in the parameter. Naturally, you may put more content in the `say` view. The content can consist of HTML tags, plain text, and even PHP statements. diff --git a/docs/guide/start-installation.md b/docs/guide/start-installation.md index 7d14124edc6..727c7f4cd4d 100644 --- a/docs/guide/start-installation.md +++ b/docs/guide/start-installation.md @@ -85,7 +85,7 @@ Installing from an Archive File Installing Yii from an archive file involves three steps: -1. Download the archive file from [yiiframework.com](http://www.yiiframework.com/download/). +1. Download the archive file from [yiiframework.com](https://www.yiiframework.com/download/). 2. Unpack the downloaded file to a Web-accessible folder. 3. Modify the `config/web.php` file by entering a secret key for the `cookieValidationKey` configuration item (this is done automatically if you are installing Yii using Composer): @@ -114,9 +114,9 @@ But there are other installation options available: Installing Assets ----------------- -Yii relies on [Bower](http://bower.io/) and/or [NPM](https://www.npmjs.org/) packages for the asset (CSS and JavaScript) libraries installation. +Yii relies on [Bower](https://bower.io/) and/or [NPM](https://www.npmjs.com/) 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/). +This can be achieved either by usage of [asset-packagist.org](https://asset-packagist.org) or [composer asset plugin](https://github.com/fxpio/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. @@ -139,7 +139,7 @@ Verifying the Installation -------------------------- After installation is done, either configure your web server (see next section) or use the -[built-in PHP web server](https://secure.php.net/manual/en/features.commandline.webserver.php) by running the following +[built-in PHP web server](https://www.php.net/manual/en/features.commandline.webserver.php) by running the following console command while in the project root directory: ```bash @@ -173,7 +173,7 @@ Yii's requirements. You can check if the minimum requirements are met using one ``` You should configure your PHP installation so that it meets the minimum requirements of Yii. Most importantly, you -should have PHP 5.4 or above. Ideally latest PHP 7. You should also install the [PDO PHP Extension](https://secure.php.net/manual/en/pdo.installation.php) +should have PHP 5.4 or above. Ideally latest PHP 7. You should also install the [PDO PHP Extension](https://www.php.net/manual/en/pdo.installation.php) and a corresponding database driver (such as `pdo_mysql` for MySQL databases), if your application needs a database. @@ -184,9 +184,9 @@ Configuring Web Servers of deploying it to a production server. The application installed according to the above instructions should work out of box with either -an [Apache HTTP server](http://httpd.apache.org/) or an [Nginx HTTP server](http://nginx.org/), on +an [Apache HTTP server](https://httpd.apache.org/) or an [Nginx HTTP server](https://nginx.org/), on Windows, Mac OS X, or Linux running PHP 5.4 or higher. Yii 2.0 is also compatible with facebook's -[HHVM](http://hhvm.com/). However, there are some edge cases where HHVM behaves different than native +[HHVM](https://hhvm.com/). However, there are some edge cases where HHVM behaves different than native PHP, so you have to take some extra care when using HHVM. On a production server, you may want to configure your Web server so that the application can be accessed @@ -236,7 +236,7 @@ DocumentRoot "path/to/basic/web" ### Recommended Nginx Configuration -To use [Nginx](http://wiki.nginx.org/), you should install PHP as an [FPM SAPI](https://secure.php.net/install.fpm). +To use [Nginx](https://wiki.nginx.org/), you should install PHP as an [FPM SAPI](https://www.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.test` with the actual hostname to serve. @@ -378,5 +378,5 @@ It's recommended to host the application in a virtual host (Web site) where docu ``` Also the following list of Microsoft's official resources could be useful in order to configure PHP on IIS: - 1. [How to set up your first IIS Web site](https://support.microsoft.com/en-us/help/323972/how-to-set-up-your-first-iis-web-site) + 1. [How to set up your first IIS Web site](https://docs.microsoft.com/en-us/iis/manage/creating-websites/scenario-build-a-static-website-on-iis) 2. [Configure a PHP Website on IIS](https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configure-a-php-website-on-iis) diff --git a/docs/guide/start-looking-ahead.md b/docs/guide/start-looking-ahead.md index a9ba1b31f64..e8c732f71c5 100644 --- a/docs/guide/start-looking-ahead.md +++ b/docs/guide/start-looking-ahead.md @@ -9,28 +9,28 @@ code automatically. Using Gii for code generation turns the bulk of your Web dev This section will summarize the Yii resources available to help you be more productive when using the framework. * Documentation - - [The Definitive Guide](http://www.yiiframework.com/doc-2.0/guide-README.html): + - [The Definitive Guide](https://www.yiiframework.com/doc-2.0/guide-README.html): As the name indicates, the guide precisely defines how Yii should work and provides general guidance about using Yii. It is the single most important Yii tutorial, and one that you should read before writing any Yii code. - - [The Class Reference](http://www.yiiframework.com/doc-2.0/index.html): + - [The Class Reference](https://www.yiiframework.com/doc-2.0/index.html): This specifies the usage of every class provided by Yii. It should be mainly used when you are writing code and want to understand the usage of a particular class, method, property. Usage of the class reference is best only after a contextual understanding of the entire framework. - - [The Wiki Articles](http://www.yiiframework.com/wiki/?tag=yii2): + - [The Wiki Articles](https://www.yiiframework.com/wiki/?tag=yii2): The wiki articles are written by Yii users based on their own experiences. Most of them are written like cookbook recipes, and show how to solve particular problems using Yii. While the quality of these articles may not be as good as the Definitive Guide, they are useful in that they cover broader topics and can often provide ready-to-use solutions. - - [Books](http://www.yiiframework.com/doc/) -* [Extensions](http://www.yiiframework.com/extensions/): + - [Books](https://www.yiiframework.com/books) +* [Extensions](https://www.yiiframework.com/extensions/): Yii boasts a library of thousands of user-contributed extensions that can be easily plugged into your applications, thereby making your application development even faster and easier. * Community - - Forum: - - IRC chat: The #yii channel on the freenode network () + - Forum: + - IRC chat: The #yii channel on the Libera () - Slack chanel: - Gitter chat: - GitHub: - Facebook: - Twitter: - LinkedIn: - - Stackoverflow: + - Stackoverflow: diff --git a/docs/guide/start-prerequisites.md b/docs/guide/start-prerequisites.md index a662478b826..4043b57e396 100644 --- a/docs/guide/start-prerequisites.md +++ b/docs/guide/start-prerequisites.md @@ -4,8 +4,8 @@ The Yii learning curve is not as steep as other PHP frameworks but still there a ## PHP -Yii is a PHP framework so make sure you [read and understand language reference](https://secure.php.net/manual/en/langref.php). -When developing with Yii you will be writing code in an object oriented fashion, so make sure you are familiar with [Classes and Objects](https://secure.php.net/manual/en/language.oop5.basic.php) as well as [namespaces](https://secure.php.net/manual/en/language.namespaces.php). +Yii is a PHP framework so make sure you [read and understand language reference](https://www.php.net/manual/en/langref.php). +When developing with Yii you will be writing code in an object oriented fashion, so make sure you are familiar with [Classes and Objects](https://www.php.net/manual/en/language.oop5.basic.php) as well as [namespaces](https://www.php.net/manual/en/language.namespaces.php). ## Object oriented programming diff --git a/docs/guide/start-workflow.md b/docs/guide/start-workflow.md index 454b07e2de3..07db9e5aa3e 100644 --- a/docs/guide/start-workflow.md +++ b/docs/guide/start-workflow.md @@ -63,7 +63,7 @@ basic/ application base path In general, the files in the application can be divided into two types: those under `basic/web` and those under other directories. The former can be directly accessed via HTTP (i.e., in a browser), while the latter can not and should not be. -Yii implements the [model-view-controller (MVC)](http://wikipedia.org/wiki/Model-view-controller) architectural pattern, +Yii implements the [model-view-controller (MVC)](https://wikipedia.org/wiki/Model-view-controller) architectural pattern, which is reflected in the above directory organization. The `models` directory contains all [model classes](structure-models.md), the `views` directory contains all [view scripts](structure-views.md), and the `controllers` directory contains all [controller classes](structure-controllers.md). diff --git a/docs/guide/structure-applications.md b/docs/guide/structure-applications.md index b057d6c359a..1f0eaf457d8 100644 --- a/docs/guide/structure-applications.md +++ b/docs/guide/structure-applications.md @@ -275,7 +275,7 @@ including message translation, date formatting, number formatting, etc. For exam will use this property value by default to determine in which language the calendar should be displayed and how the date should be formatted. -It is recommended that you specify a language in terms of an [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag). +It is recommended that you specify a language in terms of an [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands for English, while `en-US` stands for English (United States). More details about this property can be found in the [Internationalization](tutorial-i18n.md) section. @@ -347,7 +347,7 @@ This property specifies the language that the application code is written in. Th meaning English (United States). You should configure this property if the text content in your code is not in English. Like the [language](#language) property, you should configure this property in terms of -an [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands for English, +an [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands for English, while `en-US` stands for English (United States). More details about this property can be found in the [Internationalization](tutorial-i18n.md) section. @@ -357,7 +357,7 @@ More details about this property can be found in the [Internationalization](tuto This property is provided as an alternative way of setting the default time zone of the PHP runtime. By configuring this property, you are essentially calling the PHP function -[date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php). For example: +[date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php). For example: ```php [ diff --git a/docs/guide/structure-assets.md b/docs/guide/structure-assets.md index 8f178c836cd..8dc397611d8 100644 --- a/docs/guide/structure-assets.md +++ b/docs/guide/structure-assets.md @@ -79,7 +79,7 @@ explanation about the properties of [[yii\web\AssetBundle]] can be found in the can be determined by prepending [[yii\web\AssetManager::basePath]] to the relative path, and the actual URL of the file can be determined by prepending [[yii\web\AssetManager::baseUrl]] to the relative path. - an absolute URL representing an external JavaScript file. For example, - `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` or + `https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` or `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`. * [[yii\web\AssetBundle::depends|depends]]: an array listing the names of the asset bundles that this bundle depends on (to be explained shortly). @@ -201,13 +201,13 @@ class FontAwesomeAsset extends AssetBundle } ``` -The above example defines an asset bundle for the ["fontawesome" package](http://fontawesome.io/). By specifying +The above example defines an asset bundle for the ["fontawesome" package](https://fontawesome.com/). By specifying the `only` publishing option, only the `fonts` and `css` subdirectories will be published. ### Bower and NPM Assets installation -Most JavaScript/CSS packages are managed by [Bower](http://bower.io/) and/or [NPM](https://www.npmjs.org/) package +Most JavaScript/CSS packages are managed by [Bower](http://bower.io/) and/or [NPM](https://www.npmjs.com/) package managers. In PHP world we have Composer, that manages PHP dependencies, but it is possible to load both Bower and NPM packages using `composer.json` just as PHP packages. @@ -257,7 +257,7 @@ requires global installation of a special Composer plugin by running the followi composer global require "fxp/composer-asset-plugin:^1.4.1" ``` -This command installs [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) globally +This command installs [composer asset plugin](https://github.com/fxpio/composer-asset-plugin/) globally which allows managing Bower and NPM package dependencies through Composer. After the plugin installation, every single project on your computer will support Bower and NPM packages through `composer.json`. @@ -610,13 +610,13 @@ in extended syntax. Yii uses the file name extensions to identify which extended syntax an asset is in. By default it recognizes the following syntax and file name extensions: -- [LESS](http://lesscss.org/): `.less` -- [SCSS](http://sass-lang.com/): `.scss` -- [Stylus](http://learnboost.github.io/stylus/): `.styl` -- [CoffeeScript](http://coffeescript.org/): `.coffee` -- [TypeScript](http://www.typescriptlang.org/): `.ts` +- [LESS](https://lesscss.org/): `.less` +- [SCSS](https://sass-lang.com/): `.scss` +- [Stylus](https://stylus-lang.com/): `.styl` +- [CoffeeScript](https://coffeescript.org/): `.coffee` +- [TypeScript](https://www.typescriptlang.org/): `.ts` -Yii relies on the installed pre-processor tools to convert assets. For example, to use [LESS](http://lesscss.org/) +Yii relies on the installed pre-processor tools to convert assets. For example, to use [LESS](https://lesscss.org/) you should install the `lessc` pre-processor command. You can customize the pre-processor commands and the supported extended syntax by configuring diff --git a/docs/guide/structure-controllers.md b/docs/guide/structure-controllers.md index ee1708b317c..7bee33d30fd 100644 --- a/docs/guide/structure-controllers.md +++ b/docs/guide/structure-controllers.md @@ -1,7 +1,7 @@ Controllers =========== -Controllers are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. +Controllers are part of the [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. They are objects of classes extending from [[yii\base\Controller]] and are responsible for processing requests and generating responses. In particular, after taking over the control from [applications](structure-applications.md), controllers will analyze incoming request data, pass them to [models](structure-models.md), inject model results diff --git a/docs/guide/structure-entry-scripts.md b/docs/guide/structure-entry-scripts.md index 93f92963b09..fd03f1dc2b0 100644 --- a/docs/guide/structure-entry-scripts.md +++ b/docs/guide/structure-entry-scripts.md @@ -57,9 +57,9 @@ Similarly, the following is the code for the entry script of a console applicati /** * Yii console bootstrap file. * - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ defined('YII_DEBUG') or define('YII_DEBUG', true); diff --git a/docs/guide/structure-extensions.md b/docs/guide/structure-extensions.md index a0f10956390..6409c91cc0d 100644 --- a/docs/guide/structure-extensions.md +++ b/docs/guide/structure-extensions.md @@ -127,9 +127,9 @@ The following example shows the `composer.json` file for the `yiisoft/yii2-imagi "license": "BSD-3-Clause", "support": { "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki/", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "authors": [ @@ -184,8 +184,8 @@ If your extension also depends on other extensions or third-party libraries, you Make sure you also list appropriate version constraints (e.g. `1.*`, `@stable`) for each dependent package. Use stable dependencies when your extension is released in a stable version. -Most JavaScript/CSS packages are managed using [Bower](http://bower.io/) and/or [NPM](https://www.npmjs.org/), -instead of Composer. Yii uses the [Composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin) +Most JavaScript/CSS packages are managed using [Bower](http://bower.io/) and/or [NPM](https://www.npmjs.com/), +instead of Composer. Yii uses the [Composer asset plugin](https://github.com/fxpio/composer-asset-plugin) to enable managing these kinds of packages through Composer. If your extension depends on a Bower package, you can simply list the dependency in `composer.json` like the following: @@ -383,7 +383,7 @@ help other people learn about and use your extension: for you to generate pretty API documentation based on your code comments. > Info: While not a requirement, we suggest your extension adhere to certain coding styles. You may refer to - the [core framework code style](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style). + the [core framework code style](https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md). ## Core Extensions @@ -399,14 +399,12 @@ registered on [Packagist](https://packagist.org/) and can be easily installed as provides a set of commonly used auth clients, such as Facebook OAuth2 client, GitHub OAuth2 client. - [yiisoft/yii2-bootstrap](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap): provides a set of widgets that encapsulate the [Bootstrap](http://getbootstrap.com/) components and plugins. -- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception) (deprecated): - provides testing support based on [Codeception](http://codeception.com/). - [yiisoft/yii2-debug](https://www.yiiframework.com/extension/yiisoft/yii2-debug): provides debugging support for Yii applications. When this extension is used, a debugger toolbar will appear at the bottom of every page. The extension also provides a set of standalone pages to display more detailed debug information. - [yiisoft/yii2-elasticsearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch): - provides the support for using [Elasticsearch](http://www.elasticsearch.org/). It includes basic querying/search + provides the support for using [Elasticsearch](https://www.elastic.co/). It includes basic querying/search support and also implements the [Active Record](db-active-record.md) pattern that allows you to store active records in Elasticsearch. - [yiisoft/yii2-faker](https://www.yiiframework.com/extension/yiisoft/yii2-faker): @@ -421,7 +419,7 @@ registered on [Packagist](https://packagist.org/) and can be easily installed as - [yiisoft/yii2-jui](https://www.yiiframework.com/extension/yiisoft/yii2-jui): provides a set of widgets that encapsulate the [JQuery UI](http://jqueryui.com/) interactions and widgets. - [yiisoft/yii2-mongodb](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb): - provides the support for using [MongoDB](http://www.mongodb.org/). It includes features such as basic query, + provides the support for using [MongoDB](https://www.mongodb.com/). It includes features such as basic query, Active Record, migrations, caching, code generation, etc. - [yiisoft/yii2-queue](https://www.yiiframework.com/extension/yiisoft/yii2-queue): provides the supports for running tasks asynchronously via queues. @@ -439,7 +437,7 @@ registered on [Packagist](https://packagist.org/) and can be easily installed as - [yiisoft/yii2-swiftmailer](https://www.yiiframework.com/extension/yiisoft/yii2-swiftmailer): provides email sending features based on [swiftmailer](http://swiftmailer.org/). - [yiisoft/yii2-twig](https://www.yiiframework.com/extension/yiisoft/yii2-twig): - provides a template engine based on [Twig](http://twig.sensiolabs.org/). + provides a template engine based on [Twig](https://twig.symfony.com/). The following official extensions are for Yii 2.1 and above. You don't need to install them for Yii 2.0, since they are included in the core framework. diff --git a/docs/guide/structure-filters.md b/docs/guide/structure-filters.md index 0789814fc7a..8fb6d376ffe 100644 --- a/docs/guide/structure-filters.md +++ b/docs/guide/structure-filters.md @@ -121,7 +121,7 @@ public function behaviors() { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'only' => ['create', 'update'], 'rules' => [ // allow authenticated users @@ -142,7 +142,7 @@ For more details about access control in general, please refer to the [Authoriza ### Authentication Method Filters Authentication method filters are used to authenticate a user using various methods, such as -[HTTP Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication), [OAuth 2](http://oauth.net/2/). +[HTTP Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication), [OAuth 2](https://oauth.net/2/). These filter classes are all under the `yii\filters\auth` namespace. The following example shows how you can use [[yii\filters\auth\HttpBasicAuth]] to authenticate a user using @@ -157,7 +157,7 @@ public function behaviors() { return [ 'basicAuth' => [ - 'class' => HttpBasicAuth::className(), + 'class' => HttpBasicAuth::class, ], ]; } @@ -183,7 +183,7 @@ public function behaviors() { return [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -210,7 +210,7 @@ use yii\web\Response; [ 'bootstrap' => [ [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, @@ -241,7 +241,7 @@ public function behaviors() { return [ [ - 'class' => HttpCache::className(), + 'class' => HttpCache::class, 'only' => ['index'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); @@ -269,11 +269,11 @@ public function behaviors() { return [ 'pageCache' => [ - 'class' => PageCache::className(), + 'class' => PageCache::class, 'only' => ['index'], 'duration' => 60, 'dependency' => [ - 'class' => DbDependency::className(), + 'class' => DbDependency::class, 'sql' => 'SELECT COUNT(*) FROM post', ], 'variations' => [ @@ -289,7 +289,7 @@ Please refer to the [Page Caching](caching-page.md) section for more details abo ### [[yii\filters\RateLimiter|RateLimiter]] -RateLimiter implements a rate limiting algorithm based on the [leaky bucket algorithm](http://en.wikipedia.org/wiki/Leaky_bucket). +RateLimiter implements a rate limiting algorithm based on the [leaky bucket algorithm](https://en.wikipedia.org/wiki/Leaky_bucket). It is primarily used in implementing RESTful APIs. Please refer to the [Rate Limiting](rest-rate-limiting.md) section for details about using this filter. @@ -307,7 +307,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'index' => ['get'], 'view' => ['get'], @@ -339,7 +339,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, ], ], parent::behaviors()); } @@ -366,7 +366,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], @@ -387,7 +387,7 @@ public function behaviors() { return ArrayHelper::merge([ [ - 'class' => Cors::className(), + 'class' => Cors::class, 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], diff --git a/docs/guide/structure-models.md b/docs/guide/structure-models.md index 1cfc9bb95e8..928df70ab62 100644 --- a/docs/guide/structure-models.md +++ b/docs/guide/structure-models.md @@ -1,7 +1,7 @@ Models ====== -Models are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. +Models are part of the [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. They are objects representing business data, rules and logic. You can create model classes by extending [[yii\base\Model]] or its child classes. The base class @@ -37,7 +37,7 @@ echo $model->name; ``` You can also access attributes like accessing array elements, thanks to the support for -[ArrayAccess](https://secure.php.net/manual/en/class.arrayaccess.php) and [Traversable](https://secure.php.net/manual/en/class.traversable.php) +[ArrayAccess](https://www.php.net/manual/en/class.arrayaccess.php) and [Traversable](https://www.php.net/manual/en/class.traversable.php) by [[yii\base\Model]]: ```php diff --git a/docs/guide/structure-overview.md b/docs/guide/structure-overview.md index 3c535d50b32..1110f61dc9d 100644 --- a/docs/guide/structure-overview.md +++ b/docs/guide/structure-overview.md @@ -1,7 +1,7 @@ Overview ======== -Yii applications are organized according to the [model-view-controller (MVC)](http://wikipedia.org/wiki/Model-view-controller) +Yii applications are organized according to the [model-view-controller (MVC)](https://wikipedia.org/wiki/Model-view-controller) architectural pattern. [Models](structure-models.md) represent data, business logic and rules; [views](structure-views.md) are output representation of models; and [controllers](structure-controllers.md) take input and convert it to commands for [models](structure-models.md) and [views](structure-views.md). diff --git a/docs/guide/structure-views.md b/docs/guide/structure-views.md index 980ee11b2e1..12254cedf7d 100644 --- a/docs/guide/structure-views.md +++ b/docs/guide/structure-views.md @@ -1,7 +1,7 @@ Views ===== -Views are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. +Views are part of the [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. They are code responsible for presenting data to end users. In a Web application, views are usually created in terms of *view templates* which are PHP script files containing mainly HTML code and presentational PHP code. They are managed by the [[yii\web\View|view]] [application component](structure-application-components.md) which provides commonly used methods @@ -52,7 +52,7 @@ or other objects which trigger the [view rendering](#rendering-views). When creating views that generate HTML pages, it is important that you encode and/or filter the data coming from end users before presenting them. Otherwise, your application may be subject to -[cross-site scripting](http://en.wikipedia.org/wiki/Cross-site_scripting) attacks. +[cross-site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting) attacks. To display a plain text, encode it first by calling [[yii\helpers\Html::encode()]]. For example, the following code encodes the user name before displaying it: @@ -545,7 +545,7 @@ View components provide the following useful view-related features, each describ * [client script handling](output-client-scripts.md): supports CSS and JavaScript registration and rendering. * [asset bundle handling](structure-assets.md): supports registering and rendering of [asset bundles](structure-assets.md). * [alternative template engines](tutorial-template-engines.md): allows you to use other template engines, such as - [Twig](http://twig.sensiolabs.org/), [Smarty](http://www.smarty.net/). + [Twig](https://twig.symfony.com/), [Smarty](https://www.smarty.net/). You may also frequently use the following minor yet useful features when you are developing Web pages. @@ -616,14 +616,14 @@ $this->registerLinkTag([ 'title' => 'Live News for Yii', 'rel' => 'alternate', 'type' => 'application/rss+xml', - 'href' => 'http://www.yiiframework.com/rss.xml/', + 'href' => 'https://www.yiiframework.com/rss.xml/', ]); ``` The code above will result in ```html - + ``` Similar as [[yii\web\View::registerMetaTag()|registerMetaTag()]], you can specify a key when calling diff --git a/docs/guide/structure-widgets.md b/docs/guide/structure-widgets.md index e0791d6d629..65c0bb8f9f3 100644 --- a/docs/guide/structure-widgets.md +++ b/docs/guide/structure-widgets.md @@ -66,7 +66,7 @@ use yii\helpers\Html; Note that unlike [[yii\base\Widget::widget()]] which returns the rendering result of a widget, the method [[yii\base\Widget::begin()]] returns an instance of the widget which you can use to build the widget content. -> Note: Some widgets will use [output buffering](https://secure.php.net/manual/en/book.outcontrol.php) to adjust the enclosed +> Note: Some widgets will use [output buffering](https://www.php.net/manual/en/book.outcontrol.php) to adjust the enclosed > content when [[yii\base\Widget::end()]] is called. For this reason calling [[yii\base\Widget::begin()]] and > [[yii\base\Widget::end()]] is expected to happen in the same view file. > Not following this rule may result in unexpected output. diff --git a/docs/guide/test-acceptance.md b/docs/guide/test-acceptance.md index 9f5fb1bc726..189486d533b 100644 --- a/docs/guide/test-acceptance.md +++ b/docs/guide/test-acceptance.md @@ -6,8 +6,8 @@ a real browser. In both cases the browsers are communicating via HTTP so applica Acceptance testing is implemented with the help of Codeception framework which has a nice documentation about it: -- [Codeception for Yii framework](http://codeception.com/for/yii) -- [Codeception Acceptance Tests](http://codeception.com/docs/03-AcceptanceTests) +- [Codeception for Yii framework](https://codeception.com/for/yii) +- [Codeception Acceptance Tests](https://codeception.com/docs/03-AcceptanceTests) ## Running basic and advanced template tests diff --git a/docs/guide/test-fixtures.md b/docs/guide/test-fixtures.md index 8ba5a9a80a7..85a191c0f59 100644 --- a/docs/guide/test-fixtures.md +++ b/docs/guide/test-fixtures.md @@ -107,7 +107,7 @@ In the above, we have shown how to define a fixture about a DB table. To define ## Using Fixtures -If you are using [Codeception](http://codeception.com/) to test your code, you can use the built-in support for loading +If you are using [Codeception](https://codeception.com/) to test your code, you can use the built-in support for loading and accessing fixtures. If you are using other testing frameworks, you may use [[yii\test\FixtureTrait]] in your @@ -130,7 +130,7 @@ class UserProfileTest extends \Codeception\Test\Unit { return [ 'profiles' => [ - 'class' => UserProfileFixture::className(), + 'class' => UserProfileFixture::class, // fixture data located in tests/_data/user.php 'dataFile' => codecept_data_dir() . 'user.php' ], diff --git a/docs/guide/test-functional.md b/docs/guide/test-functional.md index 0c300fb65d7..908762f862a 100644 --- a/docs/guide/test-functional.md +++ b/docs/guide/test-functional.md @@ -11,8 +11,8 @@ JavaScript. Functional testing is implemented with the help of Codeception framework which has a nice documentation about it: -- [Codeception for Yii framework](http://codeception.com/for/yii) -- [Codeception Functional Tests](http://codeception.com/docs/04-FunctionalTests) +- [Codeception for Yii framework](https://codeception.com/for/yii) +- [Codeception Functional Tests](https://codeception.com/docs/04-FunctionalTests) ## Running basic and advanced template tests diff --git a/docs/guide/test-unit.md b/docs/guide/test-unit.md index 0159d4915fc..d9481474584 100644 --- a/docs/guide/test-unit.md +++ b/docs/guide/test-unit.md @@ -7,9 +7,9 @@ classes being tested. Unit testing in Yii is built on top of PHPUnit and, optionally, Codeception so it's recommended to go through their docs: -- [Codeception for Yii framework](http://codeception.com/for/yii) -- [Codeception Unit Tests](http://codeception.com/docs/05-UnitTests) -- [PHPUnit docs starting from chapter 2](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html) +- [Codeception for Yii framework](https://codeception.com/for/yii) +- [Codeception Unit Tests](https://codeception.com/docs/05-UnitTests) +- [PHPUnit docs starting from chapter 2](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html) ## Running basic and advanced template tests diff --git a/docs/guide/tutorial-core-validators.md b/docs/guide/tutorial-core-validators.md index 1b5a7e4a102..3b63fa2689d 100644 --- a/docs/guide/tutorial-core-validators.md +++ b/docs/guide/tutorial-core-validators.md @@ -82,7 +82,7 @@ is as specified by the `operator` property. is being used to validate an attribute, the default value of this property would be the name of the attribute suffixed with `_repeat`. For example, if the attribute being validated is `password`, then this property will default to `password_repeat`. -- `compareValue`: a constant value that the input value should be compared with. When both +- `compareValue`: a constant value (or a closure returning a value) that the input value should be compared with. When both of this property and `compareAttribute` are specified, this property will take precedence. - `operator`: the comparison operator. Defaults to `==`, meaning checking if the input value is equal to that of `compareAttribute` or `compareValue`. The following operators are supported: @@ -139,9 +139,9 @@ Optionally, it can convert the input value into a UNIX timestamp or other machin specified via [[yii\validators\DateValidator::timestampAttribute|timestampAttribute]]. - `format`: the date/time format that the value being validated should be in. - This can be a date time pattern as described in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). + This can be a date time pattern as described in the [ICU manual](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax). Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the PHP - `Datetime` class. Please refer to on supported formats. + `Datetime` class. Please refer to on supported formats. If this is not set, it will take the value of `Yii::$app->formatter->dateFormat`. See the [[yii\validators\DateValidator::$format|API documentation]] for more details. @@ -271,24 +271,49 @@ This validator checks if the input value is a valid email address. ```php [ // a1 needs to exist in the column represented by the "a1" attribute + // i.e. a1 = 1, valid if there is value 1 in column "a1" ['a1', 'exist'], + // equivalent of + ['a1', 'exist', 'targetAttribute' => 'a1'], + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a1']], // a1 needs to exist, but its value will use a2 to check for the existence + // i.e. a1 = 2, valid if there is value 2 in column "a2" ['a1', 'exist', 'targetAttribute' => 'a2'], + // equivalent of + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a2']], + + // a2 needs to exist, its value will use a2 to check for the existence, a1 will receive error message + // i.e. a2 = 2, valid if there is value 2 in column "a2" + ['a1', 'exist', 'targetAttribute' => ['a2']], + // equivalent of + ['a1', 'exist', 'targetAttribute' => ['a2' => 'a2']], // a1 and a2 need to exist together, and they both will receive error message + // i.e. a1 = 3, a2 = 4, valid if there is value 3 in column "a1" and value 4 in column "a2" [['a1', 'a2'], 'exist', 'targetAttribute' => ['a1', 'a2']], + // equivalent of + [['a1', 'a2'], 'exist', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a1 and a2 need to exist together, only a1 will receive error message + // i.e. a1 = 5, a2 = 6, valid if there is value 5 in column "a1" and value 6 in column "a2" ['a1', 'exist', 'targetAttribute' => ['a1', 'a2']], + // equivalent of + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a1 needs to exist by checking the existence of both a2 and a3 (using a1 value) + // i.e. a1 = 7, a2 = 8, valid if there is value 7 in column "a3" and value 8 in column "a2" ['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']], + // equivalent of + ['a1', 'exist', 'targetAttribute' => ['a2' => 'a2', 'a1' => 'a3']], // a1 needs to exist. If a1 is an array, then every element of it must exist. + // i.e. a1 = 9, valid if there is value 9 in column "a1" + // a1 = [9, 10], valid if there are values 9 and 10 in column "a1" ['a1', 'exist', 'allowArray' => true], - // type_id needs to exist in the column "id" in the table defined in ProductType class + // type_id needs to exist in the column "id" in the table defined in ProductType class + // i.e. type_id = 1, valid if there is value 1 in column "id" of ProductType's table ['type_id', 'exist', 'targetClass' => ProductType::class, 'targetAttribute' => ['type_id' => 'id']], // the same as the previous, but using already defined relation "type" @@ -310,10 +335,19 @@ multiple attribute values should exist). of the input value. If not set, it will use the name of the attribute currently being validated. You may use an array to validate the existence of multiple columns at the same time. The array values are the attributes that will be used to validate the existence, while the array keys are the attributes - whose values are to be validated. If the key and the value are the same, you can just specify the value. + whose values are to be validated. If the key, and the value are the same, you can just specify the value. + Assuming we have ModelA to be validated and ModelB set as the target class the following `targetAttribute`'s + configurations are taken as: + - `null` => value of a currently validated attribute of ModelA will be checked against stored values of ModelB's attribute with the same name + - `'a'` => value of a currently validated attribute of ModelA will be checked against stored values of attribute "a" of ModelB + - `['a']` => value of attribute "a" of ModelA will be checked against stored values of attribute "a" of ModelB + - `['a' => 'a']` => the same as above + - `['a', 'b']` => value of attribute "a" of ModelA will be checked against stored values of attribute "a" of ModelB and + at the same time value of attribute "b" of ModelA will be checked against stored values of attribute "b" of ModelB + - `['a' => 'b']` => value of attribute "a" of ModelA will be checked against stored values of attribute "b" of ModelB - `targetRelation`: since version 2.0.14 you can use convenient attribute `targetRelation`, which overrides the `targetClass` and `targetAttribute` attributes using specs from the requested relation. -- `filter`: additional filter to be applied to the DB query used to check the existence of the input value. - This can be a string or an array representing the additional query condition (refer to [[yii\db\Query::where()]] +- `filter`: an additional filter to be applied to the DB query used to check the existence of the input value. + This can be a string, or an array representing the additional query condition (refer to [[yii\db\Query::where()]] on the format of query condition), or an anonymous function with the signature `function ($query)`, where `$query` is the [[yii\db\Query|Query]] object that you can modify in the function. - `allowArray`: whether to allow the input value to be an array. Defaults to `false`. If this property is `true` @@ -342,7 +376,7 @@ This validator checks if the input is a valid uploaded file. The wildcard mask with the special character `*` can be used to match groups of mime types. For example `image/*` will pass all mime types, that begin with `image/` (e.g. `image/jpeg`, `image/png`). Mime type names are case-insensitive. Defaults to `null`, meaning all MIME types are allowed. - For more details, please refer to [common media types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types). + For more details, please refer to [common media types](https://en.wikipedia.org/wiki/Media_type). - `minSize`: the minimum number of bytes required for the uploaded file. Defaults to `null`, meaning no lower limit. - `maxSize`: the maximum number of bytes allowed for the uploaded file. Defaults to `null`, meaning no upper limit. - `maxFiles`: the maximum number of files that the given attribute can hold. Defaults to 1, meaning @@ -390,8 +424,8 @@ back to the attribute being validated. > Tip: If you want to trim input values, you may directly use the [trim](#trim) validator. > Tip: There are many PHP functions that have the signature expected for the `filter` callback. -> For example to apply type casting (using e.g. [intval](https://secure.php.net/manual/en/function.intval.php), -> [boolval](https://secure.php.net/manual/en/function.boolval.php), ...) to ensure a specific type for an attribute, +> For example to apply type casting (using e.g. [intval](https://www.php.net/manual/en/function.intval.php), +> [boolval](https://www.php.net/manual/en/function.boolval.php), ...) to ensure a specific type for an attribute, > you can simply specify the function names of the filter without the need to wrap them in a closure: > > ```php @@ -639,19 +673,34 @@ the input value. Note that if the input value is an array, it will be ignored by ```php [ // a1 needs to be unique in the column represented by the "a1" attribute + // i.e. a1 = 1, valid if there is no value 1 in column "a1" ['a1', 'unique'], + // equivalent of + ['a1', 'unique', 'targetAttribute' => 'a1'], + ['a1', 'unique', 'targetAttribute' => ['a1' => 'a1']], // a1 needs to be unique, but column a2 will be used to check the uniqueness of the a1 value + // i.e. a1 = 2, valid if there is no value 2 in column "a2" ['a1', 'unique', 'targetAttribute' => 'a2'], + // equivalent of + ['a1', 'unique', 'targetAttribute' => ['a1' => 'a2']], // a1 and a2 need to be unique together, and they both will receive error message + // i.e. a1 = 3, a2 = 4, valid if there is no value 3 in column "a1" and at the same time no value 4 in column "a2" [['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2']], + // equivalent of + [['a1', 'a2'], 'unique', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a1 and a2 need to be unique together, only a1 will receive error message ['a1', 'unique', 'targetAttribute' => ['a1', 'a2']], // a1 needs to be unique by checking the uniqueness of both a2 and a3 (using a1 value) + // i.e. a1 = 5, a2 = 6, valid if there is no value 5 in column "a3" and at the same time no value 6 in column "a2" ['a1', 'unique', 'targetAttribute' => ['a2', 'a1' => 'a3']], + + // type_id needs to be unique in the column "id" in the table defined in ProductType class + // i.e. type_id = 1, valid if there is no value 1 in column "id" of ProductType's table + ['type_id', 'unique', 'targetClass' => ProductType::class, 'targetAttribute' => 'id'], ] ``` @@ -665,9 +714,18 @@ either a single column or multiple columns. of the input value. If not set, it will use the name of the attribute currently being validated. You may use an array to validate the uniqueness of multiple columns at the same time. The array values are the attributes that will be used to validate the uniqueness, while the array keys are the attributes - whose values are to be validated. If the key and the value are the same, you can just specify the value. -- `filter`: additional filter to be applied to the DB query used to check the uniqueness of the input value. - This can be a string or an array representing the additional query condition (refer to [[yii\db\Query::where()]] + whose values are to be validated. If the key, and the value are the same, you can just specify the value. + Assuming we have ModelA to be validated and ModelB set as the target class the following `targetAttribute`'s + configurations are taken as: + - `null` => value of a currently validated attribute of ModelA will be checked against stored values of ModelB's attribute with the same name + - `'a'` => value of a currently validated attribute of ModelA will be checked against stored values of attribute "a" of ModelB + - `['a']` => value of attribute "a" of ModelA will be checked against stored values of attribute "a" of ModelB + - `['a' => 'a']` => the same as above + - `['a', 'b']` => value of attribute "a" of ModelA will be checked against stored values of attribute "a" of ModelB and + at the same time value of attribute "b" of ModelA will be checked against stored values of attribute "b" of ModelB + - `['a' => 'b']` => value of attribute "a" of ModelA will be checked against stored values of attribute "b" of ModelB +- `filter`: an additional filter to be applied to the DB query used to check the uniqueness of the input value. + This can be a string, or an array representing the additional query condition (refer to [[yii\db\Query::where()]] on the format of query condition), or an anonymous function with the signature `function ($query)`, where `$query` is the [[yii\db\Query|Query]] object that you can modify in the function. diff --git a/docs/guide/tutorial-docker.md b/docs/guide/tutorial-docker.md index 61cad4ee4a0..1ad01b07212 100644 --- a/docs/guide/tutorial-docker.md +++ b/docs/guide/tutorial-docker.md @@ -5,14 +5,14 @@ For development and deployments Yii applications can be run as Docker containers Containers can solve many issues such as having identical software versions at developer's computer and the server, fast deployments or simulating multi-server architecture while developing. -You can read more about Docker containers on [docker.com](https://www.docker.com/what-docker). +You can read more about Docker containers on [docker.com](https://www.docker.com/why-docker). ## Requirements - `docker` - `docker-compose` -Visit the [download page](https://www.docker.com/community-edition) to get the Docker tooling. +Visit the [download page](https://www.docker.com/products/container-runtime) to get the Docker tooling. ## Installation diff --git a/docs/guide/tutorial-i18n.md b/docs/guide/tutorial-i18n.md index 75cbb7e9014..1bfbb566272 100644 --- a/docs/guide/tutorial-i18n.md +++ b/docs/guide/tutorial-i18n.md @@ -19,10 +19,10 @@ For example, the ID `en-US` stands for the locale of "English and the United Sta For consistency reasons, all locale IDs used in Yii applications should be canonicalized to the format of `ll-CC`, where `ll` is a two- or three-letter lowercase language code according to -[ISO-639](http://www.loc.gov/standards/iso639-2/) and `CC` is a two-letter country code according to +[ISO-639](https://www.loc.gov/standards/iso639-2/) and `CC` is a two-letter country code according to [ISO-3166](https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes). More details about locale can be found in the -[documentation of the ICU project](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept). +[documentation of the ICU project](https://unicode-org.github.io/icu/userguide/locale/#the-locale-concept). ### Language @@ -231,7 +231,7 @@ $price = 100; echo \Yii::t('app', 'Price: {0,number,currency}', $price); ``` -> Note: Parameter formatting requires the installation of the [intl PHP extension](https://secure.php.net/manual/en/intro.intl.php). +> Note: Parameter formatting requires the installation of the [intl PHP extension](https://www.php.net/manual/en/intro.intl.php). You can use either the short form or the full form to specify a placeholder with formatting: @@ -246,7 +246,7 @@ full form: {name,type,style} echo Yii::t('app', "Example of string with ''-escaped characters'': '{' '}' '{test}' {count,plural,other{''count'' value is # '#{}'}}", ['count' => 3]); ``` -Complete format is described in the [ICU documentation](http://icu-project.org/apiref/icu4c/classMessageFormat.html). +Complete format is described in the [ICU documentation](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classMessageFormat.html). In the following we will show some common usages. @@ -274,7 +274,7 @@ echo \Yii::t('app', 'Balance: {0,number,,000,000000}', $sum); ``` Characters used in the custom format could be found in -[ICU API reference](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html) under "Special Pattern Characters" +[ICU API reference](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classDecimalFormat.html) under "Special Pattern Characters" section. @@ -302,7 +302,7 @@ You can also specify a custom pattern to format the date value: echo \Yii::t('app', 'Today is {0,date,yyyy-MM-dd}', time()); ``` -[Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +[Formatting reference](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### Time @@ -325,7 +325,7 @@ You can also specify a custom pattern to format the time value: echo \Yii::t('app', 'It is {0,date,HH:mm}', time()); ``` -[Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#details). +[Formatting reference](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details). #### Spellout @@ -347,7 +347,7 @@ echo \Yii::t('app', 'I am {n,spellout,%spellout-ordinal} agent', ['n' => 47]); Note that there should be no space after `spellout,` and before `%`. To get a list of options available for locale you're using check -"Numbering schemas, Spellout" at [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/). +"Numbering schemas, Spellout" at [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). #### Ordinal @@ -368,7 +368,7 @@ echo \Yii::t('app', '{n,ordinal,%digits-ordinal-feminine}', ['n' => 471]); Note that there should be no space after `ordinal,` and before `%`. To get a list of options available for locale you're using check -"Numbering schemas, Ordinal" at [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/). +"Numbering schemas, Ordinal" at [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). #### Duration @@ -389,7 +389,7 @@ echo \Yii::t('app', '{n,duration,%in-numerals}', ['n' => 471227]); Note that there should be no space after `duration,` and before `%`. To get a list of options available for locale you're using check -"Numbering schemas, Duration" at [http://intl.rmcreative.ru/](http://intl.rmcreative.ru/). +"Numbering schemas, Duration" at [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). #### Plural @@ -415,8 +415,8 @@ 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://cldr.unicode.org/index/cldr-spec/plural-rules). +specify for a particular locale, please refer to "Plural Rules, Cardinal" at [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). +Alternatively you can refer to [rules reference at unicode.org](https://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. @@ -441,7 +441,7 @@ echo Yii::t('app', 'You {likeCount,plural, // You and one other person liked this ``` -#### Ordinal selection +#### Ordinal selection The parameter type of `selectordinal` is meant to choose a string based on language rules for ordinals for the locale you are translating to: @@ -460,8 +460,8 @@ echo Yii::t('app', 'You are the {n,selectordinal,one{#st} two{#nd} few{#rd} othe ``` The format is very close to what's used for plurals. To learn which arguments you should specify for a particular locale, -please refer to "Plural Rules, Ordinal" 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). +please refer to "Plural Rules, Ordinal" at [https://intl.rmcreative.ru/](https://intl.rmcreative.ru/). +Alternatively you can refer to [rules reference at unicode.org](https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html). #### Selection @@ -738,12 +738,12 @@ See the [Data Formatting](output-formatting.md) section for details. ## Setting Up PHP Environment -Yii uses the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) to provide most of its I18N features, +Yii uses the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) to provide most of its I18N features, such as the date and number formatting of the [[yii\i18n\Formatter]] class and the message formatting using [[yii\i18n\MessageFormatter]]. Both classes provide a fallback mechanism when the `intl` extension is not installed. However, the fallback implementation only works well for English target language. So it is highly recommended that you install `intl` when I18N is needed. -The [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is based on the [ICU library](http://site.icu-project.org/) which +The [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is based on the [ICU library](https://icu.unicode.org/) which provides the knowledge and formatting rules for all different locales. Different versions of ICU may produce different formatting result of date and number values. To ensure your website produces the same results across all environments, it is recommended that you install the same version of the `intl` extension (and thus the same version of ICU) @@ -760,10 +760,10 @@ echo "ICU Data: " . INTL_ICU_DATA_VERSION . "\n"; It is also recommended that you use an ICU version equal or greater than version 49. This will ensure you can use all the features described in this document. For example, an ICU version below 49 does not support using `#` placeholders in plural rules. -Please refer to for a complete list of available ICU versions. Note that the version +Please refer to for a complete list of available ICU versions. Note that the version numbering has changed after the 4.8 release (e.g., ICU 4.8, ICU 49, ICU 50, etc.) Additionally the information in the time zone database shipped with the ICU library may be outdated. Please refer -to the [ICU manual](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data) for details +to the [ICU manual](https://unicode-org.github.io/icu/userguide/datetime/timezone/#updating-the-time-zone-data) for details on updating the time zone database. While for output formatting the ICU timezone database is used, the time zone database used by PHP may be relevant too. You can update it by installing the latest version of the [pecl package `timezonedb`](https://pecl.php.net/package/timezonedb). diff --git a/docs/guide/tutorial-performance-tuning.md b/docs/guide/tutorial-performance-tuning.md index b7a85b45543..104a055fb31 100644 --- a/docs/guide/tutorial-performance-tuning.md +++ b/docs/guide/tutorial-performance-tuning.md @@ -11,7 +11,7 @@ factors and explain how you can improve your application performance by adjustin A well configured PHP environment is very important. In order to get maximum performance, - Use the latest stable PHP version. Major releases of PHP may bring significant performance improvements. -- Enable bytecode caching with [Opcache](https://secure.php.net/opcache) (PHP 5.5 or later) or [APC](https://secure.php.net/apc) +- Enable bytecode caching with [Opcache](https://www.php.net/opcache) (PHP 5.5 or later) or [APC](https://www.php.net/manual/en/book.apcu.php) (PHP 5.4). Bytecode caching avoids the time spent in parsing and including PHP scripts for every incoming request. - [Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner). @@ -190,7 +190,7 @@ composer dumpautoload -o Additionally you may consider using [authoritative class maps](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) and [APCu cache](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). -Note that both opmizations may or may not be suitable for your particular case. +Note that both optimizations may or may not be suitable for your particular case. ## Processing Data Offline @@ -217,9 +217,9 @@ The following profiling tools may be useful: - [Yii debug toolbar and debugger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md) - [Blackfire](https://blackfire.io/) -- [XHProf](https://secure.php.net/manual/en/book.xhprof.php) +- [XHProf](https://www.php.net/manual/en/book.xhprof.php) - [XDebug profiler](http://xdebug.org/docs/profiler) ## Prepare application for scaling -When nothing helps you may try making your application scalabe. A good introduction is provided in [Configuring a Yii 2 Application for an Autoscaling Stack](https://github.com/samdark/yii2-cookbook/blob/master/book/scaling.md). +When nothing helps you may try making your application scalable. A good introduction is provided in [Configuring a Yii 2 Application for an Autoscaling Stack](https://github.com/samdark/yii2-cookbook/blob/master/book/scaling.md). diff --git a/docs/guide/tutorial-start-from-scratch.md b/docs/guide/tutorial-start-from-scratch.md index 9249331e290..033d01a53de 100644 --- a/docs/guide/tutorial-start-from-scratch.md +++ b/docs/guide/tutorial-start-from-scratch.md @@ -42,7 +42,7 @@ Make a Package -------------- With the template defined, create a Git repository from it, and push your files there. If you're going to open source -your template, [Github](http://github.com) is the best place to host it. If you intend to keep your template +your template, [Github](https://github.com) is the best place to host it. If you intend to keep your template non-collaborative, any Git repository site will do. Next, you need to register your package for Composer's sake. For public templates, the package should be registered diff --git a/docs/guide/tutorial-template-engines.md b/docs/guide/tutorial-template-engines.md index 70f35619195..c6017fb7fe1 100644 --- a/docs/guide/tutorial-template-engines.md +++ b/docs/guide/tutorial-template-engines.md @@ -2,7 +2,7 @@ Using template engines ====================== By default, Yii uses PHP as its template language, but you can configure Yii to support other rendering engines, such as -[Twig](http://twig.sensiolabs.org/) or [Smarty](http://www.smarty.net/) available as extensions. +[Twig](https://twig.symfony.com/) or [Smarty](https://www.smarty.net/) available as extensions. The `view` component is responsible for rendering views. You can add a custom template engine by reconfiguring this component's behavior: diff --git a/docs/guide/tutorial-yii-integration.md b/docs/guide/tutorial-yii-integration.md index 49b7d4481e7..e1bd6d5f08e 100644 --- a/docs/guide/tutorial-yii-integration.md +++ b/docs/guide/tutorial-yii-integration.md @@ -41,7 +41,7 @@ If a library carries its own class autoloader, you may install it in the [entry of your application. It is recommended the installation is done before you include the `Yii.php` file so that the Yii class autoloader can take precedence in autoloading classes. -If a library does not provide a class autoloader, but its class naming follows [PSR-4](http://www.php-fig.org/psr/psr-4/), +If a library does not provide a class autoloader, but its class naming follows [PSR-4](https://www.php-fig.org/psr/psr-4/), you may use the Yii class autoloader to autoload the classes. All you need to do is just to declare a [root alias](concept-aliases.md#defining-aliases) for each root namespace used in its classes. For example, assume you have installed a library in the directory `vendor/foo/bar`, and the library classes are under @@ -93,7 +93,7 @@ you should require a special composer package that prevent Bower and NPM package See also the general [section about installing Yii](start-installation.md#installing-via-composer) for more information on Composer and solution to possible issues popping up during the installation. -Otherwise, you can [download](http://www.yiiframework.com/download/) the Yii release file and unpack it in +Otherwise, you can [download](https://www.yiiframework.com/download/) the Yii release file and unpack it in the `BasePath/vendor` directory. Next, you should modify the entry script of the 3rd-party system by including the following code at the beginning: diff --git a/docs/internals-es/translation-workflow.md b/docs/internals-es/translation-workflow.md index 2896bc8b24d..105dab3326f 100644 --- a/docs/internals-es/translation-workflow.md +++ b/docs/internals-es/translation-workflow.md @@ -13,7 +13,7 @@ que en realidad son visibles para el usuario final, tales como errores de valida El orden para comenzar con la traducción de mensajes: 1. Comprobar que en `framework/messages/config.php` su idioma aparece en `languages`. Si no, añade tu idioma allí (recuerda que debes mantener la lista en orden alfabético). -El formato de código de idioma debe seguir el [Código de Idiomas IETF](http://es.wikipedia.org/wiki/C%C3%B3digo_de_idioma_IETF), por ejemplo, `es`. +El formato de código de idioma debe seguir el [Código de Idiomas IETF](https://es.wikipedia.org/wiki/C%C3%B3digo_de_idioma_IETF), por ejemplo, `es`. 2. Ir al directorio `framework` y ejecutar el comando `yii message/extract @yii/messages/config.php --languages=`. 3. Traducir los mensajes en `framework/messages/tu-idioma/yii.php`. Asegúrate de guardar el archivo con codificación UTF-8. 4. [Crear un pull request](https://github.com/yiisoft/yii2/blob/master/docs/internals-es/git-workflow.md). diff --git a/docs/internals-fa/core-code-style.md b/docs/internals-fa/core-code-style.md index dfce6988bac..e63e2b77951 100644 --- a/docs/internals-fa/core-code-style.md +++ b/docs/internals-fa/core-code-style.md @@ -331,7 +331,7 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { مستند نویسی ------------- -

      [phpDoc](http://phpdoc.org/) رو بخونید و موارد اونُ رعایت کنید.

      +

      [phpDoc](https://phpdoc.org/) رو بخونید و موارد اونُ رعایت کنید.

      کد بدون مستندات مجاز نیست.

      تمام کلاس ها باید شامل بلاک مستندات در ابتدای فایل باشند.

      نیازی به نوشتن return@ ندارید اگر متد شما اگر چیزی را برنمیگرداند.

      @@ -356,9 +356,9 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { ```php getResult(); @@ -362,7 +362,7 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { ドキュメント ------------ -- ドキュメントの文法については [phpDoc](http://phpdoc.org/) を参照してください。 +- ドキュメントの文法については [phpDoc](https://phpdoc.org/) を参照してください。 - ドキュメントの無いコードは許容されません。 - 全てのクラス・ファイルは、ファイル・レベルの doc ブロックを各ファイルの先頭に持ち、 クラス・レベルの doc ブロックを各クラスの直前に持たなければなりません。 @@ -395,9 +395,9 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { ```php Tip: あなたが Git に精通していない場合は、素晴らしい無料の [プロ Git ブック](https://git-scm.com/book/en/v2) を読むことをお勧めします。 @@ -154,7 +154,7 @@ Enh #999: 機能拡張の内容説明 (あなたの名前) ### 6. 修正をコミットする -以下のコマンドを使って、コミットしたいファイルや変更を [staging area](http://git.github.io/git-reference/basic/#add) に追加します。 +以下のコマンドを使って、コミットしたいファイルや変更を [staging area](https://git.github.io/git-reference/basic/#add) に追加します。 ``` git add path/to/my/file.php @@ -217,7 +217,7 @@ git push origin --delete 999-name-of-your-branch-goes-here ### 注意: -退行 (regression) を早期に発見するために、github 上の Yii コード・ベースへのマージは、すべて [Travis CI](http://travis-ci.com) に取り上げられて、自動化されたテストにかけられます。 +退行 (regression) を早期に発見するために、github 上の Yii コード・ベースへのマージは、すべて [Travis CI](https://travis-ci.com) に取り上げられて、自動化されたテストにかけられます。 コア・チームとしては、このサービスに過大な負担をかけたくないために、以下の場合にはマージの説明に [`[ci skip]`](https://docs.travis-ci.com/user/customizing-the-build/#Skipping-a-build) が含まれるようにしてください。 すなわち、プル・リクエストが下記のものである場合がそうです。 diff --git a/docs/internals-ja/report-an-issue.md b/docs/internals-ja/report-an-issue.md index 6b2a41a068a..b79adf4b4df 100644 --- a/docs/internals-ja/report-an-issue.md +++ b/docs/internals-ja/report-an-issue.md @@ -13,8 +13,8 @@ **以下の場合は課題を報告しないでください** -* Yii の何らかの機能の使い方に関する質問。この目的のためには、[フォーラム](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/) または [チャット・ルーム](http://www.yiiframework.com/chat/) を使うべきです。 -* 問題がセキュリティに関するものである場合。セキュリティ問題を報告するときは、[開発者に直接コンタクト](http://www.yiiframework.com/security/) してください。 +* Yii の何らかの機能の使い方に関する質問。この目的のためには、[フォーラム](https://forum.yiiframework.com/index.php/forum/42-general-discussions-for-yii-20/) または [チャット・ルーム](https://www.yiiframework.com/chat/) を使うべきです。 +* 問題がセキュリティに関するものである場合。セキュリティ問題を報告するときは、[開発者に直接コンタクト](https://www.yiiframework.com/security/) してください。 **課題の重複を避ける** diff --git a/docs/internals-ja/translation-workflow.md b/docs/internals-ja/translation-workflow.md index fdeecb73c3e..5bf01838d8a 100644 --- a/docs/internals-ja/translation-workflow.md +++ b/docs/internals-ja/translation-workflow.md @@ -15,7 +15,7 @@ Yii は国際的なアプリケーションと開発者にとって役に立つ 1. `framework/messages/config.php` をチェックして、あなたの言語が `languages` のリストに載っていることを確認してください。 もし無ければ、あなたの言語をそこに追加します (リストをアルファベット順に保つことを忘れないでください)。 言語コードの形式は、例えば `ru` や `zh-CN` のように、 - [IETF言語タグ](http://ja.wikipedia.org/wiki/IETF%E8%A8%80%E8%AA%9E%E3%82%BF%E3%82%B0) に従うべきです。 + [IETF言語タグ](https://ja.wikipedia.org/wiki/IETF%E8%A8%80%E8%AA%9E%E3%82%BF%E3%82%B0) に従うべきです。 2. `framework` に入って、`./yii message/extract @yii/messages/config.php --languages=` を走らせます。 3. `framework/messages/your_language/yii.php` のメッセージを翻訳します。ファイルは必ず UTF-8 エンコーディングを使って保存してください。 4. [プル・リクエスト](git-workflow.md) をします。 diff --git a/docs/internals-ja/versions.md b/docs/internals-ja/versions.md index 2a85d5d47cb..51e2eed85a3 100644 --- a/docs/internals-ja/versions.md +++ b/docs/internals-ja/versions.md @@ -2,7 +2,7 @@ Yii バージョン規約 ================== この文書は Yii のバージョン付与ポリシーを要約するものです。 -私たちの現在のバージョン付与戦略は、[Semantic Versioning](http://semver.org/) の一変種です。 +私たちの現在のバージョン付与戦略は、[Semantic Versioning](https://semver.org/) の一変種です。 コア開発者チームの内部では、2.0.x リリースを後方互換に保つことが重要であることが、何度も強調されました。 しかし、これは理想としての計画です。現実の世界では達成することは困難です。 diff --git a/docs/internals-pl/core-code-style.md b/docs/internals-pl/core-code-style.md index 736a736755b..d55bae539e9 100644 --- a/docs/internals-pl/core-code-style.md +++ b/docs/internals-pl/core-code-style.md @@ -279,7 +279,7 @@ if (!$model && null === $event) ``` Należy unikać stosowania `else` po `return`, kiedy ma to sens. -Należy używać [guard conditions](http://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html). +Należy używać [guard conditions](https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html). ```php $result = $this->getResult(); @@ -360,7 +360,7 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { Dokumentacja ------------ -- Należy stosować dokumentację zgodnie ze składnią [phpDoc](http://phpdoc.org/). +- Należy stosować dokumentację zgodnie ze składnią [phpDoc](https://phpdoc.org/). - Kod bez dokumentacji jest niedozwolony. - Każdy plik klasy musi zawierać blok dokumentacji "poziomu pliku" na początku pliku i blok dokumentacji "poziomu klasy" zaraz nad klasą. @@ -391,9 +391,9 @@ Dokumentacja ```php Tip: jeśli nie jesteś biegły w używaniu Gita, polecamy doskonałą darmową książkę [Pro Git](https://git-scm.com/book/en/v2) (z polskim tłumaczeniem dla [poprzedniej edycji](https://git-scm.com/book/pl/v1). @@ -158,7 +158,7 @@ W przypadku drobnych zmian, np. literówek i poprawek dokumentacji, nie ma potrz ### 6. Zatwierdź swoje modyfikacje -Dodaj swoje pliki/zmiany, które chcesz zatwierdzić do [kolejki oczekujących](http://git.github.io/git-reference/basic/#add) za pomocą +Dodaj swoje pliki/zmiany, które chcesz zatwierdzić do [kolejki oczekujących](https://git.github.io/git-reference/basic/#add) za pomocą ``` git add sciezka/do/mojego/pliku.php @@ -224,7 +224,7 @@ git push origin --delete 999-nazwa-twojej-galezi-w-tym-miejscu ### Note: W celu wczesnego wykrycia ewentualnych problemów z integracją, każde żądanie scalenia głównego kodu Yii na GitHubie jest -weryfikowane przez automatyczne testy [Travis CI](http://travis-ci.com). Ponieważ ekipa głównych programistów stara się nie +weryfikowane przez automatyczne testy [Travis CI](https://travis-ci.com). Ponieważ ekipa głównych programistów stara się nie nadużywać tej usługi, [`[ci skip]`](https://docs.travis-ci.com/user/customizing-the-build/#Skipping-a-build) jest dodawane przy komentarzu scalenia kodu, jeśli żądanie: diff --git a/docs/internals-pl/report-an-issue.md b/docs/internals-pl/report-an-issue.md index 9b7faa791bb..fd6a4fa7d32 100644 --- a/docs/internals-pl/report-an-issue.md +++ b/docs/internals-pl/report-an-issue.md @@ -13,8 +13,8 @@ Jeśli nie jesteś pewien, gdzie powinno trafić zgłoszenie, [wyślij je do gł **Nie zgłaszaj problemu jeśli** -* pytasz o to, w jaki sposób użyć którejś z funkcjonalności Yii. Do tego celu użyj [forum](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/) lub [chatu](http://www.yiiframework.com/chat/). -* dotyczy on bezpieczeństwa. W takim wypadku prosimy o [bezpośredni kontakt](http://www.yiiframework.com/security/). +* pytasz o to, w jaki sposób użyć którejś z funkcjonalności Yii. Do tego celu użyj [forum](https://forum.yiiframework.com/index.php/forum/42-general-discussions-for-yii-20/) lub [chatu](https://www.yiiframework.com/chat/). +* dotyczy on bezpieczeństwa. W takim wypadku prosimy o [bezpośredni kontakt](https://www.yiiframework.com/security/). **Unikaj duplikowania zgłoszeń** diff --git a/docs/internals-pl/translation-workflow.md b/docs/internals-pl/translation-workflow.md index 40d5deaf57b..c0fd426deba 100644 --- a/docs/internals-pl/translation-workflow.md +++ b/docs/internals-pl/translation-workflow.md @@ -14,7 +14,7 @@ Aby rozpocząć tłumaczenie komunikatów: 1. Sprawdź plik `framework/messages/config.php` i upewnij się, że Twój język jest wymieniony w sekcji `languages`. Jeśli nie, dodaj go tam (pamiętaj, że lista powinna być posortowana alfabetycznie). Format kodu języka powinien być zgodny - ze [specyfikacją IETF](http://en.wikipedia.org/wiki/IETF_language_tag) (przykładowo `ru`, `zh-CN`). + ze [specyfikacją IETF](https://en.wikipedia.org/wiki/IETF_language_tag) (przykładowo `ru`, `zh-CN`). 2. Przejdź do folderu `framework` i uruchom `./yii message/extract @yii/messages/config.php --languages=`. 3. Przetłumacz komunikaty w pliku `framework/messages/twoj_jezyk/yii.php`. Upewnij się, że zapisujesz plik z kodowaniem UTF-8. 4. [Wyślij prośbę o dołączenie kodu](git-workflow.md). diff --git a/docs/internals-pl/versions.md b/docs/internals-pl/versions.md index f60484d8190..50c0ccea181 100644 --- a/docs/internals-pl/versions.md +++ b/docs/internals-pl/versions.md @@ -1,7 +1,7 @@ Wersjonowanie Yii ================= -Ten dokument podsumowuje politykę wersjonowania Yii. Naszą aktualną strategię wersjonowania jest wariant [wersjonowania semantycznego](http://semver.org/). +Ten dokument podsumowuje politykę wersjonowania Yii. Naszą aktualną strategię wersjonowania jest wariant [wersjonowania semantycznego](https://semver.org/). Główni programiści Yii wiele razy już zgadzali się i podkreślali, że ważnym jest utrzymanie wydań 2.0.x kompatybilnych wstecznie. To jednak idealna teoria, którą w praktyce nie zawsze udaje się osiągnąć. Zapoznaj się z sekcją [Wsteczna kompatybilność](bc.md), diff --git a/docs/internals-pt-BR/translation-workflow.md b/docs/internals-pt-BR/translation-workflow.md index b381abc6659..ec0ff565531 100644 --- a/docs/internals-pt-BR/translation-workflow.md +++ b/docs/internals-pt-BR/translation-workflow.md @@ -68,7 +68,7 @@ Regras e Observações *itálico*, isso ajudará na revisão. - Para reduzir erros de digitação você pode utilizar um editor de texto como o MS Word para escrever pequenos blocos textos e em seguida copiar estes blocos - para um editor visual de Markdown como o http://dillinger.io/. + para um editor visual de Markdown como o https://dillinger.io/. ### Convenções Para Tradução diff --git a/docs/internals-ru/core-code-style.md b/docs/internals-ru/core-code-style.md index d53c62389c6..94e344ea4cf 100644 --- a/docs/internals-ru/core-code-style.md +++ b/docs/internals-ru/core-code-style.md @@ -335,7 +335,7 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { Документация ------------- -- Для получения информации по синтаксису документации обратитесь к первоисточнику [PHPDoc](http://phpdoc.org/); +- Для получения информации по синтаксису документации обратитесь к первоисточнику [PHPDoc](https://phpdoc.org/); - Код без документации недопустим; - Все файлы классов должны содержать блок документации в начале файла и блок документации непосредственно перед каждым классом; - Нет необходимости использовать тег `@return` если метод не возвращает значение; @@ -364,9 +364,9 @@ public function getErrors($attribute = null) ```php `. 3. Prevedite poruke unutar `framework/messages/your_language/yii.php` fajla. Pobrinite se da se fajl sačuva sa UTF-8 enkodingom. 4. [Napravite pull zahtev](https://github.com/yiisoft/yii2/blob/master/docs/internals-sr-Latn/git-workflow.md). diff --git a/docs/internals-uk/core-code-style.md b/docs/internals-uk/core-code-style.md index 559cfba4727..4eaac14c6ec 100644 --- a/docs/internals-uk/core-code-style.md +++ b/docs/internals-uk/core-code-style.md @@ -251,7 +251,7 @@ if (!$model && null === $event) ``` Краще уникайте використання `else` після `return`, де це має сенс. -Використовуйте [вартові умови](http://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html). +Використовуйте [вартові умови](https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html). ```php $result = $this->getResult(); @@ -332,7 +332,7 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { Документація ------------ -- Див. [PHPDoc](http://phpdoc.org/) для довідки про синтаксис документації. +- Див. [PHPDoc](https://phpdoc.org/) для довідки про синтаксис документації. - Код без документації не допускається. - Усі файли класів повинні містити файловий ("file-level") doc-блок на початку та класовий ("class-level") doc-блок безпосередньо над кожним класом. @@ -365,9 +365,9 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { ```php getResult(); @@ -362,7 +362,7 @@ $mul = array_reduce($numbers, function($r, $x) use($n) { Documentation ------------- -- Refer to [phpDoc](http://phpdoc.org/) for documentation syntax. +- Refer to [phpDoc](https://phpdoc.org/) for documentation syntax. - Code without documentation is not allowed. - All class files must contain a "file-level" docblock at the top of each file and a "class-level" docblock immediately above each class. @@ -395,9 +395,9 @@ Documentation ```php Tip: if you're not fluent with Git, we recommend reading excellent free [Pro Git book](https://git-scm.com/book/en/v2). @@ -154,7 +154,7 @@ For very small fixes, e.g. typos and documentation changes, there is no need to ### 6. Commit your changes -add the files/changes you want to commit to the [staging area](http://git.github.io/git-reference/basic/#add) with +add the files/changes you want to commit to the [staging area](https://git.github.io/git-reference/basic/#add) with ``` git add path/to/my/file.php @@ -218,7 +218,7 @@ git push origin --delete 999-name-of-your-branch-goes-here ### Note: To detect regressions early every merge to the Yii codebase on GitHub will be picked up by -[Travis CI](http://travis-ci.com) for an automated testrun. As core team doesn't wish to overtax this service, +[Travis CI](https://travis-ci.com) for an automated testrun. As core team doesn't wish to overtax this service, [`[ci skip]`](https://docs.travis-ci.com/user/customizing-the-build/#Skipping-a-build) will be included to the merge description if the pull request: diff --git a/docs/internals/release.md b/docs/internals/release.md index c5c0eb73feb..703190e9dc3 100644 --- a/docs/internals/release.md +++ b/docs/internals/release.md @@ -77,7 +77,7 @@ before. - create a new branch `2.0` from `master` - ensure composer.json does not contain a branch alias on this branch anymore. - merge necessary changes from `master` to `2.1` -- point `master` to the lastest commit on `2.1` +- point `master` to the latest commit on `2.1` - adjust composer.json branch alias for master to `2.1.x-dev`. - delete `2.1` branch diff --git a/docs/internals/report-an-issue.md b/docs/internals/report-an-issue.md index 1705a112984..11a1ce70590 100644 --- a/docs/internals/report-an-issue.md +++ b/docs/internals/report-an-issue.md @@ -13,8 +13,8 @@ If you are unsure, [report it to the main repository](https://github.com/yiisoft **Do not report an issue if** -* you are asking how to use some Yii feature. You should use [the forum](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/) or [chat room](http://www.yiiframework.com/chat/) for this purpose. -* your issue is about security. Please [contact us directly](http://www.yiiframework.com/security/) to report security issues. +* you are asking how to use some Yii feature. You should use [the forum](https://forum.yiiframework.com/index.php/forum/42-general-discussions-for-yii-20/) or [chat room](https://www.yiiframework.com/chat/) for this purpose. +* your issue is about security. Please [contact us directly](https://www.yiiframework.com/security/) to report security issues. **Avoid duplicated issues** diff --git a/docs/internals/translation-workflow.md b/docs/internals/translation-workflow.md index 88ceee66c5c..a7c71328972 100644 --- a/docs/internals/translation-workflow.md +++ b/docs/internals/translation-workflow.md @@ -14,7 +14,7 @@ In order to start with message translation: 1. Check `framework/messages/config.php` and make sure your language is listed in `languages`. If not, add your language there (remember to keep the list in alphabetical order). The format of language code - should follow [IETF language tag spec](http://en.wikipedia.org/wiki/IETF_language_tag), for example, + should follow [IETF language tag spec](https://en.wikipedia.org/wiki/IETF_language_tag), for example, `ru`, `zh-CN`. 2. Go to `framework` and run `./yii message/extract @yii/messages/config.php --languages=`. 3. Translate messages in `framework/messages/your_language/yii.php`. Make sure file is saved using UTF-8 encoding. diff --git a/docs/internals/versions.md b/docs/internals/versions.md index 78aaf6d22be..4ae3a228184 100644 --- a/docs/internals/versions.md +++ b/docs/internals/versions.md @@ -2,7 +2,7 @@ Yii Versioning ============== This document summarizes the versioning policy of Yii. Our current versioning strategy is -a variant of [Semantic Versioning](http://semver.org/). +a variant of [Semantic Versioning](https://semver.org/). Within the core developer team, we have emphasized several times that it is important to keep 2.0.x releases backwards compatible. But this is an ideal plan. In a real world this is hard to achieve. See [Backwards Compatibility](bc.md) diff --git a/framework/BaseYii.php b/framework/BaseYii.php index 46de9cdd394..5561df9c450 100644 --- a/framework/BaseYii.php +++ b/framework/BaseYii.php @@ -31,15 +31,15 @@ */ defined('YII_ENV') or define('YII_ENV', 'prod'); /** - * Whether the the application is running in production environment. + * Whether the application is running in the production environment. */ defined('YII_ENV_PROD') or define('YII_ENV_PROD', YII_ENV === 'prod'); /** - * Whether the the application is running in development environment. + * Whether the application is running in the development environment. */ defined('YII_ENV_DEV') or define('YII_ENV_DEV', YII_ENV === 'dev'); /** - * Whether the the application is running in testing environment. + * Whether the application is running in the testing environment. */ defined('YII_ENV_TEST') or define('YII_ENV_TEST', YII_ENV === 'test'); @@ -68,7 +68,7 @@ class BaseYii */ public static $classMap = []; /** - * @var \yii\console\Application|\yii\web\Application the application instance + * @var \yii\console\Application|\yii\web\Application|\yii\base\Application the application instance */ public static $app; /** @@ -93,7 +93,7 @@ class BaseYii */ public static function getVersion() { - return '2.0.40-dev'; + return '2.0.46-dev'; } /** @@ -124,13 +124,13 @@ public static function getVersion() * @param string $alias the alias to be translated. * @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. + * @return string|false the path corresponding to the alias, false if the root alias is not previously registered. * @throws InvalidArgumentException if the alias is invalid while $throwException is true. * @see setAlias() */ public static function getAlias($alias, $throwException = true) { - if (strncmp($alias, '@', 1)) { + if (strncmp((string)$alias, '@', 1) !== 0) { // not an alias return $alias; } @@ -162,7 +162,7 @@ public static function getAlias($alias, $throwException = true) * A root alias is an alias that has been registered via [[setAlias()]] previously. * If a given alias matches multiple root aliases, the longest one will be returned. * @param string $alias the alias - * @return string|bool the root alias, or false if no root alias is found + * @return string|false the root alias, or false if no root alias is found */ public static function getRootAlias($alias) { @@ -201,9 +201,9 @@ public static function getRootAlias($alias) * See the [guide article on aliases](guide:concept-aliases) for more information. * * @param string $alias the alias name (e.g. "@yii"). It must start with a '@' character. - * It may contain the forward slash '/' which serves as boundary character when performing + * It may contain the forward-slash '/' which serves as a boundary character when performing * alias translation by [[getAlias()]]. - * @param string $path the path corresponding to the alias. If this is null, the alias will + * @param string|null $path the path corresponding to the alias. If this is null, the alias will * be removed. Trailing '/' and '\' characters will be trimmed. This can be * * - a directory or a file path (e.g. `/tmp`, `/tmp/main.txt`) @@ -266,7 +266,7 @@ public static function setAlias($alias, $path) * and have its top-level namespace or sub-namespaces defined as path aliases. * * Example: When aliases `@yii` and `@yii/bootstrap` are defined, classes in the `yii\bootstrap` namespace - * will be loaded using the `@yii/bootstrap` alias which points to the directory where bootstrap extension + * will be loaded using the `@yii/bootstrap` alias which points to the directory where the bootstrap extension * files are installed and all classes from other `yii` namespaces will be loaded from the yii framework directory. * * Also the [guide section on autoloading](guide:concept-autoloading). @@ -278,7 +278,7 @@ public static function autoload($className) { if (isset(static::$classMap[$className])) { $classFile = static::$classMap[$className]; - if ($classFile[0] === '@') { + if (strncmp($classFile, '@', 1) === 0) { $classFile = static::getAlias($classFile); } } elseif (strpos($className, '\\') !== false) { @@ -384,7 +384,7 @@ public static function getLogger() /** * Sets the logger object. - * @param Logger $logger the logger object. + * @param Logger|null $logger the logger object. */ public static function setLogger($logger) { @@ -393,11 +393,11 @@ public static function setLogger($logger) /** * 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 + * Trace messages are logged mainly for development purposes to see + * the execution workflow 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. + * complex data structure, such as an array. * @param string $category the category of the message. * @since 2.0.14 */ @@ -411,7 +411,7 @@ public static function debug($message, $category = 'application') /** * 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. + * complex data structure, such as an array. * @param string $category the category of the message. * @deprecated since 2.0.14. Use [[debug()]] instead. */ @@ -425,7 +425,7 @@ public static function trace($message, $category = 'application') * An error message is typically logged when an unrecoverable error occurs * during the execution of an application. * @param string|array $message the message to be logged. This can be a simple string or a more - * complex data structure, such as array. + * complex data structure, such as an array. * @param string $category the category of the message. */ public static function error($message, $category = 'application') @@ -438,7 +438,7 @@ public static function error($message, $category = 'application') * A warning message is typically logged when an error occurs while the execution * can still continue. * @param string|array $message the message to be logged. This can be a simple string or a more - * complex data structure, such as array. + * complex data structure, such as an array. * @param string $category the category of the message. */ public static function warning($message, $category = 'application') @@ -451,7 +451,7 @@ public static function warning($message, $category = 'application') * An informative message is typically logged by an application to keep record of * something important (e.g. an administrator logs in). * @param string|array $message the message to be logged. This can be a simple string or a more - * complex data structure, such as array. + * complex data structure, such as an array. * @param string $category the category of the message. */ public static function info($message, $category = 'application') @@ -502,7 +502,7 @@ public static function endProfile($token, $category = 'application') public static function powered() { return \Yii::t('yii', 'Powered by {yii}', [ - 'yii' => '' . \Yii::t('yii', + 'yii' => '' . \Yii::t('yii', 'Yii Framework') . '', ]); } @@ -522,13 +522,13 @@ public static function powered() * echo \Yii::t('app', 'Hello, {username}!', ['username' => $username]); * ``` * - * Further formatting of message parameters is supported using the [PHP intl extensions](https://secure.php.net/manual/en/intro.intl.php) + * Further formatting of message parameters is supported using the [PHP intl extensions](https://www.php.net/manual/en/intro.intl.php) * message formatter. See [[\yii\i18n\I18N::translate()]] for more details. * * @param string $category the message category. * @param string $message the message to be translated. * @param array $params the parameters that will be used to replace the corresponding placeholders in the message. - * @param string $language the language code (e.g. `en-US`, `en`). If this is null, the current + * @param string|null $language the language code (e.g. `en-US`, `en`). If this is null, the current * [[\yii\base\Application::language|application language]] will be used. * @return string the translated message. */ diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 68d5563257a..3c8f82029f2 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -1,10 +1,227 @@ Yii Framework 2 Change Log ========================== -2.0.40 under development +2.0.46 under development ------------------------ -- no changes in this release. +- Bug #19380: Fix PHP 8.1 passing non string to trim() in `yii\db\Query` (wa1kb0y) +- Bug #19272: Fix bug in dirty attributes check on multidimensional array (speedplli) +- Bug #19349: Fix PHP 8.1 error when attribute and label of `yii\grid\DataColumn` are empty (githubjeka) +- Bug #19243: Handle `finfo_open` for tar.xz as `application/octet-stream` on PHP 8.1 (longthanhtran) +- Bug #19235: Fix return type compatibility of `yii\web\SessionIterator` class methods for PHP 8.1 (virtual-designer) +- Bug #19256: Pass missed `$view` to user's callback in `yii\validators\InlineValidator::clientValidateAttribute()` (WinterSilence) +- Enh #19270: Replace deprecated `scss` converter in `yii\web\AssetConverter::$commands` (WinterSilence) +- Enh #19254: Support specifying custom characters for `yii.validation.trim()` and replace deprecated `jQuery.trim()` (WinterSilence) +- Bug #19291: Reset errors and validators in `yii\base\Model::__clone()` (WinterSilence) +- Bug #19290: Fix `Request::getHostInfo()` doesn’t return the port if a Host header is used (lesha724) +- Enh #19295: Added alias `text/rtf` for mime-type `application/rtf` (lesha724) +- Enh #19308: Add `yii\web\UploadedFile::$fullPath` represents 'full_path' key added in PHP 8.1 (WinterSilence) +- Bug #19303: Fix serialization in `yii\caching\Dependency::generateReusableHash()` (WinterSilence) +- Enh #19304: Add filtering validator `yii\validators\TrimValidator` (WinterSilence) +- Enh #19309: Optimize `yii\base\Model::attributes()` (WinterSilence) +- Bug #19322: Revert force setting value to empty string in case it's `null` in `yii\validators\FilterValidator::validateAttribute()` (bizley) +- Bug #19324: Fix `yii\helpers\BaseHtml::renderSelectOptions()` giving wrong selection for boolean attributes (adnandautovic) +- Bug #19329: Fix `yii\web\GroupUrlRule` to properly normalize prefix (bizley) +- Bug #19328: Passing null to parameter #1 ($string) of type string is deprecated in `yii\db\oci\Schema` (Arkeins) +- Bug #19237: Fix OCI PHP 8.1 passing `null` to trim() (longthanhtran) +- Bug #19312: Fix PHP 8.1 error when passing null to `yii\helpers\BaseInflector` (WinterSilence) +- Bug #19368: Fix PHP 8.1 error when `$fileMimeType` is `null` in `yii\validators\FileValidator::validateMimeType()` (bizley) +- Enh #19384: Normalize `setBodyParams()` and `getBodyParam()` in `yii\web\Request` (WinterSilence, albertborsos) +- Bug #19386: Fix recursive calling `yii\helpers\BaseArrayHelper::htmlDecode()` (WinterSilence) +- Enh #19401: Delay `exit(1)` in `yii\base\ErrorHandler::handleFatalError` (arrilot) +- Bug #19402: Add shutdown event and fix working directory in `yii\base\ErrorHandler` (WinterSilence) +- Enh #19416: Update and improve configurations for `yii\console\controllers\MessageController` (WinterSilence) +- Bug #19403: Fix types in `yii\web\SessionIterator` (WinterSilence) +- Enh #19420: Update list of JS callbacks in `yii\widgets\MaskedInput` (WinterSilence) + + +2.0.45 February 11, 2022 +------------------------ + +- Bug #19004: Container::resolveCallableDependencies() unable to handle union and intersection types (sartor) +- Bug #19041: Fix PHP 8.1 issues (longthanhtran, samdark, pamparam83, sartor, githubjeka) +- Bug #19047: Fix deprecated preg_match() passing null parameters #2 in db\mysql\Schema.php (longthanhtran) +- Bug #19130: Fix DbSession breaks in some case (longthanhtran) +- Bug #19138: Allow digits in language code (ntesic) +- Bug #19148: Fix undefined array key errors in `yii\db\ActiveRelationTrait` (stevekr) +- Bug #19182: RBAC Migration failed when use oracle with oci8 (Murolike) +- Bug #19187: Fix `yii\filters\PageCache` to store original headers names instead of normalized ones (bizley) +- Bug #19191: Change `\Exception` to `\Throwable` in `BadRequestHttpException` and `HttpException` (Dmitrijlin) +- Bug #19204: Support numbers in Inflector::camel2words (longthanhtran) +- Enh #18821: Allow `yii\db\ExpressionInterface` as column in `yii\db\conditions\InBuilder` (ntesic) +- Enh #19171: Added `$pagination` and `$sort` to `\yii\rest\IndexAction` for easy configuration (rhertogh) + + +2.0.44 December 30, 2021 +------------------------ + +- Bug #17119: Fix `yii\caching\Cache::multiSet()` to use `yii\caching\Cache::$defaultDuration` when no duration is passed (OscarBarrett) +- Bug #18646: Remove stale identity data from session if `IdentityInterface::findIdentity()` returns `null` (mikehaertl) +- Bug #18660: Fix database migration template does not work with namespaced migrations when migration name does not include namespace (iridance) +- Bug #18798: Fix `StringHelper::dirname()` when passing string with a trailing slash (perlexed) +- Bug #18832: Fix `Inflector::camel2words()` adding extra spaces (brandonkelly) +- Bug #18842: Fix `yii\base\Controller::bindInjectedParams()` to not throw error when argument of `ReflectionUnionType` type is passed (bizley) +- Bug #18845: Fix duplicating `id` in `MigrateController::addDefaultPrimaryKey()` (WinterSilence, samdark) +- Bug #18880: Fix `yii\helpers\ArrayHelper::toArray()` for `DateTime` objects in PHP >= 7.4 (rhertogh) +- Bug #18883: Fix `yii\web\HeaderCollection::fromArray()` now ensures lower case keys (rhertogh) +- Bug #18898: Fix `yii\helpers\Inflector::camel2words()` to work with words ending with 0 (michaelarnauts) +- Bug #18909: Fix bug with binding default action parameters for controllers (bizley) +- Bug #18913: Add filename validation for `MessageSource::getMessageFilePath()` (uaoleg) +- Bug #18955: Check `yiisoft/yii2-swiftmailer` before using as default mailer in `yii\base\Application` (WinterSilence) +- Bug #18988: Fix default value of `yii\console\controllers\MessageController::$translator` (WinterSilence) +- Bug #18993: Load defaults by `attributes()` in `yii\db\ActiveRecord::loadDefaultValues()` (WinterSilence) +- Bug #19021: Fix return type in PhpDoc `yii\db\Migration` functions `up()`, `down()`, `safeUp()` and `safeDown()` (WinterSilence, rhertogh) +- Bug #19030: Add DI container usage to `yii\base\Widget::end()` (papppeter) +- Bug #19031: Fix displaying console help for parameters with declared types (WinterSilence) +- Bug #19096: Fix `Request::getIsConsoleRequest()` may return erroneously when testing a Web application in Codeception (WinterSilence) +- Enh #13105: Add yiiActiveForm `validate_only` property for skipping form auto-submission (ptolomaues) +- Enh #18328: Raise warning when trying to register a file after `View::endPage()` has been called (perlexed) +- Enh #18762: Add `yii\helpers\Json::$keepObjectType` and `yii\web\JsonResponseFormatter::$keepObjectType` in order to avoid changing zero-indexed objects to array in `yii\helpers\Json::encode()` (zebraf1) +- Enh #18783: Add support for URI namespaced tags in `XmlResponseFormatter` (WinterSilence, samdark) +- Enh #18783: Add `XmlResponseFormatter::$objectTagToLowercase` option to lowercase object tags (WinterSilence, samdark) +- Enh #18812: Add error messages and optimize "error" methods in `yii\helpers\BaseJson` (WinterSilence, samdark) +- Enh #18826: Add ability to turn the sorting off for a clicked column in GridView with multisort (ditibal) +- Enh #18858: Reduce memory usage in `yii\base\View::afterRender` method (LeoOnTheEarth) +- Enh #18899: Replace usages of `strpos` with `strncmp` and remove redundant usage of `array_merge` and `array_values` (AlexGx) +- Enh #18904: Improve Captcha client-side validation (hexkir) +- Enh #18967: Use proper attribute names for tabular data in `yii\widgets\ActiveField::addAriaAttributes()` (AnkIF) +- Enh #19005: Add `yii\base\Module::setControllerPath()` (WinterSilence) +- Enh #19098: Add `yii\helper\BaseHtml::$normalizeClassAttribute` to fix duplicate classes (WinterSilence) +- Enh #19108: Optimize `Component::hasEventHandlers()` and `Component::trigger()` (WinterSilence) +- Chg #18823: Rollback changes from #18806 in `yii\validators\ExistValidator::checkTargetRelationExistence()` (WinterSilence) + + +2.0.43 August 09, 2021 +---------------------- + +- Bug #14663: Do not convert int to string if database type of column is numeric (egorrishe) +- Bug #18274: Fix `yii\log\Logger` to calculate profile timings no matter the value of the flush interval (bizley) +- Bug #18648: Fix `yii\web\Request` to properly handle HTTP Basic Auth headers (olegbaturin) +- Bug #18650: Refactor `framework/assets/yii.activeForm.js` arrow function into traditional function for IE11 compatibility (marcovtwout) +- Bug #18678: Fix `yii\caching\DbCache` to use configured cache table name instead of the default one in case of MSSQL varbinary column type detection (aidanbek) +- Bug #18749: Fix `yii\web\ErrorHandler::encodeHtml()` to support strings with invalid UTF symbols (vjik) +- Bug #18756: Fix `\yii\validators\ExistValidator::queryValueExists` to validate against an array of unique values (DrDeath72) +- Bug #18807: Fix replacing source whitespaces and optimize code of `yii\helpers\BaseStringHelper::mb_ucwords()` (WinterSilence) +- Enh #18274: Add `profilingAware` option to `yii\log\Logger` to prevent breaking the profiling block messages pair when flushing them (bizley) +- Enh #18628: Add strings "software", and "hardware" to `$specials` array in `yii\helpers\BaseInflector` (kjusupov) +- Enh #18653: Add method `yii\helpers\BaseHtml::getInputIdByName()` (WinterSilence) +- Enh #18656: Add ability for `yii serve`'s `--router` param to take an alias (markhuot) +- Enh #18669: Change visibility of `yii\web\User::checkRedirectAcceptable()` to `public` (rhertogh) +- Enh #18674: Add more user-friendly exception messages for `yii\i18n\Formatter` (bizley) +- Enh #18676: Add method `yii\helpers\BaseFileHelper::changeOwnership()` and `newFileMode`/`newFileOwnership` properties to `yii\console\controllers\BaseMigrateController` (rhertogh) +- Enh #18695: Add `yii\web\Cookie::SAME_SITE_NONE` constant (rhertogh) +- Enh #18707: Change the base error handler to not expose `$_SERVER` details unless `YII_DEBUG` is enabled (coolgoose) +- Enh #18712: Add `scheme` option for `$options` argument for `yii\i18n\Formatter::asUrl()` (bizley) +- Enh #18724: Allow jQuery 3.6 to be installed (marcovtwout) +- Enh #18726: Add `yii\helpers\Json::$prettyPrint` (rhertogh) +- Enh #18734: Add `yii\validators\EmailValidator::$enableLocalIDN` (brandonkelly) +- Enh #18789: Add JSONP support in `yii\web\JsonParser::parse()` (WinterSilence) +- Enh #18817: Use `paragonie/random_compat` for random bytes and int generation (samdark) + + +2.0.42.1 May 06, 2021 +--------------------- + +- Bug #18634: Fix `yii\db\BaseActiveRecord::unlink()` and `unlinkAll()` to omit condition for `on` property when it doesn't exist (bizley) + + +2.0.42 May 05, 2021 +------------------- + +- Bug #14343: Fix `yii\test\ActiveFixture` to use model's DB connection instead of the default one (margori, bizley) +- Bug #17174: Fix `yii\db\BaseActiveRecord::unlink()` to not ignore `on` conditions in `via` relations (bizley) +- Bug #17203: Fix `yii\db\Connection` to persist customized `queryBuilder` configuration after the `close()` → `open()` cycle (silverfire) +- Bug #17479: Fix `yii\grid\ActionColumn` to render icons when no glyphicons are available (simialbi) +- Bug #17631: Fix `yii\widgets\BaseListView` to properly render custom summary (sjaakp, bizley) +- Bug #18323: Fix client validation of RadioList when there are disabled items (toir427) +- Bug #18325: Fix `yii\db\pgsql\Schema` to respect non-default PgSQL schema name for data types (theonedemon, silverfire) +- Bug #18526: Fix `yii\caching\DbCache` to work with MSSQL, add `normalizeTableRowData()` to `yii\db\mssql\QueryBuilder::upsert()` (darkdef) +- Bug #18544: Fix `yii\validators\NumberValidator` to disallow values with whitespaces (bizley) +- Bug #18552: Fix `yii\data\SqlDataProvider` to properly handle SQL with `ORDER BY` clause (bizley) +- Bug #18557: Fix `yii\data\ActiveDataProvider` to handle DB connection configuration of different type than just `yii\db\Connection` (bizley) +- Bug #18574: Fix `yii\web\DbSession` to use the correct db if strict mode is used (Mignar) +- Bug #18585: Fix `yii\validators\EmailValidator` to handle an edge case where `IDN` is enabled, but fails ascii conversion for valid email addresses (ihitbuttons) +- Bug #18590: Fix `yii\web\UrlManager` to instantiate cache only when it's actually needed (bizley) +- Bug #18592: Fix `yii\db\Command::getRawSql()` to not replace query params in invalid places (sartor) +- Bug #18593: Fix setting the `maxlength` attribute for `Html::activeInput()` and `Html::activeTextArea()` based on `length` parameter of validator (BSCheshir) +- Bug #18604: Function alterColumn for MSSQL build incorrect query with default values `NULL` and other expressions (darkdef) +- Bug #18613: Do not call static methods non-statically in `BaseActiveRecord` (samdark) +- Bug #18619: Do not modify `yii\web\Cookie::$path` on `yii\web\Response::sendCookies()` (mikk150) +- Bug #18624: Fix `yii\di\Container` to properly resolve dependencies in case of PHP 8 union types (bizley) +- Enh #18534: Add `prepareSearchQuery` property in `yii\rest\IndexAction` (programmis) +- Enh #18566: Throw the original exception when `yii\web\Controller::bindInjectedParams()` catches HttpException (pigochu) +- Enh #18569: Add `NumberValidator::$allowArray` (raidkon) + + +2.0.41.1 March 04, 2021 +----------------------- + +- Bug #18545: Reversed changes made to the `yii\db\Query::all()` and `indexBy` handling (bizley) +- Bug #18548: Fix bug with REST rules with prefixes containing tokens not being parsed properly (bizley) + + +2.0.41 March 03, 2021 +--------------------- + +- Bug #8750: Fix MySQL support when running in `ANSI`/`ANSI_QUOTES` modes (brandonkelly) +- Bug #9718: Fix user staying authorized despite authKey change (kidol, Charlie Jack, Kunal Mhaske, samdark) +- Bug #18448: Fix issues in queries and tests for older MSSQL versions (darkdef) +- Bug #18450: Allow empty string to be passed as a nullable typed argument to a controller's action (dicrtarasov, bizley) +- Bug #18464: Fix bug with processing fallback messages when translation language is set to `null` (bizley) +- Bug #18472: Fix initializing `db` component configuration in `yii\data\ActiveDataProvider` (bizley) +- Bug #18477: Fix detecting availability of Xdebug's stack trace in `yii\base\ErrorException` (bizley) +- Bug #18479: Fix invalid argument type for `preg_split()` in `\yii\console\Controller` (gazooz) +- Bug #18480: Transactions are not committed using the dblib driver (bbrunekreeft) +- Bug #18505: Fix `yii\helpers\ArrayHelper::getValue()` for ArrayAccess objects with explicitly defined properties (samdark) +- Bug #18508: Fix Postgres SQL query for load table indexes with correct column order (insolita) +- Bug #18529: Fix asset files path with `appendTimestamp` option for non-root-relative base URLs (bizley) +- Bug #18535: Set Cookie SameSite to Lax by default (samdark) +- Bug #18539: Fix "driver does not support quoting" when using the driver pdo_odbc (xpohoc69) +- Enh #18447: Do not use `getLastInsertID()` to get PK from insert query to lower collision probability for concurrent inserts (darkdef) +- Enh #18455: Add ability to use separate attributes for data model and filter model of `yii\grid\GridView` in `yii\grid\DataColumn` (PowerGamer1) +- Enh #18457: Add `EVENT_RESET` and `EVENT_FINISH` events to `yii\db\BatchQueryResult` (brandonkelly) +- Enh #18460: `compareValue` in `CompareValidator` can now take a closure returning a value (mmonem) +- Enh #18483: Add `yii\log\Logger::$dbEventNames` that allows specifying event names used to get statistical results (profiling) of DB queries (atiline) +- Enh #18487: Allow creating URLs for non-GET-verb rules (bizley) +- Enh #18493: Faster request parsing for REST UrlRule with prefix handling (bizley) +- Enh #18499: When using `yii\db\Query::all()` and `yii\db\Query::$indexBy`, the `yii\db\Query::$indexBy` is auto inserted into `yii\db\Query::$select` - the same as in `yii\db\Query::column()` (OndrejVasicek, samdark, bizley) +- Enh #18518: Add support for ngrok’s `X-Original-Host` header (brandonkelly) + + +2.0.40 December 23, 2020 +------------------------ + +- Bug #16492: Fix eager loading Active Record relations when relation key is a subject to a type-casting behavior (bizley) +- Bug #18199: Fix content body response on 304 HTTP status code, according to RFC 7232 (rad8329) +- Bug #18287: Fix the OUTPUT got SQL syntax error if the column name is MSSQL keyword e.g. key (darkdef) +- Bug #18339: Fix migrate controller actions to return exit codes (haohetao, bizley) +- Bug #18365: Move quoting of table names to upper level to function `getSchemaMetadata()` in MSSQL driver to get clean names from the schema (darkdef) +- Bug #18383: RBAC's generated file made PSR-12 compliant (perlexed) +- Bug #18386: Fix `assets/yii.activeForm.js` incorrect target selector for `validatingCssClass` (brussens) +- Bug #18393: Fix `ActiveRecord::refresh()` to load data from the database even if cache is enabled (hooman-mirghasemi) +- Bug #18395: Fix regression in `yii\helpers\BaseArrayHelper::filter()` (allowing filtering arrays with numeric keys) (bizley) +- Bug #18400: Set parent module of the newly attached child module by `Module::setModule()` and `Module::setModules()` (sup-ham) +- Bug #18406: Fix PDO exception when committing or rolling back an autocommitted transaction in PHP 8 (brandonkelly) +- Bug #18414: Fix `AssetManager::appendTimestamp()` not appending timestamp for website root in sub-directory (Isitar) +- Bug #18426: Fix check for route's leading slash in `yii\widgets\Menu` (stevekr) +- Bug #18435: Fix ensuring Active Record relation links' keys to be strings (bizley) +- Bug #18437: Change the check order whether an object is an implementation of `Arrayable` or `JsonSerializable` in `\yii\base\ArrayableTrait::toArray()` and `\yii\rest\Serializer::serialize()` (spell6inder) +- Bug #18442: Fix calls with array access to string (bizley) +- Enh #18381: The `yii\web\AssetManager` `$basePath` readable and writeable check has been moved to the `checkBasePathPermission()`. This check will run once before `publishFile()` and `publishDirectory()` (nadar) +- Enh #18394: Add support for setting `yii\web\Response::$stream` to a callable (brandonkelly) + + +2.0.39.3 November 23, 2020 +-------------------------- + +- Bug #18396: Fix not throw `InvalidConfigException` when failed to instantiate class via DI container in some cases (vjik) +- Enh #18200: Add `maxlength` attribute by default to the input text when it is an active field within a `yii\grid\DataColumn` (rad8329) + + +2.0.39.2 November 13, 2020 +-------------------------- + +- Bug #18378: Fix not taking default value when unable to resolve abstract class via DI container (vjik) 2.0.39.1 November 10, 2020 @@ -1375,7 +1592,7 @@ Yii Framework 2 Change Log - Enh #8329: Added support of options for `message` console command (vchenin) - Enh #8613: `yii\widgets\FragmentCache` will not store empty content anymore which fixes some problems related to `yii\filters\PageCache` (kidol) - Enh #8649: Added total applied migrations to final report (vernik91) -- Enh #8687: Added support for non-gregorian calendars, e.g. persian, taiwan, islamic to `yii\i18n\Formatter` (cebe, z-avanes, hooman-pro) +- Enh #8687: Added support for non-gregorian calendars, e.g. persian, taiwan, islamic to `yii\i18n\Formatter` (cebe, z-avanes, hooman-mirghasemi) - Enh #8824: Allow passing a `yii\db\Expression` to `Query::groupBy()` (cebe) - Enh #8995: `yii\validators\FileValidator::maxFiles` can be set to `0` to allow unlimited count of files (PowerGamer1, silverfire) - Enh #9282: Improved JSON error handling to support PHP 5.5 error codes (freezy-sk) diff --git a/framework/UPGRADE.md b/framework/UPGRADE.md index 0796fb183e4..81a09a6ad0c 100644 --- a/framework/UPGRADE.md +++ b/framework/UPGRADE.md @@ -51,6 +51,76 @@ 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.44 +----------------------- + +* `yii\filters\PageCache::$cacheHeaders` now takes a case-sensitive list of header names since PageCache is no longer + storing the normalized (lowercase) versions of them so make sure this list is properly updated and your page cache + is recreated. + +Upgrade from Yii 2.0.43 +----------------------- + +* `Json::encode()` can now handle zero-indexed objects in same way as `json_encode()` and keep them as objects. In order + to avoid breaking backwards compatibility this behavior could be enabled by a new option flag but is disabled by default. + * Set `yii/helpers/Json::$keepObjectType = true` anywhere in your application code + * Or configure json response formatter to enable it for all JSON responses: + ```php + 'response' => [ + 'formatters' => [ + \yii\web\Response::FORMAT_JSON => [ + 'class' => 'yii\web\JsonResponseFormatter', + 'prettyPrint' => YII_DEBUG, // use "pretty" output in debug mode + 'keepObjectType' => true, // keep object type for zero-indexed objects + ], + ], + ], + ``` +* `yii\caching\Cache::multiSet()` now uses the default cache duration (`yii\caching\Cache::$defaultDuration`) when no + duration is provided. A duration of 0 should be explicitly passed if items should not expire. + +Upgrade from Yii 2.0.42 +----------------------- + +* `yii\base\ErrorHandler` does not expose the `$_SERVER` information implicitly anymore. +* The methods `phpTypecast()` and `dbTypecast()` of `yii\db\ColumnSchema` will no longer convert `$value` from `int` to + `string`, if database column type is `INTEGER UNSIGNED` or `BIGINT UNSIGNED`. + * I.e. it affects update and insert queries. For example: + ```php + \Yii::$app->db->createCommand()->insert('{{some_table}}', ['int_unsigned_col' => 22])->execute(); + ``` + will execute next SQL: + ```sql + INSERT INTO `some_table` (`int_unsigned_col`) VALUES (22) + ``` +* Property `yii\db\ColumnSchemaBuilder::$categoryMap` has been removed in favor of getter/setter methods `getCategoryMap()` + and `setCategoryMap()`. + +Upgrade from Yii 2.0.41 +----------------------- + +* `NumberValidator` (`number`, `double`, `integer`) does not allow values with leading or terminating (non-trimmed) + white spaces anymore. If your application expects non-trimmed values provided to this validator make sure to trim + them first (i.e. by using `trim` / `filter` "validators"). + +Upgrade from Yii 2.0.40 +----------------------- + +* The methods `getAuthKey()` and `validateAuthKey()` of `yii\web\IdentityInterface` are now also used to validate active + sessions (previously these methods were only used for cookie-based login). If your identity class does not properly + implement these methods yet, you should update it accordingly (an example can be found in the guide under + `Security` -> `Authentication`). Alternatively, you can simply return `null` in the `getAuthKey()` method to keep + the old behavior (that is, no validation of active sessions). Applications that change the underlying `authKey` of + an authenticated identity, should now call `yii\web\User::switchIdentity()`, `yii\web\User::login()` + or `yii\web\User::logout()` to recreate the active session with the new `authKey`. + +Upgrade from Yii 2.0.39.3 +------------------------- + +* Priority of processing `yii\base\Arrayable`, and `JsonSerializable` data has been reversed (`Arrayable` data is checked + first now) in `yii\base\Model`, and `yii\rest\Serializer`. If your application relies on the previous priority you need + to fix it manually based on the complexity of desired (de)serialization result. + Upgrade from Yii 2.0.38 ----------------------- @@ -789,7 +859,7 @@ Upgrade from Yii 2.0 Beta You can add it with `ALTER TABLE log ADD COLUMN prefix TEXT AFTER log_time;`. * The `fileinfo` PHP extension is now required by Yii. If you use `yii\helpers\FileHelper::getMimeType()`, make sure - you have enabled this extension. This extension is [builtin](https://secure.php.net/manual/en/fileinfo.installation.php) in php above `5.3`. + you have enabled this extension. This extension is [builtin](https://www.php.net/manual/en/fileinfo.installation.php) in php above `5.3`. * Please update your main layout file by adding this line in the `` section: ``. This change is needed because `yii\web\View` no longer automatically generates CSRF meta tags due to issue #3358. diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 0c1ccb0f777..671f6dcc9f6 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -218,6 +218,7 @@ attributes: attributes, submitting: false, validated: false, + validate_only: false, // validate without auto submitting options: getFormOptions($form) }); @@ -329,7 +330,10 @@ this.$form = $form; var $input = findInput($form, this); - if ($input.is(':disabled')) { + var disabled = $input.toArray().reduce(function(result, next) { + return result && $(next).is(':disabled'); + }, true); + if (disabled) { return true; } // validate markup for select input @@ -569,7 +573,13 @@ $.each(data.attributes, function () { if (this.status === 2) { this.status = 3; - $form.find(this.container).addClass(data.settings.validatingCssClass); + + var $container = $form.find(this.container), + $input = findInput($form, this); + + var $errorElement = data.settings.validationStateOn === 'input' ? $input : $container; + + $errorElement.addClass(data.settings.validatingCssClass); } }); methods.validate.call($form); @@ -745,12 +755,14 @@ data.submitting = false; } else { data.validated = true; - if (data.submitObject) { - applyButtonOptions($form, data.submitObject); - } - $form.submit(); - if (data.submitObject) { - restoreButtonOptions($form); + if (!data.validate_only) { + if (data.submitObject) { + applyButtonOptions($form, data.submitObject); + } + $form.submit(); + if (data.submitObject) { + restoreButtonOptions($form); + } } } } else { @@ -917,4 +929,4 @@ $form.find(attribute.input).attr('aria-invalid', hasError ? 'true' : 'false'); } } -})(window.jQuery); \ No newline at end of file +})(window.jQuery); diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 88f79decba3..c4185f91849 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -24,7 +24,7 @@ yii.validation = (function ($) { var valid = false; if (options.requiredValue === undefined) { var isString = typeof value == 'string' || value instanceof String; - if (options.strict && value !== undefined || !options.strict && !pub.isEmpty(isString ? $.trim(value) : value)) { + if (options.strict && value !== undefined || !options.strict && !pub.isEmpty(isString ? trimString(value) : value)) { valid = true; } } else if (!options.strict && value == options.requiredValue || options.strict && value === options.requiredValue) { @@ -243,8 +243,17 @@ yii.validation = (function ($) { } value = $input.val(); - if (!options.skipOnEmpty || !pub.isEmpty(value)) { - value = $.trim(value); + if ( + (!options.skipOnEmpty || !pub.isEmpty(value)) + && (!options.skipOnArray || !Array.isArray(value)) + ) { + if (Array.isArray(value)) { + for (var i = 0; i < value.length; i++) { + value[i] = trimString(value[i], options); + } + } else { + value = trimString(value, options); + } $input.val(value); } @@ -261,7 +270,7 @@ yii.validation = (function ($) { hash = hash == null ? options.hash : hash[options.caseSensitive ? 0 : 1]; var v = options.caseSensitive ? value : value.toLowerCase(); for (var i = v.length - 1, h = 0; i >= 0; --i) { - h += v.charCodeAt(i); + h += v.charCodeAt(i) << i; } if (h != hash) { pub.addMessage(messages, options.message, value); @@ -467,5 +476,25 @@ yii.validation = (function ($) { } } + /** + * PHP: `trim($path, ' /')`, JS: `yii.helpers.trim(path, {chars: ' /'})` + */ + function trimString(value, options = {skipOnEmpty: true, chars: null}) { + if (options.skipOnEmpty !== false && pub.isEmpty(value)) { + return value; + } + + value = new String(value); + if (options.chars || !String.prototype.trim) { + var chars = !options.chars + ? ' \\s\xA0' + : options.chars.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\$1'); + + return value.replace(new RegExp('^[' + chars + ']+|[' + chars + ']+$', 'g'), ''); + } + + return value.trim(); + } + return pub; })(jQuery); diff --git a/framework/base/Action.php b/framework/base/Action.php index 5a9413cf296..0088f908d33 100644 --- a/framework/base/Action.php +++ b/framework/base/Action.php @@ -30,8 +30,7 @@ * * For more details and usage information on Action, see the [guide article on actions](guide:structure-controllers). * - * @property-read string $uniqueId The unique ID of this action among the whole application. This property is - * read-only. + * @property-read string $uniqueId The unique ID of this action among the whole application. * * @author Qiang Xue * @since 2.0 diff --git a/framework/base/ActionFilter.php b/framework/base/ActionFilter.php index 10d745a3b2e..b39c75826d1 100644 --- a/framework/base/ActionFilter.php +++ b/framework/base/ActionFilter.php @@ -36,7 +36,7 @@ class ActionFilter extends Behavior * * @see except */ - public $only; + public $only = []; /** * @var array list of action IDs that this filter should not apply to. * @see only diff --git a/framework/base/Application.php b/framework/base/Application.php index 94f4be11787..94910e1e3d5 100644 --- a/framework/base/Application.php +++ b/framework/base/Application.php @@ -14,40 +14,32 @@ * * For more details and usage information on Application, see the [guide article on applications](guide:structure-applications). * - * @property-read \yii\web\AssetManager $assetManager The asset manager application component. This property - * is read-only. - * @property-read \yii\rbac\ManagerInterface $authManager The auth manager application component. Null is - * returned if auth manager is not configured. This property is read-only. + * @property-read \yii\web\AssetManager $assetManager The asset manager application component. + * @property-read \yii\rbac\ManagerInterface|null $authManager The auth manager application component or null + * if it's not configured. * @property string $basePath The root directory of the application. * @property-read \yii\caching\CacheInterface $cache The cache application component. Null if the component is - * not enabled. This property is read-only. - * @property-write array $container Values given in terms of name-value pairs. This property is write-only. - * @property-read \yii\db\Connection $db The database connection. This property is read-only. + * not enabled. + * @property-write array $container Values given in terms of name-value pairs. + * @property-read \yii\db\Connection $db The database connection. * @property-read \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application - * component. This property is read-only. - * @property-read \yii\i18n\Formatter $formatter The formatter application component. This property is - * read-only. - * @property-read \yii\i18n\I18N $i18n The internationalization application component. This property is - * read-only. - * @property-read \yii\log\Dispatcher $log The log dispatcher application component. This property is - * read-only. - * @property-read \yii\mail\MailerInterface $mailer The mailer application component. This property is - * read-only. - * @property-read \yii\web\Request|\yii\console\Request $request The request component. This property is - * read-only. - * @property-read \yii\web\Response|\yii\console\Response $response The response component. This property is - * read-only. + * component. + * @property-read \yii\i18n\Formatter $formatter The formatter application component. + * @property-read \yii\i18n\I18N $i18n The internationalization application component. + * @property-read \yii\log\Dispatcher $log The log dispatcher application component. + * @property-read \yii\mail\MailerInterface $mailer The mailer application component. + * @property-read \yii\web\Request|\yii\console\Request $request The request component. + * @property-read \yii\web\Response|\yii\console\Response $response The response component. * @property string $runtimePath The directory that stores runtime files. Defaults to the "runtime" * subdirectory under [[basePath]]. - * @property-read \yii\base\Security $security The security application component. This property is read-only. + * @property-read \yii\base\Security $security The security application component. * @property string $timeZone The time zone used by this application. - * @property-read string $uniqueId The unique ID of the module. This property is read-only. - * @property-read \yii\web\UrlManager $urlManager The URL manager for this application. This property is - * read-only. + * @property-read string $uniqueId The unique ID of the module. + * @property-read \yii\web\UrlManager $urlManager The URL manager for this application. * @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under * [[basePath]]. * @property-read View|\yii\web\View $view The view application component that is used to render various view - * files. This property is read-only. + * files. * * @author Qiang Xue * @since 2.0 @@ -134,7 +126,7 @@ abstract class Application extends Module */ public $requestedRoute; /** - * @var Action the requested Action. If null, it means the request cannot be resolved into an action. + * @var Action|null the requested Action. If null, it means the request cannot be resolved into an action. */ public $requestedAction; /** @@ -142,7 +134,7 @@ abstract class Application extends Module */ public $requestedParams; /** - * @var array list of installed Yii extensions. Each array element represents a single extension + * @var array|null list of installed Yii extensions. Each array element represents a single extension * with the following structure: * * ```php @@ -477,7 +469,7 @@ public function setVendorPath($path) * If time zone is not configured in php.ini or application config, * it will be set to UTC by default. * @return string the time zone used by this application. - * @see https://secure.php.net/manual/en/function.date-default-timezone-get.php + * @see https://www.php.net/manual/en/function.date-default-timezone-get.php */ public function getTimeZone() { @@ -487,9 +479,9 @@ public function getTimeZone() /** * Sets the time zone used by this application. * This is a simple wrapper of PHP function date_default_timezone_set(). - * Refer to the [php manual](https://secure.php.net/manual/en/timezones.php) for available timezones. + * Refer to the [php manual](https://www.php.net/manual/en/timezones.php) for available timezones. * @param string $value the time zone used by this application. - * @see https://secure.php.net/manual/en/function.date-default-timezone-set.php + * @see https://www.php.net/manual/en/function.date-default-timezone-set.php */ public function setTimeZone($value) { @@ -525,7 +517,7 @@ public function getErrorHandler() /** * Returns the cache component. - * @return \yii\caching\CacheInterface the cache application component. Null if the component is not enabled. + * @return \yii\caching\CacheInterface|null the cache application component. Null if the component is not enabled. */ public function getCache() { @@ -589,6 +581,7 @@ public function getI18n() /** * Returns the mailer component. * @return \yii\mail\MailerInterface the mailer application component. + * @throws InvalidConfigException If this component is not configured. */ public function getMailer() { @@ -597,8 +590,7 @@ public function getMailer() /** * Returns the auth manager for this application. - * @return \yii\rbac\ManagerInterface the auth manager application component. - * Null is returned if auth manager is not configured. + * @return \yii\rbac\ManagerInterface|null the auth manager application component or null if it's not configured. */ public function getAuthManager() { @@ -625,20 +617,25 @@ public function getSecurity() /** * Returns the configuration of core application components. + * @return array * @see set() */ public function coreComponents() { - return [ + $components = [ 'log' => ['class' => 'yii\log\Dispatcher'], 'view' => ['class' => 'yii\web\View'], 'formatter' => ['class' => 'yii\i18n\Formatter'], 'i18n' => ['class' => 'yii\i18n\I18N'], - 'mailer' => ['class' => 'yii\swiftmailer\Mailer'], 'urlManager' => ['class' => 'yii\web\UrlManager'], 'assetManager' => ['class' => 'yii\web\AssetManager'], 'security' => ['class' => 'yii\base\Security'], ]; + if (class_exists('yii\swiftmailer\Mailer')) { + $components['mailer'] = ['class' => 'yii\swiftmailer\Mailer']; + } + + return $components; } /** @@ -646,7 +643,7 @@ public function coreComponents() * This method replaces the `exit()` function by ensuring the application life cycle is completed * before terminating the application. * @param int $status the exit status (value 0 means normal exit while other values mean abnormal exit). - * @param Response $response the response to be sent. If not set, the default application [[response]] component will be used. + * @param Response|null $response the response to be sent. If not set, the default application [[response]] component will be used. * @throws ExitException if the application is in testing mode */ public function end($status = 0, $response = null) diff --git a/framework/base/ArrayAccessTrait.php b/framework/base/ArrayAccessTrait.php index 87a1db1d61c..9c632bcd605 100644 --- a/framework/base/ArrayAccessTrait.php +++ b/framework/base/ArrayAccessTrait.php @@ -26,6 +26,7 @@ trait ArrayAccessTrait * It will be implicitly called when you use `foreach` to traverse the collection. * @return \ArrayIterator an iterator for traversing the cookies in the collection. */ + #[\ReturnTypeWillChange] public function getIterator() { return new \ArrayIterator($this->data); @@ -36,6 +37,7 @@ public function getIterator() * This method is required by Countable interface. * @return int number of data elements. */ + #[\ReturnTypeWillChange] public function count() { return count($this->data); @@ -46,6 +48,7 @@ public function count() * @param mixed $offset the offset to check on * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->data[$offset]); @@ -56,6 +59,7 @@ public function offsetExists($offset) * @param int $offset the offset to retrieve element. * @return mixed the element at the offset, null if no element is found at the offset */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return isset($this->data[$offset]) ? $this->data[$offset] : null; @@ -66,6 +70,7 @@ public function offsetGet($offset) * @param int $offset the offset to set element * @param mixed $item the element value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $item) { $this->data[$offset] = $item; @@ -75,6 +80,7 @@ public function offsetSet($offset, $item) * This method is required by the interface [[\ArrayAccess]]. * @param mixed $offset the offset to unset element */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->data[$offset]); diff --git a/framework/base/ArrayableTrait.php b/framework/base/ArrayableTrait.php index 727d71b4cf8..d2093fd8592 100644 --- a/framework/base/ArrayableTrait.php +++ b/framework/base/ArrayableTrait.php @@ -103,7 +103,7 @@ public function extraFields() * This method will first identify which fields to be included in the resulting array by calling [[resolveFields()]]. * It will then turn the model into an array with these fields. If `$recursive` is true, * any embedded objects will also be converted into arrays. - * When embeded objects are [[Arrayable]], their respective nested fields will be extracted and passed to [[toArray()]]. + * When embedded objects are [[Arrayable]], their respective nested fields will be extracted and passed to [[toArray()]]. * * If the model implements the [[Linkable]] interface, the resulting array will also have a `_link` element * which refers to a list of links as specified by the interface. @@ -128,17 +128,17 @@ public function toArray(array $fields = [], array $expand = [], $recursive = tru if ($recursive) { $nestedFields = $this->extractFieldsFor($fields, $field); $nestedExpand = $this->extractFieldsFor($expand, $field); - if ($attribute instanceof \JsonSerializable) { - $attribute = $attribute->jsonSerialize(); - } elseif ($attribute instanceof Arrayable) { + if ($attribute instanceof Arrayable) { $attribute = $attribute->toArray($nestedFields, $nestedExpand); + } elseif ($attribute instanceof \JsonSerializable) { + $attribute = $attribute->jsonSerialize(); } elseif (is_array($attribute)) { $attribute = array_map( function ($item) use ($nestedFields, $nestedExpand) { - if ($item instanceof \JsonSerializable) { - return $item->jsonSerialize(); - } elseif ($item instanceof Arrayable) { + if ($item instanceof Arrayable) { return $item->toArray($nestedFields, $nestedExpand); + } elseif ($item instanceof \JsonSerializable) { + return $item->jsonSerialize(); } return $item; }, diff --git a/framework/base/BaseObject.php b/framework/base/BaseObject.php index acb50ada50c..e5d4e1001c8 100644 --- a/framework/base/BaseObject.php +++ b/framework/base/BaseObject.php @@ -173,7 +173,7 @@ public function __set($name, $value) * Note that if the property is not defined, false will be returned. * @param string $name the property name or the event name * @return bool whether the named property is set (not null). - * @see https://secure.php.net/manual/en/function.isset.php + * @see https://www.php.net/manual/en/function.isset.php */ public function __isset($name) { @@ -195,7 +195,7 @@ public function __isset($name) * If the property is read-only, it will throw an exception. * @param string $name the property name * @throws InvalidCallException if the property is read only. - * @see https://secure.php.net/manual/en/function.unset.php + * @see https://www.php.net/manual/en/function.unset.php */ public function __unset($name) { diff --git a/framework/base/Component.php b/framework/base/Component.php index 65516e281fc..9884509ea52 100644 --- a/framework/base/Component.php +++ b/framework/base/Component.php @@ -93,8 +93,7 @@ * * For more details and usage information on Component, see the [guide article on components](guide:concept-components). * - * @property-read Behavior[] $behaviors List of behaviors attached to this component. This property is - * read-only. + * @property-read Behavior[] $behaviors List of behaviors attached to this component. * * @author Qiang Xue * @since 2.0 @@ -223,7 +222,7 @@ public function __set($name, $value) * will be implicitly called when executing `isset($component->property)`. * @param string $name the property name or the event name * @return bool whether the named property is set - * @see https://secure.php.net/manual/en/function.isset.php + * @see https://www.php.net/manual/en/function.isset.php */ public function __isset($name) { @@ -255,7 +254,7 @@ public function __isset($name) * will be implicitly called when executing `unset($component->property)`. * @param string $name the property name * @throws InvalidCallException if the property is read only. - * @see https://secure.php.net/manual/en/function.unset.php + * @see https://www.php.net/manual/en/function.unset.php */ public function __unset($name) { @@ -465,13 +464,17 @@ public function hasEventHandlers($name) { $this->ensureBehaviors(); + if (!empty($this->_events[$name])) { + return true; + } + foreach ($this->_eventWildcards as $wildcard => $handlers) { if (!empty($handlers) && StringHelper::matchWildcard($wildcard, $name)) { return true; } } - return !empty($this->_events[$name]) || Event::hasHandlers($this, $name); + return Event::hasHandlers($this, $name); } /** @@ -541,7 +544,7 @@ public function on($name, $handler, $data = null, $append = true) * wildcard will be removed, while handlers registered with plain names matching this wildcard will remain. * * @param string $name event name - * @param callable $handler the event handler to be removed. + * @param callable|null $handler the event handler to be removed. * If it is null, all handlers attached to the named event will be removed. * @return bool if a handler is found and detached * @see on() @@ -568,7 +571,7 @@ public function off($name, $handler = null) } if ($removed) { $this->_events[$name] = array_values($this->_events[$name]); - return $removed; + return true; } } @@ -594,10 +597,12 @@ public function off($name, $handler = null) /** * Triggers an event. - * This method represents the happening of an event. It invokes - * all attached handlers for the event including class-level handlers. + * + * This method represents the happening of an event. It invokes all attached handlers for the event + * including class-level handlers. + * * @param string $name the event name - * @param Event $event the event parameter. If not set, a default [[Event]] object will be created. + * @param Event|null $event the event instance. If not set, a default [[Event]] object will be created. */ public function trigger($name, Event $event = null) { @@ -606,15 +611,15 @@ public function trigger($name, Event $event = null) $eventHandlers = []; foreach ($this->_eventWildcards as $wildcard => $handlers) { if (StringHelper::matchWildcard($wildcard, $name)) { - $eventHandlers = array_merge($eventHandlers, $handlers); + $eventHandlers[] = $handlers; } } - if (!empty($this->_events[$name])) { - $eventHandlers = array_merge($eventHandlers, $this->_events[$name]); + $eventHandlers[] = $this->_events[$name]; } if (!empty($eventHandlers)) { + $eventHandlers = call_user_func_array('array_merge', $eventHandlers); if ($event === null) { $event = new Event(); } @@ -640,7 +645,7 @@ public function trigger($name, Event $event = null) /** * Returns the named behavior object. * @param string $name the behavior name - * @return null|Behavior the behavior object, or null if the behavior does not exist + * @return Behavior|null the behavior object, or null if the behavior does not exist */ public function getBehavior($name) { @@ -698,7 +703,7 @@ public function attachBehaviors($behaviors) * Detaches a behavior from the component. * The behavior's [[Behavior::detach()]] method will be invoked. * @param string $name the behavior's name. - * @return null|Behavior the detached behavior. Null if the behavior does not exist. + * @return Behavior|null the detached behavior. Null if the behavior does not exist. */ public function detachBehavior($name) { diff --git a/framework/base/Controller.php b/framework/base/Controller.php index e15b091eb0f..6bbe10b6dbd 100644 --- a/framework/base/Controller.php +++ b/framework/base/Controller.php @@ -16,12 +16,9 @@ * * For more details and usage information on Controller, see the [guide article on controllers](guide:structure-controllers). * - * @property-read Module[] $modules All ancestor modules that this controller is located within. This property - * is read-only. + * @property-read Module[] $modules All ancestor modules that this controller is located within. * @property-read string $route The route (module ID, controller ID and action ID) of the current request. - * This property is read-only. - * @property-read string $uniqueId The controller ID that is prefixed with the module ID (if any). This - * property is read-only. + * @property-read string $uniqueId The controller ID that is prefixed with the module ID (if any). * @property View|\yii\web\View $view The view object that can be used to render views or view files. * @property string $viewPath The directory containing the view files for this controller. * @@ -54,14 +51,14 @@ class Controller extends Component implements ViewContextInterface */ public $defaultAction = 'index'; /** - * @var null|string|false the name of the layout to be applied to this controller's views. + * @var string|null|false the name of the layout to be applied to this controller's views. * This property mainly affects the behavior of [[render()]]. * Defaults to null, meaning the actual layout value should inherit that from [[module]]'s layout value. * If false, no layout will be applied. */ public $layout; /** - * @var Action the action that is currently being executed. This property will be set + * @var Action|null the action that is currently being executed. This property will be set * by [[run()]] when it is called by [[Application]] to run an action. */ public $action; @@ -77,11 +74,11 @@ class Controller extends Component implements ViewContextInterface public $response = 'response'; /** - * @var View the view object that can be used to render views or view files. + * @var View|null the view object that can be used to render views or view files. */ private $_view; /** - * @var string the root directory that contains view files for this controller. + * @var string|null the root directory that contains view files for this controller. */ private $_viewPath; @@ -129,6 +126,7 @@ public function init() * * [[\Yii::createObject()]] will be used later to create the requested action * using the configuration provided here. + * @return array */ public function actions() { @@ -513,6 +511,7 @@ public function setViewPath($path) public function findLayoutFile($view) { $module = $this->module; + $layout = null; if (is_string($this->layout)) { $layout = $this->layout; } elseif ($this->layout === null) { @@ -524,7 +523,7 @@ public function findLayoutFile($view) } } - if (!isset($layout)) { + if ($layout === null) { return false; } diff --git a/framework/base/DynamicModel.php b/framework/base/DynamicModel.php index 610e03d8335..d9fadb0c03b 100644 --- a/framework/base/DynamicModel.php +++ b/framework/base/DynamicModel.php @@ -10,7 +10,9 @@ use yii\validators\Validator; /** - * DynamicModel is a model class primarily used to support ad hoc data validation. + * DynamicModel is a model class that supports defining attributes at run-time (the so-called + * "dynamic attributes") using its constructor or [[defineAttribute()]]. DynamicModel can be used + * to support ad hoc data validation. * * The typical usage of DynamicModel is as follows, * @@ -33,7 +35,7 @@ * The [[validateData()]] method creates an instance of DynamicModel, defines the attributes * using the given data (`name` and `email` in this example), and then calls [[Model::validate()]]. * - * You can check the validation result by [[hasErrors()]], like you do with a normal model. + * You can check the validation result using [[hasErrors()]], like you do with a normal model. * You may also access the dynamic attributes defined through the model instance, e.g., * `$model->name` and `$model->email`. * @@ -46,31 +48,26 @@ * ->validate(); * ``` * - * DynamicModel implements the above ad-hoc data validation feature by supporting the so-called - * "dynamic attributes". It basically allows an attribute to be defined dynamically through its constructor - * or [[defineAttribute()]]. - * * @author Qiang Xue * @since 2.0 */ class DynamicModel extends Model { + /** + * @var mixed[] dynamic attribute values (name => value). + */ private $_attributes = []; /** - * Array of the dynamic attribute labels. - * Used to as form field labels and in validation errors. - * - * @see attributeLabels() - * @see setAttributeLabels() - * @see setAttributeLabel() + * @var string[] dynamic attribute labels (name => label). + * Used as form field labels and in validation error messages. * @since 2.0.35 */ private $_attributeLabels = []; /** - * Constructors. - * @param array $attributes the dynamic attributes (name-value pairs, or names) being defined + * Constructor. + * @param array $attributes the attributes (name-value pairs, or names) being defined. * @param array $config the configuration array to be applied to this object. */ public function __construct(array $attributes = [], $config = []) @@ -151,7 +148,7 @@ public function canSetProperty($name, $checkVars = true, $checkBehaviors = true) /** * Returns a value indicating whether the model has an attribute with the specified name. - * @param string $name the name of the attribute + * @param string $name the name of the attribute. * @return bool whether the model has an attribute with the specified name. * @since 2.0.16 */ @@ -162,8 +159,8 @@ public function hasAttribute($name) /** * Defines an attribute. - * @param string $name the attribute name - * @param mixed $value the attribute value + * @param string $name the attribute name. + * @param mixed $value the attribute value. */ public function defineAttribute($name, $value = null) { @@ -172,7 +169,7 @@ public function defineAttribute($name, $value = null) /** * Undefines an attribute. - * @param string $name the attribute name + * @param string $name the attribute name. */ public function undefineAttribute($name) { @@ -183,15 +180,15 @@ public function undefineAttribute($name) * Adds a validation rule to this model. * You can also directly manipulate [[validators]] to add or remove validation rules. * This method provides a shortcut. - * @param string|array $attributes the attribute(s) to be validated by the rule + * @param string|array $attributes the attribute(s) to be validated by the rule. * @param string|Validator|\Closure $validator the validator. This can be either: * * a built-in validator name listed in [[builtInValidators]]; * * a method name of the model class; * * an anonymous function; * * a validator class name. * * a Validator. - * @param array $options the options (name-value pairs) to be applied to the validator - * @return $this the model itself + * @param array $options the options (name-value pairs) to be applied to the validator. + * @return $this */ public function addRule($attributes, $validator, $options = []) { @@ -212,9 +209,9 @@ public function addRule($attributes, $validator, $options = []) * Validates the given data with the specified validation rules. * This method will create a DynamicModel instance, populate it with the data to be validated, * create the specified validation rules, and then validate the data using these rules. - * @param array $data the data (name-value pairs) to be validated + * @param array $data the data (name-value pairs) to be validated. * @param array $rules the validation rules. Please refer to [[Model::rules()]] on the format of this parameter. - * @return static the model instance that contains the data being validated + * @return static the model instance that contains the data being validated. * @throws InvalidConfigException if a validation rule is not specified correctly. */ public static function validateData(array $data, $rules = []) @@ -249,14 +246,10 @@ public function attributes() } /** - * Sets the attribute labels in a massive way. - * - * @see attributeLabels() - * @see $_attributeLabels - * @since 2.0.35 - * - * @param array $labels Array of attribute labels + * Sets the labels for all attributes. + * @param string[] $labels attribute labels. * @return $this + * @since 2.0.35 */ public function setAttributeLabels(array $labels = []) { @@ -266,15 +259,11 @@ public function setAttributeLabels(array $labels = []) } /** - * Sets a label for an attribute. - * - * @see attributeLabels() - * @see $_attributeLabels - * @since 2.0.35 - * - * @param string $attribute Attribute name - * @param string $label Attribute label value + * Sets a label for a single attribute. + * @param string $attribute attribute name. + * @param string $label attribute label value. * @return $this + * @since 2.0.35 */ public function setAttributeLabel($attribute, $label) { @@ -284,10 +273,10 @@ public function setAttributeLabel($attribute, $label) } /** - * {@inheritDoc} + * {@inheritdoc} */ public function attributeLabels() { - return array_merge(parent::attributeLabels(), $this->_attributeLabels); + return $this->_attributeLabels; } } diff --git a/framework/base/ErrorException.php b/framework/base/ErrorException.php index c06111b57dd..24fdb6e8d7d 100644 --- a/framework/base/ErrorException.php +++ b/framework/base/ErrorException.php @@ -32,36 +32,36 @@ class ErrorException extends \ErrorException /** * Constructs the exception. - * @link https://secure.php.net/manual/en/errorexception.construct.php + * @link https://www.php.net/manual/en/errorexception.construct.php * @param string $message [optional] * @param int $code [optional] * @param int $severity [optional] * @param string $filename [optional] * @param int $lineno [optional] - * @param \Throwable|\Exception $previous [optional] + * @param \Throwable|null $previous [optional] */ public function __construct($message = '', $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, $previous = null) { parent::__construct($message, $code, $severity, $filename, $lineno, $previous); - if (function_exists('xdebug_get_function_stack')) { - // XDebug trace can't be modified and used directly with PHP 7 + if ($this->isXdebugStackAvailable()) { + // Xdebug trace can't be modified and used directly with PHP 7 // @see https://github.com/yiisoft/yii2/pull/11723 - $xDebugTrace = array_slice(array_reverse(xdebug_get_function_stack()), 1, -1); + $xdebugTrace = array_slice(array_reverse(xdebug_get_function_stack()), 1, -1); $trace = []; - foreach ($xDebugTrace as $frame) { + foreach ($xdebugTrace as $frame) { if (!isset($frame['function'])) { $frame['function'] = 'unknown'; } - // XDebug < 2.1.1: http://bugs.xdebug.org/view.php?id=695 + // Xdebug < 2.1.1: http://bugs.xdebug.org/view.php?id=695 if (!isset($frame['type']) || $frame['type'] === 'static') { $frame['type'] = '::'; } elseif ($frame['type'] === 'dynamic') { $frame['type'] = '->'; } - // XDebug has a different key name + // Xdebug has a different key name if (isset($frame['params']) && !isset($frame['args'])) { $frame['args'] = $frame['params']; } @@ -74,6 +74,32 @@ public function __construct($message = '', $code = 0, $severity = 1, $filename = } } + /** + * Ensures that Xdebug stack trace is available based on Xdebug version. + * Idea taken from developer bishopb at https://github.com/rollbar/rollbar-php + * @return bool + */ + private function isXdebugStackAvailable() + { + if (!function_exists('xdebug_get_function_stack')) { + return false; + } + + // check for Xdebug being installed to ensure origin of xdebug_get_function_stack() + $version = phpversion('xdebug'); + if ($version === false) { + return false; + } + + // Xdebug 2 and prior + if (version_compare($version, '3.0.0', '<')) { + return true; + } + + // Xdebug 3 and later, proper mode is required + return false !== strpos(ini_get('xdebug.mode'), 'develop'); + } + /** * Returns if error is one of fatal type. * diff --git a/framework/base/ErrorHandler.php b/framework/base/ErrorHandler.php index 8d98dafe789..04dfbb8d8e4 100644 --- a/framework/base/ErrorHandler.php +++ b/framework/base/ErrorHandler.php @@ -26,6 +26,12 @@ */ abstract class ErrorHandler extends Component { + /** + * @event Event an event that is triggered when the handler is called by shutdown function via [[handleFatalError()]]. + * @since 2.0.46 + */ + const EVENT_SHUTDOWN = 'shutdown'; + /** * @var bool whether to discard any existing page output before error display. Defaults to true. */ @@ -38,7 +44,7 @@ abstract class ErrorHandler extends Component */ public $memoryReserveSize = 262144; /** - * @var \Exception|null the exception that is being handled currently. + * @var \Throwable|null the exception that is being handled currently. */ public $exception; /** @@ -53,13 +59,17 @@ abstract class ErrorHandler extends Component */ private $_memoryReserve; /** - * @var \Exception from HHVM error that stores backtrace + * @var \Throwable from HHVM error that stores backtrace */ private $_hhvmException; /** * @var bool whether this instance has been registered using `register()` */ private $_registered = false; + /** + * @var string the current working directory + */ + private $_workingDirectory; public function init() @@ -70,6 +80,7 @@ public function init() /** * Register this error handler. + * * @since 2.0.32 this will not do anything if the error handler was already registered */ public function register() @@ -83,7 +94,11 @@ public function register() set_error_handler([$this, 'handleError']); } if ($this->memoryReserveSize > 0) { - $this->_memoryReserve = str_repeat('x', $this->memoryReserveSize); + $this->_memoryReserve = str_pad('', $this->memoryReserveSize, 'x'); + } + // to restore working directory in shutdown handler + if (PHP_SAPI !== 'cli') { + $this->_workingDirectory = getcwd(); } register_shutdown_function([$this, 'handleFatalError']); $this->_registered = true; @@ -97,6 +112,8 @@ public function register() public function unregister() { if ($this->_registered) { + $this->_memoryReserve = null; + $this->_workingDirectory = null; restore_error_handler(); restore_exception_handler(); $this->_registered = false; @@ -108,7 +125,7 @@ public function unregister() * * This method is implemented as a PHP exception handler. * - * @param \Exception $exception the exception that is not caught + * @param \Throwable $exception the exception that is not caught */ public function handleException($exception) { @@ -153,8 +170,8 @@ public function handleException($exception) /** * Handles exception thrown during exception processing in [[handleException()]]. - * @param \Exception|\Throwable $exception Exception that was thrown during main exception processing. - * @param \Exception $previousException Main exception processed in [[handleException()]]. + * @param \Throwable $exception Exception that was thrown during main exception processing. + * @param \Throwable $previousException Main exception processed in [[handleException()]]. * @since 2.0.11 */ protected function handleFallbackExceptionMessage($exception, $previousException) @@ -169,10 +186,10 @@ protected function handleFallbackExceptionMessage($exception, $previousException } else { echo '
      ' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '
      '; } + $msg .= "\n\$_SERVER = " . VarDumper::export($_SERVER); } else { echo 'An internal server error occurred.'; } - $msg .= "\n\$_SERVER = " . VarDumper::export($_SERVER); error_log($msg); if (defined('HHVM_VERSION')) { flush(); @@ -264,6 +281,13 @@ public function handleFatalError() { unset($this->_memoryReserve); + if (isset($this->_workingDirectory)) { + // fix working directory for some Web servers e.g. Apache + chdir($this->_workingDirectory); + // flush memory + unset($this->_workingDirectory); + } + // load ErrorException manually here because autoloading them will not work // when error occurs while autoloading a class if (!class_exists('yii\\base\\ErrorException', false)) { @@ -279,6 +303,7 @@ public function handleFatalError() $exception = new ErrorException($error['message'], $error['type'], $error['type'], $error['file'], $error['line']); } $this->exception = $exception; + unset($error); $this->logException($exception); @@ -286,25 +311,32 @@ public function handleFatalError() $this->clearOutput(); } $this->renderException($exception); + unset($exception); // need to explicitly flush logs because exit() next will terminate the app immediately Yii::getLogger()->flush(true); if (defined('HHVM_VERSION')) { flush(); } - exit(1); + + $this->trigger(static::EVENT_SHUTDOWN); + + // ensure it is called after user-defined shutdown functions + register_shutdown_function(function() { + exit(1); + }); } } /** * Renders the exception. - * @param \Exception|\Error|\Throwable $exception the exception to be rendered. + * @param \Throwable $exception the exception to be rendered. */ abstract protected function renderException($exception); /** * Logs the given exception. - * @param \Exception $exception the exception to be logged + * @param \Throwable $exception the exception to be logged * @since 2.0.3 this method is now public. */ public function logException($exception) @@ -336,7 +368,8 @@ public function clearOutput() * * This method can be used to convert exceptions inside of methods like `__toString()` * to PHP errors because exceptions cannot be thrown inside of them. - * @param \Exception|\Throwable $exception the exception to convert to a PHP error. + * @param \Throwable $exception the exception to convert to a PHP error. + * @return never */ public static function convertExceptionToError($exception) { @@ -345,7 +378,7 @@ public static function convertExceptionToError($exception) /** * Converts an exception into a simple string. - * @param \Exception|\Error|\Throwable $exception the exception being converted + * @param \Throwable $exception the exception being converted * @return string the string representation of the exception. */ public static function convertExceptionToString($exception) @@ -363,7 +396,7 @@ public static function convertExceptionToString($exception) /** * Converts an exception into a string that has verbose information about the exception and its trace. - * @param \Exception|\Error|\Throwable $exception the exception being converted + * @param \Throwable $exception the exception being converted * @return string the string representation of the exception. * * @since 2.0.14 diff --git a/framework/base/Event.php b/framework/base/Event.php index 5156c20daf3..9fd94367d15 100644 --- a/framework/base/Event.php +++ b/framework/base/Event.php @@ -34,7 +34,7 @@ class Event extends BaseObject */ public $name; /** - * @var object the sender of this event. If not set, this property will be + * @var object|null the sender of this event. If not set, this property will be * set as the object whose `trigger()` method is called. * This property may also be a `null` when this event is a * class-level event which is triggered in a static context. @@ -73,7 +73,7 @@ class Event extends BaseObject * `afterInsert` event: * * ```php - * Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { + * Event::on(ActiveRecord::class, ActiveRecord::EVENT_AFTER_INSERT, function ($event) { * Yii::trace(get_class($event->sender) . ' is inserted.'); * }); * ``` @@ -130,7 +130,7 @@ public static function on($class, $name, $handler, $data = null, $append = true) * * @param string $class the fully qualified class name from which the event handler needs to be detached. * @param string $name the event name. - * @param callable $handler the event handler to be removed. + * @param callable|null $handler the event handler to be removed. * If it is `null`, all handlers attached to the named event will be removed. * @return bool whether a handler is found and detached. * @see on() @@ -158,7 +158,7 @@ public static function off($class, $name, $handler = null) } if ($removed) { self::$_events[$name][$class] = array_values(self::$_events[$name][$class]); - return $removed; + return true; } } @@ -257,7 +257,7 @@ class_implements($class, true) * for the specified class and all its parent classes. * @param string|object $class the object or the fully qualified class name specifying the class-level event. * @param string $name the event name. - * @param Event $event the event parameter. If not set, a default [[Event]] object will be created. + * @param Event|null $event the event parameter. If not set, a default [[Event]] object will be created. */ public static function trigger($class, $name, $event = null) { diff --git a/framework/base/ExitException.php b/framework/base/ExitException.php index 4fde6a8e800..a1111abea05 100644 --- a/framework/base/ExitException.php +++ b/framework/base/ExitException.php @@ -28,11 +28,15 @@ class ExitException extends \Exception * @param int $status the exit status code * @param string $message error message * @param int $code error code - * @param \Throwable|\Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ public function __construct($status = 0, $message = null, $code = 0, $previous = null) { $this->statusCode = $status; - parent::__construct($message, $code, $previous); + if ($previous === null) { + parent::__construct((string)$message, $code); + } else { + parent::__construct((string)$message, $code, $previous); + } } } diff --git a/framework/base/Model.php b/framework/base/Model.php index 085ec1a992b..74f8da35aba 100644 --- a/framework/base/Model.php +++ b/framework/base/Model.php @@ -38,19 +38,18 @@ * For more details and usage information on Model, see the [guide article on models](guide:structure-models). * * @property-read \yii\validators\Validator[] $activeValidators The validators applicable to the current - * [[scenario]]. This property is read-only. + * [[scenario]]. * @property array $attributes Attribute values (name => value). - * @property-read array $errors An array of errors for all attributes. Empty array is returned if no error. - * The result is a two-dimensional array. See [[getErrors()]] for detailed description. This property is - * read-only. + * @property-read array $errors Errors for all attributes or the specified attribute. Empty array is returned + * if no error. See [[getErrors()]] for detailed description. Note that when returning errors for all attributes, + * the result is a two-dimensional array, like the following: ```php [ 'username' => [ 'Username is required.', + * 'Username must contain only word characters.', ], 'email' => [ 'Email address is invalid.', ] ] ``` . * @property-read array $firstErrors The first errors. The array keys are the attribute names, and the array - * values are the corresponding error messages. An empty array will be returned if there is no error. This - * property is read-only. - * @property-read ArrayIterator $iterator An iterator for traversing the items in the list. This property is - * read-only. + * values are the corresponding error messages. An empty array will be returned if there is no error. + * @property-read ArrayIterator $iterator An iterator for traversing the items in the list. * @property string $scenario The scenario that this model is in. Defaults to [[SCENARIO_DEFAULT]]. * @property-read ArrayObject|\yii\validators\Validator[] $validators All the validators declared in the - * model. This property is read-only. + * model. * * @author Qiang Xue * @since 2.0 @@ -261,21 +260,15 @@ public function formName() /** * Returns the list of attribute names. + * * By default, this method returns all public non-static properties of the class. * You may override this method to change the default behavior. - * @return array list of attribute names. + * + * @return string[] list of attribute names. */ public function attributes() { - $class = new ReflectionClass($this); - $names = []; - foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { - if (!$property->isStatic()) { - $names[] = $property->getName(); - } - } - - return $names; + return array_keys(Yii::getObjectVars($this)); } /** @@ -335,9 +328,9 @@ public function attributeHints() * Errors found during the validation can be retrieved via [[getErrors()]], * [[getFirstErrors()]] and [[getFirstError()]]. * - * @param string[]|string $attributeNames attribute name or list of attribute names that should be validated. - * If this parameter is empty, it means any attribute listed in the applicable - * validation rules should be validated. + * @param string[]|string|null $attributeNames attribute name or list of attribute names + * that should be validated. If this parameter is empty, it means any attribute listed in + * the applicable validation rules should be validated. * @param bool $clearErrors whether to call [[clearErrors()]] before performing validation * @return bool whether the validation is successful without any error. * @throws InvalidArgumentException if the current scenario is unknown. @@ -426,7 +419,7 @@ public function getValidators() /** * Returns the validators applicable to the current [[scenario]]. - * @param string $attribute the name of the attribute whose applicable validators should be returned. + * @param string|null $attribute the name of the attribute whose applicable validators should be returned. * If this is null, the validators for ALL attributes in the model will be returned. * @return \yii\validators\Validator[] the validators applicable to the current [[scenario]]. */ @@ -561,10 +554,9 @@ public function hasErrors($attribute = null) /** * Returns the errors for all attributes or a single attribute. - * @param string $attribute attribute name. Use null to retrieve errors for all attributes. - * @property array An array of errors for all attributes. Empty array is returned if no error. - * The result is a two-dimensional array. See [[getErrors()]] for detailed description. + * @param string|null $attribute attribute name. Use null to retrieve errors for all attributes. * @return array errors for all attributes or the specified attribute. Empty array is returned if no error. + * See [[getErrors()]] for detailed description. * Note that when returning errors for all attributes, the result is a two-dimensional array, like the following: * * ```php @@ -617,7 +609,7 @@ public function getFirstErrors() /** * Returns the first error of the specified attribute. * @param string $attribute attribute name. - * @return string the error message. Null is returned if no error. + * @return string|null the error message. Null is returned if no error. * @see getErrors() * @see getFirstErrors() */ @@ -678,7 +670,7 @@ public function addErrors(array $items) /** * Removes errors for all attributes or a single attribute. - * @param string $attribute attribute name. Use null to remove errors for all attributes. + * @param string|null $attribute attribute name. Use null to remove errors for all attributes. */ public function clearErrors($attribute = null) { @@ -704,7 +696,7 @@ public function generateAttributeLabel($name) /** * Returns attribute values. - * @param array $names list of attributes whose value needs to be returned. + * @param array|null $names list of attributes whose value needs to be returned. * Defaults to null, meaning all attributes listed in [[attributes()]] will be returned. * If it is an array, only the attributes in the array will be returned. * @param array $except list of attributes whose value should NOT be returned. @@ -857,7 +849,7 @@ public function activeAttributes() * Note, that the data being populated is subject to the safety check by [[setAttributes()]]. * * @param array $data the data array to load, typically `$_POST` or `$_GET`. - * @param string $formName the form name to use to load the data into the model. + * @param string|null $formName the form name to use to load the data into the model, empty string when form not use. * If not set, [[formName()]] is used. * @return bool whether `load()` found the expected form in `$data`. */ @@ -887,7 +879,7 @@ public function load($data, $formName = null) * @param array $models the models to be populated. Note that all models should have the same class. * @param array $data the data array. This is usually `$_POST` or `$_GET`, but can also be any valid array * supplied by end user. - * @param string $formName the form name to be used for loading the data into the models. + * @param string|null $formName the form name to be used for loading the data into the models. * If not set, it will use the [[formName()]] value of the first model in `$models`. * This parameter is available since version 2.0.1. * @return bool whether at least one of the models is successfully populated. @@ -923,7 +915,7 @@ public static function loadMultiple($models, $data, $formName = null) * This method will validate every model. The models being validated may * be of the same or different types. * @param array $models the models to be validated - * @param array $attributeNames list of attribute names that should be validated. + * @param array|null $attributeNames list of attribute names that should be validated. * If this parameter is empty, it means any attribute listed in the applicable * validation rules should be validated. * @return bool whether all models are valid. False will be returned if one @@ -997,6 +989,7 @@ public function fields() * This method is required by the interface [[\IteratorAggregate]]. * @return ArrayIterator an iterator for traversing the items in the list. */ + #[\ReturnTypeWillChange] public function getIterator() { $attributes = $this->getAttributes(); @@ -1007,9 +1000,10 @@ public function getIterator() * Returns whether there is an element at the specified offset. * This method is required by the SPL interface [[\ArrayAccess]]. * It is implicitly called when you use something like `isset($model[$offset])`. - * @param mixed $offset the offset to check on. + * @param string $offset the offset to check on. * @return bool whether or not an offset exists. */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->$offset); @@ -1019,9 +1013,10 @@ public function offsetExists($offset) * Returns the element at the specified offset. * This method is required by the SPL interface [[\ArrayAccess]]. * It is implicitly called when you use something like `$value = $model[$offset];`. - * @param mixed $offset the offset to retrieve element. + * @param string $offset the offset to retrieve element. * @return mixed the element at the offset, null if no element is found at the offset */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->$offset; @@ -1030,23 +1025,36 @@ public function offsetGet($offset) /** * Sets the element at the specified offset. * This method is required by the SPL interface [[\ArrayAccess]]. - * It is implicitly called when you use something like `$model[$offset] = $item;`. - * @param int $offset the offset to set element - * @param mixed $item the element value + * It is implicitly called when you use something like `$model[$offset] = $value;`. + * @param string $offset the offset to set element + * @param mixed $value the element value */ - public function offsetSet($offset, $item) + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) { - $this->$offset = $item; + $this->$offset = $value; } /** * Sets the element value at the specified offset to null. * This method is required by the SPL interface [[\ArrayAccess]]. * It is implicitly called when you use something like `unset($model[$offset])`. - * @param mixed $offset the offset to unset element + * @param string $offset the offset to unset element */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $this->$offset = null; } + + /** + * {@inheritdoc} + */ + public function __clone() + { + parent::__clone(); + + $this->_errors = null; + $this->_validators = null; + } } diff --git a/framework/base/Module.php b/framework/base/Module.php index d8577d482ed..48e040ad560 100644 --- a/framework/base/Module.php +++ b/framework/base/Module.php @@ -25,15 +25,14 @@ * * @property-write array $aliases List of path aliases to be defined. The array keys are alias names (must * start with `@`) and the array values are the corresponding paths or aliases. See [[setAliases()]] for an - * example. This property is write-only. + * example. * @property string $basePath The root directory of the module. - * @property-read string $controllerPath The directory that contains the controller classes. This property is - * read-only. + * @property string $controllerPath The directory that contains the controller classes. * @property string $layoutPath The root directory of layout files. Defaults to "[[viewPath]]/layouts". * @property array $modules The modules (indexed by their IDs). - * @property-read string $uniqueId The unique ID of the module. This property is read-only. + * @property-read string $uniqueId The unique ID of the module. * @property string $version The version of this module. Note that the type of this property differs in getter - * and setter. See [[getVersion()]] and [[setVersion()]] for details. + * and setter. See [[getVersion()]] and [[setVersion()]] for details. * @property string $viewPath The root directory of view files. Defaults to "[[basePath]]/views". * * @author Qiang Xue @@ -60,11 +59,11 @@ class Module extends ServiceLocator */ public $id; /** - * @var Module the parent module of this module. `null` if this module does not have a parent. + * @var Module|null the parent module of this module. `null` if this module does not have a parent. */ public $module; /** - * @var string|bool the layout that should be applied for views within this module. This refers to a view name + * @var string|bool|null the layout that should be applied for views within this module. This refers to a view name * relative to [[layoutPath]]. If this is not set, it means the layout value of the [[module|parent module]] * will be taken. If this is `false`, layout will be disabled within this module. */ @@ -90,7 +89,7 @@ class Module extends ServiceLocator */ public $controllerMap = []; /** - * @var string the namespace that controller classes are in. + * @var string|null the namespace that controller classes are in. * This namespace will be used to load controller classes by prepending it to the controller * class name. * @@ -115,6 +114,10 @@ class Module extends ServiceLocator * @var string the root directory of the module. */ private $_basePath; + /** + * @var string The root directory that contains the controller classes for this module. + */ + private $_controllerPath; /** * @var string the root directory that contains view files for this module */ @@ -128,7 +131,7 @@ class Module extends ServiceLocator */ private $_modules = []; /** - * @var string|callable the version of this module. + * @var string|callable|null the version of this module. * Version can be specified as a PHP callback, which can accept module instance as an argument and should * return the actual version. For example: * @@ -148,7 +151,7 @@ class Module extends ServiceLocator /** * Constructor. * @param string $id the ID of this module. - * @param Module $parent the parent module (if any). + * @param Module|null $parent the parent module (if any). * @param array $config name-value pairs that will be used to initialize the object properties. */ public function __construct($id, $parent = null, $config = []) @@ -238,7 +241,7 @@ public function setBasePath($path) { $path = Yii::getAlias($path); $p = strncmp($path, 'phar://', 7) === 0 ? $path : realpath($path); - if ($p !== false && is_dir($p)) { + if (is_string($p) && is_dir($p)) { $this->_basePath = $p; } else { throw new InvalidArgumentException("The directory does not exist: $path"); @@ -254,7 +257,22 @@ public function setBasePath($path) */ public function getControllerPath() { - return Yii::getAlias('@' . str_replace('\\', '/', $this->controllerNamespace)); + if ($this->_controllerPath === null) { + $this->_controllerPath = Yii::getAlias('@' . str_replace('\\', '/', $this->controllerNamespace)); + } + + return $this->_controllerPath; + } + + /** + * Sets the directory that contains the controller classes. + * @param string $path the root directory that contains the controller classes. + * @throws InvalidArgumentException if the directory is invalid. + * @since 2.0.44 + */ + public function setControllerPath($path) + { + $this->_controllerPath = Yii::getAlias($path); } /** @@ -324,7 +342,7 @@ public function getVersion() /** * Sets current module version. - * @param string|callable $version the version of this module. + * @param string|callable|null $version the version of this module. * Version can be specified as a PHP callback, which can accept module instance as an argument and should * return the actual version. For example: * @@ -425,7 +443,7 @@ public function getModule($id, $load = true) Yii::debug("Loading module: $id", __METHOD__); /* @var $module Module */ $module = Yii::createObject($this->_modules[$id], [$id, $this]); - $module->setInstance($module); + $module::setInstance($module); return $this->_modules[$id] = $module; } } @@ -450,6 +468,9 @@ public function setModule($id, $module) unset($this->_modules[$id]); } else { $this->_modules[$id] = $module; + if ($module instanceof self) { + $module->module = $this; + } } } @@ -504,6 +525,9 @@ public function setModules($modules) { foreach ($modules as $id => $module) { $this->_modules[$id] = $module; + if ($module instanceof self) { + $module->module = $this; + } } } diff --git a/framework/base/Security.php b/framework/base/Security.php index e3a2373ab8a..6a90b6cd5d2 100644 --- a/framework/base/Security.php +++ b/framework/base/Security.php @@ -55,12 +55,12 @@ class Security extends Component ]; /** * @var string Hash algorithm for key derivation. Recommend sha256, sha384 or sha512. - * @see [hash_algos()](https://secure.php.net/manual/en/function.hash-algos.php) + * @see [hash_algos()](https://www.php.net/manual/en/function.hash-algos.php) */ public $kdfHash = 'sha256'; /** * @var string Hash algorithm for message authentication. Recommend sha256, sha384 or sha512. - * @see [hash_algos()](https://secure.php.net/manual/en/function.hash-algos.php) + * @see [hash_algos()](https://www.php.net/manual/en/function.hash-algos.php) */ public $macHash = 'sha256'; /** @@ -116,14 +116,6 @@ protected function shouldUseLibreSSL() return $this->_useLibreSSL; } - /** - * @return bool if operating system is Windows - */ - private function isWindows() - { - return DIRECTORY_SEPARATOR !== '/'; - } - /** * Encrypts data using a password. * Derives keys for encryption and authentication from the password using PBKDF2 and a random salt, @@ -154,7 +146,7 @@ public function encryptByPassword($data, $password) * to hash input or output data. * @param string $data the data to encrypt * @param string $inputKey the input to use for encryption and authentication - * @param string $info optional context and application specific information, see [[hkdf()]] + * @param string|null $info optional context and application specific information, see [[hkdf()]] * @return string the encrypted data as byte string * @see decryptByKey() * @see encryptByPassword() @@ -180,7 +172,7 @@ public function decryptByPassword($data, $password) * Verifies and decrypts data encrypted with [[encryptByKey()]]. * @param string $data the encrypted data to decrypt * @param string $inputKey the input to use for encryption and authentication - * @param string $info optional context and application specific information, see [[hkdf()]] + * @param string|null $info optional context and application specific information, see [[hkdf()]] * @return bool|string the decrypted data or false on authentication failure * @see encryptByKey() */ @@ -294,8 +286,8 @@ protected function decrypt($data, $passwordBased, $secret, $info) * Recommend use one of the SHA-2 hash algorithms: sha224, sha256, sha384 or sha512. * @param string $algo a hash algorithm supported by `hash_hmac()`, e.g. 'SHA-256' * @param string $inputKey the source key - * @param string $salt the random salt - * @param string $info optional info to bind the derived key material to application- + * @param string|null $salt the random salt + * @param string|null $info optional info to bind the derived key material to application- * and context-specific information, e.g. a user ID or API version, see * [RFC 5869](https://tools.ietf.org/html/rfc5869) * @param int $length length of the output key in bytes. If 0, the output key is @@ -306,7 +298,7 @@ protected function decrypt($data, $passwordBased, $secret, $info) public function hkdf($algo, $inputKey, $salt = null, $info = null, $length = 0) { if (function_exists('hash_hkdf')) { - $outputKey = hash_hkdf($algo, $inputKey, $length, $info, $salt); + $outputKey = hash_hkdf((string)$algo, (string)$inputKey, $length, (string)$info, (string)$salt); if ($outputKey === false) { throw new InvalidArgumentException('Invalid parameters to hash_hkdf()'); } @@ -471,8 +463,6 @@ public function validateData($data, $key, $rawHash = false) return false; } - private $_randomFile; - /** * Generates specified number of random bytes. * Note that output may not be ASCII. @@ -493,84 +483,7 @@ public function generateRandomKey($length = 32) throw new InvalidArgumentException('First parameter ($length) must be greater than 0'); } - // always use random_bytes() if it is available - if (function_exists('random_bytes')) { - return random_bytes($length); - } - - // The recent LibreSSL RNGs are faster and likely better than /dev/urandom. - // Since 5.4.0, openssl_random_pseudo_bytes() reads from CryptGenRandom on Windows instead - // of using OpenSSL library. LibreSSL is OK everywhere but don't use OpenSSL on non-Windows. - if (function_exists('openssl_random_pseudo_bytes') - && ($this->shouldUseLibreSSL() || $this->isWindows()) - ) { - $key = openssl_random_pseudo_bytes($length, $cryptoStrong); - if ($cryptoStrong === false) { - throw new Exception( - 'openssl_random_pseudo_bytes() set $crypto_strong false. Your PHP setup is insecure.' - ); - } - if ($key !== false && StringHelper::byteLength($key) === $length) { - return $key; - } - } - - // mcrypt_create_iv() does not use libmcrypt. Since PHP 5.3.7 it directly reads - // CryptGenRandom on Windows. Elsewhere it directly reads /dev/urandom. - if (function_exists('mcrypt_create_iv')) { - $key = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); - if (StringHelper::byteLength($key) === $length) { - return $key; - } - } - - // If not on Windows, try to open a random device. - if ($this->_randomFile === null && !$this->isWindows()) { - // urandom is a symlink to random on FreeBSD. - $device = PHP_OS === 'FreeBSD' ? '/dev/random' : '/dev/urandom'; - // Check random device for special character device protection mode. Use lstat() - // instead of stat() in case an attacker arranges a symlink to a fake device. - $lstat = @lstat($device); - if ($lstat !== false && ($lstat['mode'] & 0170000) === 020000) { - $this->_randomFile = fopen($device, 'rb') ?: null; - - if (is_resource($this->_randomFile)) { - // Reduce PHP stream buffer from default 8192 bytes to optimize data - // transfer from the random device for smaller values of $length. - // This also helps to keep future randoms out of user memory space. - $bufferSize = 8; - - if (function_exists('stream_set_read_buffer')) { - stream_set_read_buffer($this->_randomFile, $bufferSize); - } - // stream_set_read_buffer() isn't implemented on HHVM - if (function_exists('stream_set_chunk_size')) { - stream_set_chunk_size($this->_randomFile, $bufferSize); - } - } - } - } - - if (is_resource($this->_randomFile)) { - $buffer = ''; - $stillNeed = $length; - while ($stillNeed > 0) { - $someBytes = fread($this->_randomFile, $stillNeed); - if ($someBytes === false) { - break; - } - $buffer .= $someBytes; - $stillNeed -= StringHelper::byteLength($someBytes); - if ($stillNeed === 0) { - // Leaving file pointer open in order to make next generation faster by reusing it. - return $buffer; - } - } - fclose($this->_randomFile); - $this->_randomFile = null; - } - - throw new Exception('Unable to generate a random key'); + return random_bytes($length); } /** @@ -616,7 +529,7 @@ public function generateRandomString($length = 32) * ``` * * @param string $password The password to be hashed. - * @param int $cost Cost parameter used by the Blowfish hash algorithm. + * @param int|null $cost Cost parameter used by the Blowfish hash algorithm. * The higher the value of cost, * the longer it takes to generate the hash and to verify a password against it. Higher cost * therefore slows down a brute-force attack. For best protection against brute-force attacks, @@ -624,7 +537,7 @@ public function generateRandomString($length = 32) * compute the hash doubles for every increment by one of $cost. * @return string The password hash string. When [[passwordHashStrategy]] is set to 'crypt', * the output is always 60 ASCII characters, when set to 'password_hash' the output length - * might increase in future versions of PHP (https://secure.php.net/manual/en/function.password-hash.php) + * might increase in future versions of PHP (https://www.php.net/manual/en/function.password-hash.php) * @throws Exception on bad password parameter or cost parameter. * @see validatePassword() */ @@ -686,7 +599,7 @@ public function validatePassword($password, $hash) /** * Generates a salt that can be used to generate a password hash. * - * The PHP [crypt()](https://secure.php.net/manual/en/function.crypt.php) built-in function + * The PHP [crypt()](https://www.php.net/manual/en/function.crypt.php) built-in function * requires, for the Blowfish hash algorithm, a salt string in a specific format: * "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters * from the alphabet "./0-9A-Za-z". diff --git a/framework/base/Theme.php b/framework/base/Theme.php index b50334426eb..011c8c239a4 100644 --- a/framework/base/Theme.php +++ b/framework/base/Theme.php @@ -74,7 +74,7 @@ class Theme extends Component { /** - * @var array the mapping between view directories and their corresponding themed versions. + * @var array|null the mapping between view directories and their corresponding themed versions. * This property is used by [[applyTo()]] when a view is trying to apply the theme. * [Path aliases](guide:concept-aliases) can be used when specifying directories. * If this property is empty or not set, a mapping [[Application::basePath]] to [[basePath]] will be used. diff --git a/framework/base/View.php b/framework/base/View.php index d5b64c668c1..dce2a9b0a0d 100644 --- a/framework/base/View.php +++ b/framework/base/View.php @@ -21,7 +21,7 @@ * For more details and usage information on View, see the [guide article on views](guide:structure-views). * * @property-read string|bool $viewFile The view file currently being rendered. False if no view file is being - * rendered. This property is read-only. + * rendered. * * @author Qiang Xue * @since 2.0 @@ -50,11 +50,11 @@ class View extends Component implements DynamicContentAwareInterface */ public $context; /** - * @var mixed custom parameters that are shared among view templates. + * @var array custom parameters that are shared among view templates. */ public $params = []; /** - * @var array a list of available renderers indexed by their corresponding supported file extensions. + * @var array|null a list of available renderers indexed by their corresponding supported file extensions. * Each renderer may be a view renderer object or the configuration for creating the renderer object. * For example, the following configuration enables both Smarty and Twig view renderers: * @@ -74,7 +74,7 @@ class View extends Component implements DynamicContentAwareInterface */ public $defaultExtension = 'php'; /** - * @var Theme|array|string the theme object or the configuration for creating the theme object. + * @var Theme|array|string|null the theme object or the configuration for creating the theme object. * If not set, it means theming is not enabled. */ public $theme; @@ -142,7 +142,7 @@ public function init() * * @param string $view the view name. * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @param object $context the context to be assigned to the view and can later be accessed via [[context]] + * @param object|null $context the context to be assigned to the view and can later be accessed via [[context]] * in the view. If the context implements [[ViewContextInterface]], it may also be used to locate * the view file corresponding to a relative view name. * @return string the rendering result @@ -160,7 +160,7 @@ public function render($view, $params = [], $context = null) * Finds the view file based on the given view name. * @param string $view the view name or the [path alias](guide:concept-aliases) of the view file. Please refer to [[render()]] * on how to specify this parameter. - * @param object $context the context to be assigned to the view and can later be accessed via [[context]] + * @param object|null $context the context to be assigned to the view and can later be accessed via [[context]] * in the view. If the context implements [[ViewContextInterface]], it may also be used to locate * the view file corresponding to a relative view name. * @return string the view file path. Note that the file may not exist. @@ -215,7 +215,7 @@ protected function findViewFile($view, $context = null) * * @param string $viewFile the view file. This can be either an absolute file path or an alias of it. * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @param object $context the context that the view should use for rendering the view. If null, + * @param object|null $context the context that the view should use for rendering the view. If null, * existing [[context]] will be used. * @return string the rendering result * @throws ViewNotFoundException if the view file does not exist @@ -316,10 +316,10 @@ public function afterRender($viewFile, $params, &$output) $event = new ViewEvent([ 'viewFile' => $viewFile, 'params' => $params, - 'output' => $output, ]); + $event->output =& $output; + $this->trigger(self::EVENT_AFTER_RENDER, $event); - $output = $event->output; } } @@ -335,7 +335,6 @@ public function afterRender($viewFile, $params, &$output) * @param string $_file_ the view file. * @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file. * @return string the rendering result - * @throws \Exception * @throws \Throwable */ public function renderPhpFile($_file_, $_params_ = []) diff --git a/framework/base/Widget.php b/framework/base/Widget.php index ab27f028f2f..ecd99ecdcd5 100644 --- a/framework/base/Widget.php +++ b/framework/base/Widget.php @@ -16,11 +16,10 @@ * For more details and usage information on Widget, see the [guide article on widgets](guide:structure-widgets). * * @property string|null $id ID of the widget. Note that the type of this property differs in getter and - * setter. See [[getId()]] and [[setId()]] for details. + * setter. See [[getId()]] and [[setId()]] for details. * @property \yii\web\View $view The view object that can be used to render views or view files. Note that the - * type of this property differs in getter and setter. See [[getView()]] and [[setView()]] for details. - * @property-read string $viewPath The directory containing the view files for this widget. This property is - * read-only. + * type of this property differs in getter and setter. See [[getView()]] and [[setView()]] for details. + * @property-read string $viewPath The directory containing the view files for this widget. * * @author Qiang Xue * @since 2.0 @@ -104,7 +103,13 @@ public static function end() { if (!empty(self::$stack)) { $widget = array_pop(self::$stack); - if (get_class($widget) === get_called_class()) { + + $calledClass = get_called_class(); + if (Yii::$container->has($calledClass) && isset(Yii::$container->getDefinitions()[$calledClass]['class'])) { + $calledClass = Yii::$container->getDefinitions()[$calledClass]['class']; + } + + if (get_class($widget) === $calledClass) { /* @var $widget Widget */ if ($widget->beforeRun()) { $result = $widget->run(); @@ -126,7 +131,7 @@ public static function end() * The widget rendering result is returned by this method. * @param array $config name-value pairs that will be used to initialize the object properties * @return string the rendering result of the widget. - * @throws \Exception + * @throws \Throwable */ public static function widget($config = []) { @@ -147,6 +152,12 @@ public static function widget($config = []) ob_end_clean(); } throw $e; + } catch (\Throwable $e) { + // close the output buffer opened above if it has not been closed already + if (ob_get_level() > 0) { + ob_end_clean(); + } + throw $e; } return ob_get_clean() . $out; @@ -206,7 +217,8 @@ public function setView($view) /** * Executes the widget. - * @return string the result of widget execution to be outputted. + * + * @return string|void the rendering result may be directly "echoed" or returned as a string */ public function run() { diff --git a/framework/behaviors/AttributeBehavior.php b/framework/behaviors/AttributeBehavior.php index c50f180f6cc..0b4ba8b3a62 100644 --- a/framework/behaviors/AttributeBehavior.php +++ b/framework/behaviors/AttributeBehavior.php @@ -28,7 +28,7 @@ * { * return [ * [ - * 'class' => AttributeBehavior::className(), + * 'class' => AttributeBehavior::class, * 'attributes' => [ * ActiveRecord::EVENT_BEFORE_INSERT => 'attribute1', * ActiveRecord::EVENT_BEFORE_UPDATE => 'attribute2', diff --git a/framework/behaviors/AttributeTypecastBehavior.php b/framework/behaviors/AttributeTypecastBehavior.php index c9c02cfe25d..4c03e1f1d33 100644 --- a/framework/behaviors/AttributeTypecastBehavior.php +++ b/framework/behaviors/AttributeTypecastBehavior.php @@ -37,7 +37,7 @@ * { * return [ * 'typecast' => [ - * 'class' => AttributeTypecastBehavior::className(), + * 'class' => AttributeTypecastBehavior::class, * 'attributeTypes' => [ * 'amount' => AttributeTypecastBehavior::TYPE_INTEGER, * 'price' => AttributeTypecastBehavior::TYPE_FLOAT, @@ -77,7 +77,7 @@ * { * return [ * 'typecast' => [ - * 'class' => AttributeTypecastBehavior::className(), + * 'class' => AttributeTypecastBehavior::class, * // 'attributeTypes' will be composed automatically according to `rules()` * ], * ]; @@ -121,7 +121,7 @@ class AttributeTypecastBehavior extends Behavior */ public $owner; /** - * @var array attribute typecast map in format: attributeName => type. + * @var array|null attribute typecast map in format: attributeName => type. * Type can be set via PHP callable, which accept raw value as an argument and should return * typecast result. * For example: @@ -132,7 +132,7 @@ class AttributeTypecastBehavior extends Behavior * 'price' => 'float', * 'is_active' => 'boolean', * 'date' => function ($value) { - * return ($value instanceof \DateTime) ? $value->getTimestamp(): (int)$value; + * return ($value instanceof \DateTime) ? $value->getTimestamp(): (int) $value; * }, * ] * ``` @@ -214,7 +214,7 @@ public function attach($owner) /** * Typecast owner attributes according to [[attributeTypes]]. - * @param array $attributeNames list of attribute names that should be type-casted. + * @param array|null $attributeNames list of attribute names that should be type-casted. * If this parameter is empty, it means any attribute listed in the [[attributeTypes]] * should be type-casted. */ @@ -346,7 +346,7 @@ public function beforeSave($event) { $this->typecastAttributes(); } - + /** * Handles owner 'afterInsert' and 'afterUpdate' events, ensuring attribute typecasting. * @param \yii\base\Event $event event instance. diff --git a/framework/behaviors/AttributesBehavior.php b/framework/behaviors/AttributesBehavior.php index 1ac025f16e4..e1b0f874ea5 100644 --- a/framework/behaviors/AttributesBehavior.php +++ b/framework/behaviors/AttributesBehavior.php @@ -28,7 +28,7 @@ * { * return [ * [ - * 'class' => AttributesBehavior::className(), + * 'class' => AttributesBehavior::class, * 'attributes' => [ * 'attribute1' => [ * ActiveRecord::EVENT_BEFORE_INSERT => new Expression('NOW()'), diff --git a/framework/behaviors/BlameableBehavior.php b/framework/behaviors/BlameableBehavior.php index 38d1a8b1441..b4c7ab07882 100755 --- a/framework/behaviors/BlameableBehavior.php +++ b/framework/behaviors/BlameableBehavior.php @@ -21,7 +21,7 @@ * public function behaviors() * { * return [ - * BlameableBehavior::className(), + * BlameableBehavior::class, * ]; * } * ``` @@ -41,7 +41,7 @@ * { * return [ * [ - * 'class' => BlameableBehavior::className(), + * 'class' => BlameableBehavior::class, * 'createdByAttribute' => 'author_id', * 'updatedByAttribute' => 'updater_id', * ], diff --git a/framework/behaviors/CacheableWidgetBehavior.php b/framework/behaviors/CacheableWidgetBehavior.php index 60db7ec023c..c6d4cd32c5c 100644 --- a/framework/behaviors/CacheableWidgetBehavior.php +++ b/framework/behaviors/CacheableWidgetBehavior.php @@ -30,7 +30,7 @@ * { * return [ * [ - * 'class' => CacheableWidgetBehavior::className(), + * 'class' => CacheableWidgetBehavior::class, * 'cacheDuration' => 0, * 'cacheDependency' => [ * 'class' => 'yii\caching\DbDependency', diff --git a/framework/behaviors/OptimisticLockBehavior.php b/framework/behaviors/OptimisticLockBehavior.php index fb01a1a488f..b3fd6a405b3 100644 --- a/framework/behaviors/OptimisticLockBehavior.php +++ b/framework/behaviors/OptimisticLockBehavior.php @@ -33,7 +33,7 @@ * public function behaviors() * { * return [ - * OptimisticLockBehavior::className(), + * OptimisticLockBehavior::class, * ]; * } * ``` diff --git a/framework/behaviors/SluggableBehavior.php b/framework/behaviors/SluggableBehavior.php index 13ebab3b5cf..f095204e067 100644 --- a/framework/behaviors/SluggableBehavior.php +++ b/framework/behaviors/SluggableBehavior.php @@ -29,7 +29,7 @@ * { * return [ * [ - * 'class' => SluggableBehavior::className(), + * 'class' => SluggableBehavior::class, * 'attribute' => 'title', * // 'slugAttribute' => 'slug', * ], @@ -50,7 +50,7 @@ * { * return [ * [ - * 'class' => SluggableBehavior::className(), + * 'class' => SluggableBehavior::class, * 'slugAttribute' => 'alias', * ], * ]; @@ -111,7 +111,7 @@ class SluggableBehavior extends AttributeBehavior */ public $uniqueValidator = []; /** - * @var callable slug unique value generator. It is used in case [[ensureUnique]] enabled and generated + * @var callable|null slug unique value generator. It is used in case [[ensureUnique]] enabled and generated * slug is not unique. This should be a PHP callable with following signature: * * ```php diff --git a/framework/behaviors/TimestampBehavior.php b/framework/behaviors/TimestampBehavior.php index 12a6ff6f9f5..7f79fe3bc9d 100644 --- a/framework/behaviors/TimestampBehavior.php +++ b/framework/behaviors/TimestampBehavior.php @@ -21,7 +21,7 @@ * public function behaviors() * { * return [ - * TimestampBehavior::className(), + * TimestampBehavior::class, * ]; * } * ``` @@ -45,7 +45,7 @@ * { * return [ * [ - * 'class' => TimestampBehavior::className(), + * 'class' => TimestampBehavior::class, * 'createdAtAttribute' => 'create_time', * 'updatedAtAttribute' => 'update_time', * 'value' => new Expression('NOW()'), @@ -84,7 +84,7 @@ class TimestampBehavior extends AttributeBehavior /** * {@inheritdoc} * - * In case, when the value is `null`, the result of the PHP function [time()](https://secure.php.net/manual/en/function.time.php) + * In case, when the value is `null`, the result of the PHP function [time()](https://www.php.net/manual/en/function.time.php) * will be used as value. */ public $value; @@ -108,7 +108,7 @@ public function init() /** * {@inheritdoc} * - * In case, when the [[value]] is `null`, the result of the PHP function [time()](https://secure.php.net/manual/en/function.time.php) + * In case, when the [[value]] is `null`, the result of the PHP function [time()](https://www.php.net/manual/en/function.time.php) * will be used as value. */ protected function getValue($event) diff --git a/framework/caching/ApcCache.php b/framework/caching/ApcCache.php index 50e893c4565..32b74eb5fbb 100644 --- a/framework/caching/ApcCache.php +++ b/framework/caching/ApcCache.php @@ -12,8 +12,8 @@ /** * ApcCache provides APC caching in terms of an application component. * - * To use this application component, the [APC PHP extension](https://secure.php.net/apc) must be loaded. - * Alternatively [APCu PHP extension](https://secure.php.net/apcu) could be used via setting `useApcu` to `true`. + * To use this application component, the [APC PHP extension](https://www.php.net/apc) must be loaded. + * Alternatively [APCu PHP extension](https://www.php.net/apcu) could be used via setting `useApcu` to `true`. * In order to enable APC or APCu for CLI you should add "apc.enable_cli = 1" to your php.ini. * * See [[Cache]] for common cache operations that ApcCache supports. diff --git a/framework/caching/Cache.php b/framework/caching/Cache.php index ea79e1427ae..36a30dbd76e 100644 --- a/framework/caching/Cache.php +++ b/framework/caching/Cache.php @@ -62,7 +62,7 @@ abstract class Cache extends Component implements CacheInterface */ public $keyPrefix; /** - * @var null|array|false the functions used to serialize and unserialize cached data. Defaults to null, meaning + * @var array|null|false the functions used to serialize and unserialize cached data. Defaults to null, meaning * using the default PHP `serialize()` and `unserialize()` functions. If you want to use some more efficient * serializer (e.g. [igbinary](https://pecl.php.net/package/igbinary)), you may configure this property with * a two-element array. The first element specifies the serialization function, and the second the deserialization @@ -135,7 +135,7 @@ public function get($key) if ($value === false || $this->serializer === false) { return $value; } elseif ($this->serializer === null) { - $value = unserialize($value); + $value = unserialize((string)$value); } else { $value = call_user_func($this->serializer[1], $value); } @@ -229,9 +229,9 @@ public function multiGet($keys) * @param mixed $key a key identifying the value to be cached. This can be a simple string or * a complex data structure consisting of factors representing the key. * @param mixed $value the value to be cached - * @param int $duration default duration in seconds before the cache will expire. If not set, + * @param int|null $duration default duration in seconds before the cache will expire. If not set, * default [[defaultDuration]] value is used. - * @param Dependency $dependency dependency of the cached item. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached item. If the dependency changes, * the corresponding value in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return bool whether the value is successfully stored into cache @@ -261,14 +261,15 @@ public function set($key, $value, $duration = null, $dependency = null) * expiration time will be replaced with the new ones, respectively. * * @param array $items the items to be cached, as key-value pairs. - * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached items. If the dependency changes, + * @param int|null $duration default duration in seconds before the cache will expire. If not set, + * default [[defaultDuration]] value is used. + * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return array array of failed keys * @deprecated This method is an alias for [[multiSet()]] and will be removed in 2.1.0. */ - public function mset($items, $duration = 0, $dependency = null) + public function mset($items, $duration = null, $dependency = null) { return $this->multiSet($items, $duration, $dependency); } @@ -279,15 +280,20 @@ public function mset($items, $duration = 0, $dependency = null) * expiration time will be replaced with the new ones, respectively. * * @param array $items the items to be cached, as key-value pairs. - * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached items. If the dependency changes, + * @param int|null $duration default duration in seconds before the cache will expire. If not set, + * default [[defaultDuration]] value is used. + * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return array array of failed keys * @since 2.0.7 */ - public function multiSet($items, $duration = 0, $dependency = null) + public function multiSet($items, $duration = null, $dependency = null) { + if ($duration === null) { + $duration = $this->defaultDuration; + } + if ($dependency !== null && $this->serializer !== false) { $dependency->evaluateDependency($this); } @@ -313,7 +319,7 @@ public function multiSet($items, $duration = 0, $dependency = null) * * @param array $items the items to be cached, as key-value pairs. * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached items. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return array array of failed keys @@ -330,7 +336,7 @@ public function madd($items, $duration = 0, $dependency = null) * * @param array $items the items to be cached, as key-value pairs. * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached items. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return array array of failed keys @@ -364,7 +370,7 @@ public function multiAdd($items, $duration = 0, $dependency = null) * a complex data structure consisting of factors representing the key. * @param mixed $value the value to be cached * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached item. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached item. If the dependency changes, * the corresponding value in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return bool whether the value is successfully stored into cache @@ -520,6 +526,7 @@ protected function addValues($data, $duration) * @param string $key a key identifying the cached value * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($key) { return $this->get($key) !== false; @@ -531,6 +538,7 @@ public function offsetExists($key) * @param string $key a key identifying the cached value * @return mixed the value stored in cache, false if the value is not in the cache or expired. */ + #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->get($key); @@ -544,6 +552,7 @@ public function offsetGet($key) * @param string $key the key identifying the value to be cached * @param mixed $value the value to be cached */ + #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->set($key, $value); @@ -554,6 +563,7 @@ public function offsetSet($key, $value) * This method is required by the interface [[\ArrayAccess]]. * @param string $key the key of the value to be deleted */ + #[\ReturnTypeWillChange] public function offsetUnset($key) { $this->delete($key); @@ -580,9 +590,9 @@ public function offsetUnset($key) * If you use $callable that can return `false`, then keep in mind that [[getOrSet()]] may work inefficiently * because the [[yii\caching\Cache::get()]] method uses `false` return value to indicate the data item is not found * in the cache. Thus, caching of `false` value will lead to unnecessary internal calls. - * @param int $duration default duration in seconds before the cache will expire. If not set, + * @param int|null $duration default duration in seconds before the cache will expire. If not set, * [[defaultDuration]] value will be used. - * @param Dependency $dependency dependency of the cached item. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached item. If the dependency changes, * the corresponding value in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is `false`. * @return mixed result of $callable execution diff --git a/framework/caching/CacheInterface.php b/framework/caching/CacheInterface.php index cc344154570..996dfe1b4ce 100644 --- a/framework/caching/CacheInterface.php +++ b/framework/caching/CacheInterface.php @@ -97,9 +97,9 @@ public function multiGet($keys); * @param mixed $key a key identifying the value to be cached. This can be a simple string or * a complex data structure consisting of factors representing the key. * @param mixed $value the value to be cached - * @param int $duration default duration in seconds before the cache will expire. If not set, + * @param int|null $duration default duration in seconds before the cache will expire. If not set, * default [[defaultDuration]] value is used. - * @param Dependency $dependency dependency of the cached item. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached item. If the dependency changes, * the corresponding value in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return bool whether the value is successfully stored into cache @@ -112,13 +112,14 @@ public function set($key, $value, $duration = null, $dependency = null); * expiration time will be replaced with the new ones, respectively. * * @param array $items the items to be cached, as key-value pairs. - * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached items. If the dependency changes, + * @param int|null $duration default duration in seconds before the cache will expire. If not set, + * default [[defaultDuration]] value is used. + * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return array array of failed keys */ - public function multiSet($items, $duration = 0, $dependency = null); + public function multiSet($items, $duration = null, $dependency = null); /** * Stores a value identified by a key into cache if the cache does not contain this key. @@ -127,7 +128,7 @@ public function multiSet($items, $duration = 0, $dependency = null); * a complex data structure consisting of factors representing the key. * @param mixed $value the value to be cached * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached item. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached item. If the dependency changes, * the corresponding value in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return bool whether the value is successfully stored into cache @@ -140,7 +141,7 @@ public function add($key, $value, $duration = 0, $dependency = null); * * @param array $items the items to be cached, as key-value pairs. * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire. - * @param Dependency $dependency dependency of the cached items. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is false. * @return array array of failed keys @@ -181,9 +182,9 @@ public function flush(); * a complex data structure consisting of factors representing the key. * @param callable|\Closure $callable the callable or closure that will be used to generate a value to be cached. * In case $callable returns `false`, the value will not be cached. - * @param int $duration default duration in seconds before the cache will expire. If not set, + * @param int|null $duration default duration in seconds before the cache will expire. If not set, * [[defaultDuration]] value will be used. - * @param Dependency $dependency dependency of the cached item. If the dependency changes, + * @param Dependency|null $dependency dependency of the cached item. If the dependency changes, * the corresponding value in the cache will be invalidated when it is fetched via [[get()]]. * This parameter is ignored if [[serializer]] is `false`. * @return mixed result of $callable execution diff --git a/framework/caching/DbCache.php b/framework/caching/DbCache.php index a387b27f20b..3cd211ec013 100644 --- a/framework/caching/DbCache.php +++ b/framework/caching/DbCache.php @@ -58,12 +58,20 @@ class DbCache extends Cache * ); * ``` * + * For MSSQL: + * ```php + * CREATE TABLE cache ( + * id VARCHAR(128) NOT NULL PRIMARY KEY, + * expire INT(11), + * data VARBINARY(MAX) + * ); + * ``` + * * where 'BLOB' refers to the BLOB-type of your preferred DBMS. Below are the BLOB type * that can be used for some popular DBMS: * * - MySQL: LONGBLOB * - PostgreSQL: BYTEA - * - MSSQL: BLOB * * When using DbCache in a production server, we recommend you create a DB index for the 'expire' * column in the cache table to improve the performance. @@ -76,6 +84,8 @@ class DbCache extends Cache */ public $gcProbability = 100; + protected $isVarbinaryDataField; + /** * Initializes the DbCache component. @@ -127,7 +137,7 @@ public function exists($key) protected function getValue($key) { $query = new Query(); - $query->select(['data']) + $query->select([$this->getDataFieldName()]) ->from($this->cacheTable) ->where('[[id]] = :id AND ([[expire]] = 0 OR [[expire]] >' . time() . ')', [':id' => $key]); if ($this->db->enableQueryCache) { @@ -153,7 +163,7 @@ protected function getValues($keys) return []; } $query = new Query(); - $query->select(['id', 'data']) + $query->select(['id', $this->getDataFieldName()]) ->from($this->cacheTable) ->where(['id' => $keys]) ->andWhere('([[expire]] = 0 OR [[expire]] > ' . time() . ')'); @@ -197,7 +207,7 @@ protected function setValue($key, $value, $duration) $db->createCommand()->upsert($this->cacheTable, [ 'id' => $key, 'expire' => $duration > 0 ? $duration + time() : 0, - 'data' => new PdoValue($value, \PDO::PARAM_LOB), + 'data' => $this->getDataFieldValue($value), ])->execute(); }); @@ -230,7 +240,7 @@ protected function addValue($key, $value, $duration) ->insert($this->cacheTable, [ 'id' => $key, 'expire' => $duration > 0 ? $duration + time() : 0, - 'data' => new PdoValue($value, \PDO::PARAM_LOB), + 'data' => $this->getDataFieldValue($value), ])->execute(); }); @@ -266,7 +276,8 @@ protected function deleteValue($key) */ public function gc($force = false) { - if ($force || mt_rand(0, 1000000) < $this->gcProbability) { + + if ($force || random_int(0, 1000000) < $this->gcProbability) { $this->db->createCommand() ->delete($this->cacheTable, '[[expire]] > 0 AND [[expire]] < ' . time()) ->execute(); @@ -286,4 +297,35 @@ protected function flushValues() return true; } + + /** + * @return bool whether field is MSSQL varbinary + * @since 2.0.42 + */ + protected function isVarbinaryDataField() + { + if ($this->isVarbinaryDataField === null) { + $this->isVarbinaryDataField = in_array($this->db->getDriverName(), ['sqlsrv', 'dblib']) && + $this->db->getTableSchema($this->cacheTable)->columns['data']->dbType === 'varbinary'; + } + return $this->isVarbinaryDataField; + } + + /** + * @return string `data` field name converted for usage in MSSQL (if needed) + * @since 2.0.42 + */ + protected function getDataFieldName() + { + return $this->isVarbinaryDataField() ? 'convert(nvarchar(max),[data]) data' : 'data'; + } + + /** + * @return PdoValue PdoValue or direct $value for usage in MSSQL + * @since 2.0.42 + */ + protected function getDataFieldValue($value) + { + return $this->isVarbinaryDataField() ? $value : new PdoValue($value, \PDO::PARAM_LOB); + } } diff --git a/framework/caching/DbQueryDependency.php b/framework/caching/DbQueryDependency.php index 3aafd0f457e..90ffb0ff1ad 100644 --- a/framework/caching/DbQueryDependency.php +++ b/framework/caching/DbQueryDependency.php @@ -41,7 +41,7 @@ class DbQueryDependency extends Dependency */ public $query; /** - * @var string|callable method which should be invoked in over the [[query]] object. + * @var string|callable|null method which should be invoked in over the [[query]] object. * * If specified as a string an own query method with such name will be invoked, passing [[db]] value as its * first argument. For example: `exists`, `all`. diff --git a/framework/caching/Dependency.php b/framework/caching/Dependency.php index 9093e8ef196..a0a02f16a86 100644 --- a/framework/caching/Dependency.php +++ b/framework/caching/Dependency.php @@ -99,16 +99,28 @@ public static function resetReusableData() /** * Generates a unique hash that can be used for retrieving reusable dependency data. + * * @return string a unique hash value for this cache dependency. * @see reusable */ protected function generateReusableHash() { - $data = $this->data; - $this->data = null; // https://github.com/yiisoft/yii2/issues/3052 - $key = sha1(serialize($this)); - $this->data = $data; - return $key; + $clone = clone $this; + $clone->data = null; // https://github.com/yiisoft/yii2/issues/3052 + + try { + $serialized = serialize($clone); + } catch (\Exception $e) { + // unserializable properties are nulled + foreach ($clone as $name => $value) { + if (is_object($value) && $value instanceof \Closure) { + $clone->{$name} = null; + } + } + $serialized = serialize($clone); + } + + return sha1($serialized); } /** diff --git a/framework/caching/ExpressionDependency.php b/framework/caching/ExpressionDependency.php index 503e6dc798d..09d6756bf83 100644 --- a/framework/caching/ExpressionDependency.php +++ b/framework/caching/ExpressionDependency.php @@ -15,7 +15,7 @@ * the same as the one evaluated when storing the data to cache. * * A PHP expression can be any PHP code that has a value. To learn more about what an expression is, - * please refer to the [php manual](https://secure.php.net/manual/en/language.expressions.php). + * please refer to the [php manual](https://www.php.net/manual/en/language.expressions.php). * * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview). * @@ -27,7 +27,7 @@ class ExpressionDependency extends Dependency /** * @var string the string representation of a PHP expression whose result is used to determine the dependency. * A PHP expression can be any PHP code that evaluates to a value. To learn more about what an expression is, - * please refer to the [php manual](https://secure.php.net/manual/en/language.expressions.php). + * please refer to the [php manual](https://www.php.net/manual/en/language.expressions.php). */ public $expression = 'true'; /** diff --git a/framework/caching/FileCache.php b/framework/caching/FileCache.php index da71b179300..33214209315 100644 --- a/framework/caching/FileCache.php +++ b/framework/caching/FileCache.php @@ -57,7 +57,7 @@ class FileCache extends Cache */ public $gcProbability = 10; /** - * @var int the permission to be set for newly created cache files. + * @var int|null the permission to be set for newly created cache files. * This value will be used by PHP chmod() function. No umask will be applied. * If not set, the permission will be determined by the current environment. */ @@ -245,7 +245,7 @@ protected function flushValues() */ public function gc($force = false, $expiredOnly = true) { - if ($force || mt_rand(0, 1000000) < $this->gcProbability) { + if ($force || random_int(0, 1000000) < $this->gcProbability) { $this->gcRecursive($this->cachePath, $expiredOnly); } } @@ -261,7 +261,7 @@ protected function gcRecursive($path, $expiredOnly) { if (($handle = opendir($path)) !== false) { while (($file = readdir($handle)) !== false) { - if ($file[0] === '.') { + if (strncmp($file, '.', 1) === 0) { continue; } $fullPath = $path . DIRECTORY_SEPARATOR . $file; diff --git a/framework/caching/MemCache.php b/framework/caching/MemCache.php index 2a83e5d3fff..c37e5b0e5ca 100644 --- a/framework/caching/MemCache.php +++ b/framework/caching/MemCache.php @@ -56,9 +56,9 @@ * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview). * * @property-read \Memcache|\Memcached $memcache The memcache (or memcached) object used by this cache - * component. This property is read-only. + * component. * @property MemCacheServer[] $servers List of memcache server configurations. Note that the type of this - * property differs in getter and setter. See [[getServers()]] and [[setServers()]] for details. + * property differs in getter and setter. See [[getServers()]] and [[setServers()]] for details. * * @author Qiang Xue * @since 2.0 @@ -77,22 +77,22 @@ class MemCache extends Cache * By default the Memcached instances are destroyed at the end of the request. To create an instance that * persists between requests, you may specify a unique ID for the instance. All instances created with the * same ID will share the same connection. - * @see https://secure.php.net/manual/en/memcached.construct.php + * @see https://www.php.net/manual/en/memcached.construct.php */ public $persistentId; /** * @var array options for Memcached. This property is used only when [[useMemcached]] is true. - * @see https://secure.php.net/manual/en/memcached.setoptions.php + * @see https://www.php.net/manual/en/memcached.setoptions.php */ public $options; /** * @var string memcached sasl username. This property is used only when [[useMemcached]] is true. - * @see https://secure.php.net/manual/en/memcached.setsaslauthdata.php + * @see https://www.php.net/manual/en/memcached.setsaslauthdata.php */ public $username; /** * @var string memcached sasl password. This property is used only when [[useMemcached]] is true. - * @see https://secure.php.net/manual/en/memcached.setsaslauthdata.php + * @see https://www.php.net/manual/en/memcached.setsaslauthdata.php */ public $password; @@ -249,8 +249,8 @@ public function getServers() /** * @param array $config list of memcache or memcached server configurations. Each element must be an array * with the following keys: host, port, persistent, weight, timeout, retryInterval, status. - * @see https://secure.php.net/manual/en/memcache.addserver.php - * @see https://secure.php.net/manual/en/memcached.addserver.php + * @see https://www.php.net/manual/en/memcache.addserver.php + * @see https://www.php.net/manual/en/memcached.addserver.php */ public function setServers($config) { @@ -286,7 +286,7 @@ protected function getValues($keys) * * @param string $key the key identifying the value to be cached * @param mixed $value the value to be cached. - * @see [Memcache::set()](https://secure.php.net/manual/en/memcache.set.php) + * @see [Memcache::set()](https://www.php.net/manual/en/memcache.set.php) * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. * @return bool true if the value is successfully stored into cache, false otherwise */ @@ -308,7 +308,7 @@ protected function setValues($data, $duration) $expire = $this->normalizeDuration($duration); // Memcached::setMulti() returns boolean - // @see https://secure.php.net/manual/en/memcached.setmulti.php + // @see https://www.php.net/manual/en/memcached.setmulti.php return $this->_cache->setMulti($data, $expire) ? [] : array_keys($data); } @@ -321,7 +321,7 @@ protected function setValues($data, $duration) * * @param string $key the key identifying the value to be cached * @param mixed $value the value to be cached - * @see [Memcache::set()](https://secure.php.net/manual/en/memcache.set.php) + * @see [Memcache::set()](https://www.php.net/manual/en/memcache.set.php) * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. * @return bool true if the value is successfully stored into cache, false otherwise */ @@ -356,8 +356,8 @@ protected function flushValues() * Normalizes duration value * * @see https://github.com/yiisoft/yii2/issues/17710 - * @see https://secure.php.net/manual/en/memcache.set.php - * @see https://secure.php.net/manual/en/memcached.expiration.php + * @see https://www.php.net/manual/en/memcache.set.php + * @see https://www.php.net/manual/en/memcached.expiration.php * * @since 2.0.31 * @param int $duration diff --git a/framework/caching/MemCacheServer.php b/framework/caching/MemCacheServer.php index c6274814eee..96d10c46ad7 100644 --- a/framework/caching/MemCacheServer.php +++ b/framework/caching/MemCacheServer.php @@ -10,7 +10,7 @@ /** * MemCacheServer represents the configuration data for a single memcache or memcached server. * - * See [PHP manual](https://secure.php.net/manual/en/memcache.addserver.php) for detailed explanation + * See [PHP manual](https://www.php.net/manual/en/memcache.addserver.php) for detailed explanation * of each configuration property. * * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview). diff --git a/framework/captcha/CaptchaAction.php b/framework/captcha/CaptchaAction.php index 40e1aa03a0a..06aa7023f5f 100644 --- a/framework/captcha/CaptchaAction.php +++ b/framework/captcha/CaptchaAction.php @@ -31,7 +31,7 @@ * to be validated by the 'captcha' validator. * 3. In the controller view, insert a [[Captcha]] widget in the form. * - * @property-read string $verifyCode The verification code. This property is read-only. + * @property-read string $verifyCode The verification code. * * @author Qiang Xue * @since 2.0 @@ -91,7 +91,7 @@ class CaptchaAction extends Action */ public $fontFile = '@yii/captcha/SpicyRice.ttf'; /** - * @var string the fixed verification code. When this property is set, + * @var string|null the fixed verification code. When this property is set, * [[getVerifyCode()]] will always return the value of this property. * This is mainly used in automated tests where we want to be able to reproduce * the same verification code each time we run the tests. @@ -99,7 +99,7 @@ class CaptchaAction extends Action */ public $fixedVerifyCode; /** - * @var string the rendering library to use. Currently supported only 'gd' and 'imagick'. + * @var string|null the rendering library to use. Currently supported only 'gd' and 'imagick'. * If not set, library will be determined automatically. * @since 2.0.7 */ @@ -150,7 +150,7 @@ public function run() public function generateValidationHash($code) { for ($h = 0, $i = strlen($code) - 1; $i >= 0; --$i) { - $h += ord($code[$i]); + $h += ord($code[$i]) << $i; } return $h; @@ -214,16 +214,17 @@ protected function generateVerifyCode() if ($this->maxLength > 20) { $this->maxLength = 20; } - $length = mt_rand($this->minLength, $this->maxLength); + + $length = random_int($this->minLength, $this->maxLength); $letters = 'bcdfghjklmnpqrstvwxyz'; $vowels = 'aeiou'; $code = ''; for ($i = 0; $i < $length; ++$i) { - if ($i % 2 && mt_rand(0, 10) > 2 || !($i % 2) && mt_rand(0, 10) > 9) { - $code .= $vowels[mt_rand(0, 4)]; + if ($i % 2 && random_int(0, 10) > 2 || !($i % 2) && random_int(0, 10) > 9) { + $code .= $vowels[random_int(0, 4)]; } else { - $code .= $letters[mt_rand(0, 20)]; + $code .= $letters[random_int(0, 20)]; } } @@ -298,8 +299,8 @@ protected function renderImageByGD($code) $x = 10; $y = round($this->height * 27 / 40); for ($i = 0; $i < $length; ++$i) { - $fontSize = (int) (mt_rand(26, 32) * $scale * 0.8); - $angle = mt_rand(-10, 10); + $fontSize = (int) (random_int(26, 32) * $scale * 0.8); + $angle = random_int(-10, 10); $letter = $code[$i]; $box = imagettftext($image, $fontSize, $angle, $x, $y, $foreColor, $this->fontFile, $letter); $x = $box[2] + $this->offset; @@ -341,9 +342,9 @@ protected function renderImageByImagick($code) for ($i = 0; $i < $length; ++$i) { $draw = new \ImagickDraw(); $draw->setFont($this->fontFile); - $draw->setFontSize((int) (mt_rand(26, 32) * $scale * 0.8)); + $draw->setFontSize((int) (random_int(26, 32) * $scale * 0.8)); $draw->setFillColor($foreColor); - $image->annotateImage($draw, $x, $y, mt_rand(-10, 10), $code[$i]); + $image->annotateImage($draw, $x, $y, random_int(-10, 10), $code[$i]); $fontMetrics = $image->queryFontMetrics($draw, $code[$i]); $x += (int) $fontMetrics['textWidth'] + $this->offset; } diff --git a/framework/classes.php b/framework/classes.php index 622a1b74b30..0dc5be01f01 100644 --- a/framework/classes.php +++ b/framework/classes.php @@ -174,6 +174,8 @@ 'yii\db\cubrid\Schema' => YII2_PATH . '/db/cubrid/Schema.php', 'yii\db\cubrid\conditions\LikeConditionBuilder' => YII2_PATH . '/db/cubrid/conditions/LikeConditionBuilder.php', 'yii\db\mssql\ColumnSchema' => YII2_PATH . '/db/mssql/ColumnSchema.php', + 'yii\db\mssql\ColumnSchemaBuilder' => YII2_PATH . '/db/mssql/ColumnSchemaBuilder.php', + 'yii\db\mssql\DBLibPDO' => YII2_PATH . '/db/mssql/DBLibPDO.php', 'yii\db\mssql\PDO' => YII2_PATH . '/db/mssql/PDO.php', 'yii\db\mssql\QueryBuilder' => YII2_PATH . '/db/mssql/QueryBuilder.php', 'yii\db\mssql\Schema' => YII2_PATH . '/db/mssql/Schema.php', @@ -345,6 +347,7 @@ 'yii\validators\StringValidator' => YII2_PATH . '/validators/StringValidator.php', 'yii\validators\UniqueValidator' => YII2_PATH . '/validators/UniqueValidator.php', 'yii\validators\UrlValidator' => YII2_PATH . '/validators/UrlValidator.php', + 'yii\validators\TrimValidator' => YII2_PATH . '/validators/TrimValidator.php', 'yii\validators\ValidationAsset' => YII2_PATH . '/validators/ValidationAsset.php', 'yii\validators\Validator' => YII2_PATH . '/validators/Validator.php', 'yii\web\Application' => YII2_PATH . '/web/Application.php', diff --git a/framework/composer.json b/framework/composer.json index 40bfe5dc56c..aaafa056878 100644 --- a/framework/composer.json +++ b/framework/composer.json @@ -5,20 +5,20 @@ "yii2", "framework" ], - "homepage": "http://www.yiiframework.com/", + "homepage": "https://www.yiiframework.com/", "type": "library", "license": "BSD-3-Clause", "authors": [ { "name": "Qiang Xue", "email": "qiang.xue@gmail.com", - "homepage": "http://www.yiiframework.com/", + "homepage": "https://www.yiiframework.com/", "role": "Founder and project lead" }, { "name": "Alexander Makarov", "email": "sam@rmcreative.ru", - "homepage": "http://rmcreative.ru/", + "homepage": "https://rmcreative.ru/", "role": "Core framework development" }, { @@ -29,7 +29,7 @@ { "name": "Carsten Brandt", "email": "mail@cebe.cc", - "homepage": "http://cebe.cc/", + "homepage": "https://www.cebe.cc/", "role": "Core framework development" }, { @@ -57,9 +57,9 @@ ], "support": { "issues": "https://github.com/yiisoft/yii2/issues?state=open", - "forum": "http://www.yiiframework.com/forum/", - "wiki": "http://www.yiiframework.com/wiki/", - "irc": "irc://irc.freenode.net/yii", + "forum": "https://forum.yiiframework.com/", + "wiki": "https://www.yiiframework.com/wiki", + "irc": "ircs://irc.libera.chat:6697/yii", "source": "https://github.com/yiisoft/yii2" }, "require": { @@ -70,10 +70,11 @@ "yiisoft/yii2-composer": "~2.0.4", "ezyang/htmlpurifier": "~4.6", "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", - "bower-asset/jquery": "3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", + "bower-asset/jquery": "3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", "bower-asset/inputmask": "~3.2.2 | ~3.3.5", "bower-asset/punycode": "1.3.*", - "bower-asset/yii2-pjax": "~2.0.1" + "bower-asset/yii2-pjax": "~2.0.1", + "paragonie/random_compat": ">=1" }, "autoload": { "psr-4": {"yii\\": ""} diff --git a/framework/console/Application.php b/framework/console/Application.php index 51d81e43b5c..d8058603f9e 100644 --- a/framework/console/Application.php +++ b/framework/console/Application.php @@ -11,7 +11,7 @@ use yii\base\InvalidRouteException; // define STDIN, STDOUT and STDERR if the PHP SAPI did not define them (e.g. creating console application in web env) -// https://secure.php.net/manual/en/features.commandline.io-streams.php +// https://www.php.net/manual/en/features.commandline.io-streams.php defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w')); defined('STDERR') or define('STDERR', fopen('php://stderr', 'w')); @@ -50,10 +50,9 @@ * yii help * ``` * - * @property-read ErrorHandler $errorHandler The error handler application component. This property is - * read-only. - * @property-read Request $request The request component. This property is read-only. - * @property-read Response $response The response component. This property is read-only. + * @property-read ErrorHandler $errorHandler The error handler application component. + * @property-read Request $request The request component. + * @property-read Response $response The response component. * * @author Qiang Xue * @since 2.0 @@ -171,8 +170,8 @@ public function handleRequest($request) * * @param string $route the route that specifies the action. * @param array $params the parameters to be passed to the action - * @return int|Response the result of the action. This can be either an exit code or Response object. - * Exit code 0 means normal, and other values mean abnormal. Exit code of `null` is treaded as `0` as well. + * @return int|Response|null the result of the action. This can be either an exit code or Response object. + * Exit code 0 means normal, and other values mean abnormal. Exit code of `null` is treated as `0` as well. * @throws Exception if the route is invalid */ public function runAction($route, $params = []) diff --git a/framework/console/Controller.php b/framework/console/Controller.php index 4288f93c822..55fb31bb2a0 100644 --- a/framework/console/Controller.php +++ b/framework/console/Controller.php @@ -28,12 +28,10 @@ * where `` is a route to a controller action and the params will be populated as properties of a command. * See [[options()]] for details. * - * @property-read string $help This property is read-only. - * @property-read string $helpSummary This property is read-only. - * @property-read array $passedOptionValues The properties corresponding to the passed options. This property - * is read-only. - * @property-read array $passedOptions The names of the options passed during execution. This property is - * read-only. + * @property-read string $help The help information for this controller. + * @property-read string $helpSummary The one-line short summary describing this controller. + * @property-read array $passedOptionValues The properties corresponding to the passed options. + * @property-read array $passedOptions The names of the options passed during execution. * @property Request $request * @property Response $response * @@ -56,7 +54,7 @@ class Controller extends \yii\base\Controller */ public $interactive = true; /** - * @var bool whether to enable ANSI color in the output. + * @var bool|null whether to enable ANSI color in the output. * If not set, ANSI color will only be enabled for terminals that support it. */ public $color; @@ -64,9 +62,9 @@ class Controller extends \yii\base\Controller * @var bool whether to display help information about current command. * @since 2.0.10 */ - public $help; + public $help = false; /** - * @var bool if true - script finish with `ExitCode::OK` in case of exception. + * @var bool|null if true - script finish with `ExitCode::OK` in case of exception. * false - `ExitCode::UNSPECIFIED_ERROR`. * Default: `YII_ENV_TEST` * @since 2.0.36 @@ -79,6 +77,9 @@ class Controller extends \yii\base\Controller private $_passedOptions = []; + /** + * {@inheritdoc} + */ public function beforeAction($action) { $silentExit = $this->silentExitOnException !== null ? $this->silentExitOnException : YII_ENV_TEST; @@ -150,7 +151,7 @@ public function runAction($id, $params = []) if (in_array($name, $options, true)) { $default = $this->$name; - if (is_array($default)) { + if (is_array($default) && is_string($value)) { $this->$name = preg_split('/\s*,\s*(?![^()]*\))/', $value); } elseif ($default !== null) { settype($value, gettype($default)); @@ -223,7 +224,12 @@ public function bindActionParams($action, $params) } $args[] = $actionParams[$key] = $params[$key]; unset($params[$key]); - } elseif (PHP_VERSION_ID >= 70100 && ($type = $param->getType()) !== null && !$type->isBuiltin()) { + } elseif ( + PHP_VERSION_ID >= 70100 + && ($type = $param->getType()) !== null + && $type instanceof \ReflectionNamedType + && !$type->isBuiltin() + ) { try { $this->bindInjectedParams($type, $name, $args, $requestedParams); } catch (\yii\base\Exception $e) { @@ -313,6 +319,7 @@ public function stdout($string) * ``` * * @param string $string the string to print + * @param int ...$args additional parameters to decorate the output * @return int|bool Number of bytes printed or false on error */ public function stderr($string) @@ -536,60 +543,69 @@ public function getActionHelp($action) * The returned value should be an array. The keys are the argument names, and the values are * the corresponding help information. Each value must be an array of the following structure: * - * - required: boolean, whether this argument is required. - * - type: string, the PHP type of this argument. - * - default: string, the default value of this argument - * - comment: string, the comment of this argument + * - required: bool, whether this argument is required + * - type: string|null, the PHP type(s) of this argument + * - default: mixed, the default value of this argument + * - comment: string, the description of this argument * - * The default implementation will return the help information extracted from the doc-comment of - * the parameters corresponding to the action method. + * The default implementation will return the help information extracted from the Reflection or + * DocBlock of the parameters corresponding to the action method. * - * @param Action $action + * @param Action $action the action instance * @return array the help information of the action arguments */ public function getActionArgsHelp($action) { $method = $this->getActionMethodReflection($action); + $tags = $this->parseDocCommentTags($method); - $params = isset($tags['param']) ? (array) $tags['param'] : []; + $tags['param'] = isset($tags['param']) ? (array) $tags['param'] : []; + $phpDocParams = []; + foreach ($tags['param'] as $i => $tag) { + if (preg_match('/^(?\S+)(\s+\$(?\w+))?(?.*)/us', $tag, $matches) === 1) { + $key = empty($matches['name']) ? $i : $matches['name']; + $phpDocParams[$key] = ['type' => $matches['type'], 'comment' => $matches['comment']]; + } + } + unset($tags); $args = []; - /** @var \ReflectionParameter $reflection */ - foreach ($method->getParameters() as $i => $reflection) { - if (PHP_VERSION_ID >= 80000) { - $class = $reflection->getType(); - } else { - $class = $reflection->getClass(); - } - - if ($class !== null) { - continue; + /** @var \ReflectionParameter $parameter */ + foreach ($method->getParameters() as $i => $parameter) { + $type = null; + $comment = ''; + if (PHP_MAJOR_VERSION > 5 && $parameter->hasType()) { + $reflectionType = $parameter->getType(); + if (PHP_VERSION_ID >= 70100) { + $types = method_exists($reflectionType, 'getTypes') ? $reflectionType->getTypes() : [$reflectionType]; + foreach ($types as $key => $reflectionType) { + $types[$key] = $reflectionType->getName(); + } + $type = implode('|', $types); + } else { + $type = (string) $reflectionType; + } } - $name = $reflection->getName(); - $tag = isset($params[$i]) ? $params[$i] : ''; - if (preg_match('/^(\S+)\s+(\$\w+\s+)?(.*)/s', $tag, $matches)) { - $type = $matches[1]; - $comment = $matches[3]; - } else { - $type = null; - $comment = $tag; + // find PhpDoc tag by property name or position + $key = isset($phpDocParams[$parameter->name]) ? $parameter->name : (isset($phpDocParams[$i]) ? $i : null); + if ($key !== null) { + $comment = $phpDocParams[$key]['comment']; + if ($type === null && !empty($phpDocParams[$key]['type'])) { + $type = $phpDocParams[$key]['type']; + } } - if ($reflection->isDefaultValueAvailable()) { - $args[$name] = [ - 'required' => false, - 'type' => $type, - 'default' => $reflection->getDefaultValue(), - 'comment' => $comment, - ]; - } else { - $args[$name] = [ - 'required' => true, - 'type' => $type, - 'default' => null, - 'comment' => $comment, - ]; + // if type still not detected, then using type of default value + if ($type === null && $parameter->isDefaultValueAvailable() && $parameter->getDefaultValue() !== null) { + $type = gettype($parameter->getDefaultValue()); } + + $args[$parameter->name] = [ + 'required' => !$parameter->isOptional(), + 'type' => $type, + 'default' => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null, + 'comment' => $comment, + ]; } return $args; diff --git a/framework/console/ErrorHandler.php b/framework/console/ErrorHandler.php index 16127a1b2d5..f06b82f918f 100644 --- a/framework/console/ErrorHandler.php +++ b/framework/console/ErrorHandler.php @@ -25,7 +25,7 @@ class ErrorHandler extends \yii\base\ErrorHandler { /** * Renders an exception using ansi format for console output. - * @param \Exception $exception the exception to be rendered. + * @param \Throwable $exception the exception to be rendered. */ protected function renderException($exception) { @@ -39,7 +39,7 @@ protected function renderException($exception) } elseif (count($alternatives) > 1) { $message .= "\n\nDid you mean one of these?\n - " . implode("\n - ", $alternatives); } - } elseif ($exception instanceof Exception && ($exception instanceof UserException || !YII_DEBUG)) { + } elseif ($exception instanceof UserException && ($exception instanceof Exception || !YII_DEBUG)) { $message = $this->formatMessage($exception->getName() . ': ') . $exception->getMessage(); } elseif (YII_DEBUG) { if ($exception instanceof Exception) { diff --git a/framework/console/UnknownCommandException.php b/framework/console/UnknownCommandException.php index 3dc4aed1bc7..180d1c9a72b 100644 --- a/framework/console/UnknownCommandException.php +++ b/framework/console/UnknownCommandException.php @@ -34,9 +34,9 @@ class UnknownCommandException extends Exception * @param string $route the route of the command that could not be found. * @param Application $application the console application instance involved. * @param int $code the Exception code. - * @param \Exception $previous the previous exception used for the exception chaining. + * @param \Throwable|null $previous the previous exception used for the exception chaining. */ - public function __construct($route, $application, $code = 0, \Exception $previous = null) + public function __construct($route, $application, $code = 0, $previous = null) { $this->command = $route; $this->application = $application; @@ -61,7 +61,7 @@ public function getName() * available commands. The Levenshtein distance is defined as the minimal number of * characters you have to replace, insert or delete to transform str1 into str2. * - * @see https://secure.php.net/manual/en/function.levenshtein.php + * @see https://www.php.net/manual/en/function.levenshtein.php * @return array a list of suggested alternatives sorted by similarity. */ public function getSuggestedAlternatives() @@ -104,7 +104,7 @@ public function getSuggestedAlternatives() * available commands. The Levenshtein distance is defined as the minimal number of * characters you have to replace, insert or delete to transform str1 into str2. * - * @see https://secure.php.net/manual/en/function.levenshtein.php + * @see https://www.php.net/manual/en/function.levenshtein.php * @param array $actions available command names. * @param string $command the command to compare to. * @return array a list of suggested alternatives sorted by similarity. diff --git a/framework/console/controllers/AssetController.php b/framework/console/controllers/AssetController.php index fe106f79bfd..4f2e492dcea 100644 --- a/framework/console/controllers/AssetController.php +++ b/framework/console/controllers/AssetController.php @@ -39,7 +39,7 @@ * check [[jsCompressor]] and [[cssCompressor]] for more details. * * @property \yii\web\AssetManager $assetManager Asset manager instance. Note that the type of this property - * differs in getter and setter. See [[getAssetManager()]] and [[setAssetManager()]] for details. + * differs in getter and setter. See [[getAssetManager()]] and [[setAssetManager()]] for details. * * @author Qiang Xue * @author Paul Klimov diff --git a/framework/console/controllers/BaseMigrateController.php b/framework/console/controllers/BaseMigrateController.php index 561d6bd44b1..3cbfa91010e 100644 --- a/framework/console/controllers/BaseMigrateController.php +++ b/framework/console/controllers/BaseMigrateController.php @@ -37,7 +37,7 @@ abstract class BaseMigrateController extends Controller */ public $defaultAction = 'up'; /** - * @var string|array the directory containing the migration classes. This can be either + * @var string|array|null the directory containing the migration classes. This can be either * a [path alias](guide:concept-aliases) or a directory path. * * Migration classes located at this path should be declared without a namespace. @@ -54,7 +54,7 @@ abstract class BaseMigrateController extends Controller * as the migration name contains the origin of the migration in the history, which is not the case when * using multiple migration paths. * - * @see $migrationNamespaces + * @see migrationNamespaces */ public $migrationPath = ['@app/migrations']; /** @@ -75,7 +75,7 @@ abstract class BaseMigrateController extends Controller * ``` * * @since 2.0.10 - * @see $migrationPath + * @see migrationPath */ public $migrationNamespaces = []; /** @@ -84,6 +84,20 @@ abstract class BaseMigrateController extends Controller * or a file path. */ public $templateFile; + /** + * @var int|null the permission to be set for newly generated migration files. + * This value will be used by PHP chmod() function. No umask will be applied. + * If not set, the permission will be determined by the current environment. + * @since 2.0.43 + */ + public $newFileMode; + /** + * @var string|int|null the user and/or group ownership to be set for newly generated migration files. + * If not set, the ownership will be determined by the current environment. + * @since 2.0.43 + * @see FileHelper::changeOwnership() + */ + public $newFileOwnership; /** * @var bool indicates whether the console output should be compacted. * If this is set to true, the individual commands ran within the migration will not be output to the console. @@ -211,6 +225,8 @@ public function actionUp($limit = 0) $this->stdout("\n$n " . ($n === 1 ? 'migration was' : 'migrations were') . " applied.\n", Console::FG_GREEN); $this->stdout("\nMigrated up successfully.\n", Console::FG_GREEN); } + + return ExitCode::OK; } /** @@ -272,6 +288,8 @@ public function actionDown($limit = 1) $this->stdout("\n$n " . ($n === 1 ? 'migration was' : 'migrations were') . " reverted.\n", Console::FG_GREEN); $this->stdout("\nMigrated down successfully.\n", Console::FG_GREEN); } + + return ExitCode::OK; } /** @@ -338,6 +356,8 @@ public function actionRedo($limit = 1) $this->stdout("\n$n " . ($n === 1 ? 'migration was' : 'migrations were') . " redone.\n", Console::FG_GREEN); $this->stdout("\nMigration redone successfully.\n", Console::FG_GREEN); } + + return ExitCode::OK; } /** @@ -367,13 +387,13 @@ public function actionRedo($limit = 1) public function actionTo($version) { if (($namespaceVersion = $this->extractNamespaceMigrationVersion($version)) !== false) { - $this->migrateToVersion($namespaceVersion); + return $this->migrateToVersion($namespaceVersion); } elseif (($migrationName = $this->extractMigrationVersion($version)) !== false) { - $this->migrateToVersion($migrationName); + return $this->migrateToVersion($migrationName); } elseif ((string) (int) $version == $version) { - $this->migrateToTime($version); + return $this->migrateToTime($version); } elseif (($time = strtotime($version)) !== false) { - $this->migrateToTime($time); + return $this->migrateToTime($time); } else { throw new Exception("The version argument must be either a timestamp (e.g. 101129_185401),\n the full name of a migration (e.g. m101129_185401_create_user_table),\n the full namespaced name of a migration (e.g. app\\migrations\\M101129185401CreateUserTable),\n a UNIX timestamp (e.g. 1392853000), or a datetime string parseable\nby the strtotime() function (e.g. 2014-02-15 13:00:50)."); } @@ -431,13 +451,11 @@ public function actionMark($version) if (strpos($migration, $version) === 0) { if ($i === 0) { $this->stdout("Already at '$originalVersion'. Nothing needs to be done.\n", Console::FG_YELLOW); - } else { - if ($this->confirm("Set migration history at $originalVersion?")) { - for ($j = 0; $j < $i; ++$j) { - $this->removeMigrationHistory($migrations[$j]); - } - $this->stdout("The migration history is set at $originalVersion.\nNo actual migration was performed.\n", Console::FG_GREEN); + } elseif ($this->confirm("Set migration history at $originalVersion?")) { + for ($j = 0; $j < $i; ++$j) { + $this->removeMigrationHistory($migrations[$j]); } + $this->stdout("The migration history is set at $originalVersion.\nNo actual migration was performed.\n", Console::FG_GREEN); } return ExitCode::OK; @@ -460,16 +478,18 @@ public function actionFresh() { if (YII_ENV_PROD) { $this->stdout("YII_ENV is set to 'prod'.\nRefreshing migrations is not possible on production systems.\n"); + return ExitCode::OK; } - if ($this->confirm( - "Are you sure you want to drop all tables and related constraints and start the migration from the beginning?\nAll data will be lost irreversibly!")) { + if ($this->confirm("Are you sure you want to drop all tables and related constraints and start the migration from the beginning?\nAll data will be lost irreversibly!")) { $this->truncateDatabase(); + return $this->actionUp(); } $this->stdout('Action was cancelled by user. Nothing has been performed.'); + return ExitCode::OK; } @@ -545,6 +565,8 @@ public function actionHistory($limit = 10) $this->stdout("\t(" . date('Y-m-d H:i:s', $time) . ') ' . $version . "\n"); } } + + return ExitCode::OK; } /** @@ -565,9 +587,7 @@ public function actionHistory($limit = 10) */ public function actionNew($limit = 10) { - if ($limit === 'all') { - $limit = null; - } else { + if ($limit !== 'all') { $limit = (int) $limit; if ($limit < 1) { throw new Exception('The limit must be greater than 0.'); @@ -580,7 +600,7 @@ public function actionNew($limit = 10) $this->stdout("No new migrations found. Your system is up-to-date.\n", Console::FG_GREEN); } else { $n = count($migrations); - if ($limit && $n > $limit) { + if ($limit !== 'all' && $n > $limit) { $migrations = array_slice($migrations, 0, $limit); $this->stdout("Showing $limit out of $n new " . ($n === 1 ? 'migration' : 'migrations') . ":\n", Console::FG_YELLOW); } else { @@ -591,6 +611,8 @@ public function actionNew($limit = 10) $this->stdout("\t" . $migration . "\n"); } } + + return ExitCode::OK; } /** @@ -610,7 +632,7 @@ public function actionNew($limit = 10) * For example: * * ``` - * yii migrate/create 'app\\migrations\\createUserTable' + * yii migrate/create app\\migrations\\createUserTable * ``` * * In case [[migrationPath]] is not set and no namespace is provided, the first entry of [[migrationNamespaces]] will be used. @@ -647,9 +669,18 @@ public function actionCreate($name) 'namespace' => $namespace, ]); FileHelper::createDirectory($migrationPath); - file_put_contents($file, $content, LOCK_EX); + if (file_put_contents($file, $content, LOCK_EX) === false) { + $this->stdout("Failed to create new migration.\n", Console::FG_RED); + + return ExitCode::IOERR; + } + + FileHelper::changeOwnership($file, $this->newFileOwnership, $this->newFileMode); + $this->stdout("New migration created successfully.\n", Console::FG_GREEN); } + + return ExitCode::OK; } /** @@ -826,8 +857,10 @@ protected function migrateToTime($time) if ($count === 0) { $this->stdout("Nothing needs to be done.\n", Console::FG_GREEN); } else { - $this->actionDown($count); + return $this->actionDown($count); } + + return ExitCode::OK; } /** @@ -844,9 +877,7 @@ protected function migrateToVersion($version) $migrations = $this->getNewMigrations(); foreach ($migrations as $i => $migration) { if (strpos($migration, $version) === 0) { - $this->actionUp($i + 1); - - return ExitCode::OK; + return $this->actionUp($i + 1); } } @@ -857,7 +888,7 @@ protected function migrateToVersion($version) if ($i === 0) { $this->stdout("Already at '$originalVersion'. Nothing needs to be done.\n", Console::FG_YELLOW); } else { - $this->actionDown($i); + return $this->actionDown($i); } return ExitCode::OK; @@ -961,7 +992,7 @@ protected function getMigrationNameLimit() /** * Returns the migration history. - * @param int $limit the maximum number of records in the history to be returned. `null` for "no limit". + * @param int|null $limit the maximum number of records in the history to be returned. `null` for "no limit". * @return array the migration history */ abstract protected function getMigrationHistory($limit); diff --git a/framework/console/controllers/CacheController.php b/framework/console/controllers/CacheController.php index b53fe73d194..8675c53410c 100644 --- a/framework/console/controllers/CacheController.php +++ b/framework/console/controllers/CacheController.php @@ -84,11 +84,11 @@ public function actionFlush() $foundCaches = array_keys($caches); $notFoundCaches = array_diff($cachesInput, array_keys($caches)); - if ($notFoundCaches) { + if ($notFoundCaches !== []) { $this->notifyNotFoundCaches($notFoundCaches); } - if (!$foundCaches) { + if ($foundCaches === []) { $this->notifyNoCachesFound(); return ExitCode::OK; } diff --git a/framework/console/controllers/FixtureController.php b/framework/console/controllers/FixtureController.php index cce951f8004..667c2a56bcf 100644 --- a/framework/console/controllers/FixtureController.php +++ b/framework/console/controllers/FixtureController.php @@ -122,7 +122,7 @@ public function actionLoad(array $fixturesInput = []) $foundFixtures = $this->findFixtures($fixtures); $notFoundFixtures = array_diff($fixtures, $foundFixtures); - if ($notFoundFixtures) { + if ($notFoundFixtures !== []) { $this->notifyNotFound($notFoundFixtures); } } else { @@ -138,7 +138,7 @@ public function actionLoad(array $fixturesInput = []) ); } - if (!$fixturesToLoad) { + if ($fixturesToLoad === []) { $this->notifyNothingToLoad($foundFixtures, $except); return ExitCode::OK; } @@ -198,23 +198,23 @@ public function actionUnload(array $fixturesInput = []) $foundFixtures = $this->findFixtures($fixtures); $notFoundFixtures = array_diff($fixtures, $foundFixtures); - if ($notFoundFixtures) { + if ($notFoundFixtures !== []) { $this->notifyNotFound($notFoundFixtures); } } else { $foundFixtures = $this->findFixtures(); } - $fixturesToUnload = array_diff($foundFixtures, $except); - - if (!$foundFixtures) { + if ($foundFixtures === []) { throw new Exception( 'No files were found for: "' . implode(', ', $fixturesInput) . "\".\n" . "Check that files exist under fixtures path: \n\"" . $this->getFixturePath() . '".' ); } - if (!$fixturesToUnload) { + $fixturesToUnload = array_diff($foundFixtures, $except); + + if ($fixturesToUnload === []) { $this->notifyNothingToUnload($foundFixtures, $except); return ExitCode::OK; } @@ -225,7 +225,7 @@ public function actionUnload(array $fixturesInput = []) $fixtures = $this->getFixturesConfig(array_merge($this->globalFixtures, $fixturesToUnload)); - if (!$fixtures) { + if ($fixtures === []) { throw new Exception('No fixtures were found in namespace: ' . $this->namespace . '".'); } diff --git a/framework/console/controllers/HelpController.php b/framework/console/controllers/HelpController.php index 5185f4e011b..30e3d53e53c 100644 --- a/framework/console/controllers/HelpController.php +++ b/framework/console/controllers/HelpController.php @@ -30,7 +30,7 @@ * In the above, if the command name is not provided, all * available commands will be displayed. * - * @property-read array $commands All available command names. This property is read-only. + * @property-read array $commands All available command names. * * @author Qiang Xue * @since 2.0 @@ -41,7 +41,7 @@ class HelpController extends Controller * Displays available commands or the detailed information * about a particular command. * - * @param string $command The name of the command to show help about. + * @param string|null $command The name of the command to show help about. * If not provided, all available commands will be displayed. * @return int the exit status * @throws Exception if the command for help is unknown @@ -473,8 +473,8 @@ protected function getSubCommandHelp($controller, $actionID) */ protected function formatOptionHelp($name, $required, $type, $defaultValue, $comment) { - $comment = trim($comment); - $type = trim($type); + $comment = trim((string)$comment); + $type = trim((string)$type); if (strncmp($type, 'bool', 4) === 0) { $type = 'boolean, 0 or 1'; } @@ -485,7 +485,7 @@ protected function formatOptionHelp($name, $required, $type, $defaultValue, $com } if (is_bool($defaultValue)) { // show as integer to avoid confusion - $defaultValue = (int)$defaultValue; + $defaultValue = (int) $defaultValue; } if (is_string($defaultValue)) { $defaultValue = "'" . $defaultValue . "'"; diff --git a/framework/console/controllers/MessageController.php b/framework/console/controllers/MessageController.php index 0aa90bee2e3..2e950b312b2 100644 --- a/framework/console/controllers/MessageController.php +++ b/framework/console/controllers/MessageController.php @@ -58,12 +58,11 @@ class MessageController extends \yii\console\Controller */ public $languages = []; /** - * @var string the name of the function for translating messages. - * Defaults to 'Yii::t'. This is used as a mark to find the messages to be - * translated. You may use a string for single function name or an array for - * multiple function names. + * @var string|string[] the name of the function for translating messages. + * This is used as a mark to find the messages to be translated. + * You may use a string for single function name or an array for multiple function names. */ - public $translator = 'Yii::t'; + public $translator = ['Yii::t', '\Yii::t']; /** * @var bool whether to sort messages by keys when merging new messages * with the existing ones. Defaults to false, which means the new (untranslated) @@ -85,23 +84,22 @@ class MessageController extends \yii\console\Controller */ public $markUnused = true; /** - * @var array list of patterns that specify which files/directories should NOT be processed. + * @var array|null list of patterns that specify which files/directories should NOT be processed. * If empty or not set, all files/directories will be processed. * See helpers/FileHelper::findFiles() description for pattern matching rules. * If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. */ public $except = [ - '.svn', - '.git', - '.gitignore', - '.gitkeep', - '.hgignore', - '.hgkeep', + '.*', + '/.*', '/messages', + '/tests', + '/runtime', + '/vendor', '/BaseYii.php', // contains examples about Yii::t() ]; /** - * @var array list of patterns that specify which files (not directories) should be processed. + * @var array|null list of patterns that specify which files (not directories) should be processed. * If empty or not set, all files will be processed. * See helpers/FileHelper::findFiles() description for pattern matching rules. * If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. @@ -288,7 +286,7 @@ public function actionConfigTemplate($filePath) * This command will search through source code files and extract * messages that need to be translated in different languages. * - * @param string $configFile the path or alias of the configuration file. + * @param string|null $configFile the path or alias of the configuration file. * You may use the "yii message/config" command to generate * this file and then customize it for your needs. * @throws Exception on failure. @@ -386,7 +384,7 @@ protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $messag if (!$removeUnused) { foreach ($obsolete as $pk => $msg) { - if (mb_substr($msg, 0, 2) === '@@' && mb_substr($msg, -2) === '@@') { + if (strncmp($msg, '@@', 2) === 0 && substr($msg, -2) === '@@') { unset($obsolete[$pk]); } } diff --git a/framework/console/controllers/MigrateController.php b/framework/console/controllers/MigrateController.php index aa2625ea06c..9b82cc800c0 100644 --- a/framework/console/controllers/MigrateController.php +++ b/framework/console/controllers/MigrateController.php @@ -301,11 +301,9 @@ protected function truncateDatabase() // First drop all foreign keys, foreach ($schemas as $schema) { - if ($schema->foreignKeys) { - foreach ($schema->foreignKeys as $name => $foreignKey) { - $db->createCommand()->dropForeignKey($name, $schema->name)->execute(); - $this->stdout("Foreign key $name dropped.\n"); - } + foreach ($schema->foreignKeys as $name => $foreignKey) { + $db->createCommand()->dropForeignKey($name, $schema->name)->execute(); + $this->stdout("Foreign key $name dropped.\n"); } } @@ -389,7 +387,7 @@ private function normalizeTableName($name) $name = substr($name, 0, -1); } - if (strpos($name, '_') === 0) { + if (strncmp($name, '_', 1) === 0) { return substr($name, 1); } @@ -408,7 +406,7 @@ protected function generateMigrationSourceCode($params) $name = $params['name']; if ($params['namespace']) { - $name = substr($name, strrpos($name, '\\') + 1); + $name = substr($name, (strrpos($name, '\\') ?: -1) + 1); } $templateFile = $this->templateFile; @@ -580,10 +578,10 @@ protected function parseFields() */ protected function splitFieldIntoChunks($field) { - $hasDoubleQuotes = false; + $originalDefaultValue = null; + $defaultValue = null; preg_match_all('/defaultValue\(["\'].*?:?.*?["\']\)/', $field, $matches, PREG_SET_ORDER, 0); if (isset($matches[0][0])) { - $hasDoubleQuotes = true; $originalDefaultValue = $matches[0][0]; $defaultValue = str_replace(':', '{{colon}}', $originalDefaultValue); $field = str_replace($originalDefaultValue, $defaultValue, $field); @@ -591,7 +589,7 @@ protected function splitFieldIntoChunks($field) $chunks = preg_split('/\s?:\s?/', $field); - if (is_array($chunks) && $hasDoubleQuotes) { + if (is_array($chunks) && $defaultValue !== null && $originalDefaultValue !== null) { foreach ($chunks as $key => $chunk) { $chunks[$key] = str_replace($defaultValue, $originalDefaultValue, $chunk); } @@ -608,7 +606,7 @@ protected function splitFieldIntoChunks($field) protected function addDefaultPrimaryKey(&$fields) { foreach ($fields as $field) { - if (false !== strripos($field['decorators'], 'primarykey()')) { + if ($field['property'] === 'id' || false !== strripos($field['decorators'], 'primarykey()')) { return; } } diff --git a/framework/console/controllers/ServeController.php b/framework/console/controllers/ServeController.php index 5eb98165974..7df3b67c8f8 100644 --- a/framework/console/controllers/ServeController.php +++ b/framework/console/controllers/ServeController.php @@ -36,8 +36,8 @@ class ServeController extends Controller */ public $docroot = '@app/web'; /** - * @var string path to router script. - * See https://secure.php.net/manual/en/features.commandline.webserver.php + * @var string path or [path alias](guide:concept-aliases) to router script. + * See https://www.php.net/manual/en/features.commandline.webserver.php */ public $router; @@ -52,6 +52,7 @@ class ServeController extends Controller public function actionIndex($address = 'localhost') { $documentRoot = Yii::getAlias($this->docroot); + $router = $this->router !== null ? Yii::getAlias($this->router) : null; if (strpos($address, ':') === false) { $address = $address . ':' . $this->port; @@ -67,19 +68,19 @@ public function actionIndex($address = 'localhost') return self::EXIT_CODE_ADDRESS_TAKEN_BY_ANOTHER_PROCESS; } - if ($this->router !== null && !file_exists($this->router)) { - $this->stdout("Routing file \"$this->router\" does not exist.\n", Console::FG_RED); + if ($this->router !== null && !file_exists($router)) { + $this->stdout("Routing file \"$router\" does not exist.\n", Console::FG_RED); return self::EXIT_CODE_NO_ROUTING_FILE; } $this->stdout("Server started on http://{$address}/\n"); $this->stdout("Document root is \"{$documentRoot}\"\n"); if ($this->router) { - $this->stdout("Routing file is \"$this->router\"\n"); + $this->stdout("Routing file is \"$router\"\n"); } $this->stdout("Quit the server with CTRL-C or COMMAND-C.\n"); - passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" $this->router"); + passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" $router"); } /** diff --git a/framework/console/widgets/Table.php b/framework/console/widgets/Table.php index 99fd5d23234..537bd31fbcf 100644 --- a/framework/console/widgets/Table.php +++ b/framework/console/widgets/Table.php @@ -40,8 +40,8 @@ * ], * ]); * - * @property-write string $listPrefix List prefix. This property is write-only. - * @property-write int $screenWidth Screen width. This property is write-only. + * @property-write string $listPrefix List prefix. + * @property-write int $screenWidth Screen width. * * @author Daniel Gomez Pan * @since 2.0.13 diff --git a/framework/data/ActiveDataFilter.php b/framework/data/ActiveDataFilter.php index 88ad36254c2..5c46d0a449b 100644 --- a/framework/data/ActiveDataFilter.php +++ b/framework/data/ActiveDataFilter.php @@ -101,7 +101,7 @@ protected function buildCondition($condition) if (!empty($parts)) { if (count($parts) > 1) { - $parts = array_merge(['AND'], $parts); + array_unshift($parts, 'AND'); } else { $parts = array_shift($parts); } diff --git a/framework/data/ActiveDataProvider.php b/framework/data/ActiveDataProvider.php index 5a4fbb88aea..477ca7aee8d 100644 --- a/framework/data/ActiveDataProvider.php +++ b/framework/data/ActiveDataProvider.php @@ -56,12 +56,11 @@ class ActiveDataProvider extends BaseDataProvider { /** - * @var QueryInterface the query that is used to fetch data models and [[totalCount]] - * if it is not explicitly set. + * @var QueryInterface|null the query that is used to fetch data models and [[totalCount]] if it is not explicitly set. */ public $query; /** - * @var string|callable the column that is used as the key of the data models. + * @var string|callable|null the column that is used as the key of the data models. * This can be either a column name, or a callable that returns the key value of a given data model. * * If this is not set, the following rules will be used to determine the keys of the data models: @@ -73,8 +72,8 @@ class ActiveDataProvider extends BaseDataProvider */ public $key; /** - * @var Connection|array|string the DB connection object or the application component ID of the DB connection. - * If not set, the default DB connection will be used. + * @var Connection|array|string|null the DB connection object or the application component ID of the DB connection. + * If set it overrides [[query]] default DB connection. * Starting from version 2.0.2, this can also be a configuration array for creating the object. */ public $db; @@ -82,14 +81,14 @@ class ActiveDataProvider extends BaseDataProvider /** * Initializes the DB connection component. - * This method will initialize the [[db]] property to make sure it refers to a valid DB connection. + * This method will initialize the [[db]] property (when set) to make sure it refers to a valid DB connection. * @throws InvalidConfigException if [[db]] is invalid. */ public function init() { parent::init(); - if (is_string($this->db)) { - $this->db = Instance::ensure($this->db, Connection::className()); + if ($this->db !== null) { + $this->db = Instance::ensure($this->db); } } @@ -175,7 +174,7 @@ protected function prepareTotalCount() public function setSort($value) { parent::setSort($value); - if (($sort = $this->getSort()) !== false && $this->query instanceof ActiveQueryInterface) { + if ($this->query instanceof ActiveQueryInterface && ($sort = $this->getSort()) !== false) { /* @var $modelClass Model */ $modelClass = $this->query->modelClass; $model = $modelClass::instance(); diff --git a/framework/data/ArrayDataProvider.php b/framework/data/ArrayDataProvider.php index 5e507800a07..17c90981757 100644 --- a/framework/data/ArrayDataProvider.php +++ b/framework/data/ArrayDataProvider.php @@ -53,7 +53,7 @@ class ArrayDataProvider extends BaseDataProvider { /** - * @var string|callable the column that is used as the key of the data models. + * @var string|callable|null the column that is used as the key of the data models. * This can be either a column name, or a callable that returns the key value of a given data model. * If this is not set, the index of the [[models]] array will be used. * @see getKeys() diff --git a/framework/data/BaseDataProvider.php b/framework/data/BaseDataProvider.php index 97214cf602c..9169cfe8b42 100644 --- a/framework/data/BaseDataProvider.php +++ b/framework/data/BaseDataProvider.php @@ -16,15 +16,15 @@ * * For more details and usage information on BaseDataProvider, see the [guide article on data providers](guide:output-data-providers). * - * @property-read int $count The number of data models in the current page. This property is read-only. + * @property-read int $count The number of data models in the current page. * @property array $keys The list of key values corresponding to [[models]]. Each data model in [[models]] is * uniquely identified by the corresponding key value in this array. * @property array $models The list of data models in the current page. * @property Pagination|false $pagination The pagination object. If this is false, it means the pagination is - * disabled. Note that the type of this property differs in getter and setter. See [[getPagination()]] and + * disabled. Note that the type of this property differs in getter and setter. See [[getPagination()]] and * [[setPagination()]] for details. * @property Sort|bool $sort The sorting object. If this is false, it means the sorting is disabled. Note that - * the type of this property differs in getter and setter. See [[getSort()]] and [[setSort()]] for details. + * the type of this property differs in getter and setter. See [[getSort()]] and [[setSort()]] for details. * @property int $totalCount Total number of possible data models. * * @author Qiang Xue @@ -37,7 +37,7 @@ abstract class BaseDataProvider extends Component implements DataProviderInterfa */ private static $counter = 0; /** - * @var string an ID that uniquely identifies the data provider among all data providers. + * @var string|null an ID that uniquely identifies the data provider among all data providers. * Generated automatically the following way in case it is not set: * * - First data provider ID is empty. diff --git a/framework/data/DataFilter.php b/framework/data/DataFilter.php index 18f218f3622..eff67233ddc 100644 --- a/framework/data/DataFilter.php +++ b/framework/data/DataFilter.php @@ -113,13 +113,12 @@ * @see ActiveDataFilter * * @property array $errorMessages Error messages in format `[errorKey => message]`. Note that the type of this - * property differs in getter and setter. See [[getErrorMessages()]] and [[setErrorMessages()]] for details. + * property differs in getter and setter. See [[getErrorMessages()]] and [[setErrorMessages()]] for details. * @property mixed $filter Raw filter value. * @property array $searchAttributeTypes Search attribute type map. Note that the type of this property - * differs in getter and setter. See [[getSearchAttributeTypes()]] and [[setSearchAttributeTypes()]] for - * details. + * differs in getter and setter. See [[getSearchAttributeTypes()]] and [[setSearchAttributeTypes()]] for details. * @property Model $searchModel Model instance. Note that the type of this property differs in getter and - * setter. See [[getSearchModel()]] and [[setSearchModel()]] for details. + * setter. See [[getSearchModel()]] and [[setSearchModel()]] for details. * * @author Paul Klimov * @since 2.0.13 @@ -356,7 +355,7 @@ protected function detectSearchAttributeTypes() /** * Detect attribute type from given validator. * - * @param Validator validator from which to detect attribute type. + * @param Validator $validator validator from which to detect attribute type. * @return string|null detected attribute type. * @since 2.0.14 */ @@ -614,7 +613,7 @@ protected function validateAttributeCondition($attribute, $condition) * Validates operator condition. * @param string $operator raw operator control keyword. * @param mixed $condition attribute condition. - * @param string $attribute attribute name. + * @param string|null $attribute attribute name. */ protected function validateOperatorCondition($operator, $condition, $attribute = null) { diff --git a/framework/data/DataProviderInterface.php b/framework/data/DataProviderInterface.php index 71ed1febfb9..0260c381e8f 100644 --- a/framework/data/DataProviderInterface.php +++ b/framework/data/DataProviderInterface.php @@ -61,7 +61,7 @@ public function getModels(); public function getKeys(); /** - * @return Sort the sorting object. If this is false, it means the sorting is disabled. + * @return Sort|false the sorting object. If this is false, it means the sorting is disabled. */ public function getSort(); diff --git a/framework/data/Pagination.php b/framework/data/Pagination.php index f593d9a9481..7e9f7bb1eb0 100644 --- a/framework/data/Pagination.php +++ b/framework/data/Pagination.php @@ -60,13 +60,13 @@ * * @property-read int $limit The limit of the data. This may be used to set the LIMIT value for a SQL * statement for fetching the current page of data. Note that if the page size is infinite, a value -1 will be - * returned. This property is read-only. + * returned. * @property-read array $links The links for navigational purpose. The array keys specify the purpose of the - * links (e.g. [[LINK_FIRST]]), and the array values are the corresponding URLs. This property is read-only. + * links (e.g. [[LINK_FIRST]]), and the array values are the corresponding URLs. * @property-read int $offset The offset of the data. This may be used to set the OFFSET value for a SQL - * statement for fetching the current page of data. This property is read-only. + * statement for fetching the current page of data. * @property int $page The zero-based current page number. - * @property-read int $pageCount Number of pages. This property is read-only. + * @property-read int $pageCount Number of pages. * @property int $pageSize The number of items per page. If it is less than 1, it means the page size is * infinite, and thus a single page contains all items. * @@ -96,12 +96,12 @@ class Pagination extends BaseObject implements Linkable */ public $forcePageParam = true; /** - * @var string the route of the controller action for displaying the paged contents. + * @var string|null the route of the controller action for displaying the paged contents. * If not set, it means using the currently requested route. */ public $route; /** - * @var array parameters (name => value) that should be used to obtain the current page number + * @var array|null parameters (name => value) that should be used to obtain the current page number * and to create new pagination URLs. If not set, all parameters from $_GET will be used instead. * * In order to add hash to all links use `array_merge($_GET, ['#' => 'my-hash'])`. @@ -111,7 +111,7 @@ class Pagination extends BaseObject implements Linkable */ public $params; /** - * @var \yii\web\UrlManager the URL manager used for creating pagination URLs. If not set, + * @var \yii\web\UrlManager|null the URL manager used for creating pagination URLs. If not set, * the "urlManager" application component will be used. */ public $urlManager; @@ -250,7 +250,7 @@ public function setPageSize($value, $validatePageSize = false) * Creates the URL suitable for pagination with the specified page number. * This method is mainly called by pagers when creating URLs used to perform pagination. * @param int $page the zero-based page number that the URL should point to. - * @param int $pageSize the number of items on each page. If not set, the value of [[pageSize]] will be used. + * @param int|null $pageSize the number of items on each page. If not set, the value of [[pageSize]] will be used. * @param bool $absolute whether to create an absolute URL. Defaults to `false`. * @return string the created URL * @see params @@ -339,8 +339,8 @@ public function getLinks($absolute = false) * Returns the value of the specified query parameter. * This method returns the named parameter value from [[params]]. Null is returned if the value does not exist. * @param string $name the parameter name - * @param string $defaultValue the value to be returned when the specified parameter does not exist in [[params]]. - * @return string the parameter value + * @param string|null $defaultValue the value to be returned when the specified parameter does not exist in [[params]]. + * @return string|null the parameter value */ protected function getQueryParam($name, $defaultValue = null) { diff --git a/framework/data/Sort.php b/framework/data/Sort.php index d96178e1321..cf08bb1e853 100644 --- a/framework/data/Sort.php +++ b/framework/data/Sort.php @@ -70,9 +70,9 @@ * * @property array $attributeOrders Sort directions indexed by attribute names. Sort direction can be either * `SORT_ASC` for ascending order or `SORT_DESC` for descending order. Note that the type of this property - * differs in getter and setter. See [[getAttributeOrders()]] and [[setAttributeOrders()]] for details. + * differs in getter and setter. See [[getAttributeOrders()]] and [[setAttributeOrders()]] for details. * @property-read array $orders The columns (keys) and their corresponding sort directions (values). This can - * be passed to [[\yii\db\Query::orderBy()]] to construct a DB query. This property is read-only. + * be passed to [[\yii\db\Query::orderBy()]] to construct a DB query. * * @author Qiang Xue * @since 2.0 @@ -159,7 +159,7 @@ class Sort extends BaseObject */ public $defaultOrder; /** - * @var string the route of the controller action for displaying the sorted contents. + * @var string|null the route of the controller action for displaying the sorted contents. * If not set, it means using the currently requested route. */ public $route; @@ -168,7 +168,7 @@ class Sort extends BaseObject */ public $separator = ','; /** - * @var array parameters (name => value) that should be used to obtain the current sort directions + * @var array|null parameters (name => value) that should be used to obtain the current sort directions * and to create new sort URLs. If not set, `$_GET` will be used instead. * * In order to add hash to all links use `array_merge($_GET, ['#' => 'my-hash'])`. @@ -181,7 +181,7 @@ class Sort extends BaseObject */ public $params; /** - * @var \yii\web\UrlManager the URL manager used for creating sort URLs. If not set, + * @var \yii\web\UrlManager|null the URL manager used for creating sort URLs. If not set, * the `urlManager` application component will be used. */ public $urlManager; @@ -305,8 +305,8 @@ public function getAttributeOrders($recalculate = false) * @param string $param the value of the [[sortParam]]. * @return array the valid sort attributes. * @since 2.0.12 - * @see $separator for the attribute name separator. - * @see $sortParam + * @see separator for the attribute name separator. + * @see sortParam */ protected function parseSortParam($param) { @@ -438,14 +438,25 @@ public function createSortParam($attribute) $definition = $this->attributes[$attribute]; $directions = $this->getAttributeOrders(); if (isset($directions[$attribute])) { - $direction = $directions[$attribute] === SORT_DESC ? SORT_ASC : SORT_DESC; + if ($this->enableMultiSort) { + if ($directions[$attribute] === SORT_ASC) { + $direction = SORT_DESC; + } else { + $direction = null; + } + } else { + $direction = $directions[$attribute] === SORT_DESC ? SORT_ASC : SORT_DESC; + } + unset($directions[$attribute]); } else { $direction = isset($definition['default']) ? $definition['default'] : SORT_ASC; } if ($this->enableMultiSort) { - $directions = array_merge([$attribute => $direction], $directions); + if ($direction !== null) { + $directions = array_merge([$attribute => $direction], $directions); + } } else { $directions = [$attribute => $direction]; } diff --git a/framework/data/SqlDataProvider.php b/framework/data/SqlDataProvider.php index 00ebd121db9..a179d9bca6d 100644 --- a/framework/data/SqlDataProvider.php +++ b/framework/data/SqlDataProvider.php @@ -80,7 +80,7 @@ class SqlDataProvider extends BaseDataProvider */ public $params = []; /** - * @var string|callable the column that is used as the key of the data models. + * @var string|callable|null the column that is used as the key of the data models. * This can be either a column name, or a callable that returns the key value of a given data model. * * If this is not set, the keys of the [[models]] array will be used. @@ -119,7 +119,7 @@ protected function prepareModels() if ($sort !== false) { $orders = $sort->getOrders(); - $pattern = '/\s+order\s+by\s+([\w\s,\.]+)$/i'; + $pattern = '/\s+order\s+by\s+([\w\s,\."`\[\]]+)$/i'; if (preg_match($pattern, $sql, $matches)) { array_unshift($orders, new Expression($matches[1])); $sql = preg_replace($pattern, '', $sql); diff --git a/framework/db/ActiveQuery.php b/framework/db/ActiveQuery.php index 300f9dda7fe..d6abab28832 100644 --- a/framework/db/ActiveQuery.php +++ b/framework/db/ActiveQuery.php @@ -81,12 +81,12 @@ class ActiveQuery extends Query implements ActiveQueryInterface const EVENT_INIT = 'init'; /** - * @var string the SQL statement to be executed for retrieving AR records. + * @var string|null the SQL statement to be executed for retrieving AR records. * This is set by [[ActiveRecord::findBySql()]]. */ public $sql; /** - * @var string|array the join condition to be used when this query is used in a relational context. + * @var string|array|null the join condition to be used when this query is used in a relational context. * The condition will be used in the ON part when [[ActiveQuery::joinWith()]] is called. * Otherwise, the condition will be used in the WHERE part of a query. * Please refer to [[Query::where()]] on how to specify this parameter. @@ -94,7 +94,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface */ public $on; /** - * @var array a list of relations that this query should be joined with + * @var array|null a list of relations that this query should be joined with */ public $joinWith; @@ -124,7 +124,7 @@ public function init() /** * Executes query and returns all results as an array. - * @param Connection $db the DB connection used to create the DB command. + * @param Connection|null $db the DB connection used to create the DB command. * If null, the DB connection returned by [[modelClass]] will be used. * @return array|ActiveRecord[] the query results. If the query results in nothing, an empty array will be returned. */ @@ -699,7 +699,7 @@ private function joinWithRelation($parent, $child, $joinType) * ```php * public function getActiveUsers() * { - * return $this->hasMany(User::className(), ['id' => 'user_id']) + * return $this->hasMany(User::class, ['id' => 'user_id']) * ->onCondition(['active' => true]); * } * ``` @@ -769,7 +769,7 @@ public function orOnCondition($condition, $params = []) * ```php * public function getItems() * { - * return $this->hasMany(Item::className(), ['id' => 'item_id']) + * return $this->hasMany(Item::class, ['id' => 'item_id']) * ->viaTable('order_item', ['order_id' => 'id']); * } * ``` @@ -778,7 +778,7 @@ public function orOnCondition($condition, $params = []) * @param array $link the link between the junction table and the table associated with [[primaryModel]]. * The keys of the array represent the columns in the junction table, and the values represent the columns * in the [[primaryModel]] table. - * @param callable $callable a PHP callback for customizing the relation associated with the junction table. + * @param callable|null $callable a PHP callback for customizing the relation associated with the junction table. * Its signature should be `function($query)`, where `$query` is the query to be customized. * @return $this the query object itself * @throws InvalidConfigException when query is not initialized properly diff --git a/framework/db/ActiveQueryInterface.php b/framework/db/ActiveQueryInterface.php index 9150e8bc2ec..3b6cdcd0374 100644 --- a/framework/db/ActiveQueryInterface.php +++ b/framework/db/ActiveQueryInterface.php @@ -31,7 +31,7 @@ public function asArray($value = true); /** * Executes query and returns a single row of result. - * @param Connection $db the DB connection used to create the DB command. + * @param Connection|null $db the DB connection used to create the DB command. * If `null`, the DB connection returned by [[ActiveQueryTrait::$modelClass|modelClass]] will be used. * @return ActiveRecordInterface|array|null a single row of query result. Depending on the setting of [[asArray]], * the query result may be either an array or an ActiveRecord object. `null` will be returned @@ -92,7 +92,7 @@ public function with(); /** * Specifies the relation associated with the junction table for use in relational query. * @param string $relationName the relation name. This refers to a relation declared in the [[ActiveRelationTrait::primaryModel|primaryModel]] of the relation. - * @param callable $callable a PHP callback for customizing the relation associated with the junction table. + * @param callable|null $callable a PHP callback for customizing the relation associated with the junction table. * Its signature should be `function($query)`, where `$query` is the query to be customized. * @return $this the relation object itself. */ diff --git a/framework/db/ActiveRecord.php b/framework/db/ActiveRecord.php index 54085022869..fd7e9539ebd 100644 --- a/framework/db/ActiveRecord.php +++ b/framework/db/ActiveRecord.php @@ -70,8 +70,8 @@ * * For more details and usage information on ActiveRecord, see the [guide article on ActiveRecord](guide:db-active-record). * - * @method ActiveQuery hasMany($class, array $link) see [[BaseActiveRecord::hasMany()]] for more info - * @method ActiveQuery hasOne($class, array $link) see [[BaseActiveRecord::hasOne()]] for more info + * @method ActiveQuery hasMany($class, array $link) See [[BaseActiveRecord::hasMany()]] for more info. + * @method ActiveQuery hasOne($class, array $link) See [[BaseActiveRecord::hasOne()]] for more info. * * @author Qiang Xue * @author Carsten Brandt @@ -115,9 +115,13 @@ class ActiveRecord extends BaseActiveRecord */ public function loadDefaultValues($skipIfSet = true) { - foreach (static::getTableSchema()->columns as $column) { - if ($column->defaultValue !== null && (!$skipIfSet || $this->{$column->name} === null)) { - $this->{$column->name} = $column->defaultValue; + $columns = static::getTableSchema()->columns; + foreach ($this->attributes() as $name) { + if (isset($columns[$name])) { + $defaultValue = $columns[$name]->defaultValue; + if ($defaultValue !== null && (!$skipIfSet || $this->getAttribute($name) === null)) { + $this->setAttribute($name, $defaultValue); + } } } @@ -289,7 +293,7 @@ public function refresh() $query->where($pk); /* @var $record BaseActiveRecord */ - $record = $query->one(); + $record = $query->noCache()->one(); return $this->refreshInternal($record); } @@ -388,7 +392,7 @@ public static function updateAllCounters($counters, $condition = '', $params = [ * * For a large set of models you might consider using [[ActiveQuery::each()]] to keep memory usage within limits. * - * @param string|array $condition the conditions that will be put in the WHERE part of the DELETE SQL. + * @param string|array|null $condition the conditions that will be put in the WHERE part of the DELETE SQL. * Please refer to [[Query::where()]] on how to specify this parameter. * @param array $params the parameters (name => value) to be bound to the query. * @return int the number of rows deleted @@ -466,7 +470,7 @@ public static function primaryKey() */ public function attributes() { - return array_keys(static::getTableSchema()->columns); + return static::getTableSchema()->getColumnNames(); } /** @@ -550,10 +554,10 @@ public static function populateRecord($record, $row) * @param bool $runValidation whether to perform validation (calling [[validate()]]) * before saving the record. Defaults to `true`. If the validation fails, the record * will not be saved to the database and this method will return `false`. - * @param array $attributes list of attributes that need to be saved. Defaults to `null`, + * @param array|null $attributes list of attributes that need to be saved. Defaults to `null`, * meaning all attributes that are loaded from DB will be saved. * @return bool whether the attributes are valid and the record is inserted successfully. - * @throws \Exception|\Throwable in case insert failed. + * @throws \Throwable in case insert failed. */ public function insert($runValidation = true, $attributes = null) { @@ -587,7 +591,7 @@ public function insert($runValidation = true, $attributes = null) /** * Inserts an ActiveRecord into DB without considering transaction. - * @param array $attributes list of attributes that need to be saved. Defaults to `null`, + * @param array|null $attributes list of attributes that need to be saved. Defaults to `null`, * meaning all attributes that are loaded from DB will be saved. * @return bool whether the record is inserted successfully. */ @@ -657,13 +661,13 @@ protected function insertInternal($attributes = null) * @param bool $runValidation whether to perform validation (calling [[validate()]]) * before saving the record. Defaults to `true`. If the validation fails, the record * will not be saved to the database and this method will return `false`. - * @param array $attributeNames list of attributes that need to be saved. Defaults to `null`, + * @param array|null $attributeNames list of attributes that need to be saved. Defaults to `null`, * meaning all attributes that are loaded from DB will be saved. * @return int|false the number of rows affected, or false if validation fails * or [[beforeSave()]] stops the updating process. * @throws StaleObjectException if [[optimisticLock|optimistic locking]] is enabled and the data * being updated is outdated. - * @throws \Exception|\Throwable in case update failed. + * @throws \Throwable in case update failed. */ public function update($runValidation = true, $attributeNames = null) { @@ -712,7 +716,7 @@ public function update($runValidation = true, $attributeNames = null) * Note that it is possible the number of rows deleted is 0, even though the deletion execution is successful. * @throws StaleObjectException if [[optimisticLock|optimistic locking]] is enabled and the data * being deleted is outdated. - * @throws \Exception|\Throwable in case delete failed. + * @throws \Throwable in case delete failed. */ public function delete() { diff --git a/framework/db/ActiveRecordInterface.php b/framework/db/ActiveRecordInterface.php index dfa9ed3096e..9cc7dc7a40b 100644 --- a/framework/db/ActiveRecordInterface.php +++ b/framework/db/ActiveRecordInterface.php @@ -79,9 +79,6 @@ public function getPrimaryKey($asArray = false); * @param bool $asArray whether to return the primary key value as an array. If true, * the return value will be an array with column name as key and column value as value. * If this is `false` (default), a scalar value will be returned for non-composite primary key. - * @property mixed The old primary key value. An array (column name => column value) is - * returned if the primary key is composite. A string is returned otherwise (`null` will be - * returned if the key value is `null`). * @return mixed the old primary key value. An array (column name => column value) is returned if the primary key * is composite or `$asArray` is true. A string is returned otherwise (`null` will be returned if * the key value is `null`). @@ -313,7 +310,7 @@ public static function updateAll($attributes, $condition = null); * Customer::deleteAll([status = 3]); * ``` * - * @param array $condition the condition that matches the records that should get deleted. + * @param array|null $condition the condition that matches the records that should get deleted. * Please refer to [[QueryInterface::where()]] on how to specify this parameter. * An empty condition will match all records. * @return int the number of rows deleted @@ -338,7 +335,7 @@ public static function deleteAll($condition = null); * @param bool $runValidation whether to perform validation (calling [[\yii\base\Model::validate()|validate()]]) * before saving the record. Defaults to `true`. If the validation fails, the record * will not be saved to the database and this method will return `false`. - * @param array $attributeNames list of attribute names that need to be saved. Defaults to `null`, + * @param array|null $attributeNames list of attribute names that need to be saved. Defaults to `null`, * meaning all attributes that are loaded from DB will be saved. * @return bool whether the saving succeeded (i.e. no validation errors occurred). */ @@ -359,7 +356,7 @@ public function save($runValidation = true, $attributeNames = null); * @param bool $runValidation whether to perform validation (calling [[\yii\base\Model::validate()|validate()]]) * before saving the record. Defaults to `true`. If the validation fails, the record * will not be saved to the database and this method will return `false`. - * @param array $attributes list of attributes that need to be saved. Defaults to `null`, + * @param array|null $attributes list of attributes that need to be saved. Defaults to `null`, * meaning all attributes that are loaded from DB will be saved. * @return bool whether the attributes are valid and the record is inserted successfully. */ @@ -380,7 +377,7 @@ public function insert($runValidation = true, $attributes = null); * @param bool $runValidation whether to perform validation (calling [[\yii\base\Model::validate()|validate()]]) * before saving the record. Defaults to `true`. If the validation fails, the record * will not be saved to the database and this method will return `false`. - * @param array $attributeNames list of attributes that need to be saved. Defaults to `null`, + * @param array|null $attributeNames list of attributes that need to be saved. Defaults to `null`, * meaning all attributes that are loaded from DB will be saved. * @return int|bool the number of rows affected, or `false` if validation fails * or updating process is stopped for other reasons. diff --git a/framework/db/ActiveRelationTrait.php b/framework/db/ActiveRelationTrait.php index f2c22e125f3..fc09be8376c 100644 --- a/framework/db/ActiveRelationTrait.php +++ b/framework/db/ActiveRelationTrait.php @@ -17,8 +17,8 @@ * @author Carsten Brandt * @since 2.0 * - * @method ActiveRecordInterface one($db = null) - * @method ActiveRecordInterface[] all($db = null) + * @method ActiveRecordInterface one($db = null) See [[ActiveQueryInterface::one()]] for more info. + * @method ActiveRecordInterface[] all($db = null) See [[ActiveQueryInterface::all()]] for more info. * @property ActiveRecord $modelClass */ trait ActiveRelationTrait @@ -87,18 +87,18 @@ public function __clone() * class Order extends ActiveRecord * { * public function getOrderItems() { - * return $this->hasMany(OrderItem::className(), ['order_id' => 'id']); + * return $this->hasMany(OrderItem::class, ['order_id' => 'id']); * } * * public function getItems() { - * return $this->hasMany(Item::className(), ['id' => 'item_id']) + * return $this->hasMany(Item::class, ['id' => 'item_id']) * ->via('orderItems'); * } * } * ``` * * @param string $relationName the relation name. This refers to a relation declared in [[primaryModel]]. - * @param callable $callable a PHP callback for customizing the relation associated with the junction table. + * @param callable|null $callable a PHP callback for customizing the relation associated with the junction table. * Its signature should be `function($query)`, where `$query` is the query to be customized. * @return $this the relation object itself. */ @@ -126,7 +126,7 @@ public function via($relationName, callable $callable = null) * ```php * public function getOrders() * { - * return $this->hasMany(Order::className(), ['customer_id' => 'id'])->inverseOf('customer'); + * return $this->hasMany(Order::class, ['customer_id' => 'id'])->inverseOf('customer'); * } * ``` * @@ -135,7 +135,7 @@ public function via($relationName, callable $callable = null) * ```php * public function getCustomer() * { - * return $this->hasOne(Customer::className(), ['id' => 'customer_id'])->inverseOf('orders'); + * return $this->hasOne(Customer::class, ['id' => 'customer_id'])->inverseOf('orders'); * } * ``` * @@ -167,7 +167,7 @@ public function inverseOf($relationName) /** * Finds the related records for the specified primary record. - * This method is invoked when a relation of an ActiveRecord is being accessed in a lazy fashion. + * This method is invoked when a relation of an ActiveRecord is being accessed lazily. * @param string $name the relation name * @param ActiveRecordInterface|BaseActiveRecord $model the primary model * @return mixed the related record(s) @@ -289,7 +289,12 @@ public function populateRelation($name, &$primaryModels) $link = array_values($deepViaQuery->link); } foreach ($primaryModels as $i => $primaryModel) { - if ($this->multiple && count($link) === 1 && is_array($keys = $primaryModel[reset($link)])) { + $keys = null; + if ($this->multiple && count($link) === 1) { + $primaryModelKey = reset($link); + $keys = isset($primaryModel[$primaryModelKey]) ? $primaryModel[$primaryModelKey] : null; + } + if (is_array($keys)) { $value = []; foreach ($keys as $key) { $key = $this->normalizeModelKey($key); @@ -386,8 +391,8 @@ private function populateInverseRelation(&$primaryModels, $models, $primaryName, /** * @param array $models * @param array $link - * @param array $viaModels - * @param null|self $viaQuery + * @param array|null $viaModels + * @param self|null $viaQuery * @param bool $checkMultiple * @return array */ @@ -523,7 +528,8 @@ private function filterByModels($models) // single key $attribute = reset($this->link); foreach ($models as $model) { - if (($value = $model[$attribute]) !== null) { + $value = isset($model[$attribute]) ? $model[$attribute] : null; + if ($value !== null) { if (is_array($value)) { $values = array_merge($values, $value); } elseif ($value instanceof ArrayExpression && $value->getDimension() === 1) { @@ -574,33 +580,36 @@ private function filterByModels($models) /** * @param ActiveRecordInterface|array $model * @param array $attributes - * @return string + * @return string|false */ private function getModelKey($model, $attributes) { $key = []; foreach ($attributes as $attribute) { - $key[] = $this->normalizeModelKey($model[$attribute]); + if (isset($model[$attribute])) { + $key[] = $this->normalizeModelKey($model[$attribute]); + } } if (count($key) > 1) { return serialize($key); } - $key = reset($key); - return is_scalar($key) ? $key : serialize($key); + return reset($key); } /** - * @param mixed $value raw key value. + * @param mixed $value raw key value. Since 2.0.40 non-string values must be convertible to string (like special + * objects for cross-DBMS relations, for example: `|MongoId`). * @return string normalized key value. */ private function normalizeModelKey($value) { - if (is_object($value) && method_exists($value, '__toString')) { - // ensure matching to special objects, which are convertable to string, for cross-DBMS relations, for example: `|MongoId` - $value = $value->__toString(); + try { + return (string)$value; + } catch (\Exception $e) { + throw new InvalidConfigException('Value must be convertable to string.'); + } catch (\Throwable $e) { + throw new InvalidConfigException('Value must be convertable to string.'); } - - return $value; } /** diff --git a/framework/db/ArrayExpression.php b/framework/db/ArrayExpression.php index 7a36793efb7..5a935ac526c 100644 --- a/framework/db/ArrayExpression.php +++ b/framework/db/ArrayExpression.php @@ -28,7 +28,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, \IteratorAggregate { /** - * @var null|string the type of the array elements. Defaults to `null` which means the type is + * @var string|null the type of the array elements. Defaults to `null` which means the type is * not explicitly specified. * * Note that in case when type is not specified explicitly and DBMS can not guess it from the context, @@ -68,8 +68,7 @@ public function __construct($value, $type = null, $dimension = 1) } /** - * @return null|string - * @see type + * @return string|null */ public function getType() { @@ -78,7 +77,6 @@ public function getType() /** * @return array|mixed|QueryInterface - * @see value */ public function getValue() { @@ -87,7 +85,6 @@ public function getValue() /** * @return int the number of indices needed to select an element - * @see dimensions */ public function getDimension() { @@ -97,7 +94,7 @@ public function getDimension() /** * Whether a offset exists * - * @link https://secure.php.net/manual/en/arrayaccess.offsetexists.php + * @link https://www.php.net/manual/en/arrayaccess.offsetexists.php * @param mixed $offset

      * An offset to check for. *

      @@ -107,6 +104,7 @@ public function getDimension() * The return value will be casted to boolean if non-boolean was returned. * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->value[$offset]); @@ -115,13 +113,14 @@ public function offsetExists($offset) /** * Offset to retrieve * - * @link https://secure.php.net/manual/en/arrayaccess.offsetget.php + * @link https://www.php.net/manual/en/arrayaccess.offsetget.php * @param mixed $offset

      * The offset to retrieve. *

      * @return mixed Can return all value types. * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->value[$offset]; @@ -130,7 +129,7 @@ public function offsetGet($offset) /** * Offset to set * - * @link https://secure.php.net/manual/en/arrayaccess.offsetset.php + * @link https://www.php.net/manual/en/arrayaccess.offsetset.php * @param mixed $offset

      * The offset to assign the value to. *

      @@ -140,6 +139,7 @@ public function offsetGet($offset) * @return void * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->value[$offset] = $value; @@ -148,13 +148,14 @@ public function offsetSet($offset, $value) /** * Offset to unset * - * @link https://secure.php.net/manual/en/arrayaccess.offsetunset.php + * @link https://www.php.net/manual/en/arrayaccess.offsetunset.php * @param mixed $offset

      * The offset to unset. *

      * @return void * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->value[$offset]); @@ -163,13 +164,14 @@ public function offsetUnset($offset) /** * Count elements of an object * - * @link https://secure.php.net/manual/en/countable.count.php + * @link https://www.php.net/manual/en/countable.count.php * @return int The custom count as an integer. *

      *

      * The return value is cast to an integer. * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function count() { return count($this->value); @@ -178,12 +180,13 @@ public function count() /** * Retrieve an external iterator * - * @link https://secure.php.net/manual/en/iteratoraggregate.getiterator.php + * @link https://www.php.net/manual/en/iteratoraggregate.getiterator.php * @return Traversable An instance of an object implementing Iterator or * Traversable * @since 2.0.14.1 * @throws InvalidConfigException when ArrayExpression contains QueryInterface object */ + #[\ReturnTypeWillChange] public function getIterator() { $value = $this->getValue(); diff --git a/framework/db/BaseActiveRecord.php b/framework/db/BaseActiveRecord.php index ead5f5c7d6e..a784d18e1ab 100644 --- a/framework/db/BaseActiveRecord.php +++ b/framework/db/BaseActiveRecord.php @@ -23,19 +23,17 @@ * * See [[\yii\db\ActiveRecord]] for a concrete implementation. * - * @property-read array $dirtyAttributes The changed attribute values (name-value pairs). This property is - * read-only. + * @property-read array $dirtyAttributes The changed attribute values (name-value pairs). * @property bool $isNewRecord Whether the record is new and should be inserted when calling [[save()]]. * @property array $oldAttributes The old attribute values (name-value pairs). Note that the type of this - * property differs in getter and setter. See [[getOldAttributes()]] and [[setOldAttributes()]] for details. + * property differs in getter and setter. See [[getOldAttributes()]] and [[setOldAttributes()]] for details. * @property-read mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is * returned if the primary key is composite. A string is returned otherwise (null will be returned if the key - * value is null). This property is read-only. + * value is null). * @property-read mixed $primaryKey The primary key value. An array (column name => column value) is returned * if the primary key is composite. A string is returned otherwise (null will be returned if the key value is - * null). This property is read-only. - * @property-read array $relatedRecords An array of related records indexed by relation names. This property - * is read-only. + * null). + * @property-read array $relatedRecords An array of related records indexed by relation names. * * @author Qiang Xue * @author Carsten Brandt @@ -198,7 +196,7 @@ public static function updateAllCounters($counters, $condition = '') * Customer::deleteAll('status = 3'); * ``` * - * @param string|array $condition the conditions that will be put in the WHERE part of the DELETE SQL. + * @param string|array|null $condition the conditions that will be put in the WHERE part of the DELETE SQL. * Please refer to [[Query::where()]] on how to specify this parameter. * @return int the number of rows deleted * @throws NotSupportedException if not overridden. @@ -226,12 +224,12 @@ public static function deleteAll($condition = null) * Or add [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] to your model * class in order to automate the process. * 3. In the Web form that collects the user input, add a hidden field that stores - * the lock version of the recording being updated. + * the lock version of the record being updated. * 4. In the controller action that does the data updating, try to catch the [[StaleObjectException]] * and implement necessary business logic (e.g. merging the changes, prompting stated data) * to resolve the conflict. * - * @return string the column name that stores the lock version of a table row. + * @return string|null the column name that stores the lock version of a table row. * If `null` is returned (default implemented), optimistic locking will not be supported. */ public function optimisticLock() @@ -335,9 +333,9 @@ public function __isset($name) { try { return $this->__get($name) !== null; - } catch (\Throwable $t) { + } catch (\Exception $t) { return false; - } catch (\Exception $e) { + } catch (\Throwable $e) { return false; } } @@ -376,7 +374,7 @@ public function __unset($name) * ```php * public function getCountry() * { - * return $this->hasOne(Country::className(), ['id' => 'country_id']); + * return $this->hasOne(Country::class, ['id' => 'country_id']); * } * ``` * @@ -411,7 +409,7 @@ public function hasOne($class, $link) * ```php * public function getOrders() * { - * return $this->hasMany(Order::className(), ['customer_id' => 'id']); + * return $this->hasMany(Order::class, ['customer_id' => 'id']); * } * ``` * @@ -641,7 +639,7 @@ public function getDirtyAttributes($names = null) } } else { foreach ($this->_attributes as $name => $value) { - if (isset($names[$name]) && (!array_key_exists($name, $this->_oldAttributes) || $value !== $this->_oldAttributes[$name])) { + if (isset($names[$name]) && (!array_key_exists($name, $this->_oldAttributes) || $this->isAttributeDirty($name, $value))) { $attributes[$name] = $value; } } @@ -668,7 +666,7 @@ public function getDirtyAttributes($names = null) * @param bool $runValidation whether to perform validation (calling [[validate()]]) * before saving the record. Defaults to `true`. If the validation fails, the record * will not be saved to the database and this method will return `false`. - * @param array $attributeNames list of attribute names that need to be saved. Defaults to null, + * @param array|null $attributeNames list of attribute names that need to be saved. Defaults to null, * meaning all attributes that are loaded from DB will be saved. * @return bool whether the saving succeeded (i.e. no validation errors occurred). */ @@ -725,7 +723,7 @@ public function save($runValidation = true, $attributeNames = null) * @param bool $runValidation whether to perform validation (calling [[validate()]]) * before saving the record. Defaults to `true`. If the validation fails, the record * will not be saved to the database and this method will return `false`. - * @param array $attributeNames list of attribute names that need to be saved. Defaults to null, + * @param array|null $attributeNames list of attribute names that need to be saved. Defaults to null, * meaning all attributes that are loaded from DB will be saved. * @return int|false the number of rows affected, or `false` if validation fails * or [[beforeSave()]] stops the updating process. @@ -785,7 +783,7 @@ public function updateAttributes($attributes) /** * @see update() - * @param array $attributes attributes to update + * @param array|null $attributes attributes to update * @return int|false the number of rows affected, or false if [[beforeSave()]] stops the updating process. * @throws StaleObjectException */ @@ -1112,16 +1110,13 @@ public function equals($record) * @param bool $asArray whether to return the primary key value as an array. If `true`, * the return value will be an array with column names as keys and column values as values. * Note that for composite primary keys, an array will always be returned regardless of this parameter value. - * @property mixed The primary key value. An array (column name => column value) is returned if - * the primary key is composite. A string is returned otherwise (null will be returned if - * the key value is null). * @return mixed the primary key value. An array (column name => column value) is returned if the primary key * is composite or `$asArray` is `true`. A string is returned otherwise (null will be returned if * the key value is null). */ public function getPrimaryKey($asArray = false) { - $keys = $this->primaryKey(); + $keys = static::primaryKey(); if (!$asArray && count($keys) === 1) { return isset($this->_attributes[$keys[0]]) ? $this->_attributes[$keys[0]] : null; } @@ -1142,9 +1137,6 @@ public function getPrimaryKey($asArray = false) * @param bool $asArray whether to return the primary key value as an array. If `true`, * the return value will be an array with column name as key and column value as value. * If this is `false` (default), a scalar value will be returned for non-composite primary key. - * @property mixed The old primary key value. An array (column name => column value) is - * returned if the primary key is composite. A string is returned otherwise (null will be - * returned if the key value is null). * @return mixed the old primary key value. An array (column name => column value) is returned if the primary key * is composite or `$asArray` is `true`. A string is returned otherwise (null will be returned if * the key value is null). @@ -1152,7 +1144,7 @@ public function getPrimaryKey($asArray = false) */ public function getOldPrimaryKey($asArray = false) { - $keys = $this->primaryKey(); + $keys = static::primaryKey(); if (empty($keys)) { throw new Exception(get_class($this) . ' does not have a primary key. You should either define a primary key for the corresponding table or override the primaryKey() method.'); } @@ -1221,6 +1213,7 @@ public static function instantiate($row) * @param mixed $offset the offset to check on * @return bool whether there is an element at the specified offset. */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return $this->__isset($offset); @@ -1232,7 +1225,7 @@ public function offsetExists($offset) * It can be declared in either the Active Record class itself or one of its behaviors. * @param string $name the relation name, e.g. `orders` for a relation defined via `getOrders()` method (case-sensitive). * @param bool $throwException whether to throw exception if the relation does not exist. - * @return ActiveQueryInterface|ActiveQuery the relational query object. If the relation does not exist + * @return ActiveQueryInterface|ActiveQuery|null the relational query object. If the relation does not exist * and `$throwException` is `false`, `null` will be returned. * @throws InvalidArgumentException if the named relation does not exist. */ @@ -1278,7 +1271,8 @@ public function getRelation($name, $throwException = true) * * The relationship is established by setting the foreign key value(s) in one model * to be the corresponding primary key value(s) in the other model. - * The model with the foreign key will be saved into database without performing validation. + * The model with the foreign key will be saved into database **without** performing validation + * and **without** events/behaviors. * * If the relationship involves a junction table, a new row will be inserted into the * junction table which contains the primary key values from both models. @@ -1294,6 +1288,7 @@ public function getRelation($name, $throwException = true) */ public function link($name, $model, $extraColumns = []) { + /* @var $relation ActiveQueryInterface|ActiveQuery */ $relation = $this->getRelation($name); if ($relation->via !== null) { @@ -1330,16 +1325,16 @@ public function link($name, $model, $extraColumns = []) $record->insert(false); } else { /* @var $viaTable string */ - static::getDb()->createCommand() - ->insert($viaTable, $columns)->execute(); + static::getDb()->createCommand()->insert($viaTable, $columns)->execute(); } } else { $p1 = $model->isPrimaryKey(array_keys($relation->link)); $p2 = static::isPrimaryKey(array_values($relation->link)); if ($p1 && $p2) { - if ($this->getIsNewRecord() && $model->getIsNewRecord()) { - throw new InvalidCallException('Unable to link models: at most one model can be newly created.'); - } elseif ($this->getIsNewRecord()) { + if ($this->getIsNewRecord()) { + if ($model->getIsNewRecord()) { + throw new InvalidCallException('Unable to link models: at most one model can be newly created.'); + } $this->bindModels(array_flip($relation->link), $this, $model); } else { $this->bindModels($relation->link, $model, $this); @@ -1384,9 +1379,12 @@ public function link($name, $model, $extraColumns = []) * If `false`, the model's foreign key will be set `null` and saved. * If `true`, the model containing the foreign key will be deleted. * @throws InvalidCallException if the models cannot be unlinked + * @throws Exception + * @throws StaleObjectException */ public function unlink($name, $model, $delete = false) { + /* @var $relation ActiveQueryInterface|ActiveQuery */ $relation = $this->getRelation($name); if ($relation->via !== null) { @@ -1410,6 +1408,9 @@ public function unlink($name, $model, $delete = false) foreach (array_keys($columns) as $a) { $nulls[$a] = null; } + if (property_exists($viaRelation, 'on') && $viaRelation->on !== null) { + $columns = ['and', $columns, $viaRelation->on]; + } if (is_array($relation->via)) { /* @var $viaClass ActiveRecordInterface */ if ($delete) { @@ -1486,6 +1487,7 @@ public function unlink($name, $model, $delete = false) */ public function unlinkAll($name, $delete = false) { + /* @var $relation ActiveQueryInterface|ActiveQuery */ $relation = $this->getRelation($name); if ($relation->via !== null) { @@ -1507,7 +1509,7 @@ public function unlinkAll($name, $delete = false) if (!empty($viaRelation->where)) { $condition = ['and', $condition, $viaRelation->where]; } - if (!empty($viaRelation->on)) { + if (property_exists($viaRelation, 'on') && !empty($viaRelation->on)) { $condition = ['and', $condition, $viaRelation->on]; } if (is_array($relation->via)) { @@ -1544,7 +1546,7 @@ public function unlinkAll($name, $delete = false) if (!empty($relation->where)) { $condition = ['and', $condition, $relation->where]; } - if (!empty($relation->on)) { + if (property_exists($relation, 'on') && !empty($relation->on)) { $condition = ['and', $condition, $relation->on]; } if ($delete) { @@ -1752,4 +1754,20 @@ private function setRelationDependencies($name, $relation, $viaRelationName = nu $this->setRelationDependencies($name, $viaQuery, $viaRelationName); } } + + /** + * @param string $attribute + * @param mixed $value + * @return bool + */ + private function isAttributeDirty($attribute, $value) + { + $old_attribute = $this->oldAttributes[$attribute]; + if (is_array($value) && is_array($this->oldAttributes[$attribute])) { + $value = ArrayHelper::recursiveSort($value); + $old_attribute = ArrayHelper::recursiveSort($old_attribute); + } + + return $value !== $old_attribute; + } } diff --git a/framework/db/BatchQueryResult.php b/framework/db/BatchQueryResult.php index c08b8745cfa..c45d3f1afb5 100644 --- a/framework/db/BatchQueryResult.php +++ b/framework/db/BatchQueryResult.php @@ -7,7 +7,7 @@ namespace yii\db; -use yii\base\BaseObject; +use yii\base\Component; /** * BatchQueryResult represents a batch query from which you can retrieve data in batches. @@ -28,10 +28,22 @@ * @author Qiang Xue * @since 2.0 */ -class BatchQueryResult extends BaseObject implements \Iterator +class BatchQueryResult extends Component implements \Iterator { /** - * @var Connection the DB connection to be used when performing batch query. + * @event Event an event that is triggered when the batch query is reset. + * @see reset() + * @since 2.0.41 + */ + const EVENT_RESET = 'reset'; + /** + * @event Event an event that is triggered when the last batch has been fetched. + * @since 2.0.41 + */ + const EVENT_FINISH = 'finish'; + + /** + * @var Connection|null the DB connection to be used when performing batch query. * If null, the "db" application component will be used. */ public $db; @@ -95,12 +107,14 @@ public function reset() $this->_batch = null; $this->_value = null; $this->_key = null; + $this->trigger(self::EVENT_RESET); } /** * Resets the iterator to the initial state. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function rewind() { $this->reset(); @@ -111,6 +125,7 @@ public function rewind() * Moves the internal pointer to the next dataset. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function next() { if ($this->_batch === null || !$this->each || $this->each && next($this->_batch) === false) { @@ -160,8 +175,14 @@ protected function getRows() $count = 0; try { - while ($count++ < $this->batchSize && ($row = $this->_dataReader->read())) { - $rows[] = $row; + while ($count++ < $this->batchSize) { + if ($row = $this->_dataReader->read()) { + $rows[] = $row; + } else { + // we've reached the end + $this->trigger(self::EVENT_FINISH); + break; + } } } catch (\PDOException $e) { $errorCode = isset($e->errorInfo[1]) ? $e->errorInfo[1] : null; @@ -178,6 +199,7 @@ protected function getRows() * This method is required by the interface [[\Iterator]]. * @return int the index of the current row. */ + #[\ReturnTypeWillChange] public function key() { return $this->_key; @@ -188,6 +210,7 @@ public function key() * This method is required by the interface [[\Iterator]]. * @return mixed the current dataset. */ + #[\ReturnTypeWillChange] public function current() { return $this->_value; @@ -198,6 +221,7 @@ public function current() * This method is required by the interface [[\Iterator]]. * @return bool whether there is a valid dataset at the current position. */ + #[\ReturnTypeWillChange] public function valid() { return !empty($this->_batch); @@ -227,7 +251,7 @@ private function getDbDriverName() /** * Unserialization is disabled to prevent remote code execution in case application * calls unserialize() on user input containing specially crafted string. - * @see CVE-2020-15148 + * @see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15148 * @since 2.0.38 */ public function __wakeup() diff --git a/framework/db/ColumnSchema.php b/framework/db/ColumnSchema.php index d392aba8c3d..5eb6b7b891b 100644 --- a/framework/db/ColumnSchema.php +++ b/framework/db/ColumnSchema.php @@ -154,6 +154,13 @@ protected function typecast($value) // ensure type cast always has . as decimal separator in all locales return StringHelper::floatToString($value); } + if (is_numeric($value) + && ColumnSchemaBuilder::CATEGORY_NUMERIC === ColumnSchemaBuilder::$typeCategoryMap[$this->type] + ) { + // https://github.com/yiisoft/yii2/issues/14663 + return $value; + } + return (string) $value; case 'integer': return (int) $value; diff --git a/framework/db/ColumnSchemaBuilder.php b/framework/db/ColumnSchemaBuilder.php index edb28efb5d1..b049c4b456d 100644 --- a/framework/db/ColumnSchemaBuilder.php +++ b/framework/db/ColumnSchemaBuilder.php @@ -16,6 +16,8 @@ * * See [[SchemaBuilderTrait]] for more detailed description and usage examples. * + * @property array $categoryMap Mapping of abstract column types (keys) to type categories (values). + * * @author Vasenin Matvey * @since 2.0.6 */ @@ -81,9 +83,9 @@ class ColumnSchemaBuilder extends BaseObject /** * @var array mapping of abstract column types (keys) to type categories (values). - * @since 2.0.8 + * @since 2.0.43 */ - public $categoryMap = [ + public static $typeCategoryMap = [ Schema::TYPE_PK => self::CATEGORY_PK, Schema::TYPE_UPK => self::CATEGORY_PK, Schema::TYPE_BIGPK => self::CATEGORY_PK, @@ -122,8 +124,8 @@ class ColumnSchemaBuilder extends BaseObject * Create a column schema builder instance giving the type and value precision. * * @param string $type type of the column. See [[$type]]. - * @param int|string|array $length length or precision of the column. See [[$length]]. - * @param \yii\db\Connection $db the current database connection. See [[$db]]. + * @param int|string|array|null $length length or precision of the column. See [[$length]]. + * @param \yii\db\Connection|null $db the current database connection. See [[$db]]. * @param array $config name-value pairs that will be used to initialize the object properties */ public function __construct($type, $length = null, $db = null, $config = []) @@ -289,6 +291,24 @@ public function __toString() return $this->buildCompleteString($format); } + /** + * @return array mapping of abstract column types (keys) to type categories (values). + * @since 2.0.43 + */ + public function getCategoryMap() + { + return static::$typeCategoryMap; + } + + /** + * @param array $categoryMap mapping of abstract column types (keys) to type categories (values). + * @since 2.0.43 + */ + public function setCategoryMap($categoryMap) + { + static::$typeCategoryMap = $categoryMap; + } + /** * Builds the length/precision part of the column. * @return string @@ -331,35 +351,46 @@ protected function buildUniqueString() } /** - * Builds the default value specification for the column. - * @return string string with default value of column. + * Return the default value for the column. + * @return string|null string with default value of column. */ - protected function buildDefaultString() + protected function buildDefaultValue() { if ($this->default === null) { - return $this->isNotNull === false ? ' DEFAULT NULL' : ''; + return $this->isNotNull === false ? 'NULL' : null; } - $string = ' DEFAULT '; switch (gettype($this->default)) { - case 'integer': - $string .= (string) $this->default; - break; case 'double': // ensure type cast always has . as decimal separator in all locales - $string .= StringHelper::floatToString($this->default); + $defaultValue = StringHelper::floatToString($this->default); break; case 'boolean': - $string .= $this->default ? 'TRUE' : 'FALSE'; + $defaultValue = $this->default ? 'TRUE' : 'FALSE'; break; + case 'integer': case 'object': - $string .= (string) $this->default; + $defaultValue = (string) $this->default; break; default: - $string .= "'{$this->default}'"; + $defaultValue = "'{$this->default}'"; + } + + return $defaultValue; + } + + /** + * Builds the default value specification for the column. + * @return string string with default value of column. + */ + protected function buildDefaultString() + { + $defaultValue = $this->buildDefaultValue(); + if ($defaultValue === null) { + return ''; } - return $string; + return ' DEFAULT ' . $defaultValue; } /** diff --git a/framework/db/Command.php b/framework/db/Command.php index 3d61e93a7e9..b99deb497b4 100644 --- a/framework/db/Command.php +++ b/framework/db/Command.php @@ -66,7 +66,7 @@ class Command extends Component public $pdoStatement; /** * @var int the default fetch mode for this command. - * @see https://secure.php.net/manual/en/pdostatement.setfetchmode.php + * @see https://www.php.net/manual/en/pdostatement.setfetchmode.php */ public $fetchMode = \PDO::FETCH_ASSOC; /** @@ -103,7 +103,7 @@ class Command extends Component */ private $_refreshTableName; /** - * @var string|false|null the isolation level to use for this transaction. + * @var string|null|false the isolation level to use for this transaction. * See [[Transaction::begin()]] for details. */ private $_isolationLevel = false; @@ -116,10 +116,10 @@ class Command extends Component /** * Enables query cache for this command. - * @param int $duration the number of seconds that query result of this command can remain valid in the cache. + * @param int|null $duration the number of seconds that query result of this command can remain valid in the cache. * If this is not set, the value of [[Connection::queryCacheDuration]] will be used instead. * Use 0 to indicate that the cached data will never expire. - * @param \yii\caching\Dependency $dependency the cache dependency associated with the cached query result. + * @param \yii\caching\Dependency|null $dependency the cache dependency associated with the cached query result. * @return $this the command object itself */ public function cache($duration = null, $dependency = null) @@ -218,7 +218,10 @@ public function getRawSql() } } if (!isset($params[1])) { - return strtr($this->_sql, $params); + return preg_replace_callback('#(:\w+)#', function($matches) use ($params) { + $m = $matches[1]; + return isset($params[$m]) ? $params[$m] : $m; + }, $this->_sql); } $sql = ''; foreach (explode('?', $this->_sql) as $i => $part) { @@ -234,7 +237,7 @@ public function getRawSql() * this may improve performance. * For SQL statement with binding parameters, this method is invoked * automatically. - * @param bool $forRead whether this method is called for a read query. If null, it means + * @param bool|null $forRead whether this method is called for a read query. If null, it means * the SQL statement should be used to determine whether it is for read or write. * @throws Exception if there is any DB error */ @@ -289,11 +292,11 @@ public function cancel() * the form `:name`. For a prepared statement using question mark * placeholders, this will be the 1-indexed position of the parameter. * @param mixed $value the PHP variable to bind to the SQL statement parameter (passed by reference) - * @param int $dataType SQL data type of the parameter. If null, the type is determined by the PHP type of the value. - * @param int $length length of the data type + * @param int|null $dataType SQL data type of the parameter. If null, the type is determined by the PHP type of the value. + * @param int|null $length length of the data type * @param mixed $driverOptions the driver-specific options * @return $this the current command being executed - * @see https://secure.php.net/manual/en/function.PDOStatement-bindParam.php + * @see https://www.php.net/manual/en/function.PDOStatement-bindParam.php */ public function bindParam($name, &$value, $dataType = null, $length = null, $driverOptions = null) { @@ -333,9 +336,9 @@ protected function bindPendingParams() * the form `:name`. For a prepared statement using question mark * placeholders, this will be the 1-indexed position of the parameter. * @param mixed $value The value to bind to the parameter - * @param int $dataType SQL data type of the parameter. If null, the type is determined by the PHP type of the value. + * @param int|null $dataType SQL data type of the parameter. If null, the type is determined by the PHP type of the value. * @return $this the current command being executed - * @see https://secure.php.net/manual/en/function.PDOStatement-bindValue.php + * @see https://www.php.net/manual/en/function.PDOStatement-bindValue.php */ public function bindValue($name, $value, $dataType = null) { @@ -396,7 +399,7 @@ public function query() /** * Executes the SQL statement and returns ALL rows at once. - * @param int $fetchMode the result fetch mode. Please refer to [PHP manual](https://secure.php.net/manual/en/function.PDOStatement-setFetchMode.php) + * @param int|null $fetchMode the result fetch mode. Please refer to [PHP manual](https://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) * for valid fetch modes. If this parameter is null, the value set in [[fetchMode]] will be used. * @return array all rows of the query result. Each array element is an array representing a row of data. * An empty array is returned if the query results in nothing. @@ -410,7 +413,7 @@ public function queryAll($fetchMode = null) /** * Executes the SQL statement and returns the first row of the result. * This method is best used when only the first row of result is needed for a query. - * @param int $fetchMode the result fetch mode. Please refer to [PHP manual](https://secure.php.net/manual/en/pdostatement.setfetchmode.php) + * @param int|null $fetchMode the result fetch mode. Please refer to [PHP manual](https://www.php.net/manual/en/pdostatement.setfetchmode.php) * for valid fetch modes. If this parameter is null, the value set in [[fetchMode]] will be used. * @return array|false the first row (in terms of an array) of the query result. False is returned if the query * results in nothing. @@ -424,7 +427,7 @@ public function queryOne($fetchMode = null) /** * Executes the SQL statement and returns the value of the first column in the first row of data. * This method is best used when only a single value is needed for a query. - * @return string|null|false the value of the first column in the first row of the query result. + * @return string|int|null|false the value of the first column in the first row of the query result. * False is returned if there is no value. * @throws Exception execution failed */ @@ -638,7 +641,7 @@ public function delete($table, $condition = '', $params = []) * * @param string $table the name of the table to be created. The name will be properly quoted by the method. * @param array $columns the columns (name => definition) in the new table. - * @param string $options additional SQL fragment that will be appended to the generated SQL. + * @param string|null $options additional SQL fragment that will be appended to the generated SQL. * @return $this the command object itself */ public function createTable($table, $columns, $options = null) @@ -690,7 +693,7 @@ public function truncateTable($table) * @param string $table the table that the new column will be added to. The table name will be properly quoted by the method. * @param string $column the name of the new column. The name will be properly quoted by the method. * @param string $type the column type. [[\yii\db\QueryBuilder::getColumnType()]] will be called - * to convert the give column type to the physical one. For example, `string` will be converted + * to convert the given column type to the physical one. For example, `string` will be converted * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. * @return $this the command object itself */ @@ -780,8 +783,8 @@ public function dropPrimaryKey($name, $table) * @param string|array $columns the name of the column to that the constraint will be added on. If there are multiple columns, separate them with commas. * @param string $refTable the table that the foreign key references to. * @param string|array $refColumns the name of the column that the foreign key references to. If there are multiple columns, separate them with commas. - * @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL - * @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL * @return $this the command object itself */ public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) @@ -1133,7 +1136,7 @@ protected function logQuery($category) /** * Performs the actual DB query of a SQL statement. * @param string $method method of PDOStatement to be called - * @param int $fetchMode the result fetch mode. Please refer to [PHP manual](https://secure.php.net/manual/en/function.PDOStatement-setFetchMode.php) + * @param int|null $fetchMode the result fetch mode. Please refer to [PHP manual](https://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) * for valid fetch modes. If this parameter is null, the value set in [[fetchMode]] will be used. * @return mixed the method execution result * @throws Exception if the query causes any problem @@ -1192,7 +1195,7 @@ protected function queryInternal($method, $fetchMode = null) * Returns the cache key for the query. * * @param string $method method of PDOStatement to be called - * @param int $fetchMode the result fetch mode. Please refer to [PHP manual](https://secure.php.net/manual/en/function.PDOStatement-setFetchMode.php) + * @param int $fetchMode the result fetch mode. Please refer to [PHP manual](https://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) * for valid fetch modes. * @return array the cache key * @since 2.0.16 diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 5e2bd45a79c..a6f81ff6581 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -15,11 +15,11 @@ use yii\caching\CacheInterface; /** - * Connection represents a connection to a database via [PDO](https://secure.php.net/manual/en/book.pdo.php). + * Connection represents a connection to a database via [PDO](https://www.php.net/manual/en/book.pdo.php). * * Connection works together with [[Command]], [[DataReader]] and [[Transaction]] * to provide data access to various DBMS in a common set of APIs. They are a thin wrapper - * of the [PDO PHP extension](https://secure.php.net/manual/en/book.pdo.php). + * of the [PDO PHP extension](https://www.php.net/manual/en/book.pdo.php). * * Connection supports database replication and read-write splitting. In particular, a Connection component * can be configured with multiple [[masters]] and [[slaves]]. It will do load balancing and failover by choosing @@ -111,24 +111,22 @@ * ``` * * @property string $driverName Name of the DB driver. - * @property-read bool $isActive Whether the DB connection is established. This property is read-only. + * @property-read bool $isActive Whether the DB connection is established. * @property-read string $lastInsertID The row ID of the last row inserted, or the last value retrieved from - * the sequence object. This property is read-only. + * the sequence object. * @property-read Connection $master The currently active master connection. `null` is returned if there is no - * master available. This property is read-only. - * @property-read PDO $masterPdo The PDO instance for the currently active master connection. This property is - * read-only. + * master available. + * @property-read PDO $masterPdo The PDO instance for the currently active master connection. * @property QueryBuilder $queryBuilder The query builder for the current DB connection. Note that the type of - * this property differs in getter and setter. See [[getQueryBuilder()]] and [[setQueryBuilder()]] for details. - * @property-read Schema $schema The schema information for the database opened by this connection. This - * property is read-only. - * @property-read string $serverVersion Server version as a string. This property is read-only. + * this property differs in getter and setter. See [[getQueryBuilder()]] and [[setQueryBuilder()]] for details. + * @property-read Schema $schema The schema information for the database opened by this connection. + * @property-read string $serverVersion Server version as a string. * @property-read Connection $slave The currently active slave connection. `null` is returned if there is no - * slave available and `$fallbackToMaster` is false. This property is read-only. + * slave available and `$fallbackToMaster` is false. * @property-read PDO $slavePdo The PDO instance for the currently active slave connection. `null` is returned - * if no slave connection is available and `$fallbackToMaster` is false. This property is read-only. + * if no slave connection is available and `$fallbackToMaster` is false. * @property-read Transaction|null $transaction The currently active transaction. Null if no active - * transaction. This property is read-only. + * transaction. * * @author Qiang Xue * @since 2.0 @@ -136,50 +134,50 @@ class Connection extends Component { /** - * @event yii\base\Event an event that is triggered after a DB connection is established + * @event \yii\base\Event an event that is triggered after a DB connection is established */ const EVENT_AFTER_OPEN = 'afterOpen'; /** - * @event yii\base\Event an event that is triggered right before a top-level transaction is started + * @event \yii\base\Event an event that is triggered right before a top-level transaction is started */ const EVENT_BEGIN_TRANSACTION = 'beginTransaction'; /** - * @event yii\base\Event an event that is triggered right after a top-level transaction is committed + * @event \yii\base\Event an event that is triggered right after a top-level transaction is committed */ const EVENT_COMMIT_TRANSACTION = 'commitTransaction'; /** - * @event yii\base\Event an event that is triggered right after a top-level transaction is rolled back + * @event \yii\base\Event an event that is triggered right after a top-level transaction is rolled back */ const EVENT_ROLLBACK_TRANSACTION = 'rollbackTransaction'; /** * @var string the Data Source Name, or DSN, contains the information required to connect to the database. - * Please refer to the [PHP manual](https://secure.php.net/manual/en/pdo.construct.php) on + * Please refer to the [PHP manual](https://www.php.net/manual/en/pdo.construct.php) on * the format of the DSN string. * - * For [SQLite](https://secure.php.net/manual/en/ref.pdo-sqlite.connection.php) you may use a [path alias](guide:concept-aliases) + * For [SQLite](https://www.php.net/manual/en/ref.pdo-sqlite.connection.php) you may use a [path alias](guide:concept-aliases) * for specifying the database path, e.g. `sqlite:@app/data/db.sql`. * * @see charset */ public $dsn; /** - * @var string the username for establishing DB connection. Defaults to `null` meaning no username to use. + * @var string|null the username for establishing DB connection. Defaults to `null` meaning no username to use. */ public $username; /** - * @var string the password for establishing DB connection. Defaults to `null` meaning no password to use. + * @var string|null the password for establishing DB connection. Defaults to `null` meaning no password to use. */ public $password; /** * @var array PDO attributes (name => value) that should be set when calling [[open()]] * to establish a DB connection. Please refer to the - * [PHP manual](https://secure.php.net/manual/en/pdo.setattribute.php) for + * [PHP manual](https://www.php.net/manual/en/pdo.setattribute.php) for * details about available attributes. */ public $attributes; /** - * @var PDO the PHP PDO instance associated with this DB connection. + * @var PDO|null the PHP PDO instance associated with this DB connection. * This property is mainly managed by [[open()]] and [[close()]] methods. * When a DB connection is active, this property will represent a PDO instance; * otherwise, it will be null. @@ -238,7 +236,7 @@ class Connection extends Component */ public $queryCache = 'cache'; /** - * @var string the charset used for database connection. The property is only used + * @var string|null the charset used for database connection. The property is only used * for MySQL, PostgreSQL and CUBRID databases. Defaults to null, meaning using default charset * as configured by the database. * @@ -250,7 +248,7 @@ class Connection extends Component */ public $charset; /** - * @var bool whether to turn on prepare emulation. Defaults to false, meaning PDO + * @var bool|null whether to turn on prepare emulation. Defaults to false, meaning PDO * will use the native prepare support if available. For some databases (such as MySQL), * this may need to be set true so that PDO can emulate the prepare support to bypass * the buggy native prepare support. @@ -286,7 +284,7 @@ class Connection extends Component 'cubrid' => 'yii\db\cubrid\Schema', // CUBRID ]; /** - * @var string Custom PDO wrapper class. If not set, it will use [[PDO]] or [[\yii\db\mssql\PDO]] when MSSQL is used. + * @var string|null Custom PDO wrapper class. If not set, it will use [[PDO]] or [[\yii\db\mssql\PDO]] when MSSQL is used. * @see pdo */ public $pdoClass; @@ -424,6 +422,13 @@ class Connection extends Component */ public $isSybase = false; + /** + * @var array An array of [[setQueryBuilder()]] calls, holding the passed arguments. + * Is used to restore a QueryBuilder configuration after the connection close/open cycle. + * + * @see restoreQueryBuilderConfiguration() + */ + private $_queryBuilderConfigurations = []; /** * @var Transaction the currently active transaction */ @@ -487,12 +492,12 @@ public function getIsActive() * * @param callable $callable a PHP callable that contains DB queries which will make use of query cache. * The signature of the callable is `function (Connection $db)`. - * @param int $duration the number of seconds that query results can remain valid in the cache. If this is + * @param int|null $duration the number of seconds that query results can remain valid in the cache. If this is * not set, the value of [[queryCacheDuration]] will be used instead. * Use 0 to indicate that the cached data will never expire. - * @param \yii\caching\Dependency $dependency the cache dependency associated with the cached query results. + * @param \yii\caching\Dependency|null $dependency the cache dependency associated with the cached query results. * @return mixed the return result of the callable - * @throws \Exception|\Throwable if there is any exception during query + * @throws \Throwable if there is any exception during query * @see enableQueryCache * @see queryCache * @see noCache() @@ -533,7 +538,7 @@ public function cache(callable $callable, $duration = null, $dependency = null) * @param callable $callable a PHP callable that contains DB queries which should not use query cache. * The signature of the callable is `function (Connection $db)`. * @return mixed the return result of the callable - * @throws \Exception|\Throwable if there is any exception during query + * @throws \Throwable if there is any exception during query * @see enableQueryCache * @see queryCache * @see cache() @@ -557,9 +562,9 @@ public function noCache(callable $callable) /** * Returns the current query cache information. * This method is used internally by [[Command]]. - * @param int $duration the preferred caching duration. If null, it will be ignored. - * @param \yii\caching\Dependency $dependency the preferred caching dependency. If null, it will be ignored. - * @return array the current query cache information, or null if query cache is not enabled. + * @param int|null $duration the preferred caching duration. If null, it will be ignored. + * @param \yii\caching\Dependency|null $dependency the preferred caching dependency. If null, it will be ignored. + * @return array|null the current query cache information, or null if query cache is not enabled. * @internal */ public function getQueryCacheInfo($duration, $dependency) @@ -687,18 +692,24 @@ protected function createPdoInstance() { $pdoClass = $this->pdoClass; if ($pdoClass === null) { - $pdoClass = 'PDO'; + $driver = null; if ($this->_driverName !== null) { $driver = $this->_driverName; } elseif (($pos = strpos($this->dsn, ':')) !== false) { $driver = strtolower(substr($this->dsn, 0, $pos)); } - if (isset($driver)) { - if ($driver === 'mssql' || $driver === 'dblib') { + switch ($driver) { + case 'mssql': $pdoClass = 'yii\db\mssql\PDO'; - } elseif ($driver === 'sqlsrv') { + break; + case 'dblib': + $pdoClass = 'yii\db\mssql\DBLibPDO'; + break; + case 'sqlsrv': $pdoClass = 'yii\db\mssql\SqlsrvPDO'; - } + break; + default: + $pdoClass = 'PDO'; } } @@ -725,6 +736,11 @@ protected function initConnection() $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->emulatePrepare); } } + + if (PHP_VERSION_ID >= 80100 && $this->getDriverName() === 'sqlite') { + $this->pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); + } + if (!$this->isSybase && in_array($this->getDriverName(), ['mssql', 'dblib'], true)) { $this->pdo->exec('SET ANSI_NULL_DFLT_ON ON'); } @@ -736,7 +752,7 @@ protected function initConnection() /** * Creates a command for execution. - * @param string $sql the SQL statement to be executed + * @param string|null $sql the SQL statement to be executed * @param array $params the parameters to be bound to the SQL statement * @return Command the DB command */ @@ -789,7 +805,7 @@ public function beginTransaction($isolationLevel = null) * @param callable $callback a valid PHP callback that performs the job. Accepts connection instance as parameter. * @param string|null $isolationLevel The isolation level to use for this transaction. * See [[Transaction::begin()]] for details. - * @throws \Exception|\Throwable if there is any exception during query. In this case the transaction will be rolled back. + * @throws \Throwable if there is any exception during query. In this case the transaction will be rolled back. * @return mixed result of callback function */ public function transaction(callable $callback, $isolationLevel = null) @@ -849,7 +865,10 @@ public function getSchema() $config = !is_array($this->schemaMap[$driver]) ? ['class' => $this->schemaMap[$driver]] : $this->schemaMap[$driver]; $config['db'] = $this; - return $this->_schema = Yii::createObject($config); + $this->_schema = Yii::createObject($config); + $this->restoreQueryBuilderConfiguration(); + + return $this->_schema; } throw new NotSupportedException("Connection does not support reading schema information for '$driver' DBMS."); @@ -873,13 +892,30 @@ public function getQueryBuilder() public function setQueryBuilder($value) { Yii::configure($this->getQueryBuilder(), $value); + $this->_queryBuilderConfigurations[] = $value; + } + + /** + * Restores custom QueryBuilder configuration after the connection close/open cycle + */ + private function restoreQueryBuilderConfiguration() + { + if ($this->_queryBuilderConfigurations === []) { + return; + } + + $queryBuilderConfigurations = $this->_queryBuilderConfigurations; + $this->_queryBuilderConfigurations = []; + foreach ($queryBuilderConfigurations as $queryBuilderConfiguration) { + $this->setQueryBuilder($queryBuilderConfiguration); + } } /** * Obtains the schema information for the named table. * @param string $name table name. * @param bool $refresh whether to reload the table schema even if it is found in the cache. - * @return TableSchema table schema information. Null if the named table does not exist. + * @return TableSchema|null table schema information. Null if the named table does not exist. */ public function getTableSchema($name, $refresh = false) { @@ -890,7 +926,7 @@ public function getTableSchema($name, $refresh = false) * Returns the ID of the last inserted row or sequence value. * @param string $sequenceName name of the sequence object (required by some DBMS) * @return string the row ID of the last row inserted, or the last value retrieved from the sequence object - * @see https://secure.php.net/manual/en/pdo.lastinsertid.php + * @see https://www.php.net/manual/en/pdo.lastinsertid.php */ public function getLastInsertID($sequenceName = '') { @@ -902,7 +938,7 @@ public function getLastInsertID($sequenceName = '') * Note that if the parameter is not a string, it will be returned without change. * @param string $value string to be quoted * @return string the properly quoted string - * @see https://secure.php.net/manual/en/pdo.quote.php + * @see https://www.php.net/manual/en/pdo.quote.php */ public function quoteValue($value) { @@ -968,12 +1004,12 @@ function ($matches) { /** * Returns the name of the DB driver. Based on the the current [[dsn]], in case it was not set explicitly * by an end user. - * @return string name of the DB driver + * @return string|null name of the DB driver */ public function getDriverName() { if ($this->_driverName === null) { - if (($pos = strpos($this->dsn, ':')) !== false) { + if (($pos = strpos((string)$this->dsn, ':')) !== false) { $this->_driverName = strtolower(substr($this->dsn, 0, $pos)); } else { $this->_driverName = strtolower($this->getSlavePdo()->getAttribute(PDO::ATTR_DRIVER_NAME)); @@ -1007,7 +1043,7 @@ public function getServerVersion() * When [[enableSlaves]] is true, one of the slaves will be used for read queries, and its PDO instance * will be returned by this method. * @param bool $fallbackToMaster whether to return a master PDO in case none of the slave connections is available. - * @return PDO the PDO instance for the currently active slave connection. `null` is returned if no slave connection + * @return PDO|null the PDO instance for the currently active slave connection. `null` is returned if no slave connection * is available and `$fallbackToMaster` is false. */ public function getSlavePdo($fallbackToMaster = true) @@ -1035,7 +1071,7 @@ public function getMasterPdo() * Returns the currently active slave connection. * If this method is called for the first time, it will try to open a slave connection when [[enableSlaves]] is true. * @param bool $fallbackToMaster whether to return a master connection in case there is no slave connection available. - * @return Connection the currently active slave connection. `null` is returned if there is no slave available and + * @return Connection|null the currently active slave connection. `null` is returned if there is no slave available and * `$fallbackToMaster` is false. */ public function getSlave($fallbackToMaster = true) @@ -1054,7 +1090,7 @@ public function getSlave($fallbackToMaster = true) /** * Returns the currently active master connection. * If this method is called for the first time, it will try to open a master connection. - * @return Connection the currently active master connection. `null` is returned if there is no master available. + * @return Connection|null the currently active master connection. `null` is returned if there is no master available. * @since 2.0.11 */ public function getMaster() @@ -1083,7 +1119,7 @@ public function getMaster() * @param callable $callback a PHP callable to be executed by this method. Its signature is * `function (Connection $db)`. Its return value will be returned by this method. * @return mixed the return value of the callback - * @throws \Exception|\Throwable if there is any exception thrown from the callback + * @throws \Throwable if there is any exception thrown from the callback */ public function useMaster(callable $callback) { @@ -1116,7 +1152,7 @@ public function useMaster(callable $callback) * * @param array $pool the list of connection configurations in the server pool * @param array $sharedConfig the configuration common to those given in `$pool`. - * @return Connection the opened DB connection, or `null` if no server is available + * @return Connection|null the opened DB connection, or `null` if no server is available * @throws InvalidConfigException if a configuration does not specify "dsn" * @see openFromPoolSequentially */ @@ -1139,11 +1175,11 @@ protected function openFromPool(array $pool, array $sharedConfig) * * If none of the servers are available the status cache is ignored and connection attempts are made to all * servers (Since version 2.0.35). This is to avoid downtime when all servers are unavailable for a short time. - * After a successful connection attempt the server is marked as avaiable again. + * After a successful connection attempt the server is marked as available again. * * @param array $pool the list of connection configurations in the server pool * @param array $sharedConfig the configuration common to those given in `$pool`. - * @return Connection the opened DB connection, or `null` if no server is available + * @return Connection|null the opened DB connection, or `null` if no server is available * @throws InvalidConfigException if a configuration does not specify "dsn" * @since 2.0.11 * @see openFromPool diff --git a/framework/db/DataReader.php b/framework/db/DataReader.php index 50a2d7dadc3..35548c3bbc8 100644 --- a/framework/db/DataReader.php +++ b/framework/db/DataReader.php @@ -37,13 +37,13 @@ * Doing it the second time will throw an exception. * * It is possible to use a specific mode of data fetching by setting - * [[fetchMode]]. See the [PHP manual](https://secure.php.net/manual/en/function.PDOStatement-setFetchMode.php) + * [[fetchMode]]. See the [PHP manual](https://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) * for more details about possible fetch mode. * - * @property-read int $columnCount The number of columns in the result set. This property is read-only. - * @property-write int $fetchMode Fetch mode. This property is write-only. - * @property-read bool $isClosed Whether the reader is closed or not. This property is read-only. - * @property-read int $rowCount Number of rows contained in the result. This property is read-only. + * @property-read int $columnCount The number of columns in the result set. + * @property-write int $fetchMode Fetch mode. + * @property-read bool $isClosed Whether the reader is closed or not. + * @property-read int $rowCount Number of rows contained in the result. * * @author Qiang Xue * @since 2.0 @@ -79,8 +79,8 @@ public function __construct(Command $command, $config = []) * in the result set. If using the column name, be aware that the name * should match the case of the column, as returned by the driver. * @param mixed $value Name of the PHP variable to which the column will be bound. - * @param int $dataType Data type of the parameter - * @see https://secure.php.net/manual/en/function.PDOStatement-bindColumn.php + * @param int|null $dataType Data type of the parameter + * @see https://www.php.net/manual/en/function.PDOStatement-bindColumn.php */ public function bindColumn($column, &$value, $dataType = null) { @@ -95,7 +95,7 @@ public function bindColumn($column, &$value, $dataType = null) * Set the default fetch mode for this statement. * * @param int $mode fetch mode - * @see https://secure.php.net/manual/en/function.PDOStatement-setFetchMode.php + * @see https://www.php.net/manual/en/function.PDOStatement-setFetchMode.php */ public function setFetchMode($mode) { @@ -196,6 +196,7 @@ public function getRowCount() * In this case, use "SELECT COUNT(*) FROM tableName" to obtain the number of rows. * @return int number of rows contained in the result. */ + #[\ReturnTypeWillChange] public function count() { return $this->getRowCount(); @@ -216,6 +217,7 @@ public function getColumnCount() * This method is required by the interface [[\Iterator]]. * @throws InvalidCallException if this method is invoked twice */ + #[\ReturnTypeWillChange] public function rewind() { if ($this->_index < 0) { @@ -231,6 +233,7 @@ public function rewind() * This method is required by the interface [[\Iterator]]. * @return int the index of the current row. */ + #[\ReturnTypeWillChange] public function key() { return $this->_index; @@ -241,6 +244,7 @@ public function key() * This method is required by the interface [[\Iterator]]. * @return mixed the current row. */ + #[\ReturnTypeWillChange] public function current() { return $this->_row; @@ -250,6 +254,7 @@ public function current() * Moves the internal pointer to the next row. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function next() { $this->_row = $this->_statement->fetch(); @@ -261,6 +266,7 @@ public function next() * This method is required by the interface [[\Iterator]]. * @return bool whether there is a row of data at current position. */ + #[\ReturnTypeWillChange] public function valid() { return $this->_row !== false; diff --git a/framework/db/Exception.php b/framework/db/Exception.php index ae16407f85d..674e26b75c0 100644 --- a/framework/db/Exception.php +++ b/framework/db/Exception.php @@ -17,7 +17,7 @@ class Exception extends \yii\base\Exception { /** * @var array the error info provided by a PDO exception. This is the same as returned - * by [PDO::errorInfo](https://secure.php.net/manual/en/pdo.errorinfo.php). + * by [PDO::errorInfo](https://www.php.net/manual/en/pdo.errorinfo.php). */ public $errorInfo = []; @@ -27,7 +27,7 @@ class Exception extends \yii\base\Exception * @param string $message PDO error message * @param array $errorInfo PDO error info * @param string $code PDO error code - * @param \Throwable|\Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ public function __construct($message, $errorInfo = [], $code = '', $previous = null) { diff --git a/framework/db/JsonExpression.php b/framework/db/JsonExpression.php index 0446ae87cc2..52366ae78ad 100644 --- a/framework/db/JsonExpression.php +++ b/framework/db/JsonExpression.php @@ -69,7 +69,7 @@ public function getValue() } /** - * @return null|string the type of JSON + * @return string|null the type of JSON * @see type */ public function getType() @@ -80,12 +80,13 @@ public function getType() /** * Specify data which should be serialized to JSON * - * @link https://secure.php.net/manual/en/jsonserializable.jsonserialize.php + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 2.0.14.2 * @throws InvalidConfigException when JsonExpression contains QueryInterface object */ + #[\ReturnTypeWillChange] public function jsonSerialize() { $value = $this->getValue(); diff --git a/framework/db/Migration.php b/framework/db/Migration.php index a144d4a43f4..2094800207d 100644 --- a/framework/db/Migration.php +++ b/framework/db/Migration.php @@ -104,7 +104,7 @@ protected function getDb() /** * This method contains the logic to be executed when applying this migration. * Child classes may override this method to provide actual migration logic. - * @return bool return a false value to indicate the migration fails + * @return false|void|mixed return a false value to indicate the migration fails * and should not proceed further. All other return values mean the migration succeeds. */ public function up() @@ -133,7 +133,7 @@ public function up() * This method contains the logic to be executed when removing this migration. * The default implementation throws an exception indicating the migration cannot be removed. * Child classes may override this method if the corresponding migrations can be removed. - * @return bool return a false value to indicate the migration fails + * @return false|void|mixed return a false value to indicate the migration fails * and should not proceed further. All other return values mean the migration succeeds. */ public function down() @@ -159,7 +159,7 @@ public function down() } /** - * @param \Throwable|\Exception $e + * @param \Throwable $e */ private function printException($e) { @@ -177,7 +177,7 @@ private function printException($e) * Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples, * please refer to [implicit commit](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). * - * @return bool return a false value to indicate the migration fails + * @return false|void|mixed return a false value to indicate the migration fails * and should not proceed further. All other return values mean the migration succeeds. */ public function safeUp() @@ -194,7 +194,7 @@ public function safeUp() * Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples, * please refer to [implicit commit](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). * - * @return bool return a false value to indicate the migration fails + * @return false|void|mixed return a false value to indicate the migration fails * and should not proceed further. All other return values mean the migration succeeds. */ public function safeDown() @@ -261,7 +261,6 @@ public function batchInsert($table, $columns, $rows) * If `true` is passed, the column data will be updated to match the insert column data. * If `false` is passed, no update will be performed if the column data already exists. * @param array $params the parameters to be bound to the command. - * @return $this the command object itself. * @since 2.0.14 */ public function upsert($table, $insertColumns, $updateColumns = true, $params = []) @@ -315,7 +314,7 @@ public function delete($table, $condition = '', $params = []) * * @param string $table the name of the table to be created. The name will be properly quoted by the method. * @param array $columns the columns (name => definition) in the new table. - * @param string $options additional SQL fragment that will be appended to the generated SQL. + * @param string|null $options additional SQL fragment that will be appended to the generated SQL. */ public function createTable($table, $columns, $options = null) { @@ -458,8 +457,8 @@ public function dropPrimaryKey($name, $table) * @param string|array $columns the name of the column to that the constraint will be added on. If there are multiple columns, separate them with commas or use an array. * @param string $refTable the table that the foreign key references to. * @param string|array $refColumns the name of the column that the foreign key references to. If there are multiple columns, separate them with commas or use an array. - * @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL - * @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL */ public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) { diff --git a/framework/db/PdoValue.php b/framework/db/PdoValue.php index 806eaa3bf31..3a0ce6f689c 100644 --- a/framework/db/PdoValue.php +++ b/framework/db/PdoValue.php @@ -16,9 +16,9 @@ * [':name' => 'John', ':profile' => new PdoValue($profile, \PDO::PARAM_LOB)]`. * ``` * - * To see possible types, check [PDO::PARAM_* constants](https://secure.php.net/manual/en/pdo.constants.php). + * To see possible types, check [PDO::PARAM_* constants](https://www.php.net/manual/en/pdo.constants.php). * - * @see https://secure.php.net/manual/en/pdostatement.bindparam.php + * @see https://www.php.net/manual/en/pdostatement.bindparam.php * @author Dmytro Naumenko * @since 2.0.14 */ @@ -30,7 +30,7 @@ final class PdoValue implements ExpressionInterface private $value; /** * @var int One of PDO_PARAM_* constants - * @see https://secure.php.net/manual/en/pdo.constants.php + * @see https://www.php.net/manual/en/pdo.constants.php */ private $type; diff --git a/framework/db/Query.php b/framework/db/Query.php index 59dcb8382aa..913e601ec7d 100644 --- a/framework/db/Query.php +++ b/framework/db/Query.php @@ -42,7 +42,7 @@ * * A more detailed usage guide on how to work with Query can be found in the [guide article on Query Builder](guide:db-query-builder). * - * @property-read string[] $tablesUsedInFrom Table names indexed by aliases. This property is read-only. + * @property-read string[] $tablesUsedInFrom Table names indexed by aliases. * * @author Qiang Xue * @author Carsten Brandt @@ -53,13 +53,13 @@ class Query extends Component implements QueryInterface, ExpressionInterface use QueryTrait; /** - * @var array the columns being selected. For example, `['id', 'name']`. + * @var array|null the columns being selected. For example, `['id', 'name']`. * This is used to construct the SELECT clause in a SQL statement. If not set, it means selecting all columns. * @see select() */ public $select; /** - * @var string additional option that should be appended to the 'SELECT' keyword. For example, + * @var string|null additional option that should be appended to the 'SELECT' keyword. For example, * in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used. */ public $selectOption; @@ -67,20 +67,20 @@ class Query extends Component implements QueryInterface, ExpressionInterface * @var bool whether to select distinct rows of data only. If this is set true, * the SELECT clause would be changed to SELECT DISTINCT. */ - public $distinct; + public $distinct = false; /** - * @var array the table(s) to be selected from. For example, `['user', 'post']`. + * @var array|null the table(s) to be selected from. For example, `['user', 'post']`. * This is used to construct the FROM clause in a SQL statement. * @see from() */ public $from; /** - * @var array how to group the query results. For example, `['company', 'department']`. + * @var array|null how to group the query results. For example, `['company', 'department']`. * This is used to construct the GROUP BY clause in a SQL statement. */ public $groupBy; /** - * @var array how to join with other tables. Each array element represents the specification + * @var array|null how to join with other tables. Each array element represents the specification * of one join which has the following structure: * * ```php @@ -98,12 +98,12 @@ class Query extends Component implements QueryInterface, ExpressionInterface */ public $join; /** - * @var string|array|ExpressionInterface the condition to be applied in the GROUP BY clause. + * @var string|array|ExpressionInterface|null the condition to be applied in the GROUP BY clause. * It can be either a string or an array. Please refer to [[where()]] on how to specify the condition. */ public $having; /** - * @var array this is used to construct the UNION clause(s) in a SQL statement. + * @var array|null this is used to construct the UNION clause(s) in a SQL statement. * Each array element is an array of the following structure: * * - `query`: either a string or a [[Query]] object representing a query @@ -111,7 +111,7 @@ class Query extends Component implements QueryInterface, ExpressionInterface */ public $union; /** - * @var array this is used to construct the WITH section in a SQL query. + * @var array|null this is used to construct the WITH section in a SQL query. * Each array element is an array of the following structure: * * - `query`: either a string or a [[Query]] object representing a query @@ -122,12 +122,12 @@ class Query extends Component implements QueryInterface, ExpressionInterface */ public $withQueries; /** - * @var array list of query parameter values indexed by parameter placeholders. + * @var array|null list of query parameter values indexed by parameter placeholders. * For example, `[':name' => 'Dan', ':age' => 31]`. */ public $params = []; /** - * @var int|true the default number of seconds that query results can remain valid in cache. + * @var int|bool|null the default number of seconds that query results can remain valid in cache. * Use 0 to indicate that the cached data will never expire. * Use a negative number to indicate that query cache should not be used. * Use boolean `true` to indicate that [[Connection::queryCacheDuration]] should be used. @@ -136,7 +136,7 @@ class Query extends Component implements QueryInterface, ExpressionInterface */ public $queryCacheDuration; /** - * @var \yii\caching\Dependency the dependency to be associated with the cached query result for this query + * @var \yii\caching\Dependency|null the dependency to be associated with the cached query result for this query * @see cache() * @since 2.0.14 */ @@ -145,7 +145,7 @@ class Query extends Component implements QueryInterface, ExpressionInterface /** * Creates a DB command that can be used to execute this query. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return Command the created DB command instance. */ @@ -191,7 +191,7 @@ public function prepare($builder) * ``` * * @param int $batchSize the number of records to be fetched in each batch. - * @param Connection $db the database connection. If not set, the "db" application component will be used. + * @param Connection|null $db the database connection. If not set, the "db" application component will be used. * @return BatchQueryResult the batch query result. It implements the [[\Iterator]] interface * and can be traversed to retrieve the data in batches. */ @@ -219,7 +219,7 @@ public function batch($batchSize = 100, $db = null) * ``` * * @param int $batchSize the number of records to be fetched in each batch. - * @param Connection $db the database connection. If not set, the "db" application component will be used. + * @param Connection|null $db the database connection. If not set, the "db" application component will be used. * @return BatchQueryResult the batch query result. It implements the [[\Iterator]] interface * and can be traversed to retrieve the data in batches. */ @@ -236,7 +236,7 @@ public function each($batchSize = 100, $db = null) /** * Executes the query and returns all results as an array. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return array the query results. If the query results in nothing, an empty array will be returned. */ @@ -245,7 +245,9 @@ public function all($db = null) if ($this->emulateExecution) { return []; } + $rows = $this->createCommand($db)->queryAll(); + return $this->populate($rows); } @@ -271,7 +273,7 @@ public function populate($rows) /** * Executes the query and returns a single row of result. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return array|bool the first row (in terms of an array) of the query result. False is returned if the query * results in nothing. @@ -288,9 +290,9 @@ public function one($db = null) /** * Returns the query result as a scalar value. * The value returned will be the first column in the first row of the query results. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. - * @return string|null|false the value of the first column in the first row of the query result. + * @return string|int|null|false the value of the first column in the first row of the query result. * False is returned if the query result is empty. */ public function scalar($db = null) @@ -304,7 +306,7 @@ public function scalar($db = null) /** * Executes the query and returns the first column of the result. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return array the first column of the query result. An empty array is returned if the query results in nothing. */ @@ -352,9 +354,9 @@ public function column($db = null) * Returns the number of records. * @param string $q the COUNT expression. Defaults to '*'. * Make sure you properly [quote](guide:db-dao#quoting-table-and-column-names) column names in the expression. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given (or null), the `db` application component will be used. - * @return int|string number of records. The result may be a string depending on the + * @return int|string|null number of records. The result may be a string depending on the * underlying database engine and to support integer values higher than a 32bit PHP integer can handle. */ public function count($q = '*', $db = null) @@ -370,7 +372,7 @@ public function count($q = '*', $db = null) * Returns the sum of the specified column values. * @param string $q the column name or expression. * Make sure you properly [quote](guide:db-dao#quoting-table-and-column-names) column names in the expression. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return mixed the sum of the specified column values. */ @@ -387,7 +389,7 @@ public function sum($q, $db = null) * Returns the average of the specified column values. * @param string $q the column name or expression. * Make sure you properly [quote](guide:db-dao#quoting-table-and-column-names) column names in the expression. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return mixed the average of the specified column values. */ @@ -404,7 +406,7 @@ public function average($q, $db = null) * Returns the minimum of the specified column values. * @param string $q the column name or expression. * Make sure you properly [quote](guide:db-dao#quoting-table-and-column-names) column names in the expression. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return mixed the minimum of the specified column values. */ @@ -417,7 +419,7 @@ public function min($q, $db = null) * Returns the maximum of the specified column values. * @param string $q the column name or expression. * Make sure you properly [quote](guide:db-dao#quoting-table-and-column-names) column names in the expression. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return mixed the maximum of the specified column values. */ @@ -428,7 +430,7 @@ public function max($q, $db = null) /** * Returns a value indicating whether the query result contains any row of data. - * @param Connection $db the database connection used to generate the SQL statement. + * @param Connection|null $db the database connection used to generate the SQL statement. * If this parameter is not given, the `db` application component will be used. * @return bool whether the query result contains any row of data. */ @@ -448,8 +450,9 @@ public function exists($db = null) * Queries a scalar value by setting [[select]] first. * Restores the value of select to make this query reusable. * @param string|ExpressionInterface $selectExpression - * @param Connection|null $db - * @return bool|string + * @param Connection|null $db the database connection used to execute the query. + * @return bool|string|null + * @throws \Throwable if can't create command */ protected function queryScalar($selectExpression, $db) { @@ -477,7 +480,7 @@ protected function queryScalar($selectExpression, $db) try { $command = $this->createCommand($db); } catch (\Exception $e) { - // throw it later + // throw it later (for PHP < 7.0) } catch (\Throwable $e) { // throw it later } @@ -630,7 +633,7 @@ private function ensureNameQuoted($name) * Starting from version 2.0.1, you may also select sub-queries as columns by specifying each such column * as a `Query` instance representing the sub-query. * - * @param string $option additional option that should be appended to the 'SELECT' keyword. For example, + * @param string|null $option additional option that should be appended to the 'SELECT' keyword. For example, * in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used. * @return $this the query object itself */ @@ -681,7 +684,7 @@ protected function normalizeSelect($columns) if ($columns instanceof ExpressionInterface) { $columns = [$columns]; } elseif (!is_array($columns)) { - $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY); + $columns = preg_split('/\s*,\s*/', trim((string)$columns), -1, PREG_SPLIT_NO_EMPTY); } $select = []; foreach ($columns as $columnAlias => $columnDefinition) { @@ -918,7 +921,7 @@ public function orWhere($condition, $params = []) */ public function andFilterCompare($name, $value, $defaultOperator = '=') { - if (preg_match('/^(<>|>=|>|<=|<|=)/', $value, $matches)) { + if (preg_match('/^(<>|>=|>|<=|<|=)/', (string)$value, $matches)) { $operator = $matches[1]; $value = substr($value, strlen($operator)); } else { @@ -1321,7 +1324,7 @@ public function addParams($params) * Use a negative number to indicate that query cache should not be used. * Use boolean `true` to indicate that [[Connection::queryCacheDuration]] should be used. * Defaults to `true`. - * @param \yii\caching\Dependency $dependency the cache dependency associated with the cached result. + * @param \yii\caching\Dependency|null $dependency the cache dependency associated with the cached result. * @return $this the Query object itself * @since 2.0.14 */ diff --git a/framework/db/QueryBuilder.php b/framework/db/QueryBuilder.php index c6f74872313..3e8e8756105 100644 --- a/framework/db/QueryBuilder.php +++ b/framework/db/QueryBuilder.php @@ -23,9 +23,9 @@ * For more details and usage information on QueryBuilder, see the [guide article on query builders](guide:db-query-builder). * * @property-write string[] $conditionClasses Map of condition aliases to condition classes. For example: - * ```php ['LIKE' => yii\db\condition\LikeCondition::class] ``` . This property is write-only. + * ```php ['LIKE' => yii\db\condition\LikeCondition::class] ``` . * @property-write string[] $expressionBuilders Array of builders that should be merged with the pre-defined - * ones in [[expressionBuilders]] property. This property is write-only. + * ones in [[expressionBuilders]] property. * * @author Qiang Xue * @since 2.0 @@ -73,7 +73,7 @@ class QueryBuilder extends \yii\base\BaseObject * * In case you want to add custom conditions support, use the [[setConditionClasses()]] method. * - * @see setConditonClasses() + * @see setConditionClasses() * @see defaultConditionClasses() * @since 2.0.14 */ @@ -159,7 +159,7 @@ protected function defaultConditionClasses() * default expression builders for this query builder. See [[expressionBuilders]] docs for details. * * @return array - * @see $expressionBuilders + * @see expressionBuilders * @since 2.0.14 */ protected function defaultExpressionBuilders() @@ -710,7 +710,7 @@ public function delete($table, $condition, &$params) * * @param string $table the name of the table to be created. The name will be properly quoted by the method. * @param array $columns the columns (name => definition) in the new table. - * @param string $options additional SQL fragment that will be appended to the generated SQL. + * @param string|null $options additional SQL fragment that will be appended to the generated SQL. * @return string the SQL statement for creating a new DB table. */ public function createTable($table, $columns, $options = null) @@ -863,8 +863,8 @@ public function alterColumn($table, $column, $type) * @param string $refTable the table that the foreign key references to. * @param string|array $refColumns the name of the column that the foreign key references to. * If there are multiple columns, separate them with commas or use an array to represent them. - * @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL - * @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL * @return string the SQL statement for adding a foreign key constraint to an existing table. */ public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) @@ -1035,7 +1035,7 @@ public function dropDefaultValue($name, $table) * The sequence will be reset such that the primary key of the next new row inserted * will have the specified value or the maximum existing value +1. * @param string $table the name of the table whose primary key sequence will be reset - * @param array|string $value the value for the primary key of the next new row inserted. If this is not set, + * @param array|string|null $value the value for the primary key of the next new row inserted. If this is not set, * the next new row's primary key will have the maximum existing value +1. * @return string the SQL statement for resetting sequence * @throws NotSupportedException if this is not supported by the underlying DBMS @@ -1051,7 +1051,7 @@ public function resetSequence($table, $value = null) * The sequence is reset such that the primary key of the next new row inserted * will have the specified value or the maximum existing value +1. * @param string $table the name of the table whose primary key sequence is reset - * @param array|string $value the value for the primary key of the next new row inserted. If this is not set, + * @param array|string|null $value the value for the primary key of the next new row inserted. If this is not set, * the next new row's primary key will have the maximum existing value +1. * @throws NotSupportedException if this is not supported by the underlying DBMS * @since 2.0.16 @@ -1228,7 +1228,7 @@ public function getColumnType($type) * @param array $columns * @param array $params the binding parameters to be populated * @param bool $distinct - * @param string $selectOption + * @param string|null $selectOption * @return string the SELECT clause built from [[Query::$select]]. */ public function buildSelect($columns, &$params, $distinct = false, $selectOption = null) diff --git a/framework/db/QueryInterface.php b/framework/db/QueryInterface.php index df57ad38385..819fc67ac58 100644 --- a/framework/db/QueryInterface.php +++ b/framework/db/QueryInterface.php @@ -24,7 +24,7 @@ interface QueryInterface { /** * Executes the query and returns all results as an array. - * @param Connection $db the database connection used to execute the query. + * @param Connection|null $db the database connection used to execute the query. * If this parameter is not given, the `db` application component will be used. * @return array the query results. If the query results in nothing, an empty array will be returned. */ @@ -32,7 +32,7 @@ public function all($db = null); /** * Executes the query and returns a single row of result. - * @param Connection $db the database connection used to execute the query. + * @param Connection|null $db the database connection used to execute the query. * If this parameter is not given, the `db` application component will be used. * @return array|bool the first row (in terms of an array) of the query result. False is returned if the query * results in nothing. @@ -42,15 +42,15 @@ public function one($db = null); /** * Returns the number of records. * @param string $q the COUNT expression. Defaults to '*'. - * @param Connection $db the database connection used to execute the query. + * @param Connection|null $db the database connection used to execute the query. * If this parameter is not given, the `db` application component will be used. - * @return int number of records. + * @return int|string|null number of records. */ public function count($q = '*', $db = null); /** * Returns a value indicating whether the query result contains any row of data. - * @param Connection $db the database connection used to execute the query. + * @param Connection|null $db the database connection used to execute the query. * If this parameter is not given, the `db` application component will be used. * @return bool whether the query result contains any row of data. */ diff --git a/framework/db/QueryTrait.php b/framework/db/QueryTrait.php index 803d6baf0be..9f6b06434b2 100644 --- a/framework/db/QueryTrait.php +++ b/framework/db/QueryTrait.php @@ -21,32 +21,32 @@ trait QueryTrait { /** - * @var string|array|ExpressionInterface query condition. This refers to the WHERE clause in a SQL statement. + * @var string|array|ExpressionInterface|null query condition. This refers to the WHERE clause in a SQL statement. * For example, `['age' => 31, 'team' => 1]`. * @see where() for valid syntax on specifying this value. */ public $where; /** - * @var int|ExpressionInterface maximum number of records to be returned. May be an instance of [[ExpressionInterface]]. + * @var int|ExpressionInterface|null maximum number of records to be returned. May be an instance of [[ExpressionInterface]]. * If not set or less than 0, it means no limit. */ public $limit; /** - * @var int|ExpressionInterface zero-based offset from where the records are to be returned. + * @var int|ExpressionInterface|null zero-based offset from where the records are to be returned. * May be an instance of [[ExpressionInterface]]. If not set or less than 0, it means starting from the beginning. */ public $offset; /** - * @var array how to sort the query results. This is used to construct the ORDER BY clause in a SQL statement. + * @var array|null how to sort the query results. This is used to construct the ORDER BY clause in a SQL statement. * The array keys are the columns to be sorted by, and the array values are the corresponding sort directions which - * can be either [SORT_ASC](https://secure.php.net/manual/en/array.constants.php#constant.sort-asc) - * or [SORT_DESC](https://secure.php.net/manual/en/array.constants.php#constant.sort-desc). + * can be either [SORT_ASC](https://www.php.net/manual/en/array.constants.php#constant.sort-asc) + * or [SORT_DESC](https://www.php.net/manual/en/array.constants.php#constant.sort-desc). * The array may also contain [[ExpressionInterface]] objects. If that is the case, the expressions * will be converted into strings without any change. */ public $orderBy; /** - * @var string|callable the name of the column by which the query results should be indexed by. + * @var string|callable|null the name of the column by which the query results should be indexed by. * This can also be a callable (e.g. anonymous function) that returns the index value based on the given * row data. For more details, see [[indexBy()]]. This property is only used by [[QueryInterface::all()|all()]]. */ diff --git a/framework/db/Schema.php b/framework/db/Schema.php index c11a22be210..e29585e253f 100644 --- a/framework/db/Schema.php +++ b/framework/db/Schema.php @@ -22,19 +22,17 @@ * Schema represents the database schema information that is DBMS specific. * * @property-read string $lastInsertID The row ID of the last row inserted, or the last value retrieved from - * the sequence object. This property is read-only. - * @property-read QueryBuilder $queryBuilder The query builder for this connection. This property is - * read-only. - * @property-read string[] $schemaNames All schema names in the database, except system schemas. This property - * is read-only. - * @property-read string $serverVersion Server version as a string. This property is read-only. - * @property-read string[] $tableNames All table names in the database. This property is read-only. + * the sequence object. + * @property-read QueryBuilder $queryBuilder The query builder for this connection. + * @property-read string[] $schemaNames All schema names in the database, except system schemas. + * @property-read string $serverVersion Server version as a string. + * @property-read string[] $tableNames All table names in the database. * @property-read TableSchema[] $tableSchemas The metadata for all tables in the database. Each array element - * is an instance of [[TableSchema]] or its child class. This property is read-only. + * is an instance of [[TableSchema]] or its child class. * @property-write string $transactionIsolationLevel The transaction isolation level to use for this * transaction. This can be one of [[Transaction::READ_UNCOMMITTED]], [[Transaction::READ_COMMITTED]], * [[Transaction::REPEATABLE_READ]] and [[Transaction::SERIALIZABLE]] but also a string containing DBMS specific - * syntax to be used after `SET TRANSACTION ISOLATION LEVEL`. This property is write-only. + * syntax to be used after `SET TRANSACTION ISOLATION LEVEL`. * * @author Qiang Xue * @author Sergey Makinen @@ -256,7 +254,7 @@ public function getQueryBuilder() * Determines the PDO type for the given PHP data value. * @param mixed $data the data whose PDO type is to be determined * @return int the PDO type - * @see https://secure.php.net/manual/en/pdo.constants.php + * @see https://www.php.net/manual/en/pdo.constants.php */ public function getPdoType($data) { @@ -324,7 +322,7 @@ public function createQueryBuilder() * This method may be overridden by child classes to create a DBMS-specific column schema builder. * * @param string $type type of the column. See [[ColumnSchemaBuilder::$type]]. - * @param int|string|array $length length or precision of the column. See [[ColumnSchemaBuilder::$length]]. + * @param int|string|array|null $length length or precision of the column. See [[ColumnSchemaBuilder::$length]]. * @return ColumnSchemaBuilder column schema builder instance * @since 2.0.6 */ @@ -361,7 +359,7 @@ public function findUniqueIndexes($table) * @param string $sequenceName name of the sequence object (required by some DBMS) * @return string the row ID of the last row inserted, or the last value retrieved from the sequence object * @throws InvalidCallException if the DB connection is not active - * @see https://secure.php.net/manual/en/function.PDO-lastInsertId.php + * @see https://www.php.net/manual/en/function.PDO-lastInsertId.php */ public function getLastInsertID($sequenceName = '') { @@ -452,7 +450,7 @@ public function insert($table, $columns) * Note that if the parameter is not a string, it will be returned without change. * @param string $str string to be quoted * @return string the properly quoted string - * @see https://secure.php.net/manual/en/function.PDO-quote.php + * @see https://www.php.net/manual/en/function.PDO-quote.php */ public function quoteValue($str) { @@ -460,7 +458,7 @@ public function quoteValue($str) return $str; } - if (($value = $this->db->getSlavePdo()->quote($str)) !== false) { + if (mb_stripos($this->db->dsn, 'odbc:') === false && ($value = $this->db->getSlavePdo()->quote($str)) !== false) { return $value; } @@ -480,7 +478,7 @@ public function quoteValue($str) public function quoteTableName($name) { - if (strpos($name, '(') === 0 && strpos($name, ')') === strlen($name) - 1) { + if (strncmp($name, '(', 1) === 0 && strpos($name, ')') === strlen($name) - 1) { return $name; } if (strpos($name, '{{') !== false) { diff --git a/framework/db/SchemaBuilderTrait.php b/framework/db/SchemaBuilderTrait.php index e57c4b0b78f..6b273d7f3ce 100644 --- a/framework/db/SchemaBuilderTrait.php +++ b/framework/db/SchemaBuilderTrait.php @@ -41,7 +41,7 @@ abstract protected function getDb(); /** * Creates a primary key column. - * @param int $length column size or precision definition. + * @param int|null $length column size or precision definition. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -53,7 +53,7 @@ public function primaryKey($length = null) /** * Creates a big primary key column. - * @param int $length column size or precision definition. + * @param int|null $length column size or precision definition. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -65,7 +65,7 @@ public function bigPrimaryKey($length = null) /** * Creates a char column. - * @param int $length column size definition i.e. the maximum string length. + * @param int|null $length column size definition i.e. the maximum string length. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.8 @@ -77,7 +77,7 @@ public function char($length = null) /** * Creates a string column. - * @param int $length column size definition i.e. the maximum string length. + * @param int|null $length column size definition i.e. the maximum string length. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -99,7 +99,7 @@ public function text() /** * Creates a tinyint column. If tinyint is not supported by the DBMS, smallint will be used. - * @param int $length column size or precision definition. + * @param int|null $length column size or precision definition. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.14 @@ -111,7 +111,7 @@ public function tinyInteger($length = null) /** * Creates a smallint column. - * @param int $length column size or precision definition. + * @param int|null $length column size or precision definition. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -123,7 +123,7 @@ public function smallInteger($length = null) /** * Creates an integer column. - * @param int $length column size or precision definition. + * @param int|null $length column size or precision definition. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -135,7 +135,7 @@ public function integer($length = null) /** * Creates a bigint column. - * @param int $length column size or precision definition. + * @param int|null $length column size or precision definition. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -147,7 +147,7 @@ public function bigInteger($length = null) /** * Creates a float column. - * @param int $precision column value precision. First parameter passed to the column type, e.g. FLOAT(precision). + * @param int|null $precision column value precision. First parameter passed to the column type, e.g. FLOAT(precision). * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -159,7 +159,7 @@ public function float($precision = null) /** * Creates a double column. - * @param int $precision column value precision. First parameter passed to the column type, e.g. DOUBLE(precision). + * @param int|null $precision column value precision. First parameter passed to the column type, e.g. DOUBLE(precision). * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -171,10 +171,10 @@ public function double($precision = null) /** * Creates a decimal column. - * @param int $precision column value precision, which is usually the total number of digits. + * @param int|null $precision column value precision, which is usually the total number of digits. * First parameter passed to the column type, e.g. DECIMAL(precision, scale). * This parameter will be ignored if not supported by the DBMS. - * @param int $scale column value scale, which is usually the number of digits after the decimal point. + * @param int|null $scale column value scale, which is usually the number of digits after the decimal point. * Second parameter passed to the column type, e.g. DECIMAL(precision, scale). * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. @@ -195,7 +195,7 @@ public function decimal($precision = null, $scale = null) /** * Creates a datetime column. - * @param int $precision column value precision. First parameter passed to the column type, e.g. DATETIME(precision). + * @param int|null $precision column value precision. First parameter passed to the column type, e.g. DATETIME(precision). * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -207,7 +207,7 @@ public function dateTime($precision = null) /** * Creates a timestamp column. - * @param int $precision column value precision. First parameter passed to the column type, e.g. TIMESTAMP(precision). + * @param int|null $precision column value precision. First parameter passed to the column type, e.g. TIMESTAMP(precision). * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -219,7 +219,7 @@ public function timestamp($precision = null) /** * Creates a time column. - * @param int $precision column value precision. First parameter passed to the column type, e.g. TIME(precision). + * @param int|null $precision column value precision. First parameter passed to the column type, e.g. TIME(precision). * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -241,7 +241,7 @@ public function date() /** * Creates a binary column. - * @param int $length column size or precision definition. + * @param int|null $length column size or precision definition. * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. * @since 2.0.6 @@ -263,10 +263,10 @@ public function boolean() /** * Creates a money column. - * @param int $precision column value precision, which is usually the total number of digits. + * @param int|null $precision column value precision, which is usually the total number of digits. * First parameter passed to the column type, e.g. DECIMAL(precision, scale). * This parameter will be ignored if not supported by the DBMS. - * @param int $scale column value scale, which is usually the number of digits after the decimal point. + * @param int|null $scale column value scale, which is usually the number of digits after the decimal point. * Second parameter passed to the column type, e.g. DECIMAL(precision, scale). * This parameter will be ignored if not supported by the DBMS. * @return ColumnSchemaBuilder the column instance which can be further customized. diff --git a/framework/db/SqlToken.php b/framework/db/SqlToken.php index 0e947c17458..be155255a58 100644 --- a/framework/db/SqlToken.php +++ b/framework/db/SqlToken.php @@ -13,10 +13,9 @@ * SqlToken represents SQL tokens produced by [[SqlTokenizer]] or its child classes. * * @property SqlToken[] $children Child tokens. - * @property-read bool $hasChildren Whether the token has children. This property is read-only. - * @property-read bool $isCollection Whether the token represents a collection of tokens. This property is - * read-only. - * @property-read string $sql SQL code. This property is read-only. + * @property-read bool $hasChildren Whether the token has children. + * @property-read bool $isCollection Whether the token represents a collection of tokens. + * @property-read string $sql SQL code. * * @author Sergey Makinen * @since 2.0.13 @@ -84,6 +83,7 @@ public function __toString() * @param int $offset child token offset. * @return bool whether the token exists. */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->_children[$this->calculateOffset($offset)]); @@ -96,6 +96,7 @@ public function offsetExists($offset) * @param int $offset child token offset. * @return SqlToken|null the child token at the specified offset, `null` if there's no token. */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { $offset = $this->calculateOffset($offset); @@ -109,6 +110,7 @@ public function offsetGet($offset) * @param int|null $offset child token offset. * @param SqlToken $token token to be added. */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $token) { $token->parent = $this; @@ -126,6 +128,7 @@ public function offsetSet($offset, $token) * It is implicitly called when you use something like `unset($token[$offset])`. * @param int $offset child token offset. */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $offset = $this->calculateOffset($offset); @@ -267,10 +270,8 @@ private function tokensMatch(SqlToken $patternToken, SqlToken $token, $offset = if ($firstMatchIndex === null) { $firstMatchIndex = $offset; - $lastMatchIndex = $offset; - } else { - $lastMatchIndex = $offset; } + $lastMatchIndex = $offset; $wildcard = false; $offset++; continue 2; diff --git a/framework/db/TableSchema.php b/framework/db/TableSchema.php index 899ddb8abb9..1bae54b5ef1 100644 --- a/framework/db/TableSchema.php +++ b/framework/db/TableSchema.php @@ -13,7 +13,7 @@ /** * TableSchema represents the metadata of a database table. * - * @property-read array $columnNames List of column names. This property is read-only. + * @property-read array $columnNames List of column names. * * @author Qiang Xue * @since 2.0 @@ -39,7 +39,7 @@ class TableSchema extends BaseObject */ public $primaryKey = []; /** - * @var string sequence name for the primary key. Null if no sequence. + * @var string|null sequence name for the primary key. Null if no sequence. */ public $sequenceName; /** @@ -64,7 +64,7 @@ class TableSchema extends BaseObject * Gets the named column metadata. * This is a convenient method for retrieving a named column even if it does not exist. * @param string $name column name - * @return ColumnSchema metadata of the named column. Null if the named column does not exist. + * @return ColumnSchema|null metadata of the named column. Null if the named column does not exist. */ public function getColumn($name) { diff --git a/framework/db/Transaction.php b/framework/db/Transaction.php index e6c1cbe93a2..15186c09544 100644 --- a/framework/db/Transaction.php +++ b/framework/db/Transaction.php @@ -36,16 +36,15 @@ * ``` * * > Note: in the above code we have two catch-blocks for compatibility - * > with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](https://secure.php.net/manual/en/class.throwable.php) + * > with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](https://www.php.net/manual/en/class.throwable.php) * > since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher. * * @property-read bool $isActive Whether this transaction is active. Only an active transaction can - * [[commit()]] or [[rollBack()]]. This property is read-only. + * [[commit()]] or [[rollBack()]]. * @property-write string $isolationLevel The transaction isolation level to use for this transaction. This * can be one of [[READ_UNCOMMITTED]], [[READ_COMMITTED]], [[REPEATABLE_READ]] and [[SERIALIZABLE]] but also a - * string containing DBMS specific syntax to be used after `SET TRANSACTION ISOLATION LEVEL`. This property is - * write-only. - * @property-read int $level The current nesting level of the transaction. This property is read-only. + * string containing DBMS specific syntax to be used after `SET TRANSACTION ISOLATION LEVEL`. + * @property-read int $level The current nesting level of the transaction. * * @author Qiang Xue * @since 2.0 @@ -140,7 +139,10 @@ public function begin($isolationLevel = null) $schema = $this->db->getSchema(); if ($schema->supportsSavepoint()) { Yii::debug('Set savepoint ' . $this->_level, __METHOD__); - $schema->createSavepoint('LEVEL' . $this->_level); + // make sure the transaction wasn't autocommitted + if ($this->db->pdo->inTransaction()) { + $schema->createSavepoint('LEVEL' . $this->_level); + } } else { Yii::info('Transaction not started: nested transaction not supported', __METHOD__); throw new NotSupportedException('Transaction not started: nested transaction not supported.'); @@ -161,7 +163,10 @@ public function commit() $this->_level--; if ($this->_level === 0) { Yii::debug('Commit transaction', __METHOD__); - $this->db->pdo->commit(); + // make sure the transaction wasn't autocommitted + if ($this->db->pdo->inTransaction()) { + $this->db->pdo->commit(); + } $this->db->trigger(Connection::EVENT_COMMIT_TRANSACTION); return; } @@ -169,7 +174,10 @@ public function commit() $schema = $this->db->getSchema(); if ($schema->supportsSavepoint()) { Yii::debug('Release savepoint ' . $this->_level, __METHOD__); - $schema->releaseSavepoint('LEVEL' . $this->_level); + // make sure the transaction wasn't autocommitted + if ($this->db->pdo->inTransaction()) { + $schema->releaseSavepoint('LEVEL' . $this->_level); + } } else { Yii::info('Transaction not committed: nested transaction not supported', __METHOD__); } @@ -189,7 +197,10 @@ public function rollBack() $this->_level--; if ($this->_level === 0) { Yii::debug('Roll back transaction', __METHOD__); - $this->db->pdo->rollBack(); + // make sure the transaction wasn't autocommitted + if ($this->db->pdo->inTransaction()) { + $this->db->pdo->rollBack(); + } $this->db->trigger(Connection::EVENT_ROLLBACK_TRANSACTION); return; } @@ -197,7 +208,10 @@ public function rollBack() $schema = $this->db->getSchema(); if ($schema->supportsSavepoint()) { Yii::debug('Roll back to savepoint ' . $this->_level, __METHOD__); - $schema->rollBackSavepoint('LEVEL' . $this->_level); + // make sure the transaction wasn't autocommitted + if ($this->db->pdo->inTransaction()) { + $schema->rollBackSavepoint('LEVEL' . $this->_level); + } } else { Yii::info('Transaction not rolled back: nested transaction not supported', __METHOD__); } diff --git a/framework/db/conditions/InConditionBuilder.php b/framework/db/conditions/InConditionBuilder.php index f685216c111..6c48d1fba33 100644 --- a/framework/db/conditions/InConditionBuilder.php +++ b/framework/db/conditions/InConditionBuilder.php @@ -7,6 +7,7 @@ namespace yii\db\conditions; +use yii\db\Expression; use yii\db\ExpressionBuilderInterface; use yii\db\ExpressionBuilderTrait; use yii\db\ExpressionInterface; @@ -54,18 +55,20 @@ public function build(ExpressionInterface $expression, array &$params = []) if (is_array($column)) { if (count($column) > 1) { return $this->buildCompositeInCondition($operator, $column, $values, $params); - } else { - $column = reset($column); } + $column = reset($column); } if ($column instanceof \Traversable) { if (iterator_count($column) > 1) { return $this->buildCompositeInCondition($operator, $column, $values, $params); - } else { - $column->rewind(); - $column = $column->current(); } + $column->rewind(); + $column = $column->current(); + } + + if ($column instanceof Expression) { + $column = $column->expression; } if (is_array($values)) { @@ -74,6 +77,8 @@ public function build(ExpressionInterface $expression, array &$params = []) $rawValues = $this->getRawValuesFromTraversableObject($values); } + $nullCondition = null; + $nullConditionOperator = null; if (isset($rawValues) && in_array(null, $rawValues, true)) { $nullCondition = $this->getNullCondition($operator, $column); $nullConditionOperator = $operator === 'IN' ? 'OR' : 'AND'; @@ -81,7 +86,7 @@ public function build(ExpressionInterface $expression, array &$params = []) $sqlValues = $this->buildValues($expression, $values, $params); if (empty($sqlValues)) { - if (!isset($nullCondition)) { + if ($nullCondition === null) { return $operator === 'IN' ? '0=1' : ''; } return $nullCondition; @@ -97,7 +102,9 @@ public function build(ExpressionInterface $expression, array &$params = []) $sql = $column . $operator . reset($sqlValues); } - return isset($nullCondition) ? sprintf('%s %s %s', $sql, $nullConditionOperator, $nullCondition) : $sql; + return $nullCondition !== null && $nullConditionOperator !== null + ? sprintf('%s %s %s', $sql, $nullConditionOperator, $nullCondition) + : $sql; } /** @@ -122,6 +129,10 @@ protected function buildValues(ConditionInterface $condition, $values, &$params) $column = $column->current(); } + if ($column instanceof Expression) { + $column = $column->expression; + } + foreach ($values as $i => $value) { if (is_array($value) || $value instanceof \ArrayAccess) { $value = isset($value[$column]) ? $value[$column] : null; @@ -153,6 +164,9 @@ protected function buildSubqueryInCondition($operator, $columns, $values, &$para if (is_array($columns)) { foreach ($columns as $i => $col) { + if ($col instanceof Expression) { + $col = $col->expression; + } if (strpos($col, '(') === false) { $columns[$i] = $this->queryBuilder->db->quoteColumnName($col); } @@ -161,6 +175,9 @@ protected function buildSubqueryInCondition($operator, $columns, $values, &$para return '(' . implode(', ', $columns) . ") $operator $sql"; } + if ($columns instanceof Expression) { + $columns = $columns->expression; + } if (strpos($columns, '(') === false) { $columns = $this->queryBuilder->db->quoteColumnName($columns); } @@ -183,6 +200,9 @@ protected function buildCompositeInCondition($operator, $columns, $values, &$par foreach ($values as $value) { $vs = []; foreach ($columns as $column) { + if ($column instanceof Expression) { + $column = $column->expression; + } if (isset($value[$column])) { $vs[] = $this->queryBuilder->bindParam($value[$column], $params); } else { @@ -198,6 +218,9 @@ protected function buildCompositeInCondition($operator, $columns, $values, &$par $sqlColumns = []; foreach ($columns as $i => $column) { + if ($column instanceof Expression) { + $column = $column->expression; + } $sqlColumns[] = strpos($column, '(') === false ? $this->queryBuilder->db->quoteColumnName($column) : $column; } diff --git a/framework/db/conditions/LikeCondition.php b/framework/db/conditions/LikeCondition.php index 3586adfff27..3566e83832a 100644 --- a/framework/db/conditions/LikeCondition.php +++ b/framework/db/conditions/LikeCondition.php @@ -18,7 +18,7 @@ class LikeCondition extends SimpleCondition { /** - * @var array|false map of chars to their replacements, false if characters should not be escaped + * @var array|null|false map of chars to their replacements, false if characters should not be escaped * or either null or empty array if escaping is condition builder responsibility. * By default it's set to `null`. */ diff --git a/framework/db/cubrid/QueryBuilder.php b/framework/db/cubrid/QueryBuilder.php index 6ebbc5845c2..27a1a91d1fa 100644 --- a/framework/db/cubrid/QueryBuilder.php +++ b/framework/db/cubrid/QueryBuilder.php @@ -263,7 +263,7 @@ public function dropCommentFromTable($table) * * @param string $table table name * @param string $column column name - * @return null|string the column definition + * @return string|null the column definition * @throws Exception in case when table does not contain column * @since 2.0.8 */ diff --git a/framework/db/cubrid/Schema.php b/framework/db/cubrid/Schema.php index a487235fdd6..73a06c4d130 100644 --- a/framework/db/cubrid/Schema.php +++ b/framework/db/cubrid/Schema.php @@ -326,7 +326,7 @@ protected function loadColumnSchema($info) * Determines the PDO type for the given PHP data value. * @param mixed $data the data whose PDO type is to be determined * @return int the PDO type - * @see https://secure.php.net/manual/en/pdo.constants.php + * @see https://www.php.net/manual/en/pdo.constants.php */ public function getPdoType($data) { diff --git a/framework/db/mssql/ColumnSchemaBuilder.php b/framework/db/mssql/ColumnSchemaBuilder.php new file mode 100644 index 00000000000..5543a7963c8 --- /dev/null +++ b/framework/db/mssql/ColumnSchemaBuilder.php @@ -0,0 +1,79 @@ + + * @since 2.0.42 + */ +class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder +{ + protected $format = '{type}{length}{notnull}{unique}{default}{check}{append}'; + + + /** + * Builds the full string for the column's schema. + * @return string + */ + public function __toString() + { + if ($this->getTypeCategory() === self::CATEGORY_PK) { + $format = '{type}{check}{comment}{append}'; + } else { + $format = $this->format; + } + + return $this->buildCompleteString($format); + } + + /** + * Changes default format string to MSSQL ALTER COMMAND. + */ + public function setAlterColumnFormat() + { + $this->format = '{type}{length}{notnull}{append}'; + } + + /** + * Getting the `Default` value for constraint + * @return string|Expression|null default value of the column. + */ + public function getDefaultValue() + { + if ($this->default instanceof Expression) { + return $this->default; + } + + return $this->buildDefaultValue(); + } + + /** + * Get the `Check` value for constraint + * @return string|null the `CHECK` constraint for the column. + */ + public function getCheckValue() + { + return $this->check !== null ? (string) $this->check : null; + } + + /** + * @return bool whether the column values should be unique. If this is `true`, a `UNIQUE` constraint will be added. + */ + public function isUnique() + { + return $this->isUnique; + } +} diff --git a/framework/db/mssql/DBLibPDO.php b/framework/db/mssql/DBLibPDO.php new file mode 100644 index 00000000000..97bcf42ca13 --- /dev/null +++ b/framework/db/mssql/DBLibPDO.php @@ -0,0 +1,53 @@ + + * @since 2.0.41 + */ +class DBLibPDO extends \PDO +{ + /** + * Returns value of the last inserted ID. + * @param string|null $name the sequence name. Defaults to null. + * @return int last inserted ID value. + */ + #[\ReturnTypeWillChange] + public function lastInsertId($name = null) + { + return $this->query('SELECT CAST(COALESCE(SCOPE_IDENTITY(), @@IDENTITY) AS bigint)')->fetchColumn(); + } + + /** + * Retrieve a database connection attribute. + * + * It is necessary to override PDO's method as some MSSQL PDO driver (e.g. dblib) does not + * support getting attributes. + * @param int $attribute One of the PDO::ATTR_* constants. + * @return mixed A successful call returns the value of the requested PDO attribute. + * An unsuccessful call returns null. + */ + #[\ReturnTypeWillChange] + public function getAttribute($attribute) + { + try { + return parent::getAttribute($attribute); + } catch (\PDOException $e) { + switch ($attribute) { + case self::ATTR_SERVER_VERSION: + return $this->query("SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR)")->fetchColumn(); + default: + throw $e; + } + } + } +} diff --git a/framework/db/mssql/PDO.php b/framework/db/mssql/PDO.php index 005774c45cc..dfdb635ed2b 100644 --- a/framework/db/mssql/PDO.php +++ b/framework/db/mssql/PDO.php @@ -21,6 +21,7 @@ class PDO extends \PDO * @param string|null $sequence the sequence name. Defaults to null. * @return int last inserted ID value. */ + #[\ReturnTypeWillChange] public function lastInsertId($sequence = null) { return $this->query('SELECT CAST(COALESCE(SCOPE_IDENTITY(), @@IDENTITY) AS bigint)')->fetchColumn(); @@ -31,6 +32,7 @@ public function lastInsertId($sequence = null) * natively support transactions. * @return bool the result of a transaction start. */ + #[\ReturnTypeWillChange] public function beginTransaction() { $this->exec('BEGIN TRANSACTION'); @@ -43,6 +45,7 @@ public function beginTransaction() * natively support transactions. * @return bool the result of a transaction commit. */ + #[\ReturnTypeWillChange] public function commit() { $this->exec('COMMIT TRANSACTION'); @@ -55,6 +58,7 @@ public function commit() * natively support transactions. * @return bool the result of a transaction roll back. */ + #[\ReturnTypeWillChange] public function rollBack() { $this->exec('ROLLBACK TRANSACTION'); @@ -71,6 +75,7 @@ public function rollBack() * @return mixed A successful call returns the value of the requested PDO attribute. * An unsuccessful call returns null. */ + #[\ReturnTypeWillChange] public function getAttribute($attribute) { try { diff --git a/framework/db/mssql/QueryBuilder.php b/framework/db/mssql/QueryBuilder.php index cc2a92067a9..bec248dab17 100644 --- a/framework/db/mssql/QueryBuilder.php +++ b/framework/db/mssql/QueryBuilder.php @@ -11,6 +11,7 @@ use yii\base\NotSupportedException; use yii\db\Constraint; use yii\db\Expression; +use yii\db\TableSchema; /** * QueryBuilder is the query builder for MS SQL Server databases (version 2008 and above). @@ -107,7 +108,7 @@ protected function newBuildOrderByAndLimit($sql, $orderBy, $limit, $offset) * Builds the ORDER BY/LIMIT/OFFSET clauses for SQL SERVER 2005 to 2008. * @param string $sql the existing SQL (without ORDER BY/LIMIT/OFFSET) * @param array $orderBy the order by columns. See [[\yii\db\Query::orderBy]] for more details on how to specify this parameter. - * @param int $limit the limit number. See [[\yii\db\Query::limit]] for more details. + * @param int|Expression $limit the limit number. See [[\yii\db\Query::limit]] for more details. * @param int $offset the offset number. See [[\yii\db\Query::offset]] for more details. * @return string the SQL completed with ORDER BY/LIMIT/OFFSET (if any) */ @@ -122,6 +123,9 @@ protected function oldBuildOrderByAndLimit($sql, $orderBy, $limit, $offset) $sql = preg_replace('/^([\s(])*SELECT(\s+DISTINCT)?(?!\s*TOP\s*\()/i', "\\1SELECT\\2 rowNum = ROW_NUMBER() over ($orderBy),", $sql); if ($this->hasLimit($limit)) { + if ($limit instanceof Expression) { + $limit = '('. (string)$limit . ')'; + } $sql = "SELECT TOP $limit * FROM ($sql) sub"; } else { $sql = "SELECT * FROM ($sql) sub"; @@ -171,35 +175,40 @@ public function renameColumn($table, $oldName, $newName) */ public function alterColumn($table, $column, $type) { - $sqlAfter = []; + $sqlAfter = [$this->dropConstraintsForColumn($table, $column, 'D')]; $columnName = $this->db->quoteColumnName($column); $tableName = $this->db->quoteTableName($table); - $constraintBase = preg_replace('/[^a-z0-9_]/i', '', $table . '_' . $column); - $type = $this->getColumnType($type); + if ($type instanceof \yii\db\mssql\ColumnSchemaBuilder) { + $type->setAlterColumnFormat(); - if (preg_match('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', $type, $matches)) { - $type = preg_replace('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', '', $type); - $sqlAfter[] = $this->dropConstraintsForColumn($table, $column, 'D'); - $sqlAfter[] = $this->addDefaultValue("DF_{$constraintBase}", $table, $column, $matches[1]); - } else { - $sqlAfter[] = $this->dropConstraintsForColumn($table, $column, 'D'); - } - if (preg_match('/\s+CHECK\s+\((.+)\)/i', $type, $matches)) { - $type = preg_replace('/\s+CHECK\s+\((.+)\)/i', '', $type); - $sqlAfter[] = "ALTER TABLE {$tableName} ADD CONSTRAINT " . $this->db->quoteColumnName("CK_{$constraintBase}") . " CHECK ({$matches[1]})"; - } + $defaultValue = $type->getDefaultValue(); + if ($defaultValue !== null) { + $sqlAfter[] = $this->addDefaultValue( + "DF_{$constraintBase}", + $table, + $column, + $defaultValue instanceof Expression ? $defaultValue : new Expression($defaultValue) + ); + } + + $checkValue = $type->getCheckValue(); + if ($checkValue !== null) { + $sqlAfter[] = "ALTER TABLE {$tableName} ADD CONSTRAINT " . + $this->db->quoteColumnName("CK_{$constraintBase}") . + " CHECK (" . ($defaultValue instanceof Expression ? $checkValue : new Expression($checkValue)) . ")"; + } - $type = preg_replace('/\s+UNIQUE/i', '', $type, -1, $count); - if ($count) { - $sqlAfter[] = "ALTER TABLE {$tableName} ADD CONSTRAINT " . $this->db->quoteColumnName("UQ_{$constraintBase}") . " UNIQUE ({$columnName})"; + if ($type->isUnique()) { + $sqlAfter[] = "ALTER TABLE {$tableName} ADD CONSTRAINT " . $this->db->quoteColumnName("UQ_{$constraintBase}") . " UNIQUE ({$columnName})"; + } } - return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' ALTER COLUMN ' - . $this->db->quoteColumnName($column) . ' ' + return 'ALTER TABLE ' . $tableName . ' ALTER COLUMN ' + . $columnName . ' ' . $this->getColumnType($type) . "\n" . implode("\n", $sqlAfter); } @@ -284,7 +293,7 @@ public function checkIntegrity($check = true, $schema = '', $table = '') * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. * @param string $table the table to be commented or whose column is to be commented. The table name will be * properly quoted by the method. - * @param string $column optional. The name of the column to be commented. If empty, the command will add the + * @param string|null $column optional. The name of the column to be commented. If empty, the command will add the * comment to the table instead. The column name will be properly quoted by the method. * @return string the SQL statement for adding a comment. * @throws InvalidArgumentException if the table does not exist. @@ -350,7 +359,7 @@ public function addCommentOnTable($table, $comment) * * @param string $table the table that will have the comment removed or whose column will have the comment removed. * The table name will be properly quoted by the method. - * @param string $column optional. The name of the column whose comment will be removed. If empty, the command + * @param string|null $column optional. The name of the column whose comment will be removed. If empty, the command * will remove the comment from the table instead. The column name will be properly quoted by the method. * @return string the SQL statement for removing the comment. * @throws InvalidArgumentException if the table does not exist. @@ -406,7 +415,7 @@ public function dropCommentFromTable($table) /** * Returns an array of column names given model name. * - * @param string $modelClass name of the model class + * @param string|null $modelClass name of the model class * @return array|null array of column names */ protected function getAllColumnNames($modelClass = null) @@ -475,19 +484,21 @@ public function insert($table, $columns, &$params) $version2005orLater = version_compare($this->db->getSchema()->getServerVersion(), '9', '>='); list($names, $placeholders, $values, $params) = $this->prepareInsertValues($table, $columns, $params); + $cols = []; + $columns = []; if ($version2005orLater) { + /* @var $schema TableSchema */ $schema = $this->db->getTableSchema($table); - $cols = []; - $columns = []; foreach ($schema->columns as $column) { if ($column->isComputed) { continue; } - $cols[] = $this->db->quoteColumnName($column->name) . ' ' + $quoteColumnName = $this->db->quoteColumnName($column->name); + $cols[] = $quoteColumnName . ' ' . $column->dbType . (in_array($column->dbType, ['char', 'varchar', 'nchar', 'nvarchar', 'binary', 'varbinary']) ? "(MAX)" : "") . ' ' . ($column->allowNull ? "NULL" : ""); - $columns[] = 'INSERTED.' . $column->name; + $columns[] = 'INSERTED.' . $quoteColumnName; } } $countColumns = count($columns); @@ -512,6 +523,8 @@ public function insert($table, $columns, &$params) */ public function upsert($table, $insertColumns, $updateColumns, &$params) { + $insertColumns = $this->normalizeTableRowData($table, $insertColumns, $params); + /** @var Constraint[] $constraints */ list($uniqueNames, $insertNames, $updateNames) = $this->prepareUpsertColumns($table, $insertColumns, $updateColumns, $constraints); if (empty($uniqueNames)) { @@ -534,8 +547,18 @@ public function upsert($table, $insertColumns, $updateColumns, &$params) } $on = $this->buildCondition($onCondition, $params); list(, $placeholders, $values, $params) = $this->prepareInsertValues($table, $insertColumns, $params); + + /** + * Fix number of select query params for old MSSQL version that does not support offset correctly. + * @see QueryBuilder::oldBuildOrderByAndLimit + */ + $insertNamesUsing = $insertNames; + if (strstr($values, 'rowNum = ROW_NUMBER()') !== false) { + $insertNamesUsing = array_merge(['[rowNum]'], $insertNames); + } + $mergeSql = 'MERGE ' . $this->db->quoteTableName($table) . ' WITH (HOLDLOCK) ' - . 'USING (' . (!empty($placeholders) ? 'VALUES (' . implode(', ', $placeholders) . ')' : ltrim($values, ' ')) . ') AS [EXCLUDED] (' . implode(', ', $insertNames) . ') ' + . 'USING (' . (!empty($placeholders) ? 'VALUES (' . implode(', ', $placeholders) . ')' : ltrim($values, ' ')) . ') AS [EXCLUDED] (' . implode(', ', $insertNamesUsing) . ') ' . "ON ($on)"; $insertValues = []; foreach ($insertNames as $name) { @@ -561,6 +584,8 @@ public function upsert($table, $insertColumns, $updateColumns, &$params) $updateColumns[$name] = new Expression($quotedName); } } + $updateColumns = $this->normalizeTableRowData($table, $updateColumns, $params); + list($updates, $params) = $this->prepareUpdateSets($table, $updateColumns, $params); $updateSql = 'UPDATE SET ' . implode(', ', $updates); return "$mergeSql WHEN MATCHED THEN $updateSql WHEN NOT MATCHED THEN $insertSql;"; @@ -643,5 +668,4 @@ public function dropColumn($table, $column) return $this->dropConstraintsForColumn($table, $column) . "\nALTER TABLE " . $this->db->quoteTableName($table) . " DROP COLUMN " . $this->db->quoteColumnName($column); } - } diff --git a/framework/db/mssql/Schema.php b/framework/db/mssql/Schema.php index 1ffad32a924..cb451e68d12 100644 --- a/framework/db/mssql/Schema.php +++ b/framework/db/mssql/Schema.php @@ -180,12 +180,7 @@ protected function findTableNames($schema = '') WHERE [t].[table_schema] = :schema AND [t].[table_type] IN ('BASE TABLE', 'VIEW') ORDER BY [t].[table_name] SQL; - $tables = $this->db->createCommand($sql, [':schema' => $schema])->queryColumn(); - $tables = array_map(static function ($item) { - return '[' . $item . ']'; - }, $tables); - - return $tables; + return $this->db->createCommand($sql, [':schema' => $schema])->queryColumn(); } /** @@ -204,6 +199,29 @@ protected function loadTableSchema($name) return null; } + /** + * {@inheritdoc} + */ + protected function getSchemaMetadata($schema, $type, $refresh) + { + $metadata = []; + $methodName = 'getTable' . ucfirst($type); + $tableNames = array_map(function ($table) { + return $this->quoteSimpleTableName($table); + }, $this->getTableNames($schema, $refresh)); + foreach ($tableNames as $name) { + if ($schema !== '') { + $name = $schema . '.' . $name; + } + $tableMetadata = $this->$methodName($name, $refresh); + if ($tableMetadata !== null) { + $metadata[] = $tableMetadata; + } + } + + return $metadata; + } + /** * {@inheritdoc} */ @@ -376,9 +394,9 @@ protected function loadColumnSchema($info) } if (!empty($matches[2])) { $values = explode(',', $matches[2]); - $column->size = $column->precision = (int)$values[0]; + $column->size = $column->precision = (int) $values[0]; if (isset($values[1])) { - $column->scale = (int)$values[1]; + $column->scale = (int) $values[1]; } if ($column->size === 1 && ($type === 'tinyint' || $type === 'bit')) { $column->type = 'boolean'; @@ -597,12 +615,7 @@ protected function findViewNames($schema = '') ORDER BY [t].[table_name] SQL; - $views = $this->db->createCommand($sql, [':schema' => $schema])->queryColumn(); - $views = array_map(static function ($item) { - return '[' . $item . ']'; - }, $views); - - return $views; + return $this->db->createCommand($sql, [':schema' => $schema])->queryColumn(); } /** @@ -776,13 +789,12 @@ public function insert($table, $columns) $tableSchema = $this->getTableSchema($table); $result = []; foreach ($tableSchema->primaryKey as $name) { - if ($tableSchema->columns[$name]->autoIncrement) { - $result[$name] = $this->getLastInsertID($tableSchema->sequenceName); - break; - } // @see https://github.com/yiisoft/yii2/issues/13828 & https://github.com/yiisoft/yii2/issues/17474 if (isset($inserted[$name])) { $result[$name] = $inserted[$name]; + } elseif ($tableSchema->columns[$name]->autoIncrement) { + // for a version earlier than 2005 + $result[$name] = $this->getLastInsertID($tableSchema->sequenceName); } elseif (isset($columns[$name])) { $result[$name] = $columns[$name]; } else { @@ -792,4 +804,12 @@ public function insert($table, $columns) return $result; } + + /** + * {@inheritdoc} + */ + public function createColumnSchemaBuilder($type, $length = null) + { + return new ColumnSchemaBuilder($type, $length, $this->db); + } } diff --git a/framework/db/mssql/SqlsrvPDO.php b/framework/db/mssql/SqlsrvPDO.php index e248b1cc6ca..d7fe600d1d6 100644 --- a/framework/db/mssql/SqlsrvPDO.php +++ b/framework/db/mssql/SqlsrvPDO.php @@ -26,6 +26,7 @@ class SqlsrvPDO extends \PDO * @param string|null $sequence the sequence name. Defaults to null. * @return int last inserted ID value. */ + #[\ReturnTypeWillChange] public function lastInsertId($sequence = null) { return !$sequence ? parent::lastInsertId() : parent::lastInsertId($sequence); diff --git a/framework/db/mssql/TableSchema.php b/framework/db/mssql/TableSchema.php index 05268ea31fa..037029e5456 100644 --- a/framework/db/mssql/TableSchema.php +++ b/framework/db/mssql/TableSchema.php @@ -16,7 +16,7 @@ class TableSchema extends \yii\db\TableSchema { /** - * @var string name of the catalog (database) that this table belongs to. + * @var string|null name of the catalog (database) that this table belongs to. * Defaults to null, meaning no catalog (or the current database). */ public $catalogName; diff --git a/framework/db/mssql/conditions/InConditionBuilder.php b/framework/db/mssql/conditions/InConditionBuilder.php index 7892b545569..1124d010246 100644 --- a/framework/db/mssql/conditions/InConditionBuilder.php +++ b/framework/db/mssql/conditions/InConditionBuilder.php @@ -8,6 +8,7 @@ namespace yii\db\mssql\conditions; use yii\base\NotSupportedException; +use yii\db\Expression; /** * {@inheritdoc} @@ -37,12 +38,18 @@ protected function buildCompositeInCondition($operator, $columns, $values, &$par { $quotedColumns = []; foreach ($columns as $i => $column) { + if ($column instanceof Expression) { + $column = $column->expression; + } $quotedColumns[$i] = strpos($column, '(') === false ? $this->queryBuilder->db->quoteColumnName($column) : $column; } $vss = []; foreach ($values as $value) { $vs = []; foreach ($columns as $i => $column) { + if ($column instanceof Expression) { + $column = $column->expression; + } if (isset($value[$column])) { $phName = $this->queryBuilder->bindParam($value[$column], $params); $vs[] = $quotedColumns[$i] . ($operator === 'IN' ? ' = ' : ' != ') . $phName; diff --git a/framework/db/mysql/QueryBuilder.php b/framework/db/mysql/QueryBuilder.php index c8b93cf186d..382f36c28fc 100644 --- a/framework/db/mysql/QueryBuilder.php +++ b/framework/db/mysql/QueryBuilder.php @@ -90,7 +90,7 @@ public function renameColumn($table, $oldName, $newName) $row = array_values($row); $sql = $row[1]; } - if (preg_match_all('/^\s*`(.*?)`\s+(.*?),?$/m', $sql, $matches)) { + if (preg_match_all('/^\s*[`"](.*?)[`"]\s+(.*?),?$/m', $sql, $matches)) { foreach ($matches[1] as $i => $c) { if ($c === $oldName) { return "ALTER TABLE $quotedTable CHANGE " @@ -357,7 +357,7 @@ public function dropCommentFromTable($table) * * @param string $table table name * @param string $column column name - * @return null|string the column definition + * @return string|null the column definition * @throws Exception in case when table does not contain column */ private function getColumnDefinition($table, $column) @@ -373,7 +373,7 @@ private function getColumnDefinition($table, $column) $row = array_values($row); $sql = $row[1]; } - if (preg_match_all('/^\s*`(.*?)`\s+(.*?),?$/m', $sql, $matches)) { + if (preg_match_all('/^\s*[`"](.*?)[`"]\s+(.*?),?$/m', $sql, $matches)) { foreach ($matches[1] as $i => $c) { if ($c === $column) { return $matches[2][$i]; diff --git a/framework/db/mysql/Schema.php b/framework/db/mysql/Schema.php index ae9d0de4eee..babb7d2aa9a 100644 --- a/framework/db/mysql/Schema.php +++ b/framework/db/mysql/Schema.php @@ -294,10 +294,11 @@ protected function loadColumnSchema($info) * See details here: https://mariadb.com/kb/en/library/now/#description */ if (($column->type === 'timestamp' || $column->type === 'datetime') + && isset($info['default']) && preg_match('/^current_timestamp(?:\(([0-9]*)\))?$/i', $info['default'], $matches)) { $column->defaultValue = new Expression('CURRENT_TIMESTAMP' . (!empty($matches[1]) ? '(' . $matches[1] . ')' : '')); } elseif (isset($type) && $type === 'bit') { - $column->defaultValue = bindec(trim($info['default'], 'b\'')); + $column->defaultValue = bindec(trim(isset($info['default']) ? $info['default'] : '', 'b\'')); } else { $column->defaultValue = $column->phpTypecast($info['default']); } @@ -413,9 +414,9 @@ protected function findConstraints($table) $regexp = '/FOREIGN KEY\s+\(([^\)]+)\)\s+REFERENCES\s+([^\(^\s]+)\s*\(([^\)]+)\)/mi'; if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { - $fks = array_map('trim', explode(',', str_replace('`', '', $match[1]))); - $pks = array_map('trim', explode(',', str_replace('`', '', $match[3]))); - $constraint = [str_replace('`', '', $match[2])]; + $fks = array_map('trim', explode(',', str_replace(['`', '"'], '', $match[1]))); + $pks = array_map('trim', explode(',', str_replace(['`', '"'], '', $match[3]))); + $constraint = [str_replace(['`', '"'], '', $match[2])]; foreach ($fks as $k => $name) { $constraint[$name] = $pks[$k]; } @@ -446,11 +447,11 @@ public function findUniqueIndexes($table) $sql = $this->getCreateTableSql($table); $uniqueIndexes = []; - $regexp = '/UNIQUE KEY\s+\`(.+)\`\s*\((\`.+\`)+\)/mi'; + $regexp = '/UNIQUE KEY\s+[`"](.+)[`"]\s*\(([`"].+[`"])+\)/mi'; if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { $indexName = $match[1]; - $indexColumns = array_map('trim', explode('`,`', trim($match[2], '`'))); + $indexColumns = array_map('trim', preg_split('/[`"],[`"]/', trim($match[2], '`"'))); $uniqueIndexes[$indexName] = $indexColumns; } } diff --git a/framework/db/oci/Schema.php b/framework/db/oci/Schema.php index 2e55c09db77..f6866e09cc1 100644 --- a/framework/db/oci/Schema.php +++ b/framework/db/oci/Schema.php @@ -25,7 +25,7 @@ * Schema is the class for retrieving metadata from an Oracle database. * * @property-read string $lastInsertID The row ID of the last row inserted, or the last value retrieved from - * the sequence object. This property is read-only. + * the sequence object. * * @author Qiang Xue * @since 2.0 @@ -372,7 +372,7 @@ protected function getTableSequenceName($tableName) /** * @Overrides method in class 'Schema' - * @see https://secure.php.net/manual/en/function.PDO-lastInsertId.php -> Oracle does not support this + * @see https://www.php.net/manual/en/function.PDO-lastInsertId.php -> Oracle does not support this * * Returns the ID of the last inserted row or sequence value. * @param string $sequenceName name of the sequence object (required by some DBMS) @@ -411,18 +411,20 @@ protected function createColumn($column) $c->phpType = $this->getColumnPhpType($c); if (!$c->isPrimaryKey) { - if (stripos($column['DATA_DEFAULT'], 'timestamp') !== false) { + if (stripos((string) $column['DATA_DEFAULT'], 'timestamp') !== false) { $c->defaultValue = null; } else { - $defaultValue = $column['DATA_DEFAULT']; + $defaultValue = (string) $column['DATA_DEFAULT']; if ($c->type === 'timestamp' && $defaultValue === 'CURRENT_TIMESTAMP') { $c->defaultValue = new Expression('CURRENT_TIMESTAMP'); } else { if ($defaultValue !== null) { - if (($len = strlen($defaultValue)) > 2 && $defaultValue[0] === "'" - && $defaultValue[$len - 1] === "'" + if ( + strlen($defaultValue) > 2 + && strncmp($defaultValue, "'", 1) === 0 + && substr($defaultValue, -1) === "'" ) { - $defaultValue = substr($column['DATA_DEFAULT'], 1, -1); + $defaultValue = substr($defaultValue, 1, -1); } else { $defaultValue = trim($defaultValue); } @@ -592,9 +594,9 @@ protected function extractColumnType($column, $dbType, $precision, $scale, $leng */ protected function extractColumnSize($column, $dbType, $precision, $scale, $length) { - $column->size = trim($length) === '' ? null : (int) $length; - $column->precision = trim($precision) === '' ? null : (int) $precision; - $column->scale = trim($scale) === '' ? null : (int) $scale; + $column->size = trim((string) $length) === '' ? null : (int) $length; + $column->precision = trim((string) $precision) === '' ? null : (int) $precision; + $column->scale = trim((string) $scale) === '' ? null : (int) $scale; } /** diff --git a/framework/db/oci/conditions/InConditionBuilder.php b/framework/db/oci/conditions/InConditionBuilder.php index 2a947759e94..e3f87a7b63f 100644 --- a/framework/db/oci/conditions/InConditionBuilder.php +++ b/framework/db/oci/conditions/InConditionBuilder.php @@ -39,7 +39,7 @@ public function build(ExpressionInterface $expression, array &$params = []) * * @param ExpressionInterface|InCondition $condition the expression to be built. * @param array $params the binding parameters. - * @return null|string null when split is not required. Otherwise - built SQL condition. + * @return string|null null when split is not required. Otherwise - built SQL condition. */ protected function splitCondition(InCondition $condition, &$params) { diff --git a/framework/db/pgsql/ArrayParser.php b/framework/db/pgsql/ArrayParser.php index 8ce08b24f5a..6a8ca148214 100644 --- a/framework/db/pgsql/ArrayParser.php +++ b/framework/db/pgsql/ArrayParser.php @@ -80,7 +80,7 @@ private function parseArray($value, &$i = 0) * * @param string $value * @param int $i parse starting position - * @return null|string + * @return string|null */ private function parseString($value, &$i) { diff --git a/framework/db/pgsql/QueryBuilder.php b/framework/db/pgsql/QueryBuilder.php index fa546c6d986..4d78c3c5d18 100644 --- a/framework/db/pgsql/QueryBuilder.php +++ b/framework/db/pgsql/QueryBuilder.php @@ -463,7 +463,7 @@ public function update($table, $columns, $condition, &$params) * @param array|Query $columns the column data (name => value) to be saved into the table or instance * of [[yii\db\Query|Query]] to perform INSERT INTO ... SELECT SQL statement. * Passing of [[yii\db\Query|Query]] is available since version 2.0.11. - * @return array normalized columns + * @return array|Query normalized columns * @since 2.0.9 */ private function normalizeTableRowData($table, $columns) diff --git a/framework/db/pgsql/Schema.php b/framework/db/pgsql/Schema.php index 75793d16d2c..7f6b9d018cc 100644 --- a/framework/db/pgsql/Schema.php +++ b/framework/db/pgsql/Schema.php @@ -232,7 +232,7 @@ protected function loadTableIndexes($tableName) INNER JOIN "pg_class" AS "ic" ON "ic"."oid" = "i"."indexrelid" INNER JOIN "pg_attribute" AS "ia" - ON "ia"."attrelid" = "i"."indrelid" AND "ia"."attnum" = ANY ("i"."indkey") + ON "ia"."attrelid" = "i"."indexrelid" WHERE "tcns"."nspname" = :schemaName AND "tc"."relname" = :tableName ORDER BY "ia"."attnum" ASC SQL; @@ -443,7 +443,7 @@ public function findUniqueIndexes($table) $row = array_change_key_case($row, CASE_LOWER); } $column = $row['columnname']; - if (!empty($column) && $column[0] === '"') { + if (strncmp($column, '"', 1) === 0) { // postgres will quote names that are not lowercase-only // https://github.com/yiisoft/yii2/issues/10613 $column = substr($column, 1, -1); @@ -476,6 +476,7 @@ protected function findColumns($table) a.attname AS column_name, COALESCE(td.typname, tb.typname, t.typname) AS data_type, COALESCE(td.typtype, tb.typtype, t.typtype) AS type_type, + (SELECT nspname FROM pg_namespace WHERE oid = COALESCE(td.typnamespace, tb.typnamespace, t.typnamespace)) AS type_scheme, a.attlen AS character_maximum_length, pg_catalog.col_description(c.oid, a.attnum) AS column_comment, a.atttypmod AS modifier, @@ -592,7 +593,12 @@ protected function loadColumnSchema($info) $column->allowNull = $info['is_nullable']; $column->autoIncrement = $info['is_autoinc']; $column->comment = $info['column_comment']; - $column->dbType = $info['data_type']; + if ($info['type_scheme'] !== null && !in_array($info['type_scheme'], [$this->defaultSchema, 'pg_catalog'], true) + ) { + $column->dbType = $info['type_scheme'] . '.' . $info['data_type']; + } else { + $column->dbType = $info['data_type']; + } $column->defaultValue = $info['column_default']; $column->enumValues = ($info['enum_values'] !== null) ? explode(',', str_replace(["''"], ["'"], $info['enum_values'])) : null; $column->unsigned = false; // has no meaning in PG @@ -601,7 +607,7 @@ protected function loadColumnSchema($info) $column->precision = $info['numeric_precision']; $column->scale = $info['numeric_scale']; $column->size = $info['size'] === null ? null : (int) $info['size']; - $column->dimension = (int)$info['dimension']; + $column->dimension = (int) $info['dimension']; // pg_get_serial_sequence() doesn't track DEFAULT value change. GENERATED BY IDENTITY columns always have null default value if (isset($column->defaultValue) && preg_match("/nextval\\('\"?\\w+\"?\.?\"?\\w+\"?'(::regclass)?\\)/", $column->defaultValue) === 1) { $column->sequenceName = preg_replace(['/nextval/', '/::/', '/regclass/', '/\'\)/', '/\(\'/'], '', $column->defaultValue); diff --git a/framework/db/sqlite/QueryBuilder.php b/framework/db/sqlite/QueryBuilder.php index dcf3dfc267f..8670f1af407 100644 --- a/framework/db/sqlite/QueryBuilder.php +++ b/framework/db/sqlite/QueryBuilder.php @@ -290,8 +290,8 @@ public function renameColumn($table, $oldName, $newName) * @param string $refTable the table that the foreign key references to. * @param string|array $refColumns the name of the column that the foreign key references to. * If there are multiple columns, separate them with commas or use an array to represent them. - * @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL - * @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL + * @param string|null $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL * @return string the SQL statement for adding a foreign key constraint to an existing table. * @throws NotSupportedException this is not supported by SQLite */ diff --git a/framework/db/sqlite/Schema.php b/framework/db/sqlite/Schema.php index 0b5a0cc8ec9..7f608399d0b 100644 --- a/framework/db/sqlite/Schema.php +++ b/framework/db/sqlite/Schema.php @@ -25,8 +25,7 @@ * Schema is the class for retrieving metadata from a SQLite (2/3) database. * * @property-write string $transactionIsolationLevel The transaction isolation level to use for this - * transaction. This can be either [[Transaction::READ_UNCOMMITTED]] or [[Transaction::SERIALIZABLE]]. This - * property is write-only. + * transaction. This can be either [[Transaction::READ_UNCOMMITTED]] or [[Transaction::SERIALIZABLE]]. * * @author Qiang Xue * @since 2.0 diff --git a/framework/db/sqlite/conditions/InConditionBuilder.php b/framework/db/sqlite/conditions/InConditionBuilder.php index 9ad84558c50..db980c346d5 100644 --- a/framework/db/sqlite/conditions/InConditionBuilder.php +++ b/framework/db/sqlite/conditions/InConditionBuilder.php @@ -8,6 +8,7 @@ namespace yii\db\sqlite\conditions; use yii\base\NotSupportedException; +use yii\db\Expression; /** * {@inheritdoc} @@ -37,12 +38,18 @@ protected function buildCompositeInCondition($operator, $columns, $values, &$par { $quotedColumns = []; foreach ($columns as $i => $column) { + if ($column instanceof Expression) { + $column = $column->expression; + } $quotedColumns[$i] = strpos($column, '(') === false ? $this->queryBuilder->db->quoteColumnName($column) : $column; } $vss = []; foreach ($values as $value) { $vs = []; foreach ($columns as $i => $column) { + if ($column instanceof Expression) { + $column = $column->expression; + } if (isset($value[$column])) { $phName = $this->queryBuilder->bindParam($value[$column], $params); $vs[] = $quotedColumns[$i] . ($operator === 'IN' ? ' = ' : ' != ') . $phName; diff --git a/framework/di/Container.php b/framework/di/Container.php index d6b396b6ed9..bfed9e5d9d6 100644 --- a/framework/di/Container.php +++ b/framework/di/Container.php @@ -9,6 +9,8 @@ use ReflectionClass; use ReflectionException; +use ReflectionNamedType; +use ReflectionParameter; use Yii; use yii\base\Component; use yii\base\InvalidConfigException; @@ -24,8 +26,8 @@ * Container supports constructor injection as well as property injection. * * To use Container, you first need to set up the class dependencies by calling [[set()]]. - * You then call [[get()]] to create a new class object. Container will automatically instantiate - * dependent objects, inject them into the object being created, configure and finally return the newly created object. + * You then call [[get()]] to create a new class object. The Container will automatically instantiate + * dependent objects, inject them into the object being created, configure, and finally return the newly created object. * * By default, [[\Yii::$container]] refers to a Container instance which is used by [[\Yii::createObject()]] * to create new object instances. You may use this method to replace the `new` operator @@ -93,9 +95,8 @@ * For more details and usage information on Container, see the [guide article on di-containers](guide:concept-di-container). * * @property-read array $definitions The list of the object definitions or the loaded shared objects (type or - * ID => definition or instance). This property is read-only. - * @property-write bool $resolveArrays Whether to attempt to resolve elements in array dependencies. This - * property is write-only. + * ID => definition or instance). + * @property-write bool $resolveArrays Whether to attempt to resolve elements in array dependencies. * * @author Qiang Xue * @since 2.0 @@ -144,7 +145,7 @@ class Container extends Component * In this case, the constructor parameters and object configurations will be used * only if the class is instantiated the first time. * - * @param string|Instance $class the class Instance, name or an alias name (e.g. `foo`) that was previously + * @param string|Instance $class the class Instance, name, or an alias name (e.g. `foo`) that was previously * registered via [[set()]] or [[setSingleton()]]. * @param array $params a list of constructor parameter values. Use one of two definitions: * - Parameters as name-value pairs, for example: `['posts' => PostRepository::class]`. @@ -294,7 +295,7 @@ public function setSingleton($class, $definition = [], array $params = []) /** * Returns a value indicating whether the container has the definition of the specified name. * @param string $class class name, interface name or alias name - * @return bool whether the container has the definition of the specified name.. + * @return bool Whether the container has the definition of the specified name. * @see set() */ public function has($class) @@ -493,7 +494,7 @@ protected function mergeParams($class, $params) * Returns the dependencies of the specified class. * @param string $class class name, interface name or alias name * @return array the dependencies of the specified class. - * @throws InvalidConfigException if a dependency cannot be resolved or if a dependency cannot be fulfilled. + * @throws NotInstantiableException if a dependency cannot be resolved or if a dependency cannot be fulfilled. */ protected function getDependencies($class) { @@ -505,7 +506,12 @@ protected function getDependencies($class) try { $reflection = new ReflectionClass($class); } catch (\ReflectionException $e) { - throw new InvalidConfigException('Failed to instantiate component or class "' . $class . '".', 0, $e); + throw new NotInstantiableException( + $class, + 'Failed to instantiate component or class "' . $class . '".', + 0, + $e + ); } $constructor = $reflection->getConstructor(); @@ -517,21 +523,36 @@ protected function getDependencies($class) if (PHP_VERSION_ID >= 80000) { $c = $param->getType(); - $isClass = $c !== null && !$param->getType()->isBuiltin(); + $isClass = false; + if ($c instanceof ReflectionNamedType) { + $isClass = !$c->isBuiltin(); + } } else { try { $c = $param->getClass(); } catch (ReflectionException $e) { - $c = null; + if (!$this->isNulledParam($param)) { + $notInstantiableClass = null; + if (PHP_VERSION_ID >= 70000) { + $type = $param->getType(); + if ($type instanceof ReflectionNamedType) { + $notInstantiableClass = $type->getName(); + } + } + throw new NotInstantiableException( + $notInstantiableClass, + $notInstantiableClass === null ? 'Can not instantiate unknown class.' : null + ); + } else { + $c = null; + } } $isClass = $c !== null; } $className = $isClass ? $c->getName() : null; - if ($className !== null && - ($this->has($className) || class_exists($className)) - ) { - $dependencies[$param->getName()] = Instance::of($className); + if ($className !== null) { + $dependencies[$param->getName()] = Instance::of($className, $this->isNulledParam($param)); } else { $dependencies[$param->getName()] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() @@ -546,10 +567,19 @@ protected function getDependencies($class) return [$reflection, $dependencies]; } + /** + * @param ReflectionParameter $param + * @return bool + */ + private function isNulledParam($param) + { + return $param->isOptional() || (PHP_VERSION_ID >= 70100 && $param->getType()->allowsNull()); + } + /** * Resolves dependencies by replacing them with the actual object instances. * @param array $dependencies the dependencies - * @param ReflectionClass $reflection the class reflection associated with the dependencies + * @param ReflectionClass|null $reflection the class reflection associated with the dependencies * @return array the resolved dependencies * @throws InvalidConfigException if a dependency cannot be resolved or if a dependency cannot be fulfilled. */ @@ -558,7 +588,7 @@ protected function resolveDependencies($dependencies, $reflection = null) foreach ($dependencies as $index => $dependency) { if ($dependency instanceof Instance) { if ($dependency->id !== null) { - $dependencies[$index] = $this->get($dependency->id); + $dependencies[$index] = $dependency->get($this); } elseif ($reflection !== null) { $name = $reflection->getConstructor()->getParameters()[$index]->getName(); $class = $reflection->getName(); @@ -575,8 +605,8 @@ protected function resolveDependencies($dependencies, $reflection = null) /** * Invoke a callback with resolving dependencies in parameters. * - * This methods allows invoking a callback and let type hinted parameter names to be - * resolved as objects of the Container. It additionally allow calling function using named parameters. + * This method allows invoking a callback and let type hinted parameter names to be + * resolved as objects of the Container. It additionally allows calling function using named parameters. * * For example, the following callback may be invoked using the Container to resolve the formatter dependency: * @@ -635,7 +665,19 @@ public function resolveCallableDependencies(callable $callback, $params = []) if (PHP_VERSION_ID >= 80000) { $class = $param->getType(); - $isClass = $class !== null && !$param->getType()->isBuiltin(); + if ($class instanceof \ReflectionUnionType || (PHP_VERSION_ID >= 80100 && $class instanceof \ReflectionIntersectionType)) { + $isClass = false; + foreach ($class->getTypes() as $type) { + if (!$type->isBuiltin()) { + $class = $type; + $isClass = true; + break; + } + } + } else { + $isClass = $class !== null && !$class->isBuiltin(); + } + } else { $class = $param->getClass(); $isClass = $class !== null; diff --git a/framework/di/Instance.php b/framework/di/Instance.php index af0044ce4ae..41af21af910 100644 --- a/framework/di/Instance.php +++ b/framework/di/Instance.php @@ -59,25 +59,32 @@ class Instance * @var string the component ID, class name, interface name or alias name */ public $id; + /** + * @var bool if null should be returned instead of throwing an exception + */ + public $optional; /** * Constructor. * @param string $id the component ID + * @param bool $optional if null should be returned instead of throwing an exception */ - protected function __construct($id) + protected function __construct($id, $optional = false) { $this->id = $id; + $this->optional = $optional; } /** * Creates a new Instance object. * @param string $id the component ID + * @param bool $optional if null should be returned instead of throwing an exception * @return Instance the new Instance object. */ - public static function of($id) + public static function of($id, $optional = false) { - return new static($id); + return new static($id, $optional); } /** @@ -94,17 +101,17 @@ public static function of($id) * use yii\db\Connection; * * // returns Yii::$app->db - * $db = Instance::ensure('db', Connection::className()); + * $db = Instance::ensure('db', Connection::class); * // returns an instance of Connection using the given configuration - * $db = Instance::ensure(['dsn' => 'sqlite:path/to/my.db'], Connection::className()); + * $db = Instance::ensure(['dsn' => 'sqlite:path/to/my.db'], Connection::class); * ``` * * @param object|string|array|static $reference an object or a reference to the desired object. * You may specify a reference in terms of a component ID or an Instance object. * Starting from version 2.0.2, you may also pass in a configuration array for creating the object. * If the "class" value is not specified in the configuration array, it will use the value of `$type`. - * @param string $type the class/interface name to be checked. If null, type check will not be performed. - * @param ServiceLocator|Container $container the container. This will be passed to [[get()]]. + * @param string|null $type the class/interface name to be checked. If null, type check will not be performed. + * @param ServiceLocator|Container|null $container the container. This will be passed to [[get()]]. * @return object the object referenced by the Instance, or `$reference` itself if it is an object. * @throws InvalidConfigException if the reference is invalid */ @@ -151,20 +158,32 @@ public static function ensure($reference, $type = null, $container = null) /** * Returns the actual object referenced by this Instance object. - * @param ServiceLocator|Container $container the container used to locate the referenced object. + * @param ServiceLocator|Container|null $container the container used to locate the referenced object. * If null, the method will first try `Yii::$app` then `Yii::$container`. * @return object the actual object referenced by this Instance object. */ public function get($container = null) { - if ($container) { - return $container->get($this->id); - } - if (Yii::$app && Yii::$app->has($this->id)) { - return Yii::$app->get($this->id); - } + try { + if ($container) { + return $container->get($this->id); + } + if (Yii::$app && Yii::$app->has($this->id)) { + return Yii::$app->get($this->id); + } - return Yii::$container->get($this->id); + return Yii::$container->get($this->id); + } catch (\Exception $e) { + if ($this->optional) { + return null; + } + throw $e; + } catch (\Throwable $e) { + if ($this->optional) { + return null; + } + throw $e; + } } /** @@ -173,7 +192,7 @@ public function get($container = null) * @param array $state * @return Instance * @throws InvalidConfigException when $state property does not contain `id` parameter - * @see var_export() + * @see https://www.php.net/manual/en/function.var-export.php * @since 2.0.12 */ public static function __set_state($state) diff --git a/framework/di/NotInstantiableException.php b/framework/di/NotInstantiableException.php index c80332ae08c..ccde5bf1c58 100644 --- a/framework/di/NotInstantiableException.php +++ b/framework/di/NotInstantiableException.php @@ -21,7 +21,7 @@ class NotInstantiableException extends InvalidConfigException /** * {@inheritdoc} */ - public function __construct($class, $message = null, $code = 0, \Exception $previous = null) + public function __construct($class, $message = null, $code = 0, $previous = null) { if ($message === null) { $message = "Can not instantiate $class."; diff --git a/framework/filters/AccessControl.php b/framework/filters/AccessControl.php index 4224f487265..d8a17d51469 100644 --- a/framework/filters/AccessControl.php +++ b/framework/filters/AccessControl.php @@ -31,7 +31,7 @@ * { * return [ * 'access' => [ - * 'class' => \yii\filters\AccessControl::className(), + * 'class' => \yii\filters\AccessControl::class, * 'only' => ['create', 'update'], * 'rules' => [ * // deny all POST requests @@ -63,7 +63,7 @@ class AccessControl extends ActionFilter */ public $user = 'user'; /** - * @var callable a callback that will be called if the access should be denied + * @var callable|null a callback that will be called if the access should be denied * to the current user. This is the case when either no rule matches, or a rule with * [[AccessRule::$allow|$allow]] set to `false` matches. * If not set, [[denyAccess()]] will be called. diff --git a/framework/filters/AccessRule.php b/framework/filters/AccessRule.php index 606c1701026..25251e5fc60 100644 --- a/framework/filters/AccessRule.php +++ b/framework/filters/AccessRule.php @@ -28,14 +28,14 @@ class AccessRule extends Component /** * @var bool whether this is an 'allow' rule or 'deny' rule. */ - public $allow; + public $allow = false; /** - * @var array list of action IDs that this rule applies to. The comparison is case-sensitive. + * @var array|null list of action IDs that this rule applies to. The comparison is case-sensitive. * If not set or empty, it means this rule applies to all actions. */ public $actions; /** - * @var array list of the controller IDs that this rule applies to. + * @var array|null list of the controller IDs that this rule applies to. * * The comparison uses [[\yii\base\Controller::uniqueId]], so each controller ID is prefixed * with the module ID (if any). For a `product` controller in the application, you would specify @@ -50,7 +50,7 @@ class AccessRule extends Component */ public $controllers; /** - * @var array list of roles that this rule applies to (requires properly configured User component). + * @var array|null list of roles that this rule applies to (requires properly configured User component). * Two special roles are recognized, and they are checked via [[User::isGuest]]: * * - `?`: matches a guest user (not authenticated yet) @@ -62,18 +62,18 @@ class AccessRule extends Component * Note that it is preferred to check for permissions instead. * * If this property is not set or empty, it means this rule applies regardless of roles. - * @see $permissions - * @see $roleParams + * @see permissions + * @see roleParams */ public $roles; - /** - * @var array list of RBAC (Role-Based Access Control) permissions that this rules applies to. + /** + * @var array|null list of RBAC (Role-Based Access Control) permissions that this rules applies to. * [[User::can()]] will be called to check access. - * + * * If this property is not set or empty, it means this rule applies regardless of permissions. * @since 2.0.12 - * @see $roles - * @see $roleParams + * @see roles + * @see roleParams */ public $permissions; /** @@ -106,12 +106,12 @@ class AccessRule extends Component * * A reference to the [[AccessRule]] instance will be passed to the closure as the first parameter. * - * @see $roles + * @see roles * @since 2.0.12 */ public $roleParams = []; /** - * @var array list of user IP addresses that this rule applies to. An IP address + * @var array|null list of user IP addresses that this rule applies to. An IP address * can contain the wildcard `*` at the end so that it matches IP addresses with the same prefix. * For example, '192.168.*' matches all IP addresses in the segment '192.168.'. * It may also contain a pattern/mask like '172.16.0.0/12' which would match all IPs from the @@ -122,7 +122,7 @@ class AccessRule extends Component */ public $ips; /** - * @var array list of request methods (e.g. `GET`, `POST`) that this rule applies to. + * @var array|null list of request methods (e.g. `GET`, `POST`) that this rule applies to. * If not set or empty, it means this rule applies to all request methods. * @see \yii\web\Request::method */ @@ -140,7 +140,7 @@ class AccessRule extends Component */ public $matchCallback; /** - * @var callable a callback that will be called if this rule determines the access to + * @var callable|null a callback that will be called if this rule determines the access to * the current action should be denied. This is the case when this rule matches * and [[$allow]] is set to `false`. * @@ -264,16 +264,17 @@ protected function matchIP($ip) return true; } foreach ($this->ips as $rule) { - if ($rule === '*' || - $rule === $ip || - ( - $ip !== null && - ($pos = strpos($rule, '*')) !== false && - strncmp($ip, $rule, $pos) === 0 - ) || - ( - ($pos = strpos($rule, '/')) !== false && - IpHelper::inRange($ip, $rule) === true + if ( + $rule === '*' + || $rule === $ip + || ( + $ip !== null + && ($pos = strpos($rule, '*')) !== false + && strncmp($ip, $rule, $pos) === 0 + ) + || ( + strpos($rule, '/') !== false + && IpHelper::inRange($ip, $rule) === true ) ) { return true; diff --git a/framework/filters/AjaxFilter.php b/framework/filters/AjaxFilter.php index 265f01a5705..65becc8b506 100644 --- a/framework/filters/AjaxFilter.php +++ b/framework/filters/AjaxFilter.php @@ -37,7 +37,7 @@ class AjaxFilter extends ActionFilter */ public $errorMessage = 'Request must be XMLHttpRequest.'; /** - * @var Request the current request. If not set, the `request` application component will be used. + * @var Request|null the current request. If not set, the `request` application component will be used. */ public $request; diff --git a/framework/filters/ContentNegotiator.php b/framework/filters/ContentNegotiator.php index 760c4a0fab2..8414f702445 100644 --- a/framework/filters/ContentNegotiator.php +++ b/framework/filters/ContentNegotiator.php @@ -102,7 +102,7 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface */ public $languageParam = '_lang'; /** - * @var array list of supported response formats. The keys are MIME types (e.g. `application/json`) + * @var array|null list of supported response formats. The keys are MIME types (e.g. `application/json`) * while the values are the corresponding formats (e.g. `html`, `json`) which must be supported * as declared in [[\yii\web\Response::$formatters]]. * @@ -110,7 +110,7 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface */ public $formats; /** - * @var array a list of supported languages. The array keys are the supported language variants (e.g. `en-GB`, `en-US`), + * @var array|null a list of supported languages. The array keys are the supported language variants (e.g. `en-GB`, `en-US`), * while the array values are the corresponding language codes (e.g. `en`, `de`) recognized by the application. * * Array keys are not always required. When an array value does not have a key, the matching of the requested language @@ -124,7 +124,7 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface */ public $request; /** - * @var Response the response to be sent. If not set, the `response` application component will be used. + * @var Response|null the response to be sent. If not set, the `response` application component will be used. */ public $response; diff --git a/framework/filters/Cors.php b/framework/filters/Cors.php index cdfe280868d..34cc5435649 100644 --- a/framework/filters/Cors.php +++ b/framework/filters/Cors.php @@ -26,7 +26,7 @@ * { * return [ * 'corsFilter' => [ - * 'class' => \yii\filters\Cors::className(), + * 'class' => \yii\filters\Cors::class, * ], * ]; * } @@ -40,7 +40,7 @@ * { * return [ * 'corsFilter' => [ - * 'class' => \yii\filters\Cors::className(), + * 'class' => \yii\filters\Cors::class, * 'cors' => [ * // restrict access to * 'Origin' => ['http://www.myserver.com', 'https://www.myserver.com'], @@ -70,11 +70,11 @@ class Cors extends ActionFilter { /** - * @var Request the current request. If not set, the `request` application component will be used. + * @var Request|null the current request. If not set, the `request` application component will be used. */ public $request; /** - * @var Response the response to be sent. If not set, the `response` application component will be used. + * @var Response|null the response to be sent. If not set, the `response` application component will be used. */ public $response; /** @@ -197,7 +197,7 @@ public function prepareHeaders($requestHeaders) if (isset($this->cors['Access-Control-Expose-Headers'])) { $responseHeaders['Access-Control-Expose-Headers'] = implode(', ', $this->cors['Access-Control-Expose-Headers']); } - + if (isset($this->cors['Access-Control-Allow-Headers'])) { $responseHeaders['Access-Control-Allow-Headers'] = implode(', ', $this->cors['Access-Control-Allow-Headers']); } diff --git a/framework/filters/HostControl.php b/framework/filters/HostControl.php index 0c9b7fbc2c2..b2f76fdb515 100644 --- a/framework/filters/HostControl.php +++ b/framework/filters/HostControl.php @@ -45,7 +45,7 @@ * { * return [ * 'hostControl' => [ - * 'class' => HostControl::className(), + * 'class' => HostControl::class, * 'allowedHosts' => [ * 'example.com', * '*.example.com', @@ -91,7 +91,7 @@ class HostControl extends ActionFilter */ public $allowedHosts; /** - * @var callable a callback that will be called if the current host does not match [[allowedHosts]]. + * @var callable|null a callback that will be called if the current host does not match [[allowedHosts]]. * If not set, [[denyAccess()]] will be called. * * The signature of the callback should be as follows: diff --git a/framework/filters/HttpCache.php b/framework/filters/HttpCache.php index 4964e59be75..cfc9c152aa7 100644 --- a/framework/filters/HttpCache.php +++ b/framework/filters/HttpCache.php @@ -86,15 +86,15 @@ class HttpCache extends ActionFilter */ public $params; /** - * @var string the value of the `Cache-Control` HTTP header. If null, the header will not be sent. + * @var string|null the value of the `Cache-Control` HTTP header. If null, the header will not be sent. * @see http://tools.ietf.org/html/rfc2616#section-14.9 */ public $cacheControlHeader = 'public, max-age=3600'; /** - * @var string the name of the cache limiter to be set when [session_cache_limiter()](https://secure.php.net/manual/en/function.session-cache-limiter.php) + * @var string|null the name of the cache limiter to be set when [session_cache_limiter()](https://www.php.net/manual/en/function.session-cache-limiter.php) * is called. The default value is an empty string, meaning turning off automatic sending of cache headers entirely. * You may set this property to be `public`, `private`, `private_no_expire`, and `nocache`. - * Please refer to [session_cache_limiter()](https://secure.php.net/manual/en/function.session-cache-limiter.php) + * Please refer to [session_cache_limiter()](https://www.php.net/manual/en/function.session-cache-limiter.php) * for detailed explanation of these values. * * If this property is `null`, then `session_cache_limiter()` will not be called. As a result, @@ -158,9 +158,9 @@ public function beforeAction($action) /** * Validates if the HTTP cache contains valid content. * If both Last-Modified and ETag are null, returns false. - * @param int $lastModified the calculated Last-Modified value in terms of a UNIX timestamp. + * @param int|null $lastModified the calculated Last-Modified value in terms of a UNIX timestamp. * If null, the Last-Modified header will not be validated. - * @param string $etag the calculated ETag value. If null, the ETag header will not be validated. + * @param string|null $etag the calculated ETag value. If null, the ETag header will not be validated. * @return bool whether the HTTP cache is still valid. */ protected function validateCache($lastModified, $etag) diff --git a/framework/filters/PageCache.php b/framework/filters/PageCache.php index 774e8dbd479..6fd7e9d8f4a 100644 --- a/framework/filters/PageCache.php +++ b/framework/filters/PageCache.php @@ -116,7 +116,7 @@ class PageCache extends ActionFilter implements DynamicContentAwareInterface */ public $enabled = true; /** - * @var \yii\base\View the view component to use for caching. If not set, the default application view component + * @var \yii\base\View|null the view component to use for caching. If not set, the default application view component * [[\yii\web\Application::view]] will be used. */ public $view; @@ -124,15 +124,13 @@ class PageCache extends ActionFilter implements DynamicContentAwareInterface * @var bool|array a boolean value indicating whether to cache all cookies, or an array of * cookie names indicating which cookies can be cached. Be very careful with caching cookies, because * it may leak sensitive or private data stored in cookies to unwanted users. - * @see insertResponseCollectionIntoData() * @since 2.0.4 */ public $cacheCookies = false; /** * @var bool|array a boolean value indicating whether to cache all HTTP headers, or an array of - * HTTP header names (case-insensitive) indicating which HTTP headers can be cached. + * HTTP header names (case-sensitive) indicating which HTTP headers can be cached. * Note if your HTTP headers contain sensitive information, you should white-list which headers can be cached. - * @see insertResponseCollectionIntoData() * @since 2.0.4 */ public $cacheHeaders = true; @@ -255,40 +253,59 @@ public function cacheResponse() foreach (['format', 'version', 'statusCode', 'statusText'] as $name) { $data[$name] = $response->{$name}; } - $this->insertResponseCollectionIntoData($response, 'headers', $data); - $this->insertResponseCollectionIntoData($response, 'cookies', $data); + $this->insertResponseHeaderCollectionIntoData($response, $data); + $this->insertResponseCookieCollectionIntoData($response, $data); $this->cache->set($this->calculateCacheKey(), $data, $this->duration, $this->dependency); $data['content'] = $this->updateDynamicContent($data['content'], $this->getDynamicPlaceholders()); echo $data['content']; } /** - * Inserts (or filters/ignores according to config) response headers/cookies into a cache data array. + * Inserts (or filters/ignores according to config) response cookies into a cache data array. * @param Response $response the response. - * @param string $collectionName currently it's `headers` or `cookies`. * @param array $data the cache data. */ - private function insertResponseCollectionIntoData(Response $response, $collectionName, array &$data) + private function insertResponseCookieCollectionIntoData(Response $response, array &$data) { - $property = 'cache' . ucfirst($collectionName); - if ($this->{$property} === false) { + if ($this->cacheCookies === false) { return; } - $all = $response->{$collectionName}->toArray(); - if (is_array($this->{$property})) { + $all = $response->cookies->toArray(); + if (is_array($this->cacheCookies)) { $filtered = []; - foreach ($this->{$property} as $name) { - if ($collectionName === 'headers') { - $name = strtolower($name); + foreach ($this->cacheCookies as $name) { + if (isset($all[$name])) { + $filtered[$name] = $all[$name]; } + } + $all = $filtered; + } + $data['cookies'] = $all; + } + + /** + * Inserts (or filters/ignores according to config) response headers into a cache data array. + * @param Response $response the response. + * @param array $data the cache data. + */ + private function insertResponseHeaderCollectionIntoData(Response $response, array &$data) + { + if ($this->cacheHeaders === false) { + return; + } + + $all = $response->headers->toOriginalArray(); + if (is_array($this->cacheHeaders)) { + $filtered = []; + foreach ($this->cacheHeaders as $name) { if (isset($all[$name])) { $filtered[$name] = $all[$name]; } } $all = $filtered; } - $data[$collectionName] = $all; + $data['headers'] = $all; } /** diff --git a/framework/filters/RateLimiter.php b/framework/filters/RateLimiter.php index daa8310d269..7ab7241539c 100644 --- a/framework/filters/RateLimiter.php +++ b/framework/filters/RateLimiter.php @@ -24,7 +24,7 @@ * { * return [ * 'rateLimiter' => [ - * 'class' => \yii\filters\RateLimiter::className(), + * 'class' => \yii\filters\RateLimiter::class, * ], * ]; * } @@ -49,7 +49,7 @@ class RateLimiter extends ActionFilter */ public $errorMessage = 'Rate limit exceeded.'; /** - * @var RateLimitInterface|Closure the user object that implements the RateLimitInterface. If not set, it will take the value of `Yii::$app->user->getIdentity(false)`. + * @var RateLimitInterface|Closure|null the user object that implements the RateLimitInterface. If not set, it will take the value of `Yii::$app->user->getIdentity(false)`. * {@since 2.0.38} It's possible to provide a closure function in order to assign the user identity on runtime. Using a closure to assign the user identity is recommend * when you are **not** using the standard `Yii::$app->user` component. See the example below: * ```php @@ -60,11 +60,11 @@ class RateLimiter extends ActionFilter */ public $user; /** - * @var Request the current request. If not set, the `request` application component will be used. + * @var Request|null the current request. If not set, the `request` application component will be used. */ public $request; /** - * @var Response the response to be sent. If not set, the `response` application component will be used. + * @var Response|null the response to be sent. If not set, the `response` application component will be used. */ public $response; diff --git a/framework/filters/VerbFilter.php b/framework/filters/VerbFilter.php index 272797c21cf..76b6d9e4fe0 100644 --- a/framework/filters/VerbFilter.php +++ b/framework/filters/VerbFilter.php @@ -28,7 +28,7 @@ * { * return [ * 'verbs' => [ - * 'class' => \yii\filters\VerbFilter::className(), + * 'class' => \yii\filters\VerbFilter::class, * 'actions' => [ * 'index' => ['GET'], * 'view' => ['GET'], @@ -57,6 +57,8 @@ class VerbFilter extends Behavior * You can use `'*'` to stand for all actions. When an action is explicitly * specified, it takes precedence over the specification given by `'*'`. * + * @see https://www.yiiframework.com/doc/guide/2.0/en/structure-controllers#action-ids + * * For example, * * ```php @@ -64,6 +66,7 @@ class VerbFilter extends Behavior * 'create' => ['GET', 'POST'], * 'update' => ['GET', 'PUT', 'POST'], * 'delete' => ['POST', 'DELETE'], + * 'author-comment' => ['POST', 'DELETE'], * '*' => ['GET'], * ] * ``` diff --git a/framework/filters/auth/AuthInterface.php b/framework/filters/auth/AuthInterface.php index 492d314ca3a..02d20cf2754 100644 --- a/framework/filters/auth/AuthInterface.php +++ b/framework/filters/auth/AuthInterface.php @@ -26,7 +26,7 @@ interface AuthInterface * @param User $user * @param Request $request * @param Response $response - * @return IdentityInterface the authenticated user identity. If authentication information is not provided, null will be returned. + * @return IdentityInterface|null the authenticated user identity. If authentication information is not provided, null will be returned. * @throws UnauthorizedHttpException if authentication information is provided but is invalid. */ public function authenticate($user, $request, $response); diff --git a/framework/filters/auth/AuthMethod.php b/framework/filters/auth/AuthMethod.php index 9dcba078c30..6612e67fc4a 100644 --- a/framework/filters/auth/AuthMethod.php +++ b/framework/filters/auth/AuthMethod.php @@ -25,15 +25,15 @@ abstract class AuthMethod extends ActionFilter implements AuthInterface { /** - * @var User the user object representing the user authentication status. If not set, the `user` application component will be used. + * @var User|null the user object representing the user authentication status. If not set, the `user` application component will be used. */ public $user; /** - * @var Request the current request. If not set, the `request` application component will be used. + * @var Request|null the current request. If not set, the `request` application component will be used. */ public $request; /** - * @var Response the response to be sent. If not set, the `response` application component will be used. + * @var Response|null the response to be sent. If not set, the `response` application component will be used. */ public $response; /** diff --git a/framework/filters/auth/CompositeAuth.php b/framework/filters/auth/CompositeAuth.php index 3b63c5af4ae..37043d4235d 100644 --- a/framework/filters/auth/CompositeAuth.php +++ b/framework/filters/auth/CompositeAuth.php @@ -23,10 +23,10 @@ * { * return [ * 'compositeAuth' => [ - * 'class' => \yii\filters\auth\CompositeAuth::className(), + * 'class' => \yii\filters\auth\CompositeAuth::class, * 'authMethods' => [ - * \yii\filters\auth\HttpBasicAuth::className(), - * \yii\filters\auth\QueryParamAuth::className(), + * \yii\filters\auth\HttpBasicAuth::class, + * \yii\filters\auth\QueryParamAuth::class, * ], * ], * ]; diff --git a/framework/filters/auth/HttpBasicAuth.php b/framework/filters/auth/HttpBasicAuth.php index 3d60077f6ae..03420efd70c 100644 --- a/framework/filters/auth/HttpBasicAuth.php +++ b/framework/filters/auth/HttpBasicAuth.php @@ -17,7 +17,7 @@ * { * return [ * 'basicAuth' => [ - * 'class' => \yii\filters\auth\HttpBasicAuth::className(), + * 'class' => \yii\filters\auth\HttpBasicAuth::class, * ], * ]; * } @@ -34,10 +34,10 @@ * { * return [ * 'basicAuth' => [ - * 'class' => \yii\filters\auth\HttpBasicAuth::className(), + * 'class' => \yii\filters\auth\HttpBasicAuth::class, * 'auth' => function ($username, $password) { * $user = User::find()->where(['username' => $username])->one(); - * if ($user->verifyPassword($password)) { + * if ($user && $user->validatePassword($password)) { * return $user; * } * return null; @@ -64,7 +64,7 @@ class HttpBasicAuth extends AuthMethod */ public $realm = 'api'; /** - * @var callable a PHP callable that will authenticate the user with the HTTP basic auth information. + * @var callable|null a PHP callable that will authenticate the user with the HTTP basic auth information. * The callable receives a username and a password as its parameters. It should return an identity object * that matches the username and password. Null should be returned if there is no such identity. * The callable will be called only if current user is not authenticated. diff --git a/framework/filters/auth/HttpBearerAuth.php b/framework/filters/auth/HttpBearerAuth.php index 82b97762746..f5fb80a97df 100644 --- a/framework/filters/auth/HttpBearerAuth.php +++ b/framework/filters/auth/HttpBearerAuth.php @@ -17,7 +17,7 @@ * { * return [ * 'bearerAuth' => [ - * 'class' => \yii\filters\auth\HttpBearerAuth::className(), + * 'class' => \yii\filters\auth\HttpBearerAuth::class, * ], * ]; * } diff --git a/framework/filters/auth/HttpHeaderAuth.php b/framework/filters/auth/HttpHeaderAuth.php index ea32b7050bb..1b0dbbff152 100644 --- a/framework/filters/auth/HttpHeaderAuth.php +++ b/framework/filters/auth/HttpHeaderAuth.php @@ -17,7 +17,7 @@ * { * return [ * 'basicAuth' => [ - * 'class' => \yii\filters\auth\HttpHeaderAuth::className(), + * 'class' => \yii\filters\auth\HttpHeaderAuth::class, * ], * ]; * } diff --git a/framework/grid/ActionColumn.php b/framework/grid/ActionColumn.php index 85400958786..e54ba3c3d2d 100644 --- a/framework/grid/ActionColumn.php +++ b/framework/grid/ActionColumn.php @@ -20,7 +20,7 @@ * 'columns' => [ * // ... * [ - * 'class' => ActionColumn::className(), + * 'class' => ActionColumn::class, * // you may configure additional properties here * ], * ] @@ -38,7 +38,7 @@ class ActionColumn extends Column */ public $headerOptions = ['class' => 'action-column']; /** - * @var string the ID of the controller that should handle the actions specified here. + * @var string|null the ID of the controller that should handle the actions specified here. * If not set, it will use the currently active controller. This property is mainly used by * [[urlCreator]] to create URLs for different actions. The value of this property will be prefixed * to each action name to form the route of the action. @@ -86,6 +86,23 @@ class ActionColumn extends Column * ``` */ public $buttons = []; + /** + * @var array button icons. The array keys are the icon names and the values the corresponding html: + * ```php + * [ + * 'eye-open' => '', + * 'pencil' => Html::tag('span', '', ['class' => 'glyphicon glyphicon-pencil']) + * ] + * ``` + * Defaults to FontAwesome 5 free svg icons. + * @since 2.0.42 + * @see https://fontawesome.com + */ + public $icons = [ + 'eye-open' => '', + 'pencil' => '', + 'trash' => '' + ]; /** @var array visibility conditions for each button. The array keys are the button names (without curly brackets), * and the values are the boolean true/false or the anonymous function. When the button name is not specified in * this array it will be shown by default. @@ -108,7 +125,7 @@ class ActionColumn extends Column */ public $visibleButtons = []; /** - * @var callable a callback that creates a button URL using the specified model information. + * @var callable|null a callback that creates a button URL using the specified model information. * The signature of the callback should be the same as that of [[createUrl()]] * Since 2.0.10 it can accept additional parameter, which refers to the column instance itself: * @@ -179,7 +196,9 @@ protected function initDefaultButton($name, $iconName, $additionalOptions = []) 'aria-label' => $title, 'data-pjax' => '0', ], $additionalOptions, $this->buttonOptions); - $icon = Html::tag('span', '', ['class' => "glyphicon glyphicon-$iconName"]); + $icon = isset($this->icons[$iconName]) + ? $this->icons[$iconName] + : Html::tag('span', '', ['class' => "glyphicon glyphicon-$iconName"]); return Html::a($icon, $url, $options); }; } diff --git a/framework/grid/Column.php b/framework/grid/Column.php index 465a8551044..4139440e2b2 100644 --- a/framework/grid/Column.php +++ b/framework/grid/Column.php @@ -26,7 +26,7 @@ class Column extends BaseObject */ public $grid; /** - * @var string the header cell content. Note that it will not be HTML-encoded. + * @var string|null the header cell content. Note that it will not be HTML-encoded. */ public $header; /** @@ -127,7 +127,7 @@ public function renderFilterCell() */ protected function renderHeaderCellContent() { - return trim($this->header) !== '' ? $this->header : $this->getHeaderCellLabel(); + return $this->header !== null && trim($this->header) !== '' ? $this->header : $this->getHeaderCellLabel(); } /** @@ -149,7 +149,7 @@ protected function getHeaderCellLabel() */ protected function renderFooterCellContent() { - return trim($this->footer) !== '' ? $this->footer : $this->grid->emptyCell; + return $this->footer !== null && trim($this->footer) !== '' ? $this->footer : $this->grid->emptyCell; } /** diff --git a/framework/grid/DataColumn.php b/framework/grid/DataColumn.php index 53c18b6b8aa..98d70bd7c8b 100644 --- a/framework/grid/DataColumn.php +++ b/framework/grid/DataColumn.php @@ -46,7 +46,7 @@ class DataColumn extends Column */ public $attribute; /** - * @var string label to be displayed in the [[header|header cell]] and also to be used as the sorting + * @var string|null label to be displayed in the [[header|header cell]] and also to be used as the sorting * link label when sorting is enabled for this column. * If it is not set and the models provided by the GridViews data provider are instances * of [[\yii\db\ActiveRecord]], the label will be determined using [[\yii\db\ActiveRecord::getAttributeLabel()]]. @@ -60,7 +60,7 @@ class DataColumn extends Column */ public $encodeLabel = true; /** - * @var string|Closure an anonymous function or a string that is used to determine the value to display in the current column. + * @var string|Closure|null an anonymous function or a string that is used to determine the value to display in the current column. * * If this is an anonymous function, it will be called for each row and the return value will be used as the value to * display for every data model. The signature of this function should be: `function ($model, $key, $index, $column)`. @@ -117,7 +117,24 @@ class DataColumn extends Column * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. */ public $filterInputOptions = ['class' => 'form-control', 'id' => null]; + /** + * @var string|null the attribute name of the [[GridView::filterModel]] associated with this column. If not set, + * will have the same value as [[attribute]]. + * @since 2.0.41 + */ + public $filterAttribute; + + /** + * {@inheritdoc} + */ + public function init() + { + parent::init(); + if($this->filterAttribute === null) { + $this->filterAttribute = $this->attribute; + } + } /** * {@inheritdoc} @@ -150,7 +167,9 @@ protected function getHeaderCellLabel() $provider = $this->grid->dataProvider; if ($this->label === null) { - if ($provider instanceof ActiveDataProvider && $provider->query instanceof ActiveQueryInterface) { + if ($this->attribute === null) { + $label = ''; + } elseif ($provider instanceof ActiveDataProvider && $provider->query instanceof ActiveQueryInterface) { /* @var $modelClass Model */ $modelClass = $provider->query->modelClass; $model = $modelClass::instance(); @@ -161,7 +180,7 @@ protected function getHeaderCellLabel() $model = $modelClass::instance(); $label = $model->getAttributeLabel($this->attribute); } elseif ($this->grid->filterModel !== null && $this->grid->filterModel instanceof Model) { - $label = $this->grid->filterModel->getAttributeLabel($this->attribute); + $label = $this->grid->filterModel->getAttributeLabel($this->filterAttribute); } else { $models = $provider->getModels(); if (($model = reset($models)) instanceof Model) { @@ -189,25 +208,26 @@ protected function renderFilterCellContent() $model = $this->grid->filterModel; - if ($this->filter !== false && $model instanceof Model && $this->attribute !== null && $model->isAttributeActive($this->attribute)) { - if ($model->hasErrors($this->attribute)) { + if ($this->filter !== false && $model instanceof Model && $this->filterAttribute !== null && $model->isAttributeActive($this->filterAttribute)) { + if ($model->hasErrors($this->filterAttribute)) { Html::addCssClass($this->filterOptions, 'has-error'); - $error = ' ' . Html::error($model, $this->attribute, $this->grid->filterErrorOptions); + $error = ' ' . Html::error($model, $this->filterAttribute, $this->grid->filterErrorOptions); } else { $error = ''; } if (is_array($this->filter)) { $options = array_merge(['prompt' => ''], $this->filterInputOptions); - return Html::activeDropDownList($model, $this->attribute, $this->filter, $options) . $error; + return Html::activeDropDownList($model, $this->filterAttribute, $this->filter, $options) . $error; } elseif ($this->format === 'boolean') { $options = array_merge(['prompt' => ''], $this->filterInputOptions); - return Html::activeDropDownList($model, $this->attribute, [ + return Html::activeDropDownList($model, $this->filterAttribute, [ 1 => $this->grid->formatter->booleanFormat[1], 0 => $this->grid->formatter->booleanFormat[0], ], $options) . $error; } + $options = array_merge(['maxlength' => true], $this->filterInputOptions); - return Html::activeTextInput($model, $this->attribute, $this->filterInputOptions) . $error; + return Html::activeTextInput($model, $this->filterAttribute, $options) . $error; } return parent::renderFilterCellContent(); diff --git a/framework/grid/GridView.php b/framework/grid/GridView.php index 6de342d86c8..c1b6a6b386f 100644 --- a/framework/grid/GridView.php +++ b/framework/grid/GridView.php @@ -137,7 +137,7 @@ class GridView extends BaseListView */ public $showOnEmpty = true; /** - * @var array|Formatter the formatter used to format model attribute values into displayable texts. + * @var array|Formatter|null the formatter used to format model attribute values into displayable texts. * This can be either an instance of [[Formatter]] or an configuration array for creating the [[Formatter]] * instance. If this property is not set, the "formatter" application component will be used. */ @@ -148,14 +148,14 @@ class GridView extends BaseListView * * ```php * [ - * ['class' => SerialColumn::className()], + * ['class' => SerialColumn::class], * [ - * 'class' => DataColumn::className(), // this line is optional + * 'class' => DataColumn::class, // this line is optional * 'attribute' => 'name', * 'format' => 'text', * 'label' => 'Name', * ], - * ['class' => CheckboxColumn::className()], + * ['class' => CheckboxColumn::class], * ] * ``` * @@ -202,7 +202,7 @@ class GridView extends BaseListView */ public $emptyCell = ' '; /** - * @var \yii\base\Model the model that keeps the user-entered filter data. When this property is set, + * @var \yii\base\Model|null the model that keeps the user-entered filter data. When this property is set, * the grid view will enable column-based filtering. Each data column by default will display a text field * at the top that users can fill in to filter the data. * @@ -214,7 +214,7 @@ class GridView extends BaseListView */ public $filterModel; /** - * @var string|array the URL for returning the filtering result. [[Url::to()]] will be called to + * @var string|array|null the URL for returning the filtering result. [[Url::to()]] will be called to * normalize the URL. If not set, the current controller action will be used. * When the user makes change to any filter input, the current filtering inputs will be appended * as GET parameters to this URL. @@ -359,7 +359,7 @@ public function renderItems() $tableFooter = false; $tableFooterAfterBody = false; - + if ($this->showFooter) { if ($this->placeFooterAfterBody) { $tableFooterAfterBody = $this->renderTableFooter(); diff --git a/framework/helpers/BaseArrayHelper.php b/framework/helpers/BaseArrayHelper.php index e30d0c070e1..84e67f43b5d 100644 --- a/framework/helpers/BaseArrayHelper.php +++ b/framework/helpers/BaseArrayHelper.php @@ -7,9 +7,9 @@ namespace yii\helpers; +use Yii; use ArrayAccess; use Traversable; -use Yii; use yii\base\Arrayable; use yii\base\InvalidArgumentException; @@ -70,6 +70,8 @@ public static function toArray($object, $properties = [], $recursive = true) } return $object; + } elseif ($object instanceof \DateTimeInterface) { + return (array)$object; } elseif (is_object($object)) { if (!empty($properties)) { $className = get_class($object); @@ -196,6 +198,10 @@ public static function getValue($array, $key, $default = null) $key = $lastKey; } + if (is_object($array) && property_exists($array, $key)) { + return $array->$key; + } + if (static::keyExists($key, $array)) { return $array[$key]; } @@ -345,7 +351,7 @@ public static function remove(&$array, $key, $default = null) * ``` * * @param array $array the array where to look the value from - * @param string $value the value to remove from the array + * @param mixed $value the value to remove from the array * @return array the items that were removed from the array * @since 2.0.11 */ @@ -520,7 +526,7 @@ public static function index($array, $key, $groups = []) * ``` * * @param array $array - * @param int|string|\Closure $name + * @param int|string|array|\Closure $name * @param bool $keepKeys whether to maintain the array keys. If false, the resulting array * will be re-indexed with integers. * @return array the list of column values @@ -579,7 +585,7 @@ public static function getColumn($array, $name, $keepKeys = true) * @param array $array * @param string|\Closure $from * @param string|\Closure $to - * @param string|\Closure $group + * @param string|\Closure|null $group * @return array */ public static function map($array, $from, $to, $group = null) @@ -611,7 +617,7 @@ public static function keyExists($key, $array, $caseSensitive = true) { if ($caseSensitive) { // Function `isset` checks key faster but skips `null`, `array_key_exists` handles this case - // https://secure.php.net/manual/en/function.array-key-exists.php#107786 + // https://www.php.net/manual/en/function.array-key-exists.php#107786 if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array))) { return true; } @@ -643,7 +649,7 @@ public static function keyExists($key, $array, $caseSensitive = true) * When sorting by multiple keys with different sorting directions, use an array of sorting directions. * @param int|array $sortFlag the PHP sort flag. Valid values include * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, `SORT_LOCALE_STRING`, `SORT_NATURAL` and `SORT_FLAG_CASE`. - * Please refer to [PHP manual](https://secure.php.net/manual/en/function.sort.php) + * Please refer to [PHP manual](https://www.php.net/manual/en/function.sort.php) * for more details. When sorting by multiple keys with different sort flags, use an array of sort flags. * @throws InvalidArgumentException if the $direction or $sortFlag parameters do not have * correct number of elements as that of $key. @@ -691,10 +697,10 @@ public static function multisort(&$array, $key, $direction = SORT_ASC, $sortFlag * @param array $data data to be encoded * @param bool $valuesOnly whether to encode array values only. If false, * both the array keys and array values will be encoded. - * @param string $charset the charset that the data is using. If not set, + * @param string|null $charset the charset that the data is using. If not set, * [[\yii\base\Application::charset]] will be used. * @return array the encoded data - * @see https://secure.php.net/manual/en/function.htmlspecialchars.php + * @see https://www.php.net/manual/en/function.htmlspecialchars.php */ public static function htmlEncode($data, $valuesOnly = true, $charset = null) { @@ -720,26 +726,28 @@ public static function htmlEncode($data, $valuesOnly = true, $charset = null) /** * Decodes HTML entities into the corresponding characters in an array of strings. + * * Only array values will be decoded by default. * If a value is an array, this method will also decode it recursively. * Only string values will be decoded. + * * @param array $data data to be decoded - * @param bool $valuesOnly whether to decode array values only. If false, - * both the array keys and array values will be decoded. + * @param bool $valuesOnly whether to decode array values only. If `false`, + * then both the array keys and array values will be decoded. * @return array the decoded data - * @see https://secure.php.net/manual/en/function.htmlspecialchars-decode.php + * @see https://www.php.net/manual/en/function.htmlspecialchars-decode.php */ public static function htmlDecode($data, $valuesOnly = true) { $d = []; foreach ($data as $key => $value) { if (!$valuesOnly && is_string($key)) { - $key = htmlspecialchars_decode($key, ENT_QUOTES); + $key = htmlspecialchars_decode($key, ENT_QUOTES | ENT_SUBSTITUTE); } if (is_string($value)) { - $d[$key] = htmlspecialchars_decode($value, ENT_QUOTES); + $d[$key] = htmlspecialchars_decode($value, ENT_QUOTES | ENT_SUBSTITUTE); } elseif (is_array($value)) { - $d[$key] = static::htmlDecode($value); + $d[$key] = static::htmlDecode($value, $valuesOnly); } else { $d[$key] = $value; } @@ -763,7 +771,7 @@ public static function htmlDecode($data, $valuesOnly = true) */ public static function isAssociative($array, $allStrings = true) { - if (!is_array($array) || empty($array)) { + if (empty($array) || !is_array($array)) { return false; } @@ -809,11 +817,13 @@ public static function isIndexed($array, $consecutive = false) return true; } + $keys = array_keys($array); + if ($consecutive) { - return array_keys($array) === range(0, count($array) - 1); + return $keys === array_keys($keys); } - foreach ($array as $key => $value) { + foreach ($keys as $key) { if (!is_int($key)) { return false; } @@ -825,41 +835,44 @@ public static function isIndexed($array, $consecutive = false) /** * Check whether an array or [[Traversable]] contains an element. * - * This method does the same as the PHP function [in_array()](https://secure.php.net/manual/en/function.in-array.php) + * This method does the same as the PHP function [in_array()](https://www.php.net/manual/en/function.in-array.php) * but additionally works for objects that implement the [[Traversable]] interface. + * * @param mixed $needle The value to look for. - * @param array|Traversable $haystack The set of values to search. + * @param iterable $haystack The set of values to search. * @param bool $strict Whether to enable strict (`===`) comparison. * @return bool `true` if `$needle` was found in `$haystack`, `false` otherwise. * @throws InvalidArgumentException if `$haystack` is neither traversable nor an array. - * @see https://secure.php.net/manual/en/function.in-array.php + * @see https://www.php.net/manual/en/function.in-array.php * @since 2.0.7 */ public static function isIn($needle, $haystack, $strict = false) { - if ($haystack instanceof Traversable) { - foreach ($haystack as $value) { - if ($needle == $value && (!$strict || $needle === $value)) { - return true; - } - } - } elseif (is_array($haystack)) { - return in_array($needle, $haystack, $strict); - } else { + if (!static::isTraversable($haystack)) { throw new InvalidArgumentException('Argument $haystack must be an array or implement Traversable'); } + if (is_array($haystack)) { + return in_array($needle, $haystack, $strict); + } + + foreach ($haystack as $value) { + if ($strict ? $needle === $value : $needle == $value) { + return true; + } + } + return false; } /** * Checks whether a variable is an array or [[Traversable]]. * - * This method does the same as the PHP function [is_array()](https://secure.php.net/manual/en/function.is-array.php) + * This method does the same as the PHP function [is_array()](https://www.php.net/manual/en/function.is-array.php) * but additionally works on objects that implement the [[Traversable]] interface. * @param mixed $var The variable being evaluated. * @return bool whether $var can be traversed via foreach - * @see https://secure.php.net/manual/en/function.is-array.php + * @see https://www.php.net/manual/en/function.is-array.php * @since 2.0.8 */ public static function isTraversable($var) @@ -872,26 +885,27 @@ public static function isTraversable($var) * * This method will return `true`, if all elements of `$needles` are contained in * `$haystack`. If at least one element is missing, `false` will be returned. - * @param array|Traversable $needles The values that must **all** be in `$haystack`. - * @param array|Traversable $haystack The set of value to search. + * + * @param iterable $needles The values that must **all** be in `$haystack`. + * @param iterable $haystack The set of value to search. * @param bool $strict Whether to enable strict (`===`) comparison. - * @throws InvalidArgumentException if `$haystack` or `$needles` is neither traversable nor an array. * @return bool `true` if `$needles` is a subset of `$haystack`, `false` otherwise. + * @throws InvalidArgumentException if `$haystack` or `$needles` is neither traversable nor an array. * @since 2.0.7 */ public static function isSubset($needles, $haystack, $strict = false) { - if (is_array($needles) || $needles instanceof Traversable) { - foreach ($needles as $needle) { - if (!static::isIn($needle, $haystack, $strict)) { - return false; - } - } + if (!static::isTraversable($needles)) { + throw new InvalidArgumentException('Argument $needles must be an array or implement Traversable'); + } - return true; + foreach ($needles as $needle) { + if (!static::isIn($needle, $haystack, $strict)) { + return false; + } } - throw new InvalidArgumentException('Argument $needles must be an array or implement Traversable'); + return true; } /** @@ -930,7 +944,7 @@ public static function isSubset($needles, $haystack, $strict = false) * ``` * * @param array $array Source array - * @param array $filters Rules that define array keys which should be left or removed from results. + * @param iterable $filters Rules that define array keys which should be left or removed from results. * Each rule is: * - `var` - `$array['var']` will be left in result. * - `var.key` = only `$array['var']['key'] will be left in result. @@ -944,13 +958,17 @@ public static function filter($array, $filters) $excludeFilters = []; foreach ($filters as $filter) { - if ($filter[0] === '!') { + if (!is_string($filter) && !is_int($filter)) { + continue; + } + + if (is_string($filter) && strncmp($filter, '!', 1) === 0) { $excludeFilters[] = substr($filter, 1); continue; } $nodeValue = $array; //set $array as root node - $keys = explode('.', $filter); + $keys = explode('.', (string) $filter); foreach ($keys as $key) { if (!array_key_exists($key, $nodeValue)) { continue 2; //Jump to next filter @@ -971,7 +989,7 @@ public static function filter($array, $filters) foreach ($excludeFilters as $filter) { $excludeNode = &$result; - $keys = explode('.', $filter); + $keys = explode('.', (string) $filter); $numNestedKeys = count($keys) - 1; foreach ($keys as $i => $key) { if (!array_key_exists($key, $excludeNode)) { @@ -989,4 +1007,29 @@ public static function filter($array, $filters) return $result; } + + /** + * Sorts array recursively. + * + * @param array $array An array passing by reference. + * @param callable|null $sorter The array sorter. If omitted, sort index array by values, sort assoc array by keys. + * @return array + */ + public static function recursiveSort(array &$array, $sorter = null) + { + foreach ($array as &$value) { + if (is_array($value)) { + static::recursiveSort($value, $sorter); + } + } + unset($value); + + if ($sorter === null) { + $sorter = static::isIndexed($array) ? 'sort' : 'ksort'; + } + + call_user_func_array($sorter, [&$array]); + + return $array; + } } diff --git a/framework/helpers/BaseConsole.php b/framework/helpers/BaseConsole.php index 285276238cf..ab4d1bfecdf 100644 --- a/framework/helpers/BaseConsole.php +++ b/framework/helpers/BaseConsole.php @@ -331,7 +331,7 @@ public static function xtermBgColor($colorCode) */ public static function stripAnsiFormat($string) { - return preg_replace(self::ansiCodesPattern(), '', $string); + return preg_replace(self::ansiCodesPattern(), '', (string)$string); } /** @@ -370,9 +370,9 @@ public static function ansiColorizedSubstr($string, $start, $length) return ''; } - $textItems = preg_split(self::ansiCodesPattern(), $string); + $textItems = preg_split(self::ansiCodesPattern(), (string)$string); - preg_match_all(self::ansiCodesPattern(), $string, $colors); + preg_match_all(self::ansiCodesPattern(), (string)$string, $colors); $colors = count($colors) ? $colors[0] : []; array_unshift($colors, ''); @@ -807,7 +807,7 @@ public static function stderr($string) * Asks the user for input. Ends when the user types a carriage return (PHP_EOL). Optionally, It also provides a * prompt. * - * @param string $prompt the prompt to display before waiting for input (optional) + * @param string|null $prompt the prompt to display before waiting for input (optional) * @return string the user's input */ public static function input($prompt = null) @@ -822,7 +822,7 @@ public static function input($prompt = null) /** * Prints text to STDOUT appended with a carriage return (PHP_EOL). * - * @param string $string the text to print + * @param string|null $string the text to print * @return int|bool number of bytes printed or false on error. */ public static function output($string = null) @@ -833,7 +833,7 @@ public static function output($string = null) /** * Prints text to STDERR appended with a carriage return (PHP_EOL). * - * @param string $string the text to print + * @param string|null $string the text to print * @return int|bool number of bytes printed or false on error. */ public static function error($string = null) @@ -998,7 +998,7 @@ public static function select($prompt, $options = []) * @param int $total the total value of items that are to be done. * @param string $prefix an optional string to display before the progress bar. * Default to empty string which results in no prefix to be displayed. - * @param int|bool $width optional width of the progressbar. This can be an integer representing + * @param int|float|bool|null $width optional width of the progressbar. This can be an integer representing * the number of characters to display for the progress bar or a float between 0 and 1 representing the * percentage of screen with the progress bar may take. It can also be set to false to disable the * bar and only show progress information like percent, number of items and ETA. @@ -1024,7 +1024,7 @@ public static function startProgress($done, $total, $prefix = '', $width = null) * * @param int $done the number of items that are completed. * @param int $total the total value of items that are to be done. - * @param string $prefix an optional string to display before the progress bar. + * @param string|null $prefix an optional string to display before the progress bar. * Defaults to null meaning the prefix specified by [[startProgress()]] will be used. * If prefix is specified it will update the prefix that will be used by later calls. * @see startProgress diff --git a/framework/helpers/BaseFileHelper.php b/framework/helpers/BaseFileHelper.php index 828ecbf83e8..dc2d965bbb7 100644 --- a/framework/helpers/BaseFileHelper.php +++ b/framework/helpers/BaseFileHelper.php @@ -9,6 +9,7 @@ use Yii; use yii\base\ErrorException; +use yii\base\Exception; use yii\base\InvalidArgumentException; use yii\base\InvalidConfigException; @@ -98,13 +99,12 @@ public static function normalizePath($path, $ds = DIRECTORY_SEPARATOR) * "path/to/zh-CN/view.php". If the file is not found, it will try a fallback with just a language code that is * "zh" i.e. "path/to/zh/view.php". If it is not found as well the original file will be returned. * - * If the target and the source language codes are the same, - * the original file will be returned. + * If the target and the source language codes are the same, the original file will be returned. * * @param string $file the original file - * @param string $language the target language that the file should be localized to. + * @param string|null $language the target language that the file should be localized to. * If not set, the value of [[\yii\base\Application::language]] will be used. - * @param string $sourceLanguage the language that the original file is in. + * @param string|null $sourceLanguage the language that the original file is in. * If not set, the value of [[\yii\base\Application::sourceLanguage]] will be used. * @return string the matching localized file, or the original file if the localized version is not found. * If the target and the source language codes are the same, the original file will be returned. @@ -137,16 +137,16 @@ public static function localize($file, $language = null, $sourceLanguage = null) /** * Determines the MIME type of the specified file. * This method will first try to determine the MIME type based on - * [finfo_open](https://secure.php.net/manual/en/function.finfo-open.php). If the `fileinfo` extension is not installed, + * [finfo_open](https://www.php.net/manual/en/function.finfo-open.php). If the `fileinfo` extension is not installed, * it will fall back to [[getMimeTypeByExtension()]] when `$checkExtension` is true. * @param string $file the file name. - * @param string $magicFile name of the optional magic database file (or alias), usually something like `/path/to/magic.mime`. - * This will be passed as the second parameter to [finfo_open()](https://secure.php.net/manual/en/function.finfo-open.php) + * @param string|null $magicFile name of the optional magic database file (or alias), usually something like `/path/to/magic.mime`. + * This will be passed as the second parameter to [finfo_open()](https://www.php.net/manual/en/function.finfo-open.php) * when the `fileinfo` extension is installed. If the MIME type is being determined based via [[getMimeTypeByExtension()]] * and this is null, it will use the file specified by [[mimeMagicFile]]. * @param bool $checkExtension whether to use the file extension to determine the MIME type in case * `finfo_open()` cannot determine it. - * @return string the MIME type (e.g. `text/plain`). Null is returned if the MIME type cannot be determined. + * @return string|null the MIME type (e.g. `text/plain`). Null is returned if the MIME type cannot be determined. * @throws InvalidConfigException when the `fileinfo` PHP extension is not installed and `$checkExtension` is `false`. */ public static function getMimeType($file, $magicFile = null, $checkExtension = true) @@ -161,6 +161,7 @@ public static function getMimeType($file, $magicFile = null, $checkExtension = t throw new InvalidConfigException('The fileinfo PHP extension is not installed.'); } + $info = finfo_open(FILEINFO_MIME_TYPE, $magicFile); if ($info) { @@ -179,7 +180,7 @@ public static function getMimeType($file, $magicFile = null, $checkExtension = t * Determines the MIME type based on the extension name of the specified file. * This method will use a local map between extension names and MIME types. * @param string $file the file name. - * @param string $magicFile the path (or alias) of the file that contains all available MIME type information. + * @param string|null $magicFile the path (or alias) of the file that contains all available MIME type information. * If this is not set, the file specified by [[mimeMagicFile]] will be used. * @return string|null the MIME type. Null is returned if the MIME type cannot be determined. */ @@ -201,7 +202,7 @@ public static function getMimeTypeByExtension($file, $magicFile = null) * Determines the extensions by given MIME type. * This method will use a local map between extension names and MIME types. * @param string $mimeType file MIME type. - * @param string $magicFile the path (or alias) of the file that contains all available MIME type information. + * @param string|null $magicFile the path (or alias) of the file that contains all available MIME type information. * If this is not set, the file specified by [[mimeMagicFile]] will be used. * @return array the extensions corresponding to the specified MIME type */ @@ -220,7 +221,7 @@ public static function getExtensionsByMimeType($mimeType, $magicFile = null) /** * Loads MIME types from the specified file. - * @param string $magicFile the path (or alias) of the file that contains all available MIME type information. + * @param string|null $magicFile the path (or alias) of the file that contains all available MIME type information. * If this is not set, the file specified by [[mimeMagicFile]] will be used. * @return array the mapping from file extensions to MIME types */ @@ -241,7 +242,7 @@ protected static function loadMimeTypes($magicFile) /** * Loads MIME aliases from the specified file. - * @param string $aliasesFile the path (or alias) of the file that contains MIME type aliases. + * @param string|null $aliasesFile the path (or alias) of the file that contains MIME type aliases. * If this is not set, the file specified by [[mimeAliasesFile]] will be used. * @return array the mapping from file extensions to MIME types * @since 2.0.14 @@ -502,13 +503,14 @@ public static function findFiles($dir, $options = []) * @param array $options options for directory searching. Valid options are: * * - `filter`: callback, a PHP callback that is called for each directory or file. - * The signature of the callback should be: `function ($path)`, where `$path` refers the full path to be filtered. - * The callback can return one of the following values: + * The signature of the callback should be: `function (string $path): bool`, where `$path` refers + * the full path to be filtered. The callback can return one of the following values: * * * `true`: the directory will be returned * * `false`: the directory will NOT be returned * * - `recursive`: boolean, whether the files under the subdirectories should also be looked for. Defaults to `true`. + * See [[findFiles()]] for more options. * @return array directories found under the directory, in no particular order. Ordering depends on the files system used. * @throws InvalidArgumentException if the dir is invalid. * @since 2.0.14 @@ -538,6 +540,8 @@ public static function findDirectories($dir, $options = []) /** * @param string $dir + * @param array $options + * @return array */ private static function setBasePath($dir, $options) { @@ -552,6 +556,8 @@ private static function setBasePath($dir, $options) /** * @param string $dir + * @return resource + * @throws InvalidArgumentException if unable to open directory */ private static function openDir($dir) { @@ -564,13 +570,15 @@ private static function openDir($dir) /** * @param string $dir + * @return string + * @throws InvalidArgumentException if directory not exists */ private static function clearDir($dir) { if (!is_dir($dir)) { throw new InvalidArgumentException("The dir argument must be a directory: $dir"); } - return rtrim($dir, DIRECTORY_SEPARATOR); + return rtrim($dir, '\/'); } /** @@ -595,19 +603,15 @@ public static function filterPath($path, $options) $path = str_replace('\\', '/', $path); - if (!empty($options['except'])) { - if (($except = self::lastExcludeMatchingFromList($options['basePath'], $path, $options['except'])) !== null) { - return $except['flags'] & self::PATTERN_NEGATIVE; - } + if ( + !empty($options['except']) + && ($except = self::lastExcludeMatchingFromList($options['basePath'], $path, $options['except'])) !== null + ) { + return $except['flags'] & self::PATTERN_NEGATIVE; } if (!empty($options['only']) && !is_dir($path)) { - if (($except = self::lastExcludeMatchingFromList($options['basePath'], $path, $options['only'])) !== null) { - // don't check PATTERN_NEGATIVE since those entries are not prefixed with ! - return true; - } - - return false; + return self::lastExcludeMatchingFromList($options['basePath'], $path, $options['only']) !== null; } return true; @@ -700,7 +704,7 @@ private static function matchBasename($baseName, $pattern, $firstWildcard, $flag private static function matchPathname($path, $basePath, $pattern, $firstWildcard, $flags) { // match with FNM_PATHNAME; the pattern has base implicitly in front of it. - if (isset($pattern[0]) && $pattern[0] === '/') { + if (strncmp($pattern, '/', 1) === 0) { $pattern = StringHelper::byteSubstr($pattern, 1, StringHelper::byteLength($pattern)); if ($firstWildcard !== false && $firstWildcard !== 0) { $firstWildcard--; @@ -806,11 +810,11 @@ private static function parseExcludePattern($pattern, $caseSensitive) $result['flags'] |= self::PATTERN_CASE_INSENSITIVE; } - if (!isset($pattern[0])) { + if (empty($pattern)) { return $result; } - if ($pattern[0] === '!') { + if (strncmp($pattern, '!', 1) === 0) { $result['flags'] |= self::PATTERN_NEGATIVE; $pattern = StringHelper::byteSubstr($pattern, 1, StringHelper::byteLength($pattern)); } @@ -822,7 +826,7 @@ private static function parseExcludePattern($pattern, $caseSensitive) $result['flags'] |= self::PATTERN_NODIR; } $result['firstWildcard'] = self::firstWildcardInPattern($pattern); - if ($pattern[0] === '*' && self::firstWildcardInPattern(StringHelper::byteSubstr($pattern, 1, StringHelper::byteLength($pattern))) === false) { + if (strncmp($pattern, '*', 1) === 0 && self::firstWildcardInPattern(StringHelper::byteSubstr($pattern, 1, StringHelper::byteLength($pattern))) === false) { $result['flags'] |= self::PATTERN_ENDSWITH; } $result['pattern'] = $pattern; @@ -874,4 +878,83 @@ protected static function normalizeOptions(array $options) return $options; } + + /** + * Changes the Unix user and/or group ownership of a file or directory, and optionally the mode. + * Note: This function will not work on remote files as the file to be examined must be accessible + * via the server's filesystem. + * Note: On Windows, this function fails silently when applied on a regular file. + * @param string $path the path to the file or directory. + * @param string|array|int|null $ownership the user and/or group ownership for the file or directory. + * When $ownership is a string, the format is 'user:group' where both are optional. E.g. + * 'user' or 'user:' will only change the user, + * ':group' will only change the group, + * 'user:group' will change both. + * When $owners is an index array the format is [0 => user, 1 => group], e.g. `[$myUser, $myGroup]`. + * It is also possible to pass an associative array, e.g. ['user' => $myUser, 'group' => $myGroup]. + * In case $owners is an integer it will be used as user id. + * If `null`, an empty array or an empty string is passed, the ownership will not be changed. + * @param int|null $mode the permission to be set for the file or directory. + * If `null` is passed, the mode will not be changed. + * + * @since 2.0.43 + */ + public static function changeOwnership($path, $ownership, $mode = null) + { + if (!file_exists((string)$path)) { + throw new InvalidArgumentException('Unable to change ownership, "' . $path . '" is not a file or directory.'); + } + + if (empty($ownership) && $ownership !== 0 && $mode === null) { + return; + } + + $user = $group = null; + if (!empty($ownership) || $ownership === 0 || $ownership === '0') { + if (is_int($ownership)) { + $user = $ownership; + } elseif (is_string($ownership)) { + $ownerParts = explode(':', $ownership); + $user = $ownerParts[0]; + if (count($ownerParts) > 1) { + $group = $ownerParts[1]; + } + } elseif (is_array($ownership)) { + $ownershipIsIndexed = ArrayHelper::isIndexed($ownership); + $user = ArrayHelper::getValue($ownership, $ownershipIsIndexed ? 0 : 'user'); + $group = ArrayHelper::getValue($ownership, $ownershipIsIndexed ? 1 : 'group'); + } else { + throw new InvalidArgumentException('$ownership must be an integer, string, array, or null.'); + } + } + + if ($mode !== null) { + if (!is_int($mode)) { + throw new InvalidArgumentException('$mode must be an integer or null.'); + } + if (!chmod($path, $mode)) { + throw new Exception('Unable to change mode of "' . $path . '" to "0' . decoct($mode) . '".'); + } + } + if ($user !== null && $user !== '') { + if (is_numeric($user)) { + $user = (int) $user; + } elseif (!is_string($user)) { + throw new InvalidArgumentException('The user part of $ownership must be an integer, string, or null.'); + } + if (!chown($path, $user)) { + throw new Exception('Unable to change user ownership of "' . $path . '" to "' . $user . '".'); + } + } + if ($group !== null && $group !== '') { + if (is_numeric($group)) { + $group = (int) $group; + } elseif (!is_string($group)) { + throw new InvalidArgumentException('The group part of $ownership must be an integer, string or null.'); + } + if (!chgrp($path, $group)) { + throw new Exception('Unable to change group ownership of "' . $path . '" to "' . $group . '".'); + } + } + } } diff --git a/framework/helpers/BaseFormatConverter.php b/framework/helpers/BaseFormatConverter.php index 1a96120c3d6..5e501fe390b 100644 --- a/framework/helpers/BaseFormatConverter.php +++ b/framework/helpers/BaseFormatConverter.php @@ -91,12 +91,12 @@ class BaseFormatConverter * * Pattern constructs that are not supported by the PHP format will be removed. * - * [php date() function format]: https://secure.php.net/manual/en/function.date.php + * [php date() function format]: https://www.php.net/manual/en/function.date.php * [ICU format]: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax * * @param string $pattern date format pattern in ICU format. * @param string $type 'date', 'time', or 'datetime'. - * @param string $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`. + * @param string|null $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`. * If not given, `Yii::$app->language` will be used. * @return string The converted date format pattern. */ @@ -238,7 +238,7 @@ public static function convertDateIcuToPhp($pattern, $type = 'date', $locale = n * * Pattern constructs that are not supported by the ICU format will be removed. * - * [php date() function format]: https://secure.php.net/manual/en/function.date.php + * [php date() function format]: https://www.php.net/manual/en/function.date.php * [ICU format]: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax * * Since 2.0.13 it handles escaped characters correctly. @@ -248,7 +248,7 @@ public static function convertDateIcuToPhp($pattern, $type = 'date', $locale = n */ public static function convertDatePhpToIcu($pattern) { - // https://secure.php.net/manual/en/function.date.php + // https://www.php.net/manual/en/function.date.php $result = strtr($pattern, [ "'" => "''''", // single `'` should be encoded as `''`, which internally should be encoded as `''''` // Day @@ -335,7 +335,7 @@ public static function convertDatePhpToIcu($pattern) '\\\\' => '\\', ]); - // remove `''` - the're result of consecutive escaped chars (`\A\B` will be `'A''B'`, but should be `'AB'`) + // remove `''` - they're result of consecutive escaped chars (`\A\B` will be `'A''B'`, but should be `'AB'`) // real `'` are encoded as `''''` return strtr($result, [ "''''" => "''", @@ -353,7 +353,7 @@ public static function convertDatePhpToIcu($pattern) * * @param string $pattern date format pattern in ICU format. * @param string $type 'date', 'time', or 'datetime'. - * @param string $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`. + * @param string|null $locale the locale to use for converting ICU short patterns `short`, `medium`, `long` and `full`. * If not given, `Yii::$app->language` will be used. * @return string The converted date format pattern. */ @@ -497,7 +497,7 @@ public static function convertDateIcuToJui($pattern, $type = 'date', $locale = n * * Pattern constructs that are not supported by the jQuery UI format will be removed. * - * [php date() function format]: https://secure.php.net/manual/en/function.date.php + * [php date() function format]: https://www.php.net/manual/en/function.date.php * [jQuery UI date format]: http://api.jqueryui.com/datepicker/#utility-formatDate * * @param string $pattern date format pattern in php date()-function format. @@ -505,7 +505,7 @@ public static function convertDateIcuToJui($pattern, $type = 'date', $locale = n */ public static function convertDatePhpToJui($pattern) { - // https://secure.php.net/manual/en/function.date.php + // https://www.php.net/manual/en/function.date.php return strtr($pattern, [ // Day 'd' => 'dd', // Day of the month, 2 digits with leading zeros 01 to 31 diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php index 902d4643334..1e0d8702dd6 100644 --- a/framework/helpers/BaseHtml.php +++ b/framework/helpers/BaseHtml.php @@ -94,6 +94,13 @@ class BaseHtml * @since 2.0.3 */ public static $dataAttributes = ['aria', 'data', 'data-ng', 'ng']; + /** + * @var bool whether to removes duplicate class names in tag attribute `class` + * @see mergeCssClasses() + * @see renderTagAttributes() + * @since 2.0.44 + */ + public static $normalizeClassAttribute = false; /** @@ -104,11 +111,11 @@ class BaseHtml * HTML entities in `$content` will not be further encoded. * @return string the encoded content * @see decode() - * @see https://secure.php.net/manual/en/function.htmlspecialchars.php + * @see https://www.php.net/manual/en/function.htmlspecialchars.php */ public static function encode($content, $doubleEncode = true) { - return htmlspecialchars($content, ENT_QUOTES | ENT_SUBSTITUTE, Yii::$app ? Yii::$app->charset : 'UTF-8', $doubleEncode); + return htmlspecialchars((string)$content, ENT_QUOTES | ENT_SUBSTITUTE, Yii::$app ? Yii::$app->charset : 'UTF-8', $doubleEncode); } /** @@ -117,7 +124,7 @@ public static function encode($content, $doubleEncode = true) * @param string $content the content to be decoded * @return string the decoded content * @see encode() - * @see https://secure.php.net/manual/en/function.htmlspecialchars-decode.php + * @see https://www.php.net/manual/en/function.htmlspecialchars-decode.php */ public static function decode($content) { @@ -565,7 +572,7 @@ public static function input($type, $name = null, $value = null, $options = []) /** * Generates an input button. - * @param string $label the value attribute. If it is null, the value attribute will not be generated. + * @param string|null $label the value attribute. If it is null, the value attribute will not be generated. * @param array $options the tag options in terms of name-value pairs. These will be rendered as * the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. * If a value is null, the corresponding attribute will not be rendered. @@ -585,7 +592,7 @@ public static function buttonInput($label = 'Button', $options = []) * Be careful when naming form elements such as submit buttons. According to the [jQuery documentation](https://api.jquery.com/submit/) there * are some reserved names that can cause conflicts, e.g. `submit`, `length`, or `method`. * - * @param string $label the value attribute. If it is null, the value attribute will not be generated. + * @param string|null $label the value attribute. If it is null, the value attribute will not be generated. * @param array $options the tag options in terms of name-value pairs. These will be rendered as * the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. * If a value is null, the corresponding attribute will not be rendered. @@ -601,7 +608,7 @@ public static function submitInput($label = 'Submit', $options = []) /** * Generates a reset input button. - * @param string $label the value attribute. If it is null, the value attribute will not be generated. + * @param string|null $label the value attribute. If it is null, the value attribute will not be generated. * @param array $options the attributes of the button tag. The values will be HTML-encoded using [[encode()]]. * Attributes whose value is null will be ignored and not put in the tag returned. * See [[renderTagAttributes()]] for details on how attributes are being rendered. @@ -1373,7 +1380,8 @@ public static function activeInput($type, $model, $attribute, $options = []) /** * If `maxlength` option is set true and the model attribute is validated by a string validator, - * the `maxlength` option will take the value of [[\yii\validators\StringValidator::max]]. + * the `maxlength` option will take the max value of [[\yii\validators\StringValidator::max]] and + * [[\yii\validators\StringValidator::length]]. * @param Model $model the model object * @param string $attribute the attribute name or expression. * @param array $options the tag options in terms of name-value pairs. @@ -1384,8 +1392,8 @@ private static function normalizeMaxLength($model, $attribute, &$options) unset($options['maxlength']); $attrName = static::getAttributeName($attribute); foreach ($model->getActiveValidators($attrName) as $validator) { - if ($validator instanceof StringValidator && $validator->max !== null) { - $options['maxlength'] = $validator->max; + if ($validator instanceof StringValidator && ($validator->max !== null || $validator->length !== null)) { + $options['maxlength'] = max($validator->max, $validator->length); break; } } @@ -1405,8 +1413,9 @@ private static function normalizeMaxLength($model, $attribute, &$options) * The following special options are recognized: * * - maxlength: integer|boolean, when `maxlength` is set true and the model attribute is validated - * by a string validator, the `maxlength` option will take the value of [[\yii\validators\StringValidator::max]]. - * This is available since version 2.0.3. + * by a string validator, the `maxlength` option will take the max value of [[\yii\validators\StringValidator::max]] + * and [[\yii\validators\StringValidator::length]. + * This is available since version 2.0.3 and improved taking `length` into account since version 2.0.42. * - placeholder: string|boolean, when `placeholder` equals `true`, the attribute label from the $model will be used * as a placeholder (this behavior is available since version 2.0.14). * @@ -1465,8 +1474,9 @@ public static function activeHiddenInput($model, $attribute, $options = []) * The following special options are recognized: * * - maxlength: integer|boolean, when `maxlength` is set true and the model attribute is validated - * by a string validator, the `maxlength` option will take the value of [[\yii\validators\StringValidator::max]]. - * This option is available since version 2.0.6. + * by a string validator, the `maxlength` option will take the max value of [[\yii\validators\StringValidator::max]] + * and [[\yii\validators\StringValidator::length]. + * This is available since version 2.0.6 and improved taking `length` into account since version 2.0.42. * - placeholder: string|boolean, when `placeholder` equals `true`, the attribute label from the $model will be used * as a placeholder (this behavior is available since version 2.0.14). * @@ -1526,8 +1536,9 @@ public static function activeFileInput($model, $attribute, $options = []) * The following special options are recognized: * * - maxlength: integer|boolean, when `maxlength` is set true and the model attribute is validated - * by a string validator, the `maxlength` option will take the value of [[\yii\validators\StringValidator::max]]. - * This option is available since version 2.0.6. + * by a string validator, the `maxlength` option will take the max value of [[\yii\validators\StringValidator::max]] + * and [[\yii\validators\StringValidator::length]. + * This is available since version 2.0.6 and improved taking `length` into account since version 2.0.42. * - placeholder: string|boolean, when `placeholder` equals `true`, the attribute label from the $model will be used * as a placeholder (this behavior is available since version 2.0.14). * @@ -1741,7 +1752,6 @@ public static function activeListBox($model, $attribute, $items, $options = []) * about attribute expression. * @param array $items the data item used to generate the checkboxes. * The array keys are the checkbox values, and the array values are the corresponding labels. - * Note that the labels will NOT be HTML-encoded, while the values will. * @param array $options options (name => config) for the checkbox list container tag. * The following options are specially handled: * @@ -1783,7 +1793,6 @@ public static function activeCheckboxList($model, $attribute, $items, $options = * about attribute expression. * @param array $items the data item used to generate the radio buttons. * The array keys are the radio values, and the array values are the corresponding labels. - * Note that the labels will NOT be HTML-encoded, while the values will. * @param array $options options (name => config) for the radio button list container tag. * The following options are specially handled: * @@ -1825,7 +1834,6 @@ public static function activeRadioList($model, $attribute, $items, $options = [] * about attribute expression. * @param array $items the data item used to generate the input fields. * The array keys are the input values, and the array values are the corresponding labels. - * Note that the labels will NOT be HTML-encoded, while the values will. * @param array $options options (name => config) for the input list. The supported special options * depend on the input type specified by `$type`. * @return string the generated input list @@ -1906,7 +1914,7 @@ public static function renderSelectOptions($selection, $items, &$tagOptions = [] $attrs['value'] = (string) $key; if (!array_key_exists('selected', $attrs)) { $attrs['selected'] = $selection !== null && - (!ArrayHelper::isTraversable($selection) && !strcmp($key, $selection) + (!ArrayHelper::isTraversable($selection) && ($strict ? !strcmp($key, $selection) : $selection == $key) || ArrayHelper::isTraversable($selection) && ArrayHelper::isIn((string)$key, $selection, $strict)); } $text = $encode ? static::encode($value) : $value; @@ -1942,7 +1950,7 @@ public static function renderSelectOptions($selection, $items, &$tagOptions = [] * @param array $attributes attributes to be rendered. The attribute values will be HTML-encoded using [[encode()]]. * @return string the rendering result. If the attributes are not empty, they will be rendered * into a string with a leading white space (so that it can be directly appended to the tag name - * in a tag. If there is no attribute, an empty string will be returned. + * in a tag). If there is no attribute, an empty string will be returned. * @see addCssClass() */ public static function renderTagAttributes($attributes) @@ -1980,6 +1988,11 @@ public static function renderTagAttributes($attributes) if (empty($value)) { continue; } + if (static::$normalizeClassAttribute === true && count($value) > 1) { + // removes duplicate classes + $value = explode(' ', implode(' ', $value)); + $value = array_unique($value); + } $html .= " $name=\"" . static::encode(implode(' ', $value)) . '"'; } elseif ($name === 'style') { if (empty($value)) { @@ -2012,7 +2025,6 @@ public static function renderTagAttributes($attributes) * * @param array $options the options to be modified. * @param string|array $class the CSS class(es) to be added - * @see mergeCssClasses() * @see removeCssClass() */ public static function addCssClass(&$options, $class) @@ -2047,7 +2059,7 @@ private static function mergeCssClasses(array $existingClasses, array $additiona } } - return array_unique($existingClasses); + return static::$normalizeClassAttribute ? array_unique($existingClasses) : $existingClasses; } /** @@ -2302,21 +2314,34 @@ public static function getInputName($model, $attribute) throw new InvalidArgumentException(get_class($model) . '::formName() cannot be empty for tabular inputs.'); } + /** + * Converts input name to ID. + * + * For example, if `$name` is `Post[content]`, this method will return `post-content`. + * + * @param string $name the input name + * @return string the generated input ID + * @since 2.0.43 + */ + public static function getInputIdByName($name) + { + $charset = Yii::$app ? Yii::$app->charset : 'UTF-8'; + $name = mb_strtolower($name, $charset); + return str_replace(['[]', '][', '[', ']', ' ', '.', '--'], ['', '-', '-', '', '-', '-', '-'], $name); + } + /** * Generates an appropriate input ID for the specified attribute name or expression. * - * This method converts the result [[getInputName()]] into a valid input ID. - * For example, if [[getInputName()]] returns `Post[content]`, this method will return `post-content`. * @param Model $model the model object * @param string $attribute the attribute name or expression. See [[getAttributeName()]] for explanation of attribute expression. - * @return string the generated input ID + * @return string the generated input ID. * @throws InvalidArgumentException if the attribute name contains non-word characters. */ public static function getInputId($model, $attribute) { - $charset = Yii::$app ? Yii::$app->charset : 'UTF-8'; - $name = mb_strtolower(static::getInputName($model, $attribute), $charset); - return str_replace(['[]', '][', '[', ']', ' ', '.'], ['', '-', '-', '', '-', '-'], $name); + $name = static::getInputName($model, $attribute); + return static::getInputIdByName($name); } /** diff --git a/framework/helpers/BaseInflector.php b/framework/helpers/BaseInflector.php index 410ee59bd82..d46aa7ad267 100644 --- a/framework/helpers/BaseInflector.php +++ b/framework/helpers/BaseInflector.php @@ -219,6 +219,8 @@ class BaseInflector 'whiting' => 'whiting', 'wildebeest' => 'wildebeest', 'Yengeese' => 'Yengeese', + 'software' => 'software', + 'hardware' => 'hardware', ]; /** * @var array fallback map for transliteration used by [[transliterate()]] when intl isn't available. @@ -285,7 +287,7 @@ class BaseInflector /** * @var mixed Either a [[\Transliterator]], or a string from which a [[\Transliterator]] can be built * for transliteration. Used by [[transliterate()]] when intl is available. Defaults to [[TRANSLITERATE_LOOSE]] - * @see https://secure.php.net/manual/en/transliterator.transliterate.php + * @see https://www.php.net/manual/en/transliterator.transliterate.php */ public static $transliterator = self::TRANSLITERATE_LOOSE; @@ -299,6 +301,9 @@ class BaseInflector */ public static function pluralize($word) { + if (empty($word)) { + return (string) $word; + } if (isset(static::$specials[$word])) { return static::$specials[$word]; } @@ -318,6 +323,9 @@ public static function pluralize($word) */ public static function singularize($word) { + if (empty($word)) { + return (string) $word; + } $result = array_search($word, static::$specials, true); if ($result !== false) { return $result; @@ -340,6 +348,9 @@ public static function singularize($word) */ public static function titleize($words, $ucAll = false) { + if (empty($words)) { + return (string) $words; + } $words = static::humanize(static::underscore($words), $ucAll); return $ucAll ? StringHelper::mb_ucwords($words, self::encoding()) : StringHelper::mb_ucfirst($words, self::encoding()); @@ -357,6 +368,9 @@ public static function titleize($words, $ucAll = false) */ public static function camelize($word) { + if (empty($word)) { + return (string) $word; + } return str_replace(' ', '', StringHelper::mb_ucwords(preg_replace('/[^\pL\pN]+/u', ' ', $word), self::encoding())); } @@ -369,11 +383,14 @@ public static function camelize($word) */ public static function camel2words($name, $ucwords = true) { - $label = mb_strtolower(trim(str_replace([ - '-', - '_', - '.', - ], ' ', preg_replace('/(? x Y) + // and any uppercase letter preceded by an uppercase letter and followed by a lowercase letter (XYz => X Yz) + $label = preg_replace('/(?<=\p{Ll})\p{Lu}|(?<=[\p{L}\d])\p{Lu}(?=\p{Ll})|(\d+)/u', ' \0', $name); + + $label = mb_strtolower(trim(str_replace(['-', '_', '.'], ' ', $label)), self::encoding()); return $ucwords ? StringHelper::mb_ucwords($label, self::encoding()) : $label; } @@ -389,6 +406,9 @@ public static function camel2words($name, $ucwords = true) */ public static function camel2id($name, $separator = '-', $strict = false) { + if (empty($name)) { + return (string) $name; + } $regex = $strict ? '/\p{Lu}/u' : '/(? 'The maximum stack depth has been exceeded.', - 'JSON_ERROR_STATE_MISMATCH' => 'Invalid or malformed JSON.', - 'JSON_ERROR_CTRL_CHAR' => 'Control character error, possibly incorrectly encoded.', - 'JSON_ERROR_SYNTAX' => 'Syntax error.', - 'JSON_ERROR_UTF8' => 'Malformed UTF-8 characters, possibly incorrectly encoded.', // PHP 5.3.3 - 'JSON_ERROR_RECURSION' => 'One or more recursive references in the value to be encoded.', // PHP 5.5.0 - 'JSON_ERROR_INF_OR_NAN' => 'One or more NAN or INF values in the value to be encoded', // PHP 5.5.0 - 'JSON_ERROR_UNSUPPORTED_TYPE' => 'A value of a type that cannot be encoded was given', // PHP 5.5.0 + 'JSON_ERROR_SYNTAX' => 'Syntax error', + 'JSON_ERROR_UNSUPPORTED_TYPE' => 'Type is not supported', + 'JSON_ERROR_DEPTH' => 'The maximum stack depth has been exceeded', + 'JSON_ERROR_STATE_MISMATCH' => 'Invalid or malformed JSON', + 'JSON_ERROR_CTRL_CHAR' => 'Control character error, possibly incorrectly encoded', + 'JSON_ERROR_UTF8' => 'Malformed UTF-8 characters, possibly incorrectly encoded', ]; @@ -51,7 +65,7 @@ class BaseJson * * @param mixed $value the data to be encoded. * @param int $options the encoding options. For more details please refer to - * . Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`. + * . Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`. * @return string the encoding result. * @throws InvalidArgumentException if there is any encoding error. */ @@ -62,6 +76,13 @@ public static function encode($value, $options = 320) set_error_handler(function () { static::handleJsonError(JSON_ERROR_SYNTAX); }, E_WARNING); + + if (static::$prettyPrint === true) { + $options |= JSON_PRETTY_PRINT; + } elseif (static::$prettyPrint === false) { + $options &= ~JSON_PRETTY_PRINT; + } + $json = json_encode($value, $options); restore_error_handler(); static::handleJsonError(json_last_error()); @@ -112,7 +133,7 @@ public static function decode($json, $asArray = true) /** * Handles [[encode()]] and [[decode()]] errors by throwing exceptions with the respective error message. * - * @param int $lastError error code from [json_last_error()](https://secure.php.net/manual/en/function.json-last-error.php). + * @param int $lastError error code from [json_last_error()](https://www.php.net/manual/en/function.json-last-error.php). * @throws InvalidArgumentException if there is any encoding/decoding error. * @since 2.0.6 */ @@ -122,15 +143,14 @@ protected static function handleJsonError($lastError) return; } - $availableErrors = []; - foreach (static::$jsonErrorMessages as $const => $message) { - if (defined($const)) { - $availableErrors[constant($const)] = $message; - } + if (PHP_VERSION_ID >= 50500) { + throw new InvalidArgumentException(json_last_error_msg(), $lastError); } - if (isset($availableErrors[$lastError])) { - throw new InvalidArgumentException($availableErrors[$lastError], $lastError); + foreach (static::$jsonErrorMessages as $const => $message) { + if (defined($const) && constant($const) === $lastError) { + throw new InvalidArgumentException($message, $lastError); + } } throw new InvalidArgumentException('Unknown JSON encoding/decoding error.'); @@ -145,6 +165,8 @@ protected static function handleJsonError($lastError) */ protected static function processData($data, &$expressions, $expPrefix) { + $revertToObject = false; + if (is_object($data)) { if ($data instanceof JsExpression) { $token = "!{[$expPrefix=" . count($expressions) . ']}!'; @@ -165,16 +187,28 @@ protected static function processData($data, &$expressions, $expPrefix) $data = $data->toArray(); } elseif ($data instanceof \SimpleXMLElement) { $data = (array) $data; + + // Avoid empty elements to be returned as array. + // Not breaking BC because empty array was always cast to stdClass before. + $revertToObject = true; } else { + /* + * $data type is changed to array here and its elements will be processed further + * We must cast $data back to object later to keep intended dictionary type in JSON. + * Revert is only done when keepObjectType flag is provided to avoid breaking BC + */ + $revertToObject = static::$keepObjectType; + $result = []; foreach ($data as $name => $value) { $result[$name] = $value; } $data = $result; - } - if ($data === []) { - return new \stdClass(); + // Avoid empty objects to be returned as array (would break BC without keepObjectType flag) + if ($data === []) { + $revertToObject = true; + } } } @@ -186,11 +220,12 @@ protected static function processData($data, &$expressions, $expPrefix) } } - return $data; + return $revertToObject ? (object) $data : $data; } /** * Generates a summary of the validation errors. + * * @param Model|Model[] $models the model(s) whose validation errors are to be displayed. * @param array $options the tag options in terms of name-value pairs. The following options are specially handled: * @@ -205,13 +240,14 @@ public static function errorSummary($models, $options = []) $showAllErrors = ArrayHelper::remove($options, 'showAllErrors', false); $lines = self::collectErrors($models, $showAllErrors); - return json_encode($lines); + return static::encode($lines); } /** - * Return array of the validation errors + * Return array of the validation errors. + * * @param Model|Model[] $models the model(s) whose validation errors are to be displayed. - * @param $showAllErrors boolean, if set to true every error message for each attribute will be shown otherwise + * @param bool $showAllErrors if set to true every error message for each attribute will be shown otherwise * only the first error message for each attribute will be shown. * @return array of the validation errors * @since 2.0.14 @@ -219,14 +255,14 @@ public static function errorSummary($models, $options = []) private static function collectErrors($models, $showAllErrors) { $lines = []; + if (!is_array($models)) { $models = [$models]; } - foreach ($models as $model) { - $lines = array_unique(array_merge($lines, $model->getErrorSummary($showAllErrors))); + $lines[] = $model->getErrorSummary($showAllErrors); } - return $lines; + return array_unique(call_user_func_array('array_merge', $lines)); } } diff --git a/framework/helpers/BaseMarkdown.php b/framework/helpers/BaseMarkdown.php index 08da9c5b0e1..8975c476396 100644 --- a/framework/helpers/BaseMarkdown.php +++ b/framework/helpers/BaseMarkdown.php @@ -45,7 +45,7 @@ class BaseMarkdown /** * @var string the markdown flavor to use when none is specified explicitly. * Defaults to `original`. - * @see $flavors + * @see flavors */ public static $defaultFlavor = 'original'; @@ -54,7 +54,7 @@ class BaseMarkdown * Converts markdown into HTML. * * @param string $markdown the markdown text to parse - * @param string $flavor the markdown flavor to use. See [[$flavors]] for available values. + * @param string|null $flavor the markdown flavor to use. See [[$flavors]] for available values. * Defaults to [[$defaultFlavor]], if not set. * @return string the parsed HTML output * @throws InvalidArgumentException when an undefined flavor is given. @@ -72,7 +72,7 @@ public static function process($markdown, $flavor = null) * This can be useful for parsing small comments or description lines. * * @param string $markdown the markdown text to parse - * @param string $flavor the markdown flavor to use. See [[$flavors]] for available values. + * @param string|null $flavor the markdown flavor to use. See [[$flavors]] for available values. * Defaults to [[$defaultFlavor]], if not set. * @return string the parsed HTML output * @throws InvalidArgumentException when an undefined flavor is given. @@ -85,7 +85,7 @@ public static function processParagraph($markdown, $flavor = null) } /** - * @param string $flavor the markdown flavor to use. See [[$flavors]] for available values. + * @param string|null $flavor the markdown flavor to use. See [[$flavors]] for available values. * Defaults to [[$defaultFlavor]], if not set. * @return \cebe\markdown\Parser * @throws InvalidArgumentException when an undefined flavor is given. diff --git a/framework/helpers/BaseStringHelper.php b/framework/helpers/BaseStringHelper.php index 417c0ae40bc..d3498c35173 100644 --- a/framework/helpers/BaseStringHelper.php +++ b/framework/helpers/BaseStringHelper.php @@ -23,27 +23,33 @@ class BaseStringHelper /** * Returns the number of bytes in the given string. * This method ensures the string is treated as a byte array by using `mb_strlen()`. + * * @param string $string the string being measured for length * @return int the number of bytes in the given string. */ public static function byteLength($string) { - return mb_strlen($string, '8bit'); + return mb_strlen((string)$string, '8bit'); } /** * Returns the portion of string specified by the start and length parameters. * This method ensures the string is treated as a byte array by using `mb_substr()`. + * * @param string $string the input string. Must be one character or longer. * @param int $start the starting position - * @param int $length the desired portion length. If not specified or `null`, there will be + * @param int|null $length the desired portion length. If not specified or `null`, there will be * no limit on length i.e. the output will be until the end of the string. * @return string the extracted part of string, or FALSE on failure or an empty string. - * @see https://secure.php.net/manual/en/function.substr.php + * @see https://www.php.net/manual/en/function.substr.php */ public static function byteSubstr($string, $start, $length = null) { - return mb_substr($string, $start, $length === null ? mb_strlen($string, '8bit') : $length, '8bit'); + if ($length === null) { + $length = static::byteLength($string); + } + + return mb_substr($string, $start, $length, '8bit'); } /** @@ -57,15 +63,18 @@ public static function byteSubstr($string, $start, $length = null) * @param string $path A path string. * @param string $suffix If the name component ends in suffix this will also be cut off. * @return string the trailing name component of the given path. - * @see https://secure.php.net/manual/en/function.basename.php + * @see https://www.php.net/manual/en/function.basename.php */ public static function basename($path, $suffix = '') { - if (($len = mb_strlen($suffix)) > 0 && mb_substr($path, -$len) === $suffix) { + $len = mb_strlen($suffix); + if ($len > 0 && mb_substr($path, -$len) === $suffix) { $path = mb_substr($path, 0, -$len); } - $path = rtrim(str_replace('\\', '/', $path), '/\\'); - if (($pos = mb_strrpos($path, '/')) !== false) { + + $path = rtrim(str_replace('\\', '/', $path), '/'); + $pos = mb_strrpos($path, '/'); + if ($pos !== false) { return mb_substr($path, $pos + 1); } @@ -79,13 +88,18 @@ public static function basename($path, $suffix = '') * * @param string $path A path string. * @return string the parent directory's path. - * @see https://secure.php.net/manual/en/function.basename.php + * @see https://www.php.net/manual/en/function.basename.php */ public static function dirname($path) { - $pos = mb_strrpos(str_replace('\\', '/', $path), '/'); - if ($pos !== false) { - return mb_substr($path, 0, $pos); + $normalizedPath = rtrim( + str_replace('\\', '/', $path), + '/' + ); + $separatorPosition = mb_strrpos($normalizedPath, '/'); + + if ($separatorPosition !== false) { + return mb_substr($path, 0, $separatorPosition); } return ''; @@ -94,10 +108,14 @@ public static function dirname($path) /** * Truncates a string to the number of characters specified. * + * In order to truncate for an exact length, the $suffix char length must be counted towards the $length. For example + * to have a string which is exactly 255 long with $suffix `...` of 3 chars, then `StringHelper::truncate($string, 252, '...')` + * must be used to ensure you have 255 long string afterwards. + * * @param string $string The string to truncate. * @param int $length How many characters from original string to include into truncated string. * @param string $suffix String to append to the end of truncated string. - * @param string $encoding The charset to use, defaults to charset currently used by application. + * @param string|null $encoding The charset to use, defaults to charset currently used by application. * @param bool $asHtml Whether to treat the string being truncated as HTML and preserve proper HTML tags. * This parameter is available since version 2.0.1. * @return string the truncated string. @@ -134,7 +152,7 @@ public static function truncateWords($string, $count, $suffix = '...', $asHtml = return static::truncateHtml($string, $count, $suffix); } - $words = preg_split('/(\s+)/u', trim($string), null, PREG_SPLIT_DELIM_CAPTURE); + $words = preg_split('/(\s+)/u', trim($string), 0, PREG_SPLIT_DELIM_CAPTURE); if (count($words) / 2 > $count) { return implode('', array_slice($words, 0, ($count * 2) - 1)) . $suffix; } @@ -146,9 +164,9 @@ public static function truncateWords($string, $count, $suffix = '...', $asHtml = * Truncate a string while preserving the HTML. * * @param string $string The string to truncate - * @param int $count + * @param int $count The counter * @param string $suffix String to append to the end of the truncated string. - * @param string|bool $encoding + * @param string|bool $encoding Encoding flag or charset. * @return string * @since 2.0.1 */ @@ -205,12 +223,12 @@ protected static function truncateHtml($string, $count, $suffix, $encoding = fal } /** - * Check if given string starts with specified substring. - * Binary and multibyte safe. + * Check if given string starts with specified substring. Binary and multibyte safe. * * @param string $string Input string * @param string $with Part to search inside the $string - * @param bool $caseSensitive Case sensitive search. Default is true. When case sensitive is enabled, $with must exactly match the starting of the string in order to get a true value. + * @param bool $caseSensitive Case sensitive search. Default is true. When case sensitive is enabled, `$with` must + * exactly match the starting of the string in order to get a true value. * @return bool Returns true if first input starts with second input, false otherwise */ public static function startsWith($string, $with, $caseSensitive = true) @@ -220,19 +238,21 @@ public static function startsWith($string, $with, $caseSensitive = true) } if ($caseSensitive) { return strncmp($string, $with, $bytes) === 0; - } + $encoding = Yii::$app ? Yii::$app->charset : 'UTF-8'; - return mb_strtolower(mb_substr($string, 0, $bytes, '8bit'), $encoding) === mb_strtolower($with, $encoding); + $string = static::byteSubstr($string, 0, $bytes); + + return mb_strtolower($string, $encoding) === mb_strtolower($with, $encoding); } /** - * Check if given string ends with specified substring. - * Binary and multibyte safe. + * Check if given string ends with specified substring. Binary and multibyte safe. * * @param string $string Input string to check - * @param string $with Part to search inside of the $string. - * @param bool $caseSensitive Case sensitive search. Default is true. When case sensitive is enabled, $with must exactly match the ending of the string in order to get a true value. + * @param string $with Part to search inside of the `$string`. + * @param bool $caseSensitive Case sensitive search. Default is true. When case sensitive is enabled, `$with` must + * exactly match the ending of the string in order to get a true value. * @return bool Returns true if first input ends with second input, false otherwise */ public static function endsWith($string, $with, $caseSensitive = true) @@ -241,7 +261,7 @@ public static function endsWith($string, $with, $caseSensitive = true) return true; } if ($caseSensitive) { - // Warning check, see https://secure.php.net/manual/en/function.substr-compare.php#refsect1-function.substr-compare-returnvalues + // Warning check, see https://php.net/substr-compare#refsect1-function.substr-compare-returnvalues if (static::byteLength($string) < $bytes) { return false; } @@ -250,7 +270,9 @@ public static function endsWith($string, $with, $caseSensitive = true) } $encoding = Yii::$app ? Yii::$app->charset : 'UTF-8'; - return mb_strtolower(mb_substr($string, -$bytes, mb_strlen($string, '8bit'), '8bit'), $encoding) === mb_strtolower($with, $encoding); + $string = static::byteSubstr($string, -$bytes); + + return mb_strtolower($string, $encoding) === mb_strtolower($with, $encoding); } /** @@ -291,26 +313,27 @@ public static function explode($string, $delimiter = ',', $trim = true, $skipEmp /** * Counts words in a string. - * @since 2.0.8 * - * @param string $string + * @param string $string the text to calculate * @return int + * @since 2.0.8 */ public static function countWords($string) { - return count(preg_split('/\s+/u', $string, null, PREG_SPLIT_NO_EMPTY)); + return count(preg_split('/\s+/u', $string, 0, PREG_SPLIT_NO_EMPTY)); } /** * Returns string representation of number value with replaced commas to dots, if decimal point * of current locale is comma. - * @param int|float|string $value + * + * @param int|float|string $value the value to normalize. * @return string * @since 2.0.11 */ public static function normalizeNumber($value) { - $value = (string)$value; + $value = (string) $value; $localeInfo = localeconv(); $decimalSeparator = isset($localeInfo['decimal_point']) ? $localeInfo['decimal_point'] : null; @@ -328,9 +351,9 @@ public static function normalizeNumber($value) * > Note: Base 64 padding `=` may be at the end of the returned string. * > `=` is not transparent to URL encoding. * - * @see https://tools.ietf.org/html/rfc4648#page-7 * @param string $input the string to encode. * @return string encoded string. + * @see https://tools.ietf.org/html/rfc4648#page-7 * @since 2.0.12 */ public static function base64UrlEncode($input) @@ -341,9 +364,9 @@ public static function base64UrlEncode($input) /** * Decodes "Base 64 Encoding with URL and Filename Safe Alphabet" (RFC 4648). * - * @see https://tools.ietf.org/html/rfc4648#page-7 * @param string $input encoded string. * @return string decoded string. + * @see https://tools.ietf.org/html/rfc4648#page-7 * @since 2.0.12 */ public static function base64UrlDecode($input) @@ -353,8 +376,8 @@ public static function base64UrlDecode($input) /** * Safely casts a float to string independent of the current locale. - * * The decimal separator will always be `.`. + * * @param float|int $number a floating point number or integer. * @return string the string representation of the number. * @since 2.0.13 @@ -369,6 +392,7 @@ public static function floatToString($number) /** * Checks if the passed string would match the given shell wildcard pattern. * This function emulates [[fnmatch()]], which may be unavailable at certain environment, using PCRE. + * * @param string $pattern the shell wildcard pattern. * @param string $string the tested string. * @param array $options options for matching. Valid options are: @@ -416,7 +440,7 @@ public static function matchWildcard($pattern, $string, $options = []) $pattern .= 'i'; } - return preg_match($pattern, $string) === 1; + return preg_match($pattern, (string)$string) === 1; } /** @@ -425,13 +449,13 @@ public static function matchWildcard($pattern, $string, $options = []) * @param string $string the string to be proceeded * @param string $encoding Optional, defaults to "UTF-8" * @return string - * @see https://secure.php.net/manual/en/function.ucfirst.php + * @see https://www.php.net/manual/en/function.ucfirst.php * @since 2.0.16 */ public static function mb_ucfirst($string, $encoding = 'UTF-8') { - $firstChar = mb_substr($string, 0, 1, $encoding); - $rest = mb_substr($string, 1, null, $encoding); + $firstChar = mb_substr((string)$string, 0, 1, $encoding); + $rest = mb_substr((string)$string, 1, null, $encoding); return mb_strtoupper($firstChar, $encoding) . $rest; } @@ -442,17 +466,25 @@ public static function mb_ucfirst($string, $encoding = 'UTF-8') * @param string $string the string to be proceeded * @param string $encoding Optional, defaults to "UTF-8" * @return string - * @see https://secure.php.net/manual/en/function.ucwords.php + * @see https://www.php.net/manual/en/function.ucwords * @since 2.0.16 */ public static function mb_ucwords($string, $encoding = 'UTF-8') { - $words = preg_split("/\s/u", $string, -1, PREG_SPLIT_NO_EMPTY); + $string = (string) $string; + if (empty($string)) { + return $string; + } - $titelized = array_map(function ($word) use ($encoding) { - return static::mb_ucfirst($word, $encoding); - }, $words); + $parts = preg_split('/(\s+[^\w]+\s+|^[^\w]+\s+|\s+)/u', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); + $ucfirstEven = trim(mb_substr($parts[0], -1, 1, $encoding)) === ''; + foreach ($parts as $key => $value) { + $isEven = (bool)($key % 2); + if ($ucfirstEven === $isEven) { + $parts[$key] = static::mb_ucfirst($value, $encoding); + } + } - return implode(' ', $titelized); + return implode('', $parts); } } diff --git a/framework/helpers/BaseUrl.php b/framework/helpers/BaseUrl.php index 4c26696dd0d..e65a52a754c 100644 --- a/framework/helpers/BaseUrl.php +++ b/framework/helpers/BaseUrl.php @@ -232,12 +232,12 @@ public static function to($url = '', $scheme = false) } /** - * Normalize URL by ensuring that it use specified scheme. + * Normalize the URL by ensuring it uses specified scheme. * - * If URL is relative or scheme is not string, normalization is skipped. + * If the URL is relative or the scheme is not a string, normalization is skipped. * * @param string $url the URL to process - * @param string $scheme the URI scheme used in URL (e.g. `http` or `https`). Use empty string to + * @param string $scheme the URI scheme used in the URL (e.g. `http` or `https`). Use an empty string to * create protocol-relative URL (e.g. `//example.com/path`) * @return string the processed URL * @since 2.0.11 @@ -248,7 +248,7 @@ public static function ensureScheme($url, $scheme) return $url; } - if (substr($url, 0, 2) === '//') { + if (strncmp($url, '//', 2) === 0) { // e.g. //example.com/path/to/resource return $scheme === '' ? $url : "$scheme:$url"; } @@ -290,7 +290,7 @@ public static function base($scheme = false) * * @param string|array $url the URL to remember. Please refer to [[to()]] for acceptable formats. * If this parameter is not specified, the currently requested URL will be used. - * @param string $name the name associated with the URL to be remembered. This can be used + * @param string|null $name the name associated with the URL to be remembered. This can be used * later by [[previous()]]. If not set, [[\yii\web\User::setReturnUrl()]] will be used with passed URL. * @see previous() * @see \yii\web\User::setReturnUrl() @@ -309,7 +309,7 @@ public static function remember($url = '', $name = null) /** * Returns the URL previously [[remember()|remembered]]. * - * @param string $name the named associated with the URL that was remembered previously. + * @param string|null $name the named associated with the URL that was remembered previously. * If not set, [[\yii\web\User::getReturnUrl()]] will be used to obtain remembered URL. * @return string|null the URL previously remembered. Null is returned if no URL was remembered with the given name * and `$name` is not specified. diff --git a/framework/helpers/Markdown.php b/framework/helpers/Markdown.php index 8552d1320c9..c86e5e47664 100644 --- a/framework/helpers/Markdown.php +++ b/framework/helpers/Markdown.php @@ -23,7 +23,7 @@ * For more details please refer to the [Markdown library documentation](https://github.com/cebe/markdown#readme). * * > Note: The Markdown library works with PHPDoc annotations so if you use it together with - * > PHP `opcache` make sure [it does not strip comments](https://secure.php.net/manual/en/opcache.configuration.php#ini.opcache.save-comments). + * > PHP `opcache` make sure [it does not strip comments](https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.save-comments). * * @author Carsten Brandt * @since 2.0 diff --git a/framework/helpers/ReplaceArrayValue.php b/framework/helpers/ReplaceArrayValue.php index a408af264d4..3ce281cd2e3 100644 --- a/framework/helpers/ReplaceArrayValue.php +++ b/framework/helpers/ReplaceArrayValue.php @@ -79,7 +79,7 @@ public function __construct($value) * @param array $state * @return ReplaceArrayValue * @throws InvalidConfigException when $state property does not contain `value` parameter - * @see var_export() + * @see https://www.php.net/manual/en/function.var-export.php * @since 2.0.16 */ public static function __set_state($state) diff --git a/framework/helpers/UnsetArrayValue.php b/framework/helpers/UnsetArrayValue.php index e350c86e811..331b0619a43 100644 --- a/framework/helpers/UnsetArrayValue.php +++ b/framework/helpers/UnsetArrayValue.php @@ -54,7 +54,7 @@ class UnsetArrayValue * * @param array $state * @return UnsetArrayValue - * @see var_export() + * @see https://www.php.net/manual/en/function.var-export.php * @since 2.0.16 */ public static function __set_state($state) diff --git a/framework/helpers/mimeAliases.php b/framework/helpers/mimeAliases.php index 97abc324fd1..4cd89888a77 100644 --- a/framework/helpers/mimeAliases.php +++ b/framework/helpers/mimeAliases.php @@ -5,6 +5,7 @@ * This file contains aliases for MIME types. */ return [ + 'text/rtf' => 'application/rtf', 'text/xml' => 'application/xml', 'image/svg' => 'image/svg+xml', 'image/x-bmp' => 'image/bmp', diff --git a/framework/helpers/mimeTypes.php b/framework/helpers/mimeTypes.php index 95713079155..1a63a105540 100644 --- a/framework/helpers/mimeTypes.php +++ b/framework/helpers/mimeTypes.php @@ -8,7 +8,7 @@ * http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup * This file has been placed in the public domain for unlimited redistribution. */ -return [ +$mimeTypes = [ '3dml' => 'text/vnd.in3d.3dml', '3ds' => 'image/x-3ds', '3g2' => 'video/3gpp2', @@ -355,6 +355,7 @@ 'jam' => 'application/vnd.jam', 'jar' => 'application/java-archive', 'java' => 'text/x-java-source', + 'jfif' => 'image/jpeg', 'jisp' => 'application/vnd.jisp', 'jlt' => 'application/vnd.hp-jlyt', 'jnlp' => 'application/x-java-jnlp-file', @@ -400,6 +401,7 @@ 'log' => 'text/plain', 'lostxml' => 'application/lost+xml', 'lrf' => 'application/octet-stream', + 0 => 'application/vnd.lotus-1-2-3', 'lrm' => 'application/vnd.ms-lrm', 'ltf' => 'application/vnd.frogans.ltf', 'lvp' => 'audio/vnd.lucent.voice', @@ -480,7 +482,6 @@ 'mpkg' => 'application/vnd.apple.installer+xml', 'mpm' => 'application/vnd.blueice.multipass', 'mpn' => 'application/vnd.mophun.application', - 0 => 'application/vnd.lotus-1-2-3', 'mpp' => 'application/vnd.ms-project', 'mpt' => 'application/vnd.ms-project', 'mpy' => 'application/vnd.ibm.minipay', @@ -553,6 +554,7 @@ 'opf' => 'application/oebps-package+xml', 'opml' => 'text/x-opml', 'oprc' => 'application/vnd.palm', + 'opus' => 'audio/ogg', 'org' => 'application/vnd.lotus-organizer', 'osf' => 'application/vnd.yamaha.openscoreformat', 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', @@ -994,3 +996,9 @@ 'zirz' => 'application/vnd.zul', 'zmm' => 'application/vnd.handheld-entertainment+xml', ]; + +if (PHP_VERSION_ID >= 80100) { + $mimeTypes = array_replace($mimeTypes, array('xz' => 'application/octet-stream')); +} + +return $mimeTypes; diff --git a/framework/i18n/Formatter.php b/framework/i18n/Formatter.php index acf71020fb8..e1bdbc43c63 100644 --- a/framework/i18n/Formatter.php +++ b/framework/i18n/Formatter.php @@ -18,9 +18,11 @@ use yii\base\Component; use yii\base\InvalidArgumentException; use yii\base\InvalidConfigException; +use yii\helpers\ArrayHelper; use yii\helpers\FormatConverter; use yii\helpers\Html; use yii\helpers\HtmlPurifier; +use yii\helpers\Url; /** * Formatter provides a set of commonly used data formatting methods. @@ -33,7 +35,7 @@ * You can access that instance via `Yii::$app->formatter`. * * The Formatter class is designed to format values according to a [[locale]]. For this feature to work - * the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) has to be installed. + * the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) has to be installed. * Most of the methods however work also if the PHP intl extension is not installed by providing * a fallback implementation. Without intl month and day names are in English only. * Note that even if the intl extension is installed, formatting date and time values for years >=2038 or <=1901 @@ -42,7 +44,7 @@ * * > Note: The Formatter class is meant to be used for formatting values for display to users in different * > languages and time zones. If you need to format a date or time in machine readable format, use the - * > PHP [date()](https://secure.php.net/manual/en/function.date.php) function instead. + * > PHP [date()](https://www.php.net/manual/en/function.date.php) function instead. * * @author Qiang Xue * @author Enrica Ruedin @@ -77,7 +79,7 @@ class Formatter extends Component const UNIT_WEIGHT = 'mass'; /** - * @var string the text to be displayed when formatting a `null` value. + * @var string|null the text to be displayed when formatting a `null` value. * Defaults to `'(not set)'`, where `(not set)` * will be translated according to [[locale]]. */ @@ -90,25 +92,25 @@ class Formatter extends Component */ public $booleanFormat; /** - * @var string the locale ID that is used to localize the date and number formatting. + * @var string|null the locale ID that is used to localize the date and number formatting. * For number and date formatting this is only effective when the - * [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is installed. + * [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is installed. * If not set, [[\yii\base\Application::language]] will be used. */ public $locale; /** - * @var string the language code (e.g. `en-US`, `en`) that is used to translate internal messages. + * @var string|null the language code (e.g. `en-US`, `en`) that is used to translate internal messages. * If not set, [[locale]] will be used (without the `@calendar` param, if included). * * @since 2.0.28 */ public $language; /** - * @var string the time zone to use for formatting time and date values. + * @var string|null the time zone to use for formatting time and date values. * - * This can be any value that may be passed to [date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php) + * This can be any value that may be passed to [date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php) * e.g. `UTC`, `Europe/Berlin` or `America/Chicago`. - * Refer to the [php manual](https://secure.php.net/manual/en/timezones.php) for available time zones. + * Refer to the [php manual](https://www.php.net/manual/en/timezones.php) for available time zones. * If this property is not set, [[\yii\base\Application::timeZone]] will be used. * * Note that the default time zone for input data is assumed to be UTC by default if no time zone is included in the input date value. @@ -119,7 +121,7 @@ class Formatter extends Component * @var string the time zone that is assumed for input values if they do not include a time zone explicitly. * * The value must be a valid time zone identifier, e.g. `UTC`, `Europe/Berlin` or `America/Chicago`. - * Please refer to the [php manual](https://secure.php.net/manual/en/timezones.php) for available time zones. + * Please refer to the [php manual](https://www.php.net/manual/en/timezones.php) for available time zones. * * It defaults to `UTC` so you only have to adjust this value if you store datetime values in another time zone in your database. * @@ -133,9 +135,9 @@ class Formatter extends Component * @var string the default format string to be used to format a [[asDate()|date]]. * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. * - * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). + * It can also be a custom format as specified in the [ICU manual](https://unicode-org.github.io/icu/userguide/format_parse/datetime/). * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the - * PHP [date()](https://secure.php.net/manual/en/function.date.php)-function. + * PHP [date()](https://www.php.net/manual/en/function.date.php)-function. * * For example: * @@ -149,9 +151,9 @@ class Formatter extends Component * @var string the default format string to be used to format a [[asTime()|time]]. * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. * - * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). + * It can also be a custom format as specified in the [ICU manual](https://unicode-org.github.io/icu/userguide/format_parse/datetime/). * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the - * PHP [date()](https://secure.php.net/manual/en/function.date.php)-function. + * PHP [date()](https://www.php.net/manual/en/function.date.php)-function. * * For example: * @@ -165,10 +167,10 @@ class Formatter extends Component * @var string the default format string to be used to format a [[asDatetime()|date and time]]. * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. * - * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). + * It can also be a custom format as specified in the [ICU manual](https://unicode-org.github.io/icu/userguide/format_parse/datetime/). * * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the - * PHP [date()](https://secure.php.net/manual/en/function.date.php)-function. + * PHP [date()](https://www.php.net/manual/en/function.date.php) function. * * For example: * @@ -180,7 +182,7 @@ class Formatter extends Component public $datetimeFormat = 'medium'; /** * @var \IntlCalendar|int|null the calendar to be used for date formatting. The value of this property will be directly - * passed to the [constructor of the `IntlDateFormatter` class](https://secure.php.net/manual/en/intldateformatter.create.php). + * passed to the [constructor of the `IntlDateFormatter` class](https://www.php.net/manual/en/intldateformatter.create.php). * * Defaults to `null`, which means the Gregorian calendar will be used. You may also explicitly pass the constant * `\IntlDateFormatter::GREGORIAN` for Gregorian calendar. @@ -199,42 +201,42 @@ class Formatter extends Component * Available calendar names can be found in the [ICU manual](http://userguide.icu-project.org/datetime/calendar). * * Since PHP 5.5 you may also use an instance of the [[\IntlCalendar]] class. - * Check the [PHP manual](https://secure.php.net/manual/en/intldateformatter.create.php) for more details. + * Check the [PHP manual](https://www.php.net/manual/en/intldateformatter.create.php) for more details. * - * If the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, setting this property will have no effect. + * If the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is not available, setting this property will have no effect. * - * @see https://secure.php.net/manual/en/intldateformatter.create.php - * @see https://secure.php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants.calendartypes - * @see https://secure.php.net/manual/en/class.intlcalendar.php + * @see https://www.php.net/manual/en/intldateformatter.create.php + * @see https://www.php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants.calendartypes + * @see https://www.php.net/manual/en/class.intlcalendar.php * @since 2.0.7 */ public $calendar; /** - * @var string the character displayed as the decimal point when formatting a number. + * @var string|null the character displayed as the decimal point when formatting a number. * If not set, the decimal separator corresponding to [[locale]] will be used. - * If [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, the default value is '.'. + * If [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is not available, the default value is '.'. */ public $decimalSeparator; /** - * @var string the character displayed as the decimal point when formatting a currency. + * @var string|null the character displayed as the decimal point when formatting a currency. * If not set, the currency decimal separator corresponding to [[locale]] will be used. - * If [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, setting this property will have no effect. + * If [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is not available, setting this property will have no effect. * @since 2.0.35 */ public $currencyDecimalSeparator; /** - * @var string the character displayed as the thousands separator (also called grouping separator) character when formatting a number. + * @var string|null the character displayed as the thousands separator (also called grouping separator) character when formatting a number. * If not set, the thousand separator corresponding to [[locale]] will be used. - * If [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, the default value is ','. + * If [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is not available, the default value is ','. */ public $thousandSeparator; /** * @var array a list of name value pairs that are passed to the - * intl [NumberFormatter::setAttribute()](https://secure.php.net/manual/en/numberformatter.setattribute.php) method of all + * intl [NumberFormatter::setAttribute()](https://www.php.net/manual/en/numberformatter.setattribute.php) method of all * the number formatter objects created by [[createNumberFormatter()]]. - * This property takes only effect if the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is installed. + * This property takes only effect if the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is installed. * - * Please refer to the [PHP manual](https://secure.php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute) + * Please refer to the [PHP manual](https://www.php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute) * for the possible options. * * For example to adjust the maximum and minimum value of fraction digits you can configure this property like the following: @@ -249,11 +251,11 @@ class Formatter extends Component public $numberFormatterOptions = []; /** * @var array a list of name value pairs that are passed to the - * intl [NumberFormatter::setTextAttribute()](https://secure.php.net/manual/en/numberformatter.settextattribute.php) method of all + * intl [NumberFormatter::setTextAttribute()](https://www.php.net/manual/en/numberformatter.settextattribute.php) method of all * the number formatter objects created by [[createNumberFormatter()]]. - * This property takes only effect if the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is installed. + * This property takes only effect if the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is installed. * - * Please refer to the [PHP manual](https://secure.php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformattextattribute) + * Please refer to the [PHP manual](https://www.php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformattextattribute) * for the possible options. * * For example to change the minus sign for negative numbers you can configure this property like the following: @@ -267,11 +269,11 @@ class Formatter extends Component public $numberFormatterTextOptions = []; /** * @var array a list of name value pairs that are passed to the - * intl [NumberFormatter::setSymbol()](https://secure.php.net/manual/en/numberformatter.setsymbol.php) method of all + * intl [NumberFormatter::setSymbol()](https://www.php.net/manual/en/numberformatter.setsymbol.php) method of all * the number formatter objects created by [[createNumberFormatter()]]. - * This property takes only effect if the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is installed. + * This property takes only effect if the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is installed. * - * Please refer to the [PHP manual](https://secure.php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatsymbol) + * Please refer to the [PHP manual](https://www.php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatsymbol) * for the possible options. * * For example to choose a custom currency symbol, e.g. [U+20BD](http://unicode-table.com/en/20BD/) instead of `руб.` for Russian Ruble: @@ -286,7 +288,7 @@ class Formatter extends Component */ public $numberFormatterSymbols = []; /** - * @var string the 3-letter ISO 4217 currency code indicating the default currency to use for [[asCurrency]]. + * @var string|null the 3-letter ISO 4217 currency code indicating the default currency to use for [[asCurrency]]. * If not set, the currency code corresponding to [[locale]] will be used. * Note that in this case the [[locale]] has to be specified with a country code, e.g. `en-US` otherwise it * is not possible to determine the default currency. @@ -375,7 +377,7 @@ class Formatter extends Component ]; /** - * @var bool whether the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is loaded. + * @var bool whether the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is loaded. */ private $_intlLoaded = false; /** @@ -443,8 +445,9 @@ public function init() public function format($value, $format) { if ($format instanceof Closure) { - return call_user_func($format, $value, $this); - } elseif (is_array($format)) { + return $format($value, $this); + } + if (is_array($format)) { if (!isset($format[0])) { throw new InvalidArgumentException('The $format array must contain at least one element.'); } @@ -463,10 +466,8 @@ public function format($value, $format) throw new InvalidArgumentException("Unknown format type: $format"); } - // simple formats - /** * Formats the value as is without any formatting. * This method simply returns back the parameter without any format. @@ -485,7 +486,7 @@ public function asRaw($value) /** * Formats the value as an HTML-encoded plain text. - * @param string $value the value to be formatted. + * @param string|null $value the value to be formatted. * @return string the formatted result. */ public function asText($value) @@ -499,7 +500,7 @@ public function asText($value) /** * Formats the value as an HTML-encoded plain text with newlines converted into breaks. - * @param string $value the value to be formatted. + * @param string|null $value the value to be formatted. * @return string the formatted result. */ public function asNtext($value) @@ -515,7 +516,7 @@ public function asNtext($value) * Formats the value as HTML-encoded text paragraphs. * Each text paragraph is enclosed within a `

      ` tag. * One or multiple consecutive empty lines divide two paragraphs. - * @param string $value the value to be formatted. + * @param string|null $value the value to be formatted. * @return string the formatted result. */ public function asParagraphs($value) @@ -531,7 +532,7 @@ public function asParagraphs($value) * Formats the value as HTML text. * The value will be purified using [[HtmlPurifier]] to avoid XSS attacks. * Use [[asRaw()]] if you do not want any purification of the value. - * @param string $value the value to be formatted. + * @param string|null $value the value to be formatted. * @param array|null $config the configuration for the HTMLPurifier class. * @return string the formatted result. */ @@ -546,7 +547,7 @@ public function asHtml($value, $config = null) /** * Formats the value as a mailto link. - * @param string $value the value to be formatted. + * @param string|null $value the value to be formatted. * @param array $options the tag options in terms of name-value pairs. See [[Html::mailto()]]. * @return string the formatted result. */ @@ -577,7 +578,11 @@ public function asImage($value, $options = []) /** * Formats the value as a hyperlink. * @param mixed $value the value to be formatted. - * @param array $options the tag options in terms of name-value pairs. See [[Html::a()]]. + * @param array $options the tag options in terms of name-value pairs. See [[Html::a()]]. Since 2.0.43 there is + * a special option available `scheme` - if set it won't be passed to [[Html::a()]] but it will control the URL + * protocol part of the link by normalizing URL and ensuring that it uses specified scheme. See [[Url::ensureScheme()]]. + * If `scheme` is not set the original behavior is preserved which is to add "http://" prefix when "://" string is + * not found in the $value. * @return string the formatted result. */ public function asUrl($value, $options = []) @@ -586,8 +591,13 @@ public function asUrl($value, $options = []) return $this->nullDisplay; } $url = $value; - if (strpos($url, '://') === false) { - $url = 'http://' . $url; + $scheme = ArrayHelper::remove($options, 'scheme'); + if ($scheme === null) { + if (strpos($url, '://') === false) { + $url = 'http://' . $url; + } + } else { + $url = Url::ensureScheme($url, $scheme); } return Html::a(Html::encode($value), $url, $options); @@ -608,19 +618,17 @@ public function asBoolean($value) return $value ? $this->booleanFormat[1] : $this->booleanFormat[0]; } - // date and time formats - /** * Formats the value as a date. - * @param int|string|DateTime|DateTimeInterface $value the value to be formatted. The following + * @param int|string|DateTime|DateTimeInterface|null $value the value to be formatted. The following * types of value are supported: * * - an integer representing a UNIX timestamp. A UNIX timestamp is always in UTC by its definition. - * - a string that can be [parsed to create a DateTime object](https://secure.php.net/manual/en/datetime.formats.php). + * - a string that can be [parsed to create a DateTime object](https://www.php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given. - * - a PHP [DateTime](https://secure.php.net/manual/en/class.datetime.php) object. You may set the time zone + * - a PHP [DateTime](https://www.php.net/manual/en/class.datetime.php) object. You may set the time zone * for the DateTime object to specify the source time zone. * * The formatter will convert date values according to [[timeZone]] before formatting it. @@ -634,7 +642,7 @@ public function asBoolean($value) * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). * * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the - * PHP [date()](https://secure.php.net/manual/en/function.date.php)-function. + * PHP [date()](https://www.php.net/manual/en/function.date.php)-function. * * @return string the formatted result. * @throws InvalidArgumentException if the input value can not be evaluated as a date value. @@ -652,13 +660,13 @@ public function asDate($value, $format = null) /** * Formats the value as a time. - * @param int|string|DateTime|DateTimeInterface $value the value to be formatted. The following + * @param int|string|DateTime|DateTimeInterface|null $value the value to be formatted. The following * types of value are supported: * * - an integer representing a UNIX timestamp. A UNIX timestamp is always in UTC by its definition. - * - a string that can be [parsed to create a DateTime object](https://secure.php.net/manual/en/datetime.formats.php). + * - a string that can be [parsed to create a DateTime object](https://www.php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given. - * - a PHP [DateTime](https://secure.php.net/manual/en/class.datetime.php) object. You may set the time zone + * - a PHP [DateTime](https://www.php.net/manual/en/class.datetime.php) object. You may set the time zone * for the DateTime object to specify the source time zone. * * The formatter will convert date values according to [[timeZone]] before formatting it. @@ -671,7 +679,7 @@ public function asDate($value, $format = null) * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). * * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the - * PHP [date()](https://secure.php.net/manual/en/function.date.php)-function. + * PHP [date()](https://www.php.net/manual/en/function.date.php)-function. * * @return string the formatted result. * @throws InvalidArgumentException if the input value can not be evaluated as a date value. @@ -689,13 +697,13 @@ public function asTime($value, $format = null) /** * Formats the value as a datetime. - * @param int|string|DateTime|DateTimeInterface $value the value to be formatted. The following + * @param int|string|DateTime|DateTimeInterface|null $value the value to be formatted. The following * types of value are supported: * * - an integer representing a UNIX timestamp. A UNIX timestamp is always in UTC by its definition. - * - a string that can be [parsed to create a DateTime object](https://secure.php.net/manual/en/datetime.formats.php). + * - a string that can be [parsed to create a DateTime object](https://www.php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given. - * - a PHP [DateTime](https://secure.php.net/manual/en/class.datetime.php) object. You may set the time zone + * - a PHP [DateTime](https://www.php.net/manual/en/class.datetime.php) object. You may set the time zone * for the DateTime object to specify the source time zone. * * The formatter will convert date values according to [[timeZone]] before formatting it. @@ -708,7 +716,7 @@ public function asTime($value, $format = null) * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). * * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the - * PHP [date()](https://secure.php.net/manual/en/function.date.php)-function. + * PHP [date()](https://www.php.net/manual/en/function.date.php)-function. * * @return string the formatted result. * @throws InvalidArgumentException if the input value can not be evaluated as a date value. @@ -735,13 +743,13 @@ public function asDatetime($value, $format = null) ]; /** - * @param int|string|DateTime|DateTimeInterface $value the value to be formatted. The following + * @param int|string|DateTime|DateTimeInterface|null $value the value to be formatted. The following * types of value are supported: * * - an integer representing a UNIX timestamp - * - a string that can be [parsed to create a DateTime object](https://secure.php.net/manual/en/datetime.formats.php). + * - a string that can be [parsed to create a DateTime object](https://www.php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given. - * - a PHP [DateTime](https://secure.php.net/manual/en/class.datetime.php) object + * - a PHP [DateTime](https://www.php.net/manual/en/class.datetime.php) object * * @param string $format the format used to convert the value into a date string. * @param string $type 'date', 'time', or 'datetime'. @@ -754,7 +762,7 @@ private function formatDateTimeValue($value, $format, $type) // avoid time zone conversion for date-only and time-only values if ($type === 'date' || $type === 'time') { list($timestamp, $hasTimeInfo, $hasDateInfo) = $this->normalizeDatetimeValue($value, true); - if ($type === 'date' && !$hasTimeInfo || $type === 'time' && !$hasDateInfo) { + if (($type === 'date' && !$hasTimeInfo) || ($type === 'time' && !$hasDateInfo)) { $timeZone = $this->defaultTimeZone; } } else { @@ -772,18 +780,41 @@ private function formatDateTimeValue($value, $format, $type) } if (isset($this->_dateFormats[$format])) { if ($type === 'date') { - $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, $timeZone, $this->calendar); + $formatter = new IntlDateFormatter( + $this->locale, + $this->_dateFormats[$format], + IntlDateFormatter::NONE, + $timeZone, + $this->calendar + ); } elseif ($type === 'time') { - $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, $this->_dateFormats[$format], $timeZone, $this->calendar); + $formatter = new IntlDateFormatter( + $this->locale, + IntlDateFormatter::NONE, + $this->_dateFormats[$format], + $timeZone, + $this->calendar + ); } else { - $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], $this->_dateFormats[$format], $timeZone, $this->calendar); + $formatter = new IntlDateFormatter( + $this->locale, + $this->_dateFormats[$format], + $this->_dateFormats[$format], + $timeZone, + $this->calendar + ); } } else { - $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $timeZone, $this->calendar, $format); - } - if ($formatter === null) { - throw new InvalidConfigException(intl_get_error_message()); + $formatter = new IntlDateFormatter( + $this->locale, + IntlDateFormatter::NONE, + IntlDateFormatter::NONE, + $timeZone, + $this->calendar, + $format + ); } + // make IntlDateFormatter work with DateTimeImmutable if ($timestamp instanceof \DateTimeImmutable) { $timestamp = new DateTime($timestamp->format(DateTime::ISO8601), $timestamp->getTimezone()); @@ -811,20 +842,20 @@ private function formatDateTimeValue($value, $format, $type) /** * Normalizes the given datetime value as a DateTime object that can be taken by various date/time formatting methods. * - * @param int|string|DateTime|DateTimeInterface $value the datetime value to be normalized. The following + * @param int|string|DateTime|DateTimeInterface|null $value the datetime value to be normalized. The following * types of value are supported: * * - an integer representing a UNIX timestamp - * - a string that can be [parsed to create a DateTime object](https://secure.php.net/manual/en/datetime.formats.php). + * - a string that can be [parsed to create a DateTime object](https://www.php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given. - * - a PHP [DateTime](https://secure.php.net/manual/en/class.datetime.php) object + * - a PHP [DateTime](https://www.php.net/manual/en/class.datetime.php) object * * @param bool $checkDateTimeInfo whether to also check if the date/time value has some time and date information attached. * Defaults to `false`. If `true`, the method will then return an array with the first element being the normalized * timestamp, the second a boolean indicating whether the timestamp has time information and third a boolean indicating * whether the timestamp has date information. * This parameter is available since version 2.0.1. - * @return DateTime|array the normalized datetime value. + * @return DateTime|array the normalized datetime value * Since version 2.0.1 this may also return an array if `$checkDateTimeInfo` is true. * The first element of the array is the normalized timestamp and the second is a boolean indicating whether * the timestamp has time information or it is just a date value. @@ -846,9 +877,23 @@ protected function normalizeDatetimeValue($value, $checkDateTimeInfo = false) if (is_numeric($value)) { // process as unix timestamp, which is always in UTC $timestamp = new DateTime('@' . (int) $value, new DateTimeZone('UTC')); return $checkDateTimeInfo ? [$timestamp, true, true] : $timestamp; - } elseif (($timestamp = DateTime::createFromFormat('Y-m-d|', $value, new DateTimeZone($this->defaultTimeZone))) !== false) { // try Y-m-d format (support invalid dates like 2012-13-01) + } + if ( + ($timestamp = DateTime::createFromFormat( + 'Y-m-d|', + $value, + new DateTimeZone($this->defaultTimeZone)) + ) !== false + ) { // try Y-m-d format (support invalid dates like 2012-13-01) return $checkDateTimeInfo ? [$timestamp, false, true] : $timestamp; - } elseif (($timestamp = DateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone($this->defaultTimeZone))) !== false) { // try Y-m-d H:i:s format (support invalid dates like 2012-13-01 12:63:12) + } + if ( + ($timestamp = DateTime::createFromFormat( + 'Y-m-d H:i:s', + $value, + new DateTimeZone($this->defaultTimeZone)) + ) !== false + ) { // try Y-m-d H:i:s format (support invalid dates like 2012-13-01 12:63:12) return $checkDateTimeInfo ? [$timestamp, true, true] : $timestamp; } // finally try to create a DateTime object with the value @@ -871,13 +916,13 @@ protected function normalizeDatetimeValue($value, $checkDateTimeInfo = false) /** * Formats a date, time or datetime in a float number as UNIX timestamp (seconds since 01-01-1970). - * @param int|string|DateTime|DateTimeInterface $value the value to be formatted. The following + * @param int|string|DateTime|DateTimeInterface|null $value the value to be formatted. The following * types of value are supported: * * - an integer representing a UNIX timestamp - * - a string that can be [parsed to create a DateTime object](https://secure.php.net/manual/en/datetime.formats.php). + * - a string that can be [parsed to create a DateTime object](https://www.php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given. - * - a PHP [DateTime](https://secure.php.net/manual/en/class.datetime.php) object + * - a PHP [DateTime](https://www.php.net/manual/en/class.datetime.php) object * * @return string the formatted result. */ @@ -899,13 +944,13 @@ public function asTimestamp($value) * 2. Using a timestamp that is relative to the `$referenceTime`. * 3. Using a `DateInterval` object. * - * @param int|string|DateTime|DateTimeInterface|DateInterval $value the value to be formatted. The following + * @param int|string|DateTime|DateTimeInterface|DateInterval|null $value the value to be formatted. The following * types of value are supported: * * - an integer representing a UNIX timestamp - * - a string that can be [parsed to create a DateTime object](https://secure.php.net/manual/en/datetime.formats.php). + * - a string that can be [parsed to create a DateTime object](https://www.php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given. - * - a PHP [DateTime](https://secure.php.net/manual/en/class.datetime.php) object + * - a PHP [DateTime](https://www.php.net/manual/en/class.datetime.php) object * - a PHP DateInterval object (a positive time interval will refer to the past, a negative one to the future) * * @param int|string|DateTime|DateTimeInterface|null $referenceTime if specified the value is used as a reference time instead of `now` @@ -923,30 +968,17 @@ public function asRelativeTime($value, $referenceTime = null) $interval = $value; } else { $timestamp = $this->normalizeDatetimeValue($value); + $timeZone = new DateTimeZone($this->timeZone); - if ($timestamp === false) { - // $value is not a valid date/time value, so we try - // to create a DateInterval with it - try { - $interval = new DateInterval($value); - } catch (\Exception $e) { - // invalid date/time and invalid interval - return $this->nullDisplay; - } + if ($referenceTime === null) { + $dateNow = new DateTime('now', $timeZone); } else { - $timeZone = new DateTimeZone($this->timeZone); - - if ($referenceTime === null) { - $dateNow = new DateTime('now', $timeZone); - } else { - $dateNow = $this->normalizeDatetimeValue($referenceTime); - $dateNow->setTimezone($timeZone); - } - - $dateThen = $timestamp->setTimezone($timeZone); - - $interval = $dateThen->diff($dateNow); + $dateNow = $this->normalizeDatetimeValue($referenceTime); + $dateNow->setTimezone($timeZone); } + + $dateThen = $timestamp->setTimezone($timeZone); + $interval = $dateThen->diff($dateNow); } if ($interval->invert) { @@ -997,8 +1029,8 @@ public function asRelativeTime($value, $referenceTime = null) /** * Represents the value as duration in human readable format. * - * @param DateInterval|string|int $value the value to be formatted. Acceptable formats: - * - [DateInterval object](https://secure.php.net/manual/ru/class.dateinterval.php) + * @param DateInterval|string|int|null $value the value to be formatted. Acceptable formats: + * - [DateInterval object](https://www.php.net/manual/ru/class.dateinterval.php) * - integer - number of seconds. For example: value `131` represents `2 minutes, 11 seconds` * - ISO8601 duration format. For example, all of these values represent `1 day, 2 hours, 30 minutes` duration: * `2015-01-01T13:00:00Z/2015-01-02T13:30:00Z` - between two datetime values @@ -1069,7 +1101,7 @@ public function asDuration($value, $implodeString = ', ', $negativeSign = '-') * Formats the value as an integer number by removing any decimal digits without rounding. * * Since 2.0.16 numbers that are mispresented after normalization are formatted as strings using fallback function - * without [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) support. For very big numbers it's + * without [PHP intl extension](https://www.php.net/manual/en/book.intl.php) support. For very big numbers it's * recommended to pass them as strings and not use scientific notation otherwise the output might be wrong. * * @param mixed $value the value to be formatted. @@ -1110,7 +1142,7 @@ public function asInteger($value, $options = [], $textOptions = []) * value is rounded automatically to the defined decimal digits. * * Since 2.0.16 numbers that are mispresented after normalization are formatted as strings using fallback function - * without [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) support. For very big numbers it's + * without [PHP intl extension](https://www.php.net/manual/en/book.intl.php) support. For very big numbers it's * recommended to pass them as strings and not use scientific notation otherwise the output might be wrong. * * @param mixed $value the value to be formatted. @@ -1160,7 +1192,7 @@ public function asDecimal($value, $decimals = null, $options = [], $textOptions * Formats the value as a percent number with "%" sign. * * Since 2.0.16 numbers that are mispresented after normalization are formatted as strings using fallback function - * without [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) support. For very big numbers it's + * without [PHP intl extension](https://www.php.net/manual/en/book.intl.php) support. For very big numbers it's * recommended to pass them as strings and not use scientific notation otherwise the output might be wrong. * * @param mixed $value the value to be formatted. It must be a factor e.g. `0.75` will result in `75%`. @@ -1213,7 +1245,8 @@ public function asPercent($value, $decimals = null, $options = [], $textOptions * If not given, the number of digits depends in the input value and is determined based on * `NumberFormatter::MIN_FRACTION_DIGITS` and `NumberFormatter::MAX_FRACTION_DIGITS`, which can be configured * using [[$numberFormatterOptions]]. - * If the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available, the default value depends on your PHP configuration. + * If the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is not available, the default value + * depends on your PHP configuration. * If you want consistent behavior between environments where intl is available and not, you should explicitly * specify a value here. * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]]. @@ -1247,7 +1280,7 @@ public function asScientific($value, $decimals = null, $options = [], $textOptio /** * Formats the value as a currency number. * - * This function does not require the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) to be installed + * This function does not require the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) to be installed * to work, but it is highly recommended to install it to get good formatting results. * * Since 2.0.16 numbers that are mispresented after normalization are formatted as strings using fallback function @@ -1278,7 +1311,7 @@ public function asCurrency($value, $currency = null, $options = [], $textOptions if ($this->_intlLoaded) { $currency = $currency ?: $this->currencyCode; // currency code must be set before fraction digits - // https://secure.php.net/manual/en/numberformatter.formatcurrency.php#114376 + // https://www.php.net/manual/en/numberformatter.formatcurrency.php#114376 if ($currency && !isset($textOptions[NumberFormatter::CURRENCY_CODE])) { $textOptions[NumberFormatter::CURRENCY_CODE] = $currency; } @@ -1308,14 +1341,14 @@ public function asCurrency($value, $currency = null, $options = [], $textOptions /** * Formats the value as a number spellout. * - * This function requires the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) to be installed. + * This function requires the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) to be installed. * * This formatter does not work well with very big numbers. * * @param mixed $value the value to be formatted * @return string the formatted result. * @throws InvalidArgumentException if the input value is not numeric or the formatting failed. - * @throws InvalidConfigException when the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available. + * @throws InvalidConfigException when the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is not available. */ public function asSpellout($value) { @@ -1338,14 +1371,14 @@ public function asSpellout($value) /** * Formats the value as a ordinal value of a number. * - * This function requires the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) to be installed. + * This function requires the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) to be installed. * * This formatter does not work well with very big numbers. * * @param mixed $value the value to be formatted * @return string the formatted result. * @throws InvalidArgumentException if the input value is not numeric or the formatting failed. - * @throws InvalidConfigException when the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is not available. + * @throws InvalidConfigException when the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is not available. */ public function asOrdinal($value) { @@ -1373,7 +1406,7 @@ public function asOrdinal($value) * If [[sizeFormatBase]] is 1024, [binary prefixes](http://en.wikipedia.org/wiki/Binary_prefix) (e.g. kibibyte/KiB, mebibyte/MiB, ...) * are used in the formatting result. * - * @param string|int|float $value value in bytes to be formatted. + * @param string|int|float|null $value value in bytes to be formatted. * @param int|null $decimals the number of digits after the decimal point. * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]]. * @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]]. @@ -1429,7 +1462,7 @@ public function asShortSize($value, $decimals = null, $options = [], $textOption * If [[sizeFormatBase]] is 1024, [binary prefixes](http://en.wikipedia.org/wiki/Binary_prefix) (e.g. kibibyte/KiB, mebibyte/MiB, ...) * are used in the formatting result. * - * @param string|int|float $value value in bytes to be formatted. + * @param string|int|float|null $value value in bytes to be formatted. * @param int|null $decimals the number of digits after the decimal point. * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]]. * @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]]. @@ -1497,7 +1530,7 @@ public function asSize($value, $decimals = null, $options = [], $textOptions = [ */ public function asLength($value, $decimals = null, $numberOptions = [], $textOptions = []) { - return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_LONG, $value, null, null, $decimals, $numberOptions, $textOptions); + return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_LONG, $value, $decimals, $numberOptions, $textOptions); } /** @@ -1520,7 +1553,7 @@ public function asLength($value, $decimals = null, $numberOptions = [], $textOpt */ public function asShortLength($value, $decimals = null, $options = [], $textOptions = []) { - return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_SHORT, $value, null, null, $decimals, $options, $textOptions); + return $this->formatUnit(self::UNIT_LENGTH, self::FORMAT_WIDTH_SHORT, $value, $decimals, $options, $textOptions); } /** @@ -1540,7 +1573,7 @@ public function asShortLength($value, $decimals = null, $options = [], $textOpti */ public function asWeight($value, $decimals = null, $options = [], $textOptions = []) { - return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_LONG, $value, null, null, $decimals, $options, $textOptions); + return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_LONG, $value, $decimals, $options, $textOptions); } /** @@ -1562,38 +1595,29 @@ public function asWeight($value, $decimals = null, $options = [], $textOptions = */ public function asShortWeight($value, $decimals = null, $options = [], $textOptions = []) { - return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_SHORT, $value, null, null, $decimals, $options, $textOptions); + return $this->formatUnit(self::UNIT_WEIGHT, self::FORMAT_WIDTH_SHORT, $value, $decimals, $options, $textOptions); } /** * @param string $unitType one of [[UNIT_WEIGHT]], [[UNIT_LENGTH]] * @param string $unitFormat one of [[FORMAT_WIDTH_SHORT]], [[FORMAT_WIDTH_LONG]] - * @param float|int $value to be formatted - * @param float $baseUnit unit of value as the multiplier of the smallest unit. When `null`, property [[baseUnits]] - * will be used to determine base unit using $unitType and $unitSystem. - * @param string $unitSystem either [[UNIT_SYSTEM_METRIC]] or [[UNIT_SYSTEM_IMPERIAL]]. When `null`, property [[systemOfUnits]] will be used. - * @param int $decimals the number of digits after the decimal point. + * @param float|int|null $value to be formatted + * @param int|null $decimals the number of digits after the decimal point. * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]]. * @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]]. * @return string * @throws InvalidConfigException when INTL is not installed or does not contain required information */ - private function formatUnit($unitType, $unitFormat, $value, $baseUnit, $unitSystem, $decimals, $options, $textOptions) + private function formatUnit($unitType, $unitFormat, $value, $decimals, $options, $textOptions) { if ($value === null) { return $this->nullDisplay; } - if ($unitSystem === null) { - $unitSystem = $this->systemOfUnits; - } - if ($baseUnit === null) { - $baseUnit = $this->baseUnits[$unitType][$unitSystem]; - } - $multipliers = array_values($this->measureUnits[$unitType][$unitSystem]); + $multipliers = array_values($this->measureUnits[$unitType][$this->systemOfUnits]); list($params, $position) = $this->formatNumber( - $this->normalizeNumericValue($value) * $baseUnit, + $this->normalizeNumericValue($value) * $this->baseUnits[$unitType][$this->systemOfUnits], $decimals, null, $multipliers, @@ -1601,7 +1625,7 @@ private function formatUnit($unitType, $unitFormat, $value, $baseUnit, $unitSyst $textOptions ); - $message = $this->getUnitMessage($unitType, $unitFormat, $unitSystem, $position); + $message = $this->getUnitMessage($unitType, $unitFormat, $this->systemOfUnits, $position); return (new \MessageFormatter($this->locale, $message))->format([ '0' => $params['nFormatted'], @@ -1612,7 +1636,7 @@ private function formatUnit($unitType, $unitFormat, $value, $baseUnit, $unitSyst /** * @param string $unitType one of [[UNIT_WEIGHT]], [[UNIT_LENGTH]] * @param string $unitFormat one of [[FORMAT_WIDTH_SHORT]], [[FORMAT_WIDTH_LONG]] - * @param string $system either [[UNIT_SYSTEM_METRIC]] or [[UNIT_SYSTEM_IMPERIAL]]. When `null`, property [[systemOfUnits]] will be used. + * @param string|null $system either [[UNIT_SYSTEM_METRIC]] or [[UNIT_SYSTEM_IMPERIAL]]. When `null`, property [[systemOfUnits]] will be used. * @param int $position internal position of size unit * @return string * @throws InvalidConfigException when INTL is not installed or does not contain required information @@ -1638,7 +1662,10 @@ private function getUnitMessage($unitType, $unitFormat, $system, $position) $unitBundle = $this->_resourceBundle[$bundleKey][$unitType][$unitNames[$position]]; if ($unitBundle === null) { - throw new InvalidConfigException('Current ICU data version does not contain information about unit type "' . $unitType . '" and unit measure "' . $unitNames[$position] . '". Check system requirements.'); + throw new InvalidConfigException( + 'Current ICU data version does not contain information about unit type "' . $unitType + . '" and unit measure "' . $unitNames[$position] . '". Check system requirements.' + ); } $message = []; @@ -1656,7 +1683,7 @@ private function getUnitMessage($unitType, $unitFormat, $system, $position) * Given the value in bytes formats number part of the human readable form. * * @param string|int|float $value value in bytes to be formatted. - * @param int $decimals the number of digits after the decimal point + * @param int|null $decimals the number of digits after the decimal point * @param int $maxPosition maximum internal position of size unit, ignored if $formatBase is an array * @param array|int $formatBase the base at which each next unit is calculated, either 1000 or 1024, or an array * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]]. @@ -1705,7 +1732,7 @@ protected function formatNumber($value, $decimals, $maxPosition, $formatBase, $o $oldThousandSeparator = $this->thousandSeparator; $this->thousandSeparator = ''; if ($this->_intlLoaded && !isset($options[NumberFormatter::GROUPING_USED])) { - $options[NumberFormatter::GROUPING_USED] = false; + $options[NumberFormatter::GROUPING_USED] = 0; } // format the size value $params = [ @@ -1724,9 +1751,9 @@ protected function formatNumber($value, $decimals, $maxPosition, $formatBase, $o /** * Normalizes a numeric input value. * - * - everything [empty](https://secure.php.net/manual/en/function.empty.php) will result in `0` - * - a [numeric](https://secure.php.net/manual/en/function.is-numeric.php) string will be casted to float - * - everything else will be returned if it is [numeric](https://secure.php.net/manual/en/function.is-numeric.php), + * - everything [empty](https://www.php.net/manual/en/function.empty.php) will result in `0` + * - a [numeric](https://www.php.net/manual/en/function.is-numeric.php) string will be casted to float + * - everything else will be returned if it is [numeric](https://www.php.net/manual/en/function.is-numeric.php), * otherwise an exception is thrown. * * @param mixed $value the input value @@ -1766,19 +1793,19 @@ protected function createNumberFormatter($style, $decimals = null, $options = [] $formatter = new NumberFormatter($this->locale, $style); // set text attributes - foreach ($this->numberFormatterTextOptions as $name => $attribute) { - $formatter->setTextAttribute($name, $attribute); + foreach ($this->numberFormatterTextOptions as $attribute => $value) { + $this->setFormatterTextAttribute($formatter, $attribute, $value, 'numberFormatterTextOptions', 'numberFormatterOptions'); } - foreach ($textOptions as $name => $attribute) { - $formatter->setTextAttribute($name, $attribute); + foreach ($textOptions as $attribute => $value) { + $this->setFormatterTextAttribute($formatter, $attribute, $value, '$textOptions', '$options'); } // set attributes - foreach ($this->numberFormatterOptions as $name => $value) { - $formatter->setAttribute($name, $value); + foreach ($this->numberFormatterOptions as $attribute => $value) { + $this->setFormatterIntAttribute($formatter, $attribute, $value, 'numberFormatterOptions', 'numberFormatterTextOptions'); } - foreach ($options as $name => $value) { - $formatter->setAttribute($name, $value); + foreach ($options as $attribute => $value) { + $this->setFormatterIntAttribute($formatter, $attribute, $value, '$options', '$textOptions'); } if ($decimals !== null) { $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals); @@ -1796,13 +1823,91 @@ protected function createNumberFormatter($style, $decimals = null, $options = [] $formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator); $formatter->setSymbol(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator); } - foreach ($this->numberFormatterSymbols as $name => $symbol) { - $formatter->setSymbol($name, $symbol); + foreach ($this->numberFormatterSymbols as $symbol => $value) { + $this->setFormatterSymbol($formatter, $symbol, $value, 'numberFormatterSymbols'); } return $formatter; } + /** + * @param NumberFormatter $formatter + * @param mixed $attribute + * @param mixed $value + * @param string $source + * @param string $alternative + */ + private function setFormatterTextAttribute($formatter, $attribute, $value, $source, $alternative) + { + if (!is_int($attribute)) { + throw new InvalidArgumentException( + "The $source array keys must be integers recognizable by NumberFormatter::setTextAttribute(). \"" + . gettype($attribute) . '" provided instead.' + ); + } + if (!is_string($value)) { + if (is_int($value)) { + throw new InvalidArgumentException( + "The $source array values must be strings. Did you mean to use $alternative?" + ); + } + throw new InvalidArgumentException( + "The $source array values must be strings. \"" . gettype($value) . '" provided instead.' + ); + } + $formatter->setTextAttribute($attribute, $value); + } + + /** + * @param NumberFormatter $formatter + * @param mixed $symbol + * @param mixed $value + * @param string $source + */ + private function setFormatterSymbol($formatter, $symbol, $value, $source) + { + if (!is_int($symbol)) { + throw new InvalidArgumentException( + "The $source array keys must be integers recognizable by NumberFormatter::setSymbol(). \"" + . gettype($symbol) . '" provided instead.' + ); + } + if (!is_string($value)) { + throw new InvalidArgumentException( + "The $source array values must be strings. \"" . gettype($value) . '" provided instead.' + ); + } + $formatter->setSymbol($symbol, $value); + } + + /** + * @param NumberFormatter $formatter + * @param mixed $attribute + * @param mixed $value + * @param string $source + * @param string $alternative + */ + private function setFormatterIntAttribute($formatter, $attribute, $value, $source, $alternative) + { + if (!is_int($attribute)) { + throw new InvalidArgumentException( + "The $source array keys must be integers recognizable by NumberFormatter::setAttribute(). \"" + . gettype($attribute) . '" provided instead.' + ); + } + if (!is_int($value)) { + if (is_string($value)) { + throw new InvalidArgumentException( + "The $source array values must be integers. Did you mean to use $alternative?" + ); + } + throw new InvalidArgumentException( + "The $source array values must be integers. \"" . gettype($value) . '" provided instead.' + ); + } + $formatter->setAttribute($attribute, $value); + } + /** * Checks if string representations of given value and its normalized version are different. * @param string|float|int $value @@ -1881,7 +1986,7 @@ protected function normalizeNumericStringValue($value) * to the defined decimal digits. * * @param string|int|float $value the value to be formatted. - * @param int $decimals the number of digits after the decimal point. The default value is `2`. + * @param int|null $decimals the number of digits after the decimal point. The default value is `2`. * @return string the formatted result. * @see decimalSeparator * @see thousandSeparator diff --git a/framework/i18n/GettextMessageSource.php b/framework/i18n/GettextMessageSource.php index 32a3bf1e6a5..2f68f1591f1 100644 --- a/framework/i18n/GettextMessageSource.php +++ b/framework/i18n/GettextMessageSource.php @@ -8,6 +8,7 @@ namespace yii\i18n; use Yii; +use yii\base\InvalidArgumentException; /** * GettextMessageSource represents a message source that is based on GNU Gettext. @@ -32,19 +33,19 @@ class GettextMessageSource extends MessageSource const PO_FILE_EXT = '.po'; /** - * @var string + * @var string base directory of messages files */ public $basePath = '@app/messages'; /** - * @var string + * @var string sub-directory of messages files */ public $catalog = 'messages'; /** - * @var bool + * @var bool whether to use generated MO files */ public $useMoFile = true; /** - * @var bool + * @var bool whether to use big-endian when reading and writing an integer */ public $useBigEndian = false; @@ -72,14 +73,12 @@ protected function loadMessages($category, $language) $fallbackLanguage = substr($language, 0, 2); $fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2); - if ($fallbackLanguage !== $language) { + if ($fallbackLanguage !== '' && $fallbackLanguage !== $language) { $messages = $this->loadFallbackMessages($category, $fallbackLanguage, $messages, $messageFile); - } elseif ($language === $fallbackSourceLanguage) { + } elseif ($fallbackSourceLanguage !== '' && $language === $fallbackSourceLanguage) { $messages = $this->loadFallbackMessages($category, $this->sourceLanguage, $messages, $messageFile); - } else { - if ($messages === null) { - Yii::error("The message file for category '$category' does not exist: $messageFile", __METHOD__); - } + } elseif ($messages === null) { + Yii::error("The message file for category '$category' does not exist: $messageFile", __METHOD__); } return (array) $messages; @@ -106,7 +105,7 @@ protected function loadFallbackMessages($category, $fallbackLanguage, $messages, if ( $messages === null && $fallbackMessages === null && $fallbackLanguage !== $this->sourceLanguage - && $fallbackLanguage !== substr($this->sourceLanguage, 0, 2) + && strpos($this->sourceLanguage, $fallbackLanguage) !== 0 ) { Yii::error("The message file for category '$category' does not exist: $originalMessageFile " . "Fallback file does not exist as well: $fallbackMessageFile", __METHOD__); @@ -115,7 +114,7 @@ protected function loadFallbackMessages($category, $fallbackLanguage, $messages, } elseif (!empty($fallbackMessages)) { foreach ($fallbackMessages as $key => $value) { if (!empty($value) && empty($messages[$key])) { - $messages[$key] = $fallbackMessages[$key]; + $messages[$key] = $value; } } } @@ -131,6 +130,10 @@ protected function loadFallbackMessages($category, $fallbackLanguage, $messages, */ protected function getMessageFilePath($language) { + $language = (string) $language; + if ($language !== '' && !preg_match('/^[a-z0-9_-]+$/i', $language)) { + throw new InvalidArgumentException(sprintf('Invalid language code: "%s".', $language)); + } $messageFile = Yii::getAlias($this->basePath) . '/' . $language . '/' . $this->catalog; if ($this->useMoFile) { $messageFile .= self::MO_FILE_EXT; diff --git a/framework/i18n/GettextMoFile.php b/framework/i18n/GettextMoFile.php index 43b5afaf1f6..942a7287b84 100644 --- a/framework/i18n/GettextMoFile.php +++ b/framework/i18n/GettextMoFile.php @@ -106,7 +106,7 @@ public function load($filePath, $context) $messages = []; for ($i = 0; $i < $count; ++$i) { $id = $this->readString($fileHandle, $sourceLengths[$i], $sourceOffsets[$i]); - $separatorPosition = strpos($id, chr(4)); + $separatorPosition = strpos((string)$id, chr(4)); if ((!$context && $separatorPosition === false) || ($context && $separatorPosition !== false && strncmp($id, $context, $separatorPosition) === 0)) { @@ -250,7 +250,7 @@ protected function writeInteger($fileHandle, $integer) * Reads a string. * @param resource $fileHandle file handle * @param int $length of the string - * @param int $offset of the string in the file. If null, it reads from the current position. + * @param int|null $offset of the string in the file. If null, it reads from the current position. * @return string the result */ protected function readString($fileHandle, $length, $offset = null) diff --git a/framework/i18n/I18N.php b/framework/i18n/I18N.php index 3e5bd425d19..49cf93bd459 100644 --- a/framework/i18n/I18N.php +++ b/framework/i18n/I18N.php @@ -19,7 +19,7 @@ * * @property MessageFormatter $messageFormatter The message formatter to be used to format message via ICU * message format. Note that the type of this property differs in getter and setter. See - * [[getMessageFormatter()]] and [[setMessageFormatter()]] for details. + * [[getMessageFormatter()]] and [[setMessageFormatter()]] for details. * * @author Qiang Xue * @since 2.0 diff --git a/framework/i18n/Locale.php b/framework/i18n/Locale.php index 86b78de6a88..f81907644aa 100644 --- a/framework/i18n/Locale.php +++ b/framework/i18n/Locale.php @@ -14,16 +14,16 @@ /** * Locale provides various locale information via convenient methods. * - * The class requires [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) to be installed. + * The class requires [PHP intl extension](https://www.php.net/manual/en/book.intl.php) to be installed. * - * @property-read string $currencySymbol This property is read-only. + * @property-read string $currencySymbol * * @since 2.0.14 */ class Locale extends Component { /** - * @var string the locale ID. + * @var string|null the locale ID. * If not set, [[\yii\base\Application::language]] will be used. */ public $locale; @@ -46,7 +46,7 @@ public function init() /** * Returns a currency symbol * - * @param string $currencyCode the 3-letter ISO 4217 currency code to get symbol for. If null, + * @param string|null $currencyCode the 3-letter ISO 4217 currency code to get symbol for. If null, * method will attempt using currency code from [[locale]]. * @return string */ diff --git a/framework/i18n/MessageFormatter.php b/framework/i18n/MessageFormatter.php index 2fdba093213..e92696c0ee2 100644 --- a/framework/i18n/MessageFormatter.php +++ b/framework/i18n/MessageFormatter.php @@ -23,7 +23,7 @@ * substituted. * - Fixes PHP 5.5 weird placeholder replacement in case no arguments are provided at all (https://bugs.php.net/bug.php?id=65920). * - Offers limited support for message formatting in case PHP intl extension is not installed. - * However it is highly recommended that you install [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) if you want + * However it is highly recommended that you install [PHP intl extension](https://www.php.net/manual/en/book.intl.php) if you want * to use MessageFormatter features. * * The fallback implementation only supports the following message formats: @@ -32,12 +32,12 @@ * - simple parameters * - integer number parameters * - * The fallback implementation does NOT support the ['apostrophe-friendly' syntax](https://secure.php.net/manual/en/messageformatter.formatmessage.php). + * The fallback implementation does NOT support the ['apostrophe-friendly' syntax](https://www.php.net/manual/en/messageformatter.formatmessage.php). * Also messages that are working with the fallback implementation are not necessarily compatible with the * PHP intl MessageFormatter so do not rely on the fallback if you are able to install intl extension somehow. * - * @property-read string $errorCode Code of the last error. This property is read-only. - * @property-read string $errorMessage Description of the last error. This property is read-only. + * @property-read string $errorCode Code of the last error. + * @property-read string $errorMessage Description of the last error. * * @author Alexander Makarov * @author Carsten Brandt @@ -51,7 +51,7 @@ class MessageFormatter extends Component /** * Get the error code from the last operation. - * @link https://secure.php.net/manual/en/messageformatter.geterrorcode.php + * @link https://www.php.net/manual/en/messageformatter.geterrorcode.php * @return string Code of the last error. */ public function getErrorCode() @@ -61,7 +61,7 @@ public function getErrorCode() /** * Get the error text from the last operation. - * @link https://secure.php.net/manual/en/messageformatter.geterrormessage.php + * @link https://www.php.net/manual/en/messageformatter.geterrormessage.php * @return string Description of the last error. */ public function getErrorMessage() @@ -72,7 +72,7 @@ public function getErrorMessage() /** * Formats a message via [ICU message format](http://userguide.icu-project.org/formatparse/messages). * - * It uses the PHP intl extension's [MessageFormatter](https://secure.php.net/manual/en/class.messageformatter.php) + * It uses the PHP intl extension's [MessageFormatter](https://www.php.net/manual/en/class.messageformatter.php) * and works around some issues. * If PHP intl is not installed a fallback will be used that supports a subset of the ICU message format. * @@ -134,7 +134,7 @@ public function format($pattern, $params, $language) /** * Parses an input string according to an [ICU message format](http://userguide.icu-project.org/formatparse/messages) pattern. * - * It uses the PHP intl extension's [MessageFormatter::parse()](https://secure.php.net/manual/en/messageformatter.parsemessage.php) + * It uses the PHP intl extension's [MessageFormatter::parse()](https://www.php.net/manual/en/messageformatter.parsemessage.php) * and adds support for named arguments. * Usage of this method requires PHP intl extension to be installed. * @@ -423,7 +423,7 @@ private function parseToken($token, $args, $locale) $selector = trim(mb_substr($selector, $pos + 1, mb_strlen($selector, $charset), $charset)); } if ($message === false && $selector === 'other' || - $selector[0] === '=' && (int) mb_substr($selector, 1, mb_strlen($selector, $charset), $charset) === $arg || + strncmp($selector, '=', 1) === 0 && (int) mb_substr($selector, 1, mb_strlen($selector, $charset), $charset) === $arg || $selector === 'one' && $arg - $offset == 1 ) { $message = implode(',', str_replace('#', $arg - $offset, $plural[$i])); diff --git a/framework/i18n/MessageSource.php b/framework/i18n/MessageSource.php index 24a4a74cd9d..6f33bed06bb 100644 --- a/framework/i18n/MessageSource.php +++ b/framework/i18n/MessageSource.php @@ -33,7 +33,7 @@ class MessageSource extends Component */ public $forceTranslation = false; /** - * @var string the language that the original messages are in. If not set, it will use the value of + * @var string|null the language that the original messages are in. If not set, it will use the value of * [[\yii\base\Application::sourceLanguage]]. */ public $sourceLanguage; diff --git a/framework/i18n/MissingTranslationEvent.php b/framework/i18n/MissingTranslationEvent.php index cfed6093415..7f31f4f61f7 100644 --- a/framework/i18n/MissingTranslationEvent.php +++ b/framework/i18n/MissingTranslationEvent.php @@ -23,7 +23,7 @@ class MissingTranslationEvent extends Event */ public $message; /** - * @var string the translated message. An event handler may overwrite this property + * @var string|null the translated message. An event handler may overwrite this property * with a translated version of [[message]] if possible. If not set (null), it means the message is not translated. */ public $translatedMessage; diff --git a/framework/i18n/PhpMessageSource.php b/framework/i18n/PhpMessageSource.php index ec4dcd1ef83..92dfa1bf55f 100644 --- a/framework/i18n/PhpMessageSource.php +++ b/framework/i18n/PhpMessageSource.php @@ -8,6 +8,7 @@ namespace yii\i18n; use Yii; +use yii\base\InvalidArgumentException; /** * PhpMessageSource represents a message source that stores translated messages in PHP scripts. @@ -71,17 +72,15 @@ protected function loadMessages($category, $language) $messageFile = $this->getMessageFilePath($category, $language); $messages = $this->loadMessagesFromFile($messageFile); - $fallbackLanguage = substr($language, 0, 2); + $fallbackLanguage = substr((string)$language, 0, 2); $fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2); - if ($language !== $fallbackLanguage) { + if ($fallbackLanguage !== '' && $language !== $fallbackLanguage) { $messages = $this->loadFallbackMessages($category, $fallbackLanguage, $messages, $messageFile); - } elseif ($language === $fallbackSourceLanguage) { + } elseif ($fallbackSourceLanguage !== '' && $language === $fallbackSourceLanguage) { $messages = $this->loadFallbackMessages($category, $this->sourceLanguage, $messages, $messageFile); - } else { - if ($messages === null) { - Yii::warning("The message file for category '$category' does not exist: $messageFile", __METHOD__); - } + } elseif ($messages === null) { + Yii::warning("The message file for category '$category' does not exist: $messageFile", __METHOD__); } return (array) $messages; @@ -108,7 +107,7 @@ protected function loadFallbackMessages($category, $fallbackLanguage, $messages, if ( $messages === null && $fallbackMessages === null && $fallbackLanguage !== $this->sourceLanguage - && $fallbackLanguage !== substr($this->sourceLanguage, 0, 2) + && strpos($this->sourceLanguage, $fallbackLanguage) !== 0 ) { Yii::error("The message file for category '$category' does not exist: $originalMessageFile " . "Fallback file does not exist as well: $fallbackMessageFile", __METHOD__); @@ -117,7 +116,7 @@ protected function loadFallbackMessages($category, $fallbackLanguage, $messages, } elseif (!empty($fallbackMessages)) { foreach ($fallbackMessages as $key => $value) { if (!empty($value) && empty($messages[$key])) { - $messages[$key] = $fallbackMessages[$key]; + $messages[$key] = $value; } } } @@ -134,6 +133,10 @@ protected function loadFallbackMessages($category, $fallbackLanguage, $messages, */ protected function getMessageFilePath($category, $language) { + $language = (string) $language; + if ($language !== '' && !preg_match('/^[a-z0-9_-]+$/i', $language)) { + throw new InvalidArgumentException(sprintf('Invalid language code: "%s".', $language)); + } $messageFile = Yii::getAlias($this->basePath) . "/$language/"; if (isset($this->fileMap[$category])) { $messageFile .= $this->fileMap[$category]; diff --git a/framework/log/DbTarget.php b/framework/log/DbTarget.php index 343ade6bb7f..bef9c50c771 100644 --- a/framework/log/DbTarget.php +++ b/framework/log/DbTarget.php @@ -78,7 +78,7 @@ public function export() list($text, $level, $category, $timestamp) = $message; if (!is_string($text)) { // exceptions may not be serializable if in the call stack somewhere is a Closure - if ($text instanceof \Throwable || $text instanceof \Exception) { + if ($text instanceof \Exception || $text instanceof \Throwable) { $text = (string) $text; } else { $text = VarDumper::export($text); diff --git a/framework/log/Dispatcher.php b/framework/log/Dispatcher.php index d888d89a8d1..26b0281a79a 100644 --- a/framework/log/Dispatcher.php +++ b/framework/log/Dispatcher.php @@ -52,8 +52,8 @@ * * @property int $flushInterval How many messages should be logged before they are sent to targets. This * method returns the value of [[Logger::flushInterval]]. - * @property Logger $logger The logger. If not set, [[\Yii::getLogger()]] will be used. Note that the type of - * this property differs in getter and setter. See [[getLogger()]] and [[setLogger()]] for details. + * @property Logger $logger The logger. If not set, [[Yii::getLogger()]] will be used. Note that the type of + * this property differs in getter and setter. See [[getLogger()]] and [[setLogger()]] for details. * @property int $traceLevel How many application call stacks should be logged together with each message. * This method returns the value of [[Logger::traceLevel]]. Defaults to 0. * @@ -69,7 +69,7 @@ class Dispatcher extends Component public $targets = []; /** - * @var Logger the logger. + * @var Logger|null the logger. */ private $_logger; @@ -106,8 +106,8 @@ public function init() /** * Gets the connected logger. - * If not set, [[\Yii::getLogger()]] will be used. - * @property Logger the logger. If not set, [[\Yii::getLogger()]] will be used. + * If not set, [[Yii::getLogger()]] will be used. + * @property Logger the logger. If not set, [[Yii::getLogger()]] will be used. * @return Logger the logger. */ public function getLogger() @@ -123,12 +123,15 @@ public function getLogger() * Sets the connected logger. * @param Logger|string|array $value the logger to be used. This can either be a logger instance * or a configuration that will be used to create one using [[Yii::createObject()]]. + * If you are providing custom logger configuration and would like it to be used for the whole application + * and not just for the dispatcher you should use [[Yii::setLogger()]] instead. */ public function setLogger($value) { if (is_string($value) || is_array($value)) { $value = Yii::createObject($value); } + $this->_logger = $value; $this->_logger->dispatcher = $this; } @@ -207,7 +210,7 @@ public function dispatch($messages, $final) * Generate target error message * * @param Target $target log target object - * @param \Throwable|\Exception $throwable catched exception + * @param \Throwable $throwable catched exception * @param string $method full method path * @return array generated error message data * @since 2.0.32 diff --git a/framework/log/FileTarget.php b/framework/log/FileTarget.php index a29c67367af..3fa91c2371a 100644 --- a/framework/log/FileTarget.php +++ b/framework/log/FileTarget.php @@ -26,7 +26,7 @@ class FileTarget extends Target { /** - * @var string log file path or [path alias](guide:concept-aliases). If not set, it will use the "@runtime/logs/app.log" file. + * @var string|null log file path or [path alias](guide:concept-aliases). If not set, it will use the "@runtime/logs/app.log" file. * The directory containing the log files will be automatically created if not existing. */ public $logFile; @@ -46,7 +46,7 @@ class FileTarget extends Target */ public $maxLogFiles = 5; /** - * @var int the permission to be set for newly created log files. + * @var int|null the permission to be set for newly created log files. * This value will be used by PHP chmod() function. No umask will be applied. * If not set, the permission will be determined by the current environment. */ @@ -64,9 +64,9 @@ class FileTarget extends Target * systems which do not play well with rename on open files. Rotation by renaming however is * a bit faster. * - * The problem with windows systems where the [rename()](https://secure.php.net/manual/en/function.rename.php) + * The problem with windows systems where the [rename()](https://www.php.net/manual/en/function.rename.php) * function does not work with files that are opened by some process is described in a - * [comment by Martin Pelletier](https://secure.php.net/manual/en/function.rename.php#102274) in + * [comment by Martin Pelletier](https://www.php.net/manual/en/function.rename.php#102274) in * the PHP documentation. By setting rotateByCopy to `true` you can work * around this problem. */ diff --git a/framework/log/Logger.php b/framework/log/Logger.php index 6a6f3b9a85e..a81f271abc4 100644 --- a/framework/log/Logger.php +++ b/framework/log/Logger.php @@ -31,12 +31,11 @@ * or [[DbTarget|database]], with the help of the [[dispatcher]]. * * @property-read array $dbProfiling The first element indicates the number of SQL statements executed, and - * the second element the total time spent in SQL execution. This property is read-only. - * @property-read float $elapsedTime The total elapsed time in seconds for current request. This property is - * read-only. + * the second element the total time spent in SQL execution. + * @property-read float $elapsedTime The total elapsed time in seconds for current request. * @property-read array $profiling The profiling results. Each element is an array consisting of these * elements: `info`, `category`, `timestamp`, `trace`, `level`, `duration`, `memory`, `memoryDiff`. The `memory` - * and `memoryDiff` values are available since version 2.0.11. This property is read-only. + * and `memoryDiff` values are available since version 2.0.11. * * @author Qiang Xue * @since 2.0 @@ -59,7 +58,7 @@ class Logger extends Component */ const LEVEL_INFO = 0x04; /** - * Tracing message level. An tracing message is one that reveals the code execution flow. + * Tracing message level. A tracing message is one that reveals the code execution flow. */ const LEVEL_TRACE = 0x08; /** @@ -67,13 +66,13 @@ class Logger extends Component */ const LEVEL_PROFILE = 0x40; /** - * Profiling message level. This indicates the message is for profiling purpose. It marks the - * beginning of a profiling block. + * Profiling message level. This indicates the message is for profiling purpose. It marks the beginning + * of a profiling block. */ const LEVEL_PROFILE_BEGIN = 0x50; /** - * Profiling message level. This indicates the message is for profiling purpose. It marks the - * end of a profiling block. + * Profiling message level. This indicates the message is for profiling purpose. It marks the end + * of a profiling block. */ const LEVEL_PROFILE_END = 0x60; @@ -95,7 +94,7 @@ class Logger extends Component public $messages = []; /** * @var int how many messages should be logged before they are flushed from memory and sent to targets. - * Defaults to 1000, meaning the [[flush]] method will be invoked once every 1000 messages logged. + * Defaults to 1000, meaning the [[flush()]] method will be invoked once every 1000 messages logged. * Set this property to be 0 if you don't want to flush messages until the application terminates. * This property mainly affects how much memory will be taken by the logged messages. * A smaller value means less memory, but will increase the execution time due to the overhead of [[flush()]]. @@ -108,9 +107,23 @@ class Logger extends Component */ public $traceLevel = 0; /** - * @var Dispatcher the message dispatcher + * @var Dispatcher the message dispatcher. */ public $dispatcher; + /** + * @var array of event names used to get statistical results of DB queries. + * @since 2.0.41 + */ + public $dbEventNames = ['yii\db\Command::query', 'yii\db\Command::execute']; + /** + * @var bool whether the profiling-aware mode should be switched on. + * If on, [[flush()]] makes sure that profiling blocks are flushed in pairs. In case that any dangling messages are + * detected these are kept for the next flush interval to find their pair. To prevent memory leaks, when number of + * dangling messages reaches flushInterval value, logger flushes them immediately and triggers a warning. + * Keep in mind that profiling-aware mode is more time and memory consuming. + * @since 2.0.43 + */ + public $profilingAware = false; /** @@ -135,7 +148,7 @@ public function init() * @param string|array $message the message to be logged. This can be a simple string or a more * complex data structure that will be handled by a [[Target|log target]]. * @param int $level the level of the message. This must be one of the following: - * `Logger::LEVEL_ERROR`, `Logger::LEVEL_WARNING`, `Logger::LEVEL_INFO`, `Logger::LEVEL_TRACE`, + * `Logger::LEVEL_ERROR`, `Logger::LEVEL_WARNING`, `Logger::LEVEL_INFO`, `Logger::LEVEL_TRACE`, `Logger::LEVEL_PROFILE`, * `Logger::LEVEL_PROFILE_BEGIN`, `Logger::LEVEL_PROFILE_END`. * @param string $category the category of the message. */ @@ -157,7 +170,13 @@ public function log($message, $level, $category = 'application') } } } - $this->messages[] = [$message, $level, $category, $time, $traces, memory_get_usage()]; + $data = [$message, $level, $category, $time, $traces, memory_get_usage()]; + if ($this->profilingAware && in_array($level, [self::LEVEL_PROFILE_BEGIN, self::LEVEL_PROFILE_END])) { + $this->messages[($level == self::LEVEL_PROFILE_BEGIN ? 'begin-' : 'end-') . md5(json_encode($message))] = $data; + } else { + $this->messages[] = $data; + } + if ($this->flushInterval > 0 && count($this->messages) >= $this->flushInterval) { $this->flush(); } @@ -169,10 +188,40 @@ public function log($message, $level, $category = 'application') */ public function flush($final = false) { - $messages = $this->messages; - // https://github.com/yiisoft/yii2/issues/5619 - // new messages could be logged while the existing ones are being handled by targets - $this->messages = []; + if ($this->profilingAware) { + $keep = []; + $messages = []; + foreach ($this->messages as $index => $message) { + if (is_int($index)) { + $messages[] = $message; + } else { + if (strncmp($index, 'begin-', 6) === 0) { + $oppositeProfile = 'end-' . substr($index, 6); + } else { + $oppositeProfile = 'begin-' . substr($index, 4); + } + if (array_key_exists($oppositeProfile, $this->messages)) { + $messages[] = $message; + } else { + $keep[$index] = $message; + } + } + } + if ($this->flushInterval > 0 && count($keep) >= $this->flushInterval) { + $this->messages = []; + $this->log( + 'Number of dangling profiling block messages reached flushInterval value and therefore these were flushed. Please consider setting higher flushInterval value or making profiling blocks shorter.', + self::LEVEL_WARNING + ); + $messages = array_merge($messages, array_values($keep)); + } else { + $this->messages = $keep; + } + } else { + $messages = $this->messages; + $this->messages = []; + } + if ($this->dispatcher instanceof Dispatcher) { $this->dispatcher->dispatch($messages, $final); } @@ -213,11 +262,15 @@ public function getProfiling($categories = [], $excludeCategories = []) return $timings; } - foreach ($timings as $i => $timing) { + foreach ($timings as $outerIndex => $outerTimingItem) { + $currentIndex = $outerIndex; $matched = empty($categories); foreach ($categories as $category) { $prefix = rtrim($category, '*'); - if (($timing['category'] === $category || $prefix !== $category) && strpos($timing['category'], $prefix) === 0) { + if ( + ($outerTimingItem['category'] === $category || $prefix !== $category) + && strpos($outerTimingItem['category'], $prefix) === 0 + ) { $matched = true; break; } @@ -226,8 +279,12 @@ public function getProfiling($categories = [], $excludeCategories = []) if ($matched) { foreach ($excludeCategories as $category) { $prefix = rtrim($category, '*'); - foreach ($timings as $i => $timing) { - if (($timing['category'] === $category || $prefix !== $category) && strpos($timing['category'], $prefix) === 0) { + foreach ($timings as $innerIndex => $innerTimingItem) { + $currentIndex = $innerIndex; + if ( + ($innerTimingItem['category'] === $category || $prefix !== $category) + && strpos($innerTimingItem['category'], $prefix) === 0 + ) { $matched = false; break; } @@ -236,7 +293,7 @@ public function getProfiling($categories = [], $excludeCategories = []) } if (!$matched) { - unset($timings[$i]); + unset($timings[$currentIndex]); } } @@ -252,7 +309,7 @@ public function getProfiling($categories = [], $excludeCategories = []) */ public function getDbProfiling() { - $timings = $this->getProfiling(['yii\db\Command::query', 'yii\db\Command::execute']); + $timings = $this->getProfiling($this->dbEventNames); $count = count($timings); $time = 0; foreach ($timings as $timing) { diff --git a/framework/log/SyslogTarget.php b/framework/log/SyslogTarget.php index 4d766fa4155..034f53a6787 100644 --- a/framework/log/SyslogTarget.php +++ b/framework/log/SyslogTarget.php @@ -27,9 +27,9 @@ class SyslogTarget extends Target */ public $facility = LOG_USER; /** - * @var int openlog options. This is a bitfield passed as the `$option` parameter to [openlog()](https://secure.php.net/openlog). + * @var int|null openlog options. This is a bitfield passed as the `$option` parameter to [openlog()](https://www.php.net/openlog). * Defaults to `null` which means to use the default options `LOG_ODELAY | LOG_PID`. - * @see https://secure.php.net/openlog for available options. + * @see https://www.php.net/openlog for available options. * @since 2.0.11 */ public $options; @@ -84,7 +84,7 @@ public function formatMessage($message) $level = Logger::getLevelName($level); if (!is_string($text)) { // exceptions may not be serializable if in the call stack somewhere is a Closure - if ($text instanceof \Throwable || $text instanceof \Exception) { + if ($text instanceof \Exception || $text instanceof \Throwable) { $text = (string) $text; } else { $text = VarDumper::export($text); diff --git a/framework/log/Target.php b/framework/log/Target.php index 846bc919a9f..fa05f1751ea 100644 --- a/framework/log/Target.php +++ b/framework/log/Target.php @@ -11,7 +11,6 @@ use yii\base\Component; use yii\base\InvalidConfigException; use yii\helpers\ArrayHelper; -use yii\helpers\StringHelper; use yii\helpers\VarDumper; use yii\web\Request; @@ -27,10 +26,10 @@ * may specify [[except]] to exclude messages of certain categories. * * @property bool $enabled Indicates whether this log target is enabled. Defaults to true. Note that the type - * of this property differs in getter and setter. See [[getEnabled()]] and [[setEnabled()]] for details. + * of this property differs in getter and setter. See [[getEnabled()]] and [[setEnabled()]] for details. * @property int $levels The message levels that this target is interested in. This is a bitmap of level * values. Defaults to 0, meaning all available levels. Note that the type of this property differs in getter and - * setter. See [[getLevels()]] and [[setLevels()]] for details. + * setter. See [[getLevels()]] and [[setLevels()]] for details. * * For more details and usage information on Target, see the [guide article on logging & targets](guide:runtime-logging). * @@ -100,7 +99,7 @@ abstract class Target extends Component '_SERVER.PHP_AUTH_PW', ]; /** - * @var callable a PHP callable that returns a string to be prefixed to every exported message. + * @var callable|null a PHP callable that returns a string to be prefixed to every exported message. * * If not set, [[getMessagePrefix()]] will be used, which prefixes the message with context information * such as user IP, user ID and session ID. @@ -297,7 +296,7 @@ public function formatMessage($message) $level = Logger::getLevelName($level); if (!is_string($text)) { // exceptions may not be serializable if in the call stack somewhere is a Closure - if ($text instanceof \Throwable || $text instanceof \Exception) { + if ($text instanceof \Exception || $text instanceof \Throwable) { $text = (string) $text; } else { $text = VarDumper::export($text); diff --git a/framework/mail/BaseMailer.php b/framework/mail/BaseMailer.php index 633974daa2f..d564ae8708e 100644 --- a/framework/mail/BaseMailer.php +++ b/framework/mail/BaseMailer.php @@ -23,7 +23,7 @@ * For more details and usage information on BaseMailer, see the [guide article on mailing](guide:tutorial-mailing). * * @property View $view View instance. Note that the type of this property differs in getter and setter. See - * [[getView()]] and [[setView()]] for details. + * [[getView()]] and [[setView()]] for details. * @property string $viewPath The directory that contains the view files for composing mail messages Defaults * to '@app/mail'. * @@ -87,7 +87,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont */ public $fileTransportPath = '@runtime/mail'; /** - * @var callable a PHP callback that will be called by [[send()]] when [[useFileTransport]] is true. + * @var callable|null a PHP callback that will be called by [[send()]] when [[useFileTransport]] is true. * The callback should return a file name which will be used to save the email message. * If not set, the file name will be generated based on the current timestamp. * @@ -342,8 +342,9 @@ protected function saveMessage($message) public function generateMessageFileName() { $time = microtime(true); + $timeInt = (int) $time; - return date('Ymd-His-', $time) . sprintf('%04d', (int) (($time - (int) $time) * 10000)) . '-' . sprintf('%04d', mt_rand(0, 10000)) . '.eml'; + return date('Ymd-His-', $timeInt) . sprintf('%04d', (int) (($time - $timeInt) * 10000)) . '-' . sprintf('%04d', random_int(0, 10000)) . '.eml'; } /** diff --git a/framework/mail/BaseMessage.php b/framework/mail/BaseMessage.php index ec04d82f756..a223ce41088 100644 --- a/framework/mail/BaseMessage.php +++ b/framework/mail/BaseMessage.php @@ -25,7 +25,7 @@ abstract class BaseMessage extends BaseObject implements MessageInterface { /** - * @var MailerInterface the mailer instance that created this message. + * @var MailerInterface|null the mailer instance that created this message. * For independently created messages this is `null`. */ public $mailer; @@ -33,7 +33,7 @@ abstract class BaseMessage extends BaseObject implements MessageInterface /** * Sends this email message. - * @param MailerInterface $mailer the mailer that should be used to send this message. + * @param MailerInterface|null $mailer the mailer that should be used to send this message. * If no mailer is given it will first check if [[mailer]] is set and if not, * the "mailer" application component will be used instead. * @return bool whether this message is sent successfully. diff --git a/framework/mail/MessageInterface.php b/framework/mail/MessageInterface.php index 414d3b778b3..aeb1d2d6867 100644 --- a/framework/mail/MessageInterface.php +++ b/framework/mail/MessageInterface.php @@ -204,7 +204,7 @@ public function embedContent($content, array $options = []); /** * Sends this email message. - * @param MailerInterface $mailer the mailer that should be used to send this message. + * @param MailerInterface|null $mailer the mailer that should be used to send this message. * If null, the "mailer" application component will be used instead. * @return bool whether this message is sent successfully. */ diff --git a/framework/messages/config.php b/framework/messages/config.php index 7f8db2d41c1..98e8fe257d8 100644 --- a/framework/messages/config.php +++ b/framework/messages/config.php @@ -12,12 +12,17 @@ 'messagePath' => __DIR__, // array, required, list of language codes that the extracted messages // should be translated to. For example, ['zh-CN', 'de']. - 'languages' => ['af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'he', 'hi', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'nb-NO', 'nl', 'pl', 'pt', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'vi', 'zh-CN', 'zh-TW'], + 'languages' => [ + 'af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'he', 'hi', + 'pt-BR', 'ro', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'nb-NO', 'nl', + 'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh-CN', + 'zh-TW' + ], // string, the name of the function for translating messages. // Defaults to 'Yii::t'. This is used as a mark to find the messages to be // translated. You may use a string for single function name or an array for // multiple function names. - 'translator' => 'Yii::t', + 'translator' => ['\Yii::t', 'Yii::t'], // boolean, whether to sort messages by keys when merging new messages // with the existing ones. Defaults to false, which means the new (untranslated) // messages will be separated from the old (translated) ones. @@ -39,13 +44,13 @@ // Note, the '/' characters in a pattern matches both '/' and '\'. // See helpers/FileHelper::findFiles() description for more details on pattern matching rules. 'except' => [ - '.svn', - '.git', - '.gitignore', - '.gitkeep', - '.hgignore', - '.hgkeep', + '.*', + '/.*', '/messages', + '/tests', + '/runtime', + '/vendor', + '/BaseYii.php', ], // array, list of patterns that specify which files (not directories) should be processed. // If empty or not set, all files will be processed. @@ -53,9 +58,9 @@ // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. 'only' => ['*.php'], 'phpFileHeader' => '/** - * @link http://www.yiiframework.com/ + * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC - * @license http://www.yiiframework.com/license/ + * @license https://www.yiiframework.com/license/ */ ', diff --git a/framework/messages/hr/yii.php b/framework/messages/hr/yii.php index cbe8ba4f49b..772ef9493e4 100644 --- a/framework/messages/hr/yii.php +++ b/framework/messages/hr/yii.php @@ -28,7 +28,7 @@ 'Are you sure you want to delete this item' => 'Želiš li to obrisati?', 'Delete' => 'Obrisati', 'Error' => 'Pogreška', - 'File upload failed.' => 'Upload podatka nije uspio.', + 'File upload failed.' => 'Upload datoteke nije uspio.', 'Home' => 'Home', 'Invalid data received for parameter "{param}".' => 'Nevažeći podaci primljeni za parametar "{param}"', 'Login Required' => 'Prijava potrebna', @@ -39,14 +39,14 @@ 'No help for unknown sub-command "{command}".' => 'Nema pomoći za nepoznatu pod-naredbu "{command}"', 'No results found.' => 'Nema rezultata.', 'Only files with these MIME types are allowed: {mimeTypes}.' => 'Samo datoteke s ovim MIME vrstama su dopuštene: {mimeTypes}.', - 'Only files with these extensions are allowed: {extensions}.' => 'Samo datoteke s ovim eksentinzijama su dopuštene:: {extensions}', + 'Only files with these extensions are allowed: {extensions}.' => 'Samo datoteke s ovim ekstenzijama su dopuštene: {extensions}', 'Page not found.' => 'Stranica nije pronađena.', 'Please fix the following errors:' => 'Molimo vas ispravite pogreške:', 'Please upload a file.' => 'Molimo vas da uploadate datoteku.', 'Showing {begin, number}-{end, number} of {totalCount, number} {totalCount, plural, one{item} other{items}}.' => 'Prikazuj {begin, number}-{end, number} od {totalCount, number} {totalCount, plural, one{stavka} few{stavke} many{stavki} other{stavki}}.', - 'The file "{file}" is not an image.' => 'Podatak "{file}" nije slika.', - 'The file "{file}" is too big. Its size cannot exceed {formattedLimit}.' => 'Podatak "{file}" je prevelik. Ne smije biti veći od {formattedLimit}.', - 'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => 'Podatak "{file}" je premalen. Ne smije biti manji od {formattedLimit}.', + 'The file "{file}" is not an image.' => 'Datoteka "{file}" nije slika.', + 'The file "{file}" is too big. Its size cannot exceed {formattedLimit}.' => 'Datoteka "{file}" je prevelika. Ne smije biti veća od {formattedLimit}.', + 'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => 'Datoteka "{file}" je premalena. Ne smije biti manja od {formattedLimit}.', 'The format of {attribute} is invalid.' => 'Format od {attribute} je nevažeći.', 'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Slika "{file}" je prevelika. Visina slike ne smije biti veća od {limit, number} {limit, plural, one{piksel} other{piksela}}.', 'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Slika "{file}" je prevelika. Širina slike ne smije biti veća od {limit, number} {limit, plural, one{piksel} other{piksela}}.', @@ -54,14 +54,14 @@ 'The image "{file}" is too small. The width cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'Slika "{file}" je premalena. Širina slike ne smije biti manja od {limit, number} {limit, plural, one{piksel} other{piksela}}.', 'The verification code is incorrect.' => 'Kod za provjeru nije točan.', 'Total {count, number} {count, plural, one{item} other{items}}.' => 'Ukupno {count, number} {count, plural, =1{stavka} one{# stavka} few{# stavke} many{# stavki} other{# stavki}}.', - 'Unable to verify your data submission.' => 'Nije moguće provjeriti podnesene podatke.', + 'Unable to verify your data submission.' => 'Nije moguće provjeriti poslane podatke.', 'Unknown command "{command}".' => 'Nepoznata naredba "{command}".', 'Unknown option: --{name}' => 'Nepoznata opcija: --{name}', 'Update' => 'Uredi', 'View' => 'Pregled', 'Yes' => 'Da', 'You are not allowed to perform this action.' => 'Nije vam dopušteno obavljati tu radnju.', - 'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Najviše možete uploadat {limit, number} {limit, plural, one{fajl} other{fajlova}}.', + 'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Najviše možete uploadat {limit, number} {limit, plural, one{datoteku} few{datoteke} other{datoteka}}.', 'in {delta, plural, =1{a day} other{# days}}' => 'u {delta, plural, =1{dan} one{# dan} few{# dana} many{# dana} other{# dana}}', 'in {delta, plural, =1{a minute} other{# minutes}}' => 'u {delta, plural, =1{minuta} one{# minuta} few{# minute} many{# minuta} other{# minuta}}', 'in {delta, plural, =1{a month} other{# months}}' => 'u {delta, plural, =1{mjesec} one{# mjesec} few{# mjeseca} many{# mjeseci} other{# mjeseci}}', @@ -87,9 +87,9 @@ '{attribute} must be no less than {min}.' => '{attribute} ne smije biti manji od {min}.', '{attribute} must be repeated exactly.' => '{attribute} mora biti točno ponovljeno.', '{attribute} must not be equal to "{compareValue}".' => '{attribute} ne smije biti jednak "{compareValue}".', - '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '{attribute} mora najmanje sadržavati {min, number} {min, plural, =1{znak} one{# znak} few{# znaka} many{# znakova} other{# znakova}}.', - '{attribute} should contain at most {max, number} {max, plural, one{character} other{characters}}.' => '{attribute} moze sadržavati najviše do {max, number} {max, plural, =1{znak} one{# znak} few{# znaka} many{# znakova} other{# znakova}}.', - '{attribute} should contain {length, number} {length, plural, one{character} other{characters}}.' => '{attribute} mora sadržavati {length, number} {length, plural, =1{znak} one{# znak} few{# znaka} many{# znakova} other{# znakova}}.', + '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '{attribute} mora najmanje sadržavati {min, number} {min, plural, =1{znak} one{znak} few{znaka} many{znakova} other{znakova}}.', + '{attribute} should contain at most {max, number} {max, plural, one{character} other{characters}}.' => '{attribute} moze sadržavati najviše do {max, number} {max, plural, =1{znak} one{znak} few{znaka} many{znakova} other{znakova}}.', + '{attribute} should contain {length, number} {length, plural, one{character} other{characters}}.' => '{attribute} mora sadržavati {length, number} {length, plural, =1{znak} one{znak} few{znaka} many{znakova} other{znakova}}.', '{delta, plural, =1{a day} other{# days}} ago' => '{delta, plural, =1{dan} one{# dan} few{# dana} many{# dana} other{# dana}}', '{delta, plural, =1{a minute} other{# minutes}} ago' => '{delta, plural, =1{minuta} one{# minuta} few{# minute} many{# minuta} other{# minuta}}', '{delta, plural, =1{a month} other{# months}} ago' => '{delta, plural, =1{mjesec} one{# mjesec} few{# mjeseca} many{# mjeseci} other{# mjeseci}}', diff --git a/framework/messages/uz-Cy/yii.php b/framework/messages/uz-Cy/yii.php new file mode 100644 index 00000000000..cc6321e4ede --- /dev/null +++ b/framework/messages/uz-Cy/yii.php @@ -0,0 +1,125 @@ + '{nFormatted} Б', + '{nFormatted} GB' => '{nFormatted} ГБ', + '{nFormatted} GiB' => '{nFormatted} ГиБ', + '{nFormatted} KB' => '{nFormatted} КБ', + '{nFormatted} KiB' => '{nFormatted} КиБ', + '{nFormatted} MB' => '{nFormatted} МБ', + '{nFormatted} MiB' => '{nFormatted} МиБ', + '{nFormatted} PB' => '{nFormatted} ПБ', + '{nFormatted} PiB' => '{nFormatted} ПиБ', + '{nFormatted} TB' => '{nFormatted} ТБ', + '{nFormatted} TiB' => '{nFormatted} ТиБ', + '{nFormatted} {n, plural, =1{byte} other{bytes}}' => '{nFormatted} {n, plural, one{байт} few{байт} many{байтлар} other{байт}}', + '{nFormatted} {n, plural, =1{gibibyte} other{gibibytes}}' => '{nFormatted} {n, plural, one{гибибайт} few{гибибайт} many{гибибайт} other{гибибайт}}', + '{nFormatted} {n, plural, =1{gigabyte} other{gigabytes}}' => '{nFormatted} {n, plural, one{гигабайт} few{гигабайт} many{гигабайт} other{гигабайт}}', + '{nFormatted} {n, plural, =1{kibibyte} other{kibibytes}}' => '{nFormatted} {n, plural, one{кибибайт} few{кибибайт} many{кибибайт} other{кибибайт}}', + '{nFormatted} {n, plural, =1{kilobyte} other{kilobytes}}' => '{nFormatted} {n, plural, one{килобайт} few{килобайт} many{килобайт} other{килобайт}}', + '{nFormatted} {n, plural, =1{mebibyte} other{mebibytes}}' => '{nFormatted} {n, plural, one{мебибайт} few{мебибайт} many{мебибайт} other{мебибайт}}', + '{nFormatted} {n, plural, =1{megabyte} other{megabytes}}' => '{nFormatted} {n, plural, one{мегабайт} few{мегабайт} many{мегабайт} other{мегабайт}}', + '{nFormatted} {n, plural, =1{pebibyte} other{pebibytes}}' => '{nFormatted} {n, plural, one{пебибайт} few{пебибайт} many{пебибайт} other{пебибайт}}', + '{nFormatted} {n, plural, =1{petabyte} other{petabytes}}' => '{nFormatted} {n, plural, one{петабайт} few{петабайт} many{петабайт} other{петабайт}}', + '{nFormatted} {n, plural, =1{tebibyte} other{tebibytes}}' => '{nFormatted} {n, plural, one{тебибайт} few{тебибайт} many{тебибайт} other{тебибайт}}', + '{nFormatted} {n, plural, =1{terabyte} other{terabytes}}' => '{nFormatted} {n, plural, one{терабайт} few{терабайт} many{терабайт} other{терабайт}}', + '(not set)' => '(қийматланмаган)', + 'An internal server error occurred.' => 'Сервернинг ички хатолиги юз берди.', + 'Are you sure you want to delete this item?' => 'Сиз ростдан ҳам ушбу элементни ўчирмоқчимисиз?', + 'Delete' => 'Ўчириш', + 'Error' => 'Хато', + 'File upload failed.' => 'Файлни юклаб бўлмади.', + 'Home' => 'Асосий', + 'Invalid data received for parameter "{param}".' => '"{param}" параметр қиймати нотўғри.', + 'Login Required' => 'Кириш талаб қилинади.', + 'Missing required arguments: {params}' => 'Қуйидаги зарур аргументлар мавжуд эмас: {params}', + 'Missing required parameters: {params}' => 'Қуйидаги зарур параметрлар мавжуд эмас: {params}', + 'No' => 'Йўқ', + 'No help for unknown command "{command}".' => '"{command}" ноаниқ команда учун маълумотнома мавжуд эмас.', + 'No help for unknown sub-command "{command}".' => '"{command}" ноаниқ қисм команда учун маълумотнома мавжуд эмас.', + 'No results found.' => 'Хеч нима топилмади.', + 'Only files with these MIME types are allowed: {mimeTypes}.' => 'Фақат MIME-туридаги файлларни юклашга рухсат берилган: {mimeTypes}.', + 'Only files with these extensions are allowed: {extensions}.' => 'Фақат қуйидаги кенгайтмали файлларни юклашга рухсат берилган: {extensions}.', + 'Page not found.' => 'Саҳифа топилмади.', + 'Please fix the following errors:' => 'Қуйидаги хатоликларни тўғриланг:', + 'Please upload a file.' => 'Файлни юкланг.', + 'Showing {begin, number}-{end, number} of {totalCount, number} {totalCount, plural, one{item} other{items}}.' => 'Намойиш этиляпти {begin, number}-{end, number} маълумот, жами: {totalCount, number} та', + 'The file "{file}" is not an image.' => '«{file}» расм файл эмас.', + 'The file "{file}" is too big. Its size cannot exceed {formattedLimit}.' => '«{file}» файл жуда катта. Ўлчам {formattedLimit} ошиши керак эмас.', + 'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => '«{file}» файл жуда кичкина. Ўлчам {formattedLimit} кам бўлмаслиги керак.', + 'The format of {attribute} is invalid.' => '«{attribute}» қийматнинг формати нотўғри.', + 'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => '«{file}» файл жуда катта. Баландлик {limit, number} {limit, plural, one{пикселдан} few{пикселдан} many{пикселдан} other{пикселдан}} ошмаслиги керак.', + 'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => '«{file}» файл жуда катта. Эни {limit, number} {limit, plural, one{пикселдан} few{пикселдан} many{пикселдан} other{пикселдан}} ошмаслиги керак.', + 'The image "{file}" is too small. The height cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => '«{file}» файл жуда кичкина. Баландлик {limit, number} {limit, plural, one{пикселдан} few{пикселдан} many{пикселдан} other{пикселдан}} кам бўлмаслиги керак.', + 'The image "{file}" is too small. The width cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => '«{file}» файл жуда кичкина. Эни {limit, number} {limit, plural, one{пикселдан} few{пикселдан} many{пикселдан} other{пикселдан}} кам бўлмаслиги керак.', + 'The requested view "{name}" was not found.' => 'Сўралаётган "{name}" файли топилмади.', + 'The verification code is incorrect.' => 'Текширув коди нотўғри.', + 'Total {count, number} {count, plural, one{item} other{items}}.' => 'Жами {count, number} {count, plural, one{ёзув} few{ёзув} many{ёзув} other{ёзув}}.', + 'Unable to verify your data submission.' => 'Юборилган маълумотларни текшириб бўлмади.', + 'Unknown command "{command}".' => '"{command}" ноаниқ бўйриқ.', + 'Unknown option: --{name}' => 'Ноаниқ танлов: --{name}', + 'Update' => 'Таҳририлаш', + 'View' => 'Кўриш', + 'Yes' => 'Ҳа', + 'You are not allowed to perform this action.' => 'Сизга ушбу амални бажаришга руҳсат берилмаган.', + 'You can upload at most {limit, number} {limit, plural, one{file} other{files}}.' => 'Сиз {limit, number} {limit, plural, one{файлдан} few{файллардан} many{файллардан} other{файллардан}} кўпини юклаб ололмайсиз.', + 'in {delta, plural, =1{a day} other{# days}}' => '{delta, plural, =1{кундан} one{# кундан} few{# кундан} many{# кунлардан} other{# кундан}} кейин', + 'in {delta, plural, =1{a minute} other{# minutes}}' => '{delta, plural, =1{минутдан} one{# минутдан} few{# минутлардан} many{# минутдан} other{# минутлардан}} кейин', + 'in {delta, plural, =1{a month} other{# months}}' => '{delta, plural, =1{ойдан} one{# ойдан} few{# ойдан} many{# ойлардан} other{# ойлардан}} кейин', + 'in {delta, plural, =1{a second} other{# seconds}}' => '{delta, plural, =1{секунддан} one{# секунддан} few{# секундлардан} many{# секунддан} other{# секундлардан}} кейин', + 'in {delta, plural, =1{a year} other{# years}}' => '{delta, plural, =1{йилдан} one{# йилдан} few{# йиллардан} many{# йиллардан} other{# йиллардан}} кейин', + 'in {delta, plural, =1{an hour} other{# hours}}' => '{delta, plural, =1{соатдан} one{# соатдан} few{# соатлардан} many{# соатлардан} other{# соатлардан}} кейин', + 'just now' => 'ҳозироқ', + 'the input value' => 'киритилган қиймат', + '{attribute} "{value}" has already been taken.' => '{attribute} «{value}» аввалроқ банд қилинган.', + '{attribute} cannot be blank.' => '«{attribute}» тўлдириш шарт.', + '{attribute} is invalid.' => '«{attribute}» қиймати нотўғри', + '{attribute} is not a valid URL.' => '«{attribute}» тўғри URL эмас.', + '{attribute} is not a valid email address.' => '«{attribute}» тўғри электрон манзил эмас.', + '{attribute} must be "{requiredValue}".' => '«{attribute}» қиймати «{requiredValue}» га тенг бўлиши керак.', + '{attribute} must be a number.' => '«{attribute}» қиймати сон бўлиши керак.', + '{attribute} must be a string.' => '«{attribute}» қиймати матн бўлиши керак.', + '{attribute} must be an integer.' => '«{attribute}» қиймати бутун сон бўлиши керак.', + '{attribute} must be either "{true}" or "{false}".' => '«{attribute}» қиймати «{true}» ёки «{false}» бўлиши керак.', + '{attribute} must be greater than "{compareValue}".' => '«{attribute}» қиймати «{compareValue}» дан катта бўлиши керак.', + '{attribute} must be greater than or equal to "{compareValue}".' => '«{attribute}» қиймати «{compareValue}» дан катта ёки тенг бўлиши керак.', + '{attribute} must be less than "{compareValue}".' => '«{attribute}» қиймати «{compareValue}» дан кичкина бўлиши керак.', + '{attribute} must be less than or equal to "{compareValue}".' => '«{attribute}» қиймати «{compareValue}» дан кичик ёки тенг бўлиши керак.', + '{attribute} must be no greater than {max}.' => '«{attribute}» қиймати {max} дан ошмаслиги керак.', + '{attribute} must be no less than {min}.' => '«{attribute}» қиймати {min} дан кичкина бўлиши керак.', + '{attribute} must be repeated exactly.' => '«{attribute}» қиймати бир хил тарзда такрорланиши керак.', + '{attribute} must not be equal to "{compareValue}".' => '«{attribute}» қиймати «{compareValue}» га тенг бўлмаслиги керак.', + '{attribute} must not be equal to "{compareValueOrAttribute}".' => '«{attribute}» қиймати «{compareValueOrAttribute}» қийматига тенг бўлмаслиги лозим.', + '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '«{attribute}» қиймати минимум {min, number} {min, plural, one{белгидан} few{белгидан} many{белгидан} other{белгидан}} ташкил топиши керак.', + '{attribute} should contain at most {max, number} {max, plural, one{character} other{characters}}.' => '«{attribute}» қиймати максимум {max, number} {max, plural, one{белгидан} few{белгидан} many{белгидан} other{белгидан}} ошмаслиги керак.', + '{attribute} should contain {length, number} {length, plural, one{character} other{characters}}.' => '«{attribute}» қиймати {length, number} {length, plural, one{белгидан} few{белгидан} many{белгидан} other{белгидан}} ташкил топиши керак.', + '{delta, plural, =1{a day} other{# days}} ago' => '{delta, plural, =1{кун} one{кун} few{# кун} many{# кун} other{# кун}} аввал', + '{delta, plural, =1{a minute} other{# minutes}} ago' => '{delta, plural, =1{дақиқа} one{# дақиқа} few{# дақиқа} many{# дақиқа} other{# дақиқа}} аввал', + '{delta, plural, =1{a month} other{# months}} ago' => '{delta, plural, =1{ой} one{# ой} few{# ой} many{# ой} other{# ой}} аввал', + '{delta, plural, =1{a second} other{# seconds}} ago' => '{delta, plural, =1{сония} one{# сония} few{# сония} many{# сония} other{# сония}} аввал', + '{delta, plural, =1{a year} other{# years}} ago' => '{delta, plural, =1{йил} one{# йил} few{# йил} many{# йил} other{# йил}} аввал', + '{delta, plural, =1{an hour} other{# hours}} ago' => '{delta, plural, =1{соат} one{# соат} few{# соат} many{# соат} other{# соат}} аввал', + ]; + diff --git a/framework/mutex/FileMutex.php b/framework/mutex/FileMutex.php index 5dc71a088cb..8d0c1385532 100644 --- a/framework/mutex/FileMutex.php +++ b/framework/mutex/FileMutex.php @@ -49,7 +49,7 @@ class FileMutex extends Mutex */ public $mutexPath = '@runtime/mutex'; /** - * @var int the permission to be set for newly created mutex files. + * @var int|null the permission to be set for newly created mutex files. * This value will be used by PHP chmod() function. No umask will be applied. * If not set, the permission will be determined by the current environment. */ @@ -62,7 +62,7 @@ class FileMutex extends Mutex */ public $dirMode = 0775; /** - * @var bool whether file handling should assume a Windows file system. + * @var bool|null whether file handling should assume a Windows file system. * This value will determine how [[releaseLock()]] goes about deleting the lock file. * If not set, it will be determined by checking the DIRECTORY_SEPARATOR constant. * @since 2.0.16 diff --git a/framework/mutex/Mutex.php b/framework/mutex/Mutex.php index cfa683409ab..4df573a9354 100644 --- a/framework/mutex/Mutex.php +++ b/framework/mutex/Mutex.php @@ -98,10 +98,11 @@ public function release($name) } /** - * Checks if a lock is currently acquired + * Checks if a lock is acquired by the current process. + * Note that it returns false if the mutex is acquired in another process. * - * @param string $name of the lock to check - * @return bool Returns true if currently acquired + * @param string $name of the lock to check. + * @return bool Returns true if currently acquired. * @since 2.0.36 */ public function isAcquired($name) diff --git a/framework/mutex/PgsqlMutex.php b/framework/mutex/PgsqlMutex.php index 8c38c75f46f..900ac5ff391 100644 --- a/framework/mutex/PgsqlMutex.php +++ b/framework/mutex/PgsqlMutex.php @@ -7,7 +7,6 @@ namespace yii\mutex; -use yii\base\InvalidArgumentException; use yii\base\InvalidConfigException; /** diff --git a/framework/rbac/BaseManager.php b/framework/rbac/BaseManager.php index c8dda76f930..4e475c8bcbf 100644 --- a/framework/rbac/BaseManager.php +++ b/framework/rbac/BaseManager.php @@ -17,10 +17,9 @@ * * For more details and usage information on DbManager, see the [guide article on security authorization](guide:security-authorization). * - * @property-read Role[] $defaultRoleInstances Default roles. The array is indexed by the role names. This - * property is read-only. + * @property-read Role[] $defaultRoleInstances Default roles. The array is indexed by the role names. * @property string[] $defaultRoles Default roles. Note that the type of this property differs in getter and - * setter. See [[getDefaultRoles()]] and [[setDefaultRoles()]] for details. + * setter. See [[getDefaultRoles()]] and [[setDefaultRoles()]] for details. * * @author Qiang Xue * @since 2.0 @@ -37,7 +36,7 @@ abstract class BaseManager extends Component implements ManagerInterface /** * Returns the named auth item. * @param string $name the auth item name. - * @return Item the auth item corresponding to the specified name. Null is returned if no such item. + * @return Item|null the auth item corresponding to the specified name. Null is returned if no such item. */ abstract protected function getItem($name); diff --git a/framework/rbac/DbManager.php b/framework/rbac/DbManager.php index 9aa29ae9453..4f909e34545 100644 --- a/framework/rbac/DbManager.php +++ b/framework/rbac/DbManager.php @@ -62,7 +62,7 @@ class DbManager extends BaseManager */ public $ruleTable = '{{%auth_rule}}'; /** - * @var CacheInterface|array|string the cache used to improve RBAC performance. This can be one of the following: + * @var CacheInterface|array|string|null the cache used to improve RBAC performance. This can be one of the following: * * - an application component ID (e.g. `cache`) * - a configuration array diff --git a/framework/rbac/ManagerInterface.php b/framework/rbac/ManagerInterface.php index 4d53d30712e..911ccbdc1d3 100644 --- a/framework/rbac/ManagerInterface.php +++ b/framework/rbac/ManagerInterface.php @@ -60,7 +60,7 @@ public function update($name, $object); /** * Returns the named role. * @param string $name the role name. - * @return null|Role the role corresponding to the specified name. Null is returned if no such role. + * @return Role|null the role corresponding to the specified name. Null is returned if no such role. */ public function getRole($name); @@ -91,7 +91,7 @@ public function getChildRoles($roleName); /** * Returns the named permission. * @param string $name the permission name. - * @return null|Permission the permission corresponding to the specified name. Null is returned if no such permission. + * @return Permission|null the permission corresponding to the specified name. Null is returned if no such permission. */ public function getPermission($name); @@ -118,7 +118,7 @@ public function getPermissionsByUser($userId); /** * Returns the rule of the specified name. * @param string $name the rule name - * @return null|Rule the rule object, or null if the specified name does not correspond to a rule. + * @return Rule|null the rule object, or null if the specified name does not correspond to a rule. */ public function getRule($name); @@ -208,7 +208,7 @@ public function revokeAll($userId); * Returns the assignment information regarding a role and a user. * @param string $roleName the role name * @param string|int $userId the user ID (see [[\yii\web\User::id]]) - * @return null|Assignment the assignment information. Null is returned if + * @return Assignment|null the assignment information. Null is returned if * the role is not assigned to the user. */ public function getAssignment($roleName, $userId); diff --git a/framework/rbac/PhpManager.php b/framework/rbac/PhpManager.php index 39fdcf17847..9a15990d3ea 100644 --- a/framework/rbac/PhpManager.php +++ b/framework/rbac/PhpManager.php @@ -796,7 +796,7 @@ protected function loadFromFile($file) */ protected function saveToFile($data, $file) { - file_put_contents($file, "invalidateScriptCache($file); } diff --git a/framework/rbac/migrations/m140506_102106_rbac_init.php b/framework/rbac/migrations/m140506_102106_rbac_init.php index 1429486a3b9..467fa8608f4 100644 --- a/framework/rbac/migrations/m140506_102106_rbac_init.php +++ b/framework/rbac/migrations/m140506_102106_rbac_init.php @@ -40,7 +40,7 @@ protected function isMSSQL() protected function isOracle() { - return $this->db->driverName === 'oci'; + return $this->db->driverName === 'oci' || $this->db->driverName === 'oci8'; } /** diff --git a/framework/requirements/YiiRequirementChecker.php b/framework/requirements/YiiRequirementChecker.php index bc214aa4ec8..612083684a0 100644 --- a/framework/requirements/YiiRequirementChecker.php +++ b/framework/requirements/YiiRequirementChecker.php @@ -295,9 +295,9 @@ function checkUploadMaxFileSize($min = null, $max = null) * This method includes the view file as a PHP script * and captures the display result if required. * @param string $_viewFile_ view file - * @param array $_data_ data to be extracted and made available to the view file + * @param array|null $_data_ data to be extracted and made available to the view file * @param bool $_return_ whether the rendering result should be returned as a string - * @return string the rendering result. Null if the rendering result is not required. + * @return string|null the rendering result. Null if the rendering result is not required. */ function renderViewFile($_viewFile_, $_data_ = null, $_return_ = false) { diff --git a/framework/requirements/requirements.php b/framework/requirements/requirements.php index 29ab338b91b..f1c675bd0fc 100644 --- a/framework/requirements/requirements.php +++ b/framework/requirements/requirements.php @@ -16,52 +16,52 @@ 'name' => 'PHP version', 'mandatory' => true, 'condition' => version_compare(PHP_VERSION, '5.4.0', '>='), - 'by' => 'Yii Framework', + 'by' => 'Yii Framework', 'memo' => 'PHP 5.4.0 or higher is required.', ), array( 'name' => 'Reflection extension', 'mandatory' => true, 'condition' => class_exists('Reflection', false), - 'by' => 'Yii Framework', + 'by' => 'Yii Framework', ), array( 'name' => 'PCRE extension', 'mandatory' => true, 'condition' => extension_loaded('pcre'), - 'by' => 'Yii Framework', + 'by' => 'Yii Framework', ), array( 'name' => 'SPL extension', 'mandatory' => true, 'condition' => extension_loaded('SPL'), - 'by' => 'Yii Framework', + 'by' => 'Yii Framework', ), array( 'name' => 'Ctype extension', 'mandatory' => true, 'condition' => extension_loaded('ctype'), - 'by' => 'Yii Framework' + 'by' => 'Yii Framework' ), array( 'name' => 'MBString extension', 'mandatory' => true, 'condition' => extension_loaded('mbstring'), - 'by' => 'Multibyte string processing', + 'by' => 'Multibyte string processing', 'memo' => 'Required for multibyte encoding string processing.' ), array( 'name' => 'OpenSSL extension', 'mandatory' => false, 'condition' => extension_loaded('openssl'), - 'by' => 'Security Component', + 'by' => 'Security Component', 'memo' => 'Required by encrypt and decrypt methods.' ), array( 'name' => 'Intl extension', 'mandatory' => false, 'condition' => $this->checkPhpExtensionVersion('intl', '1.0.2', '>='), - 'by' => 'Internationalization support', + 'by' => 'Internationalization support', 'memo' => 'PHP Intl extension 1.0.2 or higher is required when you want to use advanced parameters formatting in Yii::t(), non-latin languages with Inflector::slug(), IDN-feature of @@ -71,10 +71,10 @@ 'name' => 'ICU version', 'mandatory' => false, 'condition' => defined('INTL_ICU_VERSION') && version_compare(INTL_ICU_VERSION, '49', '>='), - 'by' => 'Internationalization support', + 'by' => 'Internationalization support', 'memo' => 'ICU 49.0 or higher is required when you want to use # placeholder in plural rules (for example, plural in - + Formatter::asRelativeTime()) in the yii\i18n\Formatter class. Your current ICU version is ' . (defined('INTL_ICU_VERSION') ? INTL_ICU_VERSION : '(ICU is missing)') . '.' ), @@ -82,10 +82,10 @@ 'name' => 'ICU Data version', 'mandatory' => false, 'condition' => defined('INTL_ICU_DATA_VERSION') && version_compare(INTL_ICU_DATA_VERSION, '49.1', '>='), - 'by' => 'Internationalization support', + 'by' => 'Internationalization support', 'memo' => 'ICU Data 49.1 or higher is required when you want to use # placeholder in plural rules (for example, plural in - + Formatter::asRelativeTime()) in the yii\i18n\Formatter class. Your current ICU Data version is ' . (defined('INTL_ICU_DATA_VERSION') ? INTL_ICU_DATA_VERSION : '(ICU Data is missing)') . '.' ), @@ -93,22 +93,22 @@ 'name' => 'Fileinfo extension', 'mandatory' => false, 'condition' => extension_loaded('fileinfo'), - 'by' => 'File Information', + 'by' => 'File Information', 'memo' => 'Required for files upload to detect correct file mime-types.' ), array( 'name' => 'DOM extension', 'mandatory' => false, 'condition' => extension_loaded('dom'), - 'by' => 'Document Object Model', + 'by' => 'Document Object Model', 'memo' => 'Required for REST API to send XML responses via yii\web\XmlResponseFormatter.' ), array( 'name' => 'IPv6 support', 'mandatory' => false, 'condition' => strlen(@inet_pton('2001:db8::1')) === 16, - 'by' => 'IPv6 expansion in IpValidator', - 'memo' => 'When IpValidator::expandIPv6 + 'by' => 'IPv6 expansion in IpValidator', + 'memo' => 'When IpValidator::expandIPv6 property is set to true, PHP must support IPv6 protocol stack. Currently PHP constant AF_INET6 is not defined and IPv6 is probably unsupported.' ) diff --git a/framework/requirements/views/console/index.php b/framework/requirements/views/console/index.php index d1559b68bcf..68c4cb543e1 100644 --- a/framework/requirements/views/console/index.php +++ b/framework/requirements/views/console/index.php @@ -23,7 +23,6 @@ foreach ($requirements as $key => $requirement) { if ($requirement['condition']) { echo $requirement['name'] . ": OK\n"; - echo "\n"; } else { echo $requirement['name'] . ': ' . ($requirement['mandatory'] ? 'FAILED!!!' : 'WARNING!!!') . "\n"; echo 'Required by: ' . strip_tags($requirement['by']) . "\n"; @@ -31,8 +30,8 @@ if (!empty($memo)) { echo 'Memo: ' . strip_tags($requirement['memo']) . "\n"; } - echo "\n"; } + echo "\n"; } $summaryString = 'Errors: ' . $summary['errors'] . ' Warnings: ' . $summary['warnings'] . ' Total checks: ' . $summary['total']; diff --git a/framework/rest/Action.php b/framework/rest/Action.php index 466acfc2f31..6afafca4502 100644 --- a/framework/rest/Action.php +++ b/framework/rest/Action.php @@ -29,7 +29,7 @@ class Action extends \yii\base\Action */ public $modelClass; /** - * @var callable a PHP callable that will be called to return the model corresponding + * @var callable|null a PHP callable that will be called to return the model corresponding * to the specified primary key value. If not set, [[findModel()]] will be used instead. * The signature of the callable should be: * @@ -45,7 +45,7 @@ class Action extends \yii\base\Action */ public $findModel; /** - * @var callable a PHP callable that will be called when running an action to determine + * @var callable|null a PHP callable that will be called when running an action to determine * if the current user has the permission to execute the action. If not set, the access * check will not be performed. The signature of the callable should be as follows, * diff --git a/framework/rest/ActiveController.php b/framework/rest/ActiveController.php index 5e7df58fbe8..7a62f562695 100644 --- a/framework/rest/ActiveController.php +++ b/framework/rest/ActiveController.php @@ -127,7 +127,7 @@ protected function verbs() * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. * * @param string $action the ID of the action to be executed - * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param object|null $model the model to be accessed. If null, it means no specific model is being accessed. * @param array $params additional parameters * @throws ForbiddenHttpException if the user does not have access */ diff --git a/framework/rest/CreateAction.php b/framework/rest/CreateAction.php index 82e77b72db1..82537a56ca8 100644 --- a/framework/rest/CreateAction.php +++ b/framework/rest/CreateAction.php @@ -52,7 +52,7 @@ public function run() if ($model->save()) { $response = Yii::$app->getResponse(); $response->setStatusCode(201); - $id = implode(',', array_values($model->getPrimaryKey(true))); + $id = implode(',', $model->getPrimaryKey(true)); $response->getHeaders()->set('Location', Url::toRoute([$this->viewAction, 'id' => $id], true)); } elseif (!$model->hasErrors()) { throw new ServerErrorHttpException('Failed to create the object for unknown reason.'); diff --git a/framework/rest/IndexAction.php b/framework/rest/IndexAction.php index f291c765e07..766ed2a6b6b 100644 --- a/framework/rest/IndexAction.php +++ b/framework/rest/IndexAction.php @@ -10,6 +10,9 @@ use Yii; use yii\data\ActiveDataProvider; use yii\data\DataFilter; +use yii\data\Pagination; +use yii\data\Sort; +use yii\helpers\ArrayHelper; /** * IndexAction implements the API endpoint for listing multiple models. @@ -22,7 +25,7 @@ class IndexAction extends Action { /** - * @var callable a PHP callable that will be called to prepare a data provider that + * @var callable|null a PHP callable that will be called to prepare a data provider that * should return a collection of the models. If not set, [[prepareDataProvider()]] will be used instead. * The signature of the callable should be: * @@ -45,9 +48,25 @@ class IndexAction extends Action * ``` */ public $prepareDataProvider; + /** + * @var callable a PHP callable that will be called to prepare query in prepareDataProvider. + * Should return $query. + * For example: + * + * ```php + * function ($query, $requestParams) { + * $query->andFilterWhere(['id' => 1]); + * ... + * return $query; + * } + * ``` + * + * @since 2.0.42 + */ + public $prepareSearchQuery; /** * @var DataFilter|null data filter to be used for the search filter composition. - * You must setup this field explicitly in order to enable filter processing. + * You must set up this field explicitly in order to enable filter processing. * For example: * * ```php @@ -68,6 +87,22 @@ class IndexAction extends Action * @since 2.0.13 */ public $dataFilter; + /** + * @var array|Pagination|false The pagination to be used by [[prepareDataProvider()]]. + * If this is `false`, it means pagination is disabled. + * Note: if a Pagination object is passed, it's `params` will be set to the request parameters. + * @see Pagination + * @since 2.0.45 + */ + public $pagination = []; + /** + * @var array|Sort|false The sorting to be used by [[prepareDataProvider()]]. + * If this is `false`, it means sorting is disabled. + * Note: if a Sort object is passed, it's `params` will be set to the request parameters. + * @see Sort + * @since 2.0.45 + */ + public $sort = []; /** @@ -115,16 +150,43 @@ protected function prepareDataProvider() if (!empty($filter)) { $query->andWhere($filter); } + if (is_callable($this->prepareSearchQuery)) { + $query = call_user_func($this->prepareSearchQuery, $query, $requestParams); + } + + if (is_array($this->pagination)) { + $pagination = ArrayHelper::merge( + [ + 'params' => $requestParams, + ], + $this->pagination + ); + } else { + $pagination = $this->pagination; + if ($this->pagination instanceof Pagination) { + $pagination->params = $requestParams; + } + } + + if (is_array($this->sort)) { + $sort = ArrayHelper::merge( + [ + 'params' => $requestParams, + ], + $this->sort + ); + } else { + $sort = $this->sort; + if ($this->sort instanceof Sort) { + $sort->params = $requestParams; + } + } return Yii::createObject([ 'class' => ActiveDataProvider::className(), 'query' => $query, - 'pagination' => [ - 'params' => $requestParams, - ], - 'sort' => [ - 'params' => $requestParams, - ], + 'pagination' => $pagination, + 'sort' => $sort, ]); } } diff --git a/framework/rest/OptionsAction.php b/framework/rest/OptionsAction.php index 2200bee2640..35c5645a5a0 100644 --- a/framework/rest/OptionsAction.php +++ b/framework/rest/OptionsAction.php @@ -31,7 +31,7 @@ class OptionsAction extends \yii\base\Action /** * Responds to the OPTIONS request. - * @param string $id + * @param string|null $id */ public function run($id = null) { diff --git a/framework/rest/Serializer.php b/framework/rest/Serializer.php index 6cb3ebc35e4..4f889613ed5 100644 --- a/framework/rest/Serializer.php +++ b/framework/rest/Serializer.php @@ -64,7 +64,7 @@ class Serializer extends Component */ public $perPageHeader = 'X-Pagination-Per-Page'; /** - * @var string the name of the envelope (e.g. `items`) for returning the resource objects in a collection. + * @var string|null the name of the envelope (e.g. `items`) for returning the resource objects in a collection. * This is used when serving a resource collection. When this is set and pagination is enabled, the serializer * will return a collection in the following format: * @@ -102,11 +102,11 @@ class Serializer extends Component */ public $metaEnvelope = '_meta'; /** - * @var Request the current request. If not set, the `request` application component will be used. + * @var Request|null the current request. If not set, the `request` application component will be used. */ public $request; /** - * @var Response the response to be sent. If not set, the `response` application component will be used. + * @var Response|null the response to be sent. If not set, the `response` application component will be used. */ public $response; /** @@ -146,10 +146,10 @@ public function serialize($data) { if ($data instanceof Model && $data->hasErrors()) { return $this->serializeModelErrors($data); - } elseif ($data instanceof \JsonSerializable) { - return $data->jsonSerialize(); } elseif ($data instanceof Arrayable) { return $this->serializeModel($data); + } elseif ($data instanceof \JsonSerializable) { + return $data->jsonSerialize(); } elseif ($data instanceof DataProviderInterface) { return $this->serializeDataProvider($data); } elseif (is_array($data)) { diff --git a/framework/rest/UrlRule.php b/framework/rest/UrlRule.php index 73c5dc4f44b..e1a0e2f87c1 100644 --- a/framework/rest/UrlRule.php +++ b/framework/rest/UrlRule.php @@ -62,7 +62,7 @@ class UrlRule extends CompositeUrlRule { /** - * @var string the common prefix string shared by all patterns. + * @var string|null the common prefix string shared by all patterns. */ public $prefix; /** @@ -158,7 +158,7 @@ public function init() } $this->controller = $controllers; - $this->prefix = trim($this->prefix, '/'); + $this->prefix = trim((string)$this->prefix, '/'); parent::init(); } @@ -205,9 +205,6 @@ protected function createRule($pattern, $prefix, $action) $config['verb'] = $verbs; $config['pattern'] = rtrim($prefix . '/' . strtr($pattern, $this->tokens), '/'); $config['route'] = $action; - if (!empty($verbs) && !in_array('GET', $verbs)) { - $config['mode'] = WebUrlRule::PARSING_ONLY; - } $config['suffix'] = $this->suffix; return Yii::createObject($config); @@ -219,6 +216,14 @@ protected function createRule($pattern, $prefix, $action) public function parseRequest($manager, $request) { $pathInfo = $request->getPathInfo(); + if ( + $this->prefix !== '' + && strpos($this->prefix, '<') === false + && strpos($pathInfo . '/', $this->prefix . '/') !== 0 + ) { + return false; + } + foreach ($this->rules as $urlName => $rules) { if (strpos($pathInfo, $urlName) !== false) { foreach ($rules as $rule) { diff --git a/framework/test/ActiveFixture.php b/framework/test/ActiveFixture.php index ff626a43b5f..9fd5ce02d6b 100644 --- a/framework/test/ActiveFixture.php +++ b/framework/test/ActiveFixture.php @@ -8,6 +8,7 @@ namespace yii\test; use yii\base\InvalidConfigException; +use yii\db\ActiveRecord; use yii\db\TableSchema; /** @@ -25,7 +26,7 @@ * For more details and usage information on ActiveFixture, see the [guide article on fixtures](guide:test-fixtures). * * @property-read TableSchema $tableSchema The schema information of the database table associated with this - * fixture. This property is read-only. + * fixture. * * @author Qiang Xue * @since 2.0 @@ -33,13 +34,13 @@ class ActiveFixture extends BaseActiveFixture { /** - * @var string the name of the database table that this fixture is about. If this property is not set, + * @var string|null the name of the database table that this fixture is about. If this property is not set, * the table name will be determined via [[modelClass]]. * @see modelClass */ public $tableName; /** - * @var string|bool the file path or [path alias](guide:concept-aliases) of the data file that contains the fixture data + * @var string|bool|null the file path or [path alias](guide:concept-aliases) of the data file that contains the fixture data * to be returned by [[getData()]]. If this is not set, it will default to `FixturePath/data/TableName.php`, * where `FixturePath` stands for the directory containing this fixture class, and `TableName` stands for the * name of the table associated with this fixture. You can set this property to be false to prevent loading any data. @@ -58,8 +59,13 @@ class ActiveFixture extends BaseActiveFixture public function init() { parent::init(); - if ($this->modelClass === null && $this->tableName === null) { - throw new InvalidConfigException('Either "modelClass" or "tableName" must be set.'); + if ($this->tableName === null) { + if ($this->modelClass === null) { + throw new InvalidConfigException('Either "modelClass" or "tableName" must be set.'); + } + /** @var ActiveRecord $modelClass */ + $modelClass = $this->modelClass; + $this->db = $modelClass::getDb(); } } diff --git a/framework/test/BaseActiveFixture.php b/framework/test/BaseActiveFixture.php index 317d0fa85f1..8262946d5ee 100644 --- a/framework/test/BaseActiveFixture.php +++ b/framework/test/BaseActiveFixture.php @@ -42,7 +42,7 @@ abstract class BaseActiveFixture extends DbFixture implements \IteratorAggregate * Returns the AR model by the specified model name. * A model name is the key of the corresponding data row in [[data]]. * @param string $name the model name. - * @return null|\yii\db\ActiveRecord the AR model, or null if the model cannot be found in the database + * @return \yii\db\ActiveRecord|null the AR model, or null if the model cannot be found in the database * @throws \yii\base\InvalidConfigException if [[modelClass]] is not set. */ public function getModel($name) @@ -84,7 +84,7 @@ public function load() * * @return array the data to be put into the database * @throws InvalidConfigException if the specified data file does not exist. - * @see [[loadData]] + * @see loadData() */ protected function getData() { diff --git a/framework/test/FixtureTrait.php b/framework/test/FixtureTrait.php index e5dc9b09a35..7be29165617 100644 --- a/framework/test/FixtureTrait.php +++ b/framework/test/FixtureTrait.php @@ -43,12 +43,12 @@ trait FixtureTrait * ```php * [ * // anonymous fixture - * PostFixture::className(), + * PostFixture::class, * // "users" fixture - * 'users' => UserFixture::className(), + * 'users' => UserFixture::class, * // "cache" fixture with configuration * 'cache' => [ - * 'class' => CacheFixture::className(), + * 'class' => CacheFixture::class, * 'host' => 'xxx', * ], * ] @@ -79,7 +79,7 @@ public function globalFixtures() /** * Loads the specified fixtures. * This method will call [[Fixture::load()]] for every fixture object. - * @param Fixture[] $fixtures the fixtures to be loaded. If this parameter is not specified, + * @param Fixture[]|null $fixtures the fixtures to be loaded. If this parameter is not specified, * the return value of [[getFixtures()]] will be used. */ public function loadFixtures($fixtures = null) @@ -103,7 +103,7 @@ public function loadFixtures($fixtures = null) /** * Unloads the specified fixtures. * This method will call [[Fixture::unload()]] for every fixture object. - * @param Fixture[] $fixtures the fixtures to be loaded. If this parameter is not specified, + * @param Fixture[]|null $fixtures the fixtures to be loaded. If this parameter is not specified, * the return value of [[getFixtures()]] will be used. */ public function unloadFixtures($fixtures = null) @@ -151,7 +151,7 @@ public function getFixtures() /** * Returns the named fixture. * @param string $name the fixture name. This can be either the fixture alias name, or the class name if the alias is not used. - * @return Fixture the fixture object, or null if the named fixture does not exist. + * @return Fixture|null the fixture object, or null if the named fixture does not exist. */ public function getFixture($name) { diff --git a/framework/validators/CompareValidator.php b/framework/validators/CompareValidator.php index 8df351b72da..fbe4d2cbe2b 100644 --- a/framework/validators/CompareValidator.php +++ b/framework/validators/CompareValidator.php @@ -16,7 +16,7 @@ * * The value being compared with can be another attribute value * (specified via [[compareAttribute]]) or a constant (specified via - * [[compareValue]]. When both are specified, the latter takes + * [[compareValue]]). When both are specified, the latter takes * precedence. If neither is specified, the attribute will be compared * with another attribute whose name is by appending "_repeat" to the source * attribute name. @@ -105,14 +105,10 @@ public function init() if ($this->message === null) { switch ($this->operator) { case '==': - $this->message = Yii::t('yii', '{attribute} must be equal to "{compareValueOrAttribute}".'); - break; case '===': $this->message = Yii::t('yii', '{attribute} must be equal to "{compareValueOrAttribute}".'); break; case '!=': - $this->message = Yii::t('yii', '{attribute} must not be equal to "{compareValueOrAttribute}".'); - break; case '!==': $this->message = Yii::t('yii', '{attribute} must not be equal to "{compareValueOrAttribute}".'); break; @@ -146,6 +142,9 @@ public function validateAttribute($model, $attribute) return; } if ($this->compareValue !== null) { + if ($this->compareValue instanceof \Closure) { + $this->compareValue = call_user_func($this->compareValue); + } $compareLabel = $compareValue = $compareValueOrAttribute = $this->compareValue; } else { $compareAttribute = $this->compareAttribute === null ? $attribute . '_repeat' : $this->compareAttribute; @@ -170,6 +169,9 @@ protected function validateValue($value) if ($this->compareValue === null) { throw new InvalidConfigException('CompareValidator::compareValue must be set.'); } + if ($this->compareValue instanceof \Closure) { + $this->compareValue = call_user_func($this->compareValue); + } if (!$this->compareValues($this->operator, $this->type, $value, $this->compareValue)) { return [$this->message, [ 'compareAttribute' => $this->compareValue, @@ -225,6 +227,10 @@ protected function compareValues($operator, $type, $value, $compareValue) */ public function clientValidateAttribute($model, $attribute, $view) { + if ($this->compareValue != null && $this->compareValue instanceof \Closure) { + $this->compareValue = call_user_func($this->compareValue); + } + ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); diff --git a/framework/validators/DateValidator.php b/framework/validators/DateValidator.php index 24604cf6721..3df5018b321 100644 --- a/framework/validators/DateValidator.php +++ b/framework/validators/DateValidator.php @@ -60,7 +60,7 @@ class DateValidator extends Validator * This property influences the default value of [[format]] and also sets the correct behavior when [[format]] is one of the intl * short formats, `short`, `medium`, `long`, or `full`. * - * This is only effective when the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is installed. + * This is only effective when the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is installed. * * This property can be set to the following values: * @@ -72,11 +72,11 @@ class DateValidator extends Validator */ public $type = self::TYPE_DATE; /** - * @var string the date format that the value being validated should follow. + * @var string|null the date format that the value being validated should follow. * This can be a date time pattern as described in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). * * Alternatively this can be a string prefixed with `php:` representing a format that can be recognized by the PHP Datetime class. - * Please refer to on supported formats. + * Please refer to on supported formats. * * If this property is not set, the default value will be obtained from `Yii::$app->formatter->dateFormat`, see [[\yii\i18n\Formatter::dateFormat]] for details. * Since version 2.0.8 the default value will be determined from different formats of the formatter class, @@ -95,8 +95,8 @@ class DateValidator extends Validator * ``` * * **Note:** the underlying date parsers being used vary dependent on the format. If you use the ICU format and - * the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is installed, the [IntlDateFormatter](https://secure.php.net/manual/en/intldateformatter.parse.php) - * is used to parse the input value. In all other cases the PHP [DateTime](https://secure.php.net/manual/en/datetime.createfromformat.php) class + * the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is installed, the [IntlDateFormatter](https://www.php.net/manual/en/intldateformatter.parse.php) + * is used to parse the input value. In all other cases the PHP [DateTime](https://www.php.net/manual/en/datetime.createfromformat.php) class * is used. The IntlDateFormatter has the advantage that it can parse international dates like `12. Mai 2015` or `12 мая 2014`, while the * PHP parser is limited to English only. The PHP parser however is more strict about the input format as it will not accept * `12.05.05` for the format `php:d.m.Y`, but the IntlDateFormatter will accept it for the format `dd.MM.yyyy`. @@ -104,22 +104,22 @@ class DateValidator extends Validator */ public $format; /** - * @var string the locale ID that is used to localize the date parsing. - * This is only effective when the [PHP intl extension](https://secure.php.net/manual/en/book.intl.php) is installed. + * @var string|null the locale ID that is used to localize the date parsing. + * This is only effective when the [PHP intl extension](https://www.php.net/manual/en/book.intl.php) is installed. * If not set, the locale of the [[\yii\base\Application::formatter|formatter]] will be used. * See also [[\yii\i18n\Formatter::locale]]. */ public $locale; /** - * @var string the timezone to use for parsing date and time values. - * This can be any value that may be passed to [date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php) + * @var string|null the timezone to use for parsing date and time values. + * This can be any value that may be passed to [date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php) * e.g. `UTC`, `Europe/Berlin` or `America/Chicago`. - * Refer to the [php manual](https://secure.php.net/manual/en/timezones.php) for available timezones. + * Refer to the [php manual](https://www.php.net/manual/en/timezones.php) for available timezones. * If this property is not set, [[\yii\base\Application::timeZone]] will be used. */ public $timeZone; /** - * @var string the name of the attribute to receive the parsing result. + * @var string|null the name of the attribute to receive the parsing result. * When this property is not null and the validation is successful, the named attribute will * receive the parsing result. * @@ -137,7 +137,7 @@ class DateValidator extends Validator */ public $timestampAttribute; /** - * @var string the format to use when populating the [[timestampAttribute]]. + * @var string|null the format to use when populating the [[timestampAttribute]]. * The format can be specified in the same way as for [[format]]. * * If not set, [[timestampAttribute]] will receive a UNIX timestamp. @@ -150,9 +150,9 @@ class DateValidator extends Validator /** * @var string the timezone to use when populating the [[timestampAttribute]] with [[timestampAttributeFormat]]. Defaults to `UTC`. * - * This can be any value that may be passed to [date_default_timezone_set()](https://secure.php.net/manual/en/function.date-default-timezone-set.php) + * This can be any value that may be passed to [date_default_timezone_set()](https://www.php.net/manual/en/function.date-default-timezone-set.php) * e.g. `UTC`, `Europe/Berlin` or `America/Chicago`. - * Refer to the [php manual](https://secure.php.net/manual/en/timezones.php) for available timezones. + * Refer to the [php manual](https://www.php.net/manual/en/timezones.php) for available timezones. * * If [[timestampAttributeFormat]] is not set, this property will be ignored. * @see timestampAttributeFormat @@ -160,7 +160,7 @@ class DateValidator extends Validator */ public $timestampAttributeTimeZone = 'UTC'; /** - * @var int|string upper limit of the date. Defaults to null, meaning no upper limit. + * @var int|string|null upper limit of the date. Defaults to null, meaning no upper limit. * This can be a unix timestamp or a string representing a date time value. * If this property is a string, [[format]] will be used to parse it. * @see tooBig for the customized message used when the date is too big. @@ -168,7 +168,7 @@ class DateValidator extends Validator */ public $max; /** - * @var int|string lower limit of the date. Defaults to null, meaning no lower limit. + * @var int|string|null lower limit of the date. Defaults to null, meaning no lower limit. * This can be a unix timestamp or a string representing a date time value. * If this property is a string, [[format]] will be used to parse it. * @see tooSmall for the customized message used when the date is too small. @@ -186,13 +186,13 @@ class DateValidator extends Validator */ public $tooSmall; /** - * @var string user friendly value of upper limit to display in the error message. + * @var string|null user friendly value of upper limit to display in the error message. * If this property is null, the value of [[max]] will be used (before parsing). * @since 2.0.4 */ public $maxString; /** - * @var string user friendly value of lower limit to display in the error message. + * @var string|null user friendly value of lower limit to display in the error message. * If this property is null, the value of [[min]] will be used (before parsing). * @since 2.0.4 */ diff --git a/framework/validators/EmailValidator.php b/framework/validators/EmailValidator.php index 0418e5f57a1..984d00d4510 100644 --- a/framework/validators/EmailValidator.php +++ b/framework/validators/EmailValidator.php @@ -32,6 +32,19 @@ class EmailValidator extends Validator * @see allowName */ public $fullPattern = '/^[^@]*<[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/'; + /** + * @var string the regular expression used to validate the part before the @ symbol, used if ASCII conversion fails to validate the address. + * @see http://www.regular-expressions.info/email.html + * @since 2.0.42 + */ + public $patternASCII = '/^[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*$/'; + /** + * @var string the regular expression used to validate email addresses with the name part before the @ symbol, used if ASCII conversion fails to validate the address. + * This property is used only when [[allowName]] is true. + * @see allowName + * @since 2.0.42 + */ + public $fullPatternASCII = '/^[^@]*<[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*$/'; /** * @var bool whether to allow name in the email address (e.g. "John Smith "). Defaults to false. * @see fullPattern @@ -50,6 +63,12 @@ class EmailValidator extends Validator * otherwise an exception would be thrown. */ public $enableIDN = false; + /** + * @var bool whether [[enableIDN]] should apply to the local part of the email (left side + * of the `@`). Only applies if [[enableIDN]] is `true`. + * @since 2.0.43 + */ + public $enableLocalIDN = true; /** @@ -77,7 +96,9 @@ protected function validateValue($value) $valid = false; } else { if ($this->enableIDN) { - $matches['local'] = $this->idnToAscii($matches['local']); + if ($this->enableLocalIDN) { + $matches['local'] = $this->idnToAsciiWithFallback($matches['local']); + } $matches['domain'] = $this->idnToAscii($matches['domain']); $value = $matches['name'] . $matches['open'] . $matches['local'] . '@' . $matches['domain'] . $matches['close']; } @@ -176,4 +197,21 @@ public function getClientOptions($model, $attribute) return $options; } + + /** + * @param string $value + * @return string|bool returns string if it is valid and/or can be converted, bool false if it can't be converted and/or is invalid + * @see https://github.com/yiisoft/yii2/issues/18585 + */ + private function idnToAsciiWithFallback($value) + { + $ascii = $this->idnToAscii($value); + if ($ascii === false) { + if (preg_match($this->patternASCII, $value) || ($this->allowName && preg_match($this->fullPatternASCII, $value))) { + return $value; + } + } + + return $ascii; + } } diff --git a/framework/validators/ExistValidator.php b/framework/validators/ExistValidator.php index 8bbcd69195e..5388b11f634 100644 --- a/framework/validators/ExistValidator.php +++ b/framework/validators/ExistValidator.php @@ -49,13 +49,13 @@ class ExistValidator extends Validator { /** - * @var string the name of the ActiveRecord class that should be used to validate the existence + * @var string|null the name of the ActiveRecord class that should be used to validate the existence * of the current attribute value. If not set, it will use the ActiveRecord class of the attribute being validated. * @see targetAttribute */ public $targetClass; /** - * @var string|array the name of the ActiveRecord attribute that should be used to + * @var string|array|null the name of the ActiveRecord attribute that should be used to * validate the existence of the current attribute value. If not set, it will use the name * of the attribute currently being validated. You may use an array to validate the existence * of multiple columns at the same time. The array key is the name of the attribute with the value to validate, @@ -131,15 +131,15 @@ private function checkTargetRelationExistence($model, $attribute) $relationQuery->andWhere($this->filter); } - if ($this->forceMasterDb && method_exists($model::getDb(), 'useMaster')) { - $model::getDb()->useMaster(function() use ($relationQuery, &$exists) { - $exists = $relationQuery->exists(); + $connection = $model::getDb(); + if ($this->forceMasterDb && method_exists($connection, 'useMaster')) { + $exists = $connection->useMaster(function() use ($relationQuery) { + return $relationQuery->exists(); }); } else { $exists = $relationQuery->exists(); } - if (!$exists) { $this->addError($model, $attribute, $this->message); } @@ -169,7 +169,7 @@ private function checkTargetAttributeExistence($model, $attribute) $conditions[] = $params; } - $targetClass = $this->targetClass === null ? get_class($model) : $this->targetClass; + $targetClass = $this->getTargetClass($model); $query = $this->createQuery($targetClass, $conditions); if (!$this->valueExists($targetClass, $query, $model->$attribute)) { @@ -181,7 +181,7 @@ private function checkTargetAttributeExistence($model, $attribute) * Processes attributes' relations described in $targetAttribute parameter into conditions, compatible with * [[\yii\db\Query::where()|Query::where()]] key-value format. * - * @param $targetAttribute array|string $attribute the name of the ActiveRecord attribute that should be used to + * @param $targetAttribute array|string|null $attribute the name of the ActiveRecord attribute that should be used to * validate the existence of the current attribute value. If not set, it will use the name * of the attribute currently being validated. You may use an array to validate the existence * of multiple columns at the same time. The array key is the name of the attribute with the value to validate, @@ -246,9 +246,9 @@ protected function validateValue($value) } /** - * Check whether value exists in target table + * Check whether value exists in target table. * - * @param string $targetClass + * @param string $targetClass the model * @param QueryInterface $query * @param mixed $value the value want to be checked * @return bool @@ -259,8 +259,8 @@ private function valueExists($targetClass, $query, $value) $exists = false; if ($this->forceMasterDb && method_exists($db, 'useMaster')) { - $db->useMaster(function ($db) use ($query, $value, &$exists) { - $exists = $this->queryValueExists($query, $value); + $exists = $db->useMaster(function () use ($query, $value) { + return $this->queryValueExists($query, $value); }); } else { $exists = $this->queryValueExists($query, $value); @@ -271,7 +271,7 @@ private function valueExists($targetClass, $query, $value) /** - * Run query to check if value exists + * Run query to check if value exists. * * @param QueryInterface $query * @param mixed $value the value to be checked @@ -280,7 +280,7 @@ private function valueExists($targetClass, $query, $value) private function queryValueExists($query, $value) { if (is_array($value)) { - return $query->count("DISTINCT [[$this->targetAttribute]]") == count($value) ; + return $query->count("DISTINCT [[$this->targetAttribute]]") == count(array_unique($value)); } return $query->exists(); } @@ -308,7 +308,7 @@ protected function createQuery($targetClass, $condition) * Returns conditions with alias. * @param ActiveQuery $query * @param array $conditions array of condition, keys to be modified - * @param null|string $alias set empty string for no apply alias. Set null for apply primary table alias + * @param string|null $alias set empty string for no apply alias. Set null for apply primary table alias * @return array */ private function applyTableAlias($query, $conditions, $alias = null) diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php index d67934ffd74..2d67ac60cb8 100644 --- a/framework/validators/FileValidator.php +++ b/framework/validators/FileValidator.php @@ -20,7 +20,7 @@ * * Note that you should enable `fileinfo` PHP extension. * - * @property-read int $sizeLimit The size limit for uploaded files. This property is read-only. + * @property-read int $sizeLimit The size limit for uploaded files. * * @author Qiang Xue * @since 2.0 @@ -28,7 +28,7 @@ class FileValidator extends Validator { /** - * @var array|string a list of file name extensions that are allowed to be uploaded. + * @var array|string|null a list of file name extensions that are allowed to be uploaded. * This can be either an array or a string consisting of file extension names * separated by space or comma (e.g. "gif, jpg"). * Extension names are case-insensitive. Defaults to null, meaning all file name @@ -42,7 +42,7 @@ class FileValidator extends Validator */ public $checkExtensionByMimeType = true; /** - * @var array|string a list of file MIME types that are allowed to be uploaded. + * @var array|string|null a list of file MIME types that are allowed to be uploaded. * This can be either an array or a string consisting of file MIME types * separated by space or comma (e.g. "text/plain, image/png"). * The mask with the special character `*` can be used to match groups of mime types. @@ -52,18 +52,18 @@ class FileValidator extends Validator */ public $mimeTypes; /** - * @var int the minimum number of bytes required for the uploaded file. + * @var int|null the minimum number of bytes required for the uploaded file. * Defaults to null, meaning no limit. * @see tooSmall for the customized message for a file that is too small. */ public $minSize; /** - * @var int the maximum number of bytes required for the uploaded file. + * @var int|null the maximum number of bytes required for the uploaded file. * Defaults to null, meaning no limit. * Note, the size limit is also affected by `upload_max_filesize` and `post_max_size` INI setting * and the 'MAX_FILE_SIZE' hidden field value. See [[getSizeLimit()]] for details. - * @see https://secure.php.net/manual/en/ini.core.php#ini.upload-max-filesize - * @see https://secure.php.net/post-max-size + * @see https://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize + * @see https://www.php.net/post-max-size * @see getSizeLimit * @see tooBig for the customized message for a file that is too big. */ @@ -77,7 +77,7 @@ class FileValidator extends Validator * > Note: The maximum number of files allowed to be uploaded simultaneously is * also limited with PHP directive `max_file_uploads`, which defaults to 20. * - * @see https://secure.php.net/manual/en/ini.core.php#ini.max-file-uploads + * @see https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads * @see tooMany for the customized message when too many files are uploaded. */ public $maxFiles = 1; @@ -188,7 +188,7 @@ public function init() $this->tooSmall = Yii::t('yii', 'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.'); } if (!is_array($this->extensions)) { - $this->extensions = preg_split('/[\s,]+/', strtolower($this->extensions), -1, PREG_SPLIT_NO_EMPTY); + $this->extensions = preg_split('/[\s,]+/', strtolower((string)$this->extensions), -1, PREG_SPLIT_NO_EMPTY); } else { $this->extensions = array_map('strtolower', $this->extensions); } @@ -196,7 +196,7 @@ public function init() $this->wrongMimeType = Yii::t('yii', 'Only files with these MIME types are allowed: {mimeTypes}.'); } if (!is_array($this->mimeTypes)) { - $this->mimeTypes = preg_split('/[\s,]+/', strtolower($this->mimeTypes), -1, PREG_SPLIT_NO_EMPTY); + $this->mimeTypes = preg_split('/[\s,]+/', strtolower((string)$this->mimeTypes), -1, PREG_SPLIT_NO_EMPTY); } else { $this->mimeTypes = array_map('strtolower', $this->mimeTypes); } @@ -530,6 +530,9 @@ private function buildMimeTypeRegexp($mask) protected function validateMimeType($file) { $fileMimeType = $this->getMimeTypeByFile($file->tempName); + if ($fileMimeType === null) { + return false; + } foreach ($this->mimeTypes as $mimeType) { if (strcasecmp($mimeType, $fileMimeType) === 0) { @@ -548,11 +551,12 @@ protected function validateMimeType($file) * Get MIME type by file path * * @param string $filePath - * @return string + * @return string|null * @throws \yii\base\InvalidConfigException * @since 2.0.26 */ - protected function getMimeTypeByFile($filePath) { + protected function getMimeTypeByFile($filePath) + { return FileHelper::getMimeType($filePath); } } diff --git a/framework/validators/FilterValidator.php b/framework/validators/FilterValidator.php index 873e1b197e7..d24131a9711 100644 --- a/framework/validators/FilterValidator.php +++ b/framework/validators/FilterValidator.php @@ -25,6 +25,8 @@ * ``` * * Many PHP functions qualify this signature (e.g. `trim()`). + * If the callback function requires non-null argument (important since PHP 8.1) + * remember to set [[skipOnEmpty]] to `true` otherwise you may trigger an error. * * To specify the filter, set [[filter]] property to be the callback. * diff --git a/framework/validators/ImageValidator.php b/framework/validators/ImageValidator.php index 6edfb97dbb7..0a06dd75f4d 100644 --- a/framework/validators/ImageValidator.php +++ b/framework/validators/ImageValidator.php @@ -27,25 +27,25 @@ class ImageValidator extends FileValidator */ public $notImage; /** - * @var int the minimum width in pixels. + * @var int|null the minimum width in pixels. * Defaults to null, meaning no limit. * @see underWidth for the customized message used when image width is too small. */ public $minWidth; /** - * @var int the maximum width in pixels. + * @var int|null the maximum width in pixels. * Defaults to null, meaning no limit. * @see overWidth for the customized message used when image width is too big. */ public $maxWidth; /** - * @var int the minimum height in pixels. + * @var int|null the minimum height in pixels. * Defaults to null, meaning no limit. * @see underHeight for the customized message used when image height is too small. */ public $minHeight; /** - * @var int the maximum width in pixels. + * @var int|null the maximum width in pixels. * Defaults to null, meaning no limit. * @see overHeight for the customized message used when image height is too big. */ diff --git a/framework/validators/InlineValidator.php b/framework/validators/InlineValidator.php index a8dcd0040d4..86924826415 100644 --- a/framework/validators/InlineValidator.php +++ b/framework/validators/InlineValidator.php @@ -10,15 +10,6 @@ /** * InlineValidator represents a validator which is defined as a method in the object being validated. * - * The validation method must have the following signature: - * - * ```php - * function foo($attribute, $params, $validator) - * ``` - * - * where `$attribute` refers to the name of the attribute being validated, while `$params` is an array representing the - * additional parameters supplied in the validation rule. Parameter `$validator` refers to the related - * [[InlineValidator]] object and is available since version 2.0.11. * * @author Qiang Xue * @since 2.0 @@ -26,16 +17,18 @@ class InlineValidator extends Validator { /** - * @var string|\Closure an anonymous function or the name of a model class method that will be + * @var string|callable an anonymous function or the name of a model class method that will be * called to perform the actual validation. The signature of the method should be like the following: * * ```php - * function foo($attribute, $params, $validator) + * function (string $attribute, mixed $params, InlineValidator $validator, mixed $current): bool { + * } * ``` * - * - `$attribute` is the name of the attribute to be validated; - * - `$params` contains the value of [[params]] that you specify when declaring the inline validation rule; - * - `$validator` is a reference to related [[InlineValidator]] object. This parameter is available since version 2.0.11. + * - `$attribute` is the name of the attribute to be validated + * - `$params` contains the value of [[params]] that you specify when declaring the inline validation rule + * - `$validator` is a reference to related [[InlineValidator]] object. This parameter is available since version 2.0.11 + * - `$current` is the attribute value. This parameter is available since version 2.0.36 */ public $method; /** @@ -47,15 +40,16 @@ class InlineValidator extends Validator * The signature of the method should be like the following: * * ```php - * function foo($attribute, $params, $validator) + * function (string $attribute, mixed $params, InlineValidator $validator, mixed $current, View $view): string * { - * return "javascript"; + * // $view->registerJs('JS validation function'); + * // or \app\assets\ValidationAsset::register($view); + * return "calling JS validation function"; * } * ``` * - * where `$attribute` refers to the attribute name to be validated. - * - * Please refer to [[clientValidateAttribute()]] for details on how to return client validation code. + * Please refer to [[clientValidateAttribute()]] and [guide](guide:input-validation#client-side-validation) for details on how + * to return client validation code. */ public $clientValidate; /** @@ -100,7 +94,7 @@ public function clientValidateAttribute($model, $attribute, $view) if ($current === null) { $current = $model->$attribute; } - return $method($attribute, $this->params, $this, $current); + return $method($attribute, $this->params, $this, $current, $view); } return null; diff --git a/framework/validators/IpValidator.php b/framework/validators/IpValidator.php index ea1e87718e3..02ac99eb0b7 100644 --- a/framework/validators/IpValidator.php +++ b/framework/validators/IpValidator.php @@ -86,7 +86,7 @@ class IpValidator extends Validator */ public $ipv4 = true; /** - * @var bool whether the address can be an IP with CIDR subnet, like `192.168.10.0/24`. + * @var bool|null whether the address can be an IP with CIDR subnet, like `192.168.10.0/24`. * The following values are possible: * * - `false` - the address must not have a subnet (default). @@ -163,7 +163,7 @@ class IpValidator extends Validator */ public $wrongCidr; /** - * @var string user-defined error message is used when validation fails due to subnet [[subnet]] set to 'only', + * @var string|null user-defined error message is used when validation fails due to subnet [[subnet]] set to 'only', * but the CIDR prefix is not set. * * You may use the following placeholders in the message: @@ -246,9 +246,7 @@ public function init() * - Recursively substitutes aliases (described in [[networks]]) with their values. * - Removes duplicates * - * @property array the IPv4 or IPv6 ranges that are allowed or forbidden. - * See [[setRanges()]] for detailed description. - * @param array|string $ranges the IPv4 or IPv6 ranges that are allowed or forbidden. + * @param array|string|null $ranges the IPv4 or IPv6 ranges that are allowed or forbidden. * * When the array is empty, or the option not set, all IP addresses are allowed. * diff --git a/framework/validators/NumberValidator.php b/framework/validators/NumberValidator.php index e6fca0fd11d..99972cefaa2 100644 --- a/framework/validators/NumberValidator.php +++ b/framework/validators/NumberValidator.php @@ -24,17 +24,22 @@ */ class NumberValidator extends Validator { + /** + * @var bool whether to allow array type attribute. Defaults to false. + * @since 2.0.42 + */ + public $allowArray = false; /** * @var bool whether the attribute value can only be an integer. Defaults to false. */ public $integerOnly = false; /** - * @var int|float upper limit of the number. Defaults to null, meaning no upper limit. + * @var int|float|null upper limit of the number. Defaults to null, meaning no upper limit. * @see tooBig for the customized message used when the number is too big. */ public $max; /** - * @var int|float lower limit of the number. Defaults to null, meaning no lower limit. + * @var int|float|null lower limit of the number. Defaults to null, meaning no lower limit. * @see tooSmall for the customized message used when the number is too small. */ public $min; @@ -49,12 +54,12 @@ class NumberValidator extends Validator /** * @var string the regular expression for matching integers. */ - public $integerPattern = '/^\s*[+-]?\d+\s*$/'; + public $integerPattern = '/^[+-]?\d+$/'; /** * @var string the regular expression for matching numbers. It defaults to a pattern * that matches floating numbers with optional exponential part (e.g. -1.23e-10). */ - public $numberPattern = '/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/'; + public $numberPattern = '/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/'; /** @@ -81,20 +86,27 @@ public function init() public function validateAttribute($model, $attribute) { $value = $model->$attribute; - if ($this->isNotNumber($value)) { + if (is_array($value) && !$this->allowArray) { $this->addError($model, $attribute, $this->message); return; } - $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern; - - if (!preg_match($pattern, StringHelper::normalizeNumber($value))) { - $this->addError($model, $attribute, $this->message); - } - if ($this->min !== null && $value < $this->min) { - $this->addError($model, $attribute, $this->tooSmall, ['min' => $this->min]); - } - if ($this->max !== null && $value > $this->max) { - $this->addError($model, $attribute, $this->tooBig, ['max' => $this->max]); + $values = !is_array($value) ? [$value] : $value; + foreach ($values as $value) { + if ($this->isNotNumber($value)) { + $this->addError($model, $attribute, $this->message); + return; + } + $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern; + + if (!preg_match($pattern, StringHelper::normalizeNumber($value))) { + $this->addError($model, $attribute, $this->message); + } + if ($this->min !== null && $value < $this->min) { + $this->addError($model, $attribute, $this->tooSmall, ['min' => $this->min]); + } + if ($this->max !== null && $value > $this->max) { + $this->addError($model, $attribute, $this->tooBig, ['max' => $this->max]); + } } } @@ -103,22 +115,28 @@ public function validateAttribute($model, $attribute) */ protected function validateValue($value) { - if ($this->isNotNumber($value)) { + if (is_array($value) && !$this->allowArray) { return [Yii::t('yii', '{attribute} is invalid.'), []]; } - $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern; - if (!preg_match($pattern, StringHelper::normalizeNumber($value))) { - return [$this->message, []]; - } elseif ($this->min !== null && $value < $this->min) { - return [$this->tooSmall, ['min' => $this->min]]; - } elseif ($this->max !== null && $value > $this->max) { - return [$this->tooBig, ['max' => $this->max]]; + $values = !is_array($value) ? [$value] : $value; + foreach ($values as $value) { + if ($this->isNotNumber($value)) { + return [Yii::t('yii', '{attribute} is invalid.'), []]; + } + $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern; + if (!preg_match($pattern, StringHelper::normalizeNumber($value))) { + return [$this->message, []]; + } elseif ($this->min !== null && $value < $this->min) { + return [$this->tooSmall, ['min' => $this->min]]; + } elseif ($this->max !== null && $value > $this->max) { + return [$this->tooBig, ['max' => $this->max]]; + } } return null; } - /* + /** * @param mixed $value the data value to be checked. */ private function isNotNumber($value) diff --git a/framework/validators/SafeValidator.php b/framework/validators/SafeValidator.php index f86f2395a3c..2b0a3c5dd7f 100644 --- a/framework/validators/SafeValidator.php +++ b/framework/validators/SafeValidator.php @@ -14,7 +14,7 @@ * when a user submits form data to be loaded into a model directly from the POST data, is it ok for a property to be copied. * In many cases, this is required but because sometimes properties are internal and you do not want the POST data to be able to * override these internal values (especially things like database row ids), Yii assumes all values are unsafe for massive assignment - * unless a validation rule exists for the property, which in most cases it will. Sometimes, however, an item is safe for massive assigment but + * unless a validation rule exists for the property, which in most cases it will. Sometimes, however, an item is safe for massive assignment but * does not have a validation rule associated with it - for instance, due to no validation being performed, in which case, you use this class * as a validation rule for that property. Although it has no functionality, it allows Yii to determine that the property is safe to copy. * diff --git a/framework/validators/StringValidator.php b/framework/validators/StringValidator.php index f06dbfc2208..3f44ce29dea 100644 --- a/framework/validators/StringValidator.php +++ b/framework/validators/StringValidator.php @@ -34,12 +34,12 @@ class StringValidator extends Validator */ public $length; /** - * @var int maximum length. If not set, it means no maximum length limit. + * @var int|null maximum length. If not set, it means no maximum length limit. * @see tooLong for the customized message for a too long string. */ public $max; /** - * @var int minimum length. If not set, it means no minimum length limit. + * @var int|null minimum length. If not set, it means no minimum length limit. * @see tooShort for the customized message for a too short string. */ public $min; @@ -60,7 +60,7 @@ class StringValidator extends Validator */ public $notEqual; /** - * @var string the encoding of the string value to be validated (e.g. 'UTF-8'). + * @var string|null the encoding of the string value to be validated (e.g. 'UTF-8'). * If this property is not set, [[\yii\base\Application::charset]] will be used. */ public $encoding; diff --git a/framework/validators/TrimValidator.php b/framework/validators/TrimValidator.php new file mode 100644 index 00000000000..2e32db69c49 --- /dev/null +++ b/framework/validators/TrimValidator.php @@ -0,0 +1,82 @@ +$attribute; + if (!$this->skipOnArray || !is_array($value)) { + $model->$attribute = is_array($value) + ? array_map([$this, 'trimValue'], $value) + : $this->trimValue($value); + } + } + + /** + * Converts given value to string and strips declared characters. + * + * @param mixed $value the value to strip + * @return string + */ + protected function trimValue($value) + { + return $this->isEmpty($value) ? '' : trim((string) $value, $this->chars ?: " \n\r\t\v\x00"); + } + + /** + * @inheritDoc + */ + public function clientValidateAttribute($model, $attribute, $view) + { + if ($this->skipOnArray && is_array($model->$attribute)) { + return null; + } + + ValidationAsset::register($view); + $options = $this->getClientOptions($model, $attribute); + + return 'value = yii.validation.trim($form, attribute, ' . json_encode($options) . ', value);'; + } + + /** + * @inheritDoc + */ + public function getClientOptions($model, $attribute) + { + return [ + 'skipOnArray' => (bool) $this->skipOnArray, + 'skipOnEmpty' => (bool) $this->skipOnEmpty, + 'chars' => $this->chars ?: false, + ]; + } +} diff --git a/framework/validators/UniqueValidator.php b/framework/validators/UniqueValidator.php index 7aa1e8131a4..3a9623627d9 100644 --- a/framework/validators/UniqueValidator.php +++ b/framework/validators/UniqueValidator.php @@ -42,13 +42,13 @@ class UniqueValidator extends Validator { /** - * @var string the name of the ActiveRecord class that should be used to validate the uniqueness + * @var string|null the name of the ActiveRecord class that should be used to validate the uniqueness * of the current attribute value. If not set, it will use the ActiveRecord class of the attribute being validated. * @see targetAttribute */ public $targetClass; /** - * @var string|array the name of the [[\yii\db\ActiveRecord|ActiveRecord]] attribute that should be used to + * @var string|array|null the name of the [[\yii\db\ActiveRecord|ActiveRecord]] attribute that should be used to * validate the uniqueness of the current attribute value. If not set, it will use the name * of the attribute currently being validated. You may use an array to validate the uniqueness * of multiple columns at the same time. The array values are the attributes that will be @@ -191,10 +191,10 @@ private function modelExists($targetClass, $conditions, $model) // only select primary key to optimize query $columnsCondition = array_flip($targetClass::primaryKey()); $query->select(array_flip($this->applyTableAlias($query, $columnsCondition))); - + // any with relation can't be loaded because related fields are not selected $query->with = null; - + if (is_array($query->joinWith)) { // any joinWiths need to have eagerLoading turned off to prevent related fields being loaded foreach ($query->joinWith as &$joinWith) { @@ -309,7 +309,7 @@ private function addComboNotUniqueError($model, $attribute) * Returns conditions with alias. * @param ActiveQuery $query * @param array $conditions array of condition, keys to be modified - * @param null|string $alias set empty string for no apply alias. Set null for apply primary table alias + * @param string|null $alias set empty string for no apply alias. Set null for apply primary table alias * @return array */ private function applyTableAlias($query, $conditions, $alias = null) @@ -321,7 +321,7 @@ private function applyTableAlias($query, $conditions, $alias = null) foreach ($conditions as $columnName => $columnValue) { if (strpos($columnName, '(') === false) { $columnName = preg_replace('/^' . preg_quote($alias) . '\.(.*)$/', '$1', $columnName); - if (strpos($columnName, '[[') === 0) { + if (strncmp($columnName, '[[', 2) === 0) { $prefixedColumn = "{$alias}.{$columnName}"; } else { $prefixedColumn = "{$alias}.[[{$columnName}]]"; diff --git a/framework/validators/UrlValidator.php b/framework/validators/UrlValidator.php index 812a218b506..b4fae1f7f8a 100644 --- a/framework/validators/UrlValidator.php +++ b/framework/validators/UrlValidator.php @@ -35,7 +35,7 @@ class UrlValidator extends Validator */ public $validSchemes = ['http', 'https']; /** - * @var string the default URI scheme. If the input doesn't contain the scheme part, the default + * @var string|null the default URI scheme. If the input doesn't contain the scheme part, the default * scheme will be prepended to it (thus changing the input). Defaults to null, meaning a URL must * contain the scheme part. */ diff --git a/framework/validators/Validator.php b/framework/validators/Validator.php index 5b808acd271..9e232ef8e9b 100644 --- a/framework/validators/Validator.php +++ b/framework/validators/Validator.php @@ -41,15 +41,15 @@ * - `required`: [[RequiredValidator]] * - `safe`: [[SafeValidator]] * - `string`: [[StringValidator]] - * - `trim`: [[FilterValidator]] + * - `trim`: [[TrimValidator]] * - `unique`: [[UniqueValidator]] * - `url`: [[UrlValidator]] * - `ip`: [[IpValidator]] * * For more details and usage information on Validator, see the [guide article on validators](guide:input-validation). * - * @property-read array $attributeNames Attribute names. This property is read-only. - * @property-read array $validationAttributes List of attribute names. This property is read-only. + * @property-read array $attributeNames Attribute names. + * @property-read array $validationAttributes List of attribute names. * * @author Qiang Xue * @since 2.0 @@ -91,8 +91,7 @@ class Validator extends Component 'safe' => 'yii\validators\SafeValidator', 'string' => 'yii\validators\StringValidator', 'trim' => [ - 'class' => 'yii\validators\FilterValidator', - 'filter' => 'trim', + 'class' => 'yii\validators\TrimValidator', 'skipOnArray' => true, ], 'unique' => 'yii\validators\UniqueValidator', @@ -105,7 +104,7 @@ class Validator extends Component */ public $attributes = []; /** - * @var string the user-defined error message. It may contain the following placeholders which + * @var string|null the user-defined error message. It may contain the following placeholders which * will be replaced accordingly by the validator: * * - `{attribute}`: the label of the attribute being validated @@ -145,14 +144,14 @@ class Validator extends Component */ public $enableClientValidation = true; /** - * @var callable a PHP callable that replaces the default implementation of [[isEmpty()]]. + * @var callable|null a PHP callable that replaces the default implementation of [[isEmpty()]]. * If not set, [[isEmpty()]] will be used to check if a value is empty. The signature * of the callable should be `function ($value)` which returns a boolean indicating * whether the value is empty. */ public $isEmpty; /** - * @var callable a PHP callable whose return value determines whether this validator should be applied. + * @var callable|null a PHP callable whose return value determines whether this validator should be applied. * The signature of the callable should be `function ($model, $attribute)`, where `$model` and `$attribute` * refer to the model and the attribute currently being validated. The callable should return a boolean value. * @@ -171,7 +170,7 @@ class Validator extends Component */ public $when; /** - * @var string a JavaScript function name whose return value determines whether this validator should be applied + * @var string|null a JavaScript function name whose return value determines whether this validator should be applied * on the client-side. The signature of the function should be `function (attribute, value)`, where * `attribute` is an object describing the attribute being validated (see [[clientValidateAttribute()]]) * and `value` the current value of the attribute. @@ -272,7 +271,7 @@ public function validateAttributes($model, $attributes = null) * - If this is a string or an array, the intersection of [[getAttributeNames()]] * and the specified attributes will be returned. * - * @return array list of attribute names. + * @return array|null list of attribute names. * @since 2.0.16 */ public function getValidationAttributes($attributes = null) @@ -314,7 +313,7 @@ public function validateAttribute($model, $attribute) * Validates a given value. * You may use this method to validate a value out of the context of a data model. * @param mixed $value the data value to be validated. - * @param string $error the error message to be returned, if the validation fails. + * @param string|null $error the error message to be returned, if the validation fails. * @return bool whether the data is valid. */ public function validate($value, &$error = null) diff --git a/framework/views/errorHandler/error.php b/framework/views/errorHandler/error.php index 9ef6dc7f13d..630bbec034f 100644 --- a/framework/views/errorHandler/error.php +++ b/framework/views/errorHandler/error.php @@ -1,5 +1,5 @@ statusCode; diff --git a/framework/views/errorHandler/exception.php b/framework/views/errorHandler/exception.php index d097a1c92fd..4601e7c42bd 100644 --- a/framework/views/errorHandler/exception.php +++ b/framework/views/errorHandler/exception.php @@ -1,6 +1,6 @@ diff --git a/framework/views/messageConfig.php b/framework/views/messageConfig.php index 2495aed76ad..dc041d2a41a 100644 --- a/framework/views/messageConfig.php +++ b/framework/views/messageConfig.php @@ -5,12 +5,17 @@ 'sourcePath' => __DIR__ . DIRECTORY_SEPARATOR . '..', // array, required, list of language codes that the extracted messages // should be translated to. For example, ['zh-CN', 'de']. - 'languages' => ['de'], + 'languages' => [ + 'af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'he', 'hi', + 'pt-BR', 'ro', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'nb-NO', 'nl', + 'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh-CN', + 'zh-TW' + ], // string, the name of the function for translating messages. // Defaults to 'Yii::t'. This is used as a mark to find the messages to be // translated. You may use a string for single function name or an array for // multiple function names. - 'translator' => 'Yii::t', + 'translator' => ['\Yii::t', 'Yii::t'], // boolean, whether to sort messages by keys when merging new messages // with the existing ones. Defaults to false, which means the new (untranslated) // messages will be separated from the old (translated) ones. @@ -31,15 +36,14 @@ // See helpers/FileHelper::findFiles() for pattern matching rules. // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. 'except' => [ - '.svn', - '.git', - '.gitignore', - '.gitkeep', - '.hgignore', - '.hgkeep', + '.*', + '/.*', '/messages', + '/tests', + '/runtime', + '/vendor', + '/BaseYii.php', ], - // 'php' output format is for saving messages to php files. 'format' => 'php', // Root directory containing message translations. diff --git a/framework/web/Application.php b/framework/web/Application.php index 6a052f19d3d..616bec622ba 100644 --- a/framework/web/Application.php +++ b/framework/web/Application.php @@ -16,13 +16,12 @@ * * For more details and usage information on Application, see the [guide article on applications](guide:structure-applications). * - * @property-read ErrorHandler $errorHandler The error handler application component. This property is - * read-only. + * @property-read ErrorHandler $errorHandler The error handler application component. * @property string $homeUrl The homepage URL. - * @property-read Request $request The request component. This property is read-only. - * @property-read Response $response The response component. This property is read-only. - * @property-read Session $session The session component. This property is read-only. - * @property-read User $user The user component. This property is read-only. + * @property-read Request $request The request component. + * @property-read Response $response The response component. + * @property-read Session $session The session component. + * @property-read User $user The user component. * * @author Qiang Xue * @since 2.0 @@ -34,7 +33,7 @@ class Application extends \yii\base\Application */ public $defaultRoute = 'site'; /** - * @var array the configuration specifying a controller action which should handle + * @var array|null the configuration specifying a controller action which should handle * all user requests. This is mainly used when the application is in maintenance mode * and needs to handle all incoming requests via a single action. * The configuration is an array whose first element specifies the route of the action. diff --git a/framework/web/AssetBundle.php b/framework/web/AssetBundle.php index 60ada80ef3b..4f7f2904e98 100644 --- a/framework/web/AssetBundle.php +++ b/framework/web/AssetBundle.php @@ -16,7 +16,7 @@ * AssetBundle represents a collection of asset files, such as CSS, JS, images. * * Each asset bundle has a unique name that globally identifies it among all asset bundles used in an application. - * The name is the [fully qualified class name](https://secure.php.net/manual/en/language.namespaces.rules.php) + * The name is the [fully qualified class name](https://www.php.net/manual/en/language.namespaces.rules.php) * of the class representing it. * * An asset bundle can depend on other asset bundles. When registering an asset bundle @@ -30,7 +30,7 @@ class AssetBundle extends BaseObject { /** - * @var string the directory that contains the source asset files for this asset bundle. + * @var string|null the directory that contains the source asset files for this asset bundle. * A source asset file is a file that is part of your source code repository of your Web application. * * You must set this property if the directory containing the source asset files is not Web accessible. @@ -40,7 +40,7 @@ class AssetBundle extends BaseObject * If you do not set this property, it means the source asset files are located under [[basePath]]. * * You can use either a directory or an alias of the directory. - * @see $publishOptions + * @see publishOptions */ public $sourcePath; /** @@ -153,22 +153,18 @@ public function registerAssetFiles($view) if (is_array($js)) { $file = array_shift($js); $options = ArrayHelper::merge($this->jsOptions, $js); - $view->registerJsFile($manager->getActualAssetUrl($this, $file), $options); - } else { - if ($js !== null) { - $view->registerJsFile($manager->getActualAssetUrl($this, $js), $this->jsOptions); - } + $view->registerJsFile($manager->getAssetUrl($this, $file, ArrayHelper::getValue($options, 'appendTimestamp')), $options); + } elseif ($js !== null) { + $view->registerJsFile($manager->getAssetUrl($this, $js), $this->jsOptions); } } foreach ($this->css as $css) { if (is_array($css)) { $file = array_shift($css); $options = ArrayHelper::merge($this->cssOptions, $css); - $view->registerCssFile($manager->getActualAssetUrl($this, $file), $options); - } else { - if ($css !== null) { - $view->registerCssFile($manager->getActualAssetUrl($this, $css), $this->cssOptions); - } + $view->registerCssFile($manager->getAssetUrl($this, $file, ArrayHelper::getValue($options, 'appendTimestamp')), $options); + } elseif ($css !== null) { + $view->registerCssFile($manager->getAssetUrl($this, $css), $this->cssOptions); } } } diff --git a/framework/web/AssetConverter.php b/framework/web/AssetConverter.php index 0cfc0d86e52..c748018513a 100644 --- a/framework/web/AssetConverter.php +++ b/framework/web/AssetConverter.php @@ -12,7 +12,7 @@ use yii\base\Exception; /** - * AssetConverter supports conversion of several popular script formats into JS or CSS scripts. + * AssetConverter supports conversion of several popular formats into JS or CSS files. * * It is used by [[AssetManager]] to convert files after they have been published. * @@ -25,6 +25,8 @@ class AssetConverter extends Component implements AssetConverterInterface * @var array the commands that are used to perform the asset conversion. * The keys are the asset file extension names, and the values are the corresponding * target script types (either "css" or "js") and the commands used for the conversion. + * + * The command placeholders: `{from}` - source file, `{to}` - converted file. * * You may also use a [path alias](guide:concept-aliases) to specify the location of the command: * @@ -33,11 +35,15 @@ class AssetConverter extends Component implements AssetConverterInterface * 'styl' => ['css', '@app/node_modules/bin/stylus < {from} > {to}'], * ] * ``` + * + * Note: `Yii::getAlias()` can replace alias at the begin of the command only. + * + * @see https://sass-lang.com/documentation/cli/ SASS/SCSS */ public $commands = [ 'less' => ['css', 'lessc {from} {to} --no-color --source-map'], - 'scss' => ['css', 'sass {from} {to} --sourcemap'], - 'sass' => ['css', 'sass {from} {to} --sourcemap'], + 'scss' => ['css', 'sass --style=compressed {from} {to}'], + 'sass' => ['css', 'sass --style=compressed {from} {to}'], 'styl' => ['css', 'stylus < {from} > {to}'], 'coffee' => ['js', 'coffee -p {from} > {to}'], 'ts' => ['js', 'tsc --out {to} {from}'], diff --git a/framework/web/AssetManager.php b/framework/web/AssetManager.php index 215f5b1ac8d..f4b41b3cf2c 100644 --- a/framework/web/AssetManager.php +++ b/framework/web/AssetManager.php @@ -34,7 +34,7 @@ * For more details and usage information on AssetManager, see the [guide article on assets](guide:structure-assets). * * @property AssetConverterInterface $converter The asset converter. Note that the type of this property - * differs in getter and setter. See [[getConverter()]] and [[setConverter()]] for details. + * differs in getter and setter. See [[getConverter()]] and [[setConverter()]] for details. * * @author Qiang Xue * @since 2.0 @@ -42,7 +42,7 @@ class AssetManager extends Component { /** - * @var array|bool list of asset bundle configurations. This property is provided to customize asset bundles. + * @var array|false list of asset bundle configurations. This property is provided to customize asset bundles. * When a bundle is being loaded by [[getBundle()]], if it has a corresponding configuration specified here, * the configuration will be applied to the bundle. * @@ -74,7 +74,7 @@ class AssetManager extends Component */ public $baseUrl = '@web/assets'; /** - * @var array mapping from source asset files (keys) to target asset files (values). + * @var string[] mapping from source asset files (keys) to target asset files (values). * * This property is provided to support fixing incorrect asset file paths in some asset bundles. * When an asset bundle is registered with a view, each relative asset file in its [[AssetBundle::css|css]] @@ -123,7 +123,7 @@ class AssetManager extends Component */ public $linkAssets = false; /** - * @var int the permission to be set for newly published asset files. + * @var int|null the permission to be set for newly published asset files. * This value will be used by PHP chmod() function. No umask will be applied. * If not set, the permission will be determined by the current environment. */ @@ -136,7 +136,7 @@ class AssetManager extends Component */ public $dirMode = 0775; /** - * @var callback a PHP callback that is called before copying each sub-directory or file. + * @var callable|null a PHP callback that is called before copying each sub-directory or file. * This option is used only when publishing a directory. If the callback returns false, the copy * operation for the sub-directory or file will be cancelled. * @@ -147,7 +147,7 @@ class AssetManager extends Component */ public $beforeCopy; /** - * @var callback a PHP callback that is called after a sub-directory or file is successfully copied. + * @var callable|null a PHP callback that is called after a sub-directory or file is successfully copied. * This option is used only when publishing a directory. The signature of the callback is the same as * for [[beforeCopy]]. * This is passed as a parameter `afterCopy` to [[\yii\helpers\FileHelper::copyDirectory()]]. @@ -171,7 +171,7 @@ class AssetManager extends Component */ public $appendTimestamp = false; /** - * @var callable a callback that will be called to produce hash for asset directory generation. + * @var callable|null a callback that will be called to produce hash for asset directory generation. * The signature of the callback should be as follows: * * ``` @@ -198,6 +198,9 @@ class AssetManager extends Component */ public $hashCallback; + /** + * @var array + */ private $_dummyBundles = []; @@ -209,12 +212,37 @@ public function init() { parent::init(); $this->basePath = Yii::getAlias($this->basePath); + + $this->basePath = realpath($this->basePath); + $this->baseUrl = rtrim(Yii::getAlias($this->baseUrl), '/'); + } + + /** + * @var bool|null + */ + private $_isBasePathPermissionChecked; + + /** + * Check whether the basePath exists and is writeable. + * + * @since 2.0.40 + */ + public function checkBasePathPermission() + { + // if the check is been done already, skip further checks + if ($this->_isBasePathPermissionChecked) { + return; + } + if (!is_dir($this->basePath)) { throw new InvalidConfigException("The directory does not exist: {$this->basePath}"); } - $this->basePath = realpath($this->basePath); - $this->baseUrl = rtrim(Yii::getAlias($this->baseUrl), '/'); + if (!is_writable($this->basePath)) { + throw new InvalidConfigException("The directory is not writable by the Web process: {$this->basePath}"); + } + + $this->_isBasePathPermissionChecked = true; } /** @@ -294,14 +322,20 @@ protected function loadDummyBundle($name) * The actual URL is obtained by prepending either [[AssetBundle::$baseUrl]] or [[AssetManager::$baseUrl]] to the given asset path. * @param AssetBundle $bundle the asset bundle which the asset file belongs to * @param string $asset the asset path. This should be one of the assets listed in [[AssetBundle::$js]] or [[AssetBundle::$css]]. + * @param bool|null $appendTimestamp Whether to append timestamp to the URL. * @return string the actual URL for the specified asset. */ - public function getAssetUrl($bundle, $asset) + public function getAssetUrl($bundle, $asset, $appendTimestamp = null) { $assetUrl = $this->getActualAssetUrl($bundle, $asset); $assetPath = $this->getAssetPath($bundle, $asset); - if ($this->appendTimestamp && $assetPath && ($timestamp = @filemtime($assetPath)) > 0) { + $withTimestamp = $this->appendTimestamp; + if ($appendTimestamp !== null) { + $withTimestamp = $appendTimestamp; + } + + if ($withTimestamp && $assetPath && ($timestamp = @filemtime($assetPath)) > 0) { return "$assetUrl?v=$timestamp"; } @@ -326,7 +360,7 @@ public function getAssetPath($bundle, $asset) /** * @param AssetBundle $bundle * @param string $asset - * @return string|bool + * @return string|false */ protected function resolveAsset($bundle, $asset) { @@ -348,6 +382,9 @@ protected function resolveAsset($bundle, $asset) return false; } + /** + * @var AssetConverterInterface + */ private $_converter; /** @@ -439,10 +476,6 @@ public function publish($path, $options = []) throw new InvalidArgumentException("The file or directory to be published does not exist: $path"); } - if (!is_writable($this->basePath)) { - throw new InvalidConfigException("The directory is not writable by the Web process: {$this->basePath}"); - } - if (is_file($src)) { return $this->_published[$path] = $this->publishFile($src); } @@ -458,6 +491,8 @@ public function publish($path, $options = []) */ protected function publishFile($src) { + $this->checkBasePathPermission(); + $dir = $this->hash($src); $fileName = basename($src); $dstDir = $this->basePath . DIRECTORY_SEPARATOR . $dir; @@ -513,6 +548,8 @@ protected function publishFile($src) */ protected function publishDirectory($src, $options) { + $this->checkBasePathPermission(); + $dir = $this->hash($src); $dstDir = $this->basePath . DIRECTORY_SEPARATOR . $dir; if ($this->linkAssets) { diff --git a/framework/web/BadRequestHttpException.php b/framework/web/BadRequestHttpException.php index 08f73826808..7b0c601b77c 100644 --- a/framework/web/BadRequestHttpException.php +++ b/framework/web/BadRequestHttpException.php @@ -23,11 +23,11 @@ class BadRequestHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(400, $message, $code, $previous); } diff --git a/framework/web/CacheSession.php b/framework/web/CacheSession.php index ecb14b782a1..1fc83c8570c 100644 --- a/framework/web/CacheSession.php +++ b/framework/web/CacheSession.php @@ -31,7 +31,7 @@ * ] * ``` * - * @property-read bool $useCustomStorage Whether to use custom storage. This property is read-only. + * @property-read bool $useCustomStorage Whether to use custom storage. * * @author Qiang Xue * @since 2.0 diff --git a/framework/web/CompositeUrlRule.php b/framework/web/CompositeUrlRule.php index d707c64ccc4..541e95daa4c 100644 --- a/framework/web/CompositeUrlRule.php +++ b/framework/web/CompositeUrlRule.php @@ -14,7 +14,7 @@ * CompositeUrlRule is the base class for URL rule classes that consist of multiple simpler rules. * * @property-read null|int $createUrlStatus Status of the URL creation after the last [[createUrl()]] call. - * `null` if rule does not provide info about create status. This property is read-only. + * `null` if rule does not provide info about create status. * * @author Qiang Xue * @since 2.0 @@ -130,10 +130,10 @@ protected function iterateRules($rules, $manager, $route, $params) * For multiple rules statuses will be combined by bitwise `or` operator * (e.g. `UrlRule::CREATE_STATUS_PARSING_ONLY | UrlRule::CREATE_STATUS_PARAMS_MISMATCH`). * - * @return null|int Status of the URL creation after the last [[createUrl()]] call. `null` if rule does not provide + * @return int|null Status of the URL creation after the last [[createUrl()]] call. `null` if rule does not provide * info about create status. - * @see $createStatus - * @see https://secure.php.net/manual/en/language.operators.bitwise.php + * @see createStatus + * @see https://www.php.net/manual/en/language.operators.bitwise.php * @since 2.0.12 */ public function getCreateUrlStatus() diff --git a/framework/web/ConflictHttpException.php b/framework/web/ConflictHttpException.php index 2e5c99da140..d3fd07c8e71 100644 --- a/framework/web/ConflictHttpException.php +++ b/framework/web/ConflictHttpException.php @@ -18,11 +18,11 @@ class ConflictHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(409, $message, $code, $previous); } diff --git a/framework/web/Controller.php b/framework/web/Controller.php index 4e205d00eb6..bce99aafb3e 100644 --- a/framework/web/Controller.php +++ b/framework/web/Controller.php @@ -142,37 +142,51 @@ public function bindActionParams($action, $params) } elseif (is_array($params[$name])) { $isValid = false; } elseif ( - PHP_VERSION_ID >= 70000 && - ($type = $param->getType()) !== null && - $type->isBuiltin() && - ($params[$name] !== null || !$type->allowsNull()) + PHP_VERSION_ID >= 70000 + && ($type = $param->getType()) !== null + && $type->isBuiltin() + && ($params[$name] !== null || !$type->allowsNull()) ) { $typeName = PHP_VERSION_ID >= 70100 ? $type->getName() : (string)$type; - switch ($typeName) { - case 'int': - $params[$name] = filter_var($params[$name], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); - break; - case 'float': - $params[$name] = filter_var($params[$name], FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE); - break; - case 'bool': - $params[$name] = filter_var($params[$name], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); - break; - } - if ($params[$name] === null) { - $isValid = false; + + if ($params[$name] === '' && $type->allowsNull()) { + if ($typeName !== 'string') { // for old string behavior compatibility + $params[$name] = null; + } + } else { + switch ($typeName) { + case 'int': + $params[$name] = filter_var($params[$name], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); + break; + case 'float': + $params[$name] = filter_var($params[$name], FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE); + break; + case 'bool': + $params[$name] = filter_var($params[$name], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + break; + } + if ($params[$name] === null) { + $isValid = false; + } } } if (!$isValid) { - throw new BadRequestHttpException(Yii::t('yii', 'Invalid data received for parameter "{param}".', [ - 'param' => $name, - ])); + throw new BadRequestHttpException( + Yii::t('yii', 'Invalid data received for parameter "{param}".', ['param' => $name]) + ); } $args[] = $actionParams[$name] = $params[$name]; unset($params[$name]); - } elseif (PHP_VERSION_ID >= 70100 && ($type = $param->getType()) !== null && !$type->isBuiltin()) { + } elseif ( + PHP_VERSION_ID >= 70100 + && ($type = $param->getType()) !== null + && $type instanceof \ReflectionNamedType + && !$type->isBuiltin() + ) { try { $this->bindInjectedParams($type, $name, $args, $requestedParams); + } catch (HttpException $e) { + throw $e; } catch (Exception $e) { throw new ServerErrorHttpException($e->getMessage(), 0, $e); } @@ -184,16 +198,16 @@ public function bindActionParams($action, $params) } if (!empty($missing)) { - throw new BadRequestHttpException(Yii::t('yii', 'Missing required parameters: {params}', [ - 'params' => implode(', ', $missing), - ])); + throw new BadRequestHttpException( + Yii::t('yii', 'Missing required parameters: {params}', ['params' => implode(', ', $missing)]) + ); } $this->actionParams = $actionParams; // We use a different array here, specifically one that doesn't contain service instances but descriptions instead. - if (\Yii::$app->requestedParams === null) { - \Yii::$app->requestedParams = array_merge($actionParams, $requestedParams); + if (Yii::$app->requestedParams === null) { + Yii::$app->requestedParams = array_merge($actionParams, $requestedParams); } return $args; @@ -276,7 +290,7 @@ public function goHome() * * For this function to work you have to [[User::setReturnUrl()|set the return URL]] in appropriate places before. * - * @param string|array $defaultUrl the default return URL in case it was not set previously. + * @param string|array|null $defaultUrl the default return URL in case it was not set previously. * If this is null and the return URL was not set previously, [[Application::homeUrl]] will be redirected to. * Please refer to [[User::setReturnUrl()]] on accepted format of the URL. * @return Response the current response object diff --git a/framework/web/Cookie.php b/framework/web/Cookie.php index f517ca3e09f..434e5cdf299 100644 --- a/framework/web/Cookie.php +++ b/framework/web/Cookie.php @@ -22,7 +22,7 @@ class Cookie extends \yii\base\BaseObject * during CSRF-prone request methods (e.g. POST, PUT, PATCH etc). * E.g. a POST request from https://otherdomain.com to https://yourdomain.com will not include the cookie, however a GET request will. * When a user follows a link from https://otherdomain.com to https://yourdomain.com it will include the cookie - * @see $sameSite + * @see sameSite */ const SAME_SITE_LAX = 'Lax'; /** @@ -30,9 +30,19 @@ class Cookie extends \yii\base\BaseObject * regardless of the request method and even when following a regular link. * E.g. a GET request from https://otherdomain.com to https://yourdomain.com or a user following a link from * https://otherdomain.com to https://yourdomain.com will not include the cookie. - * @see $sameSite + * @see sameSite */ const SAME_SITE_STRICT = 'Strict'; + /** + * SameSite policy None disables the SameSite policy so cookies will be sent in all contexts, + * i.e in responses to both first-party and cross-origin requests. + * E.g. a POST request from https://otherdomain.com to https://yourdomain.com will include the cookie. + * Note: If `sameSite` is set to None, the `secure` attribute must be set to `true` (otherwise the cookie will be blocked by the browser). + * @see sameSite + * @see secure + * @since 2.0.43 + */ + const SAME_SITE_NONE = 'None'; /** * @var string name of the cookie @@ -67,17 +77,12 @@ class Cookie extends \yii\base\BaseObject public $httpOnly = true; /** * @var string SameSite prevents the browser from sending this cookie along with cross-site requests. - * Please note that this feature is only supported since PHP 7.3.0 - * For better security, an exception will be thrown if `sameSite` is set while using an unsupported version of PHP. - * To use this feature across different PHP versions check the version first. E.g. - * ```php - * $cookie->sameSite = PHP_VERSION_ID >= 70300 ? yii\web\Cookie::SAME_SITE_LAX : null, - * ``` - * See https://www.owasp.org/index.php/SameSite for more information about sameSite. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite for more information about sameSite. * * @since 2.0.21 */ - public $sameSite; + public $sameSite = self::SAME_SITE_LAX; /** diff --git a/framework/web/CookieCollection.php b/framework/web/CookieCollection.php index c26cfd35445..7ec65d68cb4 100644 --- a/framework/web/CookieCollection.php +++ b/framework/web/CookieCollection.php @@ -17,9 +17,8 @@ * * For more details and usage information on CookieCollection, see the [guide article on handling cookies](guide:runtime-sessions-cookies). * - * @property-read int $count The number of cookies in the collection. This property is read-only. - * @property-read ArrayIterator $iterator An iterator for traversing the cookies in the collection. This - * property is read-only. + * @property-read int $count The number of cookies in the collection. + * @property-read ArrayIterator $iterator An iterator for traversing the cookies in the collection. * * @author Qiang Xue * @since 2.0 @@ -55,6 +54,7 @@ public function __construct($cookies = [], $config = []) * It will be implicitly called when you use `foreach` to traverse the collection. * @return ArrayIterator an iterator for traversing the cookies in the collection. */ + #[\ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($this->_cookies); @@ -66,6 +66,7 @@ public function getIterator() * It will be implicitly called when you use `count($collection)`. * @return int the number of cookies in the collection. */ + #[\ReturnTypeWillChange] public function count() { return $this->getCount(); @@ -83,7 +84,7 @@ public function getCount() /** * Returns the cookie with the specified name. * @param string $name the cookie name - * @return Cookie the cookie with the specified name. Null if the named cookie does not exist. + * @return Cookie|null the cookie with the specified name. Null if the named cookie does not exist. * @see getValue() */ public function get($name) @@ -105,7 +106,7 @@ public function getValue($name, $defaultValue = null) /** * Returns whether there is a cookie with the specified name. - * Note that if a cookie is marked for deletion from browser, this method will return false. + * Note that if a cookie is marked for deletion from browser or its value is an empty string, this method will return false. * @param string $name the cookie name * @return bool whether the named cookie exists * @see remove() @@ -199,6 +200,7 @@ public function fromArray(array $array) * @param string $name the cookie name * @return bool whether the named cookie exists */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return $this->has($name); @@ -210,8 +212,9 @@ public function offsetExists($name) * It is implicitly called when you use something like `$cookie = $collection[$name];`. * This is equivalent to [[get()]]. * @param string $name the cookie name - * @return Cookie the cookie with the specified name, null if the named cookie does not exist. + * @return Cookie|null the cookie with the specified name, null if the named cookie does not exist. */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->get($name); @@ -225,6 +228,7 @@ public function offsetGet($name) * @param string $name the cookie name * @param Cookie $cookie the cookie to be added */ + #[\ReturnTypeWillChange] public function offsetSet($name, $cookie) { $this->add($cookie); @@ -237,6 +241,7 @@ public function offsetSet($name, $cookie) * This is equivalent to [[remove()]]. * @param string $name the cookie name */ + #[\ReturnTypeWillChange] public function offsetUnset($name) { $this->remove($name); diff --git a/framework/web/DbSession.php b/framework/web/DbSession.php index bc23f660660..73a29bf3bd5 100644 --- a/framework/web/DbSession.php +++ b/framework/web/DbSession.php @@ -104,7 +104,7 @@ public function openSession($savePath, $sessionName) { if ($this->getUseStrictMode()) { $id = $this->getId(); - if (!$this->getReadQuery($id)->exists()) { + if (!$this->getReadQuery($id)->exists($this->db)) { //This session id does not exist, mark it for forced regeneration $this->_forceRegenerateId = $id; } @@ -140,7 +140,7 @@ public function regenerateID($deleteOldSession = false) ->queryOne(); }); - if ($row !== false) { + if ($row !== false && $this->getIsActive()) { if ($deleteOldSession) { $this->db->createCommand() ->update($this->sessionTable, ['id' => $newID], ['id' => $oldID]) @@ -151,11 +151,6 @@ public function regenerateID($deleteOldSession = false) ->insert($this->sessionTable, $row) ->execute(); } - } else { - // shouldn't reach here normally - $this->db->createCommand() - ->insert($this->sessionTable, $this->composeFields($newID, '')) - ->execute(); } } @@ -206,7 +201,7 @@ public function writeSession($id, $data) } // exception must be caught in session write handler - // https://secure.php.net/manual/en/function.session-set-save-handler.php#refsect1-function.session-set-save-handler-notes + // https://www.php.net/manual/en/function.session-set-save-handler.php#refsect1-function.session-set-save-handler-notes try { // ensure backwards compatability (fixed #9438) if ($this->writeCallback && !$this->fields) { diff --git a/framework/web/ErrorAction.php b/framework/web/ErrorAction.php index 81f06b643f7..dde5611b5c3 100644 --- a/framework/web/ErrorAction.php +++ b/framework/web/ErrorAction.php @@ -51,7 +51,7 @@ class ErrorAction extends Action { /** - * @var string the view file to be rendered. If not set, it will take the value of [[id]]. + * @var string|null the view file to be rendered. If not set, it will take the value of [[id]]. * That means, if you name the action as "error" in "SiteController", then the view name * would be "error", and the corresponding view file would be "views/site/error.php". */ @@ -67,7 +67,7 @@ class ErrorAction extends Action */ public $defaultMessage; /** - * @var string|false|null the name of the layout to be applied to this error action view. + * @var string|null|false the name of the layout to be applied to this error action view. * If not set, the layout configured in the controller will be used. * @see \yii\base\Controller::$layout * @since 2.0.14 @@ -75,8 +75,8 @@ class ErrorAction extends Action public $layout; /** - * @var \Exception the exception object, normally is filled on [[init()]] method call. - * @see [[findException()]] to know default way of obtaining exception. + * @var \Throwable the exception object, normally is filled on [[init()]] method call. + * @see findException() to know default way of obtaining exception. * @since 2.0.11 */ protected $exception; @@ -157,7 +157,7 @@ protected function getViewRenderParams() * Gets exception from the [[yii\web\ErrorHandler|ErrorHandler]] component. * In case there is no exception in the component, treat as the action has been invoked * not from error handler, but by direct route, so '404 Not Found' error will be displayed. - * @return \Exception + * @return \Throwable * @since 2.0.11 */ protected function findException() diff --git a/framework/web/ErrorHandler.php b/framework/web/ErrorHandler.php index 8c9ee2728f9..2600a8b51a0 100644 --- a/framework/web/ErrorHandler.php +++ b/framework/web/ErrorHandler.php @@ -39,7 +39,7 @@ class ErrorHandler extends \yii\base\ErrorHandler */ public $maxTraceSourceLines = 13; /** - * @var string the route (e.g. `site/error`) to the controller action that will be used + * @var string|null the route (e.g. `site/error`) to the controller action that will be used * to display external errors. Inside the action, it can retrieve the error information * using `Yii::$app->errorHandler->exception`. This property defaults to null, meaning ErrorHandler * will handle the error display. @@ -84,7 +84,7 @@ class ErrorHandler extends \yii\base\ErrorHandler /** * Renders the exception. - * @param \Exception|\Error $exception the exception to be rendered. + * @param \Throwable $exception the exception to be rendered. */ protected function renderException($exception) { @@ -138,7 +138,7 @@ protected function renderException($exception) /** * Converts an exception into an array. - * @param \Exception|\Error $exception the exception being converted + * @param \Throwable $exception the exception being converted * @return array the array representation of the exception. */ protected function convertExceptionToArray($exception) @@ -180,7 +180,7 @@ protected function convertExceptionToArray($exception) */ public function htmlEncode($text) { - return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); + return htmlspecialchars($text, ENT_NOQUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8'); } /** @@ -272,7 +272,7 @@ public function renderFile($_file_, $_params_) /** * Renders the previous exception stack for a given Exception. - * @param \Exception $exception the exception whose precursors should be rendered. + * @param \Throwable $exception the exception whose precursors should be rendered. * @return string HTML content of the rendered previous exceptions. * Empty string if there are none. */ @@ -326,7 +326,7 @@ public function renderCallStackItem($file, $line, $class, $method, $args, $index /** * Renders call stack. - * @param \Exception|\ParseError $exception exception to get call stack from + * @param \Throwable $exception exception to get call stack from * @return string HTML content of the rendered call stack. * @since 2.0.12 */ @@ -401,7 +401,7 @@ public function createServerInformationLink() 'http://lighttpd.net/' => ['lighttpd'], 'http://gwan.com/' => ['g-wan', 'gwan'], 'http://iis.net/' => ['iis', 'services'], - 'https://secure.php.net/manual/en/features.commandline.webserver.php' => ['development'], + 'https://www.php.net/manual/en/features.commandline.webserver.php' => ['development'], ]; if (isset($_SERVER['SERVER_SOFTWARE'])) { foreach ($serverUrls as $url => $keywords) { @@ -482,7 +482,7 @@ public function argumentsToString($args) /** * Returns human-readable exception name. - * @param \Exception $exception + * @param \Throwable $exception * @return string|null human-readable exception name or null if it cannot be determined */ public function getExceptionName($exception) diff --git a/framework/web/ForbiddenHttpException.php b/framework/web/ForbiddenHttpException.php index 51e0ff71aac..81e1cf02060 100644 --- a/framework/web/ForbiddenHttpException.php +++ b/framework/web/ForbiddenHttpException.php @@ -23,11 +23,11 @@ class ForbiddenHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(403, $message, $code, $previous); } diff --git a/framework/web/GoneHttpException.php b/framework/web/GoneHttpException.php index ad736ac50ea..a03a1bb0dcb 100644 --- a/framework/web/GoneHttpException.php +++ b/framework/web/GoneHttpException.php @@ -23,11 +23,11 @@ class GoneHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(410, $message, $code, $previous); } diff --git a/framework/web/GroupUrlRule.php b/framework/web/GroupUrlRule.php index 4ce3b19a141..e2f67da3120 100644 --- a/framework/web/GroupUrlRule.php +++ b/framework/web/GroupUrlRule.php @@ -60,7 +60,7 @@ class GroupUrlRule extends CompositeUrlRule */ public $prefix; /** - * @var string the prefix for the route part of every rule declared in [[rules]]. + * @var string|null the prefix for the route part of every rule declared in [[rules]]. * The prefix and the route will be separated with a slash. * If this property is not set, it will take the value of [[prefix]]. */ @@ -77,7 +77,7 @@ class GroupUrlRule extends CompositeUrlRule */ public function init() { - $this->prefix = trim($this->prefix, '/'); + $this->prefix = trim((string)$this->prefix, '/'); $this->routePrefix = $this->routePrefix === null ? $this->prefix : trim($this->routePrefix, '/'); parent::init(); } diff --git a/framework/web/HeaderCollection.php b/framework/web/HeaderCollection.php index 1fa6021f7b4..855d0240e3a 100644 --- a/framework/web/HeaderCollection.php +++ b/framework/web/HeaderCollection.php @@ -13,9 +13,8 @@ /** * HeaderCollection is used by [[Response]] to maintain the currently registered HTTP headers. * - * @property-read int $count The number of headers in the collection. This property is read-only. - * @property-read \ArrayIterator $iterator An iterator for traversing the headers in the collection. This - * property is read-only. + * @property-read int $count The number of headers in the collection. + * @property-read \ArrayIterator $iterator An iterator for traversing the headers in the collection. * * @author Qiang Xue * @since 2.0 @@ -23,9 +22,13 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayAccess, \Countable { /** - * @var array the headers in this collection (indexed by the header names) + * @var array the headers in this collection (indexed by the normalized header names) */ private $_headers = []; + /** + * @var array the original names of the headers (indexed by the normalized header names) + */ + private $_originalHeaderNames = []; /** @@ -34,6 +37,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * It will be implicitly called when you use `foreach` to traverse the collection. * @return \ArrayIterator an iterator for traversing the headers in the collection. */ + #[\ReturnTypeWillChange] public function getIterator() { return new \ArrayIterator($this->_headers); @@ -45,6 +49,7 @@ public function getIterator() * It will be implicitly called when you use `count($collection)`. * @return int the number of headers in the collection. */ + #[\ReturnTypeWillChange] public function count() { return $this->getCount(); @@ -54,6 +59,7 @@ public function count() * Returns the number of headers in the collection. * @return int the number of headers in the collection. */ + #[\ReturnTypeWillChange] public function getCount() { return count($this->_headers); @@ -65,14 +71,14 @@ public function getCount() * @param mixed $default the value to return in case the named header does not exist * @param bool $first whether to only return the first header of the specified name. * If false, all headers of the specified name will be returned. - * @return string|array the named header(s). If `$first` is true, a string will be returned; + * @return string|array|null the named header(s). If `$first` is true, a string will be returned; * If `$first` is false, an array will be returned. */ public function get($name, $default = null, $first = true) { - $name = strtolower($name); - if (isset($this->_headers[$name])) { - return $first ? reset($this->_headers[$name]) : $this->_headers[$name]; + $normalizedName = strtolower($name); + if (isset($this->_headers[$normalizedName])) { + return $first ? reset($this->_headers[$normalizedName]) : $this->_headers[$normalizedName]; } return $default; @@ -87,8 +93,9 @@ public function get($name, $default = null, $first = true) */ public function set($name, $value = '') { - $name = strtolower($name); - $this->_headers[$name] = (array) $value; + $normalizedName = strtolower($name); + $this->_headers[$normalizedName] = (array) $value; + $this->_originalHeaderNames[$normalizedName] = $name; return $this; } @@ -103,8 +110,11 @@ public function set($name, $value = '') */ public function add($name, $value) { - $name = strtolower($name); - $this->_headers[$name][] = $value; + $normalizedName = strtolower($name); + $this->_headers[$normalizedName][] = $value; + if (!\array_key_exists($normalizedName, $this->_originalHeaderNames)) { + $this->_originalHeaderNames[$normalizedName] = $name; + } return $this; } @@ -118,9 +128,10 @@ public function add($name, $value) */ public function setDefault($name, $value) { - $name = strtolower($name); - if (empty($this->_headers[$name])) { - $this->_headers[$name][] = $value; + $normalizedName = strtolower($name); + if (empty($this->_headers[$normalizedName])) { + $this->_headers[$normalizedName][] = $value; + $this->_originalHeaderNames[$normalizedName] = $name; } return $this; @@ -133,22 +144,20 @@ public function setDefault($name, $value) */ public function has($name) { - $name = strtolower($name); - - return isset($this->_headers[$name]); + return isset($this->_headers[strtolower($name)]); } /** * Removes a header. * @param string $name the name of the header to be removed. - * @return array the value of the removed header. Null is returned if the header does not exist. + * @return array|null the value of the removed header. Null is returned if the header does not exist. */ public function remove($name) { - $name = strtolower($name); - if (isset($this->_headers[$name])) { - $value = $this->_headers[$name]; - unset($this->_headers[$name]); + $normalizedName = strtolower($name); + if (isset($this->_headers[$normalizedName])) { + $value = $this->_headers[$normalizedName]; + unset($this->_headers[$normalizedName], $this->_originalHeaderNames[$normalizedName]); return $value; } @@ -161,6 +170,7 @@ public function remove($name) public function removeAll() { $this->_headers = []; + $this->_originalHeaderNames = []; } /** @@ -173,6 +183,19 @@ public function toArray() return $this->_headers; } + /** + * Returns the collection as a PHP array but instead of using normalized header names as keys (like [[toArray()]]) + * it uses original header names (case-sensitive). + * @return array the array representation of the collection. + * @since 2.0.45 + */ + public function toOriginalArray() + { + return \array_map(function ($normalizedName) { + return $this->_headers[$normalizedName]; + }, \array_flip($this->_originalHeaderNames)); + } + /** * Populates the header collection from an array. * @param array $array the headers to populate from @@ -180,7 +203,9 @@ public function toArray() */ public function fromArray(array $array) { - $this->_headers = $array; + foreach ($array as $name => $value) { + $this->set($name, $value); + } } /** @@ -190,6 +215,7 @@ public function fromArray(array $array) * @param string $name the header name * @return bool whether the named header exists */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return $this->has($name); @@ -201,8 +227,9 @@ public function offsetExists($name) * It is implicitly called when you use something like `$header = $collection[$name];`. * This is equivalent to [[get()]]. * @param string $name the header name - * @return string the header value with the specified name, null if the named header does not exist. + * @return string|null the header value with the specified name, null if the named header does not exist. */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->get($name); @@ -216,6 +243,7 @@ public function offsetGet($name) * @param string $name the header name * @param string $value the header value to be added */ + #[\ReturnTypeWillChange] public function offsetSet($name, $value) { $this->set($name, $value); @@ -228,6 +256,7 @@ public function offsetSet($name, $value) * This is equivalent to [[remove()]]. * @param string $name the header name */ + #[\ReturnTypeWillChange] public function offsetUnset($name) { $this->remove($name); diff --git a/framework/web/HttpException.php b/framework/web/HttpException.php index f7f6ac5a1c3..15d75e8544f 100644 --- a/framework/web/HttpException.php +++ b/framework/web/HttpException.php @@ -38,14 +38,14 @@ class HttpException extends UserException /** * Constructor. * @param int $status HTTP status code, such as 404, 500, etc. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($status, $message = null, $code = 0, \Exception $previous = null) + public function __construct($status, $message = null, $code = 0, $previous = null) { $this->statusCode = $status; - parent::__construct($message, $code, $previous); + parent::__construct((string)$message, $code, $previous); } /** diff --git a/framework/web/IdentityInterface.php b/framework/web/IdentityInterface.php index 849131ba517..737a0242baa 100644 --- a/framework/web/IdentityInterface.php +++ b/framework/web/IdentityInterface.php @@ -43,6 +43,13 @@ * } * ``` * + * In some situations not all of these methods are required to be implemented. + * For example, if your application is a pure stateless RESTful application, + * you would only need to implement [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] + * and [[yii\web\IdentityInterface::getId()|getId()]] while leaving all other methods with an empty body. + * Or if your application uses session only authentication, you would need to implement all the methods + * except [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]. + * * @author Qiang Xue * @since 2.0 */ @@ -82,13 +89,12 @@ public function getId(); * * The space of such keys should be big enough to defeat potential identity attacks. * - * This is required if [[User::enableAutoLogin]] is enabled. The returned key will be stored on the - * client side as a cookie and will be used to authenticate user even if PHP session has been expired. + * The returned key is used to validate session and auto-login (if [[User::enableAutoLogin]] is enabled). * * Make sure to invalidate earlier issued authKeys when you implement force user logout, password change and * other scenarios, that require forceful access revocation for old sessions. * - * @return string a key that is used to check the validity of a given identity ID. + * @return string|null a key that is used to check the validity of a given identity ID. * @see validateAuthKey() */ public function getAuthKey(); @@ -96,9 +102,8 @@ public function getAuthKey(); /** * Validates the given auth key. * - * This is required if [[User::enableAutoLogin]] is enabled. * @param string $authKey the given auth key - * @return bool whether the given auth key is valid. + * @return bool|null whether the given auth key is valid. * @see getAuthKey() */ public function validateAuthKey($authKey); diff --git a/framework/web/JsExpression.php b/framework/web/JsExpression.php index 2b8bd5650b6..83c76abf8f8 100644 --- a/framework/web/JsExpression.php +++ b/framework/web/JsExpression.php @@ -10,9 +10,9 @@ use yii\base\BaseObject; /** - * JsExpression marks a string as a JavaScript expression. + * `JsExpression` marks a string as a JavaScript expression. * - * When using [[\yii\helpers\Json::encode()]] or [[\yii\helpers\Json::htmlEncode()]] to encode a value, JsonExpression objects + * When using [[\yii\helpers\Json::encode()]] or [[\yii\helpers\Json::htmlEncode()]] to encode a value, `JsExpression` objects * will be specially handled and encoded as a JavaScript expression instead of a string. * * @author Qiang Xue @@ -43,6 +43,6 @@ public function __construct($expression, $config = []) */ public function __toString() { - return $this->expression; + return (string) $this->expression; } } diff --git a/framework/web/JsonParser.php b/framework/web/JsonParser.php index d741ba73744..94353fb5626 100644 --- a/framework/web/JsonParser.php +++ b/framework/web/JsonParser.php @@ -33,7 +33,7 @@ class JsonParser implements RequestParserInterface */ public $asArray = true; /** - * @var bool whether to throw a [[BadRequestHttpException]] if the body is invalid json + * @var bool whether to throw a [[BadRequestHttpException]] if the body is invalid JSON */ public $throwException = true; @@ -42,11 +42,16 @@ class JsonParser implements RequestParserInterface * Parses a HTTP request body. * @param string $rawBody the raw HTTP request body. * @param string $contentType the content type specified for the request body. - * @return array parameters parsed from the request body + * @return array|\stdClass parameters parsed from the request body * @throws BadRequestHttpException if the body contains invalid json and [[throwException]] is `true`. */ public function parse($rawBody, $contentType) { + // converts JSONP to JSON + if (strpos($contentType, 'application/javascript') !== false) { + $rawBody = preg_filter('/(^[^{]+|[^}]+$)/', '', $rawBody); + } + try { $parameters = Json::decode($rawBody, $this->asArray); return $parameters === null ? [] : $parameters; diff --git a/framework/web/JsonResponseFormatter.php b/framework/web/JsonResponseFormatter.php index cb847c36e8d..2e64740990a 100644 --- a/framework/web/JsonResponseFormatter.php +++ b/framework/web/JsonResponseFormatter.php @@ -26,6 +26,7 @@ * \yii\web\Response::FORMAT_JSON => [ * 'class' => 'yii\web\JsonResponseFormatter', * 'prettyPrint' => YII_DEBUG, // use "pretty" output in debug mode + * 'keepObjectType' => false, // keep object type for zero-indexed objects * // ... * ], * ], @@ -67,7 +68,7 @@ class JsonResponseFormatter extends Component implements ResponseFormatterInterf public $useJsonp = false; /** * @var int the encoding options passed to [[Json::encode()]]. For more details please refer to - * . + * . * Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`. * This property has no effect, when [[useJsonp]] is `true`. * @since 2.0.7 @@ -81,6 +82,13 @@ class JsonResponseFormatter extends Component implements ResponseFormatterInterf * @since 2.0.7 */ public $prettyPrint = false; + /** + * @var bool Avoids objects with zero-indexed keys to be encoded as array + * Json::encode((object)['test']) will be encoded as an object not array. This matches the behaviour of json_encode(). + * Defaults to Json::$keepObjectType value + * @since 2.0.44 + */ + public $keepObjectType; /** @@ -97,7 +105,7 @@ public function format($response) $this->contentType .= '; charset=UTF-8'; } $response->getHeaders()->set('Content-Type', $this->contentType); - + if ($this->useJsonp) { $this->formatJsonp($response); } else { @@ -116,7 +124,16 @@ protected function formatJson($response) if ($this->prettyPrint) { $options |= JSON_PRETTY_PRINT; } + + $default = Json::$keepObjectType; + if ($this->keepObjectType !== null) { + Json::$keepObjectType = $this->keepObjectType; + } + $response->content = Json::encode($response->data, $options); + + // Restore default value to avoid any unexpected behaviour + Json::$keepObjectType = $default; } elseif ($response->content === null) { $response->content = 'null'; } diff --git a/framework/web/MethodNotAllowedHttpException.php b/framework/web/MethodNotAllowedHttpException.php index 4241e7618db..832641e31f1 100644 --- a/framework/web/MethodNotAllowedHttpException.php +++ b/framework/web/MethodNotAllowedHttpException.php @@ -18,11 +18,11 @@ class MethodNotAllowedHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(405, $message, $code, $previous); } diff --git a/framework/web/MultiFieldSession.php b/framework/web/MultiFieldSession.php index 1b73e6d583e..9b9f9a0a881 100644 --- a/framework/web/MultiFieldSession.php +++ b/framework/web/MultiFieldSession.php @@ -22,7 +22,7 @@ * While extending this class you should use [[composeFields()]] method - while writing the session data into the storage and * [[extractData()]] - while reading session data from the storage. * - * @property-read bool $useCustomStorage Whether to use custom storage. This property is read-only. + * @property-read bool $useCustomStorage Whether to use custom storage. * * @author Paul Klimov * @since 2.0.6 @@ -89,8 +89,8 @@ public function getUseCustomStorage() /** * Composes storage field set for session writing. - * @param string $id Optional session id - * @param string $data Optional session data + * @param string|null $id Optional session id + * @param string|null $data Optional session data * @return array storage fields */ protected function composeFields($id = null, $data = null) diff --git a/framework/web/MultipartFormDataParser.php b/framework/web/MultipartFormDataParser.php index c6f8c8ccaa6..9cfac9b1996 100644 --- a/framework/web/MultipartFormDataParser.php +++ b/framework/web/MultipartFormDataParser.php @@ -109,7 +109,7 @@ public function setUploadFileMaxSize($uploadFileMaxSize) public function getUploadFileMaxCount() { if ($this->_uploadFileMaxCount === null) { - $this->_uploadFileMaxCount = ini_get('max_file_uploads'); + $this->_uploadFileMaxCount = (int)ini_get('max_file_uploads'); } return $this->_uploadFileMaxCount; diff --git a/framework/web/NotAcceptableHttpException.php b/framework/web/NotAcceptableHttpException.php index 65abdc42e93..a986195d828 100644 --- a/framework/web/NotAcceptableHttpException.php +++ b/framework/web/NotAcceptableHttpException.php @@ -22,11 +22,11 @@ class NotAcceptableHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(406, $message, $code, $previous); } diff --git a/framework/web/NotFoundHttpException.php b/framework/web/NotFoundHttpException.php index 03ce0266c96..ef064bab128 100644 --- a/framework/web/NotFoundHttpException.php +++ b/framework/web/NotFoundHttpException.php @@ -18,11 +18,11 @@ class NotFoundHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(404, $message, $code, $previous); } diff --git a/framework/web/RangeNotSatisfiableHttpException.php b/framework/web/RangeNotSatisfiableHttpException.php index 18c1ebb5500..253d8e24074 100644 --- a/framework/web/RangeNotSatisfiableHttpException.php +++ b/framework/web/RangeNotSatisfiableHttpException.php @@ -24,11 +24,11 @@ class RangeNotSatisfiableHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(416, $message, $code, $previous); } diff --git a/framework/web/Request.php b/framework/web/Request.php index 6ebd807a8bd..1736e711ed8 100644 --- a/framework/web/Request.php +++ b/framework/web/Request.php @@ -23,7 +23,7 @@ * * For more details and usage information on Request, see the [guide article on requests](guide:runtime-requests). * - * @property-read string $absoluteUrl The currently requested absolute URL. This property is read-only. + * @property-read string $absoluteUrl The currently requested absolute URL. * @property array $acceptableContentTypes The content types ordered by the quality score. Types with the * highest scores will be returned first. The array keys are the content types, while the array values are the * corresponding quality score and other parameters as given in the header. @@ -31,65 +31,59 @@ * represents the most preferred language. * @property-read array $authCredentials That contains exactly two elements: - 0: the username sent via HTTP * authentication, `null` if the username is not given - 1: the password sent via HTTP authentication, `null` if - * the password is not given. This property is read-only. + * the password is not given. * @property-read string|null $authPassword The password sent via HTTP authentication, `null` if the password - * is not given. This property is read-only. + * is not given. * @property-read string|null $authUser The username sent via HTTP authentication, `null` if the username is - * not given. This property is read-only. + * not given. * @property string $baseUrl The relative URL for the application. - * @property array $bodyParams The request parameters given in the request body. - * @property-read string $contentType Request content-type. Null is returned if this information is not - * available. This property is read-only. - * @property-read CookieCollection $cookies The cookie collection. This property is read-only. - * @property-read string $csrfToken The token used to perform CSRF validation. This property is read-only. + * @property array|object $bodyParams The request parameters given in the request body. Note that the type of + * this property differs in getter and setter. See [[getBodyParams()]] and [[setBodyParams()]] for details. + * @property-read string $contentType Request content-type. Empty string is returned if this information is + * not available. + * @property-read CookieCollection $cookies The cookie collection. + * @property-read string $csrfToken The token used to perform CSRF validation. * @property-read string $csrfTokenFromHeader The CSRF token sent via [[CSRF_HEADER]] by browser. Null is - * returned if no such header is sent. This property is read-only. - * @property-read array $eTags The entity tags. This property is read-only. - * @property-read HeaderCollection $headers The header collection. This property is read-only. + * returned if no such header is sent. + * @property-read array $eTags The entity tags. + * @property-read HeaderCollection $headers The header collection. * @property string|null $hostInfo Schema and hostname part (with port number if needed) of the request URL * (e.g. `http://www.yiiframework.com`), null if can't be obtained from `$_SERVER` and wasn't set. See * [[getHostInfo()]] for security related notes on this property. - * @property-read string|null $hostName Hostname part of the request URL (e.g. `www.yiiframework.com`). This - * property is read-only. - * @property-read bool $isAjax Whether this is an AJAX (XMLHttpRequest) request. This property is read-only. - * @property-read bool $isDelete Whether this is a DELETE request. This property is read-only. - * @property-read bool $isFlash Whether this is an Adobe Flash or Adobe Flex request. This property is - * read-only. - * @property-read bool $isGet Whether this is a GET request. This property is read-only. - * @property-read bool $isHead Whether this is a HEAD request. This property is read-only. - * @property-read bool $isOptions Whether this is a OPTIONS request. This property is read-only. - * @property-read bool $isPatch Whether this is a PATCH request. This property is read-only. - * @property-read bool $isPjax Whether this is a PJAX request. This property is read-only. - * @property-read bool $isPost Whether this is a POST request. This property is read-only. - * @property-read bool $isPut Whether this is a PUT request. This property is read-only. - * @property-read bool $isSecureConnection If the request is sent via secure channel (https). This property is - * read-only. + * @property-read string|null $hostName Hostname part of the request URL (e.g. `www.yiiframework.com`). + * @property-read bool $isAjax Whether this is an AJAX (XMLHttpRequest) request. + * @property-read bool $isDelete Whether this is a DELETE request. + * @property-read bool $isFlash Whether this is an Adobe Flash or Adobe Flex request. + * @property-read bool $isGet Whether this is a GET request. + * @property-read bool $isHead Whether this is a HEAD request. + * @property-read bool $isOptions Whether this is a OPTIONS request. + * @property-read bool $isPatch Whether this is a PATCH request. + * @property-read bool $isPjax Whether this is a PJAX request. + * @property-read bool $isPost Whether this is a POST request. + * @property-read bool $isPut Whether this is a PUT request. + * @property-read bool $isSecureConnection If the request is sent via secure channel (https). * @property-read string $method Request method, such as GET, POST, HEAD, PUT, PATCH, DELETE. The value - * returned is turned into upper case. This property is read-only. - * @property-read string|null $origin URL origin of a CORS request, `null` if not available. This property is - * read-only. + * returned is turned into upper case. + * @property-read string|null $origin URL origin of a CORS request, `null` if not available. * @property string $pathInfo Part of the request URL that is after the entry script and before the question * mark. Note, the returned path info is already URL-decoded. * @property int $port Port number for insecure requests. * @property array $queryParams The request GET parameter values. - * @property-read string $queryString Part of the request URL that is after the question mark. This property - * is read-only. + * @property-read string $queryString Part of the request URL that is after the question mark. * @property string $rawBody The request body. - * @property-read string|null $referrer URL referrer, null if not available. This property is read-only. - * @property-read string|null $remoteHost Remote host name, `null` if not available. This property is - * read-only. - * @property-read string|null $remoteIP Remote IP address, `null` if not available. This property is - * read-only. + * @property-read string|null $referrer URL referrer, null if not available. + * @property-read string|null $remoteHost Remote host name, `null` if not available. + * @property-read string|null $remoteIP Remote IP address, `null` if not available. * @property string $scriptFile The entry script file path. * @property string $scriptUrl The relative URL of the entry script. * @property int $securePort Port number for secure requests. - * @property-read string $serverName Server name, null if not available. This property is read-only. - * @property-read int|null $serverPort Server port number, null if not available. This property is read-only. + * @property-read string $serverName Server name, null if not available. + * @property-read int|null $serverPort Server port number, null if not available. * @property string $url The currently requested relative URL. Note that the URI returned may be URL-encoded * depending on the client. - * @property-read string|null $userAgent User agent, null if not available. This property is read-only. - * @property-read string|null $userHost User host name, null if not available. This property is read-only. - * @property-read string|null $userIP User IP address, null if not available. This property is read-only. + * @property-read string|null $userAgent User agent, null if not available. + * @property-read string|null $userHost User host name, null if not available. + * @property-read string|null $userIP User IP address, null if not available. * * @author Qiang Xue * @since 2.0 @@ -208,7 +202,7 @@ class Request extends \yii\base\Request * See [[IpValidator::::setRanges()|IpValidator::setRanges()]] * and [[IpValidator::networks]] for advanced matching. * - * @see $secureHeaders + * @see secureHeaders * @since 2.0.13 */ public $trustedHosts = []; @@ -218,8 +212,8 @@ class Request extends \yii\base\Request * If the list contains the `Forwarded` header, processing will be done according to RFC 7239. * The match of header names is case-insensitive. * @see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields - * @see https://tools.ietf.org/html/rfc7239 - * @see $trustedHosts + * @see https://datatracker.ietf.org/doc/html/rfc7239 + * @see trustedHosts * @since 2.0.13 */ public $secureHeaders = [ @@ -231,14 +225,17 @@ class Request extends \yii\base\Request // Microsoft: 'Front-End-Https', 'X-Rewrite-Url', + + // ngrok: + 'X-Original-Host', ]; /** * @var string[] List of headers where proxies store the real client IP. * It's not advisable to put insecure headers here. * To use the `Forwarded` header according to RFC 7239, the header must be added to [[secureHeaders]] list. * The match of header names is case-insensitive. - * @see $trustedHosts - * @see $secureHeaders + * @see trustedHosts + * @see secureHeaders * @since 2.0.13 */ public $ipHeaders = [ @@ -249,8 +246,8 @@ class Request extends \yii\base\Request * The array keys are header names and the array value is a list of header values that indicate a secure connection. * The match of header names and values is case-insensitive. * It's not advisable to put insecure headers here. - * @see $trustedHosts - * @see $secureHeaders + * @see trustedHosts + * @see secureHeaders * @since 2.0.13 */ public $secureProtocolHeaders = [ @@ -368,10 +365,16 @@ public function getHeaders() $this->_headers->add($name, $value); } } else { + // ['prefix' => length] + $headerPrefixes = ['HTTP_' => 5, 'REDIRECT_HTTP_' => 14]; + foreach ($_SERVER as $name => $value) { - if (strncmp($name, 'HTTP_', 5) === 0) { - $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))); - $this->_headers->add($name, $value); + foreach ($headerPrefixes as $prefix => $length) { + if (strncmp($name, $prefix, $length) === 0) { + $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, $length))))); + $this->_headers->add($name, $value); + continue 2; + } } } } @@ -545,7 +548,7 @@ public function setRawBody($rawBody) * Request parameters are determined using the parsers configured in [[parsers]] property. * If no parsers are configured for the current [[contentType]] it uses the PHP function `mb_parse_str()` * to parse the [[rawBody|request body]]. - * @return array the request parameters given in the request body. + * @return array|object the request parameters given in the request body. * @throws \yii\base\InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]]. * @see getMethod() * @see getBodyParam() @@ -561,7 +564,7 @@ public function getBodyParams() } $rawContentType = $this->getContentType(); - if (($pos = strpos($rawContentType, ';')) !== false) { + if (($pos = strpos((string)$rawContentType, ';')) !== false) { // e.g. text/html; charset=UTF-8 $contentType = substr($rawContentType, 0, $pos); } else { @@ -594,8 +597,8 @@ public function getBodyParams() /** * Sets the request body parameters. - * @param array $values the request body parameters (name-value pairs) - * @see getBodyParam() + * + * @param array|object $values the request body parameters (name-value pairs) * @see getBodyParams() */ public function setBodyParams($values) @@ -605,7 +608,9 @@ public function setBodyParams($values) /** * Returns the named request body parameter value. + * * If the parameter does not exist, the second parameter passed to this method will be returned. + * * @param string $name the parameter name * @param mixed $defaultValue the default parameter value if the parameter does not exist. * @return mixed the parameter value @@ -619,7 +624,7 @@ public function getBodyParam($name, $defaultValue = null) if (is_object($params)) { // unable to use `ArrayHelper::getValue()` due to different dots in key logic and lack of exception handling try { - return $params->{$name}; + return isset($params->{$name}) ? $params->{$name} : $defaultValue; } catch (\Exception $e) { return $defaultValue; } @@ -714,7 +719,7 @@ public function getQueryParam($name, $defaultValue = null) * * By default this value is based on the user request information. This method will * return the value of `$_SERVER['HTTP_HOST']` if it is available or `$_SERVER['SERVER_NAME']` if not. - * You may want to check out the [PHP documentation](https://secure.php.net/manual/en/reserved.variables.server.php) + * You may want to check out the [PHP documentation](https://www.php.net/manual/en/reserved.variables.server.php) * for more information on these variables. * * You may explicitly specify it by setting the [[setHostInfo()|hostInfo]] property. @@ -744,13 +749,22 @@ public function getHostInfo() $this->_hostInfo = $http . '://' . $this->getSecureForwardedHeaderTrustedPart('host'); } elseif ($this->headers->has('X-Forwarded-Host')) { $this->_hostInfo = $http . '://' . trim(explode(',', $this->headers->get('X-Forwarded-Host'))[0]); - } elseif ($this->headers->has('Host')) { - $this->_hostInfo = $http . '://' . $this->headers->get('Host'); - } elseif (isset($_SERVER['SERVER_NAME'])) { - $this->_hostInfo = $http . '://' . $_SERVER['SERVER_NAME']; - $port = $secure ? $this->getSecurePort() : $this->getPort(); - if (($port !== 80 && !$secure) || ($port !== 443 && $secure)) { - $this->_hostInfo .= ':' . $port; + } elseif ($this->headers->has('X-Original-Host')) { + $this->_hostInfo = $http . '://' . trim(explode(',', $this->headers->get('X-Original-Host'))[0]); + } else { + if ($this->headers->has('Host')) { + $this->_hostInfo = $http . '://' . $this->headers->get('Host'); + } elseif (filter_has_var(INPUT_SERVER, 'SERVER_NAME')) { + $this->_hostInfo = $http . '://' . filter_input(INPUT_SERVER, 'SERVER_NAME'); + } elseif (isset($_SERVER['SERVER_NAME'])) { + $this->_hostInfo = $http . '://' . $_SERVER['SERVER_NAME']; + } + + if ($this->_hostInfo !== null && !preg_match('/:\d+$/', $this->_hostInfo)) { + $port = $secure ? $this->getSecurePort() : $this->getPort(); + if (($port !== 80 && !$secure) || ($port !== 443 && $secure)) { + $this->_hostInfo .= ':' . $port; + } } } } @@ -785,7 +799,7 @@ public function setHostInfo($value) public function getHostName() { if ($this->_hostName === null) { - $this->_hostName = parse_url($this->getHostInfo(), PHP_URL_HOST); + $this->_hostName = parse_url((string)$this->getHostInfo(), PHP_URL_HOST); } return $this->_hostName; @@ -1103,7 +1117,7 @@ public function getIsSecureConnection() /** * Returns the server name. - * @return string server name, null if not available + * @return string|null server name, null if not available */ public function getServerName() { @@ -1160,7 +1174,7 @@ public function getUserAgent() /** * Returns the user IP address from [[ipHeaders]]. * @return string|null user IP address, null if not available - * @see $ipHeaders + * @see ipHeaders * @since 2.0.28 */ protected function getUserIpFromIpHeaders() @@ -1205,9 +1219,9 @@ public function getUserIP() * * @param string $ips comma separated IP list * @return string|null IP as string. Null is returned if IP can not be determined from header. - * @see $getUserHost - * @see $ipHeader - * @see $trustedHeaders + * @see getUserHost() + * @see ipHeaders + * @see getTrustedHeaders() * @since 2.0.28 */ protected function getUserIpFromIpHeader($ips) @@ -1316,13 +1330,16 @@ public function getAuthCredentials() return [$username, $password]; } - /* + /** * Apache with php-cgi does not pass HTTP Basic authentication to PHP by default. - * To make it work, add the following line to to your .htaccess file: + * To make it work, add one of the following lines to to your .htaccess file: * + * SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0 + * --OR-- * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] */ - $auth_token = $this->getHeaders()->get('HTTP_AUTHORIZATION') ?: $this->getHeaders()->get('REDIRECT_HTTP_AUTHORIZATION'); + $auth_token = $this->getHeaders()->get('Authorization'); + if ($auth_token !== null && strncasecmp($auth_token, 'basic', 5) === 0) { $parts = array_map(function ($value) { return strlen($value) === 0 ? null : $value; @@ -1459,7 +1476,7 @@ public function setAcceptableContentTypes($value) * contained in [[getRawBody()]] or, in the case of the HEAD method, the * media type that would have been sent had the request been a GET. * For the MIME-types the user expects in response, see [[acceptableContentTypes]]. - * @return string request content-type. Null is returned if this information is not available. + * @return string request content-type. Empty string is returned if this information is not available. * @link https://tools.ietf.org/html/rfc2616#section-14.17 * HTTP 1.1 header field definitions */ @@ -1470,7 +1487,7 @@ public function getContentType() } //fix bug https://bugs.php.net/bug.php?id=66606 - return $this->headers->get('Content-Type'); + return $this->headers->get('Content-Type') ?: ''; } private $_languages; @@ -1742,7 +1759,7 @@ public function getCsrfToken($regenerate = false) /** * Loads the CSRF token from cookie or session. - * @return string the CSRF token loaded from cookie or session. Null is returned if the cookie or session + * @return string|null the CSRF token loaded from cookie or session. Null is returned if the cookie or session * does not have CSRF token. */ protected function loadCsrfToken() @@ -1772,7 +1789,7 @@ protected function generateCsrfToken() } /** - * @return string the CSRF token sent via [[CSRF_HEADER]] by browser. Null is returned if no such header is sent. + * @return string|null the CSRF token sent via [[CSRF_HEADER]] by browser. Null is returned if no such header is sent. */ public function getCsrfTokenFromHeader() { @@ -1805,7 +1822,7 @@ protected function createCsrfCookie($token) * Note that the method will NOT perform CSRF validation if [[enableCsrfValidation]] is false or the HTTP method * is among GET, HEAD or OPTIONS. * - * @param string $clientSuppliedToken the user-provided CSRF token to be validated. If null, the token will be retrieved from + * @param string|null $clientSuppliedToken the user-provided CSRF token to be validated. If null, the token will be retrieved from * the [[csrfParam]] POST field or HTTP header. * This parameter is available since version 2.0.4. * @return bool whether CSRF token is valid. If [[enableCsrfValidation]] is false, this method will return true. diff --git a/framework/web/Response.php b/framework/web/Response.php index cbeac1ba37f..ba426433801 100644 --- a/framework/web/Response.php +++ b/framework/web/Response.php @@ -37,27 +37,22 @@ * * For more details and usage information on Response, see the [guide article on responses](guide:runtime-responses). * - * @property-read CookieCollection $cookies The cookie collection. This property is read-only. - * @property-write string $downloadHeaders The attachment file name. This property is write-only. - * @property-read HeaderCollection $headers The header collection. This property is read-only. - * @property-read bool $isClientError Whether this response indicates a client error. This property is - * read-only. - * @property-read bool $isEmpty Whether this response is empty. This property is read-only. - * @property-read bool $isForbidden Whether this response indicates the current request is forbidden. This - * property is read-only. - * @property-read bool $isInformational Whether this response is informational. This property is read-only. - * @property-read bool $isInvalid Whether this response has a valid [[statusCode]]. This property is - * read-only. + * @property-read CookieCollection $cookies The cookie collection. + * @property-write string $downloadHeaders The attachment file name. + * @property-read HeaderCollection $headers The header collection. + * @property-read bool $isClientError Whether this response indicates a client error. + * @property-read bool $isEmpty Whether this response is empty. + * @property-read bool $isForbidden Whether this response indicates the current request is forbidden. + * @property-read bool $isInformational Whether this response is informational. + * @property-read bool $isInvalid Whether this response has a valid [[statusCode]]. * @property-read bool $isNotFound Whether this response indicates the currently requested resource is not - * found. This property is read-only. - * @property-read bool $isOk Whether this response is OK. This property is read-only. - * @property-read bool $isRedirection Whether this response is a redirection. This property is read-only. - * @property-read bool $isServerError Whether this response indicates a server error. This property is - * read-only. - * @property-read bool $isSuccessful Whether this response is successful. This property is read-only. + * found. + * @property-read bool $isOk Whether this response is OK. + * @property-read bool $isRedirection Whether this response is a redirection. + * @property-read bool $isServerError Whether this response indicates a server error. + * @property-read bool $isSuccessful Whether this response is successful. * @property int $statusCode The HTTP status code to send with the response. - * @property-write \Exception|\Error|\Throwable $statusCodeByException The exception object. This property is - * write-only. + * @property-write \Throwable $statusCodeByException The exception object. * * @author Qiang Xue * @author Carsten Brandt @@ -132,19 +127,22 @@ class Response extends \yii\base\Response */ public $data; /** - * @var string the response content. When [[data]] is not null, it will be converted into [[content]] + * @var string|null the response content. When [[data]] is not null, it will be converted into [[content]] * according to [[format]] when the response is being sent out. * @see data */ public $content; /** - * @var resource|array the stream to be sent. This can be a stream handle or an array of stream handle, - * the begin position and the end position. Note that when this property is set, the [[data]] and [[content]] - * properties will be ignored by [[send()]]. + * @var resource|array|callable the stream to be sent. This can be a stream handle or an array of stream handle, + * the begin position and the end position. Alternatively it can be set to a callable, which returns + * (or [yields](https://www.php.net/manual/en/language.generators.syntax.php)) an array of strings that should + * be echoed and flushed out one by one. + * + * Note that when this property is set, the [[data]] and [[content]] properties will be ignored by [[send()]]. */ public $stream; /** - * @var string the charset of the text response. If not set, it will use + * @var string|null the charset of the text response. If not set, it will use * the value of [[Application::charset]]. */ public $charset; @@ -154,7 +152,7 @@ class Response extends \yii\base\Response */ public $statusText = 'OK'; /** - * @var string the version of the HTTP protocol to use. If not set, it will be determined via `$_SERVER['SERVER_PROTOCOL']`, + * @var string|null the version of the HTTP protocol to use. If not set, it will be determined via `$_SERVER['SERVER_PROTOCOL']`, * or '1.1' if that is not available. */ public $version; @@ -275,7 +273,7 @@ public function getStatusCode() * Sets the response status code. * This method will set the corresponding status text if `$text` is null. * @param int $value the status code - * @param string $text the status text. If not set, it will be set automatically based on the status code. + * @param string|null $text the status text. If not set, it will be set automatically based on the status code. * @throws InvalidArgumentException if the status code is invalid. * @return $this the response object itself */ @@ -299,7 +297,7 @@ public function setStatusCode($value, $text = null) /** * Sets the response status code based on the exception. - * @param \Exception|\Error|\Throwable $e the exception object. + * @param \Throwable $e the exception object. * @throws InvalidArgumentException if the status code is invalid. * @return $this the response object itself * @since 2.0.12 @@ -417,10 +415,11 @@ protected function sendCookies() } else { // Work around for setting sameSite cookie prior PHP 7.3 // https://stackoverflow.com/questions/39750906/php-setcookie-samesite-strict/46971326#46971326 + $cookiePath = $cookie->path; if (!is_null($cookie->sameSite)) { - $cookie->path .= '; samesite=' . $cookie->sameSite; + $cookiePath .= '; samesite=' . $cookie->sameSite; } - setcookie($cookie->name, $value, $cookie->expire, $cookie->path, $cookie->domain, $cookie->secure, $cookie->httpOnly); + setcookie($cookie->name, $value, $cookie->expire, $cookiePath, $cookie->domain, $cookie->secure, $cookie->httpOnly); } } } @@ -441,6 +440,15 @@ protected function sendContent() Yii::warning('set_time_limit() is not available', __METHOD__); } + if (is_callable($this->stream)) { + $data = call_user_func($this->stream); + foreach ($data as $datum) { + echo $datum; + flush(); + } + return; + } + $chunkSize = 8 * 1024 * 1024; // 8MB per chunk if (is_array($this->stream)) { @@ -491,7 +499,7 @@ protected function sendContent() * ``` * * @param string $filePath the path of the file to be sent. - * @param string $attachmentName the file name shown to the user. If null, it will be determined from `$filePath`. + * @param string|null $attachmentName the file name shown to the user. If null, it will be determined from `$filePath`. * @param array $options additional options for sending the file. The following options are supported: * * - `mimeType`: the MIME type of the content. If not set, it will be guessed based on `$filePath` @@ -626,10 +634,10 @@ public function sendStreamAsFile($handle, $attachmentName, $options = []) /** * Sets a default set of HTTP headers for file downloading purpose. * @param string $attachmentName the attachment file name - * @param string $mimeType the MIME type for the response. If null, `Content-Type` header will NOT be set. + * @param string|null $mimeType the MIME type for the response. If null, `Content-Type` header will NOT be set. * @param bool $inline whether the browser should open the file within the browser window. Defaults to false, * meaning a download dialog will pop up. - * @param int $contentLength the byte length of the file being downloaded. If null, `Content-Length` header will NOT be set. + * @param int|null $contentLength the byte length of the file being downloaded. If null, `Content-Length` header will NOT be set. * @return $this the response object itself */ public function setDownloadHeaders($attachmentName, $mimeType = null, $inline = false, $contentLength = null) @@ -735,7 +743,7 @@ protected function getHttpRange($fileSize) * ``` * * @param string $filePath file name with full path - * @param string $attachmentName file name shown to the user. If null, it will be determined from `$filePath`. + * @param string|null $attachmentName file name shown to the user. If null, it will be determined from `$filePath`. * @param array $options additional options for sending the file. The following options are supported: * * - `mimeType`: the MIME type of the content. If not set, it will be guessed based on `$filePath` @@ -884,7 +892,7 @@ public function redirect($url, $statusCode = 302, $checkAjax = true) if ($checkAjax) { if ($request->getIsAjax()) { - if (in_array($statusCode, [301, 302]) && preg_match('/Trident\/|MSIE[ ]/', $request->userAgent)) { + if (in_array($statusCode, [301, 302]) && preg_match('/Trident\/|MSIE[ ]/', (string)$request->userAgent)) { $statusCode = 200; } if ($request->getIsPjax()) { @@ -1061,10 +1069,14 @@ protected function defaultFormatters() * Prepares for sending the response. * The default implementation will convert [[data]] into [[content]] and set headers accordingly. * @throws InvalidConfigException if the formatter for the specified format is invalid or [[format]] is not supported + * + * @see https://tools.ietf.org/html/rfc7231#page-53 + * @see https://tools.ietf.org/html/rfc7232#page-18 */ protected function prepare() { - if ($this->statusCode === 204) { + if (in_array($this->getStatusCode(), [204, 304])) { + // A 204/304 response cannot contain a message body according to rfc7231/rfc7232 $this->content = ''; $this->stream = null; return; diff --git a/framework/web/ServerErrorHttpException.php b/framework/web/ServerErrorHttpException.php index 42e69c498bd..c9a6578b1eb 100644 --- a/framework/web/ServerErrorHttpException.php +++ b/framework/web/ServerErrorHttpException.php @@ -18,11 +18,11 @@ class ServerErrorHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(500, $message, $code, $previous); } diff --git a/framework/web/Session.php b/framework/web/Session.php index 03d4ece7c63..118a7e823b1 100644 --- a/framework/web/Session.php +++ b/framework/web/Session.php @@ -45,28 +45,26 @@ * * For more details and usage information on Session, see the [guide article on sessions](guide:runtime-sessions-cookies). * - * @property-read array $allFlashes Flash messages (key => message or key => [message1, message2]). This - * property is read-only. - * @property-read string $cacheLimiter Current cache limiter. This property is read-only. - * @property-read array $cookieParams The session cookie parameters. This property is read-only. - * @property-read int $count The number of session variables. This property is read-only. + * @property-read array $allFlashes Flash messages (key => message or key => [message1, message2]). + * @property-read string $cacheLimiter Current cache limiter. + * @property-read array $cookieParams The session cookie parameters. + * @property-read int $count The number of session variables. * @property-write string $flash The key identifying the flash message. Note that flash messages and normal * session variables share the same name space. If you have a normal session variable using the same name, its - * value will be overwritten by this method. This property is write-only. + * value will be overwritten by this method. * @property float $gCProbability The probability (percentage) that the GC (garbage collection) process is * started on every session initialization. * @property bool $hasSessionId Whether the current request has sent the session ID. * @property string $id The current session ID. - * @property-read bool $isActive Whether the session has started. This property is read-only. - * @property-read SessionIterator $iterator An iterator for traversing the session variables. This property is - * read-only. + * @property-read bool $isActive Whether the session has started. + * @property-read SessionIterator $iterator An iterator for traversing the session variables. * @property string $name The current session name. * @property string $savePath The current session save path, defaults to '/tmp'. * @property int $timeout The number of seconds after which data will be seen as 'garbage' and cleaned up. The * default value is 1440 seconds (or the value of "session.gc_maxlifetime" set in php.ini). * @property bool|null $useCookies The value indicating whether cookies should be used to store session IDs. - * @property-read bool $useCustomStorage Whether to use custom storage. This property is read-only. - * @property-read bool $useStrictMode Whether strict mode is enabled or not. This property is read-only. + * @property-read bool $useCustomStorage Whether to use custom storage. + * @property bool $useStrictMode Whether strict mode is enabled or not. * @property bool $useTransparentSessionID Whether transparent sid support is enabled or not, defaults to * false. * @@ -101,11 +99,11 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co /** * @var array parameter-value pairs to override default session cookie parameters that are used for session_set_cookie_params() function * Array may have the following possible keys: 'lifetime', 'path', 'domain', 'secure', 'httponly' - * @see https://secure.php.net/manual/en/function.session-set-cookie-params.php + * @see https://www.php.net/manual/en/function.session-set-cookie-params.php */ private $_cookieParams = ['httponly' => true]; /** - * @var $frozenSessionData array|null is used for saving session between recreations due to session parameters update. + * @var array|null is used for saving session between recreations due to session parameters update. */ private $frozenSessionData; @@ -294,7 +292,7 @@ public function setHasSessionId($value) /** * Gets the session ID. - * This is a wrapper for [PHP session_id()](https://secure.php.net/manual/en/function.session-id.php). + * This is a wrapper for [PHP session_id()](https://www.php.net/manual/en/function.session-id.php). * @return string the current session ID */ public function getId() @@ -304,7 +302,7 @@ public function getId() /** * Sets the session ID. - * This is a wrapper for [PHP session_id()](https://secure.php.net/manual/en/function.session-id.php). + * This is a wrapper for [PHP session_id()](https://www.php.net/manual/en/function.session-id.php). * @param string $value the session ID for the current session */ public function setId($value) @@ -315,7 +313,7 @@ public function setId($value) /** * Updates the current session ID with a newly generated one. * - * Please refer to for more details. + * Please refer to for more details. * * This method has no effect when session is not [[getIsActive()|active]]. * Make sure to call [[open()]] before calling it. @@ -339,7 +337,7 @@ public function regenerateID($deleteOldSession = false) /** * Gets the name of the current session. - * This is a wrapper for [PHP session_name()](https://secure.php.net/manual/en/function.session-name.php). + * This is a wrapper for [PHP session_name()](https://www.php.net/manual/en/function.session-name.php). * @return string the current session name */ public function getName() @@ -349,7 +347,7 @@ public function getName() /** * Sets the name for the current session. - * This is a wrapper for [PHP session_name()](https://secure.php.net/manual/en/function.session-name.php). + * This is a wrapper for [PHP session_name()](https://www.php.net/manual/en/function.session-name.php). * @param string $value the session name for the current session, must be an alphanumeric string. * It defaults to "PHPSESSID". */ @@ -362,7 +360,7 @@ public function setName($value) /** * Gets the current session save path. - * This is a wrapper for [PHP session_save_path()](https://secure.php.net/manual/en/function.session-save-path.php). + * This is a wrapper for [PHP session_save_path()](https://www.php.net/manual/en/function.session-save-path.php). * @return string the current session save path, defaults to '/tmp'. */ public function getSavePath() @@ -372,7 +370,7 @@ public function getSavePath() /** * Sets the current session save path. - * This is a wrapper for [PHP session_save_path()](https://secure.php.net/manual/en/function.session-save-path.php). + * This is a wrapper for [PHP session_save_path()](https://www.php.net/manual/en/function.session-save-path.php). * @param string $value the current session save path. This can be either a directory name or a [path alias](guide:concept-aliases). * @throws InvalidArgumentException if the path is not a valid directory */ @@ -388,7 +386,7 @@ public function setSavePath($value) /** * @return array the session cookie parameters. - * @see https://secure.php.net/manual/en/function.session-get-cookie-params.php + * @see https://www.php.net/manual/en/function.session-get-cookie-params.php */ public function getCookieParams() { @@ -411,7 +409,7 @@ public function getCookieParams() * See https://www.owasp.org/index.php/SameSite for more information about `sameSite`. * * @throws InvalidArgumentException if the parameters are incomplete. - * @see https://secure.php.net/manual/en/function.session-set-cookie-params.php + * @see https://www.php.net/manual/en/function.session-set-cookie-params.php */ public function setCookieParams(array $value) { @@ -422,7 +420,7 @@ public function setCookieParams(array $value) * Sets the session cookie parameters. * This method is called by [[open()]] when it is about to open the session. * @throws InvalidArgumentException if the parameters are incomplete. - * @see https://secure.php.net/manual/en/function.session-set-cookie-params.php + * @see https://www.php.net/manual/en/function.session-set-cookie-params.php */ private function setCookieParamsInternal() { @@ -548,7 +546,7 @@ public function setTimeout($value) } /** - * @var bool Whether strict mode is enabled or not. + * @param bool $value Whether strict mode is enabled or not. * When `true` this setting prevents the session component to use an uninitialized session ID. * Note: Enabling `useStrictMode` on PHP < 5.5.2 is only supported with custom storage classes. * Warning! Although enabling strict mode is mandatory for secure sessions, the default value of 'session.use-strict-mode' is `0`. @@ -662,6 +660,7 @@ public function gcSession($maxLifetime) * This method is required by the interface [[\IteratorAggregate]]. * @return SessionIterator an iterator for traversing the session variables. */ + #[\ReturnTypeWillChange] public function getIterator() { $this->open(); @@ -683,6 +682,7 @@ public function getCount() * This method is required by [[\Countable]] interface. * @return int number of items in the session. */ + #[\ReturnTypeWillChange] public function count() { return $this->getCount(); @@ -961,9 +961,10 @@ public function hasFlash($key) /** * This method is required by the interface [[\ArrayAccess]]. - * @param mixed $offset the offset to check on + * @param int|string $offset the offset to check on * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { $this->open(); @@ -973,9 +974,10 @@ public function offsetExists($offset) /** * This method is required by the interface [[\ArrayAccess]]. - * @param int $offset the offset to retrieve element. + * @param int|string $offset the offset to retrieve element. * @return mixed the element at the offset, null if no element is found at the offset */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { $this->open(); @@ -985,9 +987,10 @@ public function offsetGet($offset) /** * This method is required by the interface [[\ArrayAccess]]. - * @param int $offset the offset to set element + * @param int|string $offset the offset to set element * @param mixed $item the element value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $item) { $this->open(); @@ -996,8 +999,9 @@ public function offsetSet($offset, $item) /** * This method is required by the interface [[\ArrayAccess]]. - * @param mixed $offset the offset to unset element + * @param int|string $offset the offset to unset element */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $this->open(); diff --git a/framework/web/SessionIterator.php b/framework/web/SessionIterator.php index d8ccdf71ad0..1d1f0033246 100644 --- a/framework/web/SessionIterator.php +++ b/framework/web/SessionIterator.php @@ -20,7 +20,7 @@ class SessionIterator implements \Iterator */ private $_keys; /** - * @var mixed current key + * @var string|int|false current key */ private $_key; @@ -30,13 +30,15 @@ class SessionIterator implements \Iterator */ public function __construct() { - $this->_keys = array_keys($_SESSION); + $this->_keys = array_keys(isset($_SESSION) ? $_SESSION : []); + $this->rewind(); } /** * Rewinds internal array pointer. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function rewind() { $this->_key = reset($this->_keys); @@ -45,11 +47,12 @@ public function rewind() /** * Returns the key of the current array element. * This method is required by the interface [[\Iterator]]. - * @return mixed the key of the current array element + * @return string|int|null the key of the current array element */ + #[\ReturnTypeWillChange] public function key() { - return $this->_key; + return $this->_key === false ? null : $this->_key; } /** @@ -57,20 +60,22 @@ public function key() * This method is required by the interface [[\Iterator]]. * @return mixed the current array element */ + #[\ReturnTypeWillChange] public function current() { - return isset($_SESSION[$this->_key]) ? $_SESSION[$this->_key] : null; + return $this->_key !== false && isset($_SESSION[$this->_key]) ? $_SESSION[$this->_key] : null; } /** * Moves the internal pointer to the next array element. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function next() { do { $this->_key = next($this->_keys); - } while (!isset($_SESSION[$this->_key]) && $this->_key !== false); + } while ($this->_key !== false && !isset($_SESSION[$this->_key])); } /** @@ -78,6 +83,7 @@ public function next() * This method is required by the interface [[\Iterator]]. * @return bool */ + #[\ReturnTypeWillChange] public function valid() { return $this->_key !== false; diff --git a/framework/web/TooManyRequestsHttpException.php b/framework/web/TooManyRequestsHttpException.php index eb602112575..6549936fd99 100644 --- a/framework/web/TooManyRequestsHttpException.php +++ b/framework/web/TooManyRequestsHttpException.php @@ -22,11 +22,11 @@ class TooManyRequestsHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(429, $message, $code, $previous); } diff --git a/framework/web/UnauthorizedHttpException.php b/framework/web/UnauthorizedHttpException.php index 2f8350e7974..c261e9f00f1 100644 --- a/framework/web/UnauthorizedHttpException.php +++ b/framework/web/UnauthorizedHttpException.php @@ -25,11 +25,11 @@ class UnauthorizedHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(401, $message, $code, $previous); } diff --git a/framework/web/UnprocessableEntityHttpException.php b/framework/web/UnprocessableEntityHttpException.php index e32faac3a62..8fdc65aff6d 100644 --- a/framework/web/UnprocessableEntityHttpException.php +++ b/framework/web/UnprocessableEntityHttpException.php @@ -24,11 +24,11 @@ class UnprocessableEntityHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(422, $message, $code, $previous); } diff --git a/framework/web/UnsupportedMediaTypeHttpException.php b/framework/web/UnsupportedMediaTypeHttpException.php index 5942ea2661d..7d2c0f5661c 100644 --- a/framework/web/UnsupportedMediaTypeHttpException.php +++ b/framework/web/UnsupportedMediaTypeHttpException.php @@ -23,11 +23,11 @@ class UnsupportedMediaTypeHttpException extends HttpException { /** * Constructor. - * @param string $message error message + * @param string|null $message error message * @param int $code error code - * @param \Exception $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ - public function __construct($message = null, $code = 0, \Exception $previous = null) + public function __construct($message = null, $code = 0, $previous = null) { parent::__construct(415, $message, $code, $previous); } diff --git a/framework/web/UploadedFile.php b/framework/web/UploadedFile.php index ed8fa111b89..e4b0620d1fb 100644 --- a/framework/web/UploadedFile.php +++ b/framework/web/UploadedFile.php @@ -18,14 +18,14 @@ * You can call [[getInstance()]] to retrieve the instance of an uploaded file, * and then use [[saveAs()]] to save it on the server. * You may also query other information about the file, including [[name]], - * [[tempName]], [[type]], [[size]] and [[error]]. + * [[tempName]], [[type]], [[size]], [[error]] and [[fullPath]]. * * For more details and usage information on UploadedFile, see the [guide article on handling uploads](guide:input-file-upload). * - * @property-read string $baseName Original file base name. This property is read-only. - * @property-read string $extension File extension. This property is read-only. + * @property-read string $baseName Original file base name. + * @property-read string $extension File extension. * @property-read bool $hasError Whether there is an error with the uploaded file. Check [[error]] for - * detailed error code information. This property is read-only. + * detailed error code information. * * @author Qiang Xue * @since 2.0 @@ -54,14 +54,24 @@ class UploadedFile extends BaseObject public $size; /** * @var int an error code describing the status of this file uploading. - * @see https://secure.php.net/manual/en/features.file-upload.errors.php + * @see https://www.php.net/manual/en/features.file-upload.errors.php */ public $error; + /** + * @var string|null The full path as submitted by the browser. Note this value does not always + * contain a real directory structure, and cannot be trusted. Available as of PHP 8.1. + * @since 2.0.46 + */ + public $fullPath; /** - * @var resource a temporary uploaded stream resource used within PUT and PATCH request. + * @var resource|null a temporary uploaded stream resource used within PUT and PATCH request. */ private $_tempResource; + + /** + * @var array[] + */ private static $_files; @@ -93,7 +103,7 @@ public function __toString() * @param \yii\base\Model $model the data model * @param string $attribute the attribute name. The attribute name may contain array indexes. * For example, '[1]file' for tabular file uploading; and 'file[1]' for an element in a file array. - * @return null|UploadedFile the instance of the uploaded file. + * @return UploadedFile|null the instance of the uploaded file. * Null is returned if no file is uploaded for the specified model attribute. * @see getInstanceByName() */ @@ -121,7 +131,7 @@ public static function getInstances($model, $attribute) * Returns an uploaded file according to the given file input name. * The name can be a plain string or a string like an array element (e.g. 'Post[imageFile]', or 'Post[0][imageFile]'). * @param string $name the name of the file input field. - * @return null|UploadedFile the instance of the uploaded file. + * @return UploadedFile|null the instance of the uploaded file. * Null is returned if no file is uploaded for the specified name. */ public static function getInstanceByName($name) @@ -192,7 +202,7 @@ public function saveAs($file, $deleteTempFile = true) * Copy temporary file into file specified * * @param string $targetFile path of the file to copy to - * @return bool|int the total count of bytes copied, or false on failure + * @return int|false the total count of bytes copied, or false on failure * @since 2.0.32 */ protected function copyTempFile($targetFile) @@ -236,17 +246,26 @@ public function getHasError() } /** - * Creates UploadedFile instances from $_FILE. - * @return array the UploadedFile instances + * Returns reformated data of uplodaded files. + * + * @return array[] */ private static function loadFiles() { if (self::$_files === null) { self::$_files = []; if (isset($_FILES) && is_array($_FILES)) { - foreach ($_FILES as $class => $info) { - $resource = isset($info['tmp_resource']) ? $info['tmp_resource'] : []; - self::loadFilesRecursive($class, $info['name'], $info['tmp_name'], $info['type'], $info['size'], $info['error'], $resource); + foreach ($_FILES as $key => $info) { + self::loadFilesRecursive( + $key, + $info['name'], + $info['tmp_name'], + $info['type'], + $info['size'], + $info['error'], + isset($info['full_path']) ? $info['full_path'] : [], + isset($info['tmp_resource']) ? $info['tmp_resource'] : [] + ); } } } @@ -255,29 +274,41 @@ private static function loadFiles() } /** - * Creates UploadedFile instances from $_FILE recursively. - * @param string $key key for identifying uploaded file: class name and sub-array indexes - * @param mixed $names file names provided by PHP - * @param mixed $tempNames temporary file names provided by PHP - * @param mixed $types file types provided by PHP - * @param mixed $sizes file sizes provided by PHP - * @param mixed $errors uploading issues provided by PHP + * Recursive reformats data of uplodaded file(s). + * + * @param string $key key for identifying uploaded file(sub-array index) + * @param string[]|string $names file name(s) provided by PHP + * @param string[]|string $tempNames temporary file name(s) provided by PHP + * @param string[]|string $types file type(s) provided by PHP + * @param int[]|int $sizes file size(s) provided by PHP + * @param int[]|int $errors uploading issue(s) provided by PHP + * @param array|string|null $fullPaths the full path(s) as submitted by the browser/PHP + * @param array|resource|null $tempResources the resource(s) */ - private static function loadFilesRecursive($key, $names, $tempNames, $types, $sizes, $errors, $tempResources) + private static function loadFilesRecursive($key, $names, $tempNames, $types, $sizes, $errors, $fullPaths, $tempResources) { if (is_array($names)) { foreach ($names as $i => $name) { - $resource = isset($tempResources[$i]) ? $tempResources[$i] : []; - self::loadFilesRecursive($key . '[' . $i . ']', $name, $tempNames[$i], $types[$i], $sizes[$i], $errors[$i], $resource); + self::loadFilesRecursive( + $key . '[' . $i . ']', + $name, + $tempNames[$i], + $types[$i], + $sizes[$i], + $errors[$i], + isset($fullPaths[$i]) ? $fullPaths[$i] : null, + isset($tempResources[$i]) ? $tempResources[$i] : null + ); } - } elseif ((int) $errors !== UPLOAD_ERR_NO_FILE) { + } elseif ($errors != UPLOAD_ERR_NO_FILE) { self::$_files[$key] = [ 'name' => $names, 'tempName' => $tempNames, - 'tempResource' => $tempResources, + 'tempResource' => is_resource($tempResources) ? $tempResources : null, 'type' => $types, 'size' => $sizes, 'error' => $errors, + 'fullPath' => is_string($fullPaths) ? $fullPaths : null, ]; } } diff --git a/framework/web/UrlManager.php b/framework/web/UrlManager.php index ce6ddb3f66f..92c73d3fe9e 100644 --- a/framework/web/UrlManager.php +++ b/framework/web/UrlManager.php @@ -119,7 +119,7 @@ class UrlManager extends Component */ public $routeParam = 'r'; /** - * @var CacheInterface|array|string the cache object or the application component ID of the cache object. + * @var CacheInterface|array|string|bool the cache object or the application component ID of the cache object. * This can also be an array that is used to create a [[CacheInterface]] instance in case you do not want to use * an application component. * Compiled URL rules will be cached through this cache object, if it is available. @@ -185,17 +185,10 @@ public function init() if (!$this->enablePrettyUrl) { return; } - if ($this->cache !== false && $this->cache !== null) { - try { - $this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface'); - } catch (InvalidConfigException $e) { - Yii::warning('Unable to use cache for URL manager: ' . $e->getMessage()); - } - } - if (empty($this->rules)) { - return; + + if (!empty($this->rules)) { + $this->rules = $this->buildRules($this->rules); } - $this->rules = $this->buildRules($this->rules); } /** @@ -245,10 +238,6 @@ protected function buildRules($ruleDeclarations) $rule = ['route' => $rule]; if (preg_match("/^((?:($verbs),)*($verbs))\\s+(.*)$/", $key, $matches)) { $rule['verb'] = explode(',', $matches[1]); - // rules that are not applicable for GET requests should not be used to create URLs - if (!in_array('GET', $rule['verb'], true)) { - $rule['mode'] = UrlRule::PARSING_ONLY; - } $key = $matches[4]; } $rule['pattern'] = $key; @@ -267,6 +256,23 @@ protected function buildRules($ruleDeclarations) return $builtRules; } + /** + * @return CacheInterface|null|bool + */ + private function ensureCache() + { + if (!$this->cache instanceof CacheInterface && $this->cache !== false && $this->cache !== null) { + try { + $this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface'); + } catch (InvalidConfigException $e) { + Yii::warning('Unable to use cache for URL manager: ' . $e->getMessage()); + $this->cache = null; + } + } + + return $this->cache; + } + /** * Stores $builtRules to cache, using $rulesDeclaration as a part of cache key. * @@ -278,11 +284,12 @@ protected function buildRules($ruleDeclarations) */ protected function setBuiltRulesCache($ruleDeclarations, $builtRules) { - if (!$this->cache instanceof CacheInterface) { + $cache = $this->ensureCache(); + if (!$cache) { return false; } - return $this->cache->set([$this->cacheKey, $this->ruleConfig, $ruleDeclarations], $builtRules); + return $cache->set([$this->cacheKey, $this->ruleConfig, $ruleDeclarations], $builtRules); } /** @@ -296,11 +303,12 @@ protected function setBuiltRulesCache($ruleDeclarations, $builtRules) */ protected function getBuiltRulesFromCache($ruleDeclarations) { - if (!$this->cache instanceof CacheInterface) { + $cache = $this->ensureCache(); + if (!$cache) { return false; } - return $this->cache->get([$this->cacheKey, $this->ruleConfig, $ruleDeclarations]); + return $cache->get([$this->cacheKey, $this->ruleConfig, $ruleDeclarations]); } /** diff --git a/framework/web/UrlNormalizerRedirectException.php b/framework/web/UrlNormalizerRedirectException.php index 195d45b8fd4..9d550221832 100644 --- a/framework/web/UrlNormalizerRedirectException.php +++ b/framework/web/UrlNormalizerRedirectException.php @@ -18,12 +18,12 @@ class UrlNormalizerRedirectException extends \yii\base\Exception { /** * @var array|string the parameter to be used to generate a valid URL for redirection - * @see [[\yii\helpers\Url::to()]] + * @see \yii\helpers\Url::to() */ public $url; /** * @var bool|string the URI scheme to use in the generated URL for redirection - * @see [[\yii\helpers\Url::to()]] + * @see \yii\helpers\Url::to() */ public $scheme; /** @@ -38,15 +38,15 @@ class UrlNormalizerRedirectException extends \yii\base\Exception * @param int $statusCode HTTP status code used for redirection * @param bool|string $scheme the URI scheme to use in the generated URL for redirection. * This will be used as second parameter for [[\yii\helpers\Url::to()]] - * @param string $message the error message + * @param string|null $message the error message * @param int $code the error code - * @param \Exception $previous the previous exception used for the exception chaining + * @param \Throwable|null $previous the previous exception used for the exception chaining */ - public function __construct($url, $statusCode = 302, $scheme = false, $message = null, $code = 0, \Exception $previous = null) + public function __construct($url, $statusCode = 302, $scheme = false, $message = null, $code = 0, $previous = null) { $this->url = $url; $this->scheme = $scheme; $this->statusCode = $statusCode; - parent::__construct($message, $code, $previous); + parent::__construct((string)$message, $code, $previous); } } diff --git a/framework/web/UrlRule.php b/framework/web/UrlRule.php index 25d3cd81faf..a9027b42a7f 100644 --- a/framework/web/UrlRule.php +++ b/framework/web/UrlRule.php @@ -25,7 +25,7 @@ * ``` * * @property-read null|int $createUrlStatus Status of the URL creation after the last [[createUrl()]] call. - * `null` if rule does not provide info about create status. This property is read-only. + * `null` if rule does not provide info about create status. * * @author Qiang Xue * @since 2.0 @@ -42,33 +42,33 @@ class UrlRule extends BaseObject implements UrlRuleInterface const CREATION_ONLY = 2; /** * Represents the successful URL generation by last [[createUrl()]] call. - * @see $createStatus + * @see createStatus * @since 2.0.12 */ const CREATE_STATUS_SUCCESS = 0; /** * Represents the unsuccessful URL generation by last [[createUrl()]] call, because rule does not support * creating URLs. - * @see $createStatus + * @see createStatus * @since 2.0.12 */ const CREATE_STATUS_PARSING_ONLY = 1; /** * Represents the unsuccessful URL generation by last [[createUrl()]] call, because of mismatched route. - * @see $createStatus + * @see createStatus * @since 2.0.12 */ const CREATE_STATUS_ROUTE_MISMATCH = 2; /** * Represents the unsuccessful URL generation by last [[createUrl()]] call, because of mismatched * or missing parameters. - * @see $createStatus + * @see createStatus * @since 2.0.12 */ const CREATE_STATUS_PARAMS_MISMATCH = 4; /** - * @var string the name of this rule. If not set, it will use [[pattern]] as the name. + * @var string|null the name of this rule. If not set, it will use [[pattern]] as the name. */ public $name; /** @@ -79,7 +79,7 @@ class UrlRule extends BaseObject implements UrlRuleInterface */ public $pattern; /** - * @var string the pattern used to parse and create the host info part of a URL (e.g. `http://example.com`). + * @var string|null the pattern used to parse and create the host info part of a URL (e.g. `http://example.com`). * @see pattern */ public $host; @@ -94,20 +94,20 @@ class UrlRule extends BaseObject implements UrlRuleInterface */ public $defaults = []; /** - * @var string the URL suffix used for this rule. + * @var string|null the URL suffix used for this rule. * For example, ".html" can be used so that the URL looks like pointing to a static HTML page. * If not set, the value of [[UrlManager::suffix]] will be used. */ public $suffix; /** - * @var string|array the HTTP verb (e.g. GET, POST, DELETE) that this rule should match. + * @var string|array|null the HTTP verb (e.g. GET, POST, DELETE) that this rule should match. * Use array to represent multiple verbs that this rule may match. * If this property is not set, the rule can match any verb. * Note that this property is only used when parsing a request. It is ignored for URL creation. */ public $verb; /** - * @var int a value indicating if this rule should be used for both request parsing and URL creation, + * @var int|null a value indicating if this rule should be used for both request parsing and URL creation, * parsing only, or creation only. * If not set or 0, it means the rule is both request parsing and URL creation. * If it is [[PARSING_ONLY]], the rule is for request parsing only. @@ -336,7 +336,7 @@ private function translatePattern($allowAppendSlash) $this->pattern = '#^' . trim(strtr($this->_template, $tr), '/') . '$#u'; // if host starts with relative scheme, then insert pattern to match any - if (strncmp($this->host, '//', 2) === 0) { + if ($this->host !== null && strncmp($this->host, '//', 2) === 0) { $this->pattern = substr_replace($this->pattern, '[\w]+://', 2, 0); } @@ -541,9 +541,9 @@ public function createUrl($manager, $route, $params) /** * Returns status of the URL creation after the last [[createUrl()]] call. * - * @return null|int Status of the URL creation after the last [[createUrl()]] call. `null` if rule does not provide + * @return int|null Status of the URL creation after the last [[createUrl()]] call. `null` if rule does not provide * info about create status. - * @see $createStatus + * @see createStatus * @since 2.0.12 */ public function getCreateUrlStatus() diff --git a/framework/web/User.php b/framework/web/User.php index db1935fe605..81945a96abf 100644 --- a/framework/web/User.php +++ b/framework/web/User.php @@ -48,12 +48,11 @@ * ``` * * @property-read string|int $id The unique identifier for the user. If `null`, it means the user is a guest. - * This property is read-only. * @property IdentityInterface|null $identity The identity object associated with the currently logged-in * user. `null` is returned if the user is not logged in (not authenticated). - * @property-read bool $isGuest Whether the current user is a guest. This property is read-only. + * @property-read bool $isGuest Whether the current user is a guest. * @property string $returnUrl The URL that the user should be redirected to after login. Note that the type - * of this property differs in getter and setter. See [[getReturnUrl()]] and [[setReturnUrl()]] for details. + * of this property differs in getter and setter. See [[getReturnUrl()]] and [[setReturnUrl()]] for details. * * @author Qiang Xue * @since 2.0 @@ -81,7 +80,7 @@ class User extends Component */ public $enableSession = true; /** - * @var string|array the URL for login when [[loginRequired()]] is called. + * @var string|array|null the URL for login when [[loginRequired()]] is called. * If an array is given, [[UrlManager::createUrl()]] will be called to create the corresponding URL. * The first element of the array should be the route to the login action, and the rest of * the name-value pairs are GET parameters used to construct the login URL. For example, @@ -99,21 +98,21 @@ class User extends Component */ public $identityCookie = ['name' => '_identity', 'httpOnly' => true]; /** - * @var int the number of seconds in which the user will be logged out automatically if he + * @var int|null the number of seconds in which the user will be logged out automatically if the user * remains inactive. If this property is not set, the user will be logged out after * the current session expires (c.f. [[Session::timeout]]). * Note that this will not work if [[enableAutoLogin]] is `true`. */ public $authTimeout; /** - * @var CheckAccessInterface|string|array The access checker object to use for checking access or the application + * @var CheckAccessInterface|string|array|null The access checker object to use for checking access or the application * component ID of the access checker. * If not set the application auth manager will be used. * @since 2.0.9 */ public $accessChecker; /** - * @var int the number of seconds in which the user will be logged out automatically + * @var int|null the number of seconds in which the user will be logged out automatically * regardless of activity. * Note that this will not work if [[enableAutoLogin]] is `true`. */ @@ -131,6 +130,11 @@ class User extends Component * @var string the session variable name used to store the value of [[id]]. */ public $idParam = '__id'; + /** + * @var string the session variable name used to store authentication key. + * @since 2.0.41 + */ + public $authKeyParam = '__authKey'; /** * @var string the session variable name used to store the value of expiration timestamp of the authenticated state. * This is used when [[authTimeout]] is set. @@ -364,7 +368,7 @@ public function getIsGuest() /** * Returns a value that uniquely represents the user. - * @return string|int the unique identifier for the user. If `null`, it means the user is a guest. + * @return string|int|null the unique identifier for the user. If `null`, it means the user is a guest. * @see getIdentity() */ public function getId() @@ -380,7 +384,7 @@ public function getId() * This method reads the return URL from the session. It is usually used by the login action which * may call this method to redirect the browser to where it goes after successful authentication. * - * @param string|array $defaultUrl the default return URL in case it was not set previously. + * @param string|array|null $defaultUrl the default return URL in case it was not set previously. * If this is null and the return URL was not set previously, [[Application::homeUrl]] will be redirected to. * Please refer to [[setReturnUrl()]] on accepted format of the URL. * @return string the URL that the user should be redirected to after login. @@ -599,7 +603,8 @@ protected function getIdentityAndDurationFromCookie() if (!$identity instanceof IdentityInterface) { throw new InvalidValueException("$class::findIdentity() must return an object implementing IdentityInterface."); } elseif (!$identity->validateAuthKey($authKey)) { - Yii::warning("Invalid auth key attempted for user '$id': $authKey", __METHOD__); + $ip = Yii::$app->getRequest()->getUserIP(); + Yii::warning("Invalid cookie auth key attempted for user '$id' from $ip: $authKey", __METHOD__); } else { return ['identity' => $identity, 'duration' => $duration]; } @@ -649,14 +654,14 @@ public function switchIdentity($identity, $duration = 0) } $session = Yii::$app->getSession(); - if (!YII_ENV_TEST) { - $session->regenerateID(true); - } + $session->regenerateID(true); $session->remove($this->idParam); $session->remove($this->authTimeoutParam); + $session->remove($this->authKeyParam); if ($identity) { $session->set($this->idParam, $identity->getId()); + $session->set($this->authKeyParam, $identity->getAuthKey()); if ($this->authTimeout !== null) { $session->set($this->authTimeoutParam, time() + $this->authTimeout); } @@ -690,6 +695,18 @@ protected function renewAuthStatus() /* @var $class IdentityInterface */ $class = $this->identityClass; $identity = $class::findIdentity($id); + if ($identity === null) { + $this->switchIdentity(null); + } + } + + if ($identity !== null) { + $authKey = $session->get($this->authKeyParam); + if ($authKey !== null && !$identity->validateAuthKey($authKey)) { + $identity = null; + $ip = Yii::$app->getRequest()->getUserIP(); + Yii::warning("Invalid session auth key attempted for user '$id' from $ip: $authKey", __METHOD__); + } } $this->setIdentity($identity); @@ -754,10 +771,10 @@ public function can($permissionName, $params = [], $allowCaching = true) * @see acceptableRedirectTypes * @since 2.0.8 */ - protected function checkRedirectAcceptable() + public function checkRedirectAcceptable() { $acceptableTypes = Yii::$app->getRequest()->getAcceptableContentTypes(); - if (empty($acceptableTypes) || count($acceptableTypes) === 1 && array_keys($acceptableTypes)[0] === '*/*') { + if (empty($acceptableTypes) || (count($acceptableTypes) === 1 && array_keys($acceptableTypes)[0] === '*/*')) { return true; } diff --git a/framework/web/View.php b/framework/web/View.php index c77f59fba7a..bf03b42d75e 100644 --- a/framework/web/View.php +++ b/framework/web/View.php @@ -132,6 +132,11 @@ class View extends \yii\base\View public $jsFiles = []; private $_assetManager; + /** + * Whether [[endPage()]] has been called and all files have been registered + * @var bool + */ + private $_isPageEnded = false; /** @@ -174,6 +179,8 @@ public function endPage($ajaxMode = false) { $this->trigger(self::EVENT_END_PAGE); + $this->_isPageEnded = true; + $content = ob_get_clean(); echo strtr($content, [ @@ -195,7 +202,7 @@ public function endPage($ajaxMode = false) * * @param string $view the view name. Please refer to [[render()]] on how to specify this parameter. * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @param object $context the context that the view should use for rendering the view. If null, + * @param object|null $context the context that the view should use for rendering the view. If null, * existing [[context]] will be used. * @return string the rendering result * @see render() @@ -329,7 +336,7 @@ public function registerAssetBundle($name, $position = null) * will result in the meta tag ``. * * @param array $options the HTML attributes for the meta tag. - * @param string $key the key that identifies the meta tag. If two meta tags are registered + * @param string|null $key the key that identifies the meta tag. If two meta tags are registered * with the same key, the latter will overwrite the former. If this is null, the new meta tag * will be appended to the existing ones. */ @@ -379,7 +386,7 @@ public function registerCsrfMetaTags() * has more options for this kind of link tag. * * @param array $options the HTML attributes for the link tag. - * @param string $key the key that identifies the link tag. If two link tags are registered + * @param string|null $key the key that identifies the link tag. If two link tags are registered * with the same key, the latter will overwrite the former. If this is null, the new link tag * will be appended to the existing ones. */ @@ -396,7 +403,7 @@ public function registerLinkTag($options, $key = null) * Registers a CSS code block. * @param string $css the content of the CSS code block to be registered * @param array $options the HTML attributes for the `