ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Formula.php
Go to the documentation of this file.
1 <?php
2 
4 
7 
8 class Formula
9 {
10  private $definedNames = [];
11 
15  public function __construct(array $definedNames)
16  {
17  foreach ($definedNames as $definedName) {
18  $this->definedNames[] = $definedName->getName();
19  }
20  }
21 
22  public function convertFormula(string $formula, string $worksheetName = ''): string
23  {
24  $formula = $this->convertCellReferences($formula, $worksheetName);
25  $formula = $this->convertDefinedNames($formula);
26 
27  if (substr($formula, 0, 1) !== '=') {
28  $formula = '=' . $formula;
29  }
30 
31  return 'of:' . $formula;
32  }
33 
34  private function convertDefinedNames(string $formula): string
35  {
36  $splitCount = preg_match_all(
38  $formula,
39  $splitRanges,
40  PREG_OFFSET_CAPTURE
41  );
42 
43  $lengths = array_map('strlen', array_column($splitRanges[0], 0));
44  $offsets = array_column($splitRanges[0], 1);
45  $values = array_column($splitRanges[0], 0);
46 
47  while ($splitCount > 0) {
48  --$splitCount;
49  $length = $lengths[$splitCount];
50  $offset = $offsets[$splitCount];
51  $value = $values[$splitCount];
52 
53  if (in_array($value, $this->definedNames, true)) {
54  $formula = substr($formula, 0, $offset) . '$$' . $value . substr($formula, $offset + $length);
55  }
56  }
57 
58  return $formula;
59  }
60 
61  private function convertCellReferences(string $formula, string $worksheetName): string
62  {
63  $splitCount = preg_match_all(
65  $formula,
66  $splitRanges,
67  PREG_OFFSET_CAPTURE
68  );
69 
70  $lengths = array_map('strlen', array_column($splitRanges[0], 0));
71  $offsets = array_column($splitRanges[0], 1);
72 
73  $worksheets = $splitRanges[2];
74  $columns = $splitRanges[6];
75  $rows = $splitRanges[7];
76 
77  // Replace any commas in the formula with semi-colons for Ods
78  // If by chance there are commas in worksheet names, then they will be "fixed" again in the loop
79  // because we've already extracted worksheet names with our preg_match_all()
80  $formula = str_replace(',', ';', $formula);
81  while ($splitCount > 0) {
82  --$splitCount;
83  $length = $lengths[$splitCount];
84  $offset = $offsets[$splitCount];
85  $worksheet = $worksheets[$splitCount][0];
86  $column = $columns[$splitCount][0];
87  $row = $rows[$splitCount][0];
88 
89  $newRange = '';
90  if (empty($worksheet)) {
91  if (($offset === 0) || ($formula[$offset - 1] !== ':')) {
92  // We need a worksheet
93  $worksheet = $worksheetName;
94  }
95  } else {
96  $worksheet = str_replace("''", "'", trim($worksheet, "'"));
97  }
98  if (!empty($worksheet)) {
99  $newRange = "['" . str_replace("'", "''", $worksheet) . "'";
100  } elseif (substr($formula, $offset - 1, 1) !== ':') {
101  $newRange = '[';
102  }
103  $newRange .= '.';
104 
105  if (!empty($column)) {
106  $newRange .= $column;
107  }
108  if (!empty($row)) {
109  $newRange .= $row;
110  }
111  // close the wrapping [] unless this is the first part of a range
112  $newRange .= substr($formula, $offset + $length, 1) !== ':' ? ']' : '';
113 
114  $formula = substr($formula, 0, $offset) . $newRange . substr($formula, $offset + $length);
115  }
116 
117  return $formula;
118  }
119 }
convertFormula(string $formula, string $worksheetName='')
Definition: Formula.php:22
$values
$row
$rows
Definition: xhr_table.php:10
convertCellReferences(string $formula, string $worksheetName)
Definition: Formula.php:61
if(! $in) $columns
Definition: Utf8Test.php:45