1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of the fangface/yii2-concord package |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view |
6
|
|
|
* the file LICENSE.md that was distributed with this source code. |
7
|
|
|
* |
8
|
|
|
* @package fangface/yii2-concord |
9
|
|
|
* @author Fangface <[email protected]> |
10
|
|
|
* @copyright Copyright (c) 2014 Fangface <[email protected]> |
11
|
|
|
* @license https://github.com/fangface/yii2-concord/blob/master/LICENSE.md MIT License |
12
|
|
|
* |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace fangface; |
16
|
|
|
|
17
|
|
|
use fangface\Tools; |
18
|
|
|
use fangface\base\traits\ServiceGetterStatic; |
19
|
|
|
use fangface\base\traits\Singleton; |
20
|
|
|
use fangface\helpers\Inflector; |
21
|
|
|
use fangface\models\db\Client; |
22
|
|
|
use yii\helpers\ArrayHelper; |
23
|
|
|
use yii\helpers\StringHelper; |
24
|
|
|
|
25
|
|
|
class Tools |
26
|
|
|
{ |
27
|
|
|
|
28
|
|
|
use Singleton; |
29
|
|
|
use ServiceGetterStatic; |
30
|
|
|
|
31
|
|
|
const DATE_TIME_DB_EMPTY = '0000-00-00 00:00:00'; |
32
|
|
|
const DATE_DB_EMPTY = '0000-00-00'; |
33
|
|
|
const TIME_DB_EMPTY = '00:00:00'; |
34
|
|
|
const YEAR_DB_EMPTY = '1901'; |
35
|
|
|
const YEAR_DB_MAX = '2155'; |
36
|
|
|
|
37
|
|
|
const DATETIME_DATABASE = 'Y-m-d H:i:s'; |
38
|
|
|
const DATE_DATABASE = 'Y-m-d'; |
39
|
|
|
const TIME_DATABASE = 'H:i:s'; |
40
|
|
|
const YEAR_DATABASE = 'Y'; |
41
|
|
|
|
42
|
|
|
/* |
43
|
|
|
* Returns the current active client Id @return integer |
44
|
|
|
* |
45
|
|
|
* @return integer |
46
|
|
|
*/ |
47
|
|
|
public static function getClientId() |
48
|
|
|
{ |
49
|
|
|
$client = static::getService('client'); |
50
|
|
|
if ($client && $client instanceof Client) { |
51
|
|
|
return $client->id; |
52
|
|
|
} |
53
|
|
|
return 0; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
|
57
|
|
|
/* |
58
|
|
|
* Returns the current active client code @return string |
59
|
|
|
* |
60
|
|
|
* @return string |
61
|
|
|
*/ |
62
|
|
|
public static function getClientCode() |
63
|
|
|
{ |
64
|
|
|
$client = static::getService('client'); |
65
|
|
|
if ($client && $client instanceof Client) { |
66
|
|
|
return $client->clientCode; |
67
|
|
|
} |
68
|
|
|
return ''; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Determine if a value is a closure object |
73
|
|
|
* @param mixed $t |
74
|
|
|
* @return boolean |
75
|
|
|
*/ |
76
|
|
|
public static function is_closure($t) { |
77
|
|
|
return is_object($t) && ($t instanceof \Closure); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Return a class name with namespace removed |
83
|
|
|
* |
84
|
|
|
* @param object $object |
85
|
|
|
* @return string|false |
86
|
|
|
*/ |
87
|
|
|
public static function getClassName($object = null) |
88
|
|
|
{ |
89
|
|
|
if (! is_object($object) && ! is_string($object)) { |
90
|
|
|
return false; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
$class = explode('\\', (is_string($object) ? $object : get_class($object))); |
94
|
|
|
$str = $class[count($class) - 1]; |
95
|
|
|
|
96
|
|
|
return $str; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Determine default table name for an ActiveRecord class |
102
|
|
|
* @param \fangface\db\ActiveRecord $object |
103
|
|
|
* @return string |
104
|
|
|
*/ |
105
|
|
|
|
106
|
|
|
public static function getDefaultTableNameFromClass($object = null) |
107
|
|
|
{ |
108
|
|
|
$str = self::getClassName($object); |
109
|
|
|
|
110
|
|
|
$method = 'default'; |
111
|
|
|
if (isset(\Yii::$app->params['db.defaultTableNameType'])) { |
112
|
|
|
$method = \Yii::$app->params['db.defaultTableNameType']; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
switch ($method) { |
116
|
|
|
|
117
|
|
|
case 'camel': // OrderItem => order_items |
118
|
|
|
$tableName = Inflector::camel2id($str, '_'); |
|
|
|
|
119
|
|
|
$tableName = Inflector::pluralize($tableName); |
120
|
|
|
break; |
121
|
|
|
|
122
|
|
|
case 'plural': // OrderItem => orderItems |
123
|
|
|
$tableName = lcfirst($str); |
124
|
|
|
$tableName = Inflector::pluralize($tableName); |
125
|
|
|
break; |
126
|
|
|
|
127
|
|
|
case 'yii': // OrderItem => order_item |
128
|
|
|
default: |
129
|
|
|
$tableName = Inflector::camel2id($str, '_'); |
|
|
|
|
130
|
|
|
break; |
131
|
|
|
|
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
return $tableName; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Return a class name with namespace cleaned of characters not required |
140
|
|
|
* Typically used when the class name needs to be used as a key for anything |
141
|
|
|
* |
142
|
|
|
* @param object $object |
143
|
|
|
* @return string|false |
144
|
|
|
*/ |
145
|
|
|
public static function getCleanClassNameWithNamespace($object) |
146
|
|
|
{ |
147
|
|
|
if (!is_object($object) && !is_string($object)) { |
148
|
|
|
return false; |
149
|
|
|
} |
150
|
|
|
$className = (is_string($object) ? $object : get_class($object)); |
151
|
|
|
$className = strtolower(strtr($className, array( |
152
|
|
|
'-' => '', |
153
|
|
|
'_' => '', |
154
|
|
|
' ' => '', |
155
|
|
|
'\\' => '', |
156
|
|
|
'/' => '' |
157
|
|
|
))); |
158
|
|
|
return $className; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Converts a size in bytes to something human readable. |
164
|
|
|
*/ |
165
|
|
|
public static function getHumanBytes($bytes, $precision = 2) |
166
|
|
|
{ |
167
|
|
|
$unit = array( |
168
|
|
|
'B', |
169
|
|
|
'KB', |
170
|
|
|
'MB', |
171
|
|
|
'GB', |
172
|
|
|
'TB', |
173
|
|
|
'PB', |
174
|
|
|
'EB' |
175
|
|
|
); |
176
|
|
|
|
177
|
|
|
if (! $bytes) { |
178
|
|
|
return "0 B"; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
return @round($bytes / pow(1024, ($i = floor(log($bytes, 1024)))), $precision) . ' ' . $unit[$i]; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* Chcek if two values are numerically the same. |
187
|
|
|
* Casts the |
188
|
|
|
* arguments as integers to type check. |
189
|
|
|
* |
190
|
|
|
* @param integer $arg_1 |
191
|
|
|
* @param integer $arg_2 |
192
|
|
|
* @return boolean |
193
|
|
|
*/ |
194
|
|
|
public static function intEquals($arg_1, $arg_2) |
195
|
|
|
{ |
196
|
|
|
return (int) $arg_1 === (int) $arg_2; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* Chcek if two values are equal string. |
202
|
|
|
* Casts the |
203
|
|
|
* arguments as strings to type check. |
204
|
|
|
* |
205
|
|
|
* @param string $arg_1 |
206
|
|
|
* @param string $arg_2 |
207
|
|
|
* @return boolean |
208
|
|
|
*/ |
209
|
|
|
public static function strEquals($arg_1, $arg_2) |
210
|
|
|
{ |
211
|
|
|
return "" . $arg_1 === "" . $arg_2; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Returns the indexed element for the mixed object. |
217
|
|
|
* You can specify |
218
|
|
|
* a default value to return in $default and specify if you want to |
219
|
|
|
* just find out of the index exists ($check_index_exists). The latter |
220
|
|
|
* will return a boolean. |
221
|
|
|
* |
222
|
|
|
* @param mixed $object |
223
|
|
|
* @param string $index |
224
|
|
|
* @param mixed $default |
225
|
|
|
* @param boolean $check_index_exists |
226
|
|
|
* @return boolean|mixed |
227
|
|
|
*/ |
228
|
|
|
public static function get($object, $index, $default = FALSE, $check_index_exists = FALSE) |
229
|
|
|
{ |
230
|
|
|
if (is_array($object)) { |
231
|
|
|
if (isset($object[$index])) { |
232
|
|
|
return ($check_index_exists) ? TRUE : $object[$index]; |
233
|
|
|
} |
234
|
|
|
} else { |
235
|
|
|
if (isset($object->$index)) { |
236
|
|
|
return ($check_index_exists) ? true : $object->$index; |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
return $default; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Checks if the variable is of the specified type and a valid value |
246
|
|
|
* |
247
|
|
|
* @param mixed $mixed |
248
|
|
|
* @param string $expected_type |
249
|
|
|
* @return boolean |
250
|
|
|
*/ |
251
|
|
|
public static function isValid($mixed, $expected_type = 'INT') |
252
|
|
|
{ |
253
|
|
|
$expected_type = strtoupper($expected_type); |
254
|
|
|
if (is_numeric($mixed) || $expected_type === 'INT') { |
255
|
|
|
return is_numeric($mixed) && strlen($mixed) && (int) $mixed > 0; |
256
|
|
|
} elseif ($expected_type === 'STRING') { |
257
|
|
|
return is_string($mixed) && strlen($mixed) > 0; |
258
|
|
|
} elseif ($expected_type === 'DATE') { |
259
|
|
|
// check if date is of form YYYY-MM-DD HH:MM:SS and that it |
260
|
|
|
// is not 0000-00-00 00:00:00. |
261
|
|
|
// |
262
|
|
|
if (strlen($mixed) === 19 && !static::strEquals($mixed, self::DATE_TIME_DB_EMPTY)) { |
263
|
|
|
return true; |
264
|
|
|
} |
265
|
|
|
// check for MM/DD/YYYY type dates |
266
|
|
|
$parts = explode("/", $mixed); |
267
|
|
|
return count($parts) === 3 && checkdate($parts[0], $parts[1], $parts[2]); |
268
|
|
|
} elseif ($expected_type === 'OBJECT') { |
269
|
|
|
// iterate through object and check if there are any properties |
270
|
|
|
foreach ($mixed as $property) { |
271
|
|
|
if ($property) { |
272
|
|
|
return true; |
273
|
|
|
} |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
return false; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* List the services currently specified in the service manager |
283
|
|
|
* (useful for debug) |
284
|
|
|
* @param string $lineBreak (default is "\n") |
285
|
|
|
*/ |
286
|
|
|
public static function listServices($lineBreak = "\n") { |
287
|
|
|
print '<hr/>'; |
288
|
|
|
$services = self::getServices(); |
289
|
|
|
foreach ($services as $service => $serviceDefinition) { |
290
|
|
|
print 'Service: ' . $service . $lineBreak; |
291
|
|
|
} |
292
|
|
|
print '<hr/>'; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* |
298
|
|
|
* @param number|string|boolean|null $value |
299
|
|
|
* @param string|array|\yii\db\ColumnSchema $dataType type of attribute or an array of values specifying the column schema |
300
|
|
|
* @param integer $length number of characters for the attribute within the db table [OPTIONAL] default 0 |
301
|
|
|
* @param integer $decimals how many decimal characters exist for this attribute within the db table [OPTIONAL] default 0 |
302
|
|
|
* @param boolean $unsigned is the atribute unsigned within the db table [OPTIONAL] default false |
303
|
|
|
* @param boolean $zerofill is the attribute zerofilled within the db table [OPTIONAL] default false |
304
|
|
|
* @param boolean $isNullable is the attribute nullable within the db table [OPTIONAL] default false |
305
|
|
|
* @param boolean $autoIncrement is the attribute auto incrementing within the db table [OPTIONAL] default false |
306
|
|
|
* @param boolean $primaryKey is the attribute the primary key within the table [OPTIONAL] default false |
307
|
|
|
* @param mixed $defaultValue default value [OPTIONAL] default '' |
308
|
|
|
* @return number|string|boolean|null |
309
|
|
|
*/ |
310
|
|
|
public static function formatAttributeValue($value, $dataType, $length = 0, $decimals = 0, $unsigned = false, $zerofill = false, $isNullable = false, $autoIncrement = false, $primaryKey = false, $defaultValue = '') |
311
|
|
|
{ |
312
|
|
|
|
313
|
|
|
if (is_array($dataType) || is_object($dataType)) { |
314
|
|
|
// assume parameters are being passed in the array |
315
|
|
|
$options = $dataType; |
316
|
|
|
if (is_object($dataType)) { |
317
|
|
|
// Yii schema object format |
318
|
|
|
$dataType = strtolower($options->type); |
319
|
|
|
$length = ($options->size ? $options->size : 0); |
320
|
|
|
$decimals = $options->precision; |
321
|
|
|
$unsigned = $options->unsigned; |
322
|
|
|
$zerofill = (strpos($options->dbType, 'zerofill') !== false ? true : false); |
323
|
|
|
$isNullable = $options->allowNull; |
324
|
|
|
$autoIncrement = $options->autoIncrement; |
325
|
|
|
$primaryKey = $options->isPrimaryKey; |
326
|
|
|
$defaultValue = $options->defaultValue; |
327
|
|
|
} elseif (isset($options['characterMaximumLength'])) { |
328
|
|
|
// Zend schema format |
329
|
|
|
$dataType = strtolower($options['dataType']); |
330
|
|
|
$length = (is_null($options['characterMaximumLength']) ? (is_null($options['numericPrecision']) ? 0 : $options['numericPrecision']) : $options['characterMaximumLength']); |
331
|
|
|
$decimals = $options['numericScale']; |
332
|
|
|
$unsigned = $options['numericUnsigned']; |
333
|
|
|
$zerofill = $options['zeroFill']; |
334
|
|
|
$isNullable = $options['isNullable']; |
335
|
|
|
$autoIncrement = $options['autoIncrement']; |
336
|
|
|
$primaryKey = $options['isPrimaryKey']; |
337
|
|
|
$defaultValue = $options['defaultValue']; |
338
|
|
|
} elseif (isset($options['phpType'])) { |
339
|
|
|
// Yii schema format |
340
|
|
|
$dataType = strtolower($options['type']); |
341
|
|
|
$length = ($options['size'] ? $options['size'] : 0); |
342
|
|
|
$decimals = $options['precision']; |
343
|
|
|
$unsigned = $options['unsigned']; |
344
|
|
|
$zerofill = (strpos($options['dbType'], 'zerofill') !== false ? true : false); |
345
|
|
|
$isNullable = $options['allowNull']; |
346
|
|
|
$autoIncrement = $options['autoIncrement']; |
347
|
|
|
$primaryKey = $options['isPrimaryKey']; |
348
|
|
|
$defaultValue = $options['defaultValue']; |
349
|
|
|
} else { |
350
|
|
|
// EAV definitions format |
351
|
|
|
$dataType = strtolower($options['dataType']); |
352
|
|
|
$length = $options['length']; |
353
|
|
|
$decimals = $options['decimals']; |
354
|
|
|
$unsigned = $options['unsigned']; |
355
|
|
|
$zerofill = $options['zerofill']; |
356
|
|
|
$isNullable = $options['isNullable']; |
357
|
|
|
$autoIncrement = false; |
358
|
|
|
$primaryKey = false; |
359
|
|
|
$defaultValue = $options['defaultValue']; |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
} else { |
363
|
|
|
$dataType = strtolower($dataType); |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
if ($dataType == 'char' && $length == 0) { |
367
|
|
|
$dataType = 'longtext'; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
if ($value == '__DEFAULT__') { |
371
|
|
|
if (is_null($defaultValue) && $isNullable) { |
372
|
|
|
$value = null; |
373
|
|
|
} elseif ($autoIncrement && $primaryKey) { |
374
|
|
|
$value = 0; |
375
|
|
|
} else { |
376
|
|
|
$value = $defaultValue; |
377
|
|
|
} |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
if ($isNullable && ($value == '__NULL__' || is_null($value))) { |
381
|
|
|
|
382
|
|
|
$value = null; |
383
|
|
|
|
384
|
|
|
} else { |
385
|
|
|
|
386
|
|
|
switch ($dataType) { |
387
|
|
|
|
388
|
|
|
case 'integer': |
389
|
|
|
case 'tinyint': |
390
|
|
|
case 'smallint': |
391
|
|
|
case 'mediumint': |
392
|
|
|
case 'bigint': |
393
|
|
|
case 'serial': |
394
|
|
|
case 'numeric': |
395
|
|
|
case 'int': |
396
|
|
|
case 'timestamp': |
397
|
|
|
if ($value == '' || $value == '__NULL__') { |
398
|
|
|
if ($dataType == 'bigint') { |
399
|
|
|
$value = '0'; |
400
|
|
|
} else { |
401
|
|
|
$value = 0; |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
if ($zerofill) { |
405
|
|
|
if ($value < 0) { |
406
|
|
|
$value = '-' . str_pad(str_replace('-', '', $value), $length, "0", STR_PAD_LEFT); |
407
|
|
|
} else { |
408
|
|
|
$value = str_pad($value, $length, "0", STR_PAD_LEFT); |
409
|
|
|
} |
410
|
|
|
} else { |
411
|
|
|
if ($dataType == 'bigint') { |
412
|
|
|
$value = number_format($value, 0, '', ''); |
413
|
|
|
} else { |
414
|
|
|
$value = (int) $value; |
415
|
|
|
} |
416
|
|
|
} |
417
|
|
|
return $value; |
418
|
|
|
|
419
|
|
|
case 'char': |
420
|
|
|
case 'varchar': |
421
|
|
|
case 'text': |
422
|
|
|
case 'tinytext': |
423
|
|
|
case 'mediumtext': |
424
|
|
|
case 'longtext': |
425
|
|
|
case 'binary': |
426
|
|
|
case 'varbinary': |
427
|
|
|
case 'blob': |
428
|
|
|
case 'tinyblob': |
429
|
|
|
case 'mediumblob': |
430
|
|
|
case 'longblob': |
431
|
|
|
case 'enum': |
432
|
|
|
case 'string': |
433
|
|
|
if ($value == '__NULL__') { |
434
|
|
|
return ((string) ''); |
435
|
|
|
} else { |
436
|
|
|
return ((string) $value); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
case 'dec': |
440
|
|
|
case 'double': |
441
|
|
|
case 'numeric': |
442
|
|
|
case 'fixed': |
443
|
|
|
case 'float': |
444
|
|
|
case 'decimal': |
445
|
|
|
if ($value == '' || $value == '__NULL__') { |
446
|
|
|
$value = 0; |
447
|
|
|
} |
448
|
|
|
$value = number_format($value, $decimals, '.', ''); |
449
|
|
|
if ($zerofill) { |
450
|
|
|
if ($value < 0) { |
451
|
|
|
$value = '-' . str_pad(str_replace('-', '', $value), ($length + 1), "0", STR_PAD_LEFT); |
452
|
|
|
} else { |
453
|
|
|
$value = str_pad($value, ($length + 1), "0", STR_PAD_LEFT); |
454
|
|
|
} |
455
|
|
|
} |
456
|
|
|
return $value; |
457
|
|
|
|
458
|
|
|
case 'bool': |
459
|
|
|
case 'boolean': |
460
|
|
|
if (is_bool($value)) { |
461
|
|
|
return (($value ? true : false)); |
462
|
|
|
} elseif (is_string($value)) { |
463
|
|
|
$valueX = strtoupper(substr(trim($value), 0, 1)); |
464
|
|
|
return (($valueX == 'N' || $value == '0' || $value == '_' || ($value == 'O' && strtoupper($value) != 'ON') || $value == '' ? false : true)); |
465
|
|
|
} else { |
466
|
|
|
return (($value ? true : false)); |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
case 'date': |
470
|
|
|
if ($length) { |
471
|
|
|
return ($value != '' && $value != self::YEAR_DB_EMPTY ? $value : self::YEAR_DB_EMPTY); |
472
|
|
|
} else { |
473
|
|
|
return ($value != '' && $value != self::DATE_DB_EMPTY && strtotime($value) ? $value : self::DATE_DB_EMPTY); |
474
|
|
|
} |
475
|
|
|
case 'datetime': |
476
|
|
|
return ($value != '' && $value != self::DATE_TIME_DB_EMPTY && strtotime($value) ? $value : self::DATE_TIME_DB_EMPTY); |
477
|
|
|
default: |
478
|
|
|
return $value; |
479
|
|
|
} |
480
|
|
|
} |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
|
484
|
|
|
/** |
485
|
|
|
* Generate a random string to the specified length and optionally exclude often |
486
|
|
|
* mis-read characters |
487
|
|
|
* |
488
|
|
|
* @param integer $len number of characters to generate |
489
|
|
|
* @param boolean $excludeEasyMisRead [optional] exclude typically mis-ead characters, default false |
490
|
|
|
* @param boolean $upperCase [optional] force to upper case |
491
|
|
|
* @return string |
492
|
|
|
*/ |
493
|
|
|
public static function randomString($len, $excludeEasyMisRead = false, $upperCase = false) |
494
|
|
|
{ |
495
|
|
|
$pass = ''; |
496
|
|
|
$lchar = 0; |
497
|
|
|
$char = 0; |
498
|
|
|
for ($i = 0; $i < $len; $i ++) { |
499
|
|
|
$charOK = false; |
500
|
|
|
while ($char == $lchar || ! $charOK) { |
501
|
|
|
$char = rand(48, 109); |
502
|
|
|
if ($char > 57) |
503
|
|
|
$char += 7; |
504
|
|
|
if ($char > 90) |
505
|
|
|
$char += 6; |
506
|
|
|
if ($excludeEasyMisRead) { |
507
|
|
|
// we want to exclude characters that can and do often get mis-read by the user |
508
|
|
|
switch ($char) { |
509
|
|
|
|
510
|
|
|
case 49: // 1 |
511
|
|
|
case 73: // I |
512
|
|
|
case 105: // i |
513
|
|
|
|
514
|
|
|
case 48: // 0 |
515
|
|
|
case 79: // O |
516
|
|
|
case 111: // o |
517
|
|
|
|
518
|
|
|
case 53: // 5 |
519
|
|
|
case 83: // S |
520
|
|
|
case 115: // s |
521
|
|
|
|
522
|
|
|
break; |
523
|
|
|
default: |
524
|
|
|
$charOK = true; |
525
|
|
|
break; |
526
|
|
|
} |
527
|
|
|
} else { |
528
|
|
|
$charOK = true; |
529
|
|
|
} |
530
|
|
|
} |
531
|
|
|
$pass .= ($upperCase ? strtoupper(chr($char)) : chr($char)); |
532
|
|
|
$lchar = $char; |
533
|
|
|
} |
534
|
|
|
return $pass; |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
|
538
|
|
|
/** |
539
|
|
|
* Translates a camel case string into a string with |
540
|
|
|
* underscores (e.g. firstName -> first_name) |
541
|
|
|
* |
542
|
|
|
* @param string $str String to convert |
543
|
|
|
* @return string $str translated from camel case |
544
|
|
|
*/ |
545
|
|
|
public static function unCamelCase($str) { |
546
|
|
|
return Inflector::camel2id(StringHelper::basename($str), '_'); |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
|
550
|
|
|
/** |
551
|
|
|
* Translates a string with underscores |
552
|
|
|
* into camel case (e.g. first_name -> firstName) |
553
|
|
|
* |
554
|
|
|
* @param string $str String to convert |
555
|
|
|
* @param bool $capitaliseFirst If true, capitalise the first char in $str |
556
|
|
|
* @return string $str translated into camel case |
557
|
|
|
*/ |
558
|
|
|
function camelCase($str, $capitaliseFirst = false) { |
559
|
|
|
if ($capitaliseFirst) { |
560
|
|
|
$str = Inflector::camelize($str); |
561
|
|
|
} else { |
562
|
|
|
$str = Inflector::variablize($str); |
563
|
|
|
} |
564
|
|
|
return $str; |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
|
568
|
|
|
/** |
569
|
|
|
* Debug helper function. This is a wrapper for var_dump() that adds |
570
|
|
|
* the <pre /> tags, cleans up newlines and indents, and runs |
571
|
|
|
* htmlentities() before output. |
572
|
|
|
* |
573
|
|
|
* @param mixed $var The variable to dump. |
574
|
|
|
* @param string $label OPTIONAL Label to prepend to output. |
575
|
|
|
* @param bool $echo OPTIONAL Echo output if true. |
576
|
|
|
* @return string |
577
|
|
|
*/ |
578
|
|
|
public static function debug($var, $label = null, $echo = true) |
579
|
|
|
{ |
580
|
|
|
// format the label |
581
|
|
|
$label = ($label===null) ? '' : trim($label) . ' '; |
582
|
|
|
|
583
|
|
|
// var_dump the variable into a buffer and keep the output |
584
|
|
|
ob_start(); |
585
|
|
|
var_dump($var); |
586
|
|
|
$output = ob_get_clean(); |
587
|
|
|
|
588
|
|
|
// neaten the newlines and indents |
589
|
|
|
$output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output); |
590
|
|
|
if (PHP_SAPI == 'cli') { |
591
|
|
|
$output = PHP_EOL . $label |
592
|
|
|
. PHP_EOL . $output |
593
|
|
|
. PHP_EOL; |
594
|
|
|
} else { |
595
|
|
|
$output = \yii\helpers\Html::encode($output); |
596
|
|
|
$output = '<pre>' . trim($label . $output) . '</pre>'; |
597
|
|
|
} |
598
|
|
|
|
599
|
|
|
if ($echo) { |
600
|
|
|
echo $output; |
601
|
|
|
} |
602
|
|
|
return $output; |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
|
606
|
|
|
/** |
607
|
|
|
* Check the email provided is of a valid syntax and check that the domain portion |
608
|
|
|
* of the email exists in DNS |
609
|
|
|
* |
610
|
|
|
* @param string $email |
611
|
|
|
* @return boolean |
612
|
|
|
*/ |
613
|
|
|
public static function emailsyntax_is_valid($email) |
614
|
|
|
{ |
615
|
|
|
if (strpos($email, "@") === FALSE) { // no @ in the email address is invalid |
616
|
|
|
// invalid |
617
|
|
|
} else { |
618
|
|
|
list ($local, $domain) = explode("@", $email); |
619
|
|
|
if (strlen($local) == 0 || strlen($domain) == 0) { |
620
|
|
|
// invalid |
621
|
|
|
} else { |
622
|
|
|
$pattern_local = '^([0-9a-z]*([-|_]?[0-9a-z]+)*)(([-|_]?)\.([-|_]?)[0-9a-z]*([-|_]?[0-9a-z]+)+)*([-|_]?)$'; |
623
|
|
|
$pattern_domain = '^([0-9a-z]+([-]?[0-9a-z]+)*)(([-]?)\.([-]?)[0-9a-z]*([-]?[0-9a-z]+)+)*\.[a-z]{2,4}$'; |
624
|
|
|
|
625
|
|
|
$match_local = eregi($pattern_local, $local); |
626
|
|
|
$match_domain = eregi($pattern_domain, $domain); |
627
|
|
|
|
628
|
|
|
if ($match_local && $match_domain) { |
629
|
|
|
if (getmxrr($domain, $validate_email_temp)) { |
630
|
|
|
return true; |
631
|
|
|
} elseif (gethostbyname($domain) != $domain) { |
632
|
|
|
return true; |
633
|
|
|
} |
634
|
|
|
} |
635
|
|
|
} |
636
|
|
|
} |
637
|
|
|
return false; |
638
|
|
|
} |
639
|
|
|
|
640
|
|
|
|
641
|
|
|
/** |
642
|
|
|
* Replicate the provided character the number of times specified |
643
|
|
|
* |
644
|
|
|
* @param string $strInput |
645
|
|
|
* @param integer $intCount |
646
|
|
|
* @return string |
647
|
|
|
*/ |
648
|
|
|
public static function repli($strInput, $intCount) |
649
|
|
|
{ |
650
|
|
|
$strResult = ''; |
651
|
|
|
for ($i = 0; $i < $intCount; $i ++) { |
652
|
|
|
$strResult = $strResult . $strInput; |
653
|
|
|
} |
654
|
|
|
return $strResult; |
655
|
|
|
} |
656
|
|
|
|
657
|
|
|
|
658
|
|
|
/** |
659
|
|
|
* Sort a multi dimension array by the key specificed |
660
|
|
|
* @return array |
661
|
|
|
*/ |
662
|
|
|
public static function array_csort() |
663
|
|
|
{ |
664
|
|
|
$sortarr = array(); |
665
|
|
|
$args = func_get_args(); |
666
|
|
|
$marray = array_shift($args); |
667
|
|
|
$msortline = "return(array_multisort("; |
668
|
|
|
$i = -1; |
669
|
|
|
foreach ($args as $arg) { |
670
|
|
|
$i ++; |
671
|
|
|
if (is_string($arg)) { |
672
|
|
|
$sortarr[$i] = array(); |
673
|
|
|
foreach ($marray as $row) { |
674
|
|
|
$sortarr[$i][] = $row[$arg]; |
675
|
|
|
} |
676
|
|
|
} else { |
677
|
|
|
$sortarr[$i] = $arg; |
678
|
|
|
} |
679
|
|
|
$msortline .= "\$sortarr[" . $i . "],"; |
680
|
|
|
} |
681
|
|
|
$msortline .= "\$marray));"; |
682
|
|
|
@eval($msortline); |
683
|
|
|
return $marray; |
684
|
|
|
} |
685
|
|
|
|
686
|
|
|
|
687
|
|
|
/** |
688
|
|
|
* Format a numeric value to the preferred decimal format |
689
|
|
|
* |
690
|
|
|
* @param float|double|string $value |
691
|
|
|
* @param integer $decimals, default 2 |
692
|
|
|
* @return string |
693
|
|
|
*/ |
694
|
|
|
public static function decimalFormat($value, $decimals = 2) |
695
|
|
|
{ |
696
|
|
|
return number_format($value, $decimals, '.', ''); |
697
|
|
|
} |
698
|
|
|
|
699
|
|
|
|
700
|
|
|
/** |
701
|
|
|
* Format a numeric value to the preferred tax rate format |
702
|
|
|
* |
703
|
|
|
* @param float|string $value |
704
|
|
|
* @param integer $decimals, default 6 |
705
|
|
|
* @return string |
706
|
|
|
*/ |
707
|
|
|
public static function rateFormat($value, $decimals = 6) |
708
|
|
|
{ |
709
|
|
|
return number_format($value, $decimals, '.', ''); |
710
|
|
|
} |
711
|
|
|
|
712
|
|
|
|
713
|
|
|
/** |
714
|
|
|
* Round values up to the specified level of precision |
715
|
|
|
* |
716
|
|
|
* @param float|double $value |
717
|
|
|
* @param integer $precision |
718
|
|
|
* @return double |
719
|
|
|
*/ |
720
|
|
|
public function roundUp($value, $precision = 0) |
721
|
|
|
{ |
722
|
|
|
// allows for rounding up to precision for pre PHP 5.3 |
723
|
|
|
if ($precision == 0) { |
724
|
|
|
$precisionFactor = 1; |
725
|
|
|
} else { |
726
|
|
|
$precisionFactor = pow(10, $precision); |
727
|
|
|
} |
728
|
|
|
return ceil($value * $precisionFactor) / $precisionFactor; |
729
|
|
|
} |
730
|
|
|
|
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* Round half values up to the specified level of precision |
734
|
|
|
* |
735
|
|
|
* @param double $value |
736
|
|
|
* @param integer $precision |
737
|
|
|
* @return double |
738
|
|
|
*/ |
739
|
|
|
public function roundHalfUp($value, $precision = 0) |
740
|
|
|
{ |
741
|
|
|
if (true) { |
742
|
|
|
// no php_round_half_up support |
743
|
|
|
// return round( $value , $precision ); // looks like the same/required result to me |
744
|
|
|
$precisionFactor = ($precision == 0) ? 1 : pow(10, $precision); |
745
|
|
|
return round($value * $precisionFactor) / $precisionFactor; |
746
|
|
|
} else { |
747
|
|
|
// PHP less than 5.3 does not support round half up |
748
|
|
|
return round($value, $precision, PHP_ROUND_HALF_UP); |
749
|
|
|
} |
750
|
|
|
} |
751
|
|
|
|
752
|
|
|
|
753
|
|
|
/** |
754
|
|
|
* Round the provided number up by the specified level of significance |
755
|
|
|
* |
756
|
|
|
* @param double $number |
757
|
|
|
* @param integer $significance |
758
|
|
|
* @return double |
759
|
|
|
*/ |
760
|
|
|
function roundUpBy($number, $significance = 1) |
761
|
|
|
{ |
762
|
|
|
return (is_numeric($number) && is_numeric($significance)) ? (double) (ceil($number / $significance) * $significance) : false; |
763
|
|
|
} |
764
|
|
|
|
765
|
|
|
|
766
|
|
|
/** |
767
|
|
|
* Convert a multi-lined string to an array |
768
|
|
|
* |
769
|
|
|
* @param string $valuex the string to be converted |
770
|
|
|
* @param boolean $isVariableList specify that the string contains a list of variables, default false |
771
|
|
|
* @param boolean $returnVariables should array of variables be returned, default false |
772
|
|
|
* @param boolean $returnIsInvalidVariables should invalid variables be returned as part of the array, default false |
773
|
|
|
* @param boolean $returnLowerVariables convert variables to lower case and return those, default false |
774
|
|
|
* @param boolean $returnLowerVariablesAsExtra return lower cases variables as part of the 'extra' array element, default false |
775
|
|
|
* @param string $validKeys regular expression of valid keys |
776
|
|
|
* @param boolean $keysOnly return only the variable names, default false |
777
|
|
|
* @return array|boolean|integer |
778
|
|
|
*/ |
779
|
|
|
public static function multiLineRecordToArray($valuex, $isVariableList = false, $returnVariables = false, $returnIsInvalidVariables = false, $returnLowerVariables = false, $returnLowerVariablesAsExtra = false, $validKeys = '', $keysOnly = false) |
780
|
|
|
{ |
781
|
|
|
if (trim($valuex) != '') { |
782
|
|
|
|
783
|
|
|
$invalidVariableCount = 0; |
784
|
|
|
|
785
|
|
|
$was = array( |
786
|
|
|
'\,', |
787
|
|
|
'\;', |
788
|
|
|
'\=', |
789
|
|
|
'\&' |
790
|
|
|
); |
791
|
|
|
$now = array( |
792
|
|
|
'##comma##', |
793
|
|
|
'##semicolon##', |
794
|
|
|
'##equals##', |
795
|
|
|
'##amp##' |
796
|
|
|
); |
797
|
|
|
$valuex = str_replace($was, $now, $valuex); |
798
|
|
|
|
799
|
|
|
if ($isVariableList) { |
800
|
|
|
while (strpos($valuex, ' =') !== FALSE) { |
801
|
|
|
$valuex = str_replace(' =', '=', $valuex); |
802
|
|
|
} |
803
|
|
|
while (strpos($valuex, '= ') !== FALSE) { |
804
|
|
|
$valuex = str_replace('= ', '=', $valuex); |
805
|
|
|
} |
806
|
|
|
if ($returnVariables || $returnIsInvalidVariables) { |
807
|
|
|
$vals2 = array(); |
808
|
|
|
} |
809
|
|
|
} |
810
|
|
|
|
811
|
|
|
$vals = preg_split('/[&,;\r\n]/', $valuex, - 1, PREG_SPLIT_NO_EMPTY); |
812
|
|
|
if ($vals) { |
813
|
|
|
$xValCount = count($vals); |
814
|
|
|
for ($xVal = 0; $xVal < $xValCount; $xVal ++) { |
815
|
|
|
if ($vals[$xVal] != '') { |
816
|
|
|
$was = array( |
817
|
|
|
'##comma##', |
818
|
|
|
'##semicolon##', |
819
|
|
|
'##equals##', |
820
|
|
|
'##amp##' |
821
|
|
|
); |
822
|
|
|
$now = array( |
823
|
|
|
',', |
824
|
|
|
';', |
825
|
|
|
'=', |
826
|
|
|
'&' |
827
|
|
|
); |
828
|
|
|
$vals[$xVal] = str_replace($was, $now, trim($vals[$xVal])); |
829
|
|
|
if ($isVariableList) { |
830
|
|
|
if ($returnVariables || $returnIsInvalidVariables) { |
831
|
|
|
if (substr_count($vals[$xVal], '=') > 0) { |
832
|
|
|
list ($x, $y) = explode('=', $vals[$xVal], 2); |
833
|
|
|
} else { |
834
|
|
|
$x = $vals[$xVal]; |
835
|
|
|
$y = ''; |
836
|
|
|
} |
837
|
|
|
|
838
|
|
|
if ($validKeys != '') { |
839
|
|
|
$validVariable = eregi('^([' . $validKeys . ']*)$', $x); |
840
|
|
|
} else { |
841
|
|
|
$validVariable = eregi('^([0-9a-z_-]*)$', $x); |
842
|
|
|
} |
843
|
|
|
if (! $validVariable) { |
844
|
|
|
$invalidVariableCount ++; |
845
|
|
|
} else { |
846
|
|
|
if ($returnLowerVariables) { |
847
|
|
|
$x = strtolower($x); |
848
|
|
|
} |
849
|
|
|
$vals2[$x] = $y; |
850
|
|
|
if ($returnLowerVariablesAsExtra) { |
851
|
|
|
$x2 = strtolower($x); |
852
|
|
|
if ($x2 != $x) { |
853
|
|
|
$vals2[$x2] = $y; |
854
|
|
|
} |
855
|
|
|
} |
856
|
|
|
} |
857
|
|
|
} |
858
|
|
|
} |
859
|
|
|
} |
860
|
|
|
} |
861
|
|
|
} |
862
|
|
|
if ($isVariableList && $returnVariables && $returnIsInvalidVariables) { |
863
|
|
|
return array( |
864
|
|
|
$invalidVariableCount, |
865
|
|
|
$vals2 |
866
|
|
|
); |
867
|
|
|
} elseif ($isVariableList && $returnVariables) { |
868
|
|
|
if ($keysOnly) { |
869
|
|
|
return array_keys($vals2); |
870
|
|
|
} else { |
871
|
|
|
return $vals2; |
872
|
|
|
} |
873
|
|
|
} elseif ($isVariableList && $returnIsInvalidVariables) { |
874
|
|
|
return $invalidVariableCount; |
875
|
|
|
} else { |
876
|
|
|
return $vals; |
877
|
|
|
} |
878
|
|
|
} else { |
879
|
|
|
return false; |
880
|
|
|
} |
881
|
|
|
} |
882
|
|
|
|
883
|
|
|
|
884
|
|
|
/** |
885
|
|
|
* Return string converted to upper case |
886
|
|
|
* |
887
|
|
|
* @param string $str string to be converted |
888
|
|
|
* @param string $encoding encoding default UTF-8 |
889
|
|
|
* @return string |
890
|
|
|
*/ |
891
|
|
|
public static function fullUpper($str, $encoding = 'UTF-8') |
892
|
|
|
{ |
893
|
|
|
return mb_strtoupper($str, $encoding); |
894
|
|
|
} |
895
|
|
|
|
896
|
|
|
|
897
|
|
|
/** |
898
|
|
|
* Return string converted to lower case |
899
|
|
|
* |
900
|
|
|
* @param string $str string to be converted |
901
|
|
|
* @param string $encoding encoding default UTF-8 |
902
|
|
|
* @return string |
903
|
|
|
*/ |
904
|
|
|
public static function fullLower($str, $encoding = 'UTF-8') |
905
|
|
|
{ |
906
|
|
|
return mb_strtolower($str, $encoding); |
907
|
|
|
} |
908
|
|
|
|
909
|
|
|
/** |
910
|
|
|
* Return length of a string |
911
|
|
|
* |
912
|
|
|
* @param string $str string to be checked |
913
|
|
|
* @param string $encoding encoding default UTF-8 |
914
|
|
|
* @return integer |
915
|
|
|
*/ |
916
|
|
|
public static function strlen($str, $encoding = 'UTF-8') |
917
|
|
|
{ |
918
|
|
|
return mb_strlen($str, $encoding); |
919
|
|
|
} |
920
|
|
|
|
921
|
|
|
|
922
|
|
|
/** |
923
|
|
|
* Return a substring of a string |
924
|
|
|
* |
925
|
|
|
* @param string $str string to be conerted |
926
|
|
|
* @param integer $start |
927
|
|
|
* @param integer|null $length |
928
|
|
|
* @param string $encoding encoding default UTF-8 |
929
|
|
|
* @return string |
930
|
|
|
*/ |
931
|
|
|
public static function substr($str, $start, $length = null, $encoding = 'UTF-8') |
932
|
|
|
{ |
933
|
|
|
return mb_substr($str, $start, $length, $encoding); |
934
|
|
|
} |
935
|
|
|
|
936
|
|
|
|
937
|
|
|
public static function titleCase($string, $delimiters = array(" ", "-", ".", "'", "O'", "Mc"), $exceptions = array("and", "�t", "�s", "utca", "t�r", "krt", "k�r�t", "s�t�ny", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX", "XXI", "XXII", "XXIII", "XXIV", "XXV", "XXVI", "XXVII", "XXVIII", "XXIX", "XXX", "GTFO", "AP", "CD", "OS", "rue", "des", "UK", "USA"), $enc = 'UTF-8') |
938
|
|
|
{ |
939
|
|
|
$string = mb_convert_case($string, MB_CASE_TITLE, $enc); |
940
|
|
|
|
941
|
|
|
foreach ($delimiters as $dlnr => $delimiter) { |
942
|
|
|
$words = explode($delimiter, $string); |
943
|
|
|
$newwords = array(); |
944
|
|
|
foreach ($words as $wordnr => $word) { |
945
|
|
|
if (in_array(mb_strtoupper($word, $enc), $exceptions)) { |
946
|
|
|
// check exceptions list for any words that should be in upper case |
947
|
|
|
$word = mb_strtoupper($word, $enc); |
948
|
|
|
} elseif (in_array(mb_strtolower($word, $enc), $exceptions)) { |
949
|
|
|
// check exceptions list for any words that should be in upper case |
950
|
|
|
$word = mb_strtolower($word, $enc); |
951
|
|
|
} elseif (! in_array($word, $exceptions)) { |
952
|
|
|
// convert to uppercase |
953
|
|
|
$word = ucfirst($word); |
954
|
|
|
} |
955
|
|
|
array_push($newwords, $word); |
956
|
|
|
} |
957
|
|
|
$string = join($delimiter, $newwords); |
958
|
|
|
} // foreach |
959
|
|
|
|
960
|
|
|
$new = $string; |
961
|
|
|
|
962
|
|
|
if (strpos($new, "'S") !== FALSE) { |
963
|
|
|
$new = str_replace("'S", "'s", $new); |
964
|
|
|
} |
965
|
|
|
|
966
|
|
|
return $new; |
967
|
|
|
} |
968
|
|
|
|
969
|
|
|
|
970
|
|
|
/** |
971
|
|
|
* Convert a string to an array of lines word wrapped at a fixed number of characters using |
972
|
|
|
* a multi-byte safe word wrap function |
973
|
|
|
* |
974
|
|
|
* @param string $inputText |
975
|
|
|
* @param integer $lines |
976
|
|
|
* @param integer $width |
977
|
|
|
* @param boolean $cut |
978
|
|
|
* @param string $break |
979
|
|
|
* @param string $charSet |
980
|
|
|
* @return string |
981
|
|
|
*/ |
982
|
|
|
public static function convertLongTextToLines($inputText, $lines = 5, $width = 35, $cut = true, $break = "\n", $charSet = 'utf-8') |
983
|
|
|
{ |
984
|
|
|
$newText = Tools::iconv_wordwrap($inputText, $width, $break, $cut, $charSet); |
985
|
|
|
$array = mb_split($break, $newText); |
986
|
|
|
$arrayCount = count($array); |
987
|
|
|
if ($arrayCount < $lines) { |
988
|
|
|
for ($x = $arrayCount; $x < $lines; $x ++) { |
989
|
|
|
$array[$x] = ''; |
990
|
|
|
} |
991
|
|
|
} |
992
|
|
|
return $array; |
993
|
|
|
} |
994
|
|
|
|
995
|
|
|
|
996
|
|
|
/** |
997
|
|
|
* Multi-byte safe Word wrap |
998
|
|
|
* |
999
|
|
|
* @param string $string |
1000
|
|
|
* @param integer $width |
1001
|
|
|
* @param string $break |
1002
|
|
|
* @param boolean $cut |
1003
|
|
|
* @param string $charset |
1004
|
|
|
* @return string |
1005
|
|
|
*/ |
1006
|
|
|
public static function iconv_wordwrap($string, $width = 75, $break = "\n", $cut = false, $charset = 'utf-8') |
1007
|
|
|
{ |
1008
|
|
|
$stringWidth = iconv_strlen($string, $charset); |
1009
|
|
|
$breakWidth = iconv_strlen($break, $charset); |
1010
|
|
|
|
1011
|
|
|
if (mb_strlen($string) === 0) { |
1012
|
|
|
return ''; |
1013
|
|
|
} |
1014
|
|
|
|
1015
|
|
|
if ($break == "\n") { |
1016
|
|
|
$string = str_replace("\r", '', $string); |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
|
|
$result = ''; |
1020
|
|
|
$lastStart = $lastSpace = 0; |
1021
|
|
|
|
1022
|
|
|
for ($current = 0; $current < $stringWidth; $current ++) { |
1023
|
|
|
$char = iconv_substr($string, $current, 1, $charset); |
1024
|
|
|
|
1025
|
|
|
if ($breakWidth === 1) { |
1026
|
|
|
$possibleBreak = $char; |
1027
|
|
|
} else { |
1028
|
|
|
$possibleBreak = iconv_substr($string, $current, $breakWidth, $charset); |
1029
|
|
|
} |
1030
|
|
|
|
1031
|
|
|
if ($possibleBreak === $break) { |
1032
|
|
|
$result .= iconv_substr($string, $lastStart, $current - $lastStart + $breakWidth, $charset); |
1033
|
|
|
$current += $breakWidth - 1; |
1034
|
|
|
$lastStart = $lastSpace = $current + 1; |
1035
|
|
|
} elseif ($char === ' ') { |
1036
|
|
|
if ($current - $lastStart >= $width) { |
1037
|
|
|
$result .= iconv_substr($string, $lastStart, $current - $lastStart, $charset) . $break; |
1038
|
|
|
$lastStart = $current + 1; |
1039
|
|
|
} |
1040
|
|
|
$lastSpace = $current; |
1041
|
|
|
} elseif ($current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) { |
1042
|
|
|
$result .= iconv_substr($string, $lastStart, $current - $lastStart, $charset) . $break; |
1043
|
|
|
$lastStart = $lastSpace = $current; |
1044
|
|
|
} elseif ($current - $lastStart >= $width && $lastStart < $lastSpace) { |
1045
|
|
|
$result .= iconv_substr($string, $lastStart, $lastSpace - $lastStart, $charset) . $break; |
1046
|
|
|
$lastStart = $lastSpace = $lastSpace + 1; |
1047
|
|
|
} |
1048
|
|
|
} |
1049
|
|
|
if ($lastStart !== $current) { |
1050
|
|
|
$result .= iconv_substr($string, $lastStart, $current - $lastStart, $charset); |
1051
|
|
|
} |
1052
|
|
|
return $result; |
1053
|
|
|
} |
1054
|
|
|
|
1055
|
|
|
|
1056
|
|
|
/** |
1057
|
|
|
* Count the number of words within a string |
1058
|
|
|
* @param string $string |
1059
|
|
|
* @return integer |
1060
|
|
|
*/ |
1061
|
|
|
public static function wordCount($string) |
1062
|
|
|
{ |
1063
|
|
|
$wordCount = 0; |
1064
|
|
|
$_tString = trim($string); |
1065
|
|
|
if ($_tString != '') { |
1066
|
|
|
$wordCount = count(preg_split('/\W+/', $_tString, - 1, PREG_SPLIT_NO_EMPTY)); |
1067
|
|
|
} |
1068
|
|
|
return $wordCount; |
1069
|
|
|
} |
1070
|
|
|
|
1071
|
|
|
|
1072
|
|
|
/** |
1073
|
|
|
* Take a deep copy og an object without leaving in place any references to itself |
1074
|
|
|
* @param mixed $object |
1075
|
|
|
* @return mixed |
1076
|
|
|
*/ |
1077
|
|
|
public static function deepCopy($object) |
1078
|
|
|
{ |
1079
|
|
|
return unserialize(serialize($object)); |
1080
|
|
|
} |
1081
|
|
|
|
1082
|
|
|
|
1083
|
|
|
/** |
1084
|
|
|
* Given a string in datetime format YYYY-MM-DD HH:MM:SS return a string |
1085
|
|
|
* that represents how by default the app would like such values to be shown |
1086
|
|
|
* |
1087
|
|
|
* @param string $datetime |
1088
|
|
|
* @return string |
1089
|
|
|
*/ |
1090
|
|
|
public static function stdDateTimeFormat($datetime) |
1091
|
|
|
{ |
1092
|
|
|
$time = strtotime($datetime); |
1093
|
|
|
$format = 'd-m-Y H:i:s'; |
1094
|
|
|
if (isset(\Yii::$app->params['app.dateTimeFormat'])) { |
1095
|
|
|
$format = \Yii::$app->params['app.dateTimeFormat']; |
1096
|
|
|
} |
1097
|
|
|
return date($format, $time); |
1098
|
|
|
} |
1099
|
|
|
|
1100
|
|
|
|
1101
|
|
|
/** |
1102
|
|
|
* |
1103
|
|
|
* @param string $key the key identifying the flash message. Note that flash messages |
1104
|
|
|
* and normal session variables share the same name space. If you have a normal |
1105
|
|
|
* session variable using the same name, its value will be overwritten by this method. |
1106
|
|
|
* Can be [alert|note]-[success|info|warning|danger|error] e.g. alert-success, note-success or success |
1107
|
|
|
* @param mixed $value flash message |
1108
|
|
|
* @param string|false $title [optional] Title to be used in flash message when supported |
1109
|
|
|
* @param boolean $dismiss [optional] Allow flash message to be dismissable |
1110
|
|
|
* @param string|false $class [optional] Extra class attribute to be added to flash message div when supported |
1111
|
|
|
* @param string|array|false $extra [optional] Array of extra values to be listed (li) with the flash message when supported |
1112
|
|
|
*/ |
1113
|
|
|
public static function setFlash($key, $value, $title = false, $dismiss = true, $class = false, $extra = false) |
1114
|
|
|
{ |
1115
|
|
|
$values = [ |
1116
|
|
|
$value, |
1117
|
|
|
$title, |
1118
|
|
|
$dismiss, |
1119
|
|
|
$class, |
1120
|
|
|
$extra, |
1121
|
|
|
]; |
1122
|
|
|
\Yii::$app->session->setFlash($key, $values); |
1123
|
|
|
} |
1124
|
|
|
|
1125
|
|
|
public static function sessionArrayRecord($value, $attribute, $default = false, $element = 'auto') |
1126
|
|
|
{ |
1127
|
|
|
if (!$value) { |
1128
|
|
|
$arr = \Yii::$app->session->get($element, []); |
1129
|
|
|
$value = ArrayHelper::getValue($arr, $attribute, $default); |
1130
|
|
|
} else { |
1131
|
|
|
$arr = \Yii::$app->session->get($element, []); |
1132
|
|
|
$arr[$attribute] = $value; |
1133
|
|
|
\Yii::$app->session->set($element, $arr); |
1134
|
|
|
} |
1135
|
|
|
return $value; |
1136
|
|
|
} |
1137
|
|
|
|
1138
|
|
|
/** |
1139
|
|
|
* Check to see if a string exists within another that has been structured for such a search |
1140
|
|
|
* @param string $needle 'stack' |
1141
|
|
|
* @param string $haystack '/hay/stack/to/search/' |
1142
|
|
|
* @param string $delimiter [optional] default '/' |
1143
|
|
|
* @return boolean |
1144
|
|
|
*/ |
1145
|
|
|
public static function in($needle, $haystack, $delimiter = '/') |
1146
|
|
|
{ |
1147
|
|
|
if (substr($haystack, 0, 1) != $delimiter) { |
1148
|
|
|
$haystack = $delimiter . $haystack; |
1149
|
|
|
} |
1150
|
|
|
if (substr($haystack, -1, 1) != $delimiter) { |
1151
|
|
|
$haystack = $haystack . $delimiter; |
1152
|
|
|
} |
1153
|
|
|
return (strpos($haystack, $delimiter . $needle . $delimiter) !== false ? true : false); |
1154
|
|
|
} |
1155
|
|
|
|
1156
|
|
|
/** |
1157
|
|
|
* Obtain class name |
1158
|
|
|
* |
1159
|
|
|
* @return string the fully qualified name of this class. |
1160
|
|
|
*/ |
1161
|
|
|
public static function className() |
1162
|
|
|
{ |
1163
|
|
|
return get_called_class(); |
1164
|
|
|
} |
1165
|
|
|
|
1166
|
|
|
} |
1167
|
|
|
|
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.