WorkBookExporter::createColumnsFromFields()   C
last analyzed

Complexity

Conditions 12
Paths 6

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 12

Importance

Changes 0
Metric Value
cc 12
eloc 28
nc 6
nop 2
dl 0
loc 42
ccs 28
cts 28
cp 1
crap 12
rs 6.9666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @noinspection PhpClassConstantAccessedViaChildClassInspection
5
 */
6
7
declare(strict_types=1);
8
9
namespace Eclipxe\XlsxExporter\DBAL;
10
11
use Eclipxe\XlsxExporter\CellTypes;
12
use Eclipxe\XlsxExporter\Column;
13
use Eclipxe\XlsxExporter\Columns;
14
use Eclipxe\XlsxExporter\Style;
15
use Eclipxe\XlsxExporter\Styles\Alignment;
16
use Eclipxe\XlsxExporter\Styles\Format;
17
use Eclipxe\XlsxExporter\WorkBook;
18
use Eclipxe\XlsxExporter\WorkSheet;
19
use EngineWorks\DBAL\CommonTypes;
20
use EngineWorks\DBAL\DBAL;
21
use EngineWorks\DBAL\Recordset;
22
23
class WorkBookExporter
24
{
25
    private WorkBook $workbook;
26
27
    private ?Style $defaultHeaderStyle;
28
29 1
    public function __construct(Style $defaultStyle = null, Style $defaultHeaderStyle = null)
30
    {
31 1
        $this->workbook = new WorkBook(null, $defaultStyle);
32 1
        $this->defaultHeaderStyle = $defaultHeaderStyle;
33
    }
34
35 1
    public function getWorkbook(): WorkBook
36
    {
37 1
        return $this->workbook;
38
    }
39
40
    /**
41
     * Attach a recordset with the specified sheet-name, headers and header style
42
     *
43
     * The headers array must contain a key value array using the field-name as key and two properties:
44
     * title & style, the title must be a string and the style a valid array to be used in Style::setFromArray method
45
     *
46
     * @param Recordset $recordset
47
     * @param string $sheetName
48
     * @param array<string, array{title?: string, style?: array<string, array<string, scalar>>}> $headers
49
     * @param Style|null $defaultHeaderStyle
50
     */
51 1
    public function attach(Recordset $recordset, string $sheetName, array $headers = [], Style $defaultHeaderStyle = null): void
52
    {
53
        /** @var array<string, array{name: string, table: string, commontype: string}> $fields */
54 1
        $fields = $recordset->getFields();
55 1
        $this->workbook->getWorkSheets()->add(
56 1
            new WorkSheet(
57 1
                $sheetName,
58 1
                new RecordsetProvider($recordset),
59 1
                $this->createColumnsFromFields($fields, $headers),
60 1
                $defaultHeaderStyle ?? $this->defaultHeaderStyle
61 1
            )
62 1
        );
63
    }
64
65
    /**
66
     * This function takes an array (as exposed by recordset::getFields method)
67
     * and headers array to create a Columns object
68
     *
69
     * See attach method to write the headers array
70
     *
71
     * @param array<array{name: string, commontype: string}> $fields
72
     * @param array<string, array{title?: string, style?: array<string, array<string, scalar>>}> $headers
73
     */
74 3
    public static function createColumnsFromFields(array $fields, array $headers = []): Columns
75
    {
76 3
        $useHeaders = ([] !== $headers);
77 3
        $columns = new Columns();
78 3
        foreach ($fields as $field) {
79 3
            if ($useHeaders && ! array_key_exists($field['name'], $headers)) {
80 1
                continue;
81
            }
82 3
            $columns->add(new Column(
83 3
                $field['name'],
84 3
                $field['name'],
85 3
                self::getColumnTypeFromFieldType($field['commontype']),
86 3
                self::getColumnStyleFromFieldType($field['commontype'])
87 3
            ));
88
        }
89 3
        if ($useHeaders) {
90 1
            $sorted = new Columns();
91 1
            foreach ($headers as $fieldname => $properties) {
92 1
                if (! $columns->existsById($fieldname)) {
93 1
                    continue;
94
                }
95 1
                $column = $columns->getById($fieldname);
96
                // set title
97
                if (
98 1
                    array_key_exists('title', $properties)
99 1
                    && is_string($properties['title'])
100
                ) {
101 1
                    $column->setTitle($properties['title']);
102
                }
103
                // set style
104
                if (
105 1
                    array_key_exists('style', $properties)
106 1
                    && is_array($properties['style'])
107 1
                    && count($properties['style'])
108
                ) {
109 1
                    $column->getStyle()->setFromArray($properties['style']);
110
                }
111 1
                $sorted->add($column);
112
            }
113 1
            $columns = $sorted;
114
        }
115 3
        return $columns;
116
    }
117
118 3
    private static function getColumnTypeFromFieldType(string $type): string
119
    {
120 3
        $map = [
121 3
            CommonTypes::TTEXT => CellTypes::TEXT,
122 3
            CommonTypes::TNUMBER => CellTypes::NUMBER,
123 3
            CommonTypes::TINT => CellTypes::NUMBER,
124 3
            CommonTypes::TBOOL => CellTypes::BOOLEAN,
125 3
            CommonTypes::TDATETIME => CellTypes::DATETIME,
126 3
            CommonTypes::TDATE => CellTypes::DATE,
127 3
            CommonTypes::TTIME => CellTypes::TIME,
128 3
        ];
129 3
        return $map[$type] ?? CellTypes::TEXT;
130
    }
131
132 3
    private static function getColumnStyleFromFieldType(string $type): Style
133
    {
134
        /** @var array<string, array<string, array<string, scalar>>> $map */
135 3
        $map = [
136 3
            DBAL::TTEXT => [],
137 3
            DBAL::TNUMBER => ['format' => ['code' => Format::FORMAT_COMMA_2DECS]],
138 3
            DBAL::TINT => ['format' => ['code' => Format::FORMAT_ZERO_0DECS]],
139 3
            DBAL::TBOOL => [
140 3
                'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
141 3
            ],
142 3
            DBAL::TDATETIME => ['format' => ['code' => Format::FORMAT_DATE_YMDHM]],
143 3
            DBAL::TDATE => ['format' => ['code' => Format::FORMAT_DATE_YMD]],
144 3
            DBAL::TTIME => ['format' => ['code' => Format::FORMAT_DATE_HM]],
145 3
        ];
146 3
        $style = new Style();
147 3
        $style->setFromArray($map[$type] ?? []);
148 3
        return $style;
149
    }
150
}
151