Num   B
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 411
Duplicated Lines 6.57 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 36
c 3
b 0
f 1
lcom 2
cbo 1
dl 27
loc 411
rs 8.8

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B bytes() 0 28 2
A formatBytes() 0 20 3
B quantity() 0 17 6
B format() 0 28 5
B maskString() 0 33 6
A formatPhone() 9 9 3
A smartFormatPhone() 0 11 4
A formatExp() 9 9 3
A maskCreditCard() 9 9 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * @package    Fuel\Common
4
 * @version    2.0
5
 * @author     Fuel Development Team
6
 * @author     Chase "Syntaqx" Hutchins
7
 * @license    MIT License
8
 * @copyright  2010 - 2015 Fuel Development Team
9
 * @link       http://fuelphp.com
10
 */
11
12
namespace Fuel\Common;
13
14
/**
15
 * Numeric helper class. Provides additional formatting methods for working with
16
 * numeric values.
17
 *
18
 * Credit where credit is due:
19
 *
20
 * Techniques and inspiration were taken from all over, including:
21
 *	Kohana Framework: kohanaframework.org
22
 *	CakePHP: cakephp.org
23
 *
24
 * @since 1.0
25
 */
26
class Num
27
{
28
	/**
29
	 * @var  array  Byte units
30
	 */
31
	protected $byteUnits = array(
32
		'B'   => 0,
33
		'K'   => 10,
34
		'Ki'  => 10,
35
		'KB'  => 10,
36
		'KiB' => 10,
37
		'M'   => 20,
38
		'Mi'  => 20,
39
		'MB'  => 20,
40
		'MiB' => 20,
41
		'G'   => 30,
42
		'Gi'  => 30,
43
		'GB'  => 30,
44
		'GiB' => 30,
45
		'T'   => 40,
46
		'Ti'  => 40,
47
		'TB'  => 40,
48
		'TiB' => 40,
49
		'P'   => 50,
50
		'Pi'  => 50,
51
		'PB'  => 50,
52
		'PiB' => 50,
53
		'E'   => 60,
54
		'Ei'  => 60,
55
		'EB'  => 60,
56
		'EiB' => 60,
57
		'Z'   => 70,
58
		'Zi'  => 70,
59
		'ZB'  => 70,
60
		'ZiB' => 70,
61
		'Y'   => 80,
62
		'Yi'  => 80,
63
		'YB'  => 80,
64
		'YiB' => 80,
65
	);
66
67
	/**
68
	 * @var  array  Configuration values
69
	 */
70
	protected $config = array(
71
		// formatPhone()
72
		'phone' => '(000) 000-0000',
73
74
		// smartFormatPhone()
75
		'smartPhone' => array(
76
			7  => '000-0000',
77
			10 => '(000) 000-0000',
78
			11 => '0 (000) 000-0000',
79
		),
80
81
		// formatExp()
82
		'exp' => '00-00',
83
84
		// maskCreditCard()
85
		'creditCard' => '**** **** **** 0000',
86
	);
87
88
	/**
89
	 * Class constructor
90
	 *
91
	 * @param  array  $config     Configuration array
92
	 * @param  array  $byteUnits  Optional language dependent list of Byte Units
93
	 *
94
	 * @return  void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
95
	 *
96
	 * @since 2.0.0
97
	 */
98
	public function __construct(Array $config = array(), Array $byteUnits = array())
99
	{
100
		$this->config = array_merge($this->config, $config);
101
		$this->byteUnits = array_merge($this->byteUnits, $byteUnits);
102
	}
103
104
	/**
105
	 * Converts a file size number to a byte value. File sizes are defined in
106
	 * the format: SB, where S is the size (1, 8.5, 300, etc.) and B is the
107
	 * byte unit (K, MiB, GB, etc.). All valid byte units are defined in
108
	 * $this->byteUnits
109
	 *
110
	 * Usage:
111
	 * <code>
112
	 * $num = new \Fuel\Common\Num();
113
	 * echo $num->bytes('200K');  // 204800
114
	 * echo $num->bytes('5MiB');  // 5242880
115
	 * echo $num->bytes('1000');  // 1000
116
	 * echo $num->bytes('2.5GB'); // 2684354560
117
	 * </code>
118
	 *
119
	 * @author     Kohana Team
120
	 * @copyright  (c) 2009-2011 Kohana Team
121
	 * @license    http://kohanaframework.org/license
122
	 *
123
	 * @param  string  File size in SB format
124
	 *
125
	 * @return  float
126
	 *
127
	 * @since 1.0.0
128
	 */
129
	public function bytes($size = 0)
130
	{
131
		// Prepare the size
132
		$size = trim((string) $size);
133
134
		// Construct an OR list of byte units for the regex
135
		$accepted = implode('|', array_keys($this->byteUnits));
136
137
		// Construct the regex pattern for verifying the size format
138
		$pattern = '/^([0-9]+(?:\.[0-9]+)?)('.$accepted.')?$/Di';
139
140
		// Verify the size format and store the matching parts
141
		if (!preg_match($pattern, $size, $matches))
142
		{
143
			throw new \Exception('The byte unit size, "'.$size.'", is improperly formatted.');
144
		}
145
146
		// Find the float value of the size
147
		$size = (float) $matches[1];
148
149
		// Find the actual unit, assume B if no unit specified
150
		$unit = Arr::get($matches, 2, 'B');
151
152
		// Convert the size into bytes
153
		$bytes = $size * pow(2, $this->byteUnits[$unit]);
154
155
		return $bytes;
156
	}
157
158
	/**
159
	 * Converts a number of bytes to a human readable number by taking the
160
	 * number of that unit that the bytes will go into it. Supports TB value.
161
	 *
162
	 * Note: Integers in PHP are limited to 32 bits, unless they are on 64 bit
163
	 * architectures, then they have 64 bit size. If you need to place the
164
	 * larger size then what the PHP integer type will hold, then use a string.
165
	 * It will be converted to a double, which should always have 64 bit length.
166
	 *
167
	 * @param  int  the byte number to format
168
	 * @param  int  number of decimals
169
	 *
170
	 * @return  boolean|string  formatted string, or false if formatting failed
171
	 *
172
	 * @since 1.0.0
173
	 */
174
	public function formatBytes($bytes = 0, $decimals = 0)
175
	{
176
		static $quant = array(
177
			'TB' => 1099511627776,  // pow( 1024, 4)
178
			'GB' => 1073741824,     // pow( 1024, 3)
179
			'MB' => 1048576,        // pow( 1024, 2)
180
			'KB' => 1024,           // pow( 1024, 1)
181
			'B ' => 1,              // pow( 1024, 0)
182
		);
183
184
		foreach ($quant as $unit => $mag )
185
		{
186
			if (doubleval($bytes) >= $mag)
187
			{
188
				return sprintf('%01.'.$decimals.'f', ($bytes / $mag)).' '.$unit;
189
			}
190
		}
191
192
		return false;
193
	}
194
195
	/**
196
	 * Converts a number into a more readable human-type number.
197
	 *
198
	 * Usage:
199
	 * <code>
200
	 * $num = new \Fuel\Common\Num();
201
	 * echo $num->quantity(7000); // 7K
202
	 * echo $num->quantity(7500); // 8K
203
	 * echo $num->quantity(7500, 1); // 7.5K
204
	 * </code>
205
	 *
206
	 * @param  int  Number to convert
207
	 * @param  int  Number of decimals in the converted result
208
	 *
209
	 * @return  string  The converted number
210
	 *
211
	 * @since 1.0.0
212
	 */
213
	public function quantity($num, $decimals = 0)
214
	{
215
		if ($num >= 1000 && $num < 1000000)
216
		{
217
			return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000)).'K';
218
		}
219
		elseif ($num >= 1000000 && $num < 1000000000)
220
		{
221
			return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000000)).'M';
222
		}
223
		elseif ($num >= 1000000000)
224
		{
225
			return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000000000)).'B';
226
		}
227
228
		return $num;
229
	}
230
231
	/**
232
	 * Formats a number by injecting non-numeric characters in a specified
233
	 * format into the string in the positions they appear in the format.
234
	 *
235
	 * Usage:
236
	 * <code>
237
	 * $num = new \Fuel\Common\Num();
238
	 * echo $num->format('1234567890', '(000) 000-0000'); // (123) 456-7890
239
	 * echo $num->format('1234567890', '000.000.0000'); // 123.456.7890
240
	 * </code>
241
	 *
242
	 * @link    http://snippets.symfony-project.org/snippet/157
243
	 *
244
	 * @param  string  The string to format
245
	 * @param  string  The format to apply
246
	 *
247
	 * @return  string  Formatted number
248
	 *
249
	 * @since 1.0.0
250
	 */
251
	public function format($string, $format)
252
	{
253
		if(empty($format) or empty($string))
254
		{
255
			return $string;
256
		}
257
258
		$result = '';
259
		$fpos = 0;
260
		$spos = 0;
261
262
		while ((strlen($format) - 1) >= $fpos)
263
		{
264
			if (ctype_alnum(substr($format, $fpos, 1)))
265
			{
266
				$result .= substr($string, $spos, 1);
267
				$spos++;
268
			}
269
			else
270
			{
271
				$result .= substr($format, $fpos, 1);
272
			}
273
274
			$fpos++;
275
		}
276
277
		return $result;
278
	}
279
280
	/**
281
	 * Transforms a number by masking characters in a specified mask format, and
282
	 * ignoring characters that should be injected into the string without
283
	 * matching a character from the original string (defaults to space).
284
	 *
285
	 * Usage:
286
	 * <code>
287
	 * $num = new \Fuel\Common\Num();
288
	 * echo $num->maskString('1234567812345678', '************0000'); ************5678
289
	 * echo $num->maskString('1234567812345678', '**** **** **** 0000'); // **** **** **** 5678
290
	 * echo $num->maskString('1234567812345678', '**** - **** - **** - 0000', ' -'); // **** - **** - **** - 5678
291
	 * </code>
292
	 *
293
	 * @link    http://snippets.symfony-project.org/snippet/157
294
	 *
295
	 * @param  string  The string to transform
296
	 * @param  string  The mask format
297
	 * @param  string  A string (defaults to a single space) containing characters to ignore in the format
298
	 *
299
	 * @return  string  The masked string
300
	 *
301
	 * @since 1.0.0
302
	 */
303
	public function maskString($string, $format = '', $ignore = ' ')
304
	{
305
		if(empty($format) or empty($string))
306
		{
307
			return $string;
308
		}
309
310
		$result = '';
311
		$fpos = 0;
312
		$spos = 0;
313
314
		while ((strlen($format) - 1) >= $fpos)
315
		{
316
			if (ctype_alnum(substr($format, $fpos, 1)))
317
			{
318
				$result .= substr($string, $spos, 1);
319
				$spos++;
320
			}
321
			else
322
			{
323
				$result .= substr($format, $fpos, 1);
324
325
				if (strpos($ignore, substr($format, $fpos, 1)) === false)
326
				{
327
					++$spos;
328
				}
329
			}
330
331
			++$fpos;
332
		}
333
334
		return $result;
335
	}
336
337
	/**
338
	 * Formats a phone number.
339
	 *
340
	 * @link    http://snippets.symfony-project.org/snippet/157
341
	 *
342
	 * @param  string  The unformatted phone number to format
343
	 * @param  string  The format to use, defaults to '(000) 000-0000'
344
	 *
345
	 * @return  string  The formatted string
346
	 *
347
	 * @see  format
348
	 *
349
	 * @since 1.0.0
350
	 */
351 View Code Duplication
	public function formatPhone($string = '', $format = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
352
	{
353
		if ($format === null)
354
		{
355
			$format = isset($this->config['phone']) ? $this->config['phone'] : '(000) 000-0000';
356
		}
357
358
		return $this->format($string, $format);
0 ignored issues
show
Bug introduced by
It seems like $string defined by parameter $string on line 351 can also be of type string; however, Fuel\Common\Num::format() does only seem to accept object<Fuel\Common\The>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
359
	}
360
361
	/**
362
	 * Formats a variable length phone number, using a standard format.
363
	 *
364
	 * Usage:
365
	 * <code>
366
	 * $num = new \Fuel\Common\Num();
367
	 * echo $num->smartFormatPhone('1234567'); // 123-4567
368
	 * echo $num->smartFormatPhone('1234567890'); // (123) 456-7890
369
	 * echo $num->smartFormatPhone('91234567890'); // 9 (123) 456-7890
370
	 * echo $num->smartFormatPhone('123456'); // => 123456
371
	 * </code>
372
	 *
373
	 * @param  string  The unformatted phone number to format
374
	 *
375
	 * @return  string  The formatted string
376
	 *
377
	 * @see  format
378
	 *
379
	 * @since 1.0.0
380
	 */
381
	public function smartFormatPhone($string)
382
	{
383
		$formats = isset($this->config['smartPhone']) ? $this->config['smartPhone'] : null;
384
385
		if (is_array($formats) and isset($formats[strlen($string)]))
386
		{
387
			return $this->format($string, $formats[strlen($string)]);
388
		}
389
390
		return $string;
391
	}
392
393
	/**
394
	 * Formats a credit card expiration string. Expects 4-digit string (MMYY).
395
	 *
396
	 * @param  string  The unformatted expiration string to format
397
	 * @param  string  The format to use, defaults to '00-00'
398
	 *
399
	 * @return  string  The formatted string
400
	 *
401
	 * @see  format
402
	 *
403
	 * @since 1.0.0
404
	 */
405 View Code Duplication
	public function formatExp($string, $format = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
406
	{
407
		if ($format === null)
408
		{
409
			$format = isset($this->config['exp']) ? $this->config['exp'] : '00-00';
410
		}
411
412
		return $this->format($string, $format);
413
	}
414
415
	/**
416
	 * Formats (masks) a credit card.
417
	 *
418
	 * @param  string  The unformatted credit card number to format
419
	 * @param  string  The format to use, defaults to '**** **** **** 0000'
420
	 *
421
	 * @return  string  The masked string
422
	 *
423
	 * @see     maskString
424
	 *
425
	 * @since 1.0.0
426
	 */
427 View Code Duplication
	public function maskCreditCard($string, $format = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
428
	{
429
		if ($format === null)
430
		{
431
			$format = isset($this->config['creditCard']) ? $this->config['creditCard'] : '**** **** **** 0000';
432
		}
433
434
		return $this->maskString($string, $format);
435
	}
436
}
437