ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
FormulaConverter.php
Go to the documentation of this file.
1 <?php
2 namespace Gettext\Languages;
3 
4 use 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 }
static expandAtom($atom)
Expands an atom containing a range (for instance: &#39;n == 1,3..5&#39;).
$from
static convertFormula($cldrFormula)
Converts a formula from the CLDR representation to the gettext representation.
static convertAtom($cldrAtom)
Converts an atomic part of the CLDR formula to its gettext representation.
A helper class to convert a CLDR formula to a gettext formula.