mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 18:47:33 +08:00 
			
		
		
		
	Merge branch 'master' into 13920-validation-marks-valid-field-as-invalid
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @ -71,7 +71,7 @@ jobs: | ||||
|         run: sudo locale-gen fr_FR.UTF-8 | ||||
|  | ||||
|       - name: Checkout. | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install PHP. | ||||
|         uses: shivammathur/setup-php@v2 | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/ci-mssql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-mssql.yml
									
									
									
									
										vendored
									
									
								
							| @ -43,7 +43,7 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - 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' | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/ci-mysql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-mysql.yml
									
									
									
									
										vendored
									
									
								
							| @ -44,7 +44,7 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout. | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install PHP with extensions. | ||||
|         uses: shivammathur/setup-php@v2 | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/ci-node.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-node.yml
									
									
									
									
										vendored
									
									
								
							| @ -17,7 +17,7 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout. | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install dependencies. | ||||
|         run: composer update $DEFAULT_COMPOSER_FLAGS | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/ci-oracle.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-oracle.yml
									
									
									
									
										vendored
									
									
								
							| @ -35,7 +35,7 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout. | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install PHP with extensions. | ||||
|         uses: shivammathur/setup-php@v2 | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/ci-pgsql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-pgsql.yml
									
									
									
									
										vendored
									
									
								
							| @ -48,7 +48,7 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout. | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install PHP with extensions | ||||
|         uses: shivammathur/setup-php@v2 | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/ci-sqlite.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-sqlite.yml
									
									
									
									
										vendored
									
									
								
							| @ -31,7 +31,7 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout. | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Install PHP with extensions. | ||||
|         uses: shivammathur/setup-php@v2 | ||||
|  | ||||
| @ -121,10 +121,14 @@ class MimeTypeController extends Controller | ||||
|  * Its content is generated from the apache http mime.types file. | ||||
|  * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup | ||||
|  * This file has been placed in the public domain for unlimited redistribution. | ||||
|  * | ||||
|  * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php | ||||
|  * otherwise they will be lost on next build. | ||||
|  */ | ||||
| \$mimeTypes = $array; | ||||
|  | ||||
| if (PHP_VERSION_ID >= 80100) { | ||||
| # fix for bundled libmagic bug, see also https://github.com/yiisoft/yii2/issues/19925 | ||||
| if ((PHP_VERSION_ID >= 80100 && PHP_VERSION_ID < 80122) || (PHP_VERSION_ID >= 80200 && PHP_VERSION_ID < 80209)) { | ||||
|     \$mimeTypes = array_replace(\$mimeTypes, array('xz' => 'application/octet-stream')); | ||||
| } | ||||
|  | ||||
| @ -148,6 +152,9 @@ EOD; | ||||
|  * MIME aliases. | ||||
|  * | ||||
|  * This file contains aliases for MIME types. | ||||
|  * | ||||
|  * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php | ||||
|  * otherwise they will be lost on next build. | ||||
|  */ | ||||
| return $array; | ||||
|  | ||||
| @ -209,6 +216,9 @@ EOD; | ||||
|  * Its content is generated from the apache http mime.types file. | ||||
|  * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup | ||||
|  * This file has been placed in the public domain for unlimited redistribution. | ||||
|  * | ||||
|  * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php | ||||
|  * otherwise they will be lost on next build. | ||||
|  */ | ||||
| return $array; | ||||
|  | ||||
|  | ||||
| @ -76,8 +76,8 @@ | ||||
|         "ezyang/htmlpurifier": "^4.6", | ||||
|         "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", | ||||
|         "bower-asset/jquery": "3.7.*@stable | 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 | ~5.0.8 ", | ||||
|         "bower-asset/punycode": "1.3.* | 2.2.*", | ||||
|         "bower-asset/inputmask": "^5.0.8 ", | ||||
|         "bower-asset/punycode": "^2.2", | ||||
|         "bower-asset/yii2-pjax": "~2.0.1", | ||||
|         "paragonie/random_compat": ">=1" | ||||
|     }, | ||||
|  | ||||
| @ -498,7 +498,7 @@ class HotelController extends Controller | ||||
| как можно раньше. Ниже приведены рекомендуемые практики: | ||||
|  | ||||
| * Если вы разработчик приложения, то вы можете зарегистрировать зависимости в конфигурации вашего приложения. | ||||
|   Как это сделать описано в подразделе [Конфигурация приложения](concept-service-locator.md#application-configurations)  | ||||
|   Как это сделать описано в подразделе [Конфигурация приложения](concept-configurations.md#application-configurations)  | ||||
|   раздела [Конфигурации](concept-configurations.md). | ||||
| * Если вы разработчик распространяемого [расширения](structure-extensions.md), то вы можете зарегистрировать зависимости | ||||
|   в загрузочном классе расширения. | ||||
|  | ||||
| @ -310,7 +310,7 @@ class HelloWorldAction extends Action | ||||
|   [[yii\console\Response::exitStatus|статус выхода]] исполнения команды. | ||||
|  | ||||
| В вышеприведенных примерах, все результаты действий являются строками, которые будут использованы в качестве тела ответа, | ||||
| высланного пользователю. Следующий пример, показывает действие может перенаправить браузер пользователя на новый URL, с помощью | ||||
| высланного пользователю. Следующий пример, показывает как действие может перенаправить браузер пользователя на новый URL, с помощью | ||||
| возврата response объекта (т. к. [[yii\web\Controller::redirect()|redirect()]] метод возвращает response объект): | ||||
|  | ||||
| ```php | ||||
|  | ||||
| @ -5,12 +5,26 @@ Yii Framework 2 Change Log | ||||
| ------------------------ | ||||
|  | ||||
| - Bug #13920: Fixed erroneous validation for specific cases (tim-fischer-maschinensucher) | ||||
| - Bug #19927: Fixed `console\controllers\MessageController` when saving translations to database: fixed FK error when adding new string and language at the same time, checking/regenerating all missing messages and dropping messages for unused languages (atrandafir) | ||||
| - Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1) | ||||
|  | ||||
|  | ||||
| 2.0.49.2 October 12, 2023 | ||||
| ------------------------- | ||||
|  | ||||
| - Bug #19925: Improved PHP version check when handling MIME types (schmunk42) | ||||
|  | ||||
|  | ||||
| 2.0.49.1 October 05, 2023 | ||||
| ------------------------- | ||||
|  | ||||
| - Bug #19940: File Log writer without newline (terabytesoftw) | ||||
| - Bug #19951: Removed unneeded MIME file tests (schmunk42) | ||||
| - Bug #19950: Fix `Query::groupBy(null)` causes error for PHP 8.1: `trim(): Passing null to parameter #1 ($string) of type string is deprecated` (uaoleg) | ||||
| - Bug #19951: Removed unneeded MIME file tests (schmunk42) | ||||
| - Bug #19984: Do not duplicate log messages in memory (lubosdz) | ||||
| - Enh #19780: added pcntl to requirements check (schmunk42) | ||||
|  | ||||
|  | ||||
| 2.0.49 August 29, 2023 | ||||
| ---------------------- | ||||
|  | ||||
|  | ||||
| @ -71,8 +71,8 @@ | ||||
|         "ezyang/htmlpurifier": "^4.6", | ||||
|         "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", | ||||
|         "bower-asset/jquery": "3.7.*@stable | 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 | ~5.0.8 ", | ||||
|         "bower-asset/punycode": "1.3.* | 2.2.*", | ||||
|         "bower-asset/inputmask": "^5.0.8 ", | ||||
|         "bower-asset/punycode": "^2.2", | ||||
|         "bower-asset/yii2-pjax": "~2.0.1", | ||||
|         "paragonie/random_compat": ">=1" | ||||
|     }, | ||||
|  | ||||
| @ -354,16 +354,6 @@ EOD; | ||||
|             $currentMessages[$row['category']][$row['id']] = $row['message']; | ||||
|         } | ||||
|          | ||||
|         $currentLanguages = []; | ||||
|         $rows = (new Query())->select(['language'])->from($messageTable)->groupBy('language')->all($db); | ||||
|         foreach ($rows as $row) { | ||||
|             $currentLanguages[] = $row['language']; | ||||
|         } | ||||
|         $missingLanguages = []; | ||||
|         if (!empty($currentLanguages)) { | ||||
|             $missingLanguages = array_diff($languages, $currentLanguages); | ||||
|         } | ||||
|  | ||||
|         $new = []; | ||||
|         $obsolete = []; | ||||
|  | ||||
| @ -372,89 +362,130 @@ EOD; | ||||
|  | ||||
|             if (isset($currentMessages[$category])) { | ||||
|                 $new[$category] = array_diff($msgs, $currentMessages[$category]); | ||||
|                 // obsolete messages per category | ||||
|                 $obsolete += array_diff($currentMessages[$category], $msgs); | ||||
|             } else { | ||||
|                 $new[$category] = $msgs; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         // obsolete categories | ||||
|         foreach (array_diff(array_keys($currentMessages), array_keys($messages)) as $category) { | ||||
|             $obsolete += $currentMessages[$category]; | ||||
|         } | ||||
|  | ||||
|         if (!$removeUnused) { | ||||
|             foreach ($obsolete as $pk => $msg) { | ||||
|                 // skip already marked unused | ||||
|                 if (strncmp($msg, '@@', 2) === 0 && substr($msg, -2) === '@@') { | ||||
|                     unset($obsolete[$pk]); | ||||
|                 } | ||||
|             } | ||||
|         }         | ||||
|          | ||||
|         $obsolete = array_keys($obsolete); | ||||
|         $this->stdout('Inserting new messages...'); | ||||
|         $savedFlag = false; | ||||
|         $insertCount = 0; | ||||
|  | ||||
|         foreach ($new as $category => $msgs) { | ||||
|             foreach ($msgs as $msg) { | ||||
|                 $savedFlag = true; | ||||
|                 $lastPk = $db->schema->insert($sourceMessageTable, ['category' => $category, 'message' => $msg]); | ||||
|                 foreach ($languages as $language) { | ||||
|                     $db->createCommand() | ||||
|                        ->insert($messageTable, ['id' => $lastPk['id'], 'language' => $language]) | ||||
|                        ->execute(); | ||||
|                 } | ||||
|                 $insertCount++; | ||||
|                 $db->schema->insert($sourceMessageTable, ['category' => $category, 'message' => $msg]); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         if (!empty($missingLanguages)) { | ||||
|             $updatedMessages = []; | ||||
|             $rows = (new Query())->select(['id', 'category', 'message'])->from($sourceMessageTable)->all($db); | ||||
|             foreach ($rows as $row) { | ||||
|                 $updatedMessages[$row['category']][$row['id']] = $row['message']; | ||||
|             } | ||||
|             foreach ($updatedMessages as $category => $msgs) { | ||||
|                 foreach ($msgs as $id => $msg) { | ||||
|                     $savedFlag = true; | ||||
|                     foreach ($missingLanguages as $language) { | ||||
|                         $db->createCommand() | ||||
|                             ->insert($messageTable, ['id' => $id, 'language' => $language]) | ||||
|                             ->execute(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         $this->stdout($insertCount ? "{$insertCount} saved.\n" : "Nothing to save.\n"); | ||||
|          | ||||
|         $this->stdout($savedFlag ? "saved.\n" : "Nothing to save.\n"); | ||||
|         $this->stdout($removeUnused ? 'Deleting obsoleted messages...' : 'Updating obsoleted messages...'); | ||||
|  | ||||
|         if (empty($obsolete)) { | ||||
|             $this->stdout("Nothing obsoleted...skipped.\n"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if ($removeUnused) { | ||||
|             $db->createCommand() | ||||
|                ->delete($sourceMessageTable, ['in', 'id', $obsolete]) | ||||
|                ->execute(); | ||||
|             $this->stdout("deleted.\n"); | ||||
|         } elseif ($markUnused) { | ||||
|             $rows = (new Query()) | ||||
|                 ->select(['id', 'message']) | ||||
|                 ->from($sourceMessageTable) | ||||
|                 ->where(['in', 'id', $obsolete]) | ||||
|                 ->all($db); | ||||
|         if ($obsolete) { | ||||
|             if ($removeUnused) { | ||||
|                 $affected = $db->createCommand() | ||||
|                    ->delete($sourceMessageTable, ['in', 'id', array_keys($obsolete)]) | ||||
|                    ->execute(); | ||||
|                 $this->stdout("{$affected} deleted.\n"); | ||||
|             } elseif ($markUnused) { | ||||
|                 $marked=0; | ||||
|                 $rows = (new Query()) | ||||
|                     ->select(['id', 'message']) | ||||
|                     ->from($sourceMessageTable) | ||||
|                     ->where(['in', 'id', array_keys($obsolete)]) | ||||
|                     ->all($db); | ||||
|      | ||||
|             foreach ($rows as $row) { | ||||
|                 $db->createCommand()->update( | ||||
|                     $sourceMessageTable, | ||||
|                     ['message' => '@@' . $row['message'] . '@@'], | ||||
|                     ['id' => $row['id']] | ||||
|                 )->execute(); | ||||
|                 foreach ($rows as $row) { | ||||
|                     $marked++; | ||||
|                     $db->createCommand()->update( | ||||
|                         $sourceMessageTable, | ||||
|                         ['message' => '@@' . $row['message'] . '@@'], | ||||
|                         ['id' => $row['id']] | ||||
|                     )->execute(); | ||||
|                 } | ||||
|                 $this->stdout("{$marked} updated.\n"); | ||||
|             } else { | ||||
|                 $this->stdout("kept untouched.\n"); | ||||
|             } | ||||
|             $this->stdout("updated.\n"); | ||||
|         } else { | ||||
|             $this->stdout("kept untouched.\n"); | ||||
|         } | ||||
|          | ||||
|         // get fresh message id list | ||||
|         $freshMessagesIds = []; | ||||
|         $rows = (new Query())->select(['id'])->from($sourceMessageTable)->all($db); | ||||
|         foreach ($rows as $row) { | ||||
|             $freshMessagesIds[] = $row['id']; | ||||
|         } | ||||
|              | ||||
|         $this->stdout("Generating missing rows..."); | ||||
|         $generatedMissingRows = []; | ||||
|          | ||||
|         foreach ($languages as $language) { | ||||
|           $count = 0; | ||||
|            | ||||
|           // get list of ids of translations for this language | ||||
|           $msgRowsIds = []; | ||||
|           $msgRows = (new Query())->select(['id'])->from($messageTable)->where([ | ||||
|               'language'=>$language, | ||||
|           ])->all($db); | ||||
|           foreach ($msgRows as $row) { | ||||
|               $msgRowsIds[] = $row['id']; | ||||
|           } | ||||
|            | ||||
|           // insert missing | ||||
|           foreach ($freshMessagesIds as $id) { | ||||
|             if (!in_array($id, $msgRowsIds)) { | ||||
|               $db->createCommand() | ||||
|                  ->insert($messageTable, ['id' => $id, 'language' => $language]) | ||||
|                  ->execute(); | ||||
|               $count++; | ||||
|             } | ||||
|           } | ||||
|           if ($count) { | ||||
|             $generatedMissingRows[] = "{$count} for {$language}"; | ||||
|           } | ||||
|         } | ||||
|          | ||||
|         $this->stdout($generatedMissingRows ? implode(", ", $generatedMissingRows).".\n" : "Nothing to do.\n"); | ||||
|          | ||||
|         $this->stdout("Dropping unused languages..."); | ||||
|         $droppedLanguages=[]; | ||||
|          | ||||
|         $currentLanguages = []; | ||||
|         $rows = (new Query())->select(['language'])->from($messageTable)->groupBy('language')->all($db); | ||||
|         foreach ($rows as $row) { | ||||
|             $currentLanguages[] = $row['language']; | ||||
|         } | ||||
|          | ||||
|         foreach ($currentLanguages as $currentLanguage) { | ||||
|           if (!in_array($currentLanguage, $languages)) { | ||||
|             $deleted=$db->createCommand()->delete($messageTable, "language=:language", [ | ||||
|                 'language'=>$currentLanguage, | ||||
|             ])->execute(); | ||||
|             $droppedLanguages[] = "removed {$deleted} rows for $currentLanguage"; | ||||
|           } | ||||
|         } | ||||
|          | ||||
|         $this->stdout($droppedLanguages ? implode(", ", $droppedLanguages).".\n" : "Nothing to do.\n"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -80,7 +80,7 @@ class ServeController extends Controller | ||||
|         } | ||||
|         $this->stdout("Quit the server with CTRL-C or COMMAND-C.\n"); | ||||
|  | ||||
|         passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" $router"); | ||||
|         passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" \"$router\""); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -1787,4 +1787,57 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface | ||||
|  | ||||
|         return $newValue !== $oldValue; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Eager loads related models for the already loaded primary models. | ||||
|      * | ||||
|      * Helps to reduce the number of queries performed against database if some related models are only used | ||||
|      * when a specific condition is met. For example: | ||||
|      * | ||||
|      * ```php | ||||
|      * $customers = Customer::find()->where(['country_id' => 123])->all(); | ||||
|      * if (Yii:app()->getUser()->getIdentity()->canAccessOrders()) { | ||||
|      *     Customer::loadRelationsFor($customers, 'orders.items'); | ||||
|      * } | ||||
|      * ``` | ||||
|      * | ||||
|      * @param array|ActiveRecordInterface[] $models array of primary models. Each model should have the same type and can be: | ||||
|      * - an active record instance; | ||||
|      * - active record instance represented by array (i.e. active record was loaded using [[ActiveQuery::asArray()]]). | ||||
|      * @param string|array $relationNames the names of the relations of primary models to be loaded from database. See [[ActiveQueryInterface::with()]] on how to specify this argument. | ||||
|      * @param bool $asArray whether to load each related model as an array or an object (if the relation itself does not specify that). | ||||
|      * @since 2.0.49 | ||||
|      */ | ||||
|     public static function loadRelationsFor(&$models, $relationNames, $asArray = false) | ||||
|     { | ||||
|         // ActiveQueryTrait::findWith() called below assumes $models array is non-empty. | ||||
|         if (empty($models)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         static::find()->asArray($asArray)->findWith((array)$relationNames, $models); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Eager loads related models for the already loaded primary model. | ||||
|      * | ||||
|      * Helps to reduce the number of queries performed against database if some related models are only used | ||||
|      * when a specific condition is met. For example: | ||||
|      * | ||||
|      * ```php | ||||
|      * $customer = Customer::find()->where(['id' => 123])->one(); | ||||
|      * if (Yii:app()->getUser()->getIdentity()->canAccessOrders()) { | ||||
|      *     $customer->loadRelations('orders.items'); | ||||
|      * } | ||||
|      * ``` | ||||
|      * | ||||
|      * @param string|array $relationNames the names of the relations of this model to be loaded from database. See [[ActiveQueryInterface::with()]] on how to specify this argument. | ||||
|      * @param bool $asArray whether to load each relation as an array or an object (if the relation itself does not specify that). | ||||
|      * @since 2.0.49 | ||||
|      */ | ||||
|     public function loadRelations($relationNames, $asArray = false) | ||||
|     { | ||||
|         $models = [$this]; | ||||
|         static::loadRelationsFor($models, $relationNames, $asArray); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,6 +3,9 @@ | ||||
|  * MIME aliases. | ||||
|  * | ||||
|  * This file contains aliases for MIME types. | ||||
|  * | ||||
|  * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php | ||||
|  * otherwise they will be lost on next build. | ||||
|  */ | ||||
| return [ | ||||
|     'text/rtf' => 'application/rtf', | ||||
|  | ||||
| @ -8,6 +8,9 @@ | ||||
|  * Its content is generated from the apache http mime.types file. | ||||
|  * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup | ||||
|  * This file has been placed in the public domain for unlimited redistribution. | ||||
|  * | ||||
|  * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php | ||||
|  * otherwise they will be lost on next build. | ||||
|  */ | ||||
| return [ | ||||
|     'application/andrew-inset' => 'ez', | ||||
|  | ||||
| @ -7,6 +7,9 @@ | ||||
|  * Its content is generated from the apache http mime.types file. | ||||
|  * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup | ||||
|  * This file has been placed in the public domain for unlimited redistribution. | ||||
|  * | ||||
|  * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php | ||||
|  * otherwise they will be lost on next build. | ||||
|  */ | ||||
| $mimeTypes = [ | ||||
|     123 => 'application/vnd.lotus-1-2-3', | ||||
|  | ||||
| @ -107,9 +107,8 @@ class FileTarget extends Target | ||||
|     public function export() | ||||
|     { | ||||
|         $text = implode("\n", array_map([$this, 'formatMessage'], $this->messages)) . "\n"; | ||||
|         $trimmedText = trim($text); | ||||
|  | ||||
|         if (empty($trimmedText)) { | ||||
|         if (trim($text) === '') { | ||||
|             return; // No messages to export, so we exit the function early | ||||
|         } | ||||
|  | ||||
|  | ||||
| @ -75,8 +75,8 @@ return [ | ||||
|     '{attribute} must be greater than or equal to "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 크거나 같아야 합니다.', | ||||
|     '{attribute} must be less than "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 작아야 합니다.', | ||||
|     '{attribute} must be less than or equal to "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 작거나 같아야 합니다.', | ||||
|     '{attribute} must be no greater than {max}.' => '{attribute}는 "{compareValue}" 보다 클 수 없습니다.', | ||||
|     '{attribute} must be no less than {min}.' => '{attribute}는 "{compareValue}" 보다 작을 수 없습니다.', | ||||
|     '{attribute} must be no greater than {max}.' => '{attribute}는 "{max}" 보다 클 수 없습니다.', | ||||
|     '{attribute} must be no less than {min}.' => '{attribute}는 "{min}" 보다 작을 수 없습니다.', | ||||
|     '{attribute} must be repeated exactly.' => '{attribute}는 정확하게 반복합니다.', | ||||
|     '{attribute} must not be equal to "{compareValue}".' => '{attribute}는 "{compareValue}"와 같을 수 없습니다.', | ||||
|     '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '{attribute}는 최소 {min}자 이어야합니다.', | ||||
|  | ||||
| @ -21,7 +21,7 @@ class MaskedInputAsset extends AssetBundle | ||||
| { | ||||
|     public $sourcePath = '@bower/inputmask/dist'; | ||||
|     public $js = [ | ||||
|         'jquery.inputmask.bundle.js', | ||||
|         'jquery.inputmask.js', | ||||
|     ]; | ||||
|     public $depends = [ | ||||
|         'yii\web\YiiAsset', | ||||
|  | ||||
| @ -2225,6 +2225,53 @@ abstract class ActiveRecordTest extends DatabaseTestCase | ||||
|         $attr = 'model2.doesNotExist.attr1'; | ||||
|         $this->assertEquals($model->generateAttributeLabel($attr), $model->getAttributeLabel($attr)); | ||||
|     } | ||||
|  | ||||
|     public function testLoadRelations() | ||||
|     { | ||||
|         // Test eager loading relations for multiple primary models using loadRelationsFor(). | ||||
|         /** @var Customer[] $customers */ | ||||
|         $customers = Customer::find()->all(); | ||||
|         Customer::loadRelationsFor($customers, ['orders.items']); | ||||
|         foreach ($customers as $customer) { | ||||
|             $this->assertTrue($customer->isRelationPopulated('orders')); | ||||
|             foreach ($customer->orders as $order) { | ||||
|                 $this->assertTrue($order->isRelationPopulated('items')); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Test eager loading relations as arrays. | ||||
|         /** @var array $customers */ | ||||
|         $customers = Customer::find()->asArray(true)->all(); | ||||
|         Customer::loadRelationsFor($customers, ['orders.items' => function ($query) { $query->asArray(false); }], true); | ||||
|         foreach ($customers as $customer) { | ||||
|             $this->assertTrue(isset($customer['orders'])); | ||||
|             $this->assertTrue(is_array($customer['orders'])); | ||||
|             foreach ($customer['orders'] as $order) { | ||||
|                 $this->assertTrue(is_array($order)); | ||||
|                 $this->assertTrue(isset($order['items'])); | ||||
|                 $this->assertTrue(is_array($order['items'])); | ||||
|                 foreach ($order['items'] as $item) { | ||||
|                     $this->assertFalse(is_array($item)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Test eager loading relations for a single primary model using loadRelations(). | ||||
|         /** @var Customer $customer */ | ||||
|         $customer = Customer::find()->where(['id' => 1])->one(); | ||||
|         $customer->loadRelations('orders.items'); | ||||
|         $this->assertTrue($customer->isRelationPopulated('orders')); | ||||
|         foreach ($customer->orders as $order) { | ||||
|             $this->assertTrue($order->isRelationPopulated('items')); | ||||
|         } | ||||
|  | ||||
|         // Test eager loading previously loaded relation (relation value should be replaced with a new value loaded from database). | ||||
|         /** @var Customer $customer */ | ||||
|         $customer = Customer::find()->where(['id' => 2])->with(['orders' => function ($query) { $query->orderBy(['id' => SORT_ASC]); }])->one(); | ||||
|         $this->assertTrue($customer->orders[0]->id < $customer->orders[1]->id, 'Related models should be sorted by ID in ascending order.'); | ||||
|         $customer->loadRelations(['orders' => function ($query) { $query->orderBy(['id' => SORT_DESC]); }]); | ||||
|         $this->assertTrue($customer->orders[0]->id > $customer->orders[1]->id, 'Related models should be sorted by ID in descending order.'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| class LabelTestModel1 extends \yii\db\ActiveRecord | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Tim Fischer
					Tim Fischer