Passed
Push — master ( fcb5ef...e65bc8 )
by
unknown
13:57 queued 18s
created

DocumentGenerator::generateFunctionListByName()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 46
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 37
dl 0
loc 46
rs 8.3946
c 0
b 0
f 0
cc 7
nc 24
nop 2
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheetInfra;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Category;
6
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7
use ReflectionClass;
8
use UnexpectedValueException;
9
10
class DocumentGenerator
11
{
12
    private const EXCLUDED_FUNCTIONS = [
13
        'CEILING.ODS',
14
        'CEILING.XCL',
15
        'FLOOR.ODS',
16
        'FLOOR.XCL',
17
    ];
18
19
    /**
20
     * @param array<string, array{category: string, functionCall: string|string[], argumentCount: string, passCellReference?: bool, passByReference?: bool[], custom?: bool}> $phpSpreadsheetFunctions
21
     */
22
    public static function generateFunctionListByCategory($phpSpreadsheetFunctions): string
23
    {
24
        $result = "# Function list by category\n";
25
        foreach (self::getCategories() as $categoryConstant => $category) {
26
            $result .= "\n";
27
            $result .= "## {$categoryConstant}\n";
28
            $result .= "\n";
29
            $lengths = [25, 37];
30
            $result .= self::tableRow($lengths, ['Excel Function', 'PhpSpreadsheet Function']) . "\n";
31
            $result .= self::tableRow($lengths, null) . "\n";
32
            foreach ($phpSpreadsheetFunctions as $excelFunction => $functionInfo) {
33
                if (in_array($excelFunction, self::EXCLUDED_FUNCTIONS, true)) {
34
                    continue;
35
                }
36
                if ($category === $functionInfo['category']) {
37
                    $phpFunction = self::getPhpSpreadsheetFunctionText($functionInfo['functionCall']);
38
                    $result .= self::tableRow($lengths, [$excelFunction, $phpFunction]) . "\n";
39
                }
40
            }
41
        }
42
43
        return $result;
44
    }
45
46
    /** @return array<string, string> */
47
    private static function getCategories(): array
48
    {
49
        /** @var array<string, string> */
50
        $x = (new ReflectionClass(Category::class))->getConstants();
51
52
        return $x;
53
    }
54
55
    /**
56
     * @param int[] $lengths
57
     * @param null|array<int, int|string> $values
58
     */
59
    private static function tableRow(array $lengths, ?array $values = null): string
60
    {
61
        $result = '';
62
        foreach (array_map(null, $lengths, $values ?? []) as $i => [$length, $value]) {
63
            $pad = $value === null ? '-' : ' ';
64
            if ($i > 0) {
65
                $result .= '|' . $pad;
66
            }
67
            $result .= str_pad("$value", $length ?? 0, $pad);
68
        }
69
70
        return rtrim($result, ' ');
71
    }
72
73
    /** @param scalar|string|string[] $functionCall */
74
    private static function getPhpSpreadsheetFunctionText(mixed $functionCall): string
75
    {
76
        if (is_string($functionCall)) {
77
            return $functionCall;
78
        }
79
        if ($functionCall === [Functions::class, 'DUMMY']) {
80
            return '**Not yet Implemented**';
81
        }
82
        if (is_array($functionCall)) {
83
            return "\\{$functionCall[0]}::{$functionCall[1]}";
84
        }
85
86
        throw new UnexpectedValueException(
87
            '$functionCall is of type ' . gettype($functionCall) . '. string or array expected'
88
        );
89
    }
90
91
    /**
92
     * @param array<string, array{category: string, functionCall: string|string[], argumentCount: string, passCellReference?: bool, passByReference?: bool[], custom?: bool}> $phpSpreadsheetFunctions
93
     */
94
    public static function generateFunctionListByName(array $phpSpreadsheetFunctions, bool $compact = false): string
95
    {
96
        $categoryConstants = array_flip(self::getCategories());
97
        if ($compact) {
98
            $result = "# Function list by name compact\n";
99
            $result .= "\n";
100
            $result .= 'Category should be prefixed by `CATEGORY_` to match the values in \PhpOffice\PhpSpreadsheet\Calculation\Category';
101
            $result .= "\n\n";
102
            $result .= 'Function should be prefixed by `PhpOffice\PhpSpreadsheet\Calculation\`';
103
            $result .= "\n\n";
104
            $result .= 'A less compact list can be found [here](./function-list-by-name.md)';
105
            $result .= "\n\n";
106
        } else {
107
            $result = "# Function list by name\n";
108
            $result .= "\n";
109
            $result .= 'A more compact list can be found [here](./function-list-by-name-compact.md)';
110
            $result .= "\n\n";
111
        }
112
        $lastAlphabet = null;
113
        $lengths = $compact ? [25, 22, 37] : [25, 31, 37];
114
        foreach ($phpSpreadsheetFunctions as $excelFunction => $functionInfo) {
115
            if (in_array($excelFunction, self::EXCLUDED_FUNCTIONS, true)) {
116
                continue;
117
            }
118
            if ($lastAlphabet !== $excelFunction[0]) {
119
                $lastAlphabet = $excelFunction[0];
120
                $result .= "\n";
121
                $result .= "## {$lastAlphabet}\n";
122
                $result .= "\n";
123
                $result .= self::tableRow($lengths, ['Excel Function', 'Category', 'PhpSpreadsheet Function']) . "\n";
124
                $result .= self::tableRow($lengths, null) . "\n";
125
            }
126
            $category = $categoryConstants[$functionInfo['category']];
127
            $phpFunction = self::getPhpSpreadsheetFunctionText($functionInfo['functionCall']);
128
            if ($compact) {
129
                $category = str_replace('CATEGORY_', '', $category);
130
                $phpFunction = str_replace(
131
                    '\PhpOffice\PhpSpreadsheet\Calculation\\',
132
                    '',
133
                    $phpFunction
134
                );
135
            }
136
            $result .= self::tableRow($lengths, [$excelFunction, $category, $phpFunction]) . "\n";
137
        }
138
139
        return $result;
140
    }
141
}
142