1<?php
2
3
4namespace ComboStrap;
5
6
7class DataType
8{
9
10    /**
11     * The property name when the type value is persisted
12     */
13    public const PROPERTY_NAME = "type";
14
15
16    /**
17     * An object with several children metadata
18     * An entity
19     * A group of metadata
20     */
21    public const TABULAR_TYPE_VALUE = "tabular";
22    /**
23     * Text with carriage return
24     */
25    public const PARAGRAPH_TYPE_VALUE = "paragraph";
26    /**
27     * True/False
28     */
29    public const BOOLEAN_TYPE_VALUE = "boolean";
30
31    /**
32     * A couple of words without any carriage return
33     */
34    public const TEXT_TYPE_VALUE = "text";
35
36    /**
37     * Date Time
38     */
39    public const DATETIME_TYPE_VALUE = "datetime";
40    /**
41     * A string but in Json
42     */
43    public const JSON_TYPE_VALUE = "json";
44
45    /**
46     * Integer
47     */
48    public const INTEGER_TYPE_VALUE = "integer";
49
50    /**
51     * Array of array of array
52     */
53    const ARRAY_VALUE = "array";
54
55    /**
56     * The constant value
57     */
58    public const TYPES = [
59        DataType::TEXT_TYPE_VALUE,
60        DataType::TABULAR_TYPE_VALUE,
61        DataType::DATETIME_TYPE_VALUE,
62        DataType::PARAGRAPH_TYPE_VALUE,
63        DataType::JSON_TYPE_VALUE,
64        DataType::BOOLEAN_TYPE_VALUE,
65        DataType::INTEGER_TYPE_VALUE,
66    ];
67    const FLOOR = "floor";
68    const CEIL = "ceil";
69
70
71    /**
72     * @throws ExceptionBadArgument
73     */
74    public static function toIntegerOrDefaultIfNull($targetValue, $default): int
75    {
76        if ($targetValue === null) {
77            return $default;
78        }
79        return self::toInteger($targetValue);
80    }
81
82    /**
83     *
84     * @throws ExceptionBadArgument
85     * @var string $roundDirection - ceil or floor (by default floor)
86     */
87    public static function toInteger($targetValue, string $roundDirection = self::FLOOR): int
88    {
89
90
91        if (is_int($targetValue)) {
92            return $targetValue;
93        }
94        if (!is_string($targetValue) && !is_float($targetValue)) {
95            $varExport = var_export($targetValue, true);
96            throw new ExceptionBadArgument("The value passed is not a numeric/nor a string. We can not translate it to an integer. Value: $varExport");
97        }
98        /**
99         * Float 12.845 will return 12
100         */
101        $float = self::toFloat($targetValue);
102        if ($roundDirection === self::FLOOR) {
103            $int = floor($float);
104        } else {
105            $int = ceil($float);
106        }
107        if (
108            $int === 0 &&
109            "$targetValue" !== "0"
110        ) {
111            throw new ExceptionBadArgument("The value ($targetValue) can not be cast to an integer.");
112        }
113        return $int;
114    }
115
116    /**
117     * @throws ExceptionBadArgument
118     */
119    public static function toIntegerCeil($targetValue): int
120    {
121
122        return self::toInteger($targetValue, self::CEIL);
123
124    }
125
126    public static function toBoolean($value, $ifNull = null)
127    {
128        if ($value === null) return $ifNull;
129        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
130    }
131
132    /**
133     * @throws ExceptionBadArgument - if the value is not a numeric
134     */
135    public static function toFloat($value): float
136    {
137        if (is_float($value)) {
138            return $value;
139        }
140
141        if (!is_numeric($value)) {
142            throw new ExceptionBadArgument("The value ($value) is not a numeric");
143        }
144
145        return floatval($value);
146    }
147
148    public static function toBooleanString(?bool $value): ?string
149    {
150        if ($value === null) {
151            return null;
152        }
153        if ($value) {
154            return "true";
155        } else {
156            return "false";
157        }
158    }
159
160    /**
161     * @param mixed|null $value
162     * @return bool - true if the value is built-in boolean or null
163     */
164    public static function isBoolean($value): bool
165    {
166        return is_bool($value);
167    }
168
169    /**
170     * Normalize the string output
171     * ie (the true boolean value is not printed as `1` but `true`)
172     * @param $value
173     * @return mixed|string|null
174     */
175    public static function toString($value)
176    {
177        if ($value === null) {
178            return 'null';
179        }
180        if (is_string($value)) {
181            return $value;
182        }
183        if (is_array($value)) {
184            return ArrayUtility::formatAsString($value);
185        }
186        if (is_object($value)) {
187            return $value->__toString();
188        }
189        if (is_bool($value)) {
190            return var_export($value, true);
191        }
192        return strval($value);
193    }
194
195    public static function getType($value): string
196    {
197        if (is_string($value)) {
198            return "string";
199        }
200        if (is_array($value)) {
201            return "array";
202        }
203        if (is_object($value)) {
204            return "object (" . get_class($value) . ")";
205        }
206        return gettype($value);
207    }
208
209    public static function toMilliSeconds(\DateTime $dateTime)
210    {
211
212        $secs = $dateTime->getTimestamp(); // Gets the seconds
213        $millisecs = $secs * 1000; // Converted to milliseconds
214        $millisecs += $dateTime->format("u") / 1000; // Microseconds converted to seconds
215        return $millisecs;
216
217    }
218
219    public static function isObject($value): bool
220    {
221        return is_object($value);
222    }
223
224
225}
226