Passed
Pull Request — master (#4313)
by Owen
13:05
created

FormulaTranslator::replaceQuotedPeriod()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 14
rs 9.6111
ccs 9
cts 9
cp 1
cc 5
nc 4
nop 1
crap 5
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6
7
class FormulaTranslator
8
{
9 7
    private static function replaceQuotedPeriod(string $value): string
10
    {
11 7
        $value2 = '';
12
        $quoted = false;
13
        foreach (mb_str_split($value, 1, 'UTF-8') as $char) {
14
            if ($char === "'") {
15
                $quoted = !$quoted;
1 ignored issue
show
introduced by
The condition $quoted is always false.
Loading history...
16 7
            } elseif ($char === '.' && $quoted) {
17 7
                $char = "\u{fffe}";
18 7
            }
19 7
            $value2 .= $char;
20 7
        }
21 7
22 7
        return $value2;
23 7
    }
24 7
25 7
    public static function convertToExcelAddressValue(string $openOfficeAddress): string
26 7
    {
27 7
        // Cell range 3-d reference
28 7
        // As we don't support 3-d ranges, we're just going to take a quick and dirty approach
29 7
        //  and assume that the second worksheet reference is the same as the first
30 7
        $excelAddress = (string) preg_replace(
31 7
            [
32 7
                '/\$?([^\.]+)\.([^\.]+):\$?([^\.]+)\.([^\.]+)/miu',
33
                '/\$?([^\.]+)\.([^\.]+):\.([^\.]+)/miu', // Cell range reference in another sheet
34 7
                '/\$?([^\.]+)\.([^\.]+)/miu', // Cell reference in another sheet
35
                '/\.([^\.]+):\.([^\.]+)/miu', // Cell range reference
36
                '/\.([^\.]+)/miu', // Simple cell reference
37 23
                '/\\x{FFFE}/miu', // restore quoted periods
38
            ],
39 23
            [
40 23
                '$1!$2:$4',
41 23
                '$1!$2:$3',
42 23
                '$1!$2',
43 23
                '$1:$2',
44
                '$1',
45
                '.',
46
            ],
47 23
            self::replaceQuotedPeriod($openOfficeAddress)
48 23
        );
49 23
50 23
        return $excelAddress;
51 23
    }
52 23
53 23
    public static function convertToExcelFormulaValue(string $openOfficeFormula): string
54 23
    {
55 23
        $temp = explode(Calculation::FORMULA_STRING_QUOTE, $openOfficeFormula);
56 23
        $tKey = false;
57 23
        $inMatrixBracesLevel = 0;
58 23
        $inFunctionBracesLevel = 0;
59 23
        foreach ($temp as &$value) {
60 23
            // @var string $value
61 23
            // Only replace in alternate array entries (i.e. non-quoted blocks)
62 23
            //      so that conversion isn't done in string values
63 23
            $tKey = $tKey === false;
64
            if ($tKey) {
65 23
                $value = (string) preg_replace(
66
                    [
67
                        '/\[\$?([^\.]+)\.([^\.]+):\.([^\.]+)\]/miu', // Cell range reference in another sheet
68 23
                        '/\[\$?([^\.]+)\.([^\.]+)\]/miu', // Cell reference in another sheet
69
                        '/\[\.([^\.]+):\.([^\.]+)\]/miu', // Cell range reference
70
                        '/\[\.([^\.]+)\]/miu', // Simple cell reference
71 23
                        '/\\x{FFFE}/miu', // restore quoted periods
72 23
                    ],
73 23
                    [
74 23
                        '$1!$2:$3',
75 23
                        '$1!$2',
76 23
                        '$1:$2',
77 23
                        '$1',
78 23
                        '.',
79 23
                    ],
80 23
                    self::replaceQuotedPeriod($value)
81 23
                );
82 23
                // Convert references to defined names/formulae
83 23
                $value = str_replace('$$', '', $value);
84 23
85 23
                // Convert ODS function argument separators to Excel function argument separators
86 23
                $value = Calculation::translateSeparator(';', ',', $value, $inFunctionBracesLevel);
87
88 23
                // Convert ODS matrix separators to Excel matrix separators
89
                $value = Calculation::translateSeparator(
90
                    ';',
91
                    ',',
92
                    $value,
93 23
                    $inMatrixBracesLevel,
94
                    Calculation::FORMULA_OPEN_MATRIX_BRACE,
95 23
                    Calculation::FORMULA_CLOSE_MATRIX_BRACE
96
                );
97
                $value = Calculation::translateSeparator(
98
                    '|',
99
                    ';',
100
                    $value,
101
                    $inMatrixBracesLevel,
102
                    Calculation::FORMULA_OPEN_MATRIX_BRACE,
103
                    Calculation::FORMULA_CLOSE_MATRIX_BRACE
104
                );
105
106
                $value = (string) preg_replace('/COM\.MICROSOFT\./ui', '', $value);
107
            }
108
        }
109
110
        // Then rebuild the formula string
111
        $excelFormula = implode('"', $temp);
112
113
        return $excelFormula;
114
    }
115
}
116