DBField::castValue()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 5
nop 2
dl 0
loc 14
rs 9.4888
c 0
b 0
f 0
1
<?php
2
3
namespace Asymptix\db;
4
5
use Asymptix\core\Tools;
6
7
/**
8
 * DB field representation class.
9
 *
10
 * @category Asymptix PHP Framework
11
 * @author Dmytro Zarezenko <[email protected]>
12
 * @copyright (c) 2011 - 2016, Dmytro Zarezenko
13
 *
14
 * @git https://github.com/Asymptix/Framework
15
 * @license http://opensource.org/licenses/MIT
16
 */
17
class DBField {
18
    /**
19
     * Name of the field.
20
     *
21
     * @var string
22
     */
23
    public $name;
24
25
    /**
26
     * Value of the field.
27
     *
28
     * @var mixed
29
     */
30
    public $value;
31
32
    /**
33
     * Type of the field.
34
     *
35
     * @var string
36
     */
37
    public $type;
38
39
    /**
40
     * Constructor of the class with parameters validation.
41
     *
42
     * @param string $type Type of the field.
43
     * @param string $name Name of the field.
44
     * @param mixed $value Value of the field.
45
     */
46
    public function __construct($type = "", $name = "", $value = null) {
47
        if (!(bool)preg_match("#^[a-zA-Z][a-zA-Z0-9_]*$#", $name)) {
48
            throw new DBFieldException("Can't create DBField object: invalid field name '" . $name . "'");
49
        }
50
        $this->name = $name;
51
52
        if (empty($type)) {
53
            if (empty($value) && !is_null($value)) {
54
                throw new DBFieldException("Can't create DBField object: type and value are empty");
55
            } elseif (is_null($value)) {
56
                $this->type = null;
57
                $this->value = null;
58
            } else {
59
                $this->type = self::getType($value);
60
                $this->value = $value;
61
            }
62
        } else {
63
            $this->type = self::castType($type);
64
            if (!is_null($value)) {
65
                switch ($this->type) {
66
                    case ("i"):
67
                        $this->value = (int)$value;
68
                        break;
69
                    case ("d"):
70
                        $this->value = (float)$value;
71
                        break;
72
                    case ("s"):
73
                        $this->value = (string)$value;
74
                        break;
75
                    case ("b"):
76
                        $this->value = (bool)$value;
77
                        break;
78
                }
79
            }
80
        }
81
    }
82
83
    /**
84
     * Returns SQL type equivalent ("idsb") for common used types.
85
     *
86
     * @param string $fieldType Type of the field (example: "integer", "int",
87
     *           "double", "real", "bool", ...).
88
     *
89
     * @return string
90
     * @throws DBFieldTypeException If invalid field type passed.
91
     */
92
    public static function castType($fieldType) {
93
        $typesList = [
94
            'integer' => "i",
95
            'int'     => "i",
96
            'i'       => "i",
97
            'real'    => "d",
98
            'float'   => "d",
99
            'double'  => "d",
100
            'd'       => "d",
101
            'string'  => "s",
102
            'str'     => "s",
103
            's'       => "s",
104
            'boolean' => "b",
105
            'bool'    => "b",
106
            'b'       => "b"
107
        ];
108
109
        if (isset($typesList[$fieldType])) {
110
            return $typesList[$fieldType];
111
        }
112
        throw new DBFieldTypeException("Invalid SQL type");
113
    }
114
115
    /**
116
     * Returns type of the parameter by value.
117
     *
118
     * @param mixed $fieldValue
119
     *
120
     * @return string Types of the parameter ("idsb").
121
     * @throws DBFieldTypeException If can't detect field type by value.
122
     */
123
    public static function getType($fieldValue) {
124
        if (is_null($fieldValue)) { // Type is not principled for NULL
125
            return "i";
126
        } elseif (Tools::isInteger($fieldValue)) {
127
            return "i";
128
        } elseif (Tools::isDouble($fieldValue)) {
129
            return "d";
130
        } elseif (Tools::isBoolean($fieldValue)) {
131
            return "b";
132
        } elseif (Tools::isString($fieldValue)) {
133
            return "s";
134
        } else {
135
            throw new DBFieldTypeException(
136
                "Can't detect field value type for value '" . (string)$fieldValue . "'"
137
            );
138
        }
139
    }
140
141
    /**
142
     * Casts field value to it's type.
143
     *
144
     * @param string $type Field type.
145
     * @param mixed $value Field value.
146
     *
147
     * @return mixed Casted field value.
148
     * @throws DBFieldTypeException If invalid field type provided.
149
     */
150
    public static function castValue($type, $value) {
151
        switch (self::castType($type)) {
152
            case ("i"):
153
                return (int)$value;
154
            case ("d"):
155
                return (float)$value;
156
            case ("s"):
157
                return (string)$value;
158
            case ("b"):
159
                return (bool)$value;
160
        }
161
162
        throw new DBFieldTypeException("Invalid SQL type");
163
    }
164
165
    /**
166
     * Returns field value in the SQL query format.
167
     *
168
     * @param string $type Field type.
169
     * @param mixed $value Field value.
170
     *
171
     * @return mixed SQL formatted value of the field.
172
     * @throws DBFieldTypeException If invalid field type provided.
173
     */
174
    public static function sqlValue($type, $value) {
175
        if (is_null($value)) {
176
            return "NULL";
177
        }
178
179
        $type = self::castType($type);
180
        $value = self::castValue($type, $value);
181
        switch ($type) {
182
            case ("i"):
183
            case ("d"):
184
                return $value;
185
            case ("s"):
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
186
                if (!in_array($value, ['NOW()'])) {
187
                    return "'" . $value . "'";
188
                } else {
189
                    return $value;
190
                }
191
            case ("b"):
192
                if ($value) {
193
                    return "TRUE";
194
                }
195
196
                return "FALSE";
197
        }
198
199
        throw new DBFieldTypeException("Invalid SQL type");
200
    }
201
202
}
203
204
/**
205
 * Service exception classes.
206
 */
207
class DBFieldException extends \Exception {}
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
208
class DBFieldTypeException extends \Exception {}
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
209