Skip to content

Commit 0294cf4

Browse files
authored
Merge pull request #20058 from terabytesoftw/sinc-to-master-branch
Sinc to master branch.
2 parents 203952f + 5f5745b commit 0294cf4

File tree

16 files changed

+1122
-138
lines changed

16 files changed

+1122
-138
lines changed

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Autodetect text files
2-
* text=auto
2+
* text=auto eol=lf
33

44
# ...Unless the name matches the following overriding patterns
55

docs/internals-fa/core-code-style.md

Lines changed: 126 additions & 124 deletions
Large diffs are not rendered by default.

framework/CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,25 @@ Yii Framework 2 Change Log
44
2.2 under development
55
------------------------
66

7-
- Bug #20040: Fix type `boolean` in `MSSQL` (terabytesoftw)
87
- Chg #19902: Remove support for CUBRID (mtangoo)
98
- Chg #19891: Remove XCache and ZendDataCache support (mtangoo)
109

1110

1211
2.0.50 under development
1312
------------------------
14-
13+
- Bug #20045: Fix type `boolean` in `MySQL` (terabytesoftw)
14+
- Bug #20040: Fix type `boolean` in `MSSQL` (terabytesoftw)
1515
- Bug #20005: Fix `yii\console\controllers\ServeController` to specify the router script (terabytesoftw)
1616
- Bug #19060: Fix `yii\widgets\Menu` bug when using Closure for active item and adding additional tests in `tests\framework\widgets\MenuTest` (atrandafir)
1717
- Bug #13920: Fixed erroneous validation for specific cases (tim-fischer-maschinensucher)
1818
- 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)
1919
- Bug #20002: Fixed superfluous query on HEAD request in serializer (xicond)
2020
- Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1)
21+
- Enh #20030: Improve performance of handling `ErrorHandler::$memoryReserveSize` (antonshevelev, rob006)
22+
- Enh #20042: Add empty array check to `ActiveQueryTrait::findWith()` (renkas)
23+
- Enh #20032: Added `yii\helpers\BaseStringHelper::mask()` method for string masking with multibyte support (salehhashemi1992)
24+
- Enh #20034: Added `yii\helpers\BaseStringHelper::findBetween()` to retrieve a substring that lies between two strings (salehhashemi1992)
25+
2126

2227
2.0.49.2 October 12, 2023
2328
-------------------------

framework/base/ErrorHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function register()
9494
set_error_handler([$this, 'handleError']);
9595
}
9696
if ($this->memoryReserveSize > 0) {
97-
$this->_memoryReserve = str_pad('', $this->memoryReserveSize, 'x');
97+
$this->_memoryReserve = str_repeat('x', $this->memoryReserveSize);
9898
}
9999
// to restore working directory in shutdown handler
100100
if (PHP_SAPI !== 'cli') {

framework/db/ActiveQueryTrait.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ protected function createModels($rows)
135135
*/
136136
public function findWith($with, &$models)
137137
{
138+
if (empty($models)) {
139+
return;
140+
}
141+
138142
$primaryModel = reset($models);
139143
if (!$primaryModel instanceof ActiveRecordInterface) {
140144
/* @var $modelClass ActiveRecordInterface */

framework/db/mssql/Schema.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ protected function resolveTableNames($table, $name)
375375
*/
376376
protected function loadColumnSchema($info)
377377
{
378+
$isVersion2017orLater = version_compare($this->db->getSchema()->getServerVersion(), '14', '>=');
378379
$column = $this->createColumnSchema();
379380

380381
$column->name = $info['column_name'];
@@ -395,7 +396,7 @@ protected function loadColumnSchema($info)
395396
$column->type = $this->typeMap[$type];
396397
}
397398

398-
if ($type === 'bit') {
399+
if ($isVersion2017orLater && $type === 'bit') {
399400
$column->type = 'boolean';
400401
}
401402

@@ -406,6 +407,10 @@ protected function loadColumnSchema($info)
406407
if (isset($values[1])) {
407408
$column->scale = (int) $values[1];
408409
}
410+
411+
if ($isVersion2017orLater === false) {
412+
$column->type = $this->booleanTypeLegacy($column->size, $type);
413+
}
409414
}
410415
}
411416

@@ -811,4 +816,27 @@ public function createColumnSchemaBuilder($type, $length = null)
811816
{
812817
return Yii::createObject(ColumnSchemaBuilder::class, [$type, $length, $this->db]);
813818
}
819+
820+
/**
821+
* Assigns a type boolean for the column type bit, for legacy versions of MSSQL.
822+
*
823+
* @param int $size column size.
824+
* @param string $type column type.
825+
*
826+
* @return string column type.
827+
*/
828+
private function booleanTypeLegacy($size, $type)
829+
{
830+
if ($size === 1 && ($type === 'tinyint' || $type === 'bit')) {
831+
return 'boolean';
832+
} elseif ($type === 'bit') {
833+
if ($size > 32) {
834+
return 'bigint';
835+
} elseif ($size === 32) {
836+
return 'integer';
837+
}
838+
}
839+
840+
return $type;
841+
}
814842
}

framework/db/mysql/Schema.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ protected function loadColumnSchema($info)
279279
if (isset($values[1])) {
280280
$column->scale = (int) $values[1];
281281
}
282-
if ($column->size === 1 && $type === 'bit') {
282+
if ($column->size === 1 && ($type === 'tinyint' || $type === 'bit')) {
283283
$column->type = 'boolean';
284284
} elseif ($type === 'bit') {
285285
if ($column->size > 32) {

framework/helpers/BaseStringHelper.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,63 @@ public static function mb_ucwords($string, $encoding = 'UTF-8')
497497

498498
return implode('', $parts);
499499
}
500+
501+
/**
502+
* Masks a portion of a string with a repeated character.
503+
* This method is multibyte-safe.
504+
*
505+
* @param string $string The input string.
506+
* @param int $start The starting position from where to begin masking.
507+
* This can be a positive or negative integer.
508+
* Positive values count from the beginning,
509+
* negative values count from the end of the string.
510+
* @param int $length The length of the section to be masked.
511+
* The masking will start from the $start position
512+
* and continue for $length characters.
513+
* @param string $mask The character to use for masking. The default is '*'.
514+
* @return string The masked string.
515+
*/
516+
public static function mask($string, $start, $length, $mask = '*') {
517+
$strLength = mb_strlen($string, 'UTF-8');
518+
519+
// Return original string if start position is out of bounds
520+
if ($start >= $strLength || $start < -$strLength) {
521+
return $string;
522+
}
523+
524+
$masked = mb_substr($string, 0, $start, 'UTF-8');
525+
$masked .= str_repeat($mask, abs($length));
526+
$masked .= mb_substr($string, $start + abs($length), null, 'UTF-8');
527+
528+
return $masked;
529+
}
530+
531+
/**
532+
* Returns the portion of the string that lies between the first occurrence of the start string
533+
* and the last occurrence of the end string after that.
534+
*
535+
* @param string $string The input string.
536+
* @param string $start The string marking the start of the portion to extract.
537+
* @param string $end The string marking the end of the portion to extract.
538+
* @return string|null The portion of the string between the first occurrence of
539+
* start and the last occurrence of end, or null if either start or end cannot be found.
540+
*/
541+
public static function findBetween($string, $start, $end)
542+
{
543+
$startPos = mb_strpos($string, $start);
544+
545+
if ($startPos === false) {
546+
return null;
547+
}
548+
549+
// Cut the string from the start position
550+
$subString = mb_substr($string, $startPos + mb_strlen($start));
551+
$endPos = mb_strrpos($subString, $end);
552+
553+
if ($endPos === false) {
554+
return null;
555+
}
556+
557+
return mb_substr($subString, 0, $endPos);
558+
}
500559
}

framework/messages/fa/yii.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
'"{attribute}" does not support operator "{operator}".' => '"{attribute}" از عملگر "{operator}" پشتیبانی نمی‌کند.',
2828
'(not set)' => '(تنظیم نشده)',
2929
'Action not found.' => 'عمل یافت نشد.',
30-
'Aliases available: {aliases}' => 'نام مستعارهای موجود: {aliases}',
30+
'Aliases available: {aliases}' => 'نام‌های مستعار موجود: {aliases}',
3131
'An internal server error occurred.' => 'خطای داخلی سرور رخ داده است.',
3232
'Are you sure you want to delete this item?' => 'آیا اطمینان به حذف این مورد دارید؟',
3333
'Condition for "{attribute}" should be either a value or valid operator specification.' => 'شرط برای "{attribute}" باید یک مقدار یا مشخصه‌ی عملگر معتبر باشد.',
@@ -49,11 +49,11 @@
4949
'Page not found.' => 'صفحه‌ای یافت نشد.',
5050
'Please fix the following errors:' => 'لطفاً خطاهای زیر را رفع نمائید:',
5151
'Please upload a file.' => 'لطفاً یک فایل آپلود کنید.',
52-
'Showing <b>{begin, number}-{end, number}</b> of <b>{totalCount, number}</b> {totalCount, plural, one{item} other{items}}.' => 'نمایش <b>{begin, number} تا {end, number}</b> مورد از کل <b>{totalCount, number}</b> مورد.',
52+
'Showing <b>{begin, number}-{end, number}</b> of <b>{totalCount, number}</b> {totalCount, plural, one{item} other{items}}.' => 'نمایش <b>{begin, number}</b> تا <b>{end, number}</b> مورد از کل <b>{totalCount, number}</b> مورد.',
5353
'The combination {values} of {attributes} has already been taken.' => 'مقدار {values} از {attributes} قبلاً گرفته شده است.',
5454
'The file "{file}" is not an image.' => 'فایل "{file}" یک تصویر نیست.',
5555
'The file "{file}" is too big. Its size cannot exceed {formattedLimit}.' => 'حجم فایل "{file}" بسیار بیشتر می‌باشد. حجم آن نمی‌تواند از {formattedLimit} بیشتر باشد.',
56-
'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => 'حجم فایل "{file}" بسیار کم می‌باشد. حجم آن‌نمی تواند از {formattedLimit} کمتر باشد.',
56+
'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.' => 'حجم فایل "{file}" بسیار کم می‌باشد. حجم آن نمی‌تواند از {formattedLimit} کمتر باشد.',
5757
'The format of {attribute} is invalid.' => 'قالب {attribute} نامعتبر است.',
5858
'The format of {filter} is invalid.' => 'قالب {filter} نامعتبر است.',
5959
'The image "{file}" is too large. The height cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.' => 'تصویر "{file}" خیلی بزرگ است. ارتفاع نمی‌تواند بزرگتر از {limit, number} پیکسل باشد.',
@@ -87,7 +87,7 @@
8787
'{attribute} is invalid.' => '{attribute} معتبر نیست.',
8888
'{attribute} is not a valid URL.' => '{attribute} یک URL معتبر نیست.',
8989
'{attribute} is not a valid email address.' => '{attribute} یک آدرس ایمیل معتبر نیست.',
90-
'{attribute} is not in the allowed range.' => '{attribute} در محدوده مجاز نمی‎باشد.',
90+
'{attribute} is not in the allowed range.' => '{attribute} در محدوده مجاز نمی‌باشد.',
9191
'{attribute} must be "{requiredValue}".' => '{attribute} باید "{requiredValue}" باشد.',
9292
'{attribute} must be a number.' => '{attribute} باید یک عدد باشد.',
9393
'{attribute} must be a string.' => '{attribute} باید یک رشته باشد.',

tests/framework/caching/DbDependencyTest.php

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class DbDependencyTest extends DatabaseTestCase
2121
*/
2222
protected $driverName = 'sqlite';
2323

24-
2524
/**
2625
* {@inheritdoc}
2726
*/
@@ -39,11 +38,14 @@ protected function setUp(): void
3938
$db->createCommand()->insert('dependency_item', ['value' => 'initial'])->execute();
4039
}
4140

42-
public function testIsChanged(): void
41+
public function testQueryOneIsExecutedWhenQueryCacheEnabled()
4342
{
4443
$db = $this->getConnection(false);
4544
$cache = new ArrayCache();
4645

46+
// Enable the query cache
47+
$db->enableQueryCache = true;
48+
4749
$dependency = new DbDependency();
4850
$dependency->db = $db;
4951
$dependency->sql = 'SELECT [[id]] FROM {{dependency_item}} ORDER BY [[id]] DESC LIMIT 1';
@@ -56,4 +58,39 @@ public function testIsChanged(): void
5658

5759
$this->assertTrue($dependency->isChanged($cache));
5860
}
61+
62+
public function testQueryOneIsExecutedWhenQueryCacheDisabled()
63+
{
64+
$db = $this->getConnection(false);
65+
$cache = new ArrayCache();
66+
67+
// Disable the query cache
68+
$db->enableQueryCache = false;
69+
70+
$dependency = new DbDependency();
71+
$dependency->db = $db;
72+
$dependency->sql = 'SELECT [[id]] FROM {{dependency_item}} ORDER BY [[id]] DESC LIMIT 1';
73+
$dependency->reusable = false;
74+
75+
$dependency->evaluateDependency($cache);
76+
$this->assertFalse($dependency->isChanged($cache));
77+
78+
$db->createCommand()->insert('dependency_item', ['value' => 'new'])->execute();
79+
80+
$this->assertTrue($dependency->isChanged($cache));
81+
}
82+
83+
public function testMissingSqlThrowsException()
84+
{
85+
$this->expectException('\yii\base\InvalidConfigException');
86+
87+
$db = $this->getConnection(false);
88+
$cache = new ArrayCache();
89+
90+
$dependency = new DbDependency();
91+
$dependency->db = $db;
92+
$dependency->sql = null;
93+
94+
$dependency->evaluateDependency($cache);
95+
}
5996
}

0 commit comments

Comments
 (0)