Compare commits

..

304 Commits
master ... 3.0

Author SHA1 Message Date
Alexander Makarov fb45bf2386
Fixed typo 6 years ago
Alexander Makarov 86fbdcbe45
Added deprecation note 6 years ago
Brandon Kelly 1d5ae6de43 Fixed bug where component behaviors could be double-attached (#16663) 6 years ago
Sergey Aksenov 7f36d26f1c Fix namespace issue (#16602) 6 years ago
Andrii Vasyliev 08590596e5 Removed empty captcha directory and file (#16507) 6 years ago
Erik Verheij 6f19d3d4a9 Fixes #12895: Use custom error action when provided, regardless of the response format 6 years ago
Paul Klimov e28bf15754 Fixes #11389: `yii\base\Event` refactored to match commonly used notations 6 years ago
Andrii Vasyliev d24d795785 Fixes #16495: Added method call support in DI and `Yii::configure()` 6 years ago
Andrii Vasyliev 22c3126c1c Fixes #16487: Added circular reference detection in DI container 6 years ago
Brandon Kelly e1a49cfb6d Fixes #16247: Cloning components will now clone their behaviors as well 6 years ago
Mahesh S Warrier f903fb2c0a Fixes #16285: Modified yii\web\XmlResponseFormatter to accept attributes for XML elements 6 years ago
Alexander Makarov 705f3e4a80
Merge branch 'CjtMailer' of https://github.com/cjtterabytesoft/yii2 into cjtterabytesoft-CjtMailer 6 years ago
Alexander Makarov c184ef864e
Adjusted versioning 6 years ago
cjtterabyte 8cd14e7d54
Merge branch 'CjtMailer' of https://github.com/cjtterabytesoft/yii2 into CjtMailer 6 years ago
cjtterabyte 1c2320fd32
Fix getComposer() yii\BaseYii::createObject(null) BaseMailer.php #16327 6 years ago
Alexander Makarov 95e3237054
Update CHANGELOG.md 6 years ago
cjtterabyte 921447a25a
Fix getComposer() yii\BaseYii::createObject(null) BaseMailer.php #16327 6 years ago
cjtterabyte 9014f92bc5
Fix getComposer() yii\BaseYii::createObject(null) BaseMailer.php #16327 6 years ago
Alexander Makarov 32efb09902
Fixes #11397: `yii\i18n\MessageFormatter` polyfills and `yii\i18n\MessageFormatter::parse()` method were removed resulting in performance boost. See UPGRADE for compatibility notes 6 years ago
Carsten Brandt 501ddbeac3
Update PageCache.php 6 years ago
SilverFire - Dmitry Naumenko be8633702d
Fixing tests after meging with master 6 years ago
SilverFire - Dmitry Naumenko 1cc5f15635
Use null coalesce operator where possible 6 years ago
SilverFire - Dmitry Naumenko fa71f808c1
Merge branch 'master' into 2.1 6 years ago
Kuts Dmitriy 6b99e4f2e4 Change document root to public (#16254) 6 years ago
SilverFire - Dmitry Naumenko 2468282154
Fixing tests 6 years ago
SilverFire - Dmitry Naumenko b9ffea141c
Fixing tests 6 years ago
SilverFire - Dmitry Naumenko 4f33296491
Fixing tests 6 years ago
SilverFire - Dmitry Naumenko 3e4936982e
Fixing tests 6 years ago
SilverFire - Dmitry Naumenko e164c07145
Merge branch 'master' into 2.1 6 years ago
Carsten Brandt 290621ce4e
improved docs for DSN array syntax 7 years ago
Leandro Gehlen 892f1a8711 Added more docs about `yii\db\Connection::dsn` property (#16148) [skip ci] 7 years ago
Leandro Gehlen b576336beb Fixes #16126: Allows to configure `Connection::dsn` by config array 7 years ago
Pavel Ivanov c12e665dc8 Fixes #16067: added yii\build namespace to composer.json (#16078) 7 years ago
sashsvamir 115fa3f746 fix timezone (#16070) 7 years ago
Carsten Brandt 418fc416df
update yii version to 2.1 7 years ago
Carsten Brandt 7eadd66639
added 2.1 extensions to devcontroller 7 years ago
Roman Zhuravlev 9546bd8187 Fixes #16054: Callback execution with mutex synchronization 7 years ago
Dmitry Naumenko 8ecc361f2b
Merge pull request #15963 from rugabarbo/2.1-drop-deprecated-column-schema-properties 7 years ago
Robert Korulczyk 8a46b33ef7 Simplify yield test for `Command::batchInsert()`. (#16007) 7 years ago
Pavel Ivanov 3e25001a67 Issue #15957: dropped unnecessary PHP version checks (#15975) 7 years ago
Pavel Ivanov b0b06b1ad3 Issue #15957: dropped deprecated User::getAuthManager() method (#15981) 7 years ago
Pavel Ivanov 2c6bc8ff1c Issue #15957: dropped deprecated QueryBuilder condition builders (#15980) 7 years ago
Pavel Ivanov 741a569695 Issue #15957: dropped deprecated UniqueValidator::$comboNotUnique (#15976) 7 years ago
Pavel Ivanov b88bb2b9f7 Issue #15957: dropped deprecated createJunctionMigration template (#15977) 7 years ago
Pavel Ivanov a0b3e2bc15 Issue #15957: dropped deprecated Request::CSRF_MASK_LENGTH (#15970) 7 years ago
Pavel Ivanov e4285c59f1 Issue #15957: dropped deprecated Connection::$commandClass (#15966) 7 years ago
Pavel Ivanov a7f0fea200 Issue #15957: small fix of travis builds (#15967) 7 years ago
Pavel Ivanov 20fdf81711 Issue #15957: drop HHVM remains (#15965) 7 years ago
Pavel Ivanov 93a3260a3a Issue #15957: dropped deprecated Dependency method (#15962) 7 years ago
Pavel Ivanov 0babc4b299 Issue #15957: dropped deprecated View properties (#15961) 7 years ago
Pavel Ivanov 893f2a7bbd Issue #15957: dropped deprecated ColumnSchema properties 7 years ago
Pavel Ivanov f5315185dc Issue #15957: finally drop deprecated exit code constants (#15958) 7 years ago
Pavel Ivanov 4e15d33756 yii\base\Object finally dropped (#15956) 7 years ago
Pavel Ivanov 8005748714 #11560: removed ZendDataCache remains (#15955) 7 years ago
xicond faac174af8 Fixes #15811: Fixed issue with additional parameters on `yii\base\View::renderDynamic()` while parameters contains single quote introduced in #12938 7 years ago
Klimov Paul fdd761d6cb Added `yii\web\AssetConverter::$isOutdatedCallback` allowing custom check for outdated asset conversion result 7 years ago
Tobias Munk 25ffc7cefd added autoloading path for yii (CLI) when installed from yii2-dev (#15812) 7 years ago
Klimov Paul 43c8f457ba improve check for empty body at `Request::getParsedBody()` 7 years ago
Klimov Paul 854ae7127c fix `web\Request::getParsedBody()` throws exception for empty body without content-type 7 years ago
Klimov Paul 8ce498cf65 `OracleMutex` moved to "yiisoft/yii2-oracle" 7 years ago
Klimov Paul e74fbb1b0f CUBRID database support removed 7 years ago
Andrii Vasyliev d7cf629b10 Added support for `__construct()` in class configuration (#15815) 7 years ago
Klimov Paul d1ff652b2f class DI definitions changed to '__class' keyword 7 years ago
Klimov Paul b04e0e06dc added support for '__class' keyword at DI definitions 7 years ago
Klimov Paul 732d0a841f improve unit tests 7 years ago
Paul Klimov 603c084fbc
Fix #15383 drop PJAX (#15809) 7 years ago
Paul Klimov 13c37091d5 added changelog about extracted extensions 7 years ago
Paul Klimov 39e9ba74bc docs for REST moved to "yiisoft/yii2-rest" 7 years ago
Paul Klimov 7cf9116fe6 update docs 7 years ago
Paul Klimov 8779f7a187 unit tests clean up 7 years ago
Paul Klimov 0a5304419b 'mssql' and 'oracle' packages removed 7 years ago
Paul Klimov 5e2c16da66 `Captcha` references removed from unit tests 7 years ago
Paul Klimov fafa4044c0 fix 'filters' unit tests 7 years ago
Paul Klimov 0cb91006d5 'captcha' package removed 7 years ago
Paul Klimov 445c838fec update `composer.lock` 7 years ago
Paul Klimov c68e553879 'jquery' package removed 7 years ago
Paul Klimov bc77937bfd redundant 'compatibility' for PHPUnit removed 7 years ago
Paul Klimov 86abef49ff 'rest' package removed 7 years ago
Paul Klimov 624d39c43e upgrade note about extracted packages added 7 years ago
Paul Klimov f8893fe6c8 Merge branch 'master' of github.com:yiisoft/yii2 into 2.1 7 years ago
Paul Klimov 3b11ce91cb default condition builder class reference updated to use `::class` construction 7 years ago
Paul Klimov 0f6dbdd135 Merge branch 'master' of github.com:yiisoft/yii2 into 2.1 7 years ago
SilverFire - Dmitry Naumenko 41aa5d07ba
ReplaceArrayValue, UnsetArrayValue can be restored after `var_export()` 7 years ago
Paul Klimov ba73528038 Merge branch 'master' of github.com:yiisoft/yii2 into 2.1 7 years ago
Paul Klimov 56545c420a fix code to match '2.1' requirements 7 years ago
Paul Klimov a8d2127ad4 Merge branch 'master' of github.com:yiisoft/yii2 into 2.1 7 years ago
Klimov Paul 481970957b log level DB column type fix 7 years ago
Klimov Paul fdad1c98c5 DI container reset added to unit test 7 years ago
Klimov Paul e19d7a7917 reset logger after unit test moved to `tearDown()` 7 years ago
Klimov Paul 8e39886f62 reset logger after unit test added 7 years ago
Klimov Paul e31dda7f22 `log\DbTarget` fix 7 years ago
Klimov Paul d5117984b3 restored 'since' tag at `InvalidArgumentException` 7 years ago
Paul Klimov 9ef1c44749 fix unit tests 7 years ago
Paul Klimov 0a7327f87e fix CHANGELOG.md 7 years ago
Paul Klimov d86b716b08 unit test fix 7 years ago
Paul Klimov bccd260e9c fix `PageCache` to use actual `Response` properties 7 years ago
Paul Klimov 4c21603cb2 fix `CacheableWidgetBehaviorTest` unit test 7 years ago
Paul Klimov c3d8a3ddb4 `ActiveQueryTrait::createModels()` fix 7 years ago
Paul Klimov b44a461c2e `ActiveForm::$validationStateOn` restored 7 years ago
Paul Klimov a8b1f69d0c update code for 2.1 requirements 7 years ago
Klimov Paul c2694e7edc Merge branch 'master' of github.com:yiisoft/yii2 into 2.1 7 years ago
Klimov Paul 3b4412f195 'nestedLevel' added to Profiler messages 7 years ago
Alec Pritchard 523df834b0 Fixes #15490: Corrected recommended Apache config in start-installation.md (#15609) [skip ci] 7 years ago
Klimov Paul b01a749afd PHPDoc fix 7 years ago
Klimov Paul a39d1209ad fix code to match 2.1 7 years ago
Klimov Paul 29ce1e8687 Merge branches '2.1' and 'master' of github.com:yiisoft/yii2 into 2.1 7 years ago
Nikolay Oleynikov 21da0ed910 Remove legacy translation units (#15502) [skip ci] 7 years ago
Klimov Paul 7171db4e74 fix CHANGELOG.md 7 years ago
Klimov Paul fcc12fef65 remove outdated unit test 7 years ago
Klimov Paul e7da8b52a0 Merge branch '2.1' of github.com:yiisoft/yii2 into 2.1 7 years ago
Klimov Paul f1a738ec07 `InvalidParamException` usage removed 7 years ago
Klimov Paul 13d443a68a fix unit tests 7 years ago
Alexander Makarov d5f1627868
#15481: Removed Yii::powered() 7 years ago
Klimov Paul 359175c04b update code to match 2.1 7 years ago
Klimov Paul 9b86c46842 Merge branch 'master' of github.com:yiisoft/yii2 into 2.1 7 years ago
Vladimir Khramtsov 0391a367ed Improved BaseYii tests (#15467) 7 years ago
Alexander Makarov 61dec0f021
#15481: Html::powered() -> Html::poweredByYii() 7 years ago
Nikolay Oleynikov fd9384fc00 Fixes #15481: Moved `yii\BaseYii::powered()` method to `yii\helpers\Html::powered()` 7 years ago
Dmitry Naumenko 866c70d62e
Merge pull request #15448 from klimov-paul/optional-html-purifier 7 years ago
Vladimir Khramtsov 646cd73548 Fix code issues (#15450) 7 years ago
Klimov Paul da364fa419 notes improved 7 years ago
Klimov Paul 7e3f096bc0 `BaseHtmlPurifier::createConfig()` extracted 7 years ago
Klimov Paul 3666f2c957 wording improvement 7 years ago
Klimov Paul 3ff4eade2f "ezyang/htmlpurifier" package has been made optional 7 years ago
Paul Klimov bf116e6103 Fix #8452 Jquery Extraction (attempt 2) (#14865) 7 years ago
Klimov Paul 75349fdeb3 fix UPGRADE 7 years ago
Klimov Paul 796aed8d16 Merge branch '2.1' of github.com:yiisoft/yii2 into 2.1 7 years ago
Paul Klimov 874fcaaecb
`Psr\Http\Message\ServerRequestInterface` applied for `yii\web\Request` (#15416) 7 years ago
Klimov Paul a21c9fd8eb CHANGELOG fix 7 years ago
Alexander Makarov 87fde26d6d
Fixes #15410: Added serialization abstraction layer under `yii\serialize\*` namespace 7 years ago
Alexander Makarov 9a802dbf34
Fix not -> no [skip ci] 7 years ago
Klimov Paul dcc74c841a added UPGRADE and CHANGELOG 7 years ago
Klimov Paul ef3e89e36c `SerializerInterface` applied for `SimpleCache` 7 years ago
Klimov Paul 2fb0b05a0f `yii\serialize\*` package created 7 years ago
Alexander Makarov 45eed055cb
Fixed changelog [skip ci] 7 years ago
Alexander Makarov 11ecfc54f8
Fixed TargetTest 7 years ago
Alexander Makarov b997fdace6
Fixed FileValidatorTest 7 years ago
Alexander Makarov ac167cbd10
More test fixes 7 years ago
Alexander Makarov 742e7b81f6
Fixed BaseObject merge 7 years ago
Alexander Makarov 66b6e48f1a
Test fixes 7 years ago
Alexander Makarov b62077d581
Merge branch 'master' into 2.1 7 years ago
Elvira Sheina 7ce415b8c7 Fixes #9137: Added `clearErrors` parameter to `yii\base\Model` `validateMultiple()` method 7 years ago
E.Alamo 34865a7eb0 Fixed a typo in Widget description (#15063) [skip ci] 7 years ago
243083df 08cafaa2ee Change call_user_func_array to ...$args (#15029) 7 years ago
243083df cac4462e7a Updated code formatting and PHP 7 usage 7 years ago
Klimov Paul c421a121d2 `yii\profile\FileTarget` added 7 years ago
Klimov Paul 2cfbc38bf8 Fix typos at UPGRADE 7 years ago
Paul Klimov 497a073dfd Merge uploaded files into body params (#14817) 7 years ago
Paul Klimov a136f414ec Merge pull request #14853 from klimov-paul/merge-2.1-1 7 years ago
Klimov Paul d039605dd1 `DbManagerTestCase` unit test fix 7 years ago
Klimov Paul 82ea6a86ee `ListViewTest` unit test fix 7 years ago
Klimov Paul 3ff59d37ee merge fix 7 years ago
Klimov Paul fcff67548c `className()` usage remove 7 years ago
Klimov Paul a5b9af951e merge fix 7 years ago
Klimov Paul 4488a6d9af Merge branch 'master' into '2.1' 7 years ago
Klimov Paul 83fa82aceb `Requst::getRawBody()` usage removed 7 years ago
Klimov Paul ee81a042cf Docs fix 7 years ago
Paul Klimov e0a7baf631 Move uploaded files inside Request (#14801) 7 years ago
Klimov Paul 8854793834 unit test fix 7 years ago
Klimov Paul e7943971d2 `yii\web\Request::getBodyParams()` now generates 415 'Unsupported Media Type' error on invalid or missing 'Content-Type' header 7 years ago
Paul Klimov e703645b4d Change `RequestParserInterface::parse()` to accept whole `Request` instance (#14784) 7 years ago
Klimov Paul 5c7bdb32a6 fix unit tests 7 years ago
Klimov Paul 257604f19e `HeaderCollection::fromArray()` improved to handle header name different case 7 years ago
Klimov Paul 37580db6b1 unit test fix 7 years ago
Klimov Paul 722022f744 HTTP headers checks refactored to use PSR-7 abstraction 7 years ago
Alexander Makarov 3c16faa5b0 Fixes #14761: Removed Yii autoloader in favor of Composer's PSR-4 implementation 7 years ago
Klimov Paul 2e01076abc `yii\filters\ContentNegotiator` now generates 406 'Not Acceptable' instead of 415 'Unsupported Media Type' on content-type negotiation fail 7 years ago
Klimov Paul 89c14b7dea Fixed `yii\filters\VerbFilter` uses case-insensitive comparison for the HTTP method name 7 years ago
Alexander Makarov 2e267461a1
Another optimization for #11328 7 years ago
Alexander Makarov 4f9c642d74
Minor optimization for #11328 7 years ago
Paul Klimov e82b9c72f3 Fix #11328 PSR-7 HTTP Message Integration (#14701) 7 years ago
Alexander Makarov dc42a59b71
Removed reference to APC from docs [skip ci] 7 years ago
Klimov Paul 08e5e1e71b `CHANGELOG.md` fix 7 years ago
Klimov Paul c39a1ba4c3 missing "psr/log" added to `composer.json` 7 years ago
Paul Klimov 3e6f8b1c19 Fix #13702 PSR Logger (#14611) 7 years ago
Paul Klimov 4d9204d9f3 Fixes #879: Caching implementation refactored according to PSR-16 'Simple Cache' specification 7 years ago
Paul Klimov 28b26fb74b fix unit test 7 years ago
Ruitang Du 003d83c6e0 Fixes #14671: use `random_int()` instead of `mt_rand()` to generate cryptographically secure pseudo-random integers 7 years ago
Paul Klimov a015795c7b Refactor CAPTCHA extracting Driver (#14632) 7 years ago
Paul Klimov f590670ac9 Fix #9260 introduce `yii\mail\Template` class, allowing view rendering in isolation (#13809) 7 years ago
Boudewijn Vahrmeijer 209bcf0773 fix broken PHPDefaultFormat test with correct expected outputs (#14560) 7 years ago
Boudewijn Vahrmeijer 6605d9830b Fix risky test by add expects assertions (#14559) 7 years ago
Boudewijn Vahrmeijer 31a405bf80 Recreate test based on naming & consistency with previous test (#14557) 7 years ago
Alexander Makarov 42a7f2b012 Use APCu instead of APC in travis 7 years ago
Alexander Makarov cc869d2587
Fixed some OS-dependent checks in tests 7 years ago
Alexander Makarov 2875624600
::className() -> ::class 7 years ago
Alexander Makarov 0b421596a0
Fixed AssetBundleTest to work on Windows 7 years ago
Alexander Makarov e52e1124c1
Fixed ViewTest to use OS-dependent newline under Windows 7 years ago
Alexander Makarov 1b45ed9691
Merge branch 'master' into 2.1 7 years ago
Alexander Makarov a94e804ae4 Cleaned up everything that isn't needed for PHP 7.1 (#14511) 7 years ago
Alexander Makarov adca091fbf
Added note about APCu config to upgrade guide 7 years ago
Alexander Makarov fc47291b7e Fixes #13885: Removed APC support in ApcCache. APCu works as before 7 years ago
Alexander Makarov 85df384e8f Fixes #14178: Removed HHVM-specific code 7 years ago
Alexander Makarov ceaf101151
Merge branch 'master' into 2.1 7 years ago
Alexander Makarov 6100194bf7 Removed PHPUnit6 compatibility polyfill, fixed some tests 7 years ago
Alexander Makarov d4e7cf0171
Merge branch 'master' into 2.1 7 years ago
Alexander Makarov 3e688c1a6b
Updated composer.json 7 years ago
Alexander Makarov d98f0aff1a
Merged master 7 years ago
Alexander Makarov 0297c4e2aa
Fixed DataColumn 7 years ago
Alexander Makarov 2a9d4efc45
Additional merge fixes 7 years ago
Alexander Makarov 207f8cc0d5
Merge fixes 7 years ago
Alexander Makarov 66095fb89a
Merged master 7 years ago
Alexander Makarov f41399a6dc
Reverted selective code coverage 7 years ago
Alexander Makarov 7ef2cf55b3
Fixed accidental change 7 years ago
Alexander Makarov 75dda6e08a PHP 7.1 updates, part of #11397 7 years ago
Angel Guevara 0117459444 Used PHP 7 list syntax where appropriate 7 years ago
Alexander Makarov 51a5d78c95
Updated changelog and readme [skip ci] 7 years ago
Alexander Makarov c3bca69b5b
Removed inputmask dependency since it's moved to separate extension 7 years ago
Alexander Makarov 8e7ebfdad4
Removed support for memcache (without D) 7 years ago
Alexander Makarov add189e5ef
Adjusted travis not to tests against anything lower than 7.1 and drop HHVM 7 years ago
Alexander Makarov 68543a63ff
Adjusted composer.json 7 years ago
Alexander Makarov acef7e1e7c
Adjusted comment [skip ci] 7 years ago
Alexander Makarov f475affaeb
Removed duplicate handling for \Throwable and \Exception 7 years ago
Alexander Makarov 0afc410d12
Merged branch 'master' into 2.1 7 years ago
Bob van Leeuwen 7c85258c36
Fixing issue with filterInputValidation variable in DataColumn 7 years ago
刘旭 e310618168 Fixed typos in 'zh-CN' docs [skip ci] 8 years ago
Alexander Makarov 7aeb008a5d
Replaced className() with class 8 years ago
Alexander Makarov 1f97e03b4f
Merged master into 2.1 8 years ago
Alexander Makarov 68dd3d4567
Merge branch 'master' into 2.1 8 years ago
Klimov Paul 07f65f411b unit test `CommandTest` fix 8 years ago
Klimov Paul aca84c9a7a fix `db` unit tests 8 years ago
Klimov Paul 498ecb3b4f `className()` method usage removed 8 years ago
Klimov Paul bd989566ff unit test for `mail` fix 8 years ago
Klimov Paul e3f26cc5dc Methods `addHeader()`, `setHeader()`, `getHeader()`, `setHeaders()` have been added to `yii\i18n\MessageInterface` allowing setup of custom message headers 8 years ago
Alexander Makarov f7a4838026
Merge branch 'master' into 2.1 8 years ago
Alexander Makarov 0aca17dcfb
Merge branch 'master' into 2.1 8 years ago
Alexander Makarov 575609f21d
Merge branch 'master' into 2.1 8 years ago
Alexander Makarov a21c4a8dc0
Moved masked input field widget into separate extension https://github.com/yiisoft/yii2-maskedinput 8 years ago
Alexander Makarov a7b9ef650c
Adjusted widget tests 8 years ago
Alexander Makarov 9eabc170ad
Fixed merge bug 8 years ago
Alexander Makarov 736fb099fb
Fixed className() usage in tests 8 years ago
Alexander Makarov d6892d554a
Merge branch 'master' into 2.1 8 years ago
Alexey Rogachev 62932ef321 Fixed typo in CHANGELOG (#13164) 8 years ago
Alexey Rogachev 409c56c5c5 Rename `yii\base\InvalidParamException` to `yii\base\InvalidArgumentException` (#13082) 8 years ago
SilverFire - Dmitry Naumenko 8ea211771c Skip FormatConverterTest::testPHPDefaultFormat on HHVM. 8 years ago
SilverFire - Dmitry Naumenko 7a47f5f8c1 Fixed HHVM tests compatibility. Try 3 8 years ago
SilverFire - Dmitry Naumenko 511784631b Fixed HHVM tests compatibility. Try 2 8 years ago
SilverFire - Dmitry Naumenko 2ab2fd96cc Fixed HHVM tests compatibility 8 years ago
SilverFire - Dmitry Naumenko 7f8fdf9d56 Merge branch 'master' into 2.1 8 years ago
SilverFire - Dmitry Naumenko b063323547 Fixed code style for tests 8 years ago
Carsten Brandt 55a827dad9 ensure fallback format is consistent with ICU (#7800) 8 years ago
boehsermoe c2cd20ee49 Captcha:: have to start with /, otherwise it does not work in modules. (#13006) 8 years ago
SilverFire - Dmitry Naumenko a560db1a8f Fixed CHANGELOG 8 years ago
SilverFire - Dmitry Naumenko c64cfa9373 Merge branch 'lennartvdd-activeFormHiddenField' into 2.1 8 years ago
SilverFire - Dmitry Naumenko fcba5f3171 Merge branch 'activeFormHiddenField' of git://github.com/lennartvdd/yii2 into lennartvdd-activeFormHiddenField 8 years ago
SilverFire - Dmitry Naumenko a94c2e611d `yii\widgets\GridView::run() added missing return. Updated UPGRADE.md 8 years ago
SilverFire - Dmitry Naumenko a8be03f2b1 Fixed tests 8 years ago
SilverFire - Dmitry Naumenko e45f5c3b4f Replaced `::className()` in PHPDocs and some classes 8 years ago
SilverFire - Dmitry Naumenko 76e6a20cee Replaced all `::className()` calls to `::class` 8 years ago
SilverFire - Dmitry Naumenko 1e24d9a92e Fixed composer.json to build on PHP 5.5+ 8 years ago
SilverFire - Dmitry Naumenko d335fd6ea3 Merge branch 'master' into 2.1 8 years ago
Michael Härtl 224aac83ab Issue #12938 Add $params to View::renderDynamic() (#12955) 8 years ago
Dmitry Naumenko 164f35afef Merge pull request #12704 from rob006/enable-url-normalizer 8 years ago
Robert Korulczyk c597518378 Update upgrade note 8 years ago
Robert Korulczyk 41f5981561 Update guide 8 years ago
Robert Korulczyk a77749a6a1 Enable `UrlNormalizer` in `UrlManger` by default 8 years ago
Yordan Ivanov 0d72e37f3c Fixes #11058: Add `$checkAjax` parameter to method `yii\web\Controller::redirect()` which controls redirection in AJAX and PJAX requests 8 years ago
Alexander Makarov 2f53cee566 Fixed className() usage 8 years ago
Alexander Makarov 46e68bf9ec Merge branch 'master' into 2.1 8 years ago
Dmitry Naumenko 78224615ad Merge pull request #12607 from dynasource/12592-improve-performance-accesscontrol 8 years ago
Boudewijn Vahrmeijer 410ceab3ae #12592 enhance performance by ignoring rules that (in the end) are never used 8 years ago
Dmitry Naumenko eea58f3462 Merge pull request #12585 from brandonkelly/2.1-class 8 years ago
Brandon Kelly e94a46d720 ::className() => ::class in the docs 8 years ago
Alexander Makarov b5c2407c1d Merge branch 'master' into 2.1 8 years ago
Alexander Makarov f3478bb59b Fixes #11560: Removed XCache and Zend data cache support as caching backends 8 years ago
Alexander Makarov b53430f959 Replaced ::className() with ::class 8 years ago
Alexander Makarov 2722b3a7cf #12074: Updated `yii\widgets\ActiveField::hint()` method signature to match `label()` 8 years ago
Alexander Makarov 653362e6f8 Merge branch 'master' into 2.1 8 years ago
Alexander Makarov f8cf1e2b6a Merge branch 'master' into 2.1 8 years ago
Carsten Brandt 6791fdf1c4 revert ActiveRelationTrait abstract methods 8 years ago
Carsten Brandt aeadab5012 better method contract for ActiveRelationTrait 8 years ago
Carsten Brandt 8c03e6753b applied missing params for #10682 to mssql and oci query builder 8 years ago
Alexander Makarov b764b42f51 Merge branch 'master' into 2.1 8 years ago
Carsten Brandt fcfd54a28c Merge branch 'master' into 2.1 8 years ago
Carsten Brandt 9b54694bb0 fixed breadcrumb widget test 8 years ago
Carsten Brandt 98ed490c3d Consistent behavior of `run()` method in widgets 8 years ago
Kirill Pomerantsev 7f61cc81d8 change echo to return 8 years ago
Alexander Makarov c952e8052b Removed deprecated method 8 years ago
Alexander Makarov 5ebdf6c29a Merge branch 'master' into 2.1 8 years ago
Lennart van den Dool 30286387db Update CHANGELOG.md 8 years ago
Lennart van den Dool 79bdc5eb15 Automatically turn off field label on ActiveField->hiddenInput() 8 years ago
Alexander Makarov f8358acaeb Fixed usage of ::className() instead of ::class 8 years ago
Alexander Makarov a10365a3db Merge branch 'master' into 2.1 8 years ago
Carsten Brandt 04949e1ab4 Merge pull request #11477 from Faryshta/patch-2 8 years ago
Angel Guevara f978199fcc more changes 9 years ago
Angel Guevara 35d7cacfbd simplify default classes 9 years ago
Angel Guevara 0dee3509a8 simplify `::class` usage 9 years ago
Carsten Brandt 82d36df284 fixed test break 9 years ago
Angel Guevara e880ff2ff6 fix #11473 trailing backslash in class (#11474) 9 years ago
Carsten Brandt 25ac762d8c expression support in orderBy and groupBy (#10693) 9 years ago
Carsten Brandt 9e830b1fbf UPGRADE note about #10693 9 years ago
Carsten Brandt b41e720bf8 more test fixes for ::className() -> ::class 9 years ago
Carsten Brandt 9cf7ffa186 fixed tests for ::class syntax 9 years ago
Carsten Brandt 636591d284 ::class syntax in the Guide 9 years ago
Carsten Brandt 0888d6967b removed yii\base\Object::className() 9 years ago
Carsten Brandt b503dc9ff2 use ::class also in documentation and configs 9 years ago
Carsten Brandt 88a4f4ae9f Use ::class instead of ::className() 9 years ago
Alexander Makarov c5efe32c28 Fixes #11397: Minimum required version of PHP is 5.6.0 now 9 years ago
Alexander Makarov 52d70732c1 Fixed merge artifact in CHANGELOG 9 years ago
Alexander Makarov 64e134c29c Merge branch 'master' into 2.1 9 years ago
Alexander Makarov 6e947c84be Use current cache method names in tests 9 years ago
Alexander Makarov 9b1a87b776 Changelog 9 years ago
Alexander Makarov b05e01b2d4 Remove deprecated methods and constants 9 years ago
Alexander Makarov 083db9792d Merge branch 'master' into 2.1 9 years ago
  1. 3
      .appveyor.yml
  2. 8
      .codeclimate.yml
  3. 5
      .github/FUNDING.yml
  4. 9
      .github/PULL_REQUEST_TEMPLATE.md
  5. 6
      .github/SECURITY.md
  6. 113
      .github/workflows/build.yml
  7. 103
      .github/workflows/ci-mssql.yml
  8. 80
      .github/workflows/ci-mysql.yml
  9. 81
      .github/workflows/ci-oracle.yml
  10. 84
      .github/workflows/ci-pgsql.yml
  11. 7
      .gitignore
  12. 23
      .gitlab-ci.yml
  13. 2
      .php_cs
  14. 22
      .scrutinizer.yml
  15. 149
      .travis.yml
  16. 4
      Dockerfile
  17. 23
      README.md
  18. 27
      ROADMAP.md
  19. 28
      build/controllers/DevController.php
  20. 32
      build/controllers/MimeTypeController.php
  21. 206
      build/controllers/PhpDocController.php
  22. 40
      build/controllers/ReleaseController.php
  23. 7
      build/controllers/TranslationController.php
  24. 4
      build/controllers/Utf8Controller.php
  25. 6
      code-of-conduct.md
  26. 68
      composer.json
  27. 2118
      composer.lock
  28. 2
      contrib/completion/bash/yii
  29. 5
      cs/src/YiiConfig.php
  30. 205
      docs/guide-ar/README.md
  31. 57
      docs/guide-ar/intro-yii.md
  32. 290
      docs/guide-ar/start-databases.md
  33. 253
      docs/guide-ar/start-forms.md
  34. 161
      docs/guide-ar/start-gii.md
  35. 149
      docs/guide-ar/start-hello.md
  36. 303
      docs/guide-ar/start-installation.md
  37. 36
      docs/guide-ar/start-looking-ahead.md
  38. 25
      docs/guide-ar/start-prerequisites.md
  39. 115
      docs/guide-ar/start-workflow.md
  40. 2
      docs/guide-de/README.md
  41. 17
      docs/guide-es/README.md
  42. 18
      docs/guide-es/caching-data.md
  43. 4
      docs/guide-es/caching-http.md
  44. 4
      docs/guide-es/concept-aliases.md
  45. 2
      docs/guide-es/concept-autoloading.md
  46. 10
      docs/guide-es/concept-behaviors.md
  47. 6
      docs/guide-es/concept-di-container.md
  48. 2
      docs/guide-es/concept-events.md
  49. 20
      docs/guide-es/db-dao.md
  50. 2
      docs/guide-es/db-migrations.md
  51. 2
      docs/guide-es/db-query-builder.md
  52. 2
      docs/guide-es/glossary.md
  53. 8
      docs/guide-es/helper-array.md
  54. 8
      docs/guide-es/helper-html.md
  55. 14
      docs/guide-es/input-file-upload.md
  56. 2
      docs/guide-es/input-validation.md
  57. 16
      docs/guide-es/intro-upgrade-from-v1.md
  58. 44
      docs/guide-es/intro-yii.md
  59. 421
      docs/guide-es/output-data-providers.md
  60. 245
      docs/guide-es/output-data-widgets.md
  61. 127
      docs/guide-es/rest-authentication.md
  62. 156
      docs/guide-es/rest-controllers.md
  63. 94
      docs/guide-es/rest-error-handling.md
  64. 203
      docs/guide-es/rest-quick-start.md
  65. 44
      docs/guide-es/rest-rate-limiting.md
  66. 190
      docs/guide-es/rest-resources.md
  67. 157
      docs/guide-es/rest-response-formatting.md
  68. 92
      docs/guide-es/rest-routing.md
  69. 111
      docs/guide-es/rest-versioning.md
  70. 2
      docs/guide-es/runtime-bootstrapping.md
  71. 10
      docs/guide-es/runtime-responses.md
  72. 6
      docs/guide-es/runtime-sessions-cookies.md
  73. 4
      docs/guide-es/security-authorization.md
  74. 2
      docs/guide-es/security-passwords.md
  75. 2
      docs/guide-es/start-databases.md
  76. 2
      docs/guide-es/start-hello.md
  77. 20
      docs/guide-es/start-installation.md
  78. 16
      docs/guide-es/start-looking-ahead.md
  79. 29
      docs/guide-es/start-prerequisites.md
  80. 4
      docs/guide-es/start-workflow.md
  81. 6
      docs/guide-es/structure-applications.md
  82. 26
      docs/guide-es/structure-assets.md
  83. 2
      docs/guide-es/structure-controllers.md
  84. 4
      docs/guide-es/structure-entry-scripts.md
  85. 42
      docs/guide-es/structure-extensions.md
  86. 6
      docs/guide-es/structure-filters.md
  87. 6
      docs/guide-es/structure-models.md
  88. 2
      docs/guide-es/structure-modules.md
  89. 2
      docs/guide-es/structure-overview.md
  90. 10
      docs/guide-es/structure-views.md
  91. 151
      docs/guide-es/structure-widgets.md
  92. 20
      docs/guide-es/test-acceptance.md
  93. 58
      docs/guide-es/test-environment-setup.md
  94. 2
      docs/guide-es/test-fixtures.md
  95. 26
      docs/guide-es/test-functional.md
  96. 80
      docs/guide-es/test-overview.md
  97. 34
      docs/guide-es/test-unit.md
  98. 3
      docs/guide-es/translators.json
  99. 6
      docs/guide-es/tutorial-core-validators.md
  100. 2
      docs/guide-es/tutorial-start-from-scratch.md
  101. Some files were not shown because too many files have changed in this diff Show More

3
.appveyor.yml

@ -1,10 +1,11 @@
build: false
version: dev-{build}
shallow_clone: true
clone_folder: C:\projects\yii2
environment:
matrix:
- php_ver: 7.2.4
- php_ver: 7.2.4
cache:
- '%APPDATA%\Composer'

8
.codeclimate.yml

@ -22,11 +22,3 @@ exclude_paths:
- build/
- docs/
- framework/messages/
checks:
file-lines:
enabled: false
method-count:
enabled: false
method-lines:
enabled: false

5
.github/FUNDING.yml

@ -1,5 +0,0 @@
# These are supported funding model platforms
open_collective: yiisoft
github: [yiisoft]
tidelift: "packagist/yiisoft/yii2"

9
.github/PULL_REQUEST_TEMPLATE.md

@ -1,6 +1,7 @@
| Q | A
| ------------- | ---
| Is bugfix? | ✔/❌
| New feature? | ✔/❌
| Breaks BC? | ✔/❌
| Fixed issues | <!-- comma-separated list of tickets # fixed by the PR, if any -->
| Is bugfix? | yes/no
| New feature? | yes/no
| Breaks BC? | yes/no
| Tests pass? | yes/no
| Fixed issues | comma-separated list of tickets # fixed by the PR, if any

6
.github/SECURITY.md

@ -1,6 +0,0 @@
# Security Policy
Please use the [security issue form](https://www.yiiframework.com/security) to report to us any security issue you find in Yii.
DO NOT use the issue tracker or discuss it in the public forum as it will cause more damage than help.
Please note that as a non-commercial OpenSource project we are not able to pay bounties at the moment.

113
.github/workflows/build.yml

@ -1,113 +0,0 @@
name: build
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:
name: PHP ${{ matrix.php }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: yiitest
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
postgres:
image: postgres:9.6
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: yiitest
ports:
- 5432:5432
options: --name=postgres --health-cmd="pg_isready" --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', '8.1']
steps:
- name: Generate french locale
run: sudo locale-gen fr_FR.UTF-8
- name: Checkout
uses: actions/checkout@v2
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
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 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
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 $PHPUNIT_EXCLUDE_GROUP --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: mssql,oci,wincache,xcache,zenddata,cubrid
if: matrix.php >= '7.2'
- name: PHP Unit tests for PHP <= 7.0
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
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.2
ini-values: session.save_path=${{ runner.temp }}
- 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
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: Install node.js
uses: actions/setup-node@v1
with:
node-version: 6
- name: Tests
run: |
npm install
npm test
# env:
# CI: true

103
.github/workflows/ci-mssql.yml

@ -1,103 +0,0 @@
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@v2.3.4
- 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@v2
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

80
.github/workflows/ci-mysql.yml

@ -1,80 +0,0 @@
on:
- pull_request
- push
name: ci-mysql
jobs:
tests:
name: PHP ${{ matrix.php-version }}-mysql-${{ matrix.mysql-version }}
env:
extensions: curl, intl, pdo, pdo_mysql
key: cache-v1
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
php-version:
- "7.4"
mysql-version:
- "latest"
services:
mysql:
image: mysql:${{ matrix.mysql-version }}
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: yiitest
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup cache environment
id: cache-env
uses: shivammathur/cache-extensions@v1
with:
php-version: ${{ matrix.php-version }}
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-version }}
extensions: ${{ env.extensions }}
ini-values: date.timezone='UTC'
coverage: pcov
- name: Determine composer cache directory
if: matrix.os == 'ubuntu-latest'
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
- name: Cache dependencies installed with composer
uses: actions/cache@v1
with:
path: ${{ env.COMPOSER_CACHE_DIR }}
key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}
restore-keys: |
php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-
- name: Install dependencies with composer
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
- name: Run mysql tests with phpunit
run: vendor/bin/phpunit --group mysql --colors=always

81
.github/workflows/ci-oracle.yml

@ -1,81 +0,0 @@
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@v2
- 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@v2
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

84
.github/workflows/ci-pgsql.yml

@ -1,84 +0,0 @@
on:
- pull_request
- push
name: ci-pgsql
jobs:
tests:
name: PHP ${{ matrix.php-version }}-pgsql-${{ matrix.pgsql-version }}
env:
extensions: curl, intl, pdo, pdo_pgsql
key: cache-v1
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
php-version:
- "7.4"
pgsql-version:
- "10"
- "11"
- "12"
- "13"
services:
postgres:
image: postgres:${{ matrix.pgsql-version }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: yiitest
ports:
- 5432:5432
options: --name=postgres --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup cache environment
id: cache-env
uses: shivammathur/cache-extensions@v1
with:
php-version: ${{ matrix.php-version }}
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-version }}
extensions: ${{ env.extensions }}
ini-values: date.timezone='UTC'
coverage: pcov
- name: Determine composer cache directory
if: matrix.os == 'ubuntu-latest'
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
- name: Cache dependencies installed with composer
uses: actions/cache@v1
with:
path: ${{ env.COMPOSER_CACHE_DIR }}
key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}
restore-keys: |
php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-
- name: Install dependencies with composer
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
- name: Run pgsql tests with phpunit
run: vendor/bin/phpunit --group pgsql --colors=always

7
.gitignore vendored

@ -1,6 +1,5 @@
# phpstorm project files
.idea
*.iml
# netbeans project files
nbproject
@ -14,16 +13,11 @@ nbproject
*.sublime-project
*.sublime-workspace
# visual studio code project files
.vscode
# windows thumbnail cache
Thumbs.db
# composer vendor dir
/vendor
# cubrid install dir
/cubrid
# composer itself is not needed
composer.phar
@ -47,4 +41,3 @@ phpunit.phar
# NPM packages
/node_modules
.env
package-lock.json

23
.gitlab-ci.yml

@ -4,12 +4,13 @@ services:
- docker:dind
variables:
DOCKER_YII2_PHP_IMAGE: yiisoftware/yii2-php:7.4-apache
DOCKER_YII2_PHP_IMAGE: yiisoftware/yii2-php:7.1-apache
DOCKER_MYSQL_IMAGE: percona:5.7
DOCKER_POSTGRES_IMAGE: postgres:9.3
before_script:
- apk add --no-cache git curl docker-compose
- apk add --no-cache python py2-pip git
- pip install --no-cache-dir docker-compose==1.16.0
- docker info
- cd tests
@ -41,7 +42,7 @@ db:
- tests/full
script:
- docker-compose up --build -d
- docker-compose run --rm php vendor/bin/phpunit -v --group db --exclude caching,mysql,pgsql,mssql,cubrid,oci
- docker-compose run --rm php vendor/bin/phpunit -v --group db --exclude caching,mysql,pgsql
mysql:
@ -70,20 +71,6 @@ pgsql:
- docker-compose run --rm php vendor/bin/phpunit -v --group pgsql
cubrid:
stage: test
only:
- tests/cubrid
- tests/extra
script:
- cd cubrid
- docker-compose up --build -d
# wait for db (retry X times)
- docker-compose run --rm php bash -c 'while [ true ]; do curl cubrid:1523; if [ $? == 56 ]; then break; fi; ((c++)) && ((c==20)) && break; sleep 3; done'
- sleep 5
- docker-compose run --rm php /project/vendor/bin/phpunit -v --group cubrid
mssql:
stage: test
only:
@ -109,5 +96,5 @@ travis:
- docker-compose up --build -d
# wait for dbs ...
- sleep 10
- docker-compose run --rm php vendor/bin/phpunit -v --exclude mssql,cubrid,oci,wincache,xcache,zenddata,cubrid
- docker-compose run --rm php vendor/bin/phpunit -v --exclude wincache,xcache

2
.php_cs

@ -1,7 +1,7 @@
<?php
if (!class_exists('yii\cs\YiisoftConfig', true)) {
// TODO: change error message
// @todo change error message
fwrite(STDERR, "Your php-cs-version is outdated: please upgrade it.\n");
die(16);
}

22
.scrutinizer.yml

@ -1,20 +1,10 @@
build:
nodes:
analysis:
tests:
override:
- php-scrutinizer-run
filter:
excluded_paths:
- "tests/"
- "build/"
- "docs/"
- "framework/messages/"
dependency_paths:
- "vendor/"
imports:
- php
tools:
external_code_coverage:
runs: 3
timeout: 2100 # Timeout in seconds.
# disable copy paste detector and similarity analyzer as they have no real value
# and a huge bunch of false-positives
php_sim: false
php_cpd: false

149
.travis.yml

@ -0,0 +1,149 @@
#
# Travis Setup
#
# use ubuntu trusty for newer version of nodejs, used for JS testing
dist: trusty
# faster builds on new travis setup not using sudo
# temporary disable, see https://github.com/travis-ci/travis-ci/issues/6842
#sudo: false
sudo: required
group: edge
# build only on master branches
# commented as this prevents people from running builds on their forks:
# https://github.com/yiisoft/yii2/commit/bd87be990fa238c6d5e326d0a171f38d02dc253a
#branches:
# only:
# - master
# - 3.0
#
# Test Matrix
#
language: php
env:
global:
- DEFAULT_COMPOSER_FLAGS="--prefer-dist --no-interaction --no-progress --optimize-autoloader"
- TASK_TESTS_PHP=1
- TASK_TESTS_COVERAGE=0
- TRAVIS_SECOND_USER=travis_two
services:
- memcached
- mysql
- postgresql
# cache vendor dirs
cache:
directories:
- vendor
- $HOME/.composer/cache
- $HOME/.npm
# try running against postgres 9.6
addons:
postgresql: "9.6"
apt:
sources:
- mysql-5.7-trusty
packages:
- mysql-server
code_climate:
repo_token: 2935307212620b0e2228ab67eadd92c9f5501ddb60549d0d86007a354d56915b
matrix:
fast_finish: true
include:
- php: 7.2
# run tests coverage on PHP 7.1
- php: 7.1
env: TASK_TESTS_COVERAGE=1
- php: nightly
services:
- mysql
- postgresql
allow_failures:
- php: nightly
install:
- |
if [[ $TASK_TESTS_COVERAGE != 1 ]]; then
# disable xdebug for performance reasons when code coverage is not needed
phpenv config-rm xdebug.ini || echo "xdebug is not installed"
fi
# install composer dependencies
- travis_retry composer self-update
- export PATH="$HOME/.composer/vendor/bin:$PATH"
- travis_retry composer install $DEFAULT_COMPOSER_FLAGS
# setup PHP extension
- |
if [[ $TASK_TESTS_PHP == 1 && $TRAVIS_PHP_VERSION != nightly ]]; then
tests/data/travis/apcu-setup.sh
tests/data/travis/memcache-setup.sh
tests/data/travis/imagick-setup.sh
fi
# Needed for FileCacheTest
- sudo useradd $TRAVIS_SECOND_USER --gid $(id -g) -M
before_script:
# show some versions and env information
- php --version
- composer --version
- |
if [ $TASK_TESTS_PHP == 1 ]; then
php -r "echo INTL_ICU_VERSION . \"\n\";"
php -r "echo INTL_ICU_DATA_VERSION . \"\n\";"
psql --version
mysql --version
fi
# initialize databases
- |
if [ $TASK_TESTS_PHP == 1 ]; then
travis_retry mysql -e 'CREATE DATABASE `yiitest`;';
mysql -e "SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';";
mysql -e "CREATE USER 'travis'@'localhost' IDENTIFIED WITH mysql_native_password;";
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'travis'@'localhost' WITH GRANT OPTION;";
psql -U postgres -c 'CREATE DATABASE yiitest;';
fi
# enable code coverage
- |
if [ $TASK_TESTS_COVERAGE == 1 ]; then
PHPUNIT_FLAGS="--coverage-clover=coverage.clover"
fi
# Disable DEPRECATE messages during PHPUnit initialization on PHP 7.2. To fix them, PHPUnit should be updated to 6.*
# For Yii2 tests, messages will be enabled by tests/bootstrap.php
- |
if [[ $TRAVIS_PHP_VERSION == 7.2 || $TRAVIS_PHP_VERSION = nightly ]]; then
echo 'Disabled DEPRECATED notifications for PHP >= 7.2';
echo 'error_reporting = E_ALL & ~E_DEPRECATED' >> /tmp/php-config.ini;
phpenv config-add /tmp/php-config.ini;
fi
script:
# PHP tests
- |
if [ $TASK_TESTS_PHP == 1 ]; then
vendor/bin/phpunit --verbose $PHPUNIT_FLAGS --exclude-group wincache,xcache
fi
after_script:
- |
if [ $TASK_TESTS_COVERAGE == 1 ]; then
travis_retry wget https://scrutinizer-ci.com/ocular.phar
php ocular.phar code-coverage:upload --format=php-clover coverage.clover
fi

4
Dockerfile

@ -4,10 +4,6 @@ FROM ${DOCKER_YII2_PHP_IMAGE}
# Project source-code
WORKDIR /project
ADD composer.* /project/
# Apply testing patches
ADD tests/phpunit_mock_objects.patch /project/tests/phpunit_mock_objects.patch
ADD tests/phpunit_getopt.patch /project/tests/phpunit_getopt.patch
# Install packgaes
RUN /usr/local/bin/composer install --prefer-dist
ADD ./ /project
ENV PATH /project/vendor/bin:${PATH}

23
README.md

@ -1,6 +1,8 @@
> ⚠ 3.0 branch in this repository is deprecated. Yii 3.0 development takes place [in separate repositories](https://github.com/yiisoft/docs/blob/master/000-packages.md). Please do not use the branch in any projects.
<p align="center">
<a href="https://www.yiiframework.com/" target="_blank">
<img src="https://www.yiiframework.com/image/yii_logo_light.svg" width="400" alt="Yii Framework" />
<a href="http://www.yiiframework.com/" target="_blank">
<img src="https://www.yiiframework.com/files/logo/yii.png" width="400" alt="Yii Framework" />
</a>
</p>
@ -11,15 +13,15 @@ The framework is easy to adjust to meet your needs, because Yii has been designe
[![Latest Stable Version](https://img.shields.io/packagist/v/yiisoft/yii2.svg)](https://packagist.org/packages/yiisoft/yii2)
[![Total Downloads](https://img.shields.io/packagist/dt/yiisoft/yii2.svg)](https://packagist.org/packages/yiisoft/yii2)
[![Build Status](https://github.com/yiisoft/yii2/workflows/build/badge.svg)](https://github.com/yiisoft/yii2/actions)
[![Build Status](https://img.shields.io/travis/yiisoft/yii2.svg)](http://travis-ci.org/yiisoft/yii2)
[![Code Coverage](https://scrutinizer-ci.com/g/yiisoft/yii2/badges/coverage.png?s=31d80f1036099e9d6a3e4d7738f6b000b3c3d10e)](https://scrutinizer-ci.com/g/yiisoft/yii2/)
[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/yiisoft/yii2/badges/quality-score.png?s=b1074a1ff6d0b214d54fa5ab7abbb90fc092471d)](https://scrutinizer-ci.com/g/yiisoft/yii2/)
[![Code Climate](https://img.shields.io/codeclimate/github/yiisoft/yii2.svg)](https://codeclimate.com/github/yiisoft/yii2)
Installation
------------
- The minimum required PHP version of Yii is PHP 5.4.
- It works best with PHP 7.
- The minimum required PHP version of Yii 3.0 is PHP 7.1.
- [Follow the Definitive Guide](https://www.yiiframework.com/doc-2.0/guide-start-installation.html)
in order to get step by step instructions.
@ -52,9 +54,8 @@ You may join us and:
- [Report an issue](docs/internals/report-an-issue.md)
- [Translate documentation or messages](docs/internals/translation-workflow.md)
- [Give us feedback or start a design discussion](https://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/)
- [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/)
- [Contribute to the core code or fix bugs](docs/internals/git-workflow.md)
- [Become a sponsor](#sponsoring)
### Reporting Security issues
@ -89,11 +90,5 @@ If you are using Yii 2 as part of an OpenSource project, a way to acknowledge it
If your code is hosted at GitHub, you can place the following in your README.md file to get the badge:
```
[![Yii2](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/)
[![Yii2](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](http://www.yiiframework.com/)
```
### Sponsoring
Support this project by becoming a sponsor or a backer.
[![OpenCollective sponsors](https://opencollective.com/yiisoft/sponsors/badge.svg)](https://opencollective.com/yiisoft) [![OpenCollective backers](https://opencollective.com/yiisoft/backers/badge.svg)](https://opencollective.com/yiisoft)

27
ROADMAP.md

@ -1,27 +0,0 @@
> Roadmap for Yii 3.0 and further was moved to [yiisoft/docs](https://github.com/yiisoft/docs/blob/master/003-roadmap.md).
- Enhancements are not accepted for framework version 2.0.
- Enhancements are accepted for 2.0 extensions.
- Bug and security fixes are expected.
- Pull requests and maintainers are very welcome.
Above would stand as it is [for two years after Yii 3.0 release](https://www.yiiframework.com/release-cycle).
## Additional releases
While we focus on 3.0, we tag 2.0 releases and extension releases [about once in a week](https://www.yiiframework.com/release-cycle).
## 2.0.16+ (since 2019 till 3.0 release + 2 years)
- Bugfixes.
## 2.0.15 (2nd quarter of 2018)
- Since this release main focus is bug fixing.
- No full-branch merges into 3.0.
- No enhancements are accepted.
## 2.0.14 (1st quarter of 2018)
Will be last release with features and enhancements the last one that will be merged into 3.0 directly.

28
build/controllers/DevController.php

@ -8,7 +8,7 @@
namespace yii\build\controllers;
use Yii;
use yii\base\InvalidParamException;
use yii\base\InvalidArgumentException;
use yii\console\Controller;
use yii\helpers\Console;
use yii\helpers\FileHelper;
@ -16,8 +16,8 @@ use yii\helpers\FileHelper;
/**
* 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 contained applications/extensions vendor dirs
* to help to work on yii using the application to test it.
* 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.
*
* @author Carsten Brandt <mail@cebe.cc>
* @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;
/**
@ -51,8 +51,8 @@ class DevController extends Controller
'apidoc' => 'git@github.com:yiisoft/yii2-apidoc.git',
'authclient' => 'git@github.com:yiisoft/yii2-authclient.git',
'bootstrap' => 'git@github.com:yiisoft/yii2-bootstrap.git',
'bootstrap4' => 'git@github.com:yiisoft/yii2-bootstrap4.git',
'bootstrap5' => 'git@github.com:yiisoft/yii2-bootstrap5.git',
'captcha' => 'git@github.com:yiisoft/yii2-captcha.git',
'codeception' => 'git@github.com:yiisoft/yii2-codeception.git',
'composer' => 'git@github.com:yiisoft/yii2-composer.git',
'debug' => 'git@github.com:yiisoft/yii2-debug.git',
'elasticsearch' => 'git@github.com:yiisoft/yii2-elasticsearch.git',
@ -60,15 +60,19 @@ class DevController extends Controller
'gii' => 'git@github.com:yiisoft/yii2-gii.git',
'httpclient' => 'git@github.com:yiisoft/yii2-httpclient.git',
'imagine' => 'git@github.com:yiisoft/yii2-imagine.git',
'jquery' => 'git@github.com:yiisoft/yii2-jquery.git',
'jui' => 'git@github.com:yiisoft/yii2-jui.git',
'maskedinput' => 'git@github.com:yiisoft/yii2-maskedinput.git',
'mongodb' => 'git@github.com:yiisoft/yii2-mongodb.git',
'mssql' => 'git@github.com:yiisoft/yii2-mssql.git',
'oracle' => 'git@github.com:yiisoft/yii2-oracle.git',
'queue' => 'git@github.com:yiisoft/yii2-queue.git',
'redis' => 'git@github.com:yiisoft/yii2-redis.git',
'rest' => 'git@github.com:yiisoft/yii2-rest.git',
'shell' => 'git@github.com:yiisoft/yii2-shell.git',
'smarty' => 'git@github.com:yiisoft/yii2-smarty.git',
'sphinx' => 'git@github.com:yiisoft/yii2-sphinx.git',
'swiftmailer' => 'git@github.com:yiisoft/yii2-swiftmailer.git',
'symfonymailer' => 'git@github.com:yiisoft/yii2-symfonymailer.git',
'twig' => 'git@github.com:yiisoft/yii2-twig.git',
];
@ -166,11 +170,7 @@ class DevController extends Controller
}
$this->stdout("cloning application repo '$app' from '$repo'...\n", Console::BOLD);
passthru('git clone ' . escapeshellarg($repo) . ' ' . $appDir, $returnVar);
if ($returnVar !== 0) {
$this->stdout("Error occurred while cloning repository.\n", Console::BOLD, Console::FG_RED);
return 1;
}
passthru('git clone ' . escapeshellarg($repo) . ' ' . $appDir);
$this->stdout("done.\n", Console::BOLD, Console::FG_GREEN);
}
@ -329,14 +329,14 @@ class DevController extends Controller
$list = [];
$handle = opendir($dir);
if ($handle === false) {
throw new InvalidParamException("Unable to open directory: $dir");
throw new InvalidArgumentException("Unable to open directory: $dir");
}
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}
// ignore hidden directories
if (strpos($file, '.') === 0) {
if ($file[0] === '.') {
continue;
}
if (is_dir("$dir/$file")) {

32
build/controllers/MimeTypeController.php

@ -31,24 +31,6 @@ class MimeTypeController extends Controller
*/
private $aliases = [
'text/xml' => 'application/xml',
'image/svg' => 'image/svg+xml',
'image/x-bmp' => 'image/bmp',
'image/x-bitmap' => 'image/bmp',
'image/x-xbitmap' => 'image/bmp',
'image/x-win-bitmap' => 'image/bmp',
'image/x-windows-bmp' => 'image/bmp',
'image/ms-bmp' => 'image/bmp',
'image/x-ms-bmp' => 'image/bmp',
'application/bmp' => 'image/bmp',
'application/x-bmp' => 'image/bmp',
'application/x-win-bitmap' => 'image/bmp',
];
/**
* @var array MIME types to add to the ones parsed from Apache files
*/
private $additionalMimeTypes = [
'mjs' => 'text/javascript',
];
/**
@ -65,9 +47,9 @@ class MimeTypeController extends Controller
$aliasesOutFile = Yii::getAlias('@yii/helpers/mimeAliases.php');
}
$this->stdout('Downloading mime-type file from apache httpd repository...');
$this->stdout('downloading mime-type file from apache httpd repository...');
if ($apacheMimeTypesFileContent = file_get_contents('http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=co')) {
$this->stdout("Done.\n", Console::FG_GREEN);
$this->stdout("done.\n", Console::FG_GREEN);
$this->generateMimeTypesFile($outFile, $apacheMimeTypesFileContent);
$this->generateMimeAliasesFile($aliasesOutFile);
} else {
@ -81,11 +63,11 @@ class MimeTypeController extends Controller
*/
private function generateMimeTypesFile($outFile, $content)
{
$this->stdout("Generating file $outFile...");
$this->stdout("generating file $outFile...");
$mimeMap = [];
foreach (explode("\n", $content) as $line) {
$line = trim($line);
if (empty($line) || strpos($line, '#') === 0) { // skip comments and empty lines
if (empty($line) || $line[0] === '#') { // skip comments and empty lines
continue;
}
$parts = preg_split('/\s+/', $line);
@ -96,14 +78,8 @@ class MimeTypeController extends Controller
}
}
}
$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 = <<<EOD
<?php
/**

206
build/controllers/PhpDocController.php

@ -14,7 +14,7 @@ use yii\helpers\FileHelper;
use yii\helpers\Json;
/**
* PhpDocController is there to help to maintain PHPDoc annotation in class files.
* PhpDocController is there to help maintaining PHPDoc annotation in class files.
*
* @author Carsten Brandt <mail@cebe.cc>
* @author Alexander Makarov <sam@rmcreative.ru>
@ -56,7 +56,7 @@ class PhpDocController extends Controller
foreach ($files as $file) {
$result = $this->generateClassPropertyDocs($file);
if ($result !== false) {
list($className, $phpdoc) = $result;
[$className, $phpdoc] = $result;
if ($this->updateFiles) {
if ($this->updateClassPropertyDocs($file, $className, $phpdoc)) {
$nFilesUpdated++;
@ -180,7 +180,7 @@ class PhpDocController extends Controller
$extensionPath = \dirname(rtrim($root, '\\/'));
$this->setUpExtensionAliases($extensionPath);
list(, $extension) = $matches;
[, $extension] = $matches;
Yii::setAlias("@yii/$extension", (string)$root);
if (is_file($autoloadFile = Yii::getAlias("@yii/$extension/vendor/autoload.php"))) {
include $autoloadFile;
@ -203,7 +203,7 @@ class PhpDocController extends Controller
$extensionPath = \dirname(\dirname(rtrim($root, '\\/'))) . '/extensions';
$this->setUpExtensionAliases($extensionPath);
list(, $appName) = $matches;
[, $appName] = $matches;
Yii::setAlias("@app-$appName", (string)$root);
if (is_file($autoloadFile = Yii::getAlias("@app-$appName/vendor/autoload.php"))) {
include $autoloadFile;
@ -329,16 +329,16 @@ class PhpDocController extends Controller
$tag = false;
} elseif ($docBlock) {
$line = ltrim($line);
if (strpos($line, '*') === 0) {
if (isset($line[0]) && $line[0] === '*') {
$line = substr($line, 1);
}
if (strpos($line, ' ') === 0) {
if (isset($line[0]) && $line[0] === ' ') {
$line = substr($line, 1);
}
$docLine = str_replace("\t", ' ', rtrim($line));
if (empty($docLine)) {
$listIndent = '';
} elseif (strpos($docLine, '@') === 0) {
} elseif ($docLine[0] === '@') {
$listIndent = '';
$codeBlock = false;
$tag = true;
@ -453,15 +453,15 @@ class PhpDocController extends Controller
$endofPrivate = $i;
$property = 'Private';
$level = 0;
} elseif (strpos($line, 'const ') === 0) {
} elseif (substr($line, 0, 6) === 'const ') {
$endofConst = $i;
$property = false;
} elseif (strpos($line, 'use ') === 0) {
} elseif (substr($line, 0, 4) === 'use ') {
$endofUse = $i;
$property = false;
} elseif (strpos($line, '*') === 0) {
} elseif (!empty($line) && $line[0] === '*') {
$property = false;
} elseif (strpos($line, '*') !== 0 && strpos($line, 'function ') !== false || $line === '}') {
} elseif (!empty($line) && $line[0] !== '*' && strpos($line, 'function ') !== false || $line === '}') {
break;
}
@ -504,26 +504,18 @@ class PhpDocController extends Controller
protected function updateClassPropertyDocs($file, $className, $propertyDoc)
{
if ($this->shouldSkipClass($className)) {
$this->stderr("[INFO] Skipping class $className.\n", Console::FG_BLUE, Console::BOLD);
return false;
}
try {
$ref = new \ReflectionClass($className);
} catch (\Exception $e) {
$this->stderr("[ERR] Unable to create ReflectionClass for class '$className': " . $e->getMessage() . "\n", Console::FG_RED);
return false;
} catch (\Error $e) {
$this->stderr("[ERR] Unable to create ReflectionClass for class '$className': " . $e->getMessage() . "\n", Console::FG_RED);
return false;
}
if ($ref->getFileName() != $file) {
$this->stderr("[ERR] Unable to create ReflectionClass for class: $className loaded class is not from file: $file\n", Console::FG_RED);
return false;
}
if ($this->isBaseObject($className, $ref)) {
if (!$ref->isSubclassOf('yii\base\BaseObject') && $className !== 'yii\base\BaseObject') {
$this->stderr("[INFO] Skipping class $className as it is not a subclass of yii\\base\\BaseObject.\n", Console::FG_BLUE, Console::BOLD);
return false;
}
@ -620,9 +612,9 @@ class PhpDocController extends Controller
$propertyPosition = false;
foreach ($lines as $i => $line) {
$line = trim($line);
if (strncmp($line, '* @property', 11) === 0) {
if (strncmp($line, '* @property ', 12) === 0) {
$propertyPart = true;
} elseif ($propertyPart && $line === '*') {
} elseif ($propertyPart && $line == '*') {
$propertyPosition = $i;
$propertyPart = false;
}
@ -635,7 +627,7 @@ class PhpDocController extends Controller
}
}
// if no properties or other tags were present add properties at the end
// if no properties or other tags where present add properties at the end
if ($propertyPosition === false) {
$propertyPosition = \count($lines) - 2;
}
@ -657,12 +649,8 @@ class PhpDocController extends Controller
$file = str_replace("\r", '', str_replace("\t", ' ', file_get_contents($fileName, true)));
$ns = $this->match('#\nnamespace (?<name>[\w\\\\]+);\n#', $file);
$namespace = reset($ns);
if ($namespace === false) {
$namespace = '\\';
} else {
$namespace = $namespace['name'];
}
$classes = $this->match('#\n(?:abstract )?(?:final )?class (?<name>\w+)( extends .+)?( implements .+)?\n\{(?<content>.*)\n\}(\n|$)#', $file);
$namespace = $namespace['name'];
$classes = $this->match('#\n(?:abstract )?class (?<name>\w+)( extends .+)?( implements .+)?\n\{(?<content>.*)\n\}(\n|$)#', $file);
if (\count($classes) > 1) {
$this->stderr("[ERR] There should be only one class in a file: $fileName\n", Console::FG_RED);
@ -673,17 +661,13 @@ class PhpDocController extends Controller
$interfaces = $this->match('#\ninterface (?<name>\w+)( extends .+)?\n\{(?<content>.*)\n\}(\n|$)#', $file);
if (\count($interfaces) == 1) {
return false;
}
if (\count($interfaces) > 1) {
} elseif (\count($interfaces) > 1) {
$this->stderr("[ERR] There should be only one interface in a file: $fileName\n", Console::FG_RED);
} else {
$traits = $this->match('#\ntrait (?<name>\w+)\n\{(?<content>.*)\n\}(\n|$)#', $file);
if (\count($traits) == 1) {
return false;
}
if (\count($traits) > 1) {
} elseif (\count($traits) > 1) {
$this->stderr("[ERR] There should be only one class/trait/interface in a file: $fileName\n", Console::FG_RED);
} else {
$this->stderr("[ERR] No class in file: $fileName\n", Console::FG_RED);
@ -722,43 +706,63 @@ class PhpDocController extends Controller
];
}
if (\count($props) === 0) {
continue;
}
ksort($props);
$phpdoc .= " *\n";
foreach ($props as $propName => &$prop) {
$docLine = ' * @property';
$note = '';
if (isset($prop['get'], $prop['set'])) {
if ($prop['get']['type'] !== $prop['set']['type']) {
$note = ' Note that the type of this property differs in getter and setter.'
. ' See [[get' . ucfirst($propName) . '()]]'
. ' and [[set' . ucfirst($propName) . '()]] for details.';
}
} elseif (isset($prop['get'])) {
if (!$this->hasSetterInParents($className, $propName)) {
$docLine .= '-read';
if (\count($props) > 0) {
$phpdoc .= " *\n";
foreach ($props as $propName => &$prop) {
$docline = ' * @';
$docline .= 'property'; // Do not use property-read and property-write as few IDEs support complex syntax.
$note = '';
if (isset($prop['get'], $prop['set'])) {
if ($prop['get']['type'] != $prop['set']['type']) {
$note = ' Note that the type of this property differs in getter and setter.'
. ' See [[get' . ucfirst($propName) . '()]] and [[set' . ucfirst($propName) . '()]] for details.';
}
} elseif (isset($prop['get'])) {
// check if parent class has setter defined
$c = $className;
$parentSetter = false;
while ($parent = get_parent_class($c)) {
if (method_exists($parent, 'set' . ucfirst($propName))) {
$parentSetter = true;
break;
}
$c = $parent;
}
if (!$parentSetter) {
$note = ' This property is read-only.';
//$docline .= '-read';
}
} elseif (isset($prop['set'])) {
// check if parent class has getter defined
$c = $className;
$parentGetter = false;
while ($parent = get_parent_class($c)) {
if (method_exists($parent, 'set' . ucfirst($propName))) {
$parentGetter = true;
break;
}
$c = $parent;
}
if (!$parentGetter) {
$note = ' This property is write-only.';
//$docline .= '-write';
}
} else {
continue;
}
} elseif (isset($prop['set'])) {
if (!$this->hasGetterInParents($className, $propName)) {
$docLine .= '-write';
$docline .= ' ' . $this->getPropParam($prop, 'type') . " $$propName ";
$comment = explode("\n", $this->getPropParam($prop, 'comment') . $note);
foreach ($comment as &$cline) {
$cline = ltrim($cline, '* ');
}
} else {
continue;
}
$docLine .= ' ' . $this->getPropParam($prop, 'type') . " $$propName ";
$comment = explode("\n", $this->getPropParam($prop, 'comment') . $note);
foreach ($comment as &$cline) {
$cline = ltrim(rtrim($cline), '* ');
}
$docLine = wordwrap($docLine . implode(' ', $comment), 110, "\n * ") . "\n";
$docline = wordwrap($docline . implode(' ', $comment), 110, "\n * ") . "\n";
$phpdoc .= $docLine;
$phpdoc .= $docline;
}
$phpdoc .= " *\n";
}
$phpdoc .= " *\n";
}
return [$className, $phpdoc];
@ -795,7 +799,7 @@ class PhpDocController extends Controller
return '';
}
return strtoupper(substr($str, 0, 1)) . substr($str, 1) . ($str[\strlen($str) - 1] !== '.' ? '.' : '');
return strtoupper(substr($str, 0, 1)) . substr($str, 1) . ($str[\strlen($str) - 1] != '.' ? '.' : '');
}
protected function getPropParam($prop, $param)
@ -815,72 +819,4 @@ class PhpDocController extends Controller
}
return hash('sha256', $string);
}
/**
* @param string $className
* @param string $propName
* @return bool
*/
protected function hasGetterInParents($className, $propName)
{
$class = $className;
try {
while ($parent = get_parent_class($class)) {
if (method_exists($parent, 'get' . ucfirst($propName))) {
return true;
}
$class = $parent;
}
} catch (\Throwable $t) {
$this->stderr("[ERR] Error when getting parents for $className\n", Console::FG_RED);
return false;
}
return false;
}
/**
* @param string $className
* @param string $propName
* @return bool
*/
protected function hasSetterInParents($className, $propName)
{
$class = $className;
try {
while ($parent = get_parent_class($class)) {
if (method_exists($parent, 'set' . ucfirst($propName))) {
return true;
}
$class = $parent;
}
} catch (\Throwable $t) {
$this->stderr("[ERR] Error when getting parents for $className\n", Console::FG_RED);
return false;
}
return false;
}
/**
* @param string $className
* @param \ReflectionClass $ref
* @return bool
*/
protected function isBaseObject($className, \ReflectionClass $ref)
{
$isDeprecatedObject = false;
if (PHP_VERSION_ID <= 70100) {
$isDeprecatedObject = $ref->isSubclassOf('yii\base\Object') || $className === 'yii\base\Object';
}
return !$isDeprecatedObject && !$ref->isSubclassOf('yii\base\BaseObject') && $className !== 'yii\base\BaseObject';
}
private function shouldSkipClass($className)
{
if (PHP_VERSION_ID > 70100) {
return $className === 'yii\base\Object';
}
return false;
}
}

40
build/controllers/ReleaseController.php

@ -15,11 +15,11 @@ use yii\helpers\Console;
use yii\helpers\FileHelper;
/**
* ReleaseController is there to help to prepare releases.
* ReleaseController is there to help preparing releases.
*
* Get a version overview:
*
* ./build/build release/info
* ./build release/info
*
* run it with `--update` to fetch tags for all repos:
*
@ -27,13 +27,13 @@ use yii\helpers\FileHelper;
*
* Make a framework release (apps are always in line with framework):
*
* ./build/build release framework
* ./build/build release app-basic
* ./build/build release app-advanced
* ./build release framework
* ./build release app-basic
* ./build release app-advanced
*
* Make an extension release (e.g. for redis):
*
* ./build/build release redis
* ./build release redis
*
* Be sure to check the help info for individual sub-commands:
*
@ -53,7 +53,7 @@ class ReleaseController extends Controller
*/
public $dryRun = false;
/**
* @var bool whether to fetch the latest tags.
* @var bool whether to fetch latest tags.
*/
public $update = false;
/**
@ -206,7 +206,7 @@ class ReleaseController extends Controller
$newVersions[$k] = $this->version;
}
} else {
// otherwise, get next patch or minor
// otherwise get next patch or minor
$newVersions = $this->getNextVersions($versions, self::PATCH);
}
@ -223,7 +223,7 @@ class ReleaseController extends Controller
}
$this->stdout("- other issues with code changes?\n\n git diff -w $gitVersion.. ${gitDir}\n\n");
$travisUrl = reset($what) === 'framework' ? '' : '-' . reset($what);
$this->stdout("- are unit tests passing on travis? https://travis-ci.com/yiisoft/yii2$travisUrl/builds\n");
$this->stdout("- are unit tests passing on travis? https://travis-ci.org/yiisoft/yii2$travisUrl/builds\n");
$this->stdout("- also make sure the milestone on github is complete and no issues or PRs are left open.\n\n");
$this->printWhatUrls($what, $versions);
$this->stdout("\n");
@ -535,9 +535,7 @@ class ReleaseController extends Controller
$this->stdout("- wait for your changes to be propagated to the repo and create a tag $version on https://github.com/yiisoft/yii2-framework\n\n");
$this->stdout(" git clone git@github.com:yiisoft/yii2-framework.git\n");
$this->stdout(" cd yii2-framework/\n");
$grepVersion = preg_quote($version, '~');
$this->stdout(" export RELEASECOMMIT=$(git log --oneline |grep \"$grepVersion\" | grep -Po \"^[0-9a-f]+\")\n");
$this->stdout(" export RELEASECOMMIT=$(git log --oneline |grep $version |grep -Po \"^[0-9a-f]+\")\n");
$this->stdout(" git tag -s $version -m \"version $version\" \$RELEASECOMMIT\n");
$this->stdout(" git tag --verify $version\n");
$this->stdout(" git push --tags\n\n");
@ -545,7 +543,6 @@ class ReleaseController extends Controller
$this->stdout("- create a release on github.\n");
$this->stdout("- release news and announcement.\n");
$this->stdout("- update the website (will be automated soon and is only relevant for the new website).\n");
$this->stdout(" https://github.com/yiisoft-contrib/yiiframework.com/blob/master/config/versions.php#L69\n");
$this->stdout("\n");
$this->stdout("- release applications: ./build/build release app-basic\n");
$this->stdout("- release applications: ./build/build release app-advanced\n");
@ -629,7 +626,7 @@ class ReleaseController extends Controller
$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 release at github: ./build/build release/package app-$name\n");
$this->stdout("- Create Application packages and upload them to github: ./build release/package app-$name\n");
$this->stdout("\n");
}
@ -803,7 +800,7 @@ class ReleaseController extends Controller
try {
chdir($path);
} catch (\yii\base\ErrorException $e) {
throw new Exception('Failed to fetch git tags in ' . $path . ': ' . $e->getMessage());
throw new Exception('Failed to getch git tags in ' . $path . ': ' . $e->getMessage());
}
exec('git fetch --tags', $output, $ret);
if ($ret != 0) {
@ -825,7 +822,7 @@ class ReleaseController extends Controller
$v = str_replace('\\-', '[\\- ]', preg_quote($version, '/'));
$headline = $version . ' ' . date('F d, Y');
$this->sed(
'/' . $v . ' under development\R(-+?)\R/',
'/' . $v . ' under development\n(-+?)\n/',
$headline . "\n" . str_repeat('-', \strlen($headline)) . "\n",
$this->getChangelogs($what)
);
@ -851,7 +848,7 @@ class ReleaseController extends Controller
{
foreach ($this->getChangelogs($what) as $file) {
// split the file into relevant parts
list($start, $changelog, $end) = $this->splitChangelog($file, $version);
[$start, $changelog, $end] = $this->splitChangelog($file, $version);
$changelog = $this->resortChangelog($changelog);
file_put_contents($file, implode("\n", array_merge($start, $changelog, $end)));
}
@ -990,7 +987,7 @@ class ReleaseController extends Controller
protected function updateYiiVersion($frameworkPath, $version)
{
$this->sed(
'/function getVersion\(\)\R \{\R return \'(.+?)\';/',
'/function getVersion\(\)\n \{\n return \'(.+?)\';/',
"function getVersion()\n {\n return '$version';",
$frameworkPath . '/BaseYii.php');
}
@ -1019,13 +1016,6 @@ class ReleaseController extends Controller
throw new Exception('Command "git tag" failed with code ' . $ret);
}
rsort($tags, SORT_NATURAL); // TODO this can not deal with alpha/beta/rc...
// exclude 3.0.0-alpha1 tag
if (($key = array_search('3.0.0-alpha1', $tags, true)) !== false)
{
unset($tags[$key]);
}
$versions[$ext] = reset($tags);
}

7
build/controllers/TranslationController.php

@ -29,6 +29,7 @@ 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')
{
@ -125,11 +126,11 @@ class TranslationController extends Controller
{
$lines = explode("\n", $diff);
foreach ($lines as $key => $val) {
if (strpos($val, '@') === 0) {
if (mb_substr($val, 0, 1, 'utf-8') === '@') {
$lines[$key] = '<span class="info">' . Html::encode($val) . '</span>';
} elseif (strpos($val, '+') === 0) {
} elseif (mb_substr($val, 0, 1, 'utf-8') === '+') {
$lines[$key] = '<ins>' . Html::encode($val) . '</ins>';
} elseif (strpos($val, '-') === 0) {
} elseif (mb_substr($val, 0, 1, 'utf-8') === '-') {
$lines[$key] = '<del>' . Html::encode($val) . '</del>';
} else {
$lines[$key] = Html::encode($val);

4
build/controllers/Utf8Controller.php

@ -69,11 +69,11 @@ class Utf8Controller extends Controller
}
if ($ord < 0x0020 && $ord != 0x000A && $ord != 0x0009 ||
0x0080 <= $ord && $ord < 0x009F) {
$this->found('CONTROL CHARACTER', $c, $line, $pos, $file);
$this->found('CONTROL CHARARCTER', $c, $line, $pos, $file);
continue;
}
// if ($ord > 0x009F) {
// $this->found("NON ASCII CHARACTER", $c, $line, $pos, $file);
// $this->found("NON ASCII CHARARCTER", $c, $line, $pos, $file);
// continue;
// }
}

6
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
[https://contributor-covenant.org/version/1/4/][version]
[http://contributor-covenant.org/version/1/4/][version]
[homepage]: https://contributor-covenant.org
[version]: https://contributor-covenant.org/version/1/4/
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

68
composer.json

@ -5,20 +5,20 @@
"yii2",
"framework"
],
"homepage": "https://www.yiiframework.com/",
"homepage": "http://www.yiiframework.com/",
"type": "yii2-extension",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Qiang Xue",
"email": "qiang.xue@gmail.com",
"homepage": "https://www.yiiframework.com/",
"homepage": "http://www.yiiframework.com/",
"role": "Founder and project lead"
},
{
"name": "Alexander Makarov",
"email": "sam@rmcreative.ru",
"homepage": "https://rmcreative.ru/",
"homepage": "http://rmcreative.ru/",
"role": "Core framework development"
},
{
@ -29,7 +29,7 @@
{
"name": "Carsten Brandt",
"email": "mail@cebe.cc",
"homepage": "https://www.cebe.cc/",
"homepage": "http://cebe.cc/",
"role": "Core framework development"
},
{
@ -57,9 +57,9 @@
],
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?state=open",
"forum": "https://forum.yiiframework.com/",
"wiki": "https://www.yiiframework.com/wiki",
"irc": "ircs://irc.libera.chat:6697/yii",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"minimum-stability": "dev",
@ -68,64 +68,50 @@
"yiisoft/yii2": "self.version"
},
"require": {
"php": ">=5.4.0",
"php": ">=7.1.0",
"ext-mbstring": "*",
"ext-ctype": "*",
"lib-pcre": "*",
"psr/log": "~1.0.2",
"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.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",
"paragonie/random_compat": ">=1"
"psr/simple-cache": "~1.0.0",
"psr/http-message": "~1.0.0",
"cebe/markdown": "~1.0.0 | ~1.1.0"
},
"require-dev": {
"cweagans/composer-patches": "^1.7",
"phpunit/phpunit": "4.8.34",
"ezyang/htmlpurifier": "~4.6",
"phpunit/phpunit": "~6.2.3",
"cebe/indent": "~1.0.2",
"friendsofphp/php-cs-fixer": "~2.2.3",
"johnkary/phpunit-speedtrap": "^1.0"
"friendsofphp/php-cs-fixer": "~2.2.3"
},
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
}
],
"suggest": {
"ezyang/htmlpurifier": "required at `yii\\helpers\\HtmlPurifier` for 'html' data format support (e.g. `yii\\i18n\\Formatter:asHtml()`)",
"yiisoft/yii2-coding-standards": "you can use this package to check for code style issues when contributing to yii"
},
"autoload": {
"psr-4": {
"yii\\": "framework/",
"yii\\cs\\": "cs/src/"
},
"classmap": [
"framework/Yii.php"
]
},
"autoload-dev": {
"psr-4": {
"yiiunit\\": "tests/",
"yii\\build\\": "build/"
}
},
"config": {
"platform": {"php": "5.4"}
"platform": {"php": "7.1"}
},
"bin": [
"framework/yii"
],
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
},
"composer-exit-on-patch-failure": true,
"patches": {
"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.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php81.patch"
}
"dev-master": "3.0.x-dev"
}
}
}

2118
composer.lock generated

File diff suppressed because it is too large Load Diff

2
contrib/completion/bash/yii

@ -57,4 +57,4 @@ _yii()
# register completion for the ./yii command
# you may adjust this line if your command file is named differently
complete -o default -F _yii ./yii yii
complete -F _yii ./yii yii

5
cs/src/YiiConfig.php

@ -147,8 +147,9 @@ class YiiConfig extends Config
'single_blank_line_before_namespace' => true,
'single_quote' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline_array' => true,
'ternary_operator_spaces' => true,
'ternary_to_null_coalescing' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
@ -156,7 +157,7 @@ class YiiConfig extends Config
}
/**
* Merge current rules' config with provided list of rules.
* Merge current rules config with provided list of rules.
*
* @param array $rules
* @return $this

205
docs/guide-ar/README.md

@ -1,205 +0,0 @@
Yii 2.0 الدليل التقني الخاص ببيئة العمل
===============================
تم تحرير هذا الملف اعتمادا على [الشروط الخاصة بتوثيف ال Yii](https://www.yiiframework.com/doc/terms/).
جميع الحقوق محفوظة
2014 (c) Yii Software LLC.
المقدمة
------------
* [عن بيئة العمل Yii](intro-yii.md)
* [التحديث من الإصدار 1.1](../guide/intro-upgrade-from-v1.md)
البداية من هنا
---------------
* [ماذا يجب أن تعرف عن بيئة العمل](start-prerequisites.md)
* [تثبيت ال Yii](start-installation.md)
* [تشغيل التطبيقات - Running Applications](start-workflow.md)
* [قل مرحبا - المشروع الأول](start-hello.md)
* [التعامل مع ال forms](start-forms.md)
* [التعامل مع قواعد البيانات](start-databases.md)
* [إنشاء الشيفرة البرمجية من خلال ال gii](start-gii.md)
* [ماذا الآن - الخطوة القادمة](start-looking-ahead.md)
الهيكلية الخاصة بالتطبيق (Application Structure)
---------------------
* [نظرة عامة عن الهيكلية الخاصة بالتطبيق](../guide/structure-overview.md)
* [Entry Scripts](../guide/structure-entry-scripts.md)
* [التطبيقات](../guide/structure-applications.md)
* [مكونات التطبيقات](../guide/structure-application-components.md)
* [Controllers](../guide/structure-controllers.md)
* [Models](../guide/structure-models.md)
* [Views](../guide/structure-views.md)
* [Modules](../guide/structure-modules.md)
* [Filters](../guide/structure-filters.md)
* [Widgets](../guide/structure-widgets.md)
* [Assets](../guide/structure-assets.md)
* [Extensions](../guide/structure-extensions.md)
التعامل مع ال requests
-----------------
* [نظرة عامة عن التعامل مع ال requests](../guide/runtime-overview.md)
* [Bootstrapping](../guide/runtime-bootstrapping.md)
* [Routing and URL Creation](../guide/runtime-routing.md)
* [Requests](../guide/runtime-requests.md)
* [Responses](../guide/runtime-responses.md)
* [Sessions and Cookies](../guide/runtime-sessions-cookies.md)
* [Handling Errors - التحكم بالأخطاء](../guide/runtime-handling-errors.md)
* [Logging - تسجيل الحركات](../guide/runtime-logging.md)
المفاهيم الرئيسية (Key Concepts)
------------
* [Components](../guide/concept-components.md)
* [Properties](../guide/concept-properties.md)
* [Events](../guide/concept-events.md)
* [Behaviors](../guide/concept-behaviors.md)
* [Configurations](../guide/concept-configurations.md)
* [Aliases](../guide/concept-aliases.md)
* [Class Autoloading](../guide/concept-autoloading.md)
* [Service Locator](../guide/concept-service-locator.md)
* [Dependency Injection Container](../guide/concept-di-container.md)
التعامل مع قواعد البيانات
----------------------
* [Database Access Objects](../guide/db-dao.md): Connecting to a database, basic queries, transactions, and schema manipulation
* [Query Builder](../guide/db-query-builder.md): Querying the database using a simple abstraction layer
* [Active Record](../guide/db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations
* [Migrations](../guide/db-migrations.md): Apply version control to your databases in a team development environment
* [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)
الحصول على البيانات من خلال المستخدمين
-----------------------
* [Creating Forms](../guide/input-forms.md)
* [Validating Input](../guide/input-validation.md)
* [Uploading Files](../guide/input-file-upload.md)
* [Collecting Tabular Input](../guide/input-tabular-input.md)
* [Getting Data for Multiple Models](../guide/input-multiple-models.md)
* [Extending ActiveForm on the Client Side](../guide/input-form-javascript.md)
عرض البيانات
---------------
* [Data Formatting](../guide/output-formatting.md)
* [Pagination](../guide/output-pagination.md)
* [Sorting](../guide/output-sorting.md)
* [Data Providers](../guide/output-data-providers.md)
* [Data Widgets](../guide/output-data-widgets.md)
* [Working with Client Scripts](../guide/output-client-scripts.md)
* [Theming](../guide/output-theming.md)
الامان والحماية
--------
* [Security Overview](../guide/security-overview.md)
* [Authentication](../guide/security-authentication.md)
* [Authorization](../guide/security-authorization.md)
* [Working with Passwords](../guide/security-passwords.md)
* [Cryptography](../guide/security-cryptography.md)
* [Auth Clients](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Best Practices](../guide/security-best-practices.md)
Caching التخزين المؤقت
-------
* [Caching Overview](../guide/caching-overview.md)
* [Data Caching](../guide/caching-data.md)
* [Fragment Caching](../guide/caching-fragment.md)
* [Page Caching](../guide/caching-page.md)
* [HTTP Caching](../guide/caching-http.md)
RESTful Web Services
--------------------
* [Quick Start](../guide/rest-quick-start.md)
* [Resources](../guide/rest-resources.md)
* [Controllers](../guide/rest-controllers.md)
* [Routing](../guide/rest-routing.md)
* [Response Formatting](../guide/rest-response-formatting.md)
* [Authentication](../guide/rest-authentication.md)
* [Rate Limiting](../guide/rest-rate-limiting.md)
* [Versioning](../guide/rest-versioning.md)
* [Error Handling](../guide/rest-error-handling.md)
الأدوات المساعدة أثناء تطوير التطبيقات
-----------------
* [Debug Toolbar and Debugger](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Generating Code using Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [Generating API Documentation](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)
فحص واختبار التطبيقات
-------
* [Testing Overview](../guide/test-overview.md)
* [Testing environment setup](../guide/test-environment-setup.md)
* [Unit Tests](../guide/test-unit.md)
* [Functional Tests](../guide/test-functional.md)
* [Acceptance Tests](../guide/test-acceptance.md)
* [Fixtures](../guide/test-fixtures.md)
مواضيع وعناوين مميزة
--------------
* [Advanced Project Template](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [Building Application from Scratch](../guide/tutorial-start-from-scratch.md)
* [Console Commands](../guide/tutorial-console.md)
* [Core Validators](../guide/tutorial-core-validators.md)
* [Docker](../guide/tutorial-docker.md)
* [Internationalization](../guide/tutorial-i18n.md)
* [Mailing](../guide/tutorial-mailing.md)
* [Performance Tuning](../guide/tutorial-performance-tuning.md)
* [Shared Hosting Environment](../guide/tutorial-shared-hosting.md)
* [Template Engines](../guide/tutorial-template-engines.md)
* [Working with Third-Party Code](../guide/tutorial-yii-integration.md)
* [Using Yii as a micro framework](../guide/tutorial-yii-as-micro-framework.md)
Widgets
-------
* [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://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)
Helpers
-------
* [Helpers Overview](../guide/helper-overview.md)
* [ArrayHelper](../guide/helper-array.md)
* [Html](../guide/helper-html.md)
* [Url](../guide/helper-url.md)

57
docs/guide-ar/intro-yii.md

@ -1,57 +0,0 @@
# <div dir="rtl">ما هي بيئة العمل Yii</div>
<p dir="rtl">Yii هو إطار PHP عالي الأداء يعتمد على المكونات لتطوير تطبيقات الويب الحديثة بسرعة.
إن الاسم "Yii" (يُنطق بـ "يي" أو "[جي:]" يعني "بسيطًا وتطوريًا" باللغة الصينية. ومن الممكن ايضا
اعتباره اختصارًا لـ <b>Yes It Is</b>!</p>
# <div dir="rtl">ما هي أفضل التطبيقات أو البرمجيات التي يمكن برمجتها وتتناسب مع ال Yii</div>
<p dir="rtl">
Yii هو إطار عام لبرمجة الويب ، مما يعني أنه يمكن استخدامه لتطوير كافة أنواع
تطبيقات الويب باستخدام PHP. وذلك بسبب البنية القائمة على البنية التركيبة لبيئة العمل وترابطها مع المكونات والتخزين المؤقت، وهو مناسب بشكل خاص لتطوير portals, forums, content management systems (CMS), e-commerce projects, RESTful Web services. وما إلى ذلك.
</p>
# <div dir="rtl">كيف يمكن مقارنة بيئة العمل الخاصة بال Yii مع الأطر أو بيئات العمل الأخرى؟</div>
<p dir="rtl">
إذا كنت بالفعل على دراية بإطار العمل الأخرى ، فيمكنك معرفة كيف تتم مقارنة ال Yii:
<ul dir="rtl">
<li> مثل معظم أطر عمل ال PHP ، يطبق Yii النمط المعماري MVC (Model-View-Controller).</li>
<li> ال Yii يتبنى الفلسفة التي تقول أن الشيفرة البرمجية يجب أن تكتب بأسهل طريقها وادقها، ولكنها بذات الوقت يجب أن تكون أنيقة الكتابة مظهرا ومضمونا (شكلا وتطيبقا).</li>
<li> ال Yii هو إطار متكامل (full stack) يوفر العديد من الميزات الجاهزة للإستخدام والمعدة مسبقا، مثل ال query builders وال ActiveRecord لقواعد البيانات العلاقئية (relational) وغير العلائقية (Nosql)، بالإضافة الى دعم وتجهيز ال RESTful API والتخزين المؤقت (caching) وغيرها الكثير. </li>
<li> من مميزات ال Yii إمكانية التعديل (استبدال جزء معين أو تخيصيص وإضافة) جزء معين على أغلب ال Yii core code، وبالإضافة الى هذا، يمكنك بناء ملحقات برمجية اعتمادا على ال core code، ومن ثم نشر هذه الشيفرة وتوزيعها واستخدامها دون وجود أي مشاكل أو صعوبة تذكر.</li>
<li> الأداء العالي هو الهدف الأساسي من ال Yii.</li>
</ul>
</p>
<p dir="rtl">
ال Yii إطار عمل صمم من قبل فريق برمجي متكامل، فهو ليس مجرد عمل فردي ، بل يتكون من <a href="https://www.yiiframework.com/team">فريق تطوير أساسي وقوي</a> ، بالإضافة إلى منتدى كبير
من المهنيين الذين يساهمون باستمرار في تطوير هذا الإطار. فريق المطورين الخاص بال Yii
يراقب عن كثب أحدث اتجاهات تطوير الويب وأفضل الممارسات والمميزات التي
وجدت في الأطر والمشاريع الأخرى. وتدرج بانتظام بإضافة أفضل الممارسات والميزات الى ال Yii عبر واجهات بسيطة وأنيقة.
</p>
# <div dir="rtl">الإصدارات الخاصة بال Yii</div>
<p dir="rtl">
يتوفر لدى Yii حاليًا إصداران رئيسيان: 1.1 و 2.0. الإصدار 1.1 هو الجيل القديم وهو الآن في وضع الصيانة. الإصدار 2.0 هو إعادة كتابة وهيكلة كاملة لل Yii، تم اعتماد أحدث التقنيات والبروتوكولات فيها مثل including Composer, PSR, namespaces, traits والكثير من الأمور الأخرى، وفي هذه الإرشادات، سيكون الكلام كله موجها الى الإصدار الثاني من بيئة العمل ال Yii.
</p>
# <div dir="rtl">المتطلبات الأساسية للعمل على إطار ال Yii</div>
<p dir="rtl">
<ul dir="rtl">
<li>الإصدار PHP 5.4.0 أو أكثر</li>
<li>المعرفة الأساسية بمفاهيم البرمجة كائنية التوجه OOP</li>
<li>المعرفة بآخر وأحدث التقنيات الموجودة بال php مثل ال namespaces, traits، الفهم لهذه المفاهيم سيسهل عليك العمل كثيرا</li>
</ul>
</p>
<p dir="rtl">
ملاحظة: يمكن التحقق من توافق المتطلبات الخاصة بك مع ال yii من خلال الدخول الى الصفحة requirement الموجودة بال yii
</p>

290
docs/guide-ar/start-databases.md

@ -1,290 +0,0 @@
# <div dir="rtl">التعامل مع قواعد البيانات</div>
<p dir="rtl">
في هذا الجزء التعليمي ستتعلم آلية إنشاء صفحة جديدة تعرض بيانات يتم جلبها من قاعدة البيانات -في هذا المثال، البيانات تخص ال country-، هذه البيانات سيتم جلبها من جدول موجود في قاعدة البيانات يسمى ب <code>country</code>. لتحقيق هذا المهمة، ستقوم بعمل ال config الخاص بالإتصال بقاعدة بيانات، بالإضافة لإنشاء ال <a href="../guide/db-active-record.md">Active Record</a> class، وتعريف ال <a href="../guide/structure-controllers.md">action</a>، وإنشاء <a href="../guide/structure-views.md">view</a> لهذه الصفحة.
</p>
<p dir="rtl">
في هذا الشرح ستتعلم كيف يمكنك القيام بما يلي:
</p>
<ul dir="rtl">
<li>إعداد ال connection الخاص بقاعدة البيانات</li>
<li> التعرف على ال active record.</li>
<li>إنشاء جمل إستعلام عن البياتات بإستخدام ال active record class</li>
<li>عرض البيانات داخل ال view من خلال ال paginated fashion.</li>
</ul>
<p dir="rtl">
ملاحظة: من أجل الانتهاء من هذا الجزء التعليمي، يجب أن يكون لديك المعرفة الأساسية والخبرة باستخدام قواعد البيانات. وعلى وجه الخصوص، يجب أن تعرف كيفية إنشاء قواعد البيانات، وكيفية تنفيذ ال statements SQL باستخدام أي DB client tool.
</p>
## <div dir="rtl">إعداد قاعدة البيانات</div> <span id="preparing-database"></span>
<p dir="rtl">
في البداية، عليك إنشاء قاعدة بيانات تسمى ب <code>yii2basic</code>، والتي ستستخدم لجلب البيانات الخاصة بالتطبيق، ويمكنك إستخدام أي من ال SQLite, MySql, PostgreSQL, MSSQL or Oracle database, ال Yii بشكل افتراضي بدعم العديد من قواعد البيانات والتي يمكنك إستخدامها مباشرة في التطبيق الخاص بك، ولتبسيط الأمور، ال MySql هي التي سيتم إستخدامها في في هذا الشرح.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: إذا كنت ترغب بالحصول على خيارات متقدمة مثل دعم ال <code>JSON</code> الموجود داخل MariaDB، فيمكنك من إستخدام أحد ال Extension المذكوره بالأسفل للقيام بهذه المهمة بدلا من الإستغناء عن ال MySql، فإستخدام MariaDB بدلا عن ال MySql لم يعد صحيحا تماما.
</p></blockquote>
<p dir="rtl">
بعد قيامك بإنشاء قاعدة البيانات، سنقوم بإنشاء جدول إسمه <code>country</code>، ومن ثم سنقوم بإدخال بعض البيانات كعينة للإختيار، وللقيام بذلك، قم بتنفيذ الأوامر التالية:
</p>
```sql
CREATE TABLE `country` (
`code` CHAR(2) NOT NULL PRIMARY KEY,
`name` CHAR(52) NOT NULL,
`population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `country` VALUES ('AU','Australia',24016400);
INSERT INTO `country` VALUES ('BR','Brazil',205722000);
INSERT INTO `country` VALUES ('CA','Canada',35985751);
INSERT INTO `country` VALUES ('CN','China',1375210000);
INSERT INTO `country` VALUES ('DE','Germany',81459000);
INSERT INTO `country` VALUES ('FR','France',64513242);
INSERT INTO `country` VALUES ('GB','United Kingdom',65097000);
INSERT INTO `country` VALUES ('IN','India',1285400000);
INSERT INTO `country` VALUES ('RU','Russia',146519759);
INSERT INTO `country` VALUES ('US','United States',322976000);
```
<p dir="rtl">
الآن، أصبح لديك قاعدة بيانات إسمها <code>yii2basic</code>، وتحوي بداخلها جدول بثلاث أعمدة يسمى ب <code>country</code>، وفيه 10 صفوف من البيانات.
</p>
## <div dir="rtl">إعدادات الإتصال الخاصة بقواعد البيانات - Configuring a DB Connection</div> <span id="configuring-db-connection"></span>
<p dir="rtl">
قبل أن تكمل الشرح، تأكد من تثبيت ال PHP <a href="https://www.php.net/manual/en/book.pdo.php">PDO</a> وال PDO driver، بالنسبة لهذا المثال، فإننا سنستخدم ال driver الخاص بال MySql وهو ال <code>pdo_mysql</code>، وهذه هي المتطلبات الأساسية لبناء أي التطبيق اذا كان التطبيق يستخدم ال relational database.
</p>
<blockquote class="note"><p dir="rtl">
ملاحظة: يمكنك تقعيل ال PDO مباشرة من خلال الدخول الى php.ini ومن ثم حذف الفاصلة المنقوطة قبل السطر التالي: <code>extension=php_pdo.dll</code>
كما يمكنك تفعيل ال driver المطلوب عن طريق حذف الفاصلة المنقوطة قبل ال driver المقصود مثل:
<code>extension=php_pdo_mysql.dll</code>
ويمكنك الإطلاع على المزيد من هنا:
<a href="https://www.php.net/manual/en/pdo.installation.php">pdo installation</a>
</p></blockquote>
<p dir="rtl">
بعد إتمام ما سبق، قم بفتح الملف <code>config/db.php</code> ومن ثم قم بتعديل ال parameters لتكون الإعدادات الخاصة بقاعدة البيانات صحيحة -الإعدادت الخاصة بك-، بشكل افتراضي، يحتوي الملف على ما يلي:
</p>
```php
<?php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2basic',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];
```
<p dir="rtl">
يمثل ملف ال <code>config/db.php</code> أداة نموذجية تعتمد على الملفات للقيام بال <a href="../guide/concept-configurations.md">configuration</a>. يقوم ملف ال configuration بتحديد ال parameters المطلوبة لإنشاء وإعداد ال instance الخاص بال <code>[[yii\db\Connection]]</code>، ومن خلالها يمكنك إجراء عمليات الإستعلام على قاعدة البيانات.
</p>
<p dir="rtl">
الإعدادات الخاصة بالإتصال بقاعدة البيانات والمذكورة في الملف أعلاه يمكن الوصول اليها من خلال التطبيق عن طريق تنفيذ الأمر التالي
<code>Yii::$app->db</code>
</p>
<blockquote class="info"><p dir="rtl">
معلومة: سيتم تضمين ملف ال <code>config/db.php</code> من خلال ال main application configuration والذي يتمثل بالملف <code>config/web.php</code>، والذي يقوم بدوره بتحديد كيف يمكن تهيئة ال instance الخاص <a href="../guide/concept-configurations.md">بالتطبيق</a>، لمزيد من المعلومات، يرجى الإطلاع على قسم ال <a href="../guide/concept-configurations.md">Configurations</a>.
</p></blockquote>
<p dir="rtl">
إذا كنت بحاجة إلى العمل مع إحدى قواعد البيانات الغير مدعومة بشكل إفتراضي من ال Yii، فيمكنك التحقق من الإضافات التالية:
</p>
<ul dir="rtl">
<li><a href="https://github.com/edgardmessias/yii2-informix">Informix</a></li>
<li> <a href="https://github.com/edgardmessias/yii2-ibm-db2">IBM DB2</a></li>
<li> <a href="https://github.com/edgardmessias/yii2-firebird">Firebird</a></li>
<li> <a href="https://github.com/sam-it/yii2-mariadb">MariaDB</a></li>
</ul>
## <div dir="rtl">إنشاء ال Active Record<span id="creating-active-record"></span>
<p dir="rtl">
لجلب البيانات وعرضها من جدول ال <code>country</code>، سنقوم بإضافة ال <a href="../guide/db-active-record.md">Active Record</a> الى ال class المسمى ب <code>country</code>، والموجود في المسار <code>models/Country.php</code>.
</p>
```php
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Country extends ActiveRecord
{
}
```
<p dir="rtl">
يرث ال <code>Country</code> Class ال [[yii\db\ActiveRecord]]، ولذلك، أنت لست بحاجة لكتابة أي شيفرة برمجية بداخله، فقط الشيفرة التي تشاهدها بالأعلى. سيقوم ال Yii بشكل تلقائي بالحصول على إسم الجدول في قاعدة البيانات من خلال إسم ال Class.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: إذا لم يكن من الممكن إجراء مطابقة مباشرة بين اسم ال class واسم الجدول، فيمكنك تجاوز هذه المشكلة من خلال إستخدام الدالة [[yii\db\ActiveRecord::tableName()]] ، والتي ستقوم بعمل override على اسم الجدول.
</p></blockquote>
<p dir="rtl">
من خلال إستخدام ال <code>Country</code> class، يمكنك التحكم بكل سهولة بالبيانات الموجودة داخل جدول ال <code>country</code>، شاهد هذه الشيفرة البرمجية لتبسيط الفكرة:
</p>
```php
use app\models\Country;
// get all rows from the country table and order them by "name"
$countries = Country::find()->orderBy('name')->all();
// get the row whose primary key is "US"
$country = Country::findOne('US');
// displays "United States"
echo $country->name;
// modifies the country name to be "U.S.A." and save it to database
$country->name = 'U.S.A.';
$country->save();
```
<blockquote class="info"><p dir="rtl">
معلومة: يعتبر ال Active Record وسيلة قوية للوصول إلى بيانات قاعدة البيانات والتعامل معها بطريقة ال object oriented.
ستجد معلومات أكثر تفصيلاً في الجزء الخاص بال <a href="../guide/db-active-record.md">Active Record</a>. بالإضافة الى ذلك، يمكنك التفاعل مباشرة مع قاعدة البيانات باستخدام lower-level data accessing والتي تسمى ب <a href="../guide/db-dao.md">Database Access Objects</a>.
</p></blockquote>
## <div dir="rtl">إنشاء ال Action</a> <span id="creating-action"></span>
<p dir="rtl">
لعرض بيانات ال country للمستخدمين، يلزمك إنشاء action جديد، وبدلاً من وضع ال action الجديد في ال <code>site</code> controller كما فعلنا في المرات السابقة، سنقوم بإنشاء controller جديد، ومن ثم سنقوم بوضع ال action بداخله، والسبب المنطقي لهذا العمل أنك ستقوم بتجميع الشيفرة البرمجية المسؤولة عن أداء وظائف معينة في مكان واحد، وبهذا فإن جميع الإجرائات التي تخص ال country من المنطقي أن تكون موجودة داخل ال <code>CountryController</code>، والآن لنقم بإنشاء هذا ال controller الجديد، وال action الجديد وسيكون باسم <code>index</code>، كما هو موضح أدناه:
</p>
```php
<?php
namespace app\controllers;
use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;
class CountryController extends Controller
{
public function actionIndex()
{
$query = Country::find();
$pagination = new Pagination([
'defaultPageSize' => 5,
'totalCount' => $query->count(),
]);
$countries = $query->orderBy('name')
->offset($pagination->offset)
->limit($pagination->limit)
->all();
return $this->render('index', [
'countries' => $countries,
'pagination' => $pagination,
]);
}
}
```
<p dir="rtl">
قم بحفظ الشيفرة البرمجية التي بالأعلى داخل هذا الملف <code>controllers/CountryController.php</code>
</p>
<p dir="rtl">
يقوم ال <code>index</code> action باستخدام ال <code>Country::find()</code>، وهذه الدالة موجودة من ضمن ال <code>active record</code>، وتقوم هذه الدالة على بناء الإستعلام الخاص بقاعدة البيانات مما يسمح باسترجاع جميع البيانات الموجودة بداخل جدول ال country، ولتحديد الحد الأعلى المسموح إرجاعه في كل request، يمكنك إستخدام ال <code>[[yii\data\Pagination]]</code> object كوسيلة مساعدة، ويقدم هذا ال object غرضين أساسيين وهما:
</p>
<ul dir="rtl">
<li>كتابة جملة استعلام محددة بعدد صفوف معين، وتبدأ من مكان معين، ويتم ذلك من خلال ال <code>offset</code> وال <code>limit</code>، وبهذا التعيين فأنت ستقوم بإرجاع صفحة واحدة من البيانات وفي كل مرة سيتم عرض 5 صفوف على الأكثر. </li>
<li>كما يستخدم في صفحة ال view لعرض ال pager مع قائمة بال page buttons، وذلك كما ستشاهد في الجزء التالي من هذا الموضوع. </li>
</ul>
<p dir="rtl">
في نهاية الشيفرة البرمجية الموجودة في ال <code>index</code> action، نقوم باستدعاء صفحة ال view المسمية ب <code>index</code>، ومن ثم نقوم بإرسال معلومات ال country المنظمة على شكل صفحات (pagination) ومن ثم عرضها.
</p>
## <div dir="rtl"> إنشاء View </div> <span id="creating-view"></span>
<p dir="rtl">
الآن، سنقوم بإنشاء صفحة ال view والتي ستقوم بعرض المعلومات الخاصة بال country والقادمة من ال index action، ولذلك توجه الى المسار <code>views</code>, ومن ثم قم بإنشاء مجلد جديد بداخله باسم <code>country</code>، هذا المجلد سيحوي جمع ال views التي سيتم إستدعائها من ال <code>country</code> controller>. الآن، قم بإنشاء الصفحة index.php بداخل المسار <code>views/country</code>، ومن ثم قم بكتابة هذه الشيفرة البرمجية بداخلها:
</p>
```php
<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
<li>
<?= Html::encode("{$country->code} ({$country->name})") ?>:
<?= $country->population ?>
</li>
<?php endforeach; ?>
</ul>
<?= LinkPager::widget(['pagination' => $pagination]) ?>
```
<p dir="rtl">
في هذه الصفحة، هناك جزئيين رئيسيين، الجزء الأول هو المسؤول عن طباعة المعلومات الخاصة بال country داخل قائمة من نوع ul، والجزء الثاني عبارة عن widget يستخدم المعلومات الخاصة بال pagination والتي تم إرسالها من ال action، ليقوم بعد ذلك بعرض قائمة من ال page buttons، والتي بدورها ستقوم بعمل تحديث للمعلومات الموجودة بالصفحة بنائا على الصفحة المطلوبة، هذا ال widget يسمى ب <code>LinkPager -[[yii\widgets\LinkPager]]-</code>.
</p>
## <div dir="rtl">لنجرب المثال</div> <span id="trying-it-out"></span>
<p dir="rtl">
لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
</p>
```
http://hostname/index.php?r=country%2Findex
```
![Country List](../guide/images/start-country-list.png)
<p dir="rtl">
في البداية، ستشاهد البيانات الخاصة بخمسة دول، وأسفل هذه الدول، ستشاهد pager فيه 4 أزرار، اذا قمت بالضغط على الزر رقم 2، فإنك ستشاهد المعلومات الخاصة بخمسة دول أخرى، والتي تمثل صفوف أخرى من البيانات تم جلبها من قاعدة البيانات.
<br />
تابع بعناية أكبر وستجد أن عنوان ال URL في المتصفح قد تغير أيضًا:
</p>
```
http://hostname/index.php?r=country%2Findex&page=2
```
<p dir="rtl">
بالخفاء، يقوم ال <code>[[yii\data\Pagination|Pagination]]</code> بتقديم الدعم اللازم لكل الوظائف المطلوب تنفيذها لعمل الترقيم الخاص بال pagination:
</p>
<ul dir="rtl">
<li>في البداية، يمثل ال [[yii\data\Pagination|Pagination]] الصفحة الأولى التي تعكس جملة الإستعلام SELECT مع الجدول country مع العبارة <code>LIMIT 5 OFFSET 0</code>. ونتيجة لذلك، سيتم جلب البلدان الخمسة الأولى وعرضها.</li>
<li>ال [[yii\widgets\LinkPager|LinkPager]] widget يقوم على إستدعاء الأزرار الخاصة بأرقام الصفحات والتي يتم إنشاء ال Url الخاص بها من خلال ال [[yii\data\Pagination::createUrl()|Pagination]]، هذه ال Url تحتوي على parameter يسمى ب <code>page</code>، والذي يمثل بدورة مجموعة من الأرقام المختلفة والتي تمثل صفحات تعرض بيانات مختلفة كما هو في مثالنا عندما قمنا بالضغط على رقم 2.</li>
<li>عند قيامك بالنقر على الزر رقم 2، سينطلق request جديد الى ال <code>country/index</code> route، وحينها يقوم ال [[yii\data\Pagination|Pagination]] على قرائة ال <code>page</code> parameter من ال URL ,من ثم يقوم بتغيير رقم الصفحة الحالية الى الرقم الجديد، وهنا الرقم الجديد هو 2 بدلا من 1. كما أن جملة الإستعلام الجديدة ستحوي الشرط التالي <code>LIMIT 5 OFFSET 5</code> لتقم بذلك بجلب الصفوف الخمسة الأخرى من البلدان لعرضها.</li>
</ul>
## <div dir="rtl">الخلاصة</div> <span id="summary"></span>
<p dir="rtl">
في هذا الجزء من التوثيق، لقد تعلمنا كيف يمكننا التعامل مع قواعد البيانات، وكيف يمكننا جلب البيانات وعرضها وتجزئتها لصفحات من خلال إستخدام ال [[yii\data\Pagination]] وال [[yii\widgets\LinkPager]].
</p>
<p dir="rtl">
في الجزء القادم من هذا التوثيق، ستتعلم كيف يمكنك إستخدام إخدى الوسائل المميزة والموجودة في ال Yii لإنشاء الشيفرة البرمجية الخاصة بك، والتي يطلق عليها اسم <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a>، هذه الأداة ستساعدك على إنشاء وتنفيذ الشيفرات البرمجية التي يكثر كتابتها وإستخدامها بشكل دوري، مثل مجموعة العمليات Create-Read-Update-Delete، والتي يتم اختصارها ب CRUD، هذه الأداة ستقوم بالتعامل مع البيانات الموجدة بقاعدة البيانات، وفي الحقيقة، الشيفرة البرمجية الذي قمت بكتابته بالأعلى، يمكنك إنشائه بسهولة من خلال ال Gii بنقرة زر، لذلك فلننطلق الى الجزء التالي بأسرع وقت.
</p>

253
docs/guide-ar/start-forms.md

@ -1,253 +0,0 @@
# <div dir="rtl">العمل مع ال Forms</div>
<p dir="rtl">
في هذا الموضوع سنتعلم كيفية إنشاء صفحة تحتوي على form للحصول على البيانات من خلال المستخدمين، وستعرض هذه الصفحة form يحتوي على حقل لإدخال الإسم وحقل إدخال للبريد الإلكتروني.
وبعد الحصول على المعلومات الخاصة بهذه الحقول من المستخدم، ستقوم الصفحة بطباعة القيم التي تم إدخالها.
</p>
<p dir="rtl">
في هذا الشرح، ستقوم بإضافة <a href="../guide/structure-controllers.md">action</a> وصحفتين <a href="../guide/structure-views.md">views</a>، وستتعرف أيضا على طريقة إنشاء ال <a href="../guide/structure-models.md">model</a>.
</p>
<p dir="rtl">
من خلال هذا البرنامج التعليمي ، ستتعلم كيفية:
</p>
<ul dir="rtl">
<li>إنشاء model لتمثيل البيانات التي تم إدخالها من خلال المستخدم عن طريق ال form.</li>
<li>إنشاء rules للتحقق من صحة البيانات التي تم إدخالها.</li>
<li>بناء html form داخل صفحة ال view.</li>
</ul>
## <div dir="rtl">إنشاء ال Model</div> <span id="creating-model"></span>
<p dir="rtl">
يتم تمثيل البيانات التي يتم طلبها من خلال المستخدم عن طريق ال <code>EntryForm</code> model class كما هو موضح أدناه، ويتم حفظ هذا الملف داخل المسار models، ويكون إسم ال model ومساره في مثالنا هذا هو <code>models/EntryForm.php</code>. يرجى الرجوع إلى صفحة ال <a href="../guide/concept-autoloading.md">Class Autoloading</a> للحصول على مزيد من التفاصيل حول طريقة التعامل مع التسمية الخاصة بال class في Yii.
</p>
```php
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class EntryForm extends Model
{
public $name;
public $email;
public function rules()
{
return [
[['name', 'email'], 'required'],
['email', 'email'],
];
}
}
```
<p dir="rtl">
هذا ال class يرث ال [[yii\base\Model]], وهو base class تم تصميمه من خلال ال Yii, وبشكل عام وظيفته هي تثمثيل البيانات الخاصة بأي نموذج.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: يتم إستخدام ال [[yii\base\Model]] كأصل لل model class <b>ولا</b> يرتبط بجداول قواعد البيانات. ويستخدم ال [[yii\db\ActiveRecord]] بالشكل الإعتيادي ليكون هو الأصل الذي من خلاله يتم الإرتباط بجداول بقواعد البيانات.
</p></blockquote>
<p dir="rtl">
يحتوي class ال <code>EntryForm</code> على متغيرين إثنين من نوع Public، هما <code>name</code> و <code>email</code>، واللذان يستخدمان في تخزين البيانات التي أدخلها المستخدم. كما يحتوي أيضًا على method باسم <code>rules()</code>، والتي تُرجع مجموعة
الشروط الخاصة بالبيانات للتحقق من صحتها. والشيفرة البرمجية الموجودة داخل ال rules method تعني:
</p>
<ul dir="rtl">
<li>كل من ال <code>name</code> وال <code>email</code> حقول الزامية (required).</li>
<li>ال <code>email</code> حقل يجب أن يحتوي بداخله قيمة صحيحة تعبر عن البريد الإلكتروني (القواعد النحوية لكتابة البريد الإلكتروني).</li>
</ul>
<p dir="rtl">
إذا كان لديك object من ال <code>EntryForm</code> ويحتوي على البيانات التي أدخلها المستخدم، فيمكنك حينها إستدعاء الدالة [[yii\base\Model::validate()|validate()]] للتحقق من صحة البيانات. اذا فشلت عملية التحقق من صحة البيانات، فسيؤدي ذلك إلى تغيير قيمة ال [[yii\base\Model::hasErrors|hasErrors]] إلى <code>true</code> ، بالإضافة الى ذلك يمكنك التعرف الى الأخطاء المتعلقة بهذه البيانات من خلال الدالة [[yii\base\Model::getErrors|errors]].
</p>
```php
<?php
$model = new EntryForm();
$model->name = 'Qiang';
$model->email = 'bad';
if ($model->validate()) {
// Good!
} else {
// Failure!
// Use $model->getErrors()
}
```
## <div dir="rtl">إنشاء Action</div> <span id="creating-action"></span>
<p dir="rtl">
الآن، ستحتاج إلى إنشاء <code>action</code> جديد في ال <code>site</code> controller وليكن إسمه <code>entry</code>، والذي سيقوم بدوره باستخدام ال model الجديد الذي قمنا بإنشائه. هذه العملية تم شرحها سابقا في الجزء التالي من التوثيق <a href="start-hello.md">Saying Hello - قل مرحبا</a>.
</p>
```php
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\EntryForm;
class SiteController extends Controller
{
// ...existing code...
public function actionEntry()
{
$model = new EntryForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// valid data received in $model
// do something meaningful here about $model ...
return $this->render('entry-confirm', ['model' => $model]);
} else {
// either the page is initially displayed or there is some validation error
return $this->render('entry', ['model' => $model]);
}
}
}
```
<p dir="rtl">
أولا، يقوم ال action بإنشاء object من ال <code>EntryForm</code>. ثم يحاول تعبئة البيانات لل object من خلال ال <code>$ _POST</code>، والتي يتم تقديمها في ال Yii من خلال ال [[yii\web\Request::post()]].
إذا تم ملء ال object بنجاح (على سبيل المثال، إذا قام المستخدم بإدخال البيانات داخل ال form ومن ثم قام بإرسالها(submitted html form))، فسيتم استدعاء ال [[yii\base\Model::validate()|validate()]] من خلال ال action للتأكد من صلاحية القيم المدخلة.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: يمثل التعبير Yii::$app ال <a href="../guide/structure-applications.md">Application</a> instance الذي يمكن الوصول اليه من خلال ال singleton <br />(singleton globally accessible). وهو أيضا <a href="../guide/concept-service-locator.md">service locator</a> بحيث يوفر الدعم لل components مثل ال request, response, db..الخ، لدعم وظائف محددة. مثلا في المثال الموجود في الأعلى، فإن ال request هو component من ال application instance والذي يستخدم للوصول الى البيانات الموجودة داخل ال $_POST.
</p></blockquote>
<p dir="rtl">
إذا كان كل شيء على ما يرام، فسوف يقوم ال action بجلب ال view التالية: <code>entry-confirm</code>، وذلك لتأكيد أن العملية قد تمت بنجاح بالنسبة للمستخدم، أما إن كانت البيانات غير صحيحة، أو لم يتم إرسال أي بيانات، فإن ال view <code>entry</code> هي التي سيتم جلبها وعرضها للمستخدم، حيث يتم عرض ال Html form، مع أي رسائل تحذير بخصوص الأخطاء التي تم العثور عليها من عملية التحقق.
</p>
<blockquote class="note"><p dir="rtl">
ملاحظة: في هذا المثال البسيط، نعرض صفحة التأكيد فقط عند إرسال البيانات بشكل صحيح. عند الممارسة العملية، يجب عليك استخدام [[yii\web\Controller::refresh()|refresh()]] أو [[yii\web\Controller::redirect()|redirect()]] لتجنب أي مشكلة تحصل عن طريق ال resubmission والتي تندرج تحت العنوان <a href="https://en.wikipedia.org/wiki/Post/Redirect/Get">form resubmission problems</a>.
</p></blockquote>
## <div dir="rtl">إنشاء ال views</div> <span id="creating-views"></span>
<p dir="rtl">
أخيرا، سنقوم بإنشاء صفحتين لل views الأولى بإسم <code>entry-confirm</code> والثانية <code>entry</code>. وهاتين الصفحتين سيتم جلبهم من خلال ال <code>entry</code> action.
</p>
<p dir="rtl">
ال <code>entry-confirm</code> ستقوم بكل بساطة بعرض الإسم والبريد الإلكتروني الذي تم إدخالهم من قبل المستخدم. ويجب حفظ هذه الصفحة بالمسار التالي: <code>views/site/entry-confirm.php</code>
</p>
```php
<?php
use yii\helpers\Html;
?>
<p>You have entered the following information:</p>
<ul>
<li><label>Name</label>: <?= Html::encode($model->name) ?></li>
<li><label>Email</label>: <?= Html::encode($model->email) ?></li>
</ul>
```
<p dir="rtl">
صفحة ال <code>entry</code> ستقوم بعرض ال HTML form. هذه الصفحة يجب أن يتم حفظها داخل المسار التالي: <code>views/site/entry.php</code>
</p>
```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'email') ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
```
<p dir="rtl">
تستخدم ال view أسلوب مميز لبناء ال Forms، وذلك عن طريق ال <a href="../guide/structure-widgets.md">widget</a> الذي يسمى ب [[yii\widgets\ActiveForm|ActiveForm]]. إن الأسلوب المستخدم في هذا ال widget يقوم على إستخدام كل من الدالة <code>begin()</code> و <code>end()</code> لجلب ال opening وال closing form tags على التوالي (فتحة ال tag، ثم الإغلاق الخاص بهذا ال tag)، وبين الفتحة والإغلاق يمكنك إنشاء الحقول عن طريق إستخدام الدالة [[yii\widgets\ActiveForm::field()|field()]]. في هذا المثال كان الحقل الأول في ال form يشير الى name data، والثاني يشير الى ال email data، وبعد هذه الحقول ستجد الدالة المستخدمة لإنشاء ال Submit button وهي [[yii\helpers\Html::submitButton()]].
</p>
## <div dir="rtl">لنجرب المثال</div> <span id="trying-it-out"></span>
<p dir="rtl">
لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
</p>
```
http://hostname/index.php?r=site%2Fentry
```
<p dir="rtl">
عند دخولك الى الرابط السابق، سترى صفحة تعرض Html form يحتوي على حقلين لإدخال المعلومات. أمام كل حقل إدخال ستجد label يشير إلى البيانات المطلوب إدخالها. إذا قمت بالنقر فوق الزر "submit" بدون
أي إدخال، أو إذا لم تقم بكتابة عنوان البريد الإلكتروني بشكل صحيح، فستظهر لك رسالة خطأ بجوار الحقل المقصود.
</p>
![Form with Validation Errors](../guide/images/start-form-validation.png)
<p dir="rtl">
بعد إدخالك لإسم وبريد الكتروني صحيح، وقيامك بالنقر على زر submit، فإنك ستشاهد صفحة جديدة تقوم بعرض البيانات التي قمت بإدخالها.
</p>
![Confirmation of Data Entry](../guide/images/start-entry-confirmation.png)
## <div dir="rtl">كيف ظهر الخطأ؟ هل هو سحر؟!</div> <span id="magic-explained"></span>
<p dir="rtl">
قد تتساءل كيف يعمل ال Html form بالخفاء، وقد يبدو ذلك سحرا للوهلة الأولى، فهو يعرض ال label لكل حقل إدخال، ويعرض رسائل الخطأ إذا لم تقم بإدخال البيانات بشكل صحيح، وكل ذلك دون الحاجة لإعادة تحميل الصفحة.
</p>
<p dir="rtl">
إن السحر الموجود لدينا هنا، هو كيفية العمل الخاصة بالشيفرة البرمجية لل form، والتي تعمل بالخفاء، إن إجراء التحقق عن صحة البيانات يتم في البداية من جانب العميل -client side- وذلك باستخدام الجافا سكربت، ومن ثم -بعد تجاوز التحقق الخاص بالجافا سكربت- بتم تنفيذ التحقق من جانب ال server-side عبر ال PHP. ال [[yii\widgets\ActiveForm]] ذكية بما فيه الكفاية لاستخراج ال rule الخاصة بالتحقق والتي قمت بإنشائها وتعريفها داخل ال <code>EntryForm</code>، ومن ثم تحويل هذه القواعد إلى شيفرة برمجية بالجافا سكربت قابلة للتنفيذ، ومن ثم استخدام هذه الشيفرة من قبل الجافا سكربت لإجراء التحقق من صحة البيانات. في حال قمت بإيقاف الجافا سكربت في المتصفح الخاص بك، سوف يستمر إجراء التحقق من جانب الخادم -server side-، كما هو موضح في ال action المسمى <code>actionEntry()</code>. وهذا يضمن صحة البيانات في جميع الظروف.
</p>
<blockquote class="warning"><p dir="rtl">
تحذير: التحقق من جانب العميل -client side- يوفر تجربة أفضل للمستخدم، لكن يجب الأخذ بعين الإعتبار أن التحقق من جانب الخادم -server- مطلوب دائمًا، سواء تم التحقق من جانب العميل أم لا.
</p></blockquote>
<p dir="rtl">
يتم إنشاء ال labels الخاصة بحقول الإدخال بواسطة الدالة <code>field()</code>، وذلك من خلال إستخدام أسماء ال property الموجودة داخل ال model. على سبيل المثال، سيتم إنشاء ال label التالي <code>Name</code> للproperty التالية: <code>name</code>.
</p>
<p dir="rtl">
كما يمكنك تعديل ال label الإفتراضي لأي حقل من خلال الشيفرة البرمجية التالية:
</p>
```php
<?= $form->field($model, 'name')->label('Your Name') ?>
<?= $form->field($model, 'email')->label('Your Email') ?>
```
<blockquote class="info"><p dir="rtl">
معلومة: يوفر ال Yii العديد من ال widgets لمساعدتك في إنشاء views معقدة وديناميكية بسرعة. كما أنك ستتعلم في وقت لاحق كيف يمكنك إنشاء widget جديد، وستكتشف أن الموضوع سهل وبسيط، مما سيدفعك إلى كتابة الشيفرة البرمجية الخاصة بك داخل ال widget، والذي بدوره سيجعل من هذه الشيفرة قابلة للتطوير والإستخدام في أكثر من مكان في المستقبل.
</p></blockquote>
## <div dir="rtl">الخلاصة</div> <span id="summary"></span>
<p dir="rtl">
في هذا الجزء من التوثيق، تحدثنا عن كل جزء في ال MVC architectural pattern، لقد تعلمت الآن كيف يمكنك إنشاء model class ليقوم بتمثيل البيانات الخاصة بالمستخدمين، ومن ثم التحقق منها.
</p>
<p dir="rtl">
لقد تعلمت أيضًا كيفية الحصول على البيانات من المستخدمين، وكيفية عرض البيانات مرة أخرى في المتصفح. هذه المهمة يمكن أن تأخذ الكثير من الوقت عند تطوير أي تطبيق، ولكن، يوفر ال Yii العديد من ال widgets القوية، والتي تجعل من هذه المهمة أمرا سهلا للغاية.
</p>
<p dir="rtl">
في الجزء القادم من هذا التوثيق، ستتعلم كيف يمكنك التعامل مع قواعد البيانات، والتي سنحتاجها -غالبا- مع كل تطبيق ستعمل عليه تقريبا.
</p>

161
docs/guide-ar/start-gii.md

@ -1,161 +0,0 @@
# <div dir="rtl">إنشاء الشيفرة البرمجية من خلال ال gii</div>
<p dir="rtl">
في هذا الجزء التعليمي سنتعرف على آلية التعامل مع ال <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a>، والذي يستخدم لإنتاج الشيفرة البرمجية الخاصة بمعظم الميزات والخصائص المشتركة في أغلب المواقع بشكل تلقائي، بالإضافة الى ذلك، فإن استخدام ال Gii لإنشاء الشيفرة البرمجية بشكل تلقائي يمثل مجموعة من المعلومات الصحيحة التي بتم إدخالها إعتمادا على التعليمات الموجودة في ال Gii Web Pages.
</p>
<p dir="rtl">
من خلال هذا البرنامج التعليمي، ستتعلم كيفية:
</p>
<ul dir="rtl">
<li>تفعيل ال Gii داخل التطبيق الخاص بك</li>
<li>إستخدام ال Gii لإنشاء ال Active Record class</li>
<li>إستخدام ال Gii لإنشاء الشيفرة البرمجية الخاصة بال CRUD إعتمادا على الجداول الموجودة في قاعدة البيانات</li>
<li>تخصيص (custmize) الشيفرة البرمجية التي سيتم إنتاجها من خلال ال Gii.</li>
</ul>
## <div dir="rtl">البدء باستخدام ال Gii</a> <span id="starting-gii"></span>
<p dir="rtl">
يتم تقديم ال <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a> داخل على ال Yii على أنه <a href="../guide/structure-modules.md">module</a>، ويمكنك تفعيله من خلال الإعدادات الخاصة به والتي تجدها داخل ال application، وبالتحديد داخل ال property التالية [[yii\base\Application::modules|modules]]، واعتمادا على كيفية إنشائك للمشروع، فيمكنك إيجاد الشيفرة البرمجية التالية موجودة بشكل مسبق داخل ال <code>config/web.php</code>:
</p>
```php
$config = [ ... ];
if (YII_ENV_DEV) {
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
}
```
<p dir="rtl">
في الإعدادت الموجودة في الأعلى، فإن التطبيق سيقوم بتضمين وتفعيل ال gii في حال كانت الحالة الخاصة بالتطبيق هي <a href="../guide/concept-configurations.md#environment-constants">development enviroment</a>، بالإضافة الى ذلك، فإنه يجب تضمين واستخدام ال module <code>gii</code>، والموجود ضمن ال class التالي [[yii\gii\Module]].
</p>
<p dir="rtl">
اذا قمت بالتحقق من ال <a href="../guide/structure-entry-scripts.md">entry script</a> وبالتحديد صفحة ال <code>web/index.php</code> في التطبيق الخاص بك، ستجد هذه الأسطر، والتي يجب أن تجعل من ال <code>YII_ENV_DEV</code> ذات قيمة <code>true</code>.
</p>
```php
defined('YII_ENV') or define('YII_ENV', 'dev');
```
<p dir="rtl">
كل الشكر لهذا السطر البرمجي، التطبيق الآن أصبح بحالة ال development mode، وأصبح لديك ال Gii enabled بالفعل، والآن، يمكنك الوصول الى ال Gii من خلال عنوان ال URL التالي:
</p>
```
http://hostname/index.php?r=gii
```
<blockquote class="note"><p dir="rtl">
ملاحظة: إذا كنت تحاول الوصول إلى Gii من جهاز آخر غير ال localhost، فسيتم رفض الوصول افتراضيًا لأغراض أمنية، ولكن، يمكنك إعداد ال Gii لإضافة مجموعة من ال IP Addresses المسموح لها بالوصول وذلك من خلال:
</p></blockquote>
```php
'gii' => [
'class' => 'yii\gii\Module',
'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // عدل هذه حسب إحتياجاتك
],
```
![Gii](../guide/images/start-gii.png)
## <div dir="rtl">إنشاء ال Active Record Class من خلال ال Gii</div> <span id="generating-ar"></span>
<p dir="rtl">
لإستخدام ال Gii لإنشاء ال Active Record class, قم باختيار ال "Model Generator" (من خلال النقر على الرابط الموجود بالصفحة الرئيسية لل Gii)، ومن ثم قم بتعبئة ال form كما يلي:
</p>
<ul dir="rtl">
<li>إسم الجدول: <code>country</code></li>
<li><code>Country</code> :Model Class</li>
</ul>
![Model Generator](../guide/images/start-gii-model.png)
<p dir="rtl">
والآن، قم بالنقر على الزر "Preview"، ستشاهد الآن <code>models/Country.php</code> قد تم إنشائها وإضافتها الى قائمة النتائج، اذا قمت بالنقر على إسم ال class، فإن المحتوى الخاص بهذا ال class سيتم عرضه.
</p>
<p dir="rtl">
عند استخدام ال Gii، إذا كنت قد قمت بالفعل بإنشاء نفس الملف وستقوم بعمل overwriting عليه، فيمكنك النقر على زر <code>diff</code> الموجود بعد إسم ال class، لتشاهد الفرق بين الشيفرة البرمجية الحالية، والشيفرة البرمجية الجديدة.
</p>
![Model Generator Preview](../guide/images/start-gii-model-preview.png)
<p dir="rtl">
عند قيامك بعمل overwriting على ملف موجود، قم بالضغط على ال ckeckbox الموجودة بجانب كلمة overwrite، ومن ثم قم بالنقر على زر "Generate", اذا كان هذا الملف جديد، وغير موجود مسبقا، فيمكنك النقر مباشرة على "Generate"، بعد ذلك ستشاهد صفحة ال confirmation والتي تبين الشيفرات البرمجية التي تم إنشائها بنجاح.
</p>
<p dir="rtl">
بعد فيامك بالنقر على زر Generate، فإنك ستشاهد صفحة ال confirmation page، والتي تقوم بدورها بتوضيح الشيفرات البرمجية التي تم إنشائها بنجاح، واذا كان الملف موجود، فإنك ستشاهد أيضا رسالة تعلمك بأن الملف قد تم تعديله وتمت إضافة الشيفرة الجديدة مكان القديمة.
</p>
## <div dir="rtl">إنشاء ال CRUD Code</div> <span id="generating-crud"></span>
<p dir="rtl">
ال CRUD هي اختصار ل Create, Read, Update, And Delete (إنشاء، وقرائة، وتحديث، وحذف)، والتي تمثل أكثر المهمات المطلوبة للتعامل مع البيانات على مواقع الويب. ولإنشاء ال CRUD باستخدام ال Gii، قم باختيار ال "CRUD Generator" (من خلال النقر على الرابط الموجود بالصفحة الرئيسية لل Gii)، وهنا وبالبنسبة للمثال الخاص بال "country"، يمكنك تعبئة ال from بما يلي:
</p>
* Model Class: `app\models\Country`
* Search Model Class: `app\models\CountrySearch`
* Controller Class: `app\controllers\CountryController`
![CRUD Generator](../guide/images/start-gii-crud.png)
<p dir="rtl">
بعد ذلك، قم بالنقر على زر ال "Preivew"، وستشاهد قائمة بالملفات التي سيتم إنشائها كما في الصورة أدناه.
</p>
![CRUD Generator Preview](../guide/images/start-gii-crud-preview.png)
<p dir="rtl">
اذا قمت إنشاء الصفحتين <code>controllers/CountryController.php</code> و <code>views/country/index.php</code> عند حديثنا سابقا عند موضوع (التعامل مع قواعد البيانات)، فقم بالضغط على ال "overwrite" ليتم إستبدالهم. (الصفحات القديمة لا توجد فيها كل الخصائص التي سيتم إنتاجها من خلال ال Gii CRUD).
</p>
## <div dir="rtl"> لنجرب المثال </div> <span id="trying-it-out"></span>
<p dir="rtl">
لتشاهد آلية العمل لهذا المثال، والنتائج المتعلقة به، يمكنك إستخدام المتصفح والدخول الى الرابط التالي:
</p>
```
http://hostname/index.php?r=country%2Findex
```
<p dir="rtl">
عند دخولك إلى الرابط أعلاه، ستشاهد مجموعة الدول التي تم إستدعائها من جدول ال country من قاعدة البيانات، ويمكنك التعامل مع هذا ال grid من حيث الترتيب أو التصفية بنائا على الشروط التي ستقوم بإدخالها في مربعات النص أعلى الأعمدة.
</p>
<p dir="rtl">
لكل دولة تم جلبها وعرضها داخل ال Grid، هناك مجموعة من الخيارات التي يمكنك التعامل معها بشكل إفتراضي، مثل ال view لعرض التفاصيل الخاصة بالدولة المختارة، أو تحديث المعلومات، الخاصة بالدولة، أو حذف هذه الدولة، بالإضافة إلى ذلك يمكنك النقر على "Create Country" الموجودة في أعلى ال Grid والتي ستأخذك بدورها الى صفحة تحتوي form لإنشاء ال country.
</p>
![Data Grid of Countries](../guide/images/start-gii-country-grid.png)
![Updating a Country](../guide/images/start-gii-country-update.png)
<p dir="rtl">
فيما يلي قائمة بالملفات التي تم إنشاؤها من خلال ال Gii، في حالة رغبتك في التحقق من كيفية عمل هذه الميزات والإطلاع على الشيفرة البرمجية وتخصيصها حسب الرغبة:
</p>
* Controller: `controllers/CountryController.php`
* Models: `models/Country.php` and `models/CountrySearch.php`
* Views: `views/country/*.php`
<blockquote class="info"><p dir="rtl">
معلومة: تم تصميم ال Gii لتكون أداة إنشاء شيفرات برمجية قابلة للتخصيص بشكل كبير للغاية. اذا قمت باستخدامه بحكمة،فإنك ستقوم بتسريع وتيرة التطوير الخاصة بالتطبيق الخاص بك. لمزيد من التفاصيل، يرجى الذهاب إلى الجزء الخاص بال <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a>.
</p></blockquote>
## <div dir="rtl">الخلاصة</div> <span id="summary"></span>
<p dir="rtl">
في هذا الجزء من التوثيق، لقد تعلمنا آلية استخدام ال Gii لإنشاء الشيفرة البرمجية الخاصة بال CRUD، وتحدثنا عن الوظائف التي تقوم فيها، وكيف يمكننا من خلالها إتمام العمليات الخاصة بالبيانات من إدخال وتحديث وحذف وعرض للبيانات من قاعدة البيانات.
</p>

149
docs/guide-ar/start-hello.md

@ -1,149 +0,0 @@
# <div dir="rtl">قل مرحبا - Saying Hello</div>
<p dir="rtl">
في هذا الموضوع سنتعرف على كيفية إنشاء صفحة "Hello" جديدة في التطبيق الذي قمت بتثبيته، ولتحقيق ذلك، يجب عليك القيام بإنشاء <a href="../guide/structure-controllers.md#creating-actions">action</a> و <a href="../guide/structure-views.md">view</a> لهذه الصفحة:
</p>
<ul dir="rtl">
<li>سيقوم التطبيق بإرسال ال request الخاص بالصفحة إلى ال action.</li>
<li>وسيقوم ال action بدوره في جلب ال view التي تعرض كلمة "Hello" إلى المستخدم النهائي.</li>
</ul>
<p dir="rtl">
من خلال هذا البرنامج التعليمي ، ستتعلم ثلاثة أشياء:
</p>
<ol dir="rtl">
<li>كيفية إنشاء <a href="../guide/structure-controllers.md#creating-actions">action</a> ليقوم بإستقبال ال request ومن ثم الرد (respond) عليها.</li>
<li>كيفية إنشاء <a href="../guide/structure-views.md">view</a> وإضافة المحتوى الى ال respond.</li>
<li>و كيفية إنشاء التطبيق لل requests التي يوجهها لل <a href="../guide/structure-controllers.md#creating-actions">actions</a>. </li>
</ol>
## <div dir="rtl">إنشاء ال Action</div> <span id="creating-action"></span>
<p dir="rtl">
لإنشاء صفحة "Hello"، ستقوم بإنشاء <code>say</code> <a href="../guide/structure-controllers.md#creating-actions">action</a> والذي بدوره سيقوم بقراءة ال <code>message</code> parameter من ال request، ومن ثم عرض ال <code>message</code> مرة أخرى إلى المستخدم. إذا كان ال request لا يحمل معه ال message parameter فإن ال action سيقوم بطباعة message إفتراضية وهي "Hello".
</p>
<blockqoute class="info"><p dir="rtl">
معلومة: ال <a href="../guide/structure-controllers.md#creating-actions">Actions</a> هي الكائنات(objects) التي يمكن للمستخدمين من الوصول اليها وتنفيذ ما في بداخلها بشكل مباشر. يتم تجميع هذه ال Actions بواسطة ال <a href="../guide/structure-controllers.md">controllers</a>. ونتيجة لذلك فإن ال response الراجعة للمستخدم ستكون هي نتيجة التنفيذ الخاصة بال action.
</p></blockqoute>
<p dir="rtl">
يجب تعريف ال actions داخل ال <a href="../guide/structure-controllers.md">controller</a>، ولتبسيط الفكرة، سنقوم بتعريف ال <code>say</code> action داخل أحد ال controller الموجود مسبقا وهو ال <code>siteController</code>. هذا ال controller ستجده داخل المسار <code>controllers/siteController.php</code>. ومن هنا سنبدأ بإضافة ال action الجديد:
</p>
```php
<?php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
// ...existing code...
public function actionSay($message = 'Hello')
{
return $this->render('say', ['message' => $message]);
}
}
```
<p dir="rtl">
في الشيفرة البرمجية السابقة ، تم تعريف ال <code>say</code> action من خلال إنشاء الدالة <code>actionSay</code> داخل الكلاس <code>siteController</code>. يستخدم ال Yii كلمة action ك prefix للدوال للتميز بين الدوال ال action و ال non-action في ال controller، كما يستخدم الإسم الخاص بال action مباشرة بعد ال prefix، ويتم عمل mapping بين ال action method name وال action id ليستطيع المستخدم من الوصول للدالة المنشئة من خلال ال action id.
</p>
<p dir="rtl">
عندما يتعلق الأمر بتسمية ال action الخاصة بك، يجب عليك أن تفهم كيف يقوم ال Yii بالتعامل مع ال action id، ال action id يجب أن يكون دائما أحرف lower case، وإذا إحتوى ال action id على عدة كلمات فإن الفاصل بينهم سيكون الداش (dashes) مثل <code>create-comment</code>، ويتم ربط ال action id بال action method name من خلال حذف ال dashes من ال IDs، ويتم عمل capitalizing لأول خرف من كل كلمة، وإضافة ال prefix الى الناتج السابق من التحويل. مثال: ال action id المسمى ب <code>create-comment</code> سيتم تحويله الى ال action method name التالي: <code>actionCreateComment</code>.
</p>
<p dir="rtl">
في المثال السابق، يقوم ال action method على إستقبال parameter يسمى ب <code>$message</code>، والذي يملك قيمة إفتراضية وهي <code>"Hello"</code> (وهي مشابة تماما لطريقة وضع القيم الإفتراضية لل argument في ال PHP). عندما يستقبل التطبيق ال request ويحدد أن ال action المطلوب للتعامل مع الطلب (request) هو <code>say</code>، فإن التطبيق سيقوم بإسناد القيمة الموجودة بال request الى ال parameter الموجود بال action بشرط أن يكون الإسم الموجود بال request هو نفسه الموجود في ال action. ولتبسيط الموضوع يمكن القول أن ال request اذا احتوى على كلمة <code>message</code> وقيمة هذا ال parameter هي <code>"GoodBye"</code>، فإن ال <code>$message</code> الموجودة في ال action ستصبح قيمتها <code>"GoodBye"</code>.
</p>
<p dir="rtl">
من خلال ال action method، يتم استدعاء ال [[yii\web\Controller::render()|render()]] لتقديم
الملف الخاص بال view والمسمى هنا ب <code>say</code>. أيضا فإن ال <code>message</code> يتم تمرريرها الى ال view مما يسمح لك باستخدام هذا ال parameter داخل ال view. النتيجة المرجعة لل view تتم معالجتها وإرجاعها من خلال ال action method، وهذه النتائج سيتم إستقبالها من خلال المتصفح الخاص بالمستخدم ليتم عرضها وكأنها (جزء من صفحة Html كاملة).
</p>
## <div dir="rtl">إنشاء ال View</div> <span id="creating-view"></span>
<p dir="rtl">
ال <a href="../guide/structure-views.md">Views</a> هي شيفرات برمجية كتبت ﻹنشاء المحتوى المناسب بنائا على ال response الراجع اليها من خلال ال action.
بالنسبة إلى مثال "Hello" ، الآن سنقوم بإنشاء view مسمى ب <code>say</code>، والذي سيقوم بدوره بطباعة ال <code>message</code> التي تم إستلامها من ال action، شاهد المثال:
</p>
```php
<?php
use yii\helpers\Html;
?>
<?= Html::encode($message) ?>
```
<p dir="rtl">
صفحة ال view <code>say</code> يجب أن يتم حفظها داخل المسار التالي: <code>views/site/say.php</code>. عندما يتم إستدعاء الدالة [[yii\web\Controller::render()|render()]] من قبل ال action، فإنه سينظر للمسار على الشكل التالي: <code>views/ControllerID/ViewName.php</code>، بحيث يكون في مثالنا السابق ال ContollerID هو ال <code>site</code> وال viewName هو <code>say</code>.
</p>
<p dir="rtl">
ملاحظة: في الشيفرة البرمجية أعلاه، تكون ال <code>message</code> مضمنة داخل ال [[yii\helpers\Html::encode()]] قبل أن يتم طباعتها، هذا الأمر ضروري لأن ال parameter التي تأتي من المستخدم النهائي لا يجب الوثوق بها، فهي يمكن أن تحتوي على شيفرات برمجية تستغل الضعف الحاص بك بموضوع الأمان مثل <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">vulnerable to XSS attack</a> عن طريق دمج JS code مع ال parameter.
</p>
<p dir="rtl">
وبطبيعة الحال، يمكنك وضع المزيد من المحتوى في صفحة ال <code>say</code> view. ويمكن أن يتكون هذا المحتوى من HTML tag و plain text وحتى PHP statements.
في الواقع، تعد ال <code>say</code> view مجرد شيفرة برمجية بلغة ال PHP والتي يتم تنفيذها بواسطة [[yii\web\Controller::render()|render()]].
المحتوى الذي سيتم طباعته من خلال ال view سيتم إرجاعه الى التطبيق من خلال ال response، وسيقوم التطبيق بدوره بإخراج هذه النتيجة إلى المستخدم النهائي.
</p>
## <div dir="rtl">تطبيق المثال</div> <span id="trying-it-out"></span>
-------------
<p dir="rtl">
بعد إنشاء ال action وصفحة ال view، يمكنك الوصول إلى الصفحة الجديدة عن طريق عنوان URL التالي:
</p>
```
http://hostname/index.php?r=site%2Fsay&message=Hello+World
```
![Hello World](../guide/images/start-hello-world.png)
<p dir="rtl">
سينتج عن هذا ال URL صفحة تعرض "Hello World". هذه الصفحة لديها نفس ال Header و ال Footer لصفحات التطبيق الأخرى.
</p>
<p dir="rtl">
إذا قمت بحذف ال <code>message</code> parameter من ال URL ، فسترى الصفحة تعرض كلمة <code>" Hello "</code> فقط. ويرجع ذلك إلى أن "message" يتم تمريرها ك parameter إلى ال <code>actionSay()</code>، وعندما يتم حذفها، سيتم استخدام القيمة الافتراضية وهي <code>"Hello"</code> بدلاً من ذلك.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: تتشارك الصفحة الجديدة مع الصفحات الأخرى بالتطبيق بنفس ال Header وال Footer وذلك بسبب الدالة [[yii\web\Controller::render() | render ()]] والتي ستقوم بشكل تلقائي بتضمين النتيجة الخاصة بصفحة ال view <code>say</code> مع صفحة ال <a href="../guide/structure-views.md#layouts">Layout</a>، والتي يمكنك أن تجدها داخل المسار التالي: <code>views/layouts/main.php</code>
</p></blockquote>
<p dir="rtl">
ال <code>r</code> الموجودة في ال URL أعلاه يتطلب الكثير من الشرح. ولكن باختصار يمكن القوم أنها اختصار ل <a href="../guide/runtime-routing.md">route</a> ، وهو معرف فريد من نوعه(unique ID) للتطبيق بحيث يقوم بالتأشير على ال action، والصيغة الخاصة بال route هي <code>ControllerID/ActionID</code>. عندما يتلقى التطبيق request، فإنه سيتم التحقق من <code>r</code> parameter، فيقوم باستخدام الجزء <code>ControllerID</code> لتحديد ال controller class المطلوب ليقوم بعمل instance منه، ومن ثم يقوم ال controller باستخدام ال <code>"ActionID"</code> لتحديد ال action المطلوب والذي سيقوم بالعمل الفعلي.
في المثال الخاص بنا، فإن ال route هو <code>"site/say"</code>، وهذا ال route يتم معالجته ليستدعي ال controller class المسمى ب <code>SiteController</code> و ال action المسمى ب <code>actionSay</code> داخل هذا ال controller، ونتيجة لذلك سيتم فعليا إستدعاء الدالة <code>SiteController::actionSay()</code> لتقوم بمعالجة ال request كما يلزم.
</p>
<blockquote><p dir="rtl">
معلومة: مثل ال actions، تحتوي ال controllers أيضًا على Uniquely IDs يتم تعريفها واستخدامها من خلال التطبيق. تستخدم ال Controllers IDs نفس قواعد التسمية الخاصة بال action IDs، ويتم ذلك من خلال حذف ال dashes و capitalizing أول حرف من كل كلمة، ثم إضافة كلمة <code>Controller</code> الى الإسم الناتج -وهنا الإختلاف عن ال action ID-. مثال: ال controller ID المسمى ب <code>"post-comment"</code> ستم معالجته ليصبح <code>PostCommentController</code>.
</p></blockquote>
## <div dir="rtl">الخلاصة</div> <span id="summary"></span>
<p dir="rtl">
في هذا الموضوع، قمنا بالتعرف على ال controller وال view كأجزاء من MVC architectural pattern، كما قمنا بإنشاء action داخل controller موجود ليستقبل specific request ويتحكم فيه، وقمنا أيضا بإنشاء view لعرض المحتوى. في هذا المثال البسيط، لم نتطرق الى ال model، وقمنا فقط باستخدام ال data بشكل مباشر من خلال ال <code>message</code> parameter.
</p>
<p dir="rtl">
كما تعرفنا أيضا على ال routes في ال Yii، والتي تعمل بدورها كجسر بين ال user request وال controller actions.
</p>
<p dir="rtl">
في الموضوع القادم، ستتعلم كيف يمكنك إنشاء model وكيف يمكنك إنشاء صفحة جديدة تحتوي على Html form.
</p>

303
docs/guide-ar/start-installation.md

@ -1,303 +0,0 @@
# <div dir="rtl">تثبيت ال Yii</div>
<p dir="rtl">يمكنك تثبيت ال Yii بطريقتين ، الأولى باستخدام مدير الحزم <a href="https://getcomposer.org">Composer</a> أو عن طريق تنزيل Archive File. الطريقة الأولى هي الطريقة المفضلة للعمل، ، لأنها تتيح لك تثبيت [<a href="../guide/structure-extensions.md">extensions</a> - ملحقات أو اضافات] جديدة، أو تحديث إطار العمل Yii ببساطة عن طريق تشغيل أمر واحد فقط.
</p>
<p dir="rtl">
التثبيت الإفتراضي لل Yii ينتج عنه بنية تركيبة منظمة ومرتبة للمجلدات والملفات التي بداخلها، ويوفر هذا الكلام بعض المميزات التي يتم إضافتها وإنشائها بشكل تلقائي مثل صفحة تسجيل الدخول، ونموذج اتصل بنا...الخ، هذا الأمر سيشكل نقطة إنطلاق جيدة لبدء العمل على أي مشروع.
</p>
<p dir="rtl">
في هذه الصفحة من التوثيق سنقوم بشرح ووصف كيف يمكن تثبيت إطار العمل Yii وبالتحديد Yii2 Basic Project Template.
هناك Template آخر موجود بإطار العمل Yii وهو <a href="https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide">Yii2 Advanced Project Template</a>، وهو الأفضل للعمل وإنشاء المشاريع لفريق عمل برمجي، ولتطوير المشاريع متعددة الطبقات(multiple tires).
</p>
<blockquote class="info"><p dir="rtl">
معلومة: قالب المشروع الأساسي (Basic) مناسب لتطوير 90% من تطبيقات الويب. ويختلف القالب المتقدم (Advanced Template) عن القالب الأساسي في كيفية تنظيم وهيكلة الشيفرة البرمجية.
اذا كنت جديدا في عالم تطوير تطبيقات الويب باستخدام ال Yii، فإننا نوصيك بقوة بأن تستخدم القالب الأساسي في بناء المشروع الخاص بك.
</p></blockquote>
## <div dir="rtl">تثبيت ال Yii من خلال (Composer)</div> <span id="installing-via-composer"></span>
### <div dir="rtl">تثبيت ال Composer</div>
<p dir="rtl">
إن لم يكن لديك Composer مثبت مسبقا، فيمكنك السير بخطوات تثبيته من خلال الدخول الى هذا الرابط <a href="https://getcomposer.org/download/">https://getcomposer.org/download/</a>.
لتثبيت ال Composer في كل من نظامي Linux و Max OS X، يمكنك تنفيذ الأوامر التالية:
</p>
```bash
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
```
<p dir="rtl">
ولنظام ويندوز يمكنك تثبيت ال <a href="https://getcomposer.org/Composer-Setup.exe">Composer-Setup.exe</a> ومن ثم عمل run
</p>
<p dir="rtl">
يرجى الدخول الى <a href="https://getcomposer.org/doc/articles/troubleshooting.md">Troubleshooting section of the Composer Documentation</a> في حال واجهتك أي مشاكل متعلقة بال composer, وإذا كنت مستخدمًا جديدًا لل composer، ننصحك أيضًا بقراءة <a href="https://getcomposer.org/doc/01-basic-usage.md">قسم الاستخدام الأساسي</a> على الأقل من التوثيف الخاص بال composer.
</p>
<p dir="rtl">
في هذا الدليل ، نفترض أنك قمت بتثبيت ال composer على مستوى جميع المشاريع (<a href="https://getcomposer.org/doc/00-intro.md#globally">globally</a>) بحيث تكون أوامر ال composer متاحة لجميع المشاريع من أي مكان. أما إذا كنت تستخدم ال composer.phar لمسار محدد فقط(local directory)، فيجب عليك ضبط الأومر وفقًا لذلك.
</p>
<p dir="rtl">
إذا كان ال composer مثبتًا من قبل، فتأكد من استخدام إصدار حديث. يمكنك تحديث ال composer عن طريق تنفيذ الأمر التالي <code>composer self-update</code>
</p>
<blockquote class="note"><p dir="rtl">
ملاحظة مهمة: أثناء تثبيت ال Yii ، سيحتاج ال composer إلى طلب(request) الكثير من المعلومات من ال Github Api. يعتمد عدد الطلبات على عدد dependencies التي يمتلكها التطبيق الخاص بك، وقد يكون هذا العدد أكبر من الحد المسموح به من قبل ال Github Api <b>(Github API rate limit)</b>. إذا وصلت الى الحد الأعلى المسموح به من الطلبات، فقد يطلب منك ال composer بيانات تسجيل الدخول إلى Github، وذلك للحصول على رمز (token) للدخول إلى Github Api. اذا كانت عمليات الإتصال سريعة، فقد تصل إلى هذا الحد(limit) قبل أن يتمكن ال composer من التعامل معه ، لذالك نوصي بتكوين رمز الدخول(access token) قبل تثبيت ال Yii. يرجى الرجوع إلى التوثيق الخاص بال Composer والإطلاع على التعليمات الخاصة <a href="https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens">Github API tokens</a> للحصول على الإرشادات اللازمة للقيام بذلك.
</p></blockquote>
### <div dir="rtl">تثبيت ال Yii</div> <span id="installing-from-composer"></span>
<p dir="rtl">
من خلال ال Composer، يمكنك الآن تثبيت ال Yii من خلال تنفيذ سطر الأوامر التالي داخل أي مسار يمكن الوصول اليه من قبل الويب
</p>
```bash
composer create-project --prefer-dist yiisoft/yii2-app-basic basic
```
<p dir="rtl">
سطر الأوامر السابق سيقوم بتثبيت أحدث نسخة مستقرة(stable) من إطار العمل Yii داخل مسار جديد اسمه basic، ويمكنك التعديل على سطر الأوامر السابق لتغيير اسم المشروع لأي اسم ترغب فيه.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: اذا واجهتك أي مشكلة عند تنفيذ السطر `composer create-project` فيمكنك الذهاب إلى <a href="https://getcomposer.org/doc/articles/troubleshooting.md">قسم استكشاف الأخطاء في ال composer</a>.
في معظم الأخطاء الشائعة، وعند حل المشكلة أو الخطأ، يمكنك إكمال التثبيت من خلال الدخول الى المسار `basic` ومن ثم تنفيذ الأمر التالي: `composer update`.
</p></blockquote>
<blockquote class="tip"><p dir="rtl">
تلميح: اذا كنت ترغب بتثبيت أحدث نسخة خاصة بالمطورين من ال Yii، فيمكنك ذلك من خلال إضافة الخيار <a href="https://getcomposer.org/doc/04-schema.md#minimum-stability">stability</a> وذلك من خلال سطر الأوامر التالي:
</p></blockquote>
```bash
composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
```
<blockquote class="note"><p dir="rtl">
ملاحظة: نسخة المطورين من ال Yii يجب أن يتم إستخدامها للمواقع الإلكترونية التي لن تصدر كنسخة نهائية للمستخدم(Not for production) لأن ذلك يمكن أن يسبب بإيقاف المشروع أو الشيفرة البرمجية الخاصة بك.
</p></blockquote>
### <div dir="rtl">تثبيت ال Yii من خلال ال Archive File</div> <span id="installing-from-archive-file"></span>
--------------------------
<p dir="rtl">
يتضمن تثبيت Yii من ملف أرشيف ثلاث خطوات وهي:
</p>
<ol dir="rtl">
<li> تثبت الملف من خلال الموقع الرسمي <a href="https://www.yiiframework.com/download/">yiiframework.com</a>.</li>
<li> قم بفك ضغط الملف الذي تم تنزيله إلى مجلد يمكن الوصول إليه عبر الويب.</li>
<li> قم بتعديل ملف <code>config/web.php</code> عن طريق إدخال secret key ل<code> cookieValidationKey</code>
(يتم ذلك تلقائيًا إذا قمت بتثبيت ال Yii باستخدام Composer): </li>
</ol>
```php
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'enter your secret key here',
```
### <div dir="rtl">خيارات تثبيت أخرى</div> <span id="other-installation-options"></span>
--------------------------
<p dir="rtl">
توضح تعليمات التثبيت أعلاه كيفية تثبيت ال Yii ، والذي يقوم أيضًا بإنشاء تطبيق ويب أساسي(basic).
هذا النهج هو نقطة انطلاق جيدة لمعظم المشاريع، صغيرة كانت أو كبيرة. خصوصا اذا كنت قد بدأت تعلم ال Yii من وقت قريب.
<br /><br />
لكن، هناك خيارات أخرى متاحة لتثبيت ال Yii وهي:
</p>
<ul dir="rtl">
<li> إذا كنت ترغب فقط في تثبيت ال core لإطار العمل Yii، وترغب ببناء المكونات الخاصة بإطار العمل كما ترغب أنت وبطريقتك أنت، يمكنك اتباع التعليمات كما هو موضح في هذه الصفحة <a href="../guide/tutorial-start-from-scratch.md"> Building Application from Scratch</a>.</li>
<li> إذا كنت تريد البدء بتطبيق أكثر تعقيدًا وأكثر إحترافية، ويتناسب بشكل أفضل مع وجود فريق عمل تقني،
فأنت اذا سترغب بتثبيت ال <a href="https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md">Advanced Project Template</a>
</li>
</ul>
### <div dir="rtl">تثبيت ال Assets</div> <span id="installing-assets"></span>
--------------------------
<p dir="rtl">
تعتمد ال Yii على حزم <a href="https://bower.io/">Bower</a> و/أو <a href="https://www.npmjs.com/">NPM</a> لتثبيت مكتبات ال (CSS و JavaScript). ويستخدم ال composer للحصول على هذه المكتبات ، مما يسمح بالحصول على إصدارات ال PHP و CSS/JavaScript في نفس الوقت. ويمكن تحقيق ذلك إما عن طريق استخدام <a href="https://asset-packagist.org/">asset-packagist.org</a> أو من خلال ال <a href="https://github.com/fxpio/composer-asset-plugin">composer asset plugin</a>، يرجى الرجوع إلى <a href="../guide/structure-assets.md">Assets documentation</a> لمزيد من التفاصيل.
<br /><br />
قد ترغب في إدارة ال assets عبر ال native Bower/NPM أو استخدام ال CDN أو تجنب تثبيت ال assets بالكامل من حلال ال Composer ، ويمكن ذلك من خلال إضافة الأسطر التالية إلى "composer.json":
</p>
```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"
},
```
<blockquote class="note"><p dir="rtl">
ملاحظة: في حالة تجاوز تثبيت ال assets عبر ال Composer، فأنت المسؤول عن تثبيت ال assets وحل مشكلات التعارض بين الإصدارات والمكتبات المختلفة. وكن مستعدًا لعدم تناسق محتمل بين ملفات ال asstes والإضافات المختلفة.
</p></blockquote>
### <div dir="rtl">التحقق من التثبيت</div> <span id="verifying-installation"></span>
--------------------------
<p dir="rtl">
بعد الانتهاء من التثبيت، ستحتاج الى القيام بإعداد خادم الويب الخاص بك(your web server) (انظر القسم التالي) أو قم باستخدام <a href="https://www.php.net/manual/en/features.commandline.webserver.php">built-in PHP web server</a> عن طريق تنفيذ الأمر التالي داخل المسار web في المشروع الخاص بك:
</p>
```bash
php yii serve
```
<blockquote class="note"><p dir="rtl">
ملاحظة: افتراضيًا ال HTTP-server يعمل على البورت 8080. ومع ذلك ، إذا كان هذا البورت قيد الاستخدام بالفعل أو كنت ترغب في تشغيل أكثر من تطبيق بهذه الطريقة، حينها سيلزمك تحديد البورت الذي يجب استخدامه. ما عليك سوى إضافة --port:
</p></blockquote>
```bash
php yii serve --port=8888
```
<p dir="rtl">
يمكنك استخدام الرابط الموجود في الأسفل للوصول الى تطبيق ال Yii الذي قمت بتثبيته وتنفيذ الأوامر السابقة عليه.
</p>
```
http://localhost:8080/
```
![Successful Installation of Yii](../guide/images/start-app-installed.png)
<p dir="rtl">
اذا كانت كل الإعدادات السابقة تعمل بشكل صحيح، فيجب أن ترى الصورة الموجودة بالأعلى "Congratulations!" على المتصفح. إذا لم يكن كذلك، يرجى التحقق مما إذا كان تثبيت الPHP الخاص بك متوافق مع متطلبات ال Yii. يمكنك التحقق من ذلك باستخدام أحد الأساليب التالية:
</p>
<ul dir="rtl">
<li>قم بنسخ الملف <code>/requirements.php</code> الى المسار <code>/web/requirements.php</code> بحيث يمكنك الوصول الى الصفحة من خلال الرابط التالي: <code>http://localhost/requirements.php</code></li>
<li>قم بتنفيذ الأوامر التالية: <br /><code>
cd basic
</code><br /><code>php requirements.php</code></li>
</ul>
<p dir="rtl">
يجب عليك أن تقوم بتثبيت وإعداد ال PHP الخاص بك بحيث تلبي الحد الأدنى من متطلبات ال Yii. الأهم من ذلك يجب أن يكون الإصدار الخاص بال PHP أعلى أو يساوي 5.4. من الناحية المثالية أحدث إصدار يعمل مع ال Yii هو ال PHP 7. يجب عليك أيضًا تثبيت ال <a href="https://www.php.net/manual/en/pdo.installation.php">PDO PHP Extension</a>.
</p>
### <div dir="rtl">إعداد ال Web Servers</div> <span id="configuring-web-servers"></span>
-----------------------
<blockquote class="info"><p dir="rtl">
معلومة: يمكنك تخطي هذا الجزء الآن إذا كنت تختبر فقط إطار العمل Yii دون أي نية لنشر هذا التطبيق على الويب(بدون رفع التطبيق على production server).
</p></blockquote>
<p dir="rtl">
يجب أن يعمل التطبيق الذي تم تثبيته وفقًا للتعليمات المذكورة أعلاه مع أي من الخوادم ال <a href="https://httpd.apache.org/">Apache HTTP</a> أو ال <a href="https://nginx.org/">Nginx HTTP</a> في كل من أنظمة التشغيل Windows, Mac OS X أو Linux ممن لديها إصدار أعلى أو يساوي PHP 5.4، كما أن ال Yii 2.0 متوافق مع ال Facebook <a href="https://hhvm.com/">HHVM</a>، لكن، يجب أن تأخذ بعين الإعتبار أن ال HHVM يسلك في بعض الأحيان بطريقة مختلفة عن ال Native PHP، لذلك يجب أن تأخذ عناية إضافية عندما تعمل على ال HHVM.
</p>
<p dir="rtl">
على ال production server، قد ترغب في إعداد خادم الويب الخاص بك بحيث يمكن الوصول إلى التطبيق
الخاص بك عبر ال URL التالي <code>http://www.example.com/index.php</code> بدلاً من <code>http://www.example.com/basic/web/index.php</code>. هذا الكلام يتطلب إنشاء إعداد يقوم بتوجيه ال document root الموجود على ال web server الى مجلد ال basic/web، كما قد ترغب أيضا بإخفاء ال <code>index.php</code> من ال URL كما هو موضح في ال <a href="../guide/runtime-routing.md">Routing and URL Creation</a>. في هذا الموضوع ستتعلم كيف يمكنك إعداد ال Apache أو ال Nginx server لتحقيق هذه الأهداف.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: من خلال تعيين ال <code>basic/web</code> ك <code>document root</code>، فإنك بذلك تمنع أيضًا المستخدمين النهائيين من الوصول الى الشيفرة البرمجية الخاصة بالتطبيق الخاص بك، وتمنعهم من الوصول الى الملفات الحساسة والمهمة والمخزنة في sibling directories من <code>basic/web</code>، ويعبر رفض الوصول الى المجلدات الأخرى تحسينا أمنيا مهما، يساعد في الحفاظ على مستوى أعلى من الحماية.
</p></blockquote>
<blockquote class="info"><p dir="rtl">
معلومة: إذا كان سيتم تشغيل التطبيق الخاص بك في بيئة استضافة مشتركة(shared hosting) حيث ليس لديك الصلاحية لتعديل الإعدادات الخاصة بال web server، ستحتاج حينها الى تعديل في البنية الخاصة بالمشروع للحصول على أفضل أمان ممكن. يرجى الرجوع إلى <a href="../guide/tutorial-shared-hosting.md">Shared Hosting Environment</a> لمزيد من المعلومات.
</p></blockquote>
<blockquote class="info"><p dir="rtl">
معلومة: إذا كنت تقوم بتشغيل تطبيق ال Yii بوجود ال proxy، فقد تحتاج إلى إعداد التطبيق ليكون ضمن ال <a href="../guide/runtime-requests.md#trusted-proxies">trusted proxies and header</a>.
</p></blockquote>
### <div dir="rtl">الإعدادات الموصى بها لل Apache</div> <span id="recommended-apache-configuration"></span>
-----------------------
<p dir="rtl">
استخدم الإعدادات التالية في ملف ال <code>httpd.conf</code> في Apache أو ضمن إعدادات ال virtual host.
ملاحظة: يجب عليك استبدال المسار التالي <code>path/to/basic/web</code> بالمسار الفعلي للتطبيق الخاص بك وصولا الى ال <code>basic/web</code>.
</p>
```apache
# Set document root to be "basic/web"
DocumentRoot "path/to/basic/web"
<Directory "path/to/basic/web">
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
# if $showScriptName is false in UrlManager, do not allow accessing URLs with script name
RewriteRule ^index.php/ - [L,R=404]
# ...other settings...
</Directory>
```
### <div dir="rtl">الإعدادات الموصى بها لل Nginx</div> <span id="recommended-nginx-configuration"></span>
-----------------------
<p dir="rtl">
لاستخدام <a href="https://wiki.nginx.org/">Nginx</a>، يجب تثبيت PHP على أنه <a href="https://www.php.net/install.fpm">FPM SAPI</a>، ويمكنك استخدام إعدادات ال Nginx التالية، مع الإنتباه على استبدال المسار من <code>path/to/basic/web</code> الى المسار الفعلي وصولا إلى <code>basic/web</code> بالإضافة الى إستبدال <code>mysite.test</code> إلى ال hostname الخاص بالتطبيق.
</p>
```nginx
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.test;
root /path/to/basic/web;
index index.php;
access_log /path/to/basic/log/access.log;
error_log /path/to/basic/log/error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}
```
<p dir="rtl">
عند استخدامك لهذا الإعداد، يجب عليك أيضًا تعيين <code>cgi.fix_pathinfo = 0</code> في ملف php.ini
من أجل تجنب العديد من طلبات ال <code>stat()</code> الغير الضرورية للنظام.
</p>
<p dir="rtl">
لاحظ أيضًا أنه عند تشغيل خادم HTTPS، تحتاج إلى إضافة <code>fastcgi_param HTTPS on;</code>
بحيث يمكنك إكتشاف إذا ما كان الاتصال آمنًا أم لا.
</p>

36
docs/guide-ar/start-looking-ahead.md

@ -1,36 +0,0 @@
# <div dir="rtl">ماذا الآن - الخطوة القادمة</div>
<p dir="rtl">
إذا قمت بقرائة الفصل الخاص ب "البداية من هنا"، فأنت الآن قادر على بناء تطبيق Yii متكامل، لقد تعلمت كيف يمكنك تنفيذ وإستخدام أكثر الخصائص والمميزات المشتركة، مثل جلب البيانات من قاعدة البيانات، وأخذ البيانات من المستخدمين، ومن ثم عرضها، كما تعلمت كيف يمكنك تقسيم البيانات الى صفحات، وقمنا باستخدام ال <a href="https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide">Gii</a> وتعلمنا كيف يمكننا إنشاء شيفرة برمجية من خلاله بشكل تلقائي، ومن الممارسة تعلمنا أن إنشاء الشيفرة البرمجية من خلال ال Gii يجعل من عملية تطوير المواقع والوظائف المطلوبة أمرا بسيطا وسهلا للغابة، كل ما عليك القيام به هو تعبئة ال forms.
</p>
<p dir="rtl">
في هذا الجزء من التوثيق سنعرض ملخص للمصادر المتاحة لل Yii، والتي ستساعدك في تحسين إنتاجيتك عند إستخدامك لبيئة العمل Yii.
</p>
<ul dir="rtl">
<li>
التوثيق
<ul>
<li><a href="https://www.yiiframework.com/doc-2.0/guide-README.html">The Definitive Guide - الدليل الشامل</a>: كما يشير الإسم، فإن هذا الدليل يحدد آلية عمل ال Yii بدقة عالية، ويوفر إرشادات حول كيفية إستخدام ال Yii، هذا الجزء الأكثر أهمية في ال Yii، والذي يجب عليك قرائته قبل كتابة أي Yii code (ملاحظة: جزء البداية من هنا، والذي قمنا بدراسته هو أحد هذه الأجزاء، ومن أهمها للبدء بإنشاء التطبيقات من خلال ال Yii).</li>
<li><a href="https://www.yiiframework.com/doc-2.0/index.html">The Class Reference - المرجع الخاص بال Class</a> في هذا الجزء يتم تحديد الية إستخدام كل Class يقدمه ال Yii، في العادة يتم إستخدام هذا المرجع عند كتابة شيفرة برمجية وأنت ترغب في فهم آلية العمل ل Class معين، أو Method, او فهم Proporty معينة...الخ، من الأفضل إستخدام المرجع الخاص بال Class فقط عند فهم آلية العمل لل Yii. </li>
<li><a href="https://www.yiiframework.com/wiki/?tag=yii2">The Wiki Articles - مقالات الويكي</a> مقالات الويكي هي مجموعة من الخبرات العملية للمستخدمين، تمت كتابتها ونشرها على شكل مقالات لمشاركة الخبرات، ومعظم هذه الكتابات تكون مثل الوصفات الخاصة بالطبخ، موجودة لخدمة هدف معين، وحل مشكلة محددة باستخدام ال Yii، وبالرغم من أن هذه الكتابات قد لا تكون بجودة ودقة الدليل الشامل، الا أنها قد تغطي مواضيع أكثر، وتطرح أيضا حلولا مباشرة للإستخدام.</li>
<li><a href="https://www.yiiframework.com/doc/">الكتب</a></li>
</ul>
</li>
<li><a href="https://www.yiiframework.com/extensions/">Extensions - الملحقات</a>: تفتخر ال Yii بوجود مكتبة ضخمة من الملحقات التي تمت برمجتها وإضافتها من قبل المستخدمين المتطوعين الذين شاركوا أعمالهم وطورها لتجعل مهمة المطورين الآخرين أسهل وأسرع في تطوير التطبيفات المبنية بواسطة ال Yii.</li>
<li>
المجتمع
<ul>
<li>المنتدى: <a href="https://forum.yiiframework.com/">https://forum.yiiframework.com/</a></li>
<li>IRC chat: The #yii channel on the Libera (ircs://irc.libera.chat:6697/yii)</li>
<li>Slack chanel: <a href="https://yii.slack.com">https://yii.slack.com</a></li>
<li>Gitter chat: <a href="https://gitter.im/yiisoft/yii2">https://gitter.im/yiisoft/yii2</a></li>
<li>GitHub: <a href="https://github.com/yiisoft/yii2">https://github.com/yiisoft/yii2</a></li>
<li>Facebook: <a href="https://www.facebook.com/groups/yiitalk/">https://www.facebook.com/groups/yiitalk/</a></li>
<li>Twitter: <a href="https://twitter.com/yiiframework">https://twitter.com/yiiframework</a></li>
<li>LinkedIn: <a href="https://www.linkedin.com/groups/yii-framework-1483367">https://www.linkedin.com/groups/yii-framework-1483367</a></li>
<li>Stackoverflow: <a href="https://stackoverflow.com/questions/tagged/yii2">https://stackoverflow.com/questions/tagged/yii2</a></li>
</ul>
</li>
</ul>

25
docs/guide-ar/start-prerequisites.md

@ -1,25 +0,0 @@
# <div dir="rtl">ماذا يجب أن تعرف قبل البدء بال Yii</div>
<p dir="rtl">
منحنى التعلم الخاص بال Yii ليس حادًا مثل أطر PHP الأخرى، ولكن لا يزال هناك بعض الأشياء التي يجب أن تتعلمها قبل البدء بـال Yii.
</p>
## <div dir="rtl">PHP</div>
<p dir="rtl">
ال Yii هو إطار عمل PHP، لذا تأكد من قراءة وفهم المرجع الرسمي الخاص بلغة ال <a href="https://www.php.net/manual/en/langref.php">PHP</a>. عند البدء بتطوير المشاريع أو التطبيقات باستخدام ال Yii ، ستكتب التعليمات البرمجية بطريقة كائنية التوجه OOP، لذا تأكد من أنك على دراية بـمفاهيم ال <a href="https://www.php.net/manual/en/language.oop5.basic.php">OOP</a> وكذلك ال <a href="https://www.php.net/manual/en/language.namespaces.php">namespaces</a>.
</p>
## <div dir="rtl">البرمجة كائنية التوجه object oriented programming</div>
<p dir="rtl">
كمبرمج أو مطور يرغب بالعمل على ال Yii، يجب عليك أن تمتلك المعرفة الأساسية للبرمجة كائنية التوجه OOP. إذا لم تكن على دراية بها ، فيمكنك تعلم ذلك من خلال واحدة من هذه الدورات المنتشرة مثل هذه الدورة من <a href="https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762">tuts+</a>.<br />
ملاحظة: كلما زاد تعقيد التطبيق أو المشروع الذي تعمل عليه، كلما احتجت الى مستوى أعلى وإحترافي أكثر من مفاهيم ال OOP لحل وإدارة التعقديات التي ستترب على مثل هذه المشاريع.
</p>
## <div dir="rtl">Command line and composer</div>
<p dir="rtl">تستخدم ال Yii بشكل كبير de-facto standard PHP package manager، ال <a href="https://getcomposer.org/">Composer</a>، لذلك تأكد من قرائتك وفهمك لهذا الموضوع قبل أن تبدء. بالإضافة الى ذلك إذا لم تكن على دراية باستخدام سطر الأوامر (command line) ، فقد حان الوقت لبدء المحاولة. بمجرد تعلم الأساسيات ، لن ترغب في العمل بدون إستخدام سطر الأوامر.<br />
ال composer: ويترجم حرفيا الى كلمة "الملحن"، وهي عبارة عن أداة لإدارة المشاريع البرمجية والتي تسمح لك بتحديث وتنزيل المكتبات البرمجية المطلوبة للمشروع الخاص بك.
</p>

115
docs/guide-ar/start-workflow.md

@ -1,115 +0,0 @@
# <div dir="rtl">تشغيل التطبيقات</div>
<p dir="rtl">
بعد تثبيت ال Yii، سيكون لديك تطبيق Yii جاهز للعمل عليه ويمكن الوصول إليه عبر
الرابط التالي: <code>http://hostname/basic/web/index.php</code> أو <code>http://hostname/index.php</code> إعتمادا على الإعدادات
الخاصة بك (إعدادت ال web server). في هذا الجزء سنستعرض الوظائف ال built-in الموجودة في التطبيق الإفتراضي لإطار العمل Yii، وكيف يقوم بتنظيم الشيفرة البرمجية، وكيف يعالج (handling) هذا التطبيق الطلبات (requests) بشكل عام.
</p>
<blockquote class="info"><p dir="rtl">
معلومة: من أجل تبسيط الطرح، ومن خلال هذا البرنامج التعليمي " Getting Started - البداية من هنا"، من المفترض أنك قمت بتعيين <code>basic/web</code> ك <code>document root</code> لل Web server، وقد قمت أيضا بإعداد ال Url الذي يسمح لك بالوصول الى التطبيق المثبت من خلاله ليكون على الشكل التالي: <code>http://hostname/index.php</code> أو ما شابه ذلك.
اذا لم تقم بذلك، ولتلبية إحتياجاتك في هذا البرنامج التعليمي، يرجى ضبط ال Url كما هو موضح في هذه الصفحة.
يمكنك معرفة الضبط الخاص بال Web server من هنا: <a href="start-installation.md">تثبيت ال Yii </a>
</p></blockquote>
<p dir="rtl">
ملاحظة: بخلاف إطار العمل نفسه(Yii framework)، بعد تثبيت ال template الخاص بالمشروع، يكون كل شيء في هذا التطبيق يخصك أنت، بحيث تملك الحرية في إضافة أو حذف أو تعديل كل ما تحتاج اليه.
</p>
## <div dir="rtl">خصائص / وظائف التطبيق المثبت - Functionality</div> <span id="functionality"></span>
<p dir="rtl">
يحتوي ال Basic ِApplication Template الذي قمنا بتثبيته على أربع صفحات:
</p>
<ul dir="rtl">
<li>الصفحة الرئيسية(Homepage): يتم عرض هذه الصفحة من خلال الرابط التالي <code>http://hostname/index.php</code> </li>
<li>صفحة من نحن(About)</li>
<li>صفحة اتصل بنا (Contact): في هذه الصفحة يتم عرض form يسمح للأعشاء بالإتصال بك من خلال البريد الإلكتروني.</li>
<li>صفحة تسجيل الدخول (Login): في هذه الصفحة يتم عرض form يسمح للأعضاء بالحصول على الإذن لإستخدام الخصائص التي لا يجوز لغيرهم من الوصول اليها، قم بتجربة تسجيل الدخول من خلال استخدام <code>admin/admin</code> ولاحظ أن كلمة "Login" ستختفي من القائمة الرئيسية وستظهر محلها الكلمة "Logout"</li>
</ul>
<p dir="rtl">
هذه الصفحات تشترك بامتلاكها common header and footer -الترويسة أعلى الصفحة، والذيل أسفل الصفحة-. ويحتوي ال header على القائمة الرئيسية (main menu) والتي بدورها تسمح لك بالتنقل بين الصفحات المختلفة.
</p>
<p dir="rtl">
أيضا، يجب عليك أن تنظر الى ال toolbar الموجود في أسفل نافذة المتصفح. ال <a href="https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md">debugger tool</a> هذه تعتبر كأداة مفيدة مقدمة من ال Yii لتسجيل وعرض الكثير من المعلومات وتصحيح الأخطاء، مثل log messages, response statuses, the database queries run وما إلى ذلك.
</p>
<p dir="rtl">
بالإضافة إلى ال web application، يوجد هناك "console script" يسمى ب <code>yii</code>، والذي ستجده في المسار الرئيسي للتطبيق. هذا السكربت يمكن استخدامه لتشغيل المهام التي تعمل في الخفاء (background) أو لتنفيذ مهام الصيانة (ال maintenance). <br /> ستجد الوصف الخاص بهذا السكربت
داخل هذه الصفحة <a href="tutorial-console.md">Console Application Section</a>.
</p>
## <div dir="rtl">هيكلية التطبيق - Application Structure</a> <span id="application-structure"></span>
<p dir="rtl">
أكثر المسارات والملفات أهمية الموجودة داخل التطبيق (بافتراض أن ال application's root directory هو <code>basic</code>) هي:
</p>
```js
basic/ application base path
composer.json used by Composer, describes package information
config/ contains application and other configurations
console.php the console application configuration
web.php the Web application configuration
commands/ contains console command classes
controllers/ contains controller classes
models/ contains model classes
runtime/ contains files generated by Yii during runtime, such as logs and cache files
vendor/ contains the installed Composer packages, including the Yii framework itself
views/ contains view files
web/ application Web root, contains Web accessible files
assets/ contains published asset files (javascript and css) by Yii
index.php the entry (or bootstrap) script for the application
yii the Yii console command execution script
```
<p dir="rtl">
بشكل عام، يمكن تقسيم الملفات داخل التطبيق إلى نوعين: الاول تجده تحت المسار التالي: <code>basic/web</code والثاني تجده بالمسارات الأخرى.<br />
وبنائا على ذلك، فإنه من الممكن الوصول إلى النوع الأول مباشرة عبر ال HTTP (أي من خلال المتصفح) ، بينما لا يمكن أن يكون ذلك للنوع الثاني.
</p>
<p dir="rtl">
يعتمد ال Yii على إستخدام ال MVC، وال MVC هو أحد ال Architectural Pattern، وهي اختصار ل <a href="https://wikipedia.org/wiki/Model-view-controller">model-view-controller</a>،
هذا الأسلوب ينعكس في تنظيم المسارات الخاصة بالملفات كما في الشكل أعلاه. يحتوي المسار <code>models</code> على جميع الكلاس <a href="../guide/structure-models.md">(model classes)</a> ، ويحتوي مسار ال <code>views</code> على جميع الصفحات التي ستستخدم في العرض <a href="../guide/structure-controllers.md">(view scripts)</a>، ويحتوي مسار ال<code>controllers</code> على
جميع <a href="../guide/structure-views.md">(controller classes)</a>
</p>
<p dir="rtl">
يوضح المخطط التالي ال static structure للتطبيق.
</p>
![Static Structure of Application](../guide/images/application-structure.png)
<p dir="rtl">
يحتوي كل تطبيق على نص برمجي يستخدم للدخول الى التطبيق (كبوابة بعدها يظهر التطبيق للناظر)، ويسمى هذا الجزء بال entry script، وهو يمثل الصفحة <code>web/index.php</code>، ويعد هذا المدخل النص البرمجي الوحيد الذي يمكن الوصول إليه من خلال ال PHP في التطبيق، ويعمل هذا ال entry script على أخذ ال request ومن ثم إنشاء instance خاص بالتطبيق ليستطيع التعامل معه (التعامل مع التطبيق ومكوناته).
يقوم <a href="../guide/structure-applications.md">التطبيق</a> على معالجة ال request بمساعدة من ال <a href="../guide/concept-components.md">components</a>، ومن ثم بقوم التطبيق بإرسال ال request الى عناصر ال MVC، كما يتم استخدام ال <a href="../guide/structure-widgets.md">Widgets</a> في ال <a href="../guide/structure-views.md">views</a> للمساعدة في إنشاء العناصر المعقدة والمتغيرة (Complex & Dynamic user interface) لواجهة المستخدم.
</p>
## <div dir="rtl">دورة الحياة الخاصة بال request</a> <span id="request-lifecycle"></span>
<p dir="rtl">
يوضح المخطط التالي كيفية معالجة التطبيق ل request معين.
</p>
![Request Lifecycle](../guide/images/request-lifecycle.png)
<ol dir="rtl">
<li>يقوم المستخدم بعمل request لل <a href="../guide/structure-entry-scripts.md">entry script</a> <code>web/index.php</code>.</li>
<li>يقوم ال entry script على جلب <a href="../guide/concept-configurations.md">الإعدادات</a> الخاصة بالتطبيق ومن ثم إنشاء ال instance الخاص بالتطبيق ليستطيع التحكم ب request وإدارتها.</li>
<li>يقوم التطبيق بمعالجة ال <a href="../guide/runtime-routing.md">requested route</a> بمساعدة من ال <a href="../guide/runtime-requests.md">request</a> application component.</li>
<li>يقوم التطبيق على إنشاء instance من ال <a href="../guide/structure-controllers.md">controller</a> للتحكم بال request.</li>
<li>يقوم ال controller على إنشاء <a href="../guide/structure-controllers.md">action</a> instance مع مجموعة من الفلاتر(المرشحات) الخاصة بهذا ال action.</li>
<li>في حالة فشل أي فلتر، يتم إلغاء الإجراء.</li>
<li>في حال نجاح جميع الفلاتر ، يتم تنفيذ الإجراء.</li>
<li>يقوم ال action بجلب بعض البيانات الخاصة بال models, وفي الغالب ستكون من قاعدة البيانات إن أمكن ذلك.</li>
<li>سيقوم ال action بجلب ال view ليقوم بتقديم البيانات التي تم جلبها لل view.</li>
<li>عملية الجلب السابقة ستقوم على إرجاع النتائج الى <a href="../guide/runtime-responses.md">response</a> application component</li>
<li>بعد ذلك سيقوم ال response component بإرسال النتيجة النهائية الى المتصفح الخاص بالمستخدم. </li>
</ol>

2
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](https://www.yiiframework.com/doc/terms/) veröffentlicht.
Dieses Tutorial wurde unter den [Bedingungen der Yii-Dokumentation](http://www.yiiframework.com/doc/terms/) veröffentlicht.
Alle Rechte vorbehalten.

17
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](https://www.yiiframework.com/doc/terms/).
Este tutorial se publica bajo los [Términos de Documentación Yii](http://www.yiiframework.com/doc/terms/).
Todos los derechos reservados.
@ -18,7 +18,6 @@ Introducción
Primeros pasos
--------------
* [Qué necesita saber](start-prerequisites.md)
* [Instalar Yii](start-installation.md)
* [Funcionamiento de aplicaciones](start-workflow.md)
* [Hola a todos](start-hello.md)
@ -131,20 +130,6 @@ Caché
* [Caché HTTP](caching-http.md)
Servicios Web RESTful
---------------------
* [Guía breve](rest-quick-start.md)
* [Recursos (Resources)](rest-resources.md)
* [Controladores](rest-controllers.md)
* [Gestión de rutas](rest-routing.md)
* [Formateo de respuestas](rest-response-formatting.md)
* [Autenticación](rest-authentication.md)
* [Límite de Rango](rest-rate-limiting.md)
* [Gestión de versiones](rest-versioning.md)
* [Gestión de errores](rest-error-handling.md)
Herramientas de Desarrollo
--------------------------

18
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](https://memcached.org/) con dos servidores caché:
`cache` para usar [memcached](http://memcached.org/) con dos servidores caché:
```php
'components' => [
@ -72,15 +72,13 @@ 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://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\ApcCache]]: utiliza la extensión de PHP [APC](http://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\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://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é.
* [[yii\caching\MemCache]]: utiliza las extensiones de PHP [memcache](http://php.net/manual/es/book.memcache.php) y [memcached](http://php.net/manual/es/book.memcached.php). Esta opción puede ser considerada como la más rápida cuando la caché es manejada en una aplicación distribuida (ej. con varios servidores, con balance de carga, etc..)
* [[yii\redis\Cache]]: implementa un componente de caché basado en [Redis](http://redis.io/) que almacenan pares clave-valor (requiere la versión 2.6.12 de redis).
* [[yii\caching\WinCache]]: utiliza la extensión de PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension) ([ver también](http://php.net/manual/es/book.wincache.php)).
> 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).
@ -98,7 +96,7 @@ Todos los componentes de almacenamiento de caché provienen de la misma clase "p
* [[yii\caching\Cache::madd()|madd()]]: almacena múltiples elementos de datos en la memoria caché. Cada elemento se identifica con una clave. Si una clave ya existe en la caché, el elemento será omitido.
* [[yii\caching\Cache::exists()|exists()]]: devuelve un valor que indica si la clave especificada se encuentra en la memoria caché.
* [[yii\caching\Cache::delete()|delete()]]: elimina un elemento de datos identificado por una clave de la caché.
* [[yii\caching\Cache::flush()|flush()]]: elimina todos los elementos de datos de la cache.
* [[yii\caching\Cache::clear()|clear()]]: elimina todos los elementos de datos de la cache.
> Note: No Almacenes el valor boolean `false` en caché directamente porque el método [[yii\caching\Cache::get()|get()]] devuelve
el valor `false` para indicar que el dato no ha sido encontrado en la caché. Puedes poner `false` dentro de un array y cachear
@ -221,7 +219,7 @@ $result = Customer::getDb()->cache(function ($db) {
});
```
> 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.
> 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.
### Configuraciones <span id="query-caching-configs"></span>

4
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](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4),
> Note: En cumplimiento con [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4),
`HttpCache` enviará ambas cabeceras `ETag` y `Last-Modified` si ambas están configuradas. Y si el clientes envía tanto la cabecera `If-None-Match` como la cabecera `If-Modified-Since`, solo la primera será respetada.
## La Cabecera `Cache-Control` <span id="cache-control"></span>
@ -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://www.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()](http://www.php.net/manual/es/function.session-cache-limiter.php)
para una mejor explicación sobre esos valores.

4
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](https://bower.io/). Por defecto `@vendor/bower`.
- `@npm`, el directorio raíz que contiene [paquetes npm](https://www.npmjs.com/). Por defecto `@vendor/npm`.
- `@bower`, el directorio raíz que contiene [paquetes bower](http://bower.io/). Por defecto `@vendor/bower`.
- `@npm`, el directorio raíz que contiene [paquetes npm](https://www.npmjs.org/). Por defecto `@vendor/npm`.
El alias `@yii` se define cuando incluyes el archivo `Yii.php` en tu [script de entrada](structure-entry-scripts.md),
mientras que el resto de los alias están definidos en el constructor de la aplicación cuando se aplica la

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

@ -1,7 +1,7 @@
Autocarga de clases
===================
Yii depende del [mecanismo de autocarga de clases](https://www.php.net/manual/es/language.oop5.autoload.php) para localizar
Yii depende del [mecanismo de autocarga de clases](http://www.php.net/manual/es/language.oop5.autoload.php) para localizar
e incluir los archivos de las clases requiridas. Proporciona un cargador de clases de alto rendimiento que cumple con el
[estandard PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md).
El cargador se instala cuando incluyes el archivo `Yii.php`.

10
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](https://en.wikipedia.org/wiki/Mixin), te permiten mejorar la funcionalidad de un [[yii\base\Component|componente]]
[mixins](http://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
@ -151,7 +151,7 @@ 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::class);
@ -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::class, // un comportamiento anónimo
'myBehavior1' => new MyBehavior, // un comportamiento nombrado
MyBehavior::class, // un comportamiento anónimo
]);
```
@ -309,7 +309,7 @@ $user->touch('login_time');
Comparación con Traits <span id="comparison-with-traits"></span>
----------------------
Mientras que los comportamientos son similares a [traits](https://www.php.net/traits) en cuanto que ambos "inyectan" sus
Mientras que los comportamientos son similares a [traits](http://www.php.net/traits) en cuanto que ambos "inyectan" sus
métodos y propiedades a la clase primaria, son diferentes en muchos aspectos. Tal y como se describe abajo, los dos
tienen sus ventajas y desventajas. Son más como complementos el uno al otro en lugar de alternativas.

6
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](https://martinfowler.com/articles/injection.html) contiene una buena
objetos dependientes. El [articulo de Martin](http://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://www.php.net/manual/es/language.types.callable.php);
* Inyección de [llamadas de retorno PHP](http://php.net/manual/es/language.types.callable.php);
### Inyección de Constructores <span id="constructor-injection"></span>
@ -316,7 +316,7 @@ Resumen <span id="summary"></span>
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](https://martinfowler.com/articles/injection.html) para obtener una mejor
encarecida la lectura del articulo de [Martin](http://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.

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

@ -13,7 +13,7 @@ Gestor de Eventos <span id="event-handlers"></span>
-----------------
Un gestor de eventos es una
[llamada de retorno PHP (PHP callback)](https://www.php.net/manual/es/language.types.callable.php) que se ejecuta cuando se
[llamada de retorno PHP (PHP callback)](http://php.net/manual/es/language.types.callable.php) que se ejecuta cuando se
lanza el evento al que corresponde. Se puede usar cualquier llamada de retorno de las enumeradas a continuación:
- una función de PHP global especificada como una cadena de texto (sin paréntesis), ej. `'trim'`;

20
docs/guide-es/db-dao.md

@ -1,7 +1,7 @@
Objetos de Acceso a Bases de Datos
==================================
Construido sobre [PDO](https://www.php.net/manual/es/book.pdo.php), Yii DAO (Objetos de Acceso a Bases de Datos) proporciona una
Construido sobre [PDO](http://php.net/manual/es/book.pdo.php), Yii DAO (Objetos de Acceso a Bases de Datos) proporciona una
API orientada a objetos para el acceso a bases de datos relacionales. Es el fundamento para otros métodos de acceso a bases de datos
más avanzados, incluyendo el [constructor de consultas](db-query-builder.md) y [active record](db-active-record.md).
@ -11,12 +11,11 @@ Yii DAO también significa que tienes que tienes que tomar un esfuerzo adicional
Yii DAO soporta las siguientes bases de datos:
- [MySQL](https://www.mysql.com/)
- [MySQL](http://www.mysql.com/)
- [MariaDB](https://mariadb.com/)
- [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/)
- [SQLite](http://sqlite.org/)
- [PostgreSQL](http://www.postgresql.org/): versión 8.4 o superior.
- [Oracle](http://www.oracle.com/us/products/database/overview/index.html)
- [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): versión 2008 o superior.
## Creando Conexiones DB <span id="creating-db-connections"></span>
@ -60,12 +59,11 @@ 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://www.php.net/manual/es/function.PDO-construct.php) para más detalles. Abajo están algunos ejemplos:
[manual de PHP](http://www.php.net/manual/es/function.PDO-construct.php) para más detalles. Abajo están algunos ejemplos:
* MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase`
* SQLite: `sqlite:/path/to/database/file`
* PostgreSQL: `pgsql:host=localhost;port=5432;dbname=mydatabase`
* CUBRID: `cubrid:dbname=demodb;host=localhost;port=33000`
* MS SQL Server (mediante sqlsrv driver): `sqlsrv:Server=localhost;Database=mydatabase`
* MS SQL Server (mediante dblib driver): `dblib:host=localhost;dbname=mydatabase`
* MS SQL Server (mediante mssql driver): `mssql:host=localhost;dbname=mydatabase`
@ -185,7 +183,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://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php).
La vinculación parámetros es implementada mediante [sentencias preparadas (prepared statements)](http://php.net/manual/es/mysqli.quickstart.prepared-statements.php).
Además de prevenir ataques de inyección de SQL, también puede mejorar el rendimiento preparando una sola vez una sentencia SQL y ejecutándola múltiples veces con diferentes
parámetros. Por ejemplo,
@ -396,7 +394,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]: https://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels
[isolation levels]: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels
### Transacciones Anidadas <span id="nesting-transactions"></span>
@ -437,7 +435,7 @@ try {
## Replicación y División Lectura-Escritura <span id="read-write-splitting"></span>
Muchos DBMS soportan [replicación de bases de datos](https://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) para tener
Muchos DBMS soportan [replicación de bases de datos](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) para tener
una mejor disponibilidad de la base de datos y un mejor tiempo de respuesta del servidor. Con la replicación de bases
de datos, los datos están replicados en los llamados *servidores maestros* (master servers) y *servidores esclavos*
(slave servers). Todas las escrituras y actualizaciones deben hacerse en el servidor maestro, mientras que las lecturas

2
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](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). En estos casos,
por favor lee acerca de [commits implícitos](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). En estos casos,
deberías igualmente implementar `up()` y `down()`.

2
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`](https://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) en lugar de `like` para
[`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) en lugar de `like` para
filtrar resultados insensibles a mayúsculas (case-insensitive).
- `or like`: similar al operando `like` exceptuando que se usa `OR` para concatenar los predicados `LIKE` cuando haya

2
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://www.php.net/manual/es/language.namespaces.php) activamente utilizada en Yii 2.
Namespace (espacio de nombres) se refiere a una [característica de PHP](http://php.net/manual/es/language.namespaces.php) activamente utilizada en Yii 2.
# P

8
docs/guide-es/helper-array.md

@ -1,7 +1,7 @@
ArrayHelper
===========
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
Adicionalmente al [rico conjunto de funciones para arrays de PHP](http://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 <span id="checking-existence-of-keys"></span>
`ArrayHelper::keyExists` funciona de la misma manera que [array_key_exists](https://www.php.net/manual/es/function.array-key-exists.php)
`ArrayHelper::keyExists` funciona de la misma manera que [array_key_exists](http://php.net/manual/es/function.array-key-exists.php)
excepto que también soporta case-insensitive para la comparación de claves. Por ejemplo,
```php
@ -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://www.php.net/manual/es/function.sort.php).
PHP [sort()](http://php.net/manual/es/function.sort.php).
## Detectando Tipos de Array <span id="detecting-array-types"></span>
@ -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://www.php.net/manual/en/function.in-array.php).
[in_array()](http://php.net/manual/en/function.in-array.php).
```php
// true

8
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://www.php.net/manual/es/language.basic-syntax.phpmode.php) pero cuando se
[mezclando PHP y HTML en un mismo archivo](http://php.net/manual/es/language.basic-syntax.phpmode.php) pero cuando se
generan dinámicamente empieza a complicarse su gestión sin ayuda extra. Yii ofrece esta ayuda en forma de una clase auxiliar Html
que proporciona un conjunto de métodos estáticos para gestionar las etiquetas HTML más comúnmente usadas, sus opciones y contenidos.
@ -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](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes).
[atributos booleanos](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes).
- Los valores de los atributos se codificarán en HTML usando [[yii\helpers\Html::encode()|Html::encode()]].
- El atributo "data" puede recibir un array. En este caso, se "expandirá" y se renderizará una lista de atributos
`data` ej. `'data' => ['id' => 1, 'name' => 'yii']` se convierte en `data-id="1" data-name="yii"`.
@ -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://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
codificado. En PHP esto se hace con [htmlspecialchars](http://www.php.net/manual/es/function.htmlspecialchars.php) y
[htmlspecialchars_decode](http://www.php.net/manual/es/function.htmlspecialchars-decode.php). El problema con el uso
de estos métodos directamente es que se tiene que especificar la codificación y opciones extra cada vez. Ya que las
opciones siempre son las mismas y la codificación debe coincidir con la de la aplicación para prevenir problemas de
seguridad, Yii proporciona dos métodos simples y compactos:

14
docs/guide-es/input-file-upload.md

@ -1,7 +1,7 @@
Subir Archivos
==============
Subir archivos en Yii es normalmente realizado con la ayuda de [[yii\web\UploadedFile]], que encapsula cada archivo subido
Subir archivos en Yii es normalmente realizado con la ayuda de [[yii\http\UploadedFile]], que encapsula cada archivo subido
en un objeto `UploadedFile`. Combinado con [[yii\widgets\ActiveForm]] y [modelos](structure-models.md),
puedes fácilmente implementar un mecanismo seguro de subida de archivos.
@ -16,7 +16,7 @@ Por ejemplo,
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
use yii\http\UploadedFile;
class UploadForm extends Model
{
@ -90,7 +90,7 @@ namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
use yii\http\UploadedFile;
class SiteController extends Controller
{
@ -111,7 +111,7 @@ class SiteController extends Controller
}
```
En el código anterior, cuando se envía el formulario, el método [[yii\web\UploadedFile::getInstance()]] es llamado
En el código anterior, cuando se envía el formulario, el método [[yii\http\UploadedFile::getInstance()]] es llamado
para representar el archivo subido como una instancia de `UploadedFile`. Entonces dependemos de la validación del modelo
para asegurarnos que el archivo subido es válido y entonces subirlo al servidor.
@ -123,14 +123,14 @@ 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://www.php.net/manual/en/ini.core.php#ini.max-file-uploads),
por la directiva PHP [`max_file_uploads`](http://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
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
use yii\http\UploadedFile;
class UploadForm extends Model
{
@ -186,7 +186,7 @@ namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
use yii\http\UploadedFile;
class SiteController extends Controller
{

2
docs/guide-es/input-validation.md

@ -584,7 +584,7 @@ JS;
### Validación Diferida <span id="deferred-validation"></span>
Si necesitas realizar validación del lado del cliente asincrónica, puedes crear [Objetos Diferidos](https://api.jquery.com/category/deferred-object/).
Si necesitas realizar validación del lado del cliente asincrónica, puedes crear [Objetos Diferidos](http://api.jquery.com/category/deferred-object/).
Por ejemplo, para realizar validación AJAX personalizada, puedes utilizar el siguiente código:
```php

16
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://www.php.net/manual/es/language.namespaces.php).
- [Funciones anónimas](https://www.php.net/manual/es/functions.anonymous.php).
- [Namespaces](http://php.net/manual/es/language.namespaces.php).
- [Funciones anónimas](http://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 `<?=`. Esto se puede utilizar desde PHP 5.4.
- [SPL - Biblioteca estándar de PHP](https://www.php.net/manual/es/book.spl.php).
- [Enlace estático en tiempo de ejecución](https://www.php.net/manual/es/language.oop5.late-static-bindings.php).
- [Fecha y Hora](https://www.php.net/manual/es/book.datetime.php).
- [Traits](https://www.php.net/manual/es/language.oop5.traits.php).
- [intl](https://www.php.net/manual/es/book.intl.php). Yii 2.0 utiliza la extensión `intl` de PHP
- [SPL - Biblioteca estándar de PHP](http://php.net/manual/es/book.spl.php).
- [Enlace estático en tiempo de ejecución](http://php.net/manual/es/language.oop5.late-static-bindings.php).
- [Fecha y Hora](http://php.net/manual/es/book.datetime.php).
- [Traits](http://php.net/manual/es/language.oop5.traits.php).
- [intl](http://php.net/manual/es/book.intl.php). Yii 2.0 utiliza la extensión `intl` de PHP
como soporte para internacionalización.
@ -291,7 +291,7 @@ Por favor consulta la sección [Comandos de Consola](tutorial-console.md) para m
I18N
----
Yii 2.0 remueve el formateador de fecha y números previamente incluido en favor del [módulo de PHP PECL intl](https://pecl.php.net/package/intl).
Yii 2.0 remueve el formateador de fecha y números previamente incluido en favor del [módulo de PHP PECL intl](http://pecl.php.net/package/intl).
La traducción de mensajes ahora es ejecutada vía el componente `i18n` de la aplicación.
Este componente maneja un grupo de mensajes origen, lo que te permite utilizar diferentes mensajes

44
docs/guide-es/intro-yii.md

@ -2,8 +2,8 @@
============
Yii es un framework de PHP de alto rendimiento, basado en componentes para desarrollar aplicaciones web
modernas en poco tiempo. El nombre Yii significa "simple y evolutivo" en chino. También se puede considerar como el acrónimo
de _**Yes It Is**_ (que en inglés significa _**Sí, lo es**_)!
modernas en poco tiempo. El nombre Yii significa "simple y evolutivo" en chino. También se puede considerar como un acrónimo
de _**Yes It Is**_ (que en inglés significa _**Sí, eso es**_)!
¿En qué es mejor Yii?
@ -11,33 +11,25 @@ de _**Yes It Is**_ (que en inglés significa _**Sí, lo es**_)!
Yii es un framework genérico de programación web, lo que significa que se puede utilizar para desarrollar todo tipo de aplicaciones web en PHP.
Debido a su arquitectura basada en componentes y a su sofisticada compatibilidad de caché, es especialmente apropiado para el desarrollo
de aplicaciones de gran envergadura, como páginas web, foros, sistemas de gestión de contenidos (CMS), proyectos de comercio electrónico,
servicios web compatibles con la arquitectura REST y muchos más.
de aplicaciones de gran envergadura, como portales, foros, sistemas de gestión de contenidos (CMS), proyectos de comercio electrónico,
servicios web compatibles con la arquitectura REST y muchas más.
¿Cómo se compara Yii con otros frameworks?
--------------------------------------
Si estás ya familiarizado con otros framework, puedes apreciar como se compara Yii con ellos:
- Como la mayoría de los framework de PHP, Yii implementa el patrón de diseño MVC (Modelo-Vista-Controlador) y
promueve la organización de código basada en este patrón.
- La filosofía de Yii consiste en escribir el código de manera simple y elegante, sin sobrediseñar nunca por el
mero hecho de seguir un patrón de diseño determinado.
- Yii es un framework completo (full stack) que provee muchas características probadas y listas para usar, como los
constructores de consultas y la clase ActiveRecord para las bases de datos relacionales y NoSQL,
la compatibilidad con la arquitectura REST para desarrollar API, la compatibilidad de caché en varios niveles
y muchas más.
- Yii es extremadamente extensible. Puedes personalizar o reemplazar prácticamente cualquier pieza de código de base,
como se puede también aprovechar su sólida arquitectura de extensiones para utilizar o desarrollar extensiones distribuibles.
Si estás familiarizado con otros framework, puedes apreciar como se compara Yii con ellos:
- Como la mayoría de los framework de PHP, Yii implementa el patrón de diseño MVC (Modelo-Vista-Controlador) y promueve la organización de código basada en este patrón.
- La filosofía de Yii consiste en escribir el código de manera simple y elegante, sin sobrediseñar nunca por el mero hecho de seguir un patrón de diseño determinado.
- Yii es un framework completo que provee muchas características probadas y listas para usar, como los constructores de consultas y la clase ActiveRecord para las bases de datos relacionales y NoSQL, la compatibilidad con la arquitectura REST para desarrollar API, la compatibilidad de caché en varios niveles y muchas más.
- Yii es extremadamente extensible. Puedes personalizar o reemplazar prácticamente cualquier pieza de código de base, como se puede también aprovechar su sólida arquitectura de extensiones para utilizar o desarrollar extensiones distribuibles.
- El alto rendimiento es siempre la meta principal de Yii.
Yii no es un proyecto de un sola persona, detrás de Yii hay un [sólido equipo de desarrollo](https://www.yiiframework.com/team/),
así como una gran comunidad en la que numerosos profesionales contribuyen constantemente a su desarrollo.
Yii no es un proyecto de un sola persona, detrás de Yii hay un [sólido equipo de desarrollo][about_yii], así como una gran comunidad en la que numerosos profesionales contribuyen constantemente a su desarrollo.
El equipo de desarrollo de Yii se mantiene atento a las últimas tendencias de desarrollo web, así como a las mejores prácticas y características de otros frameworks y proyectos.
Las buenas prácticas y características más relevantes de otros proyectos se incorporan regularmente a la base del framework y se exponen a través de interfaces simples y elegantes.
[about_yii]: https://www.yiiframework.com/about/
[about_yii]: http://www.yiiframework.com/about/
Versiones de Yii
----------------
@ -48,13 +40,13 @@ La versión 2.0 representa la actual generación del framework y su desarrollo r
Esta guía está basada principalmente en la versión 2.0. del framework.
Requisitos y Prerequisitos
--------------------------
Requisitos
-----------
Yii 2.0 requiere PHP 5.4.0 o una versión posterior y corre de mejor manera en la última versión de PHP 7. Se pueden encontrar requisitos más detallados de características individuales
ejecutando el script de comprobación incluido en cada lanzamiento de Yii.
Yii 2.0 requiere PHP 5.4.0 o una versión posterior. Se pueden encontrar requisitos más detallados de características individuales
ejecutando el script de comprobación incluido en cada release de Yii.
Para utilizar Yii se requieren conocimientos básicos de programación orientada a objetos (POO), porque el framework Yii se basa íntegramente en esta tecnología.
Yii 2.0 hace uso también de las últimas características de PHP, como [namespaces](https://www.php.net/manual/es/language.namespaces.php)
y [traits](https://www.php.net/manual/es/language.oop5.traits.php). Comprender estos conceptos te ayudará a entender mejor Yii 2.0.
Yii 2.0 hace uso también de las últimas características de PHP, como [namespaces](http://www.php.net/manual/es/language.namespaces.php)
y [traits](http://www.php.net/manual/es/language.oop5.traits.php). Comprender estos conceptos te ayudará a entender mejor Yii 2.0.

421
docs/guide-es/output-data-providers.md

@ -1,421 +0,0 @@
Proveedores de datos
====================
En las secciones sobre [paginación](output-pagination.md) y [ordenación](output-sorting.md) se
describe como permitir a los usuarios finales elegir que se muestre una página de datos en
particular, y ordenar los datos por algunas columnas. Como la tarea de paginar y ordenar datos
es muy común, Yii proporciona un conjunto de clases *proveedoras de datos* para encapsularla.
Un proveedor de datos es una clase que implementa la interfaz [[yii\data\DataProviderInterface]].
Básicamente se encarga de obtener datos paginados y ordenados. Normalmente se usa junto con
[_widgets_ de datos](output-data-widgets.md) para que los usuarios finales puedan paginar y
ordenar datos de forma interactiva.
Yii incluye las siguientes clases proveedoras de datos:
* [[yii\data\ActiveDataProvider]]: usa [[yii\db\Query]] o [[yii\db\ActiveQuery]] para consultar datos de bases de datos y devolverlos como _arrays_ o instancias [Active Record](db-active-record.md).
* [[yii\data\SqlDataProvider]]: ejecuta una sentencia SQL y devuelve los datos de la base de datos como _arrays_.
* [[yii\data\ArrayDataProvider]]: toma un _array_ grande y devuelve una rodaja de él basándose en las especificaciones de paginación y ordenación.
El uso de todos estos proveedores de datos comparte el siguiente patrón común:
```php
// Crear el proveedor de datos configurando sus propiedades de paginación y ordenación
$provider = new XyzDataProvider([
'pagination' => [...],
'sort' => [...],
]);
// Obtener los datos paginados y ordenados
$models = $provider->getModels();
// Obtener el número de elementos de la página actual
$count = $provider->getCount();
// Obtener el número total de elementos entre todas las páginas
$totalCount = $provider->getTotalCount();
```
Se puede especificar los comportamientos de paginación y ordenación de un proveedor de datos
configurando sus propiedades [[yii\data\BaseDataProvider::pagination|pagination]] y
[[yii\data\BaseDataProvider::sort|sort]], que corresponden a las configuraciones para
[[yii\data\Pagination]] y [[yii\data\Sort]] respectivamente. También se pueden configurar a
`false` para inhabilitar las funciones de paginación y/u ordenación.
Los [_widgets_ de datos](output-data-widgets.md), como [[yii\grid\GridView]], tienen una
propiedad llamada `dataProvider` que puede tomar una instancia de un proveedor de datos y
mostrar los datos que proporciona. Por ejemplo,
```php
echo yii\grid\GridView::widget([
'dataProvider' => $dataProvider,
]);
```
Estos proveedores de datos varían principalmente en la manera en que se especifica la fuente de
datos. En las siguientes secciones se explica el uso detallado de cada uno de estos proveedores
de datos.
## Proveedor de datos activo <span id="active-data-provider"></span>
Para usar [[yii\data\ActiveDataProvider]], hay que configurar su propiedad
[[yii\data\ActiveDataProvider::query|query]].
Puede tomar un objeto [[yii\db\Query] o [[yii\db\ActiveQuery]]. En el primer caso, los datos
devueltos serán _arrays_. En el segundo, los datos devueltos pueden ser _arrays_ o instancias de
[Active Record](db-active-record.md). Por ejemplo:
```php
use yii\data\ActiveDataProvider;
$query = Post::find()->where(['state_id' => 1]);
$provider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'defaultOrder' => [
'created_at' => SORT_DESC,
'title' => SORT_ASC,
]
],
]);
// Devuelve un array de objetos Post
$posts = $provider->getModels();
```
En el ejemplo anterior, si `$query` se crea el siguiente código, el proveedor de datos
devolverá _arrays_ en bruto.
```php
use yii\db\Query;
$query = (new Query())->from('post')->where(['state' => 1]);
```
> Note: Si una consulta ya tiene la cláusula `orderBy`, las nuevas instrucciones de ordenación
dadas por los usuarios finales (mediante la configuración de `sort`) se añadirán a la cláusula
`orderBy` previa. Las cláusulas `limit` y `offset` que pueda haber se sobrescribirán por la
petición de paginación de los usuarios finales (mediante la configuración de `pagination`).
Por omisión, [[yii\data\ActiveDataProvider]] usa el componente `db` de la aplicación como
conexión con la base de datos. Se puede indicar una conexión con base de datos diferente
configurando la propiedad [[yii\data\ActiveDataProvider::db]].
## Proveedor de datos SQL <span id="sql-data-provider"></span>
[[yii\data\SqlDataProvider]] funciona con una sentencia SQL en bruto, que se usa para obtener
los datos requeridos.
Basándose en las especificaciones de [[yii\data\SqlDataProvider::sort|sort]] y
[[yii\data\SqlDataProvider::pagination|pagination]], el proveedor ajustará las cláusulas
`ORDER BY` y `LIMIT` de la sentencia SQL acordemente para obtener sólo la página de datos
solicitados en el orden deseado.
Para usar [[yii\data\SqlDataProvider]], hay que especificar las propiedades
[[yii\data\SqlDataProvider::sql|sql]] y [[yii\data\SqlDataProvider::totalCount|totalCount]].
Por ejemplo:
```php
use yii\data\SqlDataProvider;
$count = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM post WHERE status=:status
', [':status' => 1])->queryScalar();
$provider = new SqlDataProvider([
'sql' => 'SELECT * FROM post WHERE status=:status',
'params' => [':status' => 1],
'totalCount' => $count,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'attributes' => [
'title',
'view_count',
'created_at',
],
],
]);
// Devuelve un array de filas de datos
$models = $provider->getModels();
```
> Info: La propiedad [[yii\data\SqlDataProvider::totalCount|totalCount]] se requiere sólo si se
necesita paginar los datos. Esto es porque el proveedor modificará la sentencia SQL
especificada vía [[yii\data\SqlDataProvider::sql|sql]] para que devuelva sólo la pagina de
datos solicitada. El proveedor sigue necesitando saber el número total de elementos de datos
para calcular correctamente el número de páginas.
## Proveedor de datos de _arrays_ <span id="array-data-provider"></span>
Se recomienda usar [[yii\data\ArrayDataProvider]] cuando se trabaja con un _array_ grande.
El proveedor permite devolver una página de los datos del _array_ ordenados por una o varias
columnas. Para usar [[yii\data\ArrayDataProvider]], hay que especificar la propiedad
[[yii\data\ArrayDataProvider::allModels|allModels]] como el _array_ grande. Los elementos
del _array_ grande pueden ser _arrays_ asociativos (por ejemplo resultados de consultas de
[DAO](db-dao.md) u objetos (por ejemplo instancias de [Active Record](db-active-record.md).
Por ejemplo:
```php
use yii\data\ArrayDataProvider;
$data = [
['id' => 1, 'name' => 'name 1', ...],
['id' => 2, 'name' => 'name 2', ...],
...
['id' => 100, 'name' => 'name 100', ...],
];
$provider = new ArrayDataProvider([
'allModels' => $data,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'attributes' => ['id', 'name'],
],
]);
// Obtener las filas de la página solicitada
$rows = $provider->getModels();
```
> Note: En comparación con [Active Data Provider](#active-data-provider) y
[SQL Data Provider](#sql-data-provider), Array Data Provider es menos eficiente porque
requiere cargar *todos* los datos en memoria.
## Trabajar con las claves de los datos <span id="working-with-keys"></span>
Al utilizar los elementos de datos devueltos por un proveedor de datos, con frecuencia
necesita identificar cada elemento de datos con una clave única.
Por ejemplo, si los elementos de datos representan información de los clientes, puede querer
usar el ID de cliente como la clave de cada conjunto de datos de un cliente.
Los proveedores de datos pueden devolver una lista de estas claves correspondientes a los
elementos de datos devueltos por [[yii\data\DataProviderInterface::getModels()]].
Por ejemplo:
```php
use yii\data\ActiveDataProvider;
$query = Post::find()->where(['status' => 1]);
$provider = new ActiveDataProvider([
'query' => $query,
]);
// Devuelve un array de objetos Post
$posts = $provider->getModels();
// Devuelve los valores de las claves primarias correspondientes a $posts
$ids = $provider->getKeys();
```
En el ejemplo superior, como se le proporciona a [[yii\data\ActiveDataProvider]] un objeto
[[yii\db\ActiveQuery]], es lo suficientemente inteligente como para devolver los valores de
las claves primarias como las claves. También puede indicar explícitamente cómo se deben
calcular los valores de la clave configurando [[yii\data\ActiveDataProvider::key]] con un
nombre de columna o un invocable que calcule los valores de la clave. Por ejemplo:
```php
// Utiliza la columna «slug» como valores de la clave
$provider = new ActiveDataProvider([
'query' => Post::find(),
'key' => 'slug',
]);
// Utiliza el resultado de md5(id) como valores de la clave
$provider = new ActiveDataProvider([
'query' => Post::find(),
'key' => function ($model) {
return md5($model->id);
}
]);
```
## Creación de un proveedor de datos personalizado <span id="custom-data-provider"></span>
Para crear su propio proveedor de datos personalizado, debe implementar
[[yii\data\DataProviderInterface]].
Una manera más fácil es extender [[yii\data\BaseDataProvider]], que le permite centrarse
en la lógica central del proveedor de datos. En particular, esencialmente necesita
implementar los siguientes métodos:
- [[yii\data\BaseDataProvider::prepareModels()|prepareModels()]]: prepara los modelos
de datos que estarán disponibles en la página actual y los devuelve como un _array_.
- [[yii\data\BaseDataProvider::prepareKeys()|prepareKeys()]]: acepta un _array_ de
modelos de datos disponibles actualmente y devuelve las claves asociadas a ellos.
- [[yii\data\BaseDataProvider::prepareTotalCount()|prepareTotalCount]]: devuelve un valor
que indica el número total de modelos de datos en el proveedor de datos.
Debajo se muestra un ejemplo de un proveedor de datos que lee datos CSV eficientemente:
```php
<?php
use yii\data\BaseDataProvider;
class CsvDataProvider extends BaseDataProvider
{
/**
* @var string nombre del fichero CSV a leer
*/
public $filename;
/**
* @var string|callable nombre de la columna clave o un invocable que la devuelva
*/
public $key;
/**
* @var SplFileObject
*/
protected $fileObject; // SplFileObject es muy práctico para buscar una línea concreta en un fichero
/**
* {@inheritdoc}
*/
public function init()
{
parent::init();
// Abrir el fichero
$this->fileObject = new SplFileObject($this->filename);
}
/**
* {@inheritdoc}
*/
protected function prepareModels()
{
$models = [];
$pagination = $this->getPagination();
if ($pagination === false) {
// En caso de que no haya paginación, leer todas las líneas
while (!$this->fileObject->eof()) {
$models[] = $this->fileObject->fgetcsv();
$this->fileObject->next();
}
} else {
// En caso de que haya paginación, leer sólo una única página
$pagination->totalCount = $this->getTotalCount();
$this->fileObject->seek($pagination->getOffset());
$limit = $pagination->getLimit();
for ($count = 0; $count < $limit; ++$count) {
$models[] = $this->fileObject->fgetcsv();
$this->fileObject->next();
}
}
return $models;
}
/**
* {@inheritdoc}
*/
protected function prepareKeys($models)
{
if ($this->key !== null) {
$keys = [];
foreach ($models as $model) {
if (is_string($this->key)) {
$keys[] = $model[$this->key];
} else {
$keys[] = call_user_func($this->key, $model);
}
}
return $keys;
}
return array_keys($models);
}
/**
* {@inheritdoc}
*/
protected function prepareTotalCount()
{
$count = 0;
while (!$this->fileObject->eof()) {
$this->fileObject->next();
++$count;
}
return $count;
}
}
```
## Filtrar proveedores de datos usando filtros de datos <span id="filtering-data-providers-using-data-filters"></span>
Si bien puede construir condiciones para un proveedor de datos activo manualmente tal
y como se describe en las secciones [Filtering Data](output-data-widgets.md#filtering-data)
y [Separate Filter Form](output-data-widgets.md#separate-filter-form) de la guía de
_widgets_ de datos, Yii tiene filtros de datos que son muy útiles si necesita
condiciones de filtro flexibles. Los filtros de datos se pueden usar así:
```php
$filter = new ActiveDataFilter([
'searchModel' => 'app\models\PostSearch'
]);
$filterCondition = null;
// Puede cargar los filtros de datos de cualquier fuente.
// Por ejemplo, si prefiere JSON en el cuerpo de la petición,
// use Yii::$app->request->getBodyParams() aquí abajo:
if ($filter->load(\Yii::$app->request->get())) {
$filterCondition = $filter->build();
if ($filterCondition === false) {
// Serializer recibiría errores
return $filter;
}
}
$query = Post::find();
if ($filterCondition !== null) {
$query->andWhere($filterCondition);
}
return new ActiveDataProvider([
'query' => $query,
]);
```
El propósito del modelo `PostSearch` es definir por qué propiedades y valores se permite filtrar:
```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],
];
}
}
```
Los filtros de datos son bastante flexibles. Puede personalizar cómo se construyen
las condiciones y qué operadores se permiten.
Para más detalles consulte la documentación de la API en [[\yii\data\DataFilter]].

245
docs/guide-es/output-data-widgets.md

@ -1,245 +0,0 @@
Widgets de datos
================
Yii proporciona un conjunto de [widgets](structure-widgets.md) que se pueden usar para mostrar datos.
Mientras que el _widget_ [DetailView](#detail-view) se puede usar para mostrar los datos de un único
registro, [ListView](#list-view) y [GridView](#grid-view) se pueden usar para mostrar una lista o
tabla de registros de datos proporcionando funcionalidades como paginación, ordenación y filtro.
DetailView <span id="detail-view"></span>
----------
El _widget_ [[yii\widgets\DetailView|DetailView]] muestra los detalles de un único
[[yii\widgets\DetailView::$model|modelo]] de datos.
Se recomienda su uso para mostrar un modelo en un formato estándar (por ejemplo, cada atributo del
modelo se muestra como una fila en una tabla). El modelo puede ser tanto una instancia o subclase
de [[\yii\base\Model]] como un [active record](db-active-record.md) o un _array_ asociativo.
DetailView usa la propiedad [[yii\widgets\DetailView::$attributes|$attributes]] para determinar
qué atributos del modelo se deben mostrar y cómo se deben formatear.
En la [sección sobre formateadores](output-formatting.html) se pueden ver las opciones de formato
disponibles.
Un uso típico de DetailView sería así:
```php
echo DetailView::widget([
'model' => $model,
'attributes' => [
'title', // atributo title (en texto plano)
'description:html', // atributo description formateado como HTML
[ // nombre del propietario del modelo
'label' => 'Owner',
'value' => $model->owner->name,
'contentOptions' => ['class' => 'bg-red'], // atributos HTML para personalizar el valor
'captionOptions' => ['tooltip' => 'Tooltip'], // atributos HTML para personalizar la etiqueta
],
'created_at:datetime', // fecha de creación formateada como datetime
],
]);
```
Recuerde que a diferencia de [[yii\widgets\GridView|GridView]], que procesa un conjunto de modelos,
[[yii\widgets\DetailView|DetailView]] sólo procesa uno. Así que la mayoría de las veces no hay
necesidad de usar funciones anónimas ya que `$model` es el único modelo a mostrar y está disponible
en la vista como una variable.
Sin embargo, en algunos casos el uso de una función anónima puede ser útil. Por ejemplo cuando
`visible` está especificado y se desea impedir el cálculo de `value` en case de que evalúe a `false`:
```php
echo DetailView::widget([
'model' => $model,
'attributes' => [
[
'attribute' => 'owner',
'value' => function ($model) {
return $model->owner->name;
},
'visible' => \Yii::$app->user->can('posts.owner.view'),
],
],
]);
```
ListView <span id="list-view"></span>
--------
El _widget_ [[yii\widgets\ListView|ListView]] se usa para mostrar datos de un
[proveedor de datos](output-data-providers.md).
Cada modelo de datos se representa usando el [[yii\widgets\ListView::$itemView|fichero de vista]]
indicado.
Como proporciona de serie funcionalidades tales como paginación, ordenación y filtro,
es útil tanto para mostrar información al usuario final como para crear una interfaz
de usuario de gestión de datos.
Un uso típico es el siguiente:
```php
use yii\widgets\ListView;
use yii\data\ActiveDataProvider;
$dataProvider = new ActiveDataProvider([
'query' => Post::find(),
'pagination' => [
'pageSize' => 20,
],
]);
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_post',
]);
```
El fichero de vista `_post` podría contener lo siguiente:
```php
<?php
use yii\helpers\Html;
use yii\helpers\HtmlPurifier;
?>
<div class="tarea">
<h2><?= Html::encode($model->title) ?></h2>
<?= HtmlPurifier::process($model->text) ?>
</div>
```
En el fichero de vista anterior, el modelo de datos actual está disponible como `$model`.
Además están disponibles las siguientes variables:
- `$key`: mixto, el valor de la clave asociada a este elemento de datos.
- `$index`: entero, el índice empezando por cero del elemento de datos en el array de elementos devuelto por el proveedor de datos.
- `$widget`: ListView, esta instancia del _widget_.
Si se necesita pasar datos adicionales a cada vista, se puede usar la propiedad
[[yii\widgets\ListView::$viewParams|$viewParams]] para pasar parejas clave-valor como las siguientes:
```php
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_post',
'viewParams' => [
'fullView' => true,
'context' => 'main-page',
// ...
],
]);
```
Entonces éstas también estarán disponibles en la vista como variables.
GridView <span id="grid-view"></span>
--------
La cuadrícula de datos o [[yii\grid\GridView|GridView]] es uno de los _widgets_ de Yii
más potentes. Es extremadamente útil si necesita construir rápidamente la sección de
administración del sistema. Recibe los datos de un [proveedor de datos](output-data-providers.md)
y representa cada fila usando un conjunto de [[yii\grid\GridView::columns|columnas]]
que presentan los datos en forma de tabla.
Cada fila de la tabla representa los datos de un único elemento de datos, y una columna
normalmente representa un atributo del elemento (algunas columnas pueden corresponder a
expresiones complejas de los atributos o a un texto estático).
El mínimo código necesario para usar GridView es como sigue:
```php
use yii\grid\GridView;
use yii\data\ActiveDataProvider;
$dataProvider = new ActiveDataProvider([
'query' => Post::find(),
'pagination' => [
'pageSize' => 20,
],
]);
echo GridView::widget([
'dataProvider' => $dataProvider,
]);
```
El código anterior primero crea un proveedor de datos y a continuación usa GridView
para mostrar cada atributo en cada fila tomados del proveedor de datos. La tabla
mostrada está equipada de serie con las funcionalidades de ordenación y paginación.
### Columnas de la cuadrícula <span id="grid-columns"></span>
Las columnas de la tabla se configuran en términos de clase [[yii\grid\Column]], que
se configuran en la propiedad [[yii\grid\GridView::columns|columns]] de la configuración
del GridView.
Dependiendo del tipo y ajustes de las columnas éstas pueden presentar los datos de
diferentes maneras.
La clase predefinida es [[yii\grid\DataColumn]], que representa un atributo del modelo
por el que se puede ordenar y filtrar.
```php
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
// Columnas sencillas definidas por los datos contenidos en $dataProvider.
// Se usarán los datos de la columna del modelo.
'id',
'username',
// Un ejemplo más complejo.
[
'class' => 'yii\grid\DataColumn', // Se puede omitir, ya que es la predefinida.
'value' => function ($data) {
return $data->name; // $data['name'] para datos de un array, por ejemplo al usar SqlDataProvider.
},
],
],
]);
```
Observe que si no se especifica la parte [[yii\grid\GridView::columns|columns]] de la
configuración, Yii intenta mostrar todas las columnas posibles del modelo del proveedor
de datos.
### Clases de columna <span id="column-classes"></span>
Las columnas de la cuadrícula se pueden personalizar usando diferentes clases de columna:
```php
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
[
'class' => 'yii\grid\SerialColumn', // <-- aquí
// puede configurar propiedades adicionales aquí
],
```
Además de las clases de columna proporcionadas por Yii que se revisarán más abajo,
puede crear sus propias clases de columna.
Cada clase de columna extiende [[yii\grid\Column]] de modo que hay algunas opciones
comunes que puede establecer al configurar las columnas de una cuadrícula.
- [[yii\grid\Column::header|header]] permite establecer el contenida para la fila cabecera
- [[yii\grid\Column::footer|footer]] permite establece el contenido de la fila al pie
- [[yii\grid\Column::visible|visible]] define si la columna debería ser visible.
- [[yii\grid\Column::content|content]] le permite pasar una función PHP válida que devuelva datos para una fila. El formato es el siguiente:
```php
function ($model, $key, $index, $column) {
return 'una cadena';
}
```
Puede indicar varias opciones HTML del contenedor pasando _arrays_ a:
- [[yii\grid\Column::headerOptions|headerOptions]]
- [[yii\grid\Column::footerOptions|footerOptions]]
- [[yii\grid\Column::filterOptions|filterOptions]]
- [[yii\grid\Column::contentOptions|contentOptions]]

127
docs/guide-es/rest-authentication.md

@ -1,127 +0,0 @@
Autenticación
=============
A diferencia de las aplicaciones Web, las API RESTful son usualmente sin estado (stateless), lo que permite que las sesiones o las cookies
no sean usadas. Por lo tanto, cada petición debe llevar alguna suerte de credenciales de autenticación,
porque la autenticación del usuario no puede ser mantenida por las sesiones o las cookies. Una práctica común
es enviar una pieza (token) secreta de acceso con cada petición para autenticar al usuario. Dado que una pieza de autenticación
puede ser usada para identificar y autenticar solamente a un usuario, **la API de peticiones tiene que ser siempre enviado
vía HTTPS para prevenir ataques tipo "man-in-the-middle" (MitM) **.
Hay muchas maneras de enviar una token (pieza) de acceso:
* [Autenticación Básica HTTP](https://es.wikipedia.org/wiki/Autenticaci%C3%B3n_de_acceso_b%C3%A1sica): la pieza de acceso
es enviada como nombre de usuario. Esto sólo debe de ser usado cuando la pieza de acceso puede ser guardada
de forma segura en la parte del API del consumidor. Por ejemplo, el API del consumidor es un programa ejecutándose en un servidor.
* Parámetro de la consulta: la pieza de acceso es enviada como un parámetro de la consulta en la URL de la API, p.e.,
`https://example.com/users?access-token=xxxxxxxx`. Debido que muchos servidores dejan los parámetros de consulta en los logs del servidor,
esta aproximación suele ser usada principalmente para servir peticiones `JSONP`
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](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.
Para activar la autenticación para tus APIs, sigue los pasos siguientes:
1. Configura el componente `user` de la aplicación:
- Define la propiedad [[yii\web\User::enableSession|enableSession]] como `false`.
- Define la propiedad [[yii\web\User::loginUrl|loginUrl]] como `null` para mostrar un error HTTP 403 en vez de redireccionar a la pantalla de login.
2. Especifica cuál método de autenticación planeas usar configurando el comportamiento (behavior) `authenticator` en tus
clases de controladores REST.
3. Implementa [[yii\web\IdentityInterface::findIdentityByAccessToken()]] en tu [[yii\web\User::identityClass|clase de identidad de usuarios]].
El paso 1 no es necesario pero sí recomendable para las APIs RESTful, pues son sin estado (stateless).
Cuando [[yii\web\User::enableSession|enableSession]] es `false`, el estado de autenticación del usuario puede NO persistir entre peticiones usando sesiones.
Si embargo, la autenticación será realizada para cada petición, lo que se consigue en los pasos 2 y 3.
> Tip:Puedes configurar [[yii\web\User::enableSession|enableSession]] del componente de la aplicación `user` en la configuración
> de las aplicaciones si estás desarrollando APIs RESTful en términos de un aplicación. Si desarrollas un módulo de las APIs RESTful,
> puedes poner la siguiente línea en el método del módulo `init()`, tal y como sigue:
>
> ```php
> public function init()
> {
> parent::init();
> \Yii::$app->user->enableSession = false;
> }
> ```
Por ejemplo, para usar HTTP Basic Auth, puedes configurar el comportamiento (behavior) `authenticator` como sigue,
```php
use yii\filters\auth\HttpBasicAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::class,
];
return $behaviors;
}
```
Si quieres implementar los tres métodos de autenticación explicados antes, puedes usar `CompositeAuth` de la siguiente manera,
```php
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::class,
'authMethods' => [
HttpBasicAuth::class,
HttpBearerAuth::class,
QueryParamAuth::class,
],
];
return $behaviors;
}
```
Cada elemento en `authMethods` debe de ser el nombre de una clase de método de autenticación o un array de configuración.
La implementación de `findIdentityByAccessToken()` es específico de la aplicación. Por ejemplo, en escenarios simples
cuando cada usuario sólo puede tener un token de acceso, puedes almacenar este token en la columna `access_token`
en la tabla de usuario. El método debe de ser inmediatamente implementado en la clase `User` como sigue,
```php
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token' => $token]);
}
}
```
Después que la autenticación es activada, tal y como se describe arriba, para cada petición de la API, el controlador solicitado
puede intentar autenticar al usuario en su evento `beforeAction()`.
Si la autenticación tiene éxito, el controlador realizará otras comprobaciones (como son límite del ratio, autorización)
y entonces ejecutar la acción. La identidad del usuario autenticado puede ser recuperada via `Yii::$app->user->identity`.
Si la autenticación falla, una respuesta con estado HTTP 401 será devuelta junto con otras cabeceras apropiadas
(tal como la cabecera para autenticación básica HTTP `WWW-Authenticate`).
## Autorización <span id="authorization"></span>
Después de que un usuario se ha autenticado, probablementer querrás comprobar si él o ella tiene los permisos para realizar
la acción solicitada. Este proceso es llamado *autorización (authorization)* y está cubierto en detalle
en la [Sección de Autorización](security-authorization.md).
Si tus controladores extienden de [[yii\rest\ActiveController]], puedes sobreescribir
el método [[yii\rest\ActiveController::checkAccess()|checkAccess()]] para realizar la comprobación de la autorización.
El método será llamado por las acciones contenidas en [[yii\rest\ActiveController]].

156
docs/guide-es/rest-controllers.md

@ -1,156 +0,0 @@
Controladores
=============
Después de crear las clases de recursos y especificar cómo debe ser el formato de datos de recursos, el siguiente paso
es crear acciones del controlador para exponer los recursos a los usuarios finales a través de las APIs RESTful.
Yii ofrece dos clases controlador base para simplificar tu trabajo de crear acciones REST:
[[yii\rest\Controller]] y [[yii\rest\ActiveController]]. La diferencia entre estos dos controladores
es que este último proporciona un conjunto predeterminado de acciones que están específicamente diseñado para trabajar con
los recursos representados como [Active Record](db-active-record.md). Así que si estás utilizando [Active Record](db-active-record.md)
y te sientes cómodo con las acciones integradas provistas, podrías considerar extender tus controladores
de [[yii\rest\ActiveController]], lo que te permitirá crear potentes APIs RESTful con un mínimo de código.
Ambos [[yii\rest\Controller]] y [[yii\rest\ActiveController]] proporcionan las siguientes características,
algunas de las cuales se describen en detalle en las siguientes secciones:
* Método de Validación HTTP;
* [Negociación de contenido y formato de datos](rest-response-formatting.md);
* [Autenticación](rest-authentication.md);
* [Límite de Rango](rest-rate-limiting.md).
[[yii\rest\ActiveController]] además provee de las siguientes características:
* Un conjunto de acciones comunes necesarias: `index`, `view`, `create`, `update`, `delete`, `options`;
* La autorización del usuario de acuerdo a la acción y recurso solicitado.
## Creando Clases de Controlador <span id="creating-controller"></span>
Al crear una nueva clase de controlador, una convención para nombrar la clase del controlador es utilizar
el nombre del tipo de recurso en singular. Por ejemplo, para servir información de usuario,
el controlador puede ser nombrado como `UserController`.
Crear una nueva acción es similar a crear una acción para una aplicación Web. La única diferencia
es que en lugar de renderizar el resultado utilizando una vista llamando al método `render()`, para las acciones REST
regresas directamente los datos. El [[yii\rest\Controller::serializer|serializer]] y el
[[yii\web\Response|response object]] se encargarán de la conversión de los datos originales
al formato solicitado. Por ejemplo,
```php
public function actionView($id)
{
return User::findOne($id);
}
```
## Filtros <span id="filters"></span>
La mayoría de las características API REST son proporcionadas por [[yii\rest\Controller]] son implementadas en los términos de [filtros](structure-filters.md).
En particular, los siguientes filtros se ejecutarán en el orden en que aparecen:
* [[yii\filters\ContentNegotiator|contentNegotiator]]: soporta la negociación de contenido, que se explica en
la sección [Formateo de respuestas](rest-response-formatting.md);
* [[yii\filters\VerbFilter|verbFilter]]: soporta métodos de validación HTTP;
* [[yii\filters\auth\AuthMethod|authenticator]]: soporta la autenticación de usuarios, que se explica en
la sección [Autenticación](rest-authentication.md);
* [[yii\filters\RateLimiter|rateLimiter]]: soporta la limitación de rango, que se explica en
la sección [Límite de Rango](rest-rate-limiting.md).
Estos filtros se declaran nombrándolos en el método [[yii\rest\Controller::behaviors()|behaviors()]].
Puede sobrescribir este método para configurar filtros individuales, desactivar algunos de ellos, o añadir los tuyos.
Por ejemplo, si sólo deseas utilizar la autenticación básica HTTP, puede escribir el siguiente código:
```php
use yii\filters\auth\HttpBasicAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::class,
];
return $behaviors;
}
```
## Extendiendo `ActiveController` <span id="extending-active-controller"></span>
Si tu clase controlador extiende de [[yii\rest\ActiveController]], debe establecer
su propiedad [[yii\rest\ActiveController::modelClass|modelClass]] con el nombre de la clase del recurso
que planeas servir a través de este controlador. La clase debe extender de [[yii\db\ActiveRecord]].
### Personalizando Acciones <span id="customizing-actions"></span>
Por defecto, [[yii\rest\ActiveController]] provee de las siguientes acciones:
* [[yii\rest\IndexAction|index]]: listar recursos página por página;
* [[yii\rest\ViewAction|view]]: devolver el detalle de un recurso específico;
* [[yii\rest\CreateAction|create]]: crear un nuevo recurso;
* [[yii\rest\UpdateAction|update]]: actualizar un recurso existente;
* [[yii\rest\DeleteAction|delete]]: eliminar un recurso específico;
* [[yii\rest\OptionsAction|options]]: devolver los métodos HTTP soportados.
Todas esta acciones se declaran a través de método [[yii\rest\ActiveController::actions()|actions()]].
Puedes configurar estas acciones o desactivar alguna de ellas sobrescribiendo el método `actions()`, como se muestra a continuación,
```php
public function actions()
{
$actions = parent::actions();
// disable the "delete" and "create" actions
unset($actions['delete'], $actions['create']);
// customize the data provider preparation with the "prepareDataProvider()" method
$actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider'];
return $actions;
}
public function prepareDataProvider()
{
// prepare and return a data provider for the "index" action
}
```
Por favor, consulta las referencias de clases de acciones individuales para aprender las opciones de configuración disponibles para cada una.
### Realizando Comprobación de Acceso <span id="performing-access-check"></span>
Al exponer los recursos a través de RESTful APIs, a menudo es necesario comprobar si el usuario actual tiene permiso
para acceder y manipular el/los recurso solicitado/s. Con [[yii\rest\ActiveController]], esto puede lograrse
sobrescribiendo el método [[yii\rest\ActiveController::checkAccess()|checkAccess()]] como a continuación,
```php
/**
* Checks the privilege of the current user.
*
* This method should be overridden to check whether the current user has the privilege
* to run the specified action against the specified data model.
* If the user does not have access, a [[ForbiddenHttpException]] should be thrown.
*
* @param string $action the ID of the action to be executed
* @param \yii\base\Model $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
*/
public function checkAccess($action, $model = null, $params = [])
{
// check if the user can access $action and $model
// throw ForbiddenHttpException if access should be denied
if ($action === 'update' || $action === 'delete') {
if ($model->author_id !== \Yii::$app->user->id)
throw new \yii\web\ForbiddenHttpException(sprintf('You can only %s articles that you\'ve created.', $action));
}
}
```
El método `checkAccess()` será llamado por defecto en las acciones predeterminadas de [[yii\rest\ActiveController]]. Si creas
nuevas acciones y también deseas llevar a cabo la comprobación de acceso, debe llamar a este método de forma explícita en las nuevas acciones.
> Tip: Puedes implementar `checkAccess()` mediante el uso del [Componente Role-Based Access Control (RBAC)](security-authorization.md).

94
docs/guide-es/rest-error-handling.md

@ -1,94 +0,0 @@
Manejo de errores
=================
Cuando se maneja una petición de API RESTful, si ocurre un error en la petición del usuario o si algo inesperado
ocurre en el servidor, simplemente puedes lanzar una excepción para notificar al usuario que algo erróneo ocurrió.
Si puedes identificar la causa del error (p.e., el recurso solicitado no existe), debes considerar lanzar una excepción
con el código HTTP de estado apropiado (p.e., [[yii\web\NotFoundHttpException]] representa un código de estado 404).
Yii enviará la respuesta a continuación con el correspondiente código de estado HTTP y el texto. Yii puede incluir también
la representación serializada de la excepción en el cuerpo de la respuesta.
Por ejemplo:
```
HTTP/1.1 404 Not Found
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
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"name": "Not Found Exception",
"message": "The requested resource was not found.",
"code": 0,
"status": 404
}
```
La siguiente lista sumariza los códigos de estado HTTP que son usados por el framework REST:
* `200`: OK. Todo ha funcionado como se esperaba.
* `201`: El recurso ha creado con éxito en respuesta a la petición `POST`. La cabecera de situación `Location`
contiene la URL apuntando al nuevo recurso creado.
* `204`: La petición ha sido manejada con éxito y el cuerpo de la respuesta no tiene contenido (como una petición `DELETE`).
* `304`: El recurso no ha sido modificado. Puede usar la versión en caché.
* `400`: Petición errónea. Esto puede estar causado por varias acciones de el usuario, como proveer un JSON no válido
en el cuerpo de la petición, proveyendo parámetros de acción no válidos, etc.
* `401`: Autenticación fallida.
* `403`: El usuario autenticado no tiene permitido acceder a la API final.
* `404`: El recurso pedido no existe.
* `405`: Método no permitido. Por favor comprueba la cabecera `Allow` por los métodos HTTP permitidos.
* `415`: Tipo de medio no soportado. El tipo de contenido pedido o el número de versión no es válido.
* `422`: La validación de datos ha fallado (en respuesta a una petición `POST` , por ejemplo). Por favor, comprueba en el cuerpo de la respuesta el mensaje detallado.
* `429`: Demasiadas peticiones. La petición ha sido rechazada debido a un limitación de rango.
* `500`: Error interno del servidor. Esto puede estar causado por errores internos del programa.
## Personalizar la Respuesta al Error <span id="customizing-error-response"></span>
A veces puedes querer personalizar el formato de la respuesta del error por defecto . Por ejemplo, en lugar de depender
del uso de diferentes estados HTTP para indicar los diferentes errores, puedes querer usar siempre el estado HTTP 200
y encapsular el código de estado HTTP real como parte de una estructura JSON en la respuesta, como se muestra a continuación,
```
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
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"success": false,
"data": {
"name": "Not Found Exception",
"message": "The requested resource was not found.",
"code": 0,
"status": 404
}
}
```
Para lograrlo, puedes responder al evento `beforeSend` del componente `response` en la configuración de la aplicación:
```php
return [
// ...
'components' => [
'response' => [
'class' => 'yii\web\Response',
'on beforeSend' => function ($event) {
$response = $event->sender;
if ($response->data !== null && Yii::$app->request->get('suppress_response_code')) {
$response->data = [
'success' => $response->isSuccessful,
'data' => $response->data,
];
$response->statusCode = 200;
}
},
],
],
];
```
El anterior código reformateará la respuesta (sea exitosa o fallida) como se explicó cuando
`suppress_response_code` es pasado como un parámetro `GET`.

203
docs/guide-es/rest-quick-start.md

@ -1,203 +0,0 @@
Guía Breve
==========
Yii ofrece todo un conjunto de herramientas para simplificar la tarea de implementar un
servicio web APIs RESTful.
En particular, Yii soporta las siguientes características sobre APIs RESTful;
* Prototipado rápido con soporte para APIs comunes para [Active Record](db-active-record.md);
* 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](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;
* Cacheo de datos y cacheo HTTP;
* Limitación de rango;
A continuación, utilizamos un ejemplo para ilustrar como se puede construir un conjunto de APIs RESTful con un esfuerzo mínimo de codificación.
Supongamos que deseas exponer los datos de los usuarios vía APIs RESTful. Los datos de usuario son almacenados en la tabla DB `user`,
y ya tienes creado la clase [[yii\db\ActiveRecord|ActiveRecord]] `app\models\User` para acceder a los datos del usuario.
## Creando un controlador <span id="creating-controller"></span>
Primero, crea una clase controladora `app\controllers\UserController` como la siguiente,
```php
namespace app\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
}
```
La clase controladora extiende de [[yii\rest\ActiveController]]. Especificado por [[yii\rest\ActiveController::modelClass|modelClass]]
como `app\models\User`, el controlador sabe que modelo puede ser usado para recoger y manipular sus datos.
## Configurando las reglas de las URL <span id="configuring-url-rules"></span>
A continuación, modifica la configuración del componente `urlManager` en la configuración de tu aplicación:
```php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
]
```
La configuración anterior principalmente añade una regla URL para el controlador `user` de manera
que los datos de user pueden ser accedidos y manipulados con URLs amigables y verbos HTTP significativos.
## Habilitando entradas JSON <span id="enabling-json-input"></span>
Para permitir que la API acepte datos de entrada con formato JSON, configura la propiedad [[yii\web\Request::$parsers|parsers]]
del componente de aplicación `request` para usar [[yii\web\JsonParser]] para entradas JSON:
```php
'request' => [
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
]
```
> Tip: La configuración anterior es opcional. Sin la configuración anterior, la API sólo reconocería
`application/x-www-form-urlencoded` y `multipart/form-data` como formatos de entrada.
## Probándolo <span id="trying-it-out"></span>
Con la mínima cantidad de esfuerzo, tienes ya finalizado tu tarea de crear las APIs RESTful
para acceder a los datos de user. Las APIs que tienes creado incluyen:
* `GET /users`: una lista de todos los usuarios página por página;
* `HEAD /users`: muestra la información general de la lista de usuarios;
* `POST /users`: crea un nuevo usuario;
* `GET /users/123`: devuelve los detalles del usuario 123;
* `HEAD /users/123`: muestra la información general del usuario 123;
* `PATCH /users/123` y `PUT /users/123`: actualiza el usuario 123;
* `DELETE /users/123`: elimina el usuario 123;
* `OPTIONS /users`: muestra los verbos compatibles respecto al punto final `/users`;
* `OPTIONS /users/123`: muestra los verbos compatibles respecto al punto final `/users/123`.
> Info: Yii automáticamente pluraliza los nombres de los controladores para usarlo en los puntos finales.
> Puedes configurar esto usando la propiedad [[yii\rest\UrlRule::$pluralize]].
Puedes acceder a tus APIs con el comando `curl` de la siguiente manera,
```
$ curl -i -H "Accept:application/json" "http://localhost/users"
HTTP/1.1 200 OK
...
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
[
{
"id": 1,
...
},
{
"id": 2,
...
},
...
]
```
Intenta cambiar el tipo de contenido aceptado para ser `application/xml`, y verá que el resultado
se devuelve en formato XML:
```
$ curl -i -H "Accept:application/xml" "http://localhost/users"
HTTP/1.1 200 OK
...
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<response>
<item>
<id>1</id>
...
</item>
<item>
<id>2</id>
...
</item>
...
</response>
```
El siguiente comando creará un nuevo usuario mediante el envío de una petición POST con los datos del usuario en formato JSON:
```
$ curl -i -H "Accept:application/json" -H "Content-Type:application/json" -XPOST "http://localhost/users" -d '{"username": "example", "email": "user@example.com"}'
HTTP/1.1 201 Created
...
Location: http://localhost/users/1
Content-Length: 99
Content-Type: application/json; charset=UTF-8
{"id":1,"username":"example","email":"user@example.com","created_at":1414674789,"updated_at":1414674789}
```
> Tip: También puedes acceder a tus APIs a través del navegador web introduciendo la URL `http://localhost/users`.
Sin embargo, es posible que necesites algunos plugins para el navegador para enviar cabeceras especificas en la petición.
Como se puede ver, en las cabeceras de la respuesta, hay información sobre la cuenta total, número de páginas, etc.
También hay enlaces que permiten navegar por otras páginas de datos. Por ejemplo, `http://localhost/users?page=2`
le daría la página siguiente de los datos de usuario.
Utilizando los parámetros `fields` y `expand`, puedes también especificar que campos deberían ser incluidos en el resultado.
Por ejemplo, la URL `http://localhost/users?fields=id,email` sólo devolverá los campos `id` y `email`.
> Info: Puedes haber notado que el resultado de `http://localhost/users` incluye algunos campos sensibles,
> tal como `password_hash`, `auth_key`. Seguramente no quieras que éstos aparecieran en el resultado de tu API.
> Puedes y deberías filtrar estos campos como se describe en la sección [Response Formatting](rest-response-formatting.md).
## Resumen <span id="summary"></span>
Utilizando el framework Yii API RESTful, implementa un punto final API en términos de una acción de un controlador, y utiliza
un controlador para organizar las acciones que implementan los puntos finales para un sólo tipo de recurso.
Los recursos son representados como modelos de datos que extienden de la clase [[yii\base\Model]].
Si estás trabajando con bases de datos (relacionales o NoSQL), es recomendable utilizar [[yii\db\ActiveRecord|ActiveRecord]]
para representar los recursos.
Puedes utilizar [[yii\rest\UrlRule]] para simplificar el enrutamiento de los puntos finales de tu API.
Aunque no es obligatorio, es recomendable que desarrolles tus APIs RESTful como una aplicación separada, diferente de
tu WEB front end y tu back end para facilitar el mantenimiento.

44
docs/guide-es/rest-rate-limiting.md

@ -1,44 +0,0 @@
Limitando el rango (rate)
=========================
Para prevenir el abuso, puedes considerar añadir un *límitación del rango (rate limiting)* para tus APIs. Por ejemplo,
puedes querer limitar el uso del API de cada usuario a un máximo de 100 llamadas al API dentro de un periodo de 10 minutos.
Si se reciben demasiadas peticiones de un usuario dentro del periodo de tiempo declarado, deveríá devolverse una respuesta con código de estado 429 (que significa "Demasiadas peticiones").
Para activar la limitación de rango, la clase [[yii\web\User::identityClass|user identity class]] debe implementar [[yii\filters\RateLimitInterface]].
Este interface requiere la implementación de tres métodos:
* `getRateLimit()`: devuelve el número máximo de peticiones permitidas y el periodo de tiempo (p.e., `[100, 600]` significa que como mucho puede haber 100 llamadas al API dentro de 600 segundos).
* `loadAllowance()`: devuelve el número de peticiones que quedan permitidas y el tiempo (fecha/hora) UNIX
con el último límite del rango que ha sido comprobado.
* `saveAllowance()`: guarda ambos, el número restante de peticiones permitidas y el tiempo actual (fecha/hora) UNIX .
Puedes usar dos columnas en la tabla de usuario para guardar la información de lo permitido y la fecha/hora (timestamp). Con ambas definidas,
entonces `loadAllowance()` y `saveAllowance()` pueden ser utilizados para leer y guardar los valores de las dos columnas correspondientes al actual usuario autenticado.
Para mejorar el desempeño, también puedes considerar almacenar esas piezas de información en caché o almacenamiento NoSQL.
Una vez que la clase de identidad implementa la interfaz requerida, Yii utilizará automáticamente [[yii\filters\RateLimiter]]
configurado como un filtro de acción para que [[yii\rest\Controller]] compruebe el límite de rango. El limitador de rango
lanzará una excepeción [[yii\web\TooManyRequestsHttpException]] cuando el límite del rango sea excedido.
Puedes configurar el limitador de rango
en tu clase controlador REST como sigue:
```php
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
return $behaviors;
}
```
Cuando se activa el límite de rango, por defecto todas las respuestas serán enviadas con la siguiente cabecera HTTP conteniendo
información sobre el límite actual de rango:
* `X-Rate-Limit-Limit`, el máximo número de peticiones permitidas en un periodo de tiempo
* `X-Rate-Limit-Remaining`, el número de peticiones restantes en el periodo de tiempo actual
* `X-Rate-Limit-Reset`, el número de segundos a esperar para pedir el máximo número de peticiones permitidas
Puedes desactivar estas cabeceras configurando [[yii\filters\RateLimiter::enableRateLimitHeaders]] a `false`,
tal y como en el anterior ejemplo.

190
docs/guide-es/rest-resources.md

@ -1,190 +0,0 @@
Recursos
=========
Las APIs RESTful lo son todos para acceder y manipular *recursos (resources)*. Puedes observar los recursos en el paradigma MVC en [Modelos (models)](structure-models.md) .
Mientras que no hay restricción a cómo representar un recurso, en YII usualmente, puedes representar recursos como objetos de la clase [[yii\base\Model]] o sus clases hijas (p.e. [[yii\db\ActiveRecord]]), por las siguientes razones:
* [[yii\base\Model]] implementa el interface [[yii\base\Arrayable]] , el cual te permite personalizar como exponer los datos de los recursos a travès de las APIs RESTful.
* [[yii\base\Model]] soporta [Validación de entrada (input validation)](input-validation.md), lo cual es muy usado en las APIs RESTful para soportar la entrada de datos.
* [[yii\db\ActiveRecord]] provee un poderoso soporte para el acceso a datos en bases de datos y su manipulación, lo que lo le hace servir perfectamente si sus recursos de datos están en bases de datos.
En esta sección, vamos principalmente a describir como la clase con recursos que extiende de [[yii\base\Model]] (o sus clases hijas) puede especificar qué datos puede ser devueltos vía las APIs RESTful. Si la clase de los recursos no extiende de [[yii\base\Model]], entonces todas las variables públicas miembro serán devueltas.
## Campos (fields) <span id="fields"></span>
Cuando incluimos un recurso en una respuesta de la API RESTful, el recurso necesita ser serializado en una cadena.
Yii divide este proceso en dos pasos. Primero, el recurso es convertido en un array por [[yii\rest\Serializer]].
Segundo, el array es serializado en una cadena en el formato requerido (p.e. JSON, XML) por [[yii\web\ResponseFormatterInterface|response formatters]]. El primer paso es en el que debes de concentrarte principalmente cuando desarrolles una clase de un recurso.
Sobreescribiendo [[yii\base\Model::fields()|fields()]] y/o [[yii\base\Model::extraFields()|extraFields()]],
puedes especificar qué datos, llamados *fields*, en el recursos, pueden ser colocados en el array que le representa.
La diferencia entre estos dos métodos es que el primero especifica el conjunto de campos por defecto que deben ser incluidos en el array que los representa, mientras que el último especifica campos adicionales que deben de ser incluidos en el array si una petición del usuario final para ellos vía el parámetro de consulta `expand`. Por ejemplo,
```
// devuelve todos los campos declarados en fields()
http://localhost/users
// sólo devuelve los campos id y email, provistos por su declaración en fields()
http://localhost/users?fields=id,email
// devuelve todos los campos en fields() y el campo profile siempre y cuando esté declarado en extraFields()
http://localhost/users?expand=profile
// sólo devuelve los campos id, email y profile, siempre y cuando ellos estén declarados en fields() y extraFields()
http://localhost/users?fields=id,email&expand=profile
```
### Sobreescribiendo `fields()` <span id="overriding-fields"></span>
Por defecto, [[yii\base\Model::fields()]] devuelve todos los atributos de los modelos como si fueran campos, mientras [[yii\db\ActiveRecord::fields()]] sólo devuelve los atributos que tengan datos en la base de datos.
Puedes sobreescribir `fields()` para añadir, quitar, renombrar o redefinir campos. El valor de retorno de `fields()` ha de estar en un array. Las claves del array son los nombres de los campos y los valores del array son las correspondientes definiciones de los campos que pueden ser tanto nombres de propiedades/atributos o funciones anónimas que devuelven los correspondientes valores del los campos. En el caso especial de que el nombre de un campo sea el mismo que su definición puedes omitir la clave en el array. Por ejemplo,
```php
// explícitamente lista cada campo, siendo mejor usarlo cuando quieras asegurarte que los cambios
// en una tabla de la base de datos o en un atributo del modelo no provoque el cambio de tu campo (para mantener la compatibilidad anterior).
public function fields()
{
return [
// el nombre de campo es el mismo nombre del atributo
'id',
// el nombre del campo es "email", su atributo se denomina "email_address"
'email' => 'email_address',
// el nombre del campo es "name", su valor es definido está definido por una función anónima de retrollamada (callback)
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
// el ignorar algunos campos, es mejor usarlo cuando heredas de una implementación padre
// y pones en la lista negra (blacklist) algunos campos sensibles
public function fields()
{
$fields = parent::fields();
// quita los campos con información sensible
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
```
> Warning: Dado que, por defecto, todos los atributos de un modelo pueden ser incluidos en la devolución del API, debes
> examinar tus datos para estar seguro de que no contiene información sensible. Si se da este tipo de información,
> debes sobreescribir `fields()` para filtrarlos. En el ejemplo anterior, escogemos
> quitar `auth_key`, `password_hash` y `password_reset_token`.
### Sobreescribiendo `extraFields()` <span id="overriding-extra-fields"></span>
Por defecto, [[yii\base\Model::extraFields()]] no devuelve nada, mientras que [[yii\db\ActiveRecord::extraFields()]] devuelve los nombres de las relaciones que tienen datos (populated) obtenidos de la base de datos.
El formato de devolución de los datos de `extraFields()` es el mismo que el de `fields()`. Usualmente, `extraFields()` es principalmente usado para especificar campos cuyos valores sean objetos. Por ejemplo, dado la siguiente declaración de campo,
```php
public function fields()
{
return ['id', 'email'];
}
public function extraFields()
{
return ['profile'];
}
```
la petición `http://localhost/users?fields=id,email&expand=profile` puede devolver los siguientes datos en formato JSON :
```php
[
{
"id": 100,
"email": "100@example.com",
"profile": {
"id": 100,
"age": 30,
}
},
...
]
```
## Enlaces (Links) <span id="links"></span>
[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,
```php
use yii\db\ActiveRecord;
use yii\web\Link;
use yii\web\Linkable;
use yii\helpers\Url;
class User extends ActiveRecord implements Linkable
{
public function getLinks()
{
return [
Link::REL_SELF => Url::to(['user/view', 'id' => $this->id], true),
];
}
}
```
Cuando un objeto `User` es devuelto en una respuesta, puede contener un elemento `_links` representando los enlaces relacionados con el usuario, por ejemplo,
```
{
"id": 100,
"email": "user@example.com",
// ...
"_links" => {
"self": {
"href": "https://example.com/users/100"
}
}
}
```
## Colecciones <span id="collections"></span>
Los objetos de los recursos pueden ser agrupados en *collections*. Cada colección contiene una lista de recursos objeto del mismo tipo.
Las colecciones pueden ser representadas como arrays pero, es usualmente más deseable representarlas como [proveedores de datos (data providers)](output-data-providers.md). Esto es así porque los proveedores de datos soportan paginación y ordenación de los recursos, lo cual es comunmente necesario en las colecciones devueltas con las APIs RESTful. Por ejemplo, la siguiente acción devuelve un proveedor de datos sobre los recursos post:
```php
namespace app\controllers;
use yii\rest\Controller;
use yii\data\ActiveDataProvider;
use app\models\Post;
class PostController extends Controller
{
public function actionIndex()
{
return new ActiveDataProvider([
'query' => Post::find(),
]);
}
}
```
Cuando un proveedor de datos está enviando una respuesta con el API RESTful, [[yii\rest\Serializer]] llevará la actual página de los recursos y los serializa como un array de recursos objeto. Adicionalmente, [[yii\rest\Serializer]]
puede incluir también la información de paginación a través de las cabeceras HTTP siguientes:
* `X-Pagination-Total-Count`: Número total de recursos;
* `X-Pagination-Page-Count`: Número de páginas;
* `X-Pagination-Current-Page`: Página actual (iniciando en 1);
* `X-Pagination-Per-Page`: Número de recursos por página;
* `Link`: Un conjunto de enlaces de navegación permitiendo al cliente recorrer los recursos página a página.
Un ejemplo se puede ver en la sección [Inicio rápido (Quick Start)](rest-quick-start.md#trying-it-out).

157
docs/guide-es/rest-response-formatting.md

@ -1,157 +0,0 @@
Formato de Respuesta
====================
Cuando se maneja una petición al API RESTful, una aplicación realiza usualmente los siguientes pasos que están relacionados
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)](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
realizado por los [[yii\web\ResponseFormatterInterface|formatos de respuesta]] registrados
con la propiedad [[yii\web\Response::formatters|formatters]] del
[componente de la aplicación](structure-application-components.md) `response`.
## Negociación de contenido (Content Negotiation) <span id="content-negotiation"></span>
Yii soporta la negociación de contenido a través del filtro [[yii\filters\ContentNegotiator]]. La clase de controlador base
del API RESTful [[yii\rest\Controller]] está equipada con este filtro bajo el nombre `contentNegotiator`.
El filtro provee tanto un formato de respuesta de negociación como una negociación de lenguaje. Por ejemplo, si la petición API RESTful
contiene la siguiente cabecera,
```
Accept: application/json; q=1.0, */*; q=0.1
```
puede obtener una respuesta en formato JSON, como a continuación:
```
$ curl -i -H "Accept: application/json; q=1.0, */*; q=0.1" "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: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
[
{
"id": 1,
...
},
{
"id": 2,
...
},
...
]
```
Detrás de escena, antes de que sea ejecutada una acción del controlador del API RESTful, el filtro [[yii\filters\ContentNegotiator]]
comprobará la cabecera HTTP `Accept` de la petición y definirá el [[yii\web\Response::format|response format]]
como `'json'`. Después de que la acción sea ejecutada y devuelva el objeto recurso o la colección resultante,
[[yii\rest\Serializer]] convertirá el resultado en un array. Y finalmente, [[yii\web\JsonResponseFormatter]]
serializará el array en una cadena JSON incluyéndola en el cuerpo de la respuesta.
Por defecto, el API RESTful soporta tanto el formato JSON como el XML. Para soportar un nuevo formato, debes configurar
la propiedad [[yii\filters\ContentNegotiator::formats|formats]] del filtro `contentNegotiator` tal y como sigue,
en las clases del controlador del API:
```php
use yii\web\Response;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_HTML;
return $behaviors;
}
```
Las claves de la propiedad `formats` son los tipos MIME soportados, mientras que los valores son los nombres de formato de respuesta correspondientes,
los cuales deben ser soportados en [[yii\web\Response::formatters]].
## Serialización de Datos <span id="data-serializing"></span>
Como hemos descrito antes, [[yii\rest\Serializer]] es la pieza central responsable de convertir
objetos recurso o colecciones en arrays. Reconoce objetos tanto implementando [[yii\base\ArrayableInterface]]
como [[yii\data\DataProviderInterface]]. El primer formateador es implementado principalmente para objetos recursos,
mientras que el segundo para recursos collección.
Puedes configurar el serializador definiendo la propiedad [[yii\rest\Controller::serializer]] con un array de configuración.
Por ejemplo, a veces puedes querer ayudar a simplificar el trabajo de desarrollo del cliente incluyendo información de la paginación
directamente en el cuerpo de la respuesta. Para hacer esto, configura la propiedad [[yii\rest\Serializer::collectionEnvelope]]
como sigue:
```php
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
}
```
Puedes obtener la respuesta que sigue para la petición `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: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"items": [
{
"id": 1,
...
},
{
"id": 2,
...
},
...
],
"_links": {
"self": {
"href": "http://localhost/users?page=1"
},
"next": {
"href": "http://localhost/users?page=2"
},
"last": {
"href": "http://localhost/users?page=50"
}
},
"_meta": {
"totalCount": 1000,
"pageCount": 50,
"currentPage": 1,
"perPage": 20
}
}
```

92
docs/guide-es/rest-routing.md

@ -1,92 +0,0 @@
Enrutamiento
============
Con las clases de controlador y recurso preparadas, puedes acceder a los recursos usando una URL como
`http://localhost/index.php?r=user/create`, parecida a la que usas con aplicaciones Web normales.
En la práctica, querrás usualmente usar URLs limpias y obtener ventajas de los verbos HTTP.
Por ejemplo, una petición `POST /users` significaría acceder a la acción `user/create`.
Esto puede realizarse fácilmente configurando el componente de la aplicación `urlManager`
como sigue:
```php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
]
```
En comparación con la gestión de URL en las aplicaciones Web, lo principalmente nuevo de lo anterior es el uso de
[[yii\rest\UrlRule]] para el enrutamiento de las peticiones con el API RESTful. Esta clase especial de regla URL creará
un conjunto completo de reglas URL hijas para soportar el enrutamiento y creación de URL para el/los controlador/es especificados.
Por ejemplo, el código anterior es equivalente a las siguientes reglas:
```php
[
'PUT,PATCH users/<id>' => 'user/update',
'DELETE users/<id>' => 'user/delete',
'GET,HEAD users/<id>' => 'user/view',
'POST users' => 'user/create',
'GET,HEAD users' => 'user/index',
'users/<id>' => 'user/options',
'users' => 'user/options',
]
```
Y los siguientes puntos finales del API son mantenidos por esta regla:
* `GET /users`: lista de todos los usuarios página a página;
* `HEAD /users`: muestra ĺa información resumen del usuario listado;
* `POST /users`: crea un nuevo usuario;
* `GET /users/123`: devuelve los detalles del usuario 123;
* `HEAD /users/123`: muestra la información resumen del usuario 123;
* `PATCH /users/123` y `PUT /users/123`: actualizan al usuario 123;
* `DELETE /users/123`: borra el usuario 123;
* `OPTIONS /users`: muestra los verbos soportados de acuerdo al punto final `/users`;
* `OPTIONS /users/123`: muestra los verbos soportados de acuerdo al punto final `/users/123`.
Puedes configurar las opciones `only` y `except` para explícitamente listar cuáles acciones soportar o cuáles
deshabilitar, respectivamente. Por ejemplo,
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user',
'except' => ['delete', 'create', 'update'],
],
```
También puedes configurar las propiedades `patterns` o `extraPatterns` para redefinir patrones existentes o añadir nuevos soportados por esta regla.
Por ejemplo, para soportar una nueva acción `search` para el punto final `GET /users/search`, configura la opción `extraPatterns` como sigue,
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user',
'extraPatterns' => [
'GET search' => 'search',
],
]
```
Puedes haber notado que el ID del controlador `user` aparece en formato plural `users` en los puntos finales de las URLs.
Esto se debe a que [[yii\rest\UrlRule]] automáticamente pluraliza los IDs de los controladores al crear reglas URL hijas.
Puedes desactivar este comportamiento definiendo la propiedad [[yii\rest\UrlRule::pluralize]] como `false`.
> Info: La pluralización de los IDs de los controladores es realizada por [[yii\helpers\Inflector::pluralize()]]. Este método respeta
reglas especiales de pluralización. Por ejemplo, la palabra `box` (caja) será pluralizada como `boxes` en vez de `boxs`.
En caso de que la pluralización automática no encaje en tus requerimientos, puedes además configurar la propiedad
[[yii\rest\UrlRule::controller]] para especificar explícitamente cómo mapear un nombre utilizado en un punto final URL
a un ID de controlador. Por ejemplo, el siguiente código mapea el nombre `u` al ID del controlador `user`.
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => ['u' => 'user'],
]
```

111
docs/guide-es/rest-versioning.md

@ -1,111 +0,0 @@
Versionado
==========
Una buena API ha de ser *versionada*: los cambios y las nuevas características son implementadas en las nuevas versiones del API, en vez de estar continuamente modificando sólo una versión. Al contrario que en las aplicaciones Web, en las cuales tienes total control del código de ambas partes lado del cliente y lado del servidor,
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](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.
Por ejemplo, `http://example.com/v1/users` se refiere al punto final `/users` de la versión 1 de la API.
Otro método de versionado de la API,
la cual está ganando predominancia recientemente, es poner el número de versión en las cabeceras de la petición HTTP. Esto se suele hacer típicamente a través la cabecera `Accept`:
```
// vía parámetros
Accept: application/json; version=v1
// vía de el tipo de contenido del proveedor
Accept: application/vnd.company.myapp-v1+json
```
Ambos métodos tienen sus pros y sus contras, y hay gran cantidad de debates sobre cada uno. Debajo puedes ver una estrategia
práctica para el versionado de la API que es una mezcla de estos dos métodos:
* Pon cada versión superior de la implementación de la API en un módulo separado cuyo ID es el número de la versión mayor (p.e. `v1`, `v2`).
Naturalmente, las URLs de la API contendrán números de versión mayores.
* Dentro de cada versión mayor (y por lo tanto, dentro del correspondiente módulo), usa la cabecera de HTTP `Accept`
para determinar el número de la versión menor y escribe código condicional para responder a la menor versión como corresponde.
Para cada módulo sirviendo una versión mayor, el módulo debe incluir las clases de recursos y y controladores
que especifican la versión. Para separar mejor la responsabilidad del código, puedes conservar un conjunto común de
clases base de recursos y controladores, y hacer subclases de ellas en cada versión individual del módulo. Dentro de las subclases,
impementa el código concreto como por ejemplo `Model::fields()`.
Tu código puede estar organizado como lo que sigue:
```
api/
common/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
modules/
v1/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
v2/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
```
La configuración de tu aplicación puede tener este aspecto:
```php
return [
'modules' => [
'v1' => [
'basePath' => '@app/modules/v1',
'controllerNamespace' => 'app\modules\v1\controllers',
],
'v2' => [
'basePath' => '@app/modules/v2',
'controllerNamespace' => 'app\modules\v2\controllers',
],
],
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user', 'v1/post']],
['class' => 'yii\rest\UrlRule', 'controller' => ['v2/user', 'v2/post']],
],
],
],
];
```
Como consecuencia del código anterior, `http://example.com/v1/users` devolverá la lista de usuarios en la versión 1, mientras
`http://example.com/v2/users` devolverá la versión 2 de los usuarios.
Gracias a los módulos, el código de las diferentes principales versiones puede ser aislado. Pero los módulos hacen posible
reutilizar el código a través de los módulos vía clases base comunes y otros recursos compartidos.
Para tratar con versiones menores, puedes tomar ventaja de la característica de negociación de contenido
provista por el comportamiento (behavior) [[yii\filters\ContentNegotiator|contentNegotiator]]. El comportamiento `contentNegotiator`
definirá la propiedad [[yii\web\Response::acceptParams]] cuando determina qué tipo
de contenido soportar.
Por ejemplo, si una petición es enviada con la cabecera HTTP `Accept: application/json; version=v1`,
después de la negociación de contenido, [[yii\web\Response::acceptParams]] contendrá el valor `['version' => 'v1']`.
Basado en la información de versión contenida en `acceptParams`, puedes escribir código condicional en lugares
como acciones, clases de recursos, serializadores, etc. para proveer la funcionalidad apropiada.
Dado que por definición las versiones menores requireren mantener la compatibilidad hacia atrás, con suerte no tendrás demasiadas
comprobaciones de versión en tu código. De otra manera, probablemente puede ocurrir que necesites crear una versión mayor.

2
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://www.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](http://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.

10
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](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)
- 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)
## Enviar la Respuesta <span id="sending-response"></span>

6
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](https://redis.io/) como medio de almacenamiento.
* [[yii\mongodb\Session]]: almacena los datos de sesión en [MongoDB](https://www.mongodb.com/).
* [[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/).
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://owasp.org/www-community/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://www.owasp.org/index.php/HttpOnly) para más detalles.
### Validación de la Cookie <span id="cookie-validation"></span>

4
docs/guide-es/security-authorization.md

@ -153,10 +153,10 @@ class SiteController extends Controller
## Control de Acceso Basado en Roles (RBAC) <span id="rbac"></span>
El Control de Acceso Basado en Roles (RBAC) provee una simple pero poderosa manera centralizada de control de acceso. Por favos consulta
la [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) para más detalles sobre comparar RBAC
la [Wikipedia](http://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](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/1992/10/13/role-based-access-controls/documents/ferraiolo-kuhn-92.pdf).
Yii implementa una Jerarquía General RBAC, siguiendo el [modelo NIST RBAC](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.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

2
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://www.php.net/manual/en/function.crypt.php). Yii provee
En PHP, puedes generar un hash `bcrypt` utilizando la [función crypt](http://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:

2
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 <span id="configuring-db-connection"></span>
------------------------------------------
Asegúrate de tener instalado la extensión de PHP [PDO](https://www.php.net/manual/es/book.pdo.php) y el driver
Asegúrate de tener instalado la extensión de PHP [PDO](http://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.

2
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)](https://es.wikipedia.org/wiki/Cross-site_scripting) pudiendo inyectar código de Javascript malicioso dentro del parámetro.
[ataques cross-site scripting (XSS)](http://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()]].

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

@ -18,7 +18,7 @@ en el entorno de un equipo de desarrollo.
utilizar el Template de Proyecto Básico por su simplicidad pero funcionalidad suficiente.
Instalando via Composer <span id="installing-via-composer"></span>
Installing via Composer <span id="installing-via-composer"></span>
-------------------------------
Si aún no tienes Composer instalado, puedes hacerlo siguiendo las instrucciones que se encuentran en
@ -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/fxpio/composer-asset-plugin),
El primer comando instala [composer asset plugin](https://github.com/francoispluchino/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 <span id="installing-from-archive-file"></s
Instalar Yii desde un archivo comprimido involucra tres pasos:
1. Descargar el archivo desde [yiiframework.com](https://www.yiiframework.com/download/yii2-basic).
1. Descargar el archivo desde [yiiframework.com](http://www.yiiframework.com/download/yii2-basic).
2. Descomprimirlo en un directorio accesible vía Web.
3. Modificar el archivo `config/web.php` introduciendo una clave secreta para el ítem de configuración `cookieValidationKey`
(esto se realiza automáticamente si estás instalando Yii a través de Composer):
@ -97,7 +97,7 @@ Verificando las Instalación <span id="verifying-installation"></span>
---------------------------
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://www.php.net/manual/en/features.commandline.webserver.php) ejecutando el siguiente
el [servidor web incluido en PHP](https://secure.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
@ -115,7 +115,7 @@ Puedes utilizar tu navegador para acceder a la aplicación instalada de Yii en l
```
http://localhost:8080/.
```
![Instalación Correcta de Yii](images/start-app-installed.png)
@ -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://www.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](http://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,10 +142,8 @@ Configurar Servidores Web <span id="configuring-web-servers"></span>
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](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.
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.
En un servidor de producción, podrías querer configurar el servidor Web para que la aplicación sea accedida
a través de la URL `http://www.example.com/index.php` en vez de `http://www.example.com/basic/web/index.php`. Tal configuración
@ -187,7 +185,7 @@ DocumentRoot "path/to/basic/web"
### Configuración Recomendada de Nginx <span id="recommended-nginx-configuration"></span>
Para utilizar [Nginx](https://wiki.nginx.org/), debes instalar PHP como un [FPM SAPI](https://www.php.net/install.fpm).
Para utilizar [Nginx](http://wiki.nginx.org/), debes instalar PHP como un [FPM SAPI](http://php.net/install.fpm).
Utiliza la siguiente configuración de Nginx, reemplazando `path/to/basic/web` con la ruta real a
`basic/web` y `mysite.test` con el hostname real a servir.

16
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](https://www.yiiframework.com/doc-2.0/guide-README.html):
- [La Guía Definitiva](http://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](https://www.yiiframework.com/doc-2.0/index.html):
- [La Referencia de Clases](http://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](https://www.yiiframework.com/wiki/?tag=yii2):
- [Los Artículos de la Wiki](http://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](https://www.yiiframework.com/books)
* [Extensiones](https://www.yiiframework.com/extensions/):
- [Libros](http://www.yiiframework.com/doc/)
* [Extensiones](http://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: <https://forum.yiiframework.com/>
- Chat IRC: El canal #yii en la red Libera (<ircs://irc.libera.chat:6697/yii>)
- Foro: <http://www.yiiframework.com/forum/>
- Chat IRC: El canal #yii en la red freenode (<irc://irc.freenode.net/yii>)
- Chat Gitter: <https://gitter.im/yiisoft/yii2>
- GitHub: <https://github.com/yiisoft/yii2>
- Facebook: <https://www.facebook.com/groups/yiitalk/>
- Twitter: <https://twitter.com/yiiframework>
- LinkedIn: <https://www.linkedin.com/groups/yii-framework-1483367>
- Stackoverflow: <https://stackoverflow.com/questions/tagged/yii2>
- Stackoverflow: <http://stackoverflow.com/questions/tagged/yii2>

29
docs/guide-es/start-prerequisites.md

@ -1,29 +0,0 @@
# Qué necesita saber
La curva de aprendizaje de Yii no es tan empinada como en otros _frameworks_ en PHP,
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://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://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
Se requiere una comprensión básica de la programación orientada a objetos. Si no está
familiarizado con ella, diríjase a alguno de los muchos tutoriales disponibles, como
[el de tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762).
Observe que cuanto más complicada sea su aplicación, más conceptos avanzados de la
POO deberá aprender para gestionar con éxito esa complejidad.
## Línea de órdenes y composer
Yii usa profusamente el gestor de paquetes _de facto_ de PHP, [Composer](https://getcomposer.org/),
así que asegúrese de leer y comprender su [guía](https://getcomposer.org/doc/01-basic-usage.md).
Si no está familiarizado con el uso de la línea de órdenes, es hora de empezar a probarla.
Una vez que aprenda los fundamentos, nunca querrá trabajar sin ella.

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

@ -42,7 +42,7 @@ Estructura de la aplicación <span id="application-structure"></span>
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)](https://wikipedia.org/wiki/Model-view-controller),
Yii implementa el patrón de diseño [modelo-vista-controlador (MVC)](http://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).

6
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](https://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](http://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](https://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](http://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]] <span id="timeZone"></span>
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://www.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()](http://php.net/manual/es/function.date-default-timezone-set.php).
Por ejemplo:
```php

26
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,
`https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` o
`http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` o
`//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`.
* [[yii\web\AssetBundle::css|css]]: un array que lista los archivos CSS que contiene 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](https://fontawesome.com/). Especificando
El ejemplo anterior define un asset bundle para el ["fontawesome" package](http://fontawesome.io/). Especificando
la opción de publicación `beforeCopy`, solo los subdirectorios `fonts` y `css` serán publicados.
### Bower y NPM Assets <span id="bower-npm-assets"></span>
La mayoría de paquetes JavaScript/CSS se gestionan con [Bower](https://bower.io/) y/o [NPM](https://www.npmjs.com/).
La mayoría de paquetes JavaScript/CSS se gestionan con [Bower](http://bower.io/) y/o [NPM](https://www.npmjs.org/).
Si tu aplicación o extensión usa estos paquetes, se recomienda seguir los siguientes pasos para gestionar los assets en
la librería:
@ -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](https://lesscss.org) o [SCSS](https://sass-lang.com/); y para JavaScript se puede usar
[TypeScript](https://www.typescriptlang.org/).
puede usar [LESS](http://lesscss.org) o [SCSS](http://sass-lang.com/); y para JavaScript se puede usar
[TypeScript](http://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](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`
- [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`
Yii se basa en las herramientas pre-procesadoras instalada para convertir los assets. Por ejemplo, para usar
[LESS](https://lesscss.org/) se debe instalar el comando pre-procesador `lessc`.
[LESS](http://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](https://gruntjs.com/) para
anteriormente. Por ejemplo, se pueden usar herramientas generadoras tales como [grunt](http://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](https://gruntjs.com/) para lograr el mismo
Se puede usar la excelente herramienta de ejecución de tareas [grunt](http://gruntjs.com/) para lograr el mismo
objetivo.

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

@ -1,7 +1,7 @@
Controladores
=============
Los controladores son parte del patrón o arquitectura [MVC](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador).
Los controladores son parte del patrón o arquitectura [MVC](http://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

4
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 https://www.yiiframework.com/
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
* @license http://www.yiiframework.com/license/
*/
defined('YII_DEBUG') or define('YII_DEBUG', true);

42
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](https://www.php-fig.org/psr/psr-4/), se puede usar la clase de autocarga proporcionada por Yii para cargar
[PSR-4](http://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": "https://forum.yiiframework.com/",
"wiki": "https://www.yiiframework.com/wiki/",
"irc": "ircs://irc.libera.chat:6697/yii",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/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](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)
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)
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 <span id="namespaces"></span>
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](https://www.php-fig.org/psr/psr-4/) o el
[estándar PSR-0](https://www.php-fig.org/psr/psr-0/).
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/).
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 <span id="versioning"></span>
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](https://semver.org/lang/es/) para determinar que números se deben usar.
seguir la práctica [Versionamiento Semántico](http://semver.org/lang/es/) para determinar que números se deben usar.
#### Lanzamientos <span id="releasing"></span>
@ -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](https://daringfireball.net/projects/markdown/) y llamarlo
Recomendamos que se escriba en formato [Markdown](http://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/blob/master/docs/internals/core-code-style.md) para
[estilo de código del núcleo del framework](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style) para
obtener más detalles.
## Extensiones del Núcleo <span id="core-extensions"></span>
@ -406,12 +406,14 @@ 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](https://getbootstrap.com/).
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/).
- [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](https://www.elastic.co/). Incluye soporte básico para realizar consultas/búsquedas y también
[Elasticsearch](http://www.elasticsearch.org/). 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
@ -421,20 +423,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](https://imagine.readthedocs.org/).
imágenes basadas en [Imagine](http://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](https://jqueryui.com/).
iteraciones y widgets de [JQuery UI](http://jqueryui.com/).
- [yiisoft/yii2-mongodb](https://github.com/yiisoft/yii2-mongodb): proporciona soporte para utilizar
[MongoDB](https://www.mongodb.com/). incluye características como consultas básicas, Active Record, migraciones,
[MongoDB](http://www.mongodb.org/). 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](https://redis.io/). incluye características como consultas básicas, Active Record, caching, etc.
[redis](http://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](https://www.smarty.net/).
[Smarty](http://www.smarty.net/).
- [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx): proporciona soporte para utilizar
[Sphinx](https://sphinxsearch.com). incluye características como consultas básicas, Active Record, code generation,
[Sphinx](http://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](https://twig.symfony.com/).
[Twig](http://twig.sensiolabs.org/).

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

@ -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 <span id="auth-method-filters"></span>
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](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`.
[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`.
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
@ -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]] <span id="rate-limiter"></span>
RateLimiter implementa un algoritmo de para limitar la tasa de descarga basándose en
[leaky bucket algorithm](https://en.wikipedia.org/wiki/Leaky_bucket). Este se utiliza sobre todo en la implementación
[leaky bucket algorithm](http://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.

6
docs/guide-es/structure-models.md

@ -2,7 +2,7 @@ Modelos
=======
Los modelos forman parte de la arquitectura
[MVC](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador). Son objetos que representan datos de
[MVC](http://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://www.php.net/manual/es/class.arrayaccess.php) y
[ArrayIterator](https://www.php.net/manual/es/class.arrayiterator.php) que brinda [[yii\base\Model]]:
[ArrayAccess](http://php.net/manual/es/class.arrayaccess.php) y
[ArrayIterator](http://php.net/manual/es/class.arrayiterator.php) que brinda [[yii\base\Model]]:
```php
$model = new \app\models\ContactForm;

2
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

2
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)](https://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)](http://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).

10
docs/guide-es/structure-views.md

@ -1,7 +1,7 @@
Vistas
======
Las Vistas (views) son una parte de la arquitectura [MVC](https://es.wikipedia.org/wiki/Modelo%E2%80%93vista%E2%80%93controlador).
Las Vistas (views) son una parte de la arquitectura [MVC](http://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](https://es.wikipedia.org/wiki/Cross-site_scripting).
a ataques tipo [cross-site scripting](http://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](https://twig.symfony.com/) o [Smarty](https://www.smarty.net/).
[Twig](http://twig.sensiolabs.org/) o [Smarty](http://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' => 'https://www.yiiframework.com/rss.xml/',
'href' => 'http://www.yiiframework.com/rss.xml/',
]);
```
El resultado del código es el siguiente:
```html
<link title="Noticias en Vivo de Yii" rel="alternate" type="application/rss+xml" href="https://www.yiiframework.com/rss.xml/">
<link title="Noticias en Vivo de Yii" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/">
```
Al igual que con [[yii\web\View::registerMetaTag()|registerMetaTags()]], puedes especificar una clave al llamar

151
docs/guide-es/structure-widgets.md

@ -1,11 +1,10 @@
Widgets
=======
Los _widgets_ son bloques de código reutilizables que se usan en las [vistas](structure-views.md)
para crear elementos de interfaz de usuario complejos y configurables, de forma orientada a objetos.
Por ejemplo, un _widget_ de selección de fecha puede generar un selector de fechas bonito que
permita a los usuarios seleccionar una fecha. Todo lo que hay que hacer es insertar el siguiente
código en una vista:
Los Widgets son bloques de código reutilizables utilizados en las [vistas](structure-views.md) para crear elementos de
interfaz de usuario complejos y configurables de forma orientada a objetos. Por ejemplo, widget DatePicker puede
generar un DatePicker de lujo que permita a los usuarios seleccionar una fecha. Todo lo que se tiene que hacer es
insertar el siguiente código en una vista.
```php
<?php
@ -14,22 +13,18 @@ use yii\jui\DatePicker;
<?= DatePicker::widget(['name' => 'date']) ?>
```
Yii incluye un buen número de _widgets_, tales como
[[yii\widgets\ActiveForm|formulario activo]],
[[yii\widgets\Menu|menú]],
[_widgets_ de jQuery UI](https://www.yiiframework.com/extension/yiisoft/yii2-jui), y
[_widgets_ de Twitter Bootstrap](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap).
A continuación presentaremos las nociones básicas de de los _widgets_. Por favor, refiérase a la
documentación de la API de clases si quiere aprender más acerca del uso de un _widget_ en particular.
Hay un buen número de widgets incluidos en Yii, tales como [[yii\widgets\ActiveForm|active form]],
[[yii\widgets\Menu|menu]], [Widgets de jQuery UI](widget-jui.md), [widgets de Twitter Bootstrap](widget-bootstrap.md).
En adelante, introduciremos las nociones básicas acerca de los widgets. Por favor, refiérase a la documentación de la
API de clases si quiere aprender más acerca de el uso de un widget en particular.
## Uso de los Widgets <span id="using-widgets"></span>
## Uso de los _widgets_ <span id="using-widgets"></span>
Los _widgets_ se usan principalmente en las [vistas](structure-views.md). Se puede llamar al método
[[yii\base\Widget::widget()]] para usar un _widget_ en una vista. El método toma un _array_ de
[configuración](concept-configurations.md) para inicializar el _widget_ y devuelve la representación
resultante del _widget_. Por ejemplo, el siguiente código inserta un _widget_ de selección de fecha
configurado para usar el idioma ruso y guardar la selección en el atributo `from_date` de `$model`.
Los Widgets son usados principalmente en las [vistas](structure-views.md). Se puede llamar al método
[[yii\base\Widget::widget()]] para usar un widget en una vista. El método obtiene un array de
[configuración](concept-configurations.md) para inicializar el widget y retorna la representación resultante del
widget. Por ejemplo, el siguiente código inserta un widget DatePicker que esta configurado para usar el idioma Ruso y
mantener la entrada en atributo 'form_date' del '$model'.
```php
<?php
@ -39,15 +34,17 @@ use yii\jui\DatePicker;
'model' => $model,
'attribute' => 'from_date',
'language' => 'ru',
'dateFormat' => 'php:Y-m-d',
'clientOptions' => [
'dateFormat' => 'yy-mm-dd',
],
]) ?>
```
Algunos _widgets_ pueden coger un bloque de contenido que debería encontrarse entre la invocación de
[[yii\base\Widget::begin()]] y [[yii\base\Widget::end()]]. Por ejemplo, el siguiente código usa el
_widget_ [[yii\widgets\ActiveForm]] para generar un formulario de inicio de sesión. El _widget_
generará las etiquetas `<form>` de apertura y cierre donde se llame a `begin()` y `end()`
respectivamente. Cualquier cosa que este en medio se representará tal cual.
Algunos widgets pueden coger un bloque de contenido que debería encontrarse entre la invocación de
[[yii\base\Widget::begin()]] y [[yii\base\Widget::end()]]. Por ejemplo, el siguiente código usa el widget
[[yii\widgets\ActiveForm]] para generar un formulario de inicio de sesión. El widget generará las etiquetas '<form>'
de apertura y cierre donde sean llamados 'begin()' y 'end()', respectivamente. Cualquier cosa que este en medio será
representado como tal.
```php
<?php
@ -68,39 +65,20 @@ use yii\helpers\Html;
<?php ActiveForm::end(); ?>
```
Hay que tener en cuenta que, a diferencia de [[yii\base\Widget::widget()]] que devuelve la
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://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.
> No seguir esta regla puede desembocar en una salida distinta a la esperada.
Hay que tener en cuenta que a diferencia de [[yii\base\Widget::widget()]] que devuelve la 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.
## Creación Widgets <span id="creating-widgets"></span>
### Configuración de las variables globales predefinidas
Para crear un widget, se debe extender a [[yii\base\Widget]] y sobrescribir los métodos [[yii\base\Widget::init()]]
y/o [[yii\base\Widget::run()]]. Normalmente el método 'init()' debería contener el código que estandariza las
propiedades del widget, mientras que el método 'run()' debería contener el código que genere la representación
resultante del widget. La representación resultante puede ser "pintada" directamente o devuelta como una cadena por el
método 'run()'.
Las variables globales predefinidas de un _widget_ se pueden configurar por medio del contenedor
de inyección de dependencias:
```php
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
```
Consulte la [sección "Uso práctico" de la Guía del contenedor de inyección de dependencias](concept-di-container.md#practical-usage) para más detalles.
## Creación de _widgets_ <span id="creating-widgets"></span>
Para crear un _widget_, extienda la clase [[yii\base\Widget]] y sobrescriba los métodos
[[yii\base\Widget::init()]] y/o [[yii\base\Widget::run()]]. Normalmente el método `init()` debería
contener el código que inicializa las propiedades del _widget_, mientras que el método `run()`
debería contener el código que genera la representación resultante del _widget_. La representación
resultante del método `run()` puede pasarse directamente a `echo` o devolverse como una cadena.
En el siguiente ejemplo, `HelloWidget` codifica en HTML y muestra el contenido asignado a su
propiedad `message`. Si la propiedad no está establecida, mostrará «Hello World» por omisión.
En el siguiente ejemplo, 'HelloWidget' codifica en HTML y muestra el contenido asignado a su propiedad 'message'. Si
la propiedad no está establecida, mostrará "Hello World" por defecto.
```php
namespace app\components;
@ -127,7 +105,7 @@ class HelloWidget extends Widget
}
```
Para usar este _widget_, simplemente inserte el siguiente código en una vista:
Para usar este widget, simplemente inserte el siguiente código en una vista:
```php
<?php
@ -136,8 +114,8 @@ use app\components\HelloWidget;
<?= HelloWidget::widget(['message' => 'Good morning']) ?>
```
Abajo se muestra una variante de `HelloWidget` que toma el contenido insertado entre las llamadas a
`begin()` y `end()`, lo codifica en HTML y posteriormente lo muestra.
Abajo se muestra una variante de 'HelloWidget' obtiene el contenido entre las llamadas 'begin()' y 'end()', lo
codifica en HTML y posteriormente lo muestra.
```php
namespace app\components;
@ -161,15 +139,14 @@ class HelloWidget extends Widget
}
```
Como se puede observar, el búfer de salida de PHP es iniciado en `init()` para que toda salida
entre las llamadas de `init()` y `run()` puede ser capturada, procesada y devuelta en `run()`.
Como se puede observar, el búfer de salida PHP es iniciado en 'init()' por tanto cualquier salida entre las llamadas
de 'init()' y 'run()' puede ser capturada, procesada y devuelta en 'run()'.
> Info: Cuando llame a [[yii\base\Widget::begin()]], se creará una nueva instancia del _widget_ y se
> llamará a su método `init()` al final del constructor del _widget_. Cuando llame a
> [[yii\base\Widget::end()]], se invocará el método `run()` y el resultado que devuelva será pasado
> a `echo` por `end()`.
> Info: Cuando se llama a [[yii\base\Widget::begin()]], se creará una nueva instancia del widget y el método 'init()'
será llamado al final del constructor del widget. Cuando se llama [[yii\base\Widget::end()]], el método 'run()' será
llamado el resultado que devuelva será escrito por 'end()'.
El siguiente código muestra cómo usar esta nueva variante de `HelloWidget`:
El siguiente código muestra como usar esta nueva variante de 'HelloWidget':
```php
<?php
@ -177,15 +154,14 @@ use app\components\HelloWidget;
?>
<?php HelloWidget::begin(); ?>
contenido que puede contener <etiqueta>s
content that may contain <tag>'s
<?php HelloWidget::end(); ?>
```
A veces, un _widget_ puede necesitar representar un gran bloque de contenido. Aunque que se
podría incrustar el contenido dentro del método `run()`, es preferible ponerlo dentro de una
[vista](structure-views.md) y llamar al método [[yii\base\Widget::render()]] para representarlo.
Por ejemplo:
A veces, un widget puede necesitar representar una gran cantidad de contenido. Mientras que se puede incrustar el
contenido dentro del método 'run()', ponerlo dentro de una [vista](structure-views.md) y llamar
[[yii\base\Widget::render()]] para representarla, es un mejor enfoque. Por ejemplo:
```php
public function run()
@ -194,27 +170,24 @@ public function run()
}
```
Por omisión, las vistas para un _widget_ deberían encontrarse en ficheros dentro del directorio
`WidgetPath/views`, donde `WidgetPath` representa el directorio que contiene el fichero de clase
del _widget_. Por lo tanto, el ejemplo anterior representará el fichero de vista
`@app/components/views/hello.php`, suponiendo que la clase del _widget_ se encuentre en
`@app/components`. Se puede sobrescribir el método [[yii\base\Widget::getViewPath()]] para
personalizar el directorio que contiene los ficheros de vista del _widget_.
Por defecto, las vistas para un widget deberían encontrarse en ficheros dentro del directorio 'WidgetPath/views',
donde 'WidgetPath' representa el directorio que contiene el fichero de clase del widget. Por lo tanto, el anterior
ejemplo representará el fichero de la vista `@app/components/views/hello.php`, asumiendo que la clase del widget se
encuentre en `@app/components`. Se puede sobrescribir el método [[yii\base\Widget::getViewPath()]] para personalizar
el directorio que contenga los ficheros de la vista del widget.
## Buenas prácticas <span id="best-practices"></span>
## Mejores Prácticas <span id="best-practices"></span>
Los _widgets_ son una manera orientada a objetos de reutilizar código de las vistas.
Los widgets son una manera orientada a objetos de reutilizar código de las vistas.
Al crear _widgets_, debería continuar suguiendo el patrón MVC. En general, se debería mantener la
lógica en las clases del widget y la presentación en las [vistas](structure-views.md).
Cuando se crean widgets, se debería continuar manteniendo el patrón MVC. En general, se debería mantener la lógica en
las clases del widget y mantener la presentación en las [vistas](structure-views.md).
Los _widgets_ deberían diseñarse para ser autosuficientes. Es decir, cuando se use un _widget_, se
debería poder ponerlo en una vista sin hacer nada más. Esto puede resultar complicado si un
_widget_ requiere recursos externos, tales como CSS, JavaScript, imágenes, etc. Afortunadamente
Yii proporciona soporte para [paquetes de recursos](structure-asset-bundles.md) (_asset bundles_)
que se pueden utilizar para resolver este problema.
Los widgets deberían ser diseñados para ser autónomos. Es decir, cuando se usa un widget, se debería poder poner en
una vista sin hacer nada más. Esto puede resultar complicado si un widget requiere recursos externos, tales como CSS,
JavaScript, imágenes, etc. Afortunadamente Yii proporciona soporte para
[asset bundles](structure-asset-bundles.md) que pueden ser utilizados para resolver el problema.
Cuando un _widget_ sólo contiene código de vista, es muy similar a una [vista](structure-views.md).
De hecho, en este caso, su única diferencia es que un _widget_ es una clase redistribuible, mientras
que una vista es sólo un simple script PHP que prefiere mantener dentro de su aplicación.
Cuando un widget sólo contiene código de vista, este es muy similar a una [vista](structure-views.md). De hecho, en
este caso, su única diferencia es que un widget es una clase redistribuible, mientras que una vista es sólo un script
PHP llano que prefiere mantenerse dentro de su aplicación.

20
docs/guide-es/test-acceptance.md

@ -1,20 +0,0 @@
Tests de aceptación
===================
Un test de aceptación verifica escenarios desde la perspectiva de un usuario.
Se accede a la aplicación testeada por medio de PhpBrowser o de un navegador de verdad.
En ambos casos los navegadores se comunican vía HTTP así que la aplicación debe ser
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](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
Si ha empezado con la plantilla avanzada, consulte la [guía de testeo](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-testing.md)
para más detalles sobre la ejecución de tests.
Si ha empezado con la plantilla básica, consulte la [sección sobre testeo de su README](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing).

58
docs/guide-es/test-environment-setup.md

@ -1,23 +1,49 @@
Preparación del entorno de pruebas
==================================
Preparación del entorno de test
===============================
Yii 2 ha mantenido oficialmente integración con el _framework_ de testeo [`Codeception`](https://github.com/Codeception/Codeception),
que le permite crear los siguientes tipos de tests:
> Note: Esta sección se encuentra en desarrollo.
- [Unitari](test-unit.md) - verifica que una unidad simple de código funciona como se espera;
- [Funcional](test-functional.md) - verifica escenarios desde la perspectiva de un usuario a través de la emulación de un navegador;
- [De aceptación](test-acceptance.md) - verifica escenarios desde la perspectiva de un usuario en un navegador.
Yii 2 ha mantenido integración oficial con el framework de testing [`Codeception`](https://github.com/Codeception/Codeception),
que te permite crear los siguientes tipos de tests:
Yii provee grupos de pruebas listos para utilizar para los tres tipos de test, tanto en la plantilla de proyecto
[`yii2-basic`](https://github.com/yiisoft/yii2-app-basic) como en
[`yii2-advanced`](https://github.com/yiisoft/yii2-app-advanced).
- [Test de unidad](test-unit.md) - verifica que una unidad simple de código funciona como se espera;
- [Test funcional](test-functional.md) - verifica escenarios desde la perspectiva de un usuario a través de la emulación de un navegador;
- [Test de aceptación](test-acceptance.md) - verifica escenarios desde la perspectiva de un usuario en un navegador.
Codeception viene preinstalado tanto en la plantilla de proyecto básica como en la avanzada.
En caso de que no use una de estas plantillas, puede instalar Codeception ejecutando
las siguientes órdenes de consola:
Yii provee grupos de pruebas listos para utilizar en ambos
[`yii2-basic`](https://github.com/yiisoft/yii2-app-basic) y
[`yii2-advanced`](https://github.com/yiisoft/yii2-app-advanced) templates de proyectos.
Para poder ejecutar estos tests es necesario instalar [Codeception](https://github.com/Codeception/Codeception).
Puedes instalarlo tanto localmente - únicamente para un proyecto en particular, o globalmente - para tu máquina de desarrollo.
Para la instalación local utiliza los siguientes comandos:
```
composer require "codeception/codeception=2.1.*"
composer require "codeception/specify=*"
composer require "codeception/verify=*"
```
Para la instalación global necesitarás la directiva `global`:
```
composer require codeception/codeception
composer require codeception/specify
composer require codeception/verify
composer global require "codeception/codeception=2.1.*"
composer global require "codeception/specify=*"
composer global require "codeception/verify=*"
```
En caso de que nunca hayas utilizado Composer para paquetes globales, ejecuta `composer global status`. Esto debería mostrar la salida:
```
Changed current directory to <directory>
```
Entonces agrega `<directory>/vendor/bin` a tu variable de entorno `PATH`. Ahora podrás utilizar el `codecept` en la línea
de comandos a nivel global.
> Note: la instalación global te permite usar Codeception para todos los proyectos en los que trabajes en tu máquina de desarrollo y
te permite ejecutar el comando `codecept` globalmente sin especificar su ruta. De todos modos, ese acercamiento podría ser inapropiado,
por ejemplo, si 2 proyectos diferentes requieren diferentes versiones de Codeception instaladas.
Por simplicidad, todos los comandos relacionados a tests en esta guía están escritos asumiendo que Codeception
ha sido instalado en forma global.

2
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](https://codeception.com/) para hacer tests de tu código, deberías considerar el utilizar
Si estás utilizando [Codeception](http://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.

26
docs/guide-es/test-functional.md

@ -1,25 +1,11 @@
Tests funcionales
Tests Funcionales
=================
Los tests funcionales verifican escenarios desde la perspectiva de un usuario.
Son similares a los [tests de aceptación](test-acceptance.md) pero en lugar de
comunicarse vía HTTP rellena el entorno como parámetros POST y GET y después ejecuta
una instancia de la aplicación directamente desde el código.
> Note: Esta sección se encuentra en desarrollo.
Los tests funcionales son generalmente más rápidos que los tests de aceptación y
proporcionan _stack traces_ detalladas en los fallos.
Como regla general, debería preferirlos salvo que tenga una configuración de servidor
web especial o una interfaz de usuario compleja en Javascript.
- [Tests Funcionales de Codeception](http://codeception.com/docs/04-FunctionalTests)
Las pruebas funcionales se implementan con ayuda del _framework_ Codeception, que tiene
una buena documentación:
Ejecutar test funcionales de templates básicos y avanzados
----------------------------------------------------------
- [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
Si ha empezado con la plantilla avanzada, consulte la [guía de testeo](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-testing.md)
para más detalles sobre la ejecución de tests.
Si ha empezado con la plantilla básica, consulte la [sección sobre testeo de su README](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing).
Por favor consulta las instrucciones provistas en `apps/advanced/tests/README.md` y `apps/basic/tests/README.md`.

80
docs/guide-es/test-overview.md

@ -1,80 +0,0 @@
Tests
=====
Las pruebas son una parte importante del desarrollo de software. Seamos conscientes
de ello o no, ralizamos pruebas contínuamente.
Por ejemplo, cuando escribimos una clase en PHP, podemos depurarla paso a paso o
simplemente usar declaraciones `echo` o `die` para verificar que la implementación
funciona conforme a nuestro plan inicial. En el caso de una aplicación web, introducimos
algunos datos de prueba en los formularios para asegurarnos de que la página interactúa
con nosotros como esperábamos.
El proceso de testeo se puede automatizar para que cada vez que necesitemos verificar
algo, solamente necesitemos invocar el código que lo hace por nosotros. El código que
verifica que el restulado coincide con lo que habíamos planeado se llama *test* y el proceso
de su creación y posterior ejecución es conocido como *testeo automatizado*, que es el
principal tema de estos capítulos sobre testeo.
## Desarrollo con tests
El Desarrollo Dirigido por Pruebas (_Test-Driven Development_ o TDD) y el Desarrollo
Dirigido por Corpotamientos (_Behavior-Driven Development_ o BDD) son enfoques para
desarrollar software, en los que se describe el comportamiento de un trozo de código
o de toda la funcionalidad como un conjunto de escenarios o pruebas antes de escribir
el código real y sólo entonces crear la implementación que permite pasar esos tests
verificando que se ha logrado el comportamiento pretendido.
El proceso de desarrollo de una funcionalidad es el siguiente:
- Crear un nuevo test que describe una funcionalidad a implementar.
- Ejecutar el nuevo test y asegurarse de que falla. Esto es lo esperado, dado que todavía no hay ninguna implementación.
- Escribir un código sencillo para superar el nuevo test.
- Ejecutar todos los tests y asegurarse de que se pasan todos.
- Mejorar el código y asegurarse de que los tests siguen superándose.
Una vez hecho, se repite el proceso de neuvo para otra funcionalidad o mejora.
Si se va a cambiar la funcionalidad existente, también hay que cambiar los tests.
> Tip: Si siente que está perdiendo tiempo haciendo un montón de iteraciones pequeñas
> y simples, intente cubrir más por cada escenario de test, de modo que haga más cosas antes
> de ejecutar los tests de nuevo. Si está depurando demasiado, intente hacer lo contrario.
La razón para crear los tests antes de hacer ninguna implementación es que eso nos permite
centrarnos en lo que queremos alcanzar y sumergirnos totalmente en «cómo hacerlo» después.
Normalmente conduce a mejores abstracciones y a un más fácil mantenimiento de los tests
cuando toque hacer ajustes a las funcionalidades o componentes menos acoplados.
Para resumir, las ventajas de este enfoque son las siguientes:
- Le mantiene centrado en una sola cosa en cada momento, lo que resulta en una mejor planificación e implementación.
- Resulta en más funcionalidades cubiertas por tests, y en mayor detalle. Es decir, si se superan los tests, lo más problable es que no haya nada roto.
A largo plazo normalmente tiene como efecto un buen ahorro de tiempo.
## Qué y cómo probar
Aunque el enfoque de primero los tests descrito arriba tiene sentido para el largo plazo
y proyectos relativamente complejos, sería excesivo para proyectos más simples.
Hay algunas indicaciones de cuándo es apropiado:
- El proyecto ya es grande y complejo.
- Los requisitos del proyecto están empezando a hacerse complejos. El proyecto crece constantemente.
- El proyecto pretende a ser a largo plazo.
- El coste de fallar es demasiado alto.
No hay nada malo en crear tests que cubran el comportamiento de una implementación existente.
- Es un proyecto legado que se va a renovar gradualmente.
- Le han dado un proyecto sobre el que trabajar y no tiene tests.
En algunos casos cualquier forma de testo automatizado sería exagerada:
- El proyecto es sencillo y no se va a volver más complejo.
- Es un proyecto puntual en el que no se seguirá trabajando.
De todas formas, si dispone de tiempo, es bueno automatizar las pruebas también en esos casos.
## Más lecturas
- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.

34
docs/guide-es/test-unit.md

@ -1,25 +1,25 @@
Pruebas unitarias
=================
Tests de Unidad
===============
Un test unitario se encarga de verificar que una unidad simple de código funcione como se espera.
Esto decir, dados diferentes parámetros de entrada, el test verifica que el método
de la clase devuelve el resultado esperado.
Normalmente los tests unitarios son desarrollados por la persona que escribe las clases testeadas.
> Note: Esta sección se encuentra en desarrollo.
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:
Un test de unidad se encarga de verificar que una unidad simple de código funcione como se espera. En la programación orientada a objetos,
la unidad de código más básica es una clase. Por lo tanto, un test de unidad necesita verificar que cada método de la interfaz de la clase funciona apropiadamente.
Esto quiere decir que, dando diferentes parámetros de entrada, el test verifica que el método devuelve el resultado esperado.
Los tests de unidad son normalmente desarrollados por la persona que escribe las clases siendo testeadas.
- [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)
Los tests de unidad en Yii están construidos en base a PHPUnit y opcionalmente, Codeception, por lo que se recomineda consultar su respectiva documentación:
## Ejecución de tests en las plantillas básica y avanzada
- [Documentación de PHPUnit comienza en el capítulo 2](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html).
- [Tests de Unidad con Codeception](http://codeception.com/docs/05-UnitTests).
Si ha empezado con la plantilla avanzada, consulte la [guía de testeo](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-testing.md)
para más detalles sobre la ejecución de tests.
Ejecutar test de unidad de templates básicos y avanzados
--------------------------------------------------------
Si ha empezado con la plantilla básica, consulte la [sección sobre testeo de su README](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing).
Por favor consulta las instrucciones provistas en `apps/advanced/tests/README.md` y `apps/basic/tests/README.md`.
##Tests unitarios del framework
Test de unidad del Framework
----------------------------
Si desea ejecutar tests unitarios para el framework Yii en sí, consulte
«[Comenzando con el desarrollo de Yii 2](https://github.com/yiisoft/yii2/blob/master/docs/internals/getting-started.md)».
Si quieres ejecutar tests de unidad para Yii en sí, consulta
"[Comenzando a desarrollar con Yii 2](https://github.com/yiisoft/yii2/blob/master/docs/internals/getting-started.md)".

3
docs/guide-es/translators.json

@ -1,7 +1,6 @@
[
"Antonio Ramirez",
"Daniel Gómez Pan",
"Enrique Matías Sánchez (Quique)",
"'larnu'",
"Luciano Baraglia"
]
]

6
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](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 <https://www.php.net/manual/en/datetime.createfromformat.php> sobre los formatos soportados.
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 <http://php.net/manual/en/datetime.createfromformat.php> 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.
@ -221,7 +221,7 @@ Este validador comprueba que el fichero subido es el adecuado.
- `maxFiles`: el máximo número de ficheros que determinado atributo puede manejar. Por defecto a 1, lo que significa que la entrada debe de ser sólo un fichero. Si es mayor que 1, entonces la entrada tiene que ser un array conteniendo como máximo el número `maxFiles` de elementos que representan los ficheros a subir.
- `checkExtensionByMimeType`: cuando comprobar la extensión del fichero por el tipo MIME. Si la extensión producida por la comprobación del tipo MIME difiere la extensión del fichero subido, el fichero será considerado como no válido. Por defecto a `true`, significando que realiza este tipo de comprobación.
`FileValidator` es usado con [[yii\web\UploadedFile]]. Por favor, refiérase a la sección [Subida de ficheros](input-file-upload.md) para una completa cobertura sobre la subida de ficheros y llevar a cabo la validación de los ficheros subidos.
`FileValidator` es usado con [[yii\http\UploadedFile]]. Por favor, refiérase a la sección [Subida de ficheros](input-file-upload.md) para una completa cobertura sobre la subida de ficheros y llevar a cabo la validación de los ficheros subidos.
## [[yii\validators\FilterValidator|filter]] <span id="filter"></span>

2
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](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á.
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á.
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).

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

Loading…
Cancel
Save