Browse Source

Fix bitmasked null behavior.

mscherer 7 years ago
parent
commit
cbccb89d96

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

@@ -65,8 +65,12 @@ class BitmaskedBehavior extends Behavior {
 		}
 
 		$bits = $this->encodeBitmask($options['bits']);
+		if ($bits === null) {
+			$field = $this->getConfig('field');
+			$bits = $this->_getDefaultValue($field);
+		}
 
-		return $query->where([$this->_table->getAlias() . '.' . $this->_config['field'] => $bits]);
+		return $query->where([$this->_table->getAlias() . '.' . $this->_config['field'] . ' IS' => $bits]);
 	}
 
 	/**
@@ -363,6 +367,12 @@ class BitmaskedBehavior extends Behavior {
 		$bitmask = $this->encodeBitmask($bits);
 
 		$field = $this->_config['field'];
+		if ($bitmask === null) {
+			$emptyValue = $this->_getDefaultValue($field);
+
+			return [$this->_table->getAlias() . '.' . $field . ' IS' => $emptyValue];
+		}
+
 		$contain = $contain ? ' & ? = ?' : ' & ? != ?';
 		$contain = Text::insert($contain, [$bitmask, $bitmask]);
 
@@ -376,4 +386,15 @@ class BitmaskedBehavior extends Behavior {
 		return ['(' . $this->_table->getAlias() . '.' . $field . $contain . ')'];
 	}
 
+	/**
+	 * @param string $field
+	 *
+	 * @return int|null
+	 */
+	protected function _getDefaultValue($field) {
+		$schema = $this->_table->getSchema()->getColumn($field);
+
+		return $schema['default'] ?: 0;
+	}
+
 }

+ 11 - 1
tests/TestCase/Model/Behavior/BitmaskedBehaviorTest.php

@@ -84,10 +84,12 @@ class BitmaskedBehaviorTest extends TestCase {
 	 */
 	public function testFindBitmasked() {
 		$res = $this->Comments->find('bits', ['bits' => []])->toArray();
-		$this->assertSame([], $res);
+		$this->assertCount(1, $res);
+		$this->assertSame([], $res[0]->statuses);
 
 		$res = $this->Comments->find('bits', ['bits' => [BitmaskedComment::STATUS_ACTIVE, BitmaskedComment::STATUS_APPROVED]])->toArray();
 		$this->assertCount(1, $res);
+		$this->assertSame([BitmaskedComment::STATUS_ACTIVE, BitmaskedComment::STATUS_APPROVED], $res[0]->statuses);
 	}
 
 	/**
@@ -95,6 +97,14 @@ class BitmaskedBehaviorTest extends TestCase {
 	 */
 	public function testFindBitmaskedContain() {
 		$options = [
+			'bits' => [],
+			'type' => 'contain'
+		];
+		$res = $this->Comments->find('bits', $options)->toArray();
+		$this->assertCount(1, $res);
+		$this->assertSame([], $res[0]->statuses);
+
+		$options = [
 			'bits' => [BitmaskedComment::STATUS_APPROVED],
 			'type' => 'contain'
 		];