ソースを参照

Add contain mode AND.

mscherer 4 年 前
コミット
d81e04e9a3

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

@@ -46,6 +46,8 @@ class BitmaskedBehavior extends Behavior {
 		'implementedFinders' => [
 			'bits' => 'findBitmasked',
 		],
+		'type' => null, // Auto-defaults to current default "exact", set to "contain" for contain mode
+		'containMode' => 'or', // Use "and" when a record must match all bits
 	];
 
 	/**
@@ -58,7 +60,10 @@ class BitmaskedBehavior extends Behavior {
 		if (!isset($options['bits'])) {
 			throw new InvalidArgumentException("The 'bits' key is required for find('bits')");
 		}
-		$options += ['type' => 'exact'];
+		$options += [
+			'type' => $this->_config['type'] ?? 'exact',
+			'containMode' => $this->_config['containMode'],
+		];
 
 		if ($options['type'] === 'contain') {
 			$bits = (array)$options['bits'];
@@ -68,6 +73,12 @@ class BitmaskedBehavior extends Behavior {
 				return $query->where([$this->_table->getAlias() . '.' . $field => $this->_getDefaultValue($field)]);
 			}
 
+			if ($options['containMode'] === 'and') {
+				$bits = $this->encodeBitmask($options['bits']);
+
+				return $query->where($this->containsBit($bits));
+			}
+
 			$conditions = [];
 			foreach ($bits as $bit) {
 				$conditions[] = $this->containsBit($bit);

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

@@ -124,6 +124,36 @@ class BitmaskedBehaviorTest extends TestCase {
 	/**
 	 * @return void
 	 */
+	public function testFindBitmaskedContainAnd() {
+		$options = [
+			'bits' => [],
+			'type' => 'contain',
+			'containMode' => 'and',
+		];
+		$res = $this->Comments->find('bits', $options)->toArray();
+		$this->assertCount(1, $res);
+		$this->assertSame([], $res[0]->statuses);
+
+		$options = [
+			'bits' => [BitmaskedComment::STATUS_APPROVED],
+			'type' => 'contain',
+			'containMode' => 'and',
+		];
+		$res = $this->Comments->find('bits', $options)->toArray();
+		$this->assertCount(3, $res);
+
+		$options = [
+			'bits' => [BitmaskedComment::STATUS_APPROVED, BitmaskedComment::STATUS_PUBLISHED],
+			'type' => 'contain',
+			'containMode' => 'and',
+		];
+		$res = $this->Comments->find('bits', $options)->toArray();
+		$this->assertCount(1, $res);
+	}
+
+	/**
+	 * @return void
+	 */
 	public function testSaveBasic() {
 		$data = [
 			'comment' => 'test save',