diff --git a/CHANGELOG.md b/CHANGELOG.md index be56a9439..ce09d97e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 redis extension Change Log 2.0.20 under development ------------------------ +- Bug #251: Fixed string escaping issue of `\032` in LuaScriptBuilder (vistart) - Bug #270: Prevent null parameter on `mb_strlen` to avoid PHP 8.4 implicity nullable types deprecation (tehmaestro) diff --git a/src/LuaScriptBuilder.php b/src/LuaScriptBuilder.php index 489c20b7e..b303d64f4 100644 --- a/src/LuaScriptBuilder.php +++ b/src/LuaScriptBuilder.php @@ -237,7 +237,7 @@ private function quoteValue($str) return $str; } - return "'" . addcslashes($str, "\000\n\r\\\032\047") . "'"; + return "'" . addcslashes($str, "\000\n\r\\\047") . "'"; } /** diff --git a/tests/ActiveRecordTest.php b/tests/ActiveRecordTest.php index 2013a8fd1..de22c3f7b 100644 --- a/tests/ActiveRecordTest.php +++ b/tests/ActiveRecordTest.php @@ -6,6 +6,7 @@ use yii\redis\LuaScriptBuilder; use yiiunit\extensions\redis\data\ar\ActiveRecord; use yiiunit\extensions\redis\data\ar\Customer; +use yiiunit\extensions\redis\data\ar\CustomerBinary; use yiiunit\extensions\redis\data\ar\OrderItem; use yiiunit\extensions\redis\data\ar\Order; use yiiunit\extensions\redis\data\ar\Item; @@ -19,6 +20,11 @@ class ActiveRecordTest extends TestCase { use ActiveRecordTestTrait; + public $fkBinary1; + public $fkBinary2; + public $fkBinary3; + public $userBinary; + public $fkBinaryNonExist; /** * @return string @@ -28,6 +34,11 @@ public function getCustomerClass() return Customer::className(); } + public function getCustomerBinaryClass() + { + return CustomerBinary::className(); + } + /** * @return string */ @@ -164,6 +175,21 @@ public function setUp() $orderItem->setAttributes(['order_id' => 3, 'item_id' => 2, 'quantity' => 1, 'subtotal' => 40.0], false); $orderItem->save(false); + $this->fkBinary1 = hex2bin(str_replace([' ', '-'], '', '51a4e62e-1b1a-56c9-e9e5-9efe21f55276')); + $this->fkBinary2 = hex2bin(str_replace([' ', '-'], '', '51a4e62e-1b1a-56c9-e9e6-9efe21f55276')); + $this->fkBinary3 = hex2bin(str_replace([' ', '-'], '', '51a4e62e-1b1a-56c9-e9e7-9efe21f55276')); + $this->userBinary = hex2bin(str_replace([' ', '-'], '', '51a4e62e-1b1a-56c9-e9e5-9efe21f55277')); + $this->fkBinaryNonExist = hex2bin(str_replace([' ', '-'], '', '51a4e62e-1b1a-56c9-e9e5-9efe21f55278')); + $customer = new CustomerBinary(); + $customer->setAttributes(['guid' => $this->fkBinary1, 'user_guid' => $this->userBinary, 'email' => 'user1@example.com', 'name' => 'user1', 'address' => 'address1', 'status' => 1, 'profile_id' => 1], false); + $customer->save(false); + $customer = new CustomerBinary(); + $customer->setAttributes(['guid' => $this->fkBinary2, 'user_guid' => $this->userBinary, 'email' => 'user2@example.com', 'name' => 'user2', 'address' => 'address2', 'status' => 1, 'profile_id' => null], false); + $customer->save(false); + $customer = new CustomerBinary(); + $customer->setAttributes(['guid' => $this->fkBinary3, 'user_guid' => $this->userBinary, 'email' => 'user3@example.com', 'name' => 'user3', 'address' => 'address3', 'status' => 2, 'profile_id' => 2], false); + $customer->save(false); + } /** @@ -705,4 +731,64 @@ public function testFind() $this->assertCount(2, $customerClass::find()->active()->all()); $this->assertEquals(2, $customerClass::find()->active()->count()); } + + /** + * @group binary + */ + public function testFindBinaryPk() + { + /* @var $customerClass \yii\db\ActiveRecordInterface */ + $customerClass = $this->getCustomerBinaryClass(); + + // find one + /* @var $this TestCase|ActiveRecordTestTrait */ + $result = $customerClass::find(); + $this->assertInstanceOf('\\yii\\db\\ActiveQueryInterface', $result); + $customer = $result->one(); + $this->assertInstanceOf($customerClass, $customer); + + // find all + $customers = $customerClass::find()->all(); + $this->assertCount(3, $customers); + $this->assertInstanceOf($customerClass, $customers[0]); + $this->assertInstanceOf($customerClass, $customers[1]); + $this->assertInstanceOf($customerClass, $customers[2]); + + // find by a single primary key + $customer = $customerClass::findOne($this->fkBinary1); + $this->assertInstanceOf($customerClass, $customer); + $this->assertEquals('user1', $customer->name); + $customer = $customerClass::findOne($this->fkBinaryNonExist); + $this->assertNull($customer); + $customer = $customerClass::findOne(['guid' => [$this->fkBinary1, $this->fkBinaryNonExist]]); + $this->assertInstanceOf($customerClass, $customer); + $customer = $customerClass::find()->where(['guid' => [$this->fkBinary1, $this->fkBinaryNonExist]])->one(); + $this->assertNotNull($customer); + + // find by column values + $customer = $customerClass::findOne(['guid' => $this->fkBinary2, 'name' => 'user2']); + $this->assertInstanceOf($customerClass, $customer); + $this->assertEquals('user2', $customer->name); + $customer = $customerClass::findOne(['guid' => $this->fkBinary2, 'name' => 'user1']); + $this->assertNull($customer); + $customer = $customerClass::findOne(['guid' => $this->fkBinaryNonExist]); + $this->assertNull($customer); + $customer = $customerClass::findOne(['name' => 'user5']); + $this->assertNull($customer); + $customer = $customerClass::findOne(['user_guid' => $this->userBinary]); + $this->assertInstanceOf($customerClass, $customer); + + // find by attributes + $customer = $customerClass::find()->where(['name' => 'user2'])->one(); + $this->assertInstanceOf($customerClass, $customer); + $this->assertEquals($this->fkBinary2, $customer->guid); + $customer = $customerClass::find()->where(['user_guid' => $this->userBinary])->one(); + $this->assertInstanceOf($customerClass, $customer); + + // scope + $this->assertCount(2, $customerClass::find()->active()->all()); + $this->assertEquals(2, $customerClass::find()->active()->count()); + $this->assertCount(3, $customerClass::find()->where(['user_guid' => $this->userBinary])->all()); + $this->assertEquals(3, $customerClass::find()->where(['user_guid' => $this->userBinary])->count()); + } } diff --git a/tests/data/ar/CustomerBinary.php b/tests/data/ar/CustomerBinary.php new file mode 100644 index 000000000..78f805825 --- /dev/null +++ b/tests/data/ar/CustomerBinary.php @@ -0,0 +1,57 @@ +<?php + +namespace yiiunit\extensions\redis\data\ar; + +use yiiunit\extensions\redis\ActiveRecordTest; + +/** + * CustomerBinary + * + * @property string $guid + * @property string $user_guid + * @property string $email + * @property string $name + * @property string $address + * @property int $status + * + * @method CustomerBinaryQuery findBySql($sql, $params = []) static + */ +class CustomerBinary extends ActiveRecord +{ + const STATUS_ACTIVE = 1; + const STATUS_INACTIVE = 2; + + public $status2; + + /** + * @inheritdoc + */ + public function attributes() + { + return ['guid', 'user_guid', 'email', 'name', 'address', 'status']; + } + + public static function primaryKey() + { + return ['guid']; + } + + /** + * @inheritdoc + */ + public function afterSave($insert, $changedAttributes) + { + ActiveRecordTest::$afterSaveInsert = $insert; + ActiveRecordTest::$afterSaveNewRecord = $this->isNewRecord; + parent::afterSave($insert, $changedAttributes); + } + + /** + * @inheritdoc + * @return CustomerBinaryQuery + */ + public static function find() + { + return new CustomerBinaryQuery(get_called_class()); + } +} diff --git a/tests/data/ar/CustomerBinaryQuery.php b/tests/data/ar/CustomerBinaryQuery.php new file mode 100644 index 000000000..f2526fbf6 --- /dev/null +++ b/tests/data/ar/CustomerBinaryQuery.php @@ -0,0 +1,21 @@ +<?php + +namespace yiiunit\extensions\redis\data\ar; + +use yii\redis\ActiveQuery; + +/** + * CustomerBinaryQuery + */ +class CustomerBinaryQuery extends ActiveQuery +{ + /** + * @return $this + */ + public function active() + { + $this->andWhere(['status' => 1]); + + return $this; + } +}