Browse Source

Fix up inclusive search using contain.

mscherer 4 years ago
parent
commit
4e2323bd6f

+ 2 - 2
docs/Behavior/Bitmasked.md

@@ -117,11 +117,11 @@ $this->Comments->find('bits', ['bits' => $statuses, 'type' => 'contain])->toArra
 If you build more complex finders or queries for your data, you might find the following info useful:
 If you build more complex finders or queries for your data, you might find the following info useful:
 
 
 "contains" (looking for any that contains this type) is translated to `field & {type} = {type}` in the ORM, e.g. `status & 1 = 1`.
 "contains" (looking for any that contains this type) is translated to `field & {type} = {type}` in the ORM, e.g. `status & 1 = 1`.
-Once you are looking for a combination of types, it will be the bitmask of those integers, e.g. `1 + 2 = 3`, so `status & 3 = 3`.
+Once you are looking for a combination of types, it will be an `OR` of those elements, e.g. `status & 1 = 1 OR status & 2 = 2`.
 
 
 Using the finder you do not have to care about the SQL details here, as it will translate to this automatically.
 Using the finder you do not have to care about the SQL details here, as it will translate to this automatically.
 
 
-"exact" (default) only looks at the values exclusivly. If you are looking for multiple ones at once that are exclusive, this will need to be translated to `IN (...)` using only the type integers directly (not the bitmasked combinations), e.g. `IN (1, 2, 4`).
+"exact" (default) only looks at the values exclusively. If you are looking for multiple ones at once that are exclusive, this will need to be translated to `IN (...)` using only the type integers directly (not the bitmasked combinations), e.g. `IN (1, 2, 4`).
 
 
 
 
 ### Configuration
 ### Configuration

+ 13 - 1
src/Model/Behavior/BitmaskedBehavior.php

@@ -61,7 +61,19 @@ class BitmaskedBehavior extends Behavior {
 		$options += ['type' => 'exact'];
 		$options += ['type' => 'exact'];
 
 
 		if ($options['type'] === 'contain') {
 		if ($options['type'] === 'contain') {
-			return $query->where($this->containsBit($options['bits']));
+			$bits = (array)$options['bits'];
+			if (!$bits) {
+				$field = $this->_config['field'];
+
+				return $query->where([$this->_table->getAlias() . '.' . $field  => $this->_getDefaultValue($field)]);
+			}
+
+			$conditions = [];
+			foreach ($bits as $bit) {
+				$conditions[] = $this->containsBit($bit);
+			}
+
+			return $query->where(['OR' => $conditions]);
 		}
 		}
 
 
 		$bits = $this->encodeBitmask($options['bits']);
 		$bits = $this->encodeBitmask($options['bits']);

+ 9 - 8
tests/Fixture/BitmaskedCommentsFixture.php

@@ -3,6 +3,7 @@
 namespace Tools\Test\Fixture;
 namespace Tools\Test\Fixture;
 
 
 use Cake\TestSuite\Fixture\TestFixture;
 use Cake\TestSuite\Fixture\TestFixture;
+use TestApp\Model\Entity\BitmaskedComment;
 
 
 /**
 /**
  * For BitmaskedBehaviorTest
  * For BitmaskedBehaviorTest
@@ -19,7 +20,7 @@ class BitmaskedCommentsFixture extends TestFixture {
 		'article_id' => ['type' => 'integer', 'null' => true],
 		'article_id' => ['type' => 'integer', 'null' => true],
 		'user_id' => ['type' => 'integer', 'null' => true],
 		'user_id' => ['type' => 'integer', 'null' => true],
 		'comment' => 'text',
 		'comment' => 'text',
-		'status' => ['type' => 'integer', 'null' => false, 'length' => 2, 'default' => '0'],
+		'status' => ['type' => 'integer', 'null' => false, 'length' => 2, 'default' => 0],
 		'created' => 'datetime',
 		'created' => 'datetime',
 		'updated' => 'datetime',
 		'updated' => 'datetime',
 		'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]],
 		'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]],
@@ -31,13 +32,13 @@ class BitmaskedCommentsFixture extends TestFixture {
 	 * @var array
 	 * @var array
 	 */
 	 */
 	public $records = [
 	public $records = [
-		['article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article', 'status' => '0', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'],
-		['article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article', 'status' => '1', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'],
-		['article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article', 'status' => '2', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'],
-		['article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article', 'status' => '3', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'],
-		['article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article', 'status' => '4', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'],
-		['article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article', 'status' => '5', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31'],
-		['article_id' => 2, 'user_id' => 3, 'comment' => 'Comment With All Bits set', 'status' => '15', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31'],
+		['article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article', 'status' => 0, 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'],
+		['article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article', 'status' => BitmaskedComment::STATUS_ACTIVE, 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'],
+		['article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article', 'status' => BitmaskedComment::STATUS_PUBLISHED, 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'],
+		['article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article', 'status' => 3, 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'],
+		['article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article', 'status' => BitmaskedComment::STATUS_APPROVED, 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'],
+		['article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article', 'status' => 5, 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31'],
+		['article_id' => 2, 'user_id' => 3, 'comment' => 'Comment With All Bits set', 'status' => 15, 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31'],
 	];
 	];
 
 
 }
 }

+ 7 - 0
tests/TestCase/Model/Behavior/BitmaskedBehaviorTest.php

@@ -112,6 +112,13 @@ class BitmaskedBehaviorTest extends TestCase {
 		];
 		];
 		$res = $this->Comments->find('bits', $options)->toArray();
 		$res = $this->Comments->find('bits', $options)->toArray();
 		$this->assertCount(3, $res);
 		$this->assertCount(3, $res);
+
+		$options = [
+			'bits' => [BitmaskedComment::STATUS_APPROVED, BitmaskedComment::STATUS_PUBLISHED],
+			'type' => 'contain',
+		];
+		$res = $this->Comments->find('bits', $options)->toArray();
+		$this->assertCount(5, $res);
 	}
 	}
 
 
 	/**
 	/**