9
9
10
10
class Formatter
11
11
{
12
+ /**
13
+ * Matches any @ symbol that isn't enclosed in quotes.
14
+ */
12
15
private const SYMBOL_AT = '/@(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu ' ;
16
+
17
+ /**
18
+ * Matches any ; symbol that isn't enclosed in quotes, for a "section" split.
19
+ */
13
20
private const SECTION_SPLIT = '/;(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu ' ;
14
21
15
22
/**
16
23
* @param mixed $value
17
- * @param mixed $val
18
- * @param mixed $dfval
24
+ * @param mixed $comparisonValue
25
+ * @param mixed $defaultComparisonValue
19
26
*/
20
- private static function splitFormatCompare ($ value , ?string $ cond , $ val , string $ dfcond , $ dfval ): bool
21
- {
22
- if (!$ cond ) {
23
- $ cond = $ dfcond ;
24
- $ val = $ dfval ;
27
+ private static function splitFormatComparison (
28
+ $ value ,
29
+ ?string $ condition ,
30
+ $ comparisonValue ,
31
+ string $ defaultCondition ,
32
+ $ defaultComparisonValue
33
+ ): bool {
34
+ if (!$ condition ) {
35
+ $ condition = $ defaultCondition ;
36
+ $ comparisonValue = $ defaultComparisonValue ;
25
37
}
26
- switch ($ cond ) {
38
+
39
+ switch ($ condition ) {
27
40
case '> ' :
28
- return $ value > $ val ;
41
+ return $ value > $ comparisonValue ;
29
42
30
43
case '< ' :
31
- return $ value < $ val ;
44
+ return $ value < $ comparisonValue ;
32
45
33
46
case '<= ' :
34
- return $ value <= $ val ;
47
+ return $ value <= $ comparisonValue ;
35
48
36
49
case '<> ' :
37
- return $ value != $ val ;
50
+ return $ value != $ comparisonValue ;
38
51
39
52
case '= ' :
40
- return $ value == $ val ;
53
+ return $ value == $ comparisonValue ;
41
54
}
42
55
43
- return $ value >= $ val ;
56
+ return $ value >= $ comparisonValue ;
44
57
}
45
58
46
59
/** @param mixed $value */
47
- private static function splitFormat (array $ sections , $ value ): array
60
+ private static function splitFormatForSectionSelection (array $ sections , $ value ): array
48
61
{
49
62
// Extract the relevant section depending on whether number is positive, negative, or zero?
50
63
// Text not supported yet.
@@ -53,30 +66,30 @@ private static function splitFormat(array $sections, $value): array
53
66
// 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE]
54
67
// 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO]
55
68
// 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT]
56
- $ cnt = count ($ sections );
69
+ $ sectionCount = count ($ sections );
57
70
$ color_regex = '/ \\[( ' . implode ('| ' , Color::NAMED_COLORS ) . ') \\]/mui ' ;
58
71
$ cond_regex = '/ \\[(>|>=|<|<=|=|<>)([+-]? \\d+([.] \\d+)?) \\]/ ' ;
59
72
$ colors = ['' , '' , '' , '' , '' ];
60
- $ condops = ['' , '' , '' , '' , '' ];
61
- $ condvals = [0 , 0 , 0 , 0 , 0 ];
62
- for ($ idx = 0 ; $ idx < $ cnt ; ++$ idx ) {
73
+ $ conditionOperations = ['' , '' , '' , '' , '' ];
74
+ $ conditionComparisonValues = [0 , 0 , 0 , 0 , 0 ];
75
+ for ($ idx = 0 ; $ idx < $ sectionCount ; ++$ idx ) {
63
76
if (preg_match ($ color_regex , $ sections [$ idx ], $ matches )) {
64
77
$ colors [$ idx ] = $ matches [0 ];
65
78
$ sections [$ idx ] = (string ) preg_replace ($ color_regex , '' , $ sections [$ idx ]);
66
79
}
67
80
if (preg_match ($ cond_regex , $ sections [$ idx ], $ matches )) {
68
- $ condops [$ idx ] = $ matches [1 ];
69
- $ condvals [$ idx ] = $ matches [2 ];
81
+ $ conditionOperations [$ idx ] = $ matches [1 ];
82
+ $ conditionComparisonValues [$ idx ] = $ matches [2 ];
70
83
$ sections [$ idx ] = (string ) preg_replace ($ cond_regex , '' , $ sections [$ idx ]);
71
84
}
72
85
}
73
86
$ color = $ colors [0 ];
74
87
$ format = $ sections [0 ];
75
88
$ absval = $ value ;
76
- switch ($ cnt ) {
89
+ switch ($ sectionCount ) {
77
90
case 2 :
78
91
$ absval = abs ($ value );
79
- if (!self ::splitFormatCompare ($ value , $ condops [0 ], $ condvals [0 ], '>= ' , 0 )) {
92
+ if (!self ::splitFormatComparison ($ value , $ conditionOperations [0 ], $ conditionComparisonValues [0 ], '>= ' , 0 )) {
80
93
$ color = $ colors [1 ];
81
94
$ format = $ sections [1 ];
82
95
}
@@ -85,8 +98,8 @@ private static function splitFormat(array $sections, $value): array
85
98
case 3 :
86
99
case 4 :
87
100
$ absval = abs ($ value );
88
- if (!self ::splitFormatCompare ($ value , $ condops [0 ], $ condvals [0 ], '> ' , 0 )) {
89
- if (self ::splitFormatCompare ($ value , $ condops [1 ], $ condvals [1 ], '< ' , 0 )) {
101
+ if (!self ::splitFormatComparison ($ value , $ conditionOperations [0 ], $ conditionComparisonValues [0 ], '> ' , 0 )) {
102
+ if (self ::splitFormatComparison ($ value , $ conditionOperations [1 ], $ conditionComparisonValues [1 ], '< ' , 0 )) {
90
103
$ color = $ colors [1 ];
91
104
$ format = $ sections [1 ];
92
105
} else {
@@ -105,7 +118,8 @@ private static function splitFormat(array $sections, $value): array
105
118
* Convert a value in a pre-defined format to a PHP string.
106
119
*
107
120
* @param null|bool|float|int|RichText|string $value Value to format
108
- * @param string $format Format code, see = NumberFormat::FORMAT_*
121
+ * @param string $format Format code: see = self::FORMAT_* for predefined values;
122
+ * or can be any valid MS Excel custom format string
109
123
* @param array $callBack Callback function for additional formatting of string
110
124
*
111
125
* @return string Formatted string
@@ -149,7 +163,7 @@ function ($matches) {
149
163
// Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal)
150
164
$ sections = preg_split (self ::SECTION_SPLIT , $ format ) ?: [];
151
165
152
- [$ colors , $ format , $ value ] = self ::splitFormat ($ sections , $ value );
166
+ [$ colors , $ format , $ value ] = self ::splitFormatForSectionSelection ($ sections , $ value );
153
167
154
168
// In Excel formats, "_" is used to add spacing,
155
169
// The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space
0 commit comments