ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
FormulaConverter.php
Go to the documentation of this file.
1<?php
2namespace Gettext\Languages;
3
4use Exception;
5
10{
17 public static function convertFormula($cldrFormula)
18 {
19 if (strpbrk($cldrFormula, '()') !== false) {
20 throw new Exception("Unable to convert the formula '$cldrFormula': parenthesis handling not implemented");
21 }
22 $orSeparatedChunks = array();
23 foreach (explode(' or ', $cldrFormula) as $cldrFormulaChunk) {
24 $gettextFormulaChunk = null;
25 $andSeparatedChunks = array();
26 foreach (explode(' and ', $cldrFormulaChunk) as $cldrAtom) {
27 $gettextAtom = self::convertAtom($cldrAtom);
28 if ($gettextAtom === false) {
29 // One atom joined by 'and' always evaluates to false => the whole 'and' group is always false
30 $gettextFormulaChunk = false;
31 break;
32 } elseif ($gettextAtom !== true) {
33 $andSeparatedChunks[] = $gettextAtom;
34 }
35 }
36 if (!isset($gettextFormulaChunk)) {
37 if (empty($andSeparatedChunks)) {
38 // All the atoms joined by 'and' always evaluate to true => the whole 'and' group is always true
39 $gettextFormulaChunk = true;
40 } else {
41 $gettextFormulaChunk = implode(' && ', $andSeparatedChunks);
42 // Special cases simplification
43 switch ($gettextFormulaChunk) {
44 case 'n >= 0 && n <= 2 && n != 2':
45 $gettextFormulaChunk = 'n == 0 || n == 1';
46 break;
47 }
48 }
49 }
50 if ($gettextFormulaChunk === true) {
51 // One part of the formula joined with the others by 'or' always evaluates to true => the whole formula always evaluates to true
52 return true;
53 } elseif ($gettextFormulaChunk !== false) {
54 $orSeparatedChunks[] = $gettextFormulaChunk;
55 }
56 }
57 if (empty($orSeparatedChunks)) {
58 // All the parts joined by 'or' always evaluate to false => the whole formula always evaluates to false
59 return false;
60 } else {
61 return implode(' || ', $orSeparatedChunks);
62 }
63 }
70 private static function convertAtom($cldrAtom)
71 {
72 $m = null;
73 $gettextAtom = $cldrAtom;
74 $gettextAtom = str_replace(' = ', ' == ', $gettextAtom);
75 $gettextAtom = str_replace('i', 'n', $gettextAtom);
76 if (preg_match('/^n( % \d+)? (!=|==) \d+$/', $gettextAtom)) {
77 return $gettextAtom;
78 }
79 if (preg_match('/^n( % \d+)? (!=|==) \d+(,\d+|\.\.\d+)+$/', $gettextAtom)) {
80 return self::expandAtom($gettextAtom);
81 }
82 if (preg_match('/^(?:v|w)(?: % 10+)? == (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // For gettext: v == 0, w == 0
83 return (intval($m[1]) === 0) ? true : false;
84 }
85 if (preg_match('/^(?:v|w)(?: % 10+)? != (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // For gettext: v == 0, w == 0
86 return (intval($m[1]) === 0) ? false : true;
87 }
88 if (preg_match('/^(?:f|t)(?: % 10+)? == (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // f == empty, t == empty
89 return (intval($m[1]) === 0) ? true : false;
90 }
91 if (preg_match('/^(?:f|t)(?: % 10+)? != (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // f == empty, t == empty
92 return (intval($m[1]) === 0) ? false : true;
93 }
94 throw new Exception("Unable to convert the formula chunk '$cldrAtom' from CLDR to gettext");
95 }
102 private static function expandAtom($atom)
103 {
104 $m = null;
105 if (preg_match('/^(n(?: % \d+)?) (==|!=) (\d+(?:\.\.\d+|,\d+)+)$/', $atom, $m)) {
106 $what = $m[1];
107 $op = $m[2];
108 $chunks = array();
109 foreach (explode(',', $m[3]) as $range) {
110 $chunk = null;
111 if ((!isset($chunk)) && preg_match('/^\d+$/', $range)) {
112 $chunk = "$what $op $range";
113 }
114 if ((!isset($chunk)) && preg_match('/^(\d+)\.\.(\d+)$/', $range, $m)) {
115 $from = intval($m[1]);
116 $to = intval($m[2]);
117 if (($to - $from) === 1) {
118 switch ($op) {
119 case '==':
120 $chunk = "($what == $from || $what == $to)";
121 break;
122 case '!=':
123 $chunk = "$what != $from && $what == $to";
124 break;
125 }
126 } else {
127 switch ($op) {
128 case '==':
129 $chunk = "$what >= $from && $what <= $to";
130 break;
131 case '!=':
132 if ($what === 'n' && $from <= 0) {
133 $chunk = "$what > $to";
134 } else {
135 $chunk = "($what < $from || $what > $to)";
136 }
137 break;
138 }
139 }
140 }
141 if (!isset($chunk)) {
142 throw new Exception("Unhandled range '$range' in '$atom'");
143 }
144 $chunks[] = $chunk;
145 }
146 if (count($chunks) === 1) {
147 return $chunks[0];
148 }
149 switch ($op) {
150 case '==':
151 return '('.implode(' || ', $chunks).')';break;
152 case '!=':
153 return implode(' && ', $chunks);
154 }
155 }
156 throw new Exception("Unable to expand '$atom'");
157 }
158}
An exception for terminatinating execution or to throw for unit testing.
A helper class to convert a CLDR formula to a gettext formula.
static convertAtom($cldrAtom)
Converts an atomic part of the CLDR formula to its gettext representation.
static convertFormula($cldrFormula)
Converts a formula from the CLDR representation to the gettext representation.
static expandAtom($atom)
Expands an atom containing a range (for instance: 'n == 1,3..5').
$from