Parser::parse()   C
last analyzed

Complexity

Conditions 13
Paths 216

Size

Total Lines 81
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 13.0036

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 13
eloc 36
c 2
b 0
f 0
nc 216
nop 1
dl 0
loc 81
ccs 35
cts 36
cp 0.9722
crap 13.0036
rs 5.5833

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Parser
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2023 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Money
9
 */
10
11
namespace Pronamic\WordPress\Money;
12
13
use Exception;
14
15
/**
16
 * Parser
17
 *
18
 * @author  Remco Tolsma
19
 * @version 2.0.0
20
 * @since   1.1.0
21
 */
22
class Parser {
23
	/**
24
	 * Parse.
25
	 *
26
	 * @link https://github.com/wp-pay/core/blob/2.0.2/src/Core/Util.php#L128-L176
27
	 *
28
	 * @param string $string String to parse as money.
29
	 *
30
	 * @return Money
31
	 *
32
	 * @throws Exception Throws exception when parsing string fails.
33
	 */
34 59
	public function parse( $string ) {
35 59
		global $wp_locale;
36
37 59
		$decimal_sep = $wp_locale->number_format['decimal_point'];
38
39
		// Separators.
40 59
		$separators = [ $decimal_sep, '.', ',' ];
41 59
		$separators = array_unique( array_filter( $separators ) );
42
43
		// Check.
44 59
		foreach ( [ - 3, - 2 ] as $i ) {
45 59
			$test = substr( $string, $i, 1 );
46
47 59
			if ( in_array( $test, $separators, true ) ) {
48 37
				$decimal_sep = $test;
49
50 59
				break;
51
			}
52
		}
53
54
		// Split.
55 59
		$position = false;
56
57 59
		if ( is_string( $decimal_sep ) ) {
58 58
			$position = strrpos( $string, $decimal_sep );
59
		}
60
61
		// Check decimal position on -4th position at end of string of negative amount (e.g. `2.500,75-`).
62 59
		if ( false === $position && '-' === \substr( $string, -1, 1 ) ) {
63 7
			$test = substr( $string, -4, 1 );
64
65 7
			if ( is_string( $test ) && in_array( $test, $separators, true ) ) {
66 1
				$position = strrpos( $string, $test );
67
			}
68
		}
69
70 59
		if ( false !== $position ) {
71 42
			$full = substr( $string, 0, $position );
72 42
			$half = substr( $string, $position + 1 );
73
74
			/*
75
			 * Consider `-` after decimal separator as alternative notation for 'no minor units' (e.g. `€ 5,-`).
76
			 *
77
			 * @link https://taaladvies.net/taal/advies/vraag/275/euro_komma_en_streepje_in_de_notatie_van_hele_bedragen/
78
			 */
79 42
			if ( \in_array( $half, [ '-', '–', '—' ], true ) ) {
80 2
				$half = '';
81
			}
82
83 42
			$end_minus = ( '-' === \substr( $half, -1, 1 ) );
84
85 42
			$full = filter_var( $full, FILTER_SANITIZE_NUMBER_INT );
86 42
			$half = filter_var( $half, FILTER_SANITIZE_NUMBER_INT );
87
88
			// Make amount negative if half string ends with minus sign.
89 42
			if ( $end_minus ) {
90
				// Make full negative.
91 3
				$full = sprintf( '-%s', $full );
92
93
				// Remove minus from end of half.
94 3
				$half = \substr( (string) $half, 0, -1 );
95
			}
96
97 42
			$string = $full . '.' . $half;
98
		} else {
99
			// Make amount negative if full string ends with minus sign.
100 17
			if ( '-' === \substr( $string, -1, 1 ) ) {
101 6
				$string = sprintf( '-%s', \substr( $string, 0, -1 ) );
102
			}
103
104 17
			$string = filter_var( $string, FILTER_SANITIZE_NUMBER_INT );
105
		}
106
107
		// Filter.
108 59
		$value = filter_var( $string, FILTER_VALIDATE_FLOAT );
109
110 59
		if ( false === $value ) {
111
			throw new Exception( 'Could not parse value to money object.' );
112
		}
113
114 59
		return new Money( $value );
115
	}
116
}
117