1: <?php
2: /**
3: * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4: * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5: *
6: * Licensed under The MIT License
7: * For full copyright and license information, please see the LICENSE.txt
8: * Redistributions of files must retain the above copyright notice.
9: *
10: * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11: * @link https://cakephp.org CakePHP(tm) Project
12: * @since 3.1.2
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Database\Type;
16:
17: use Cake\Database\Driver;
18: use Cake\Database\Type;
19: use Cake\Database\TypeInterface;
20: use Cake\Database\Type\BatchCastingInterface;
21: use InvalidArgumentException;
22: use PDO;
23:
24: /**
25: * Bool type converter.
26: *
27: * Use to convert bool data between PHP and the database types.
28: */
29: class BoolType extends Type implements TypeInterface, BatchCastingInterface
30: {
31: /**
32: * Identifier name for this type.
33: *
34: * (This property is declared here again so that the inheritance from
35: * Cake\Database\Type can be removed in the future.)
36: *
37: * @var string|null
38: */
39: protected $_name;
40:
41: /**
42: * Constructor.
43: *
44: * (This method is declared here again so that the inheritance from
45: * Cake\Database\Type can be removed in the future.)
46: *
47: * @param string|null $name The name identifying this type
48: */
49: public function __construct($name = null)
50: {
51: $this->_name = $name;
52: }
53:
54: /**
55: * Convert bool data into the database format.
56: *
57: * @param mixed $value The value to convert.
58: * @param \Cake\Database\Driver $driver The driver instance to convert with.
59: * @return bool|null
60: */
61: public function toDatabase($value, Driver $driver)
62: {
63: if ($value === true || $value === false || $value === null) {
64: return $value;
65: }
66:
67: if (in_array($value, [1, 0, '1', '0'], true)) {
68: return (bool)$value;
69: }
70:
71: throw new InvalidArgumentException(sprintf(
72: 'Cannot convert value of type `%s` to bool',
73: getTypeName($value)
74: ));
75: }
76:
77: /**
78: * Convert bool values to PHP booleans
79: *
80: * @param mixed $value The value to convert.
81: * @param \Cake\Database\Driver $driver The driver instance to convert with.
82: * @return bool|null
83: */
84: public function toPHP($value, Driver $driver)
85: {
86: if ($value === null || $value === true || $value === false) {
87: return $value;
88: }
89:
90: if (!is_numeric($value)) {
91: return strtolower($value) === 'true';
92: }
93:
94: return !empty($value);
95: }
96:
97: /**
98: * {@inheritDoc}
99: *
100: * @return array
101: */
102: public function manyToPHP(array $values, array $fields, Driver $driver)
103: {
104: foreach ($fields as $field) {
105: if (!isset($values[$field]) || $values[$field] === true || $values[$field] === false) {
106: continue;
107: }
108:
109: if ($values[$field] === '1') {
110: $values[$field] = true;
111: continue;
112: }
113:
114: if ($values[$field] === '0') {
115: $values[$field] = false;
116: continue;
117: }
118:
119: $value = $values[$field];
120: if (!is_numeric($value)) {
121: $values[$field] = strtolower($value) === 'true';
122: continue;
123: }
124:
125: $values[$field] = !empty($value);
126: }
127:
128: return $values;
129: }
130:
131: /**
132: * Get the correct PDO binding type for bool data.
133: *
134: * @param mixed $value The value being bound.
135: * @param \Cake\Database\Driver $driver The driver.
136: * @return int
137: */
138: public function toStatement($value, Driver $driver)
139: {
140: if ($value === null) {
141: return PDO::PARAM_NULL;
142: }
143:
144: return PDO::PARAM_BOOL;
145: }
146:
147: /**
148: * Marshalls request data into PHP booleans.
149: *
150: * @param mixed $value The value to convert.
151: * @return bool|null Converted value.
152: */
153: public function marshal($value)
154: {
155: if ($value === null) {
156: return null;
157: }
158: if ($value === 'true') {
159: return true;
160: }
161: if ($value === 'false') {
162: return false;
163: }
164: if (!is_scalar($value)) {
165: return null;
166: }
167:
168: return !empty($value);
169: }
170: }
171: