Completed
Push — develop ( cdbf33...653adf )
by Adrien
26:38
created

Worksheet   F

Complexity

Total Complexity 214

Size/Duplication

Total Lines 1198
Duplicated Lines 0 %

Test Coverage

Coverage 89.7%

Importance

Changes 0
Metric Value
dl 0
loc 1198
ccs 505
cts 563
cp 0.897
rs 0.6314
c 0
b 0
f 0
wmc 214

23 Methods

Rating   Name   Duplication   Size   Complexity  
A writeDimension() 0 6 1
B writeCols() 0 55 9
C writeSheetPr() 0 38 8
D writeSheetFormatPr() 0 43 9
D writeSheetProtection() 0 26 18
B writePageSetup() 0 26 5
A writeMergeCells() 0 15 3
A writeProtectedRanges() 0 19 4
F writeSheetData() 0 76 16
F writeCell() 0 108 29
B writeHyperlinks() 0 31 5
A writeLegacyDrawingHF() 0 7 2
A writePrintOptions() 0 17 4
A writeLegacyDrawing() 0 7 2
D writeDataValidations() 0 57 16
A writePageMargins() 0 11 1
B writeHeaderFooter() 0 16 5
A writeDrawings() 0 9 4
F writeSheetViews() 0 101 16
B writeWorksheet() 0 86 2
D writeAutoFilter() 0 83 21
C writeBreaks() 0 47 8
C writeConditionalFormatting() 0 65 26

How to fix   Complexity   

Complex Class

Complex classes like Worksheet often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Worksheet, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Cell\Cell;
6
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
7
use PhpOffice\PhpSpreadsheet\RichText\RichText;
8
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
9
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
10
use PhpOffice\PhpSpreadsheet\Style\Conditional;
11
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
12
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
13
use PhpOffice\PhpSpreadsheet\Worksheet\SheetView;
14
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as PhpspreadsheetWorksheet;
15
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
16
17
/**
18
 * @category   PhpSpreadsheet
19
 *
20
 * @copyright  Copyright (c) 2006 - 2015 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
21
 */
22
class Worksheet extends WriterPart
23
{
24
    /**
25
     * Write worksheet to XML format.
26
     *
27
     * @param PhpspreadsheetWorksheet $pSheet
28
     * @param string[] $pStringTable
29
     * @param bool $includeCharts Flag indicating if we should write charts
30
     *
31
     * @throws WriterException
32
     *
33
     * @return string XML Output
34
     */
35 60
    public function writeWorksheet(PhpspreadsheetWorksheet $pSheet, $pStringTable = null, $includeCharts = false)
36
    {
37
        // Create XML writer
38 60
        $objWriter = null;
39 60
        if ($this->getParentWriter()->getUseDiskCaching()) {
40
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
41
        } else {
42 60
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
43
        }
44
45
        // XML header
46 60
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
47
48
        // Worksheet
49 60
        $objWriter->startElement('worksheet');
50 60
        $objWriter->writeAttribute('xml:space', 'preserve');
51 60
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
52 60
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
53
54
        // sheetPr
55 60
        $this->writeSheetPr($objWriter, $pSheet);
56
57
        // Dimension
58 60
        $this->writeDimension($objWriter, $pSheet);
59
60
        // sheetViews
61 60
        $this->writeSheetViews($objWriter, $pSheet);
62
63
        // sheetFormatPr
64 60
        $this->writeSheetFormatPr($objWriter, $pSheet);
65
66
        // cols
67 60
        $this->writeCols($objWriter, $pSheet);
68
69
        // sheetData
70 60
        $this->writeSheetData($objWriter, $pSheet, $pStringTable);
1 ignored issue
show
Bug introduced by
It seems like $pStringTable can also be of type null; however, parameter $pStringTable of PhpOffice\PhpSpreadsheet...sheet::writeSheetData() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
        $this->writeSheetData($objWriter, $pSheet, /** @scrutinizer ignore-type */ $pStringTable);
Loading history...
71
72
        // sheetProtection
73 60
        $this->writeSheetProtection($objWriter, $pSheet);
74
75
        // protectedRanges
76 60
        $this->writeProtectedRanges($objWriter, $pSheet);
77
78
        // autoFilter
79 60
        $this->writeAutoFilter($objWriter, $pSheet);
80
81
        // mergeCells
82 60
        $this->writeMergeCells($objWriter, $pSheet);
83
84
        // conditionalFormatting
85 60
        $this->writeConditionalFormatting($objWriter, $pSheet);
86
87
        // dataValidations
88 60
        $this->writeDataValidations($objWriter, $pSheet);
89
90
        // hyperlinks
91 60
        $this->writeHyperlinks($objWriter, $pSheet);
92
93
        // Print options
94 60
        $this->writePrintOptions($objWriter, $pSheet);
95
96
        // Page margins
97 60
        $this->writePageMargins($objWriter, $pSheet);
98
99
        // Page setup
100 60
        $this->writePageSetup($objWriter, $pSheet);
101
102
        // Header / footer
103 60
        $this->writeHeaderFooter($objWriter, $pSheet);
104
105
        // Breaks
106 60
        $this->writeBreaks($objWriter, $pSheet);
107
108
        // Drawings and/or Charts
109 60
        $this->writeDrawings($objWriter, $pSheet, $includeCharts);
110
111
        // LegacyDrawing
112 60
        $this->writeLegacyDrawing($objWriter, $pSheet);
113
114
        // LegacyDrawingHF
115 60
        $this->writeLegacyDrawingHF($objWriter, $pSheet);
116
117 60
        $objWriter->endElement();
118
119
        // Return
120 60
        return $objWriter->getData();
121
    }
122
123
    /**
124
     * Write SheetPr.
125
     *
126
     * @param XMLWriter $objWriter XML Writer
127
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
128
     *
129
     * @throws WriterException
130
     */
131 60
    private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
132
    {
133
        // sheetPr
134 60
        $objWriter->startElement('sheetPr');
135 60
        if ($pSheet->getParent()->hasMacros()) {
136
            //if the workbook have macros, we need to have codeName for the sheet
137
            if ($pSheet->hasCodeName() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
138
                $pSheet->setCodeName($pSheet->getTitle());
139
            }
140
            $objWriter->writeAttribute('codeName', $pSheet->getCodeName());
141
        }
142 60
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
143 60
        if (!empty($autoFilterRange)) {
144 3
            $objWriter->writeAttribute('filterMode', 1);
145 3
            $pSheet->getAutoFilter()->showHideRows();
146
        }
147
148
        // tabColor
149 60
        if ($pSheet->isTabColorSet()) {
150 6
            $objWriter->startElement('tabColor');
151 6
            $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
152 6
            $objWriter->endElement();
153
        }
154
155
        // outlinePr
156 60
        $objWriter->startElement('outlinePr');
157 60
        $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
158 60
        $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
159 60
        $objWriter->endElement();
160
161
        // pageSetUpPr
162 60
        if ($pSheet->getPageSetup()->getFitToPage()) {
163
            $objWriter->startElement('pageSetUpPr');
164
            $objWriter->writeAttribute('fitToPage', '1');
165
            $objWriter->endElement();
166
        }
167
168 60
        $objWriter->endElement();
169 60
    }
170
171
    /**
172
     * Write Dimension.
173
     *
174
     * @param XMLWriter $objWriter XML Writer
175
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
176
     *
177
     * @throws WriterException
178
     */
179 60
    private function writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
180
    {
181
        // dimension
182 60
        $objWriter->startElement('dimension');
183 60
        $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
184 60
        $objWriter->endElement();
185 60
    }
186
187
    /**
188
     * Write SheetViews.
189
     *
190
     * @param XMLWriter $objWriter XML Writer
191
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
192
     *
193
     * @throws WriterException
194
     */
195 60
    private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
196
    {
197
        // sheetViews
198 60
        $objWriter->startElement('sheetViews');
199
200
        // Sheet selected?
201 60
        $sheetSelected = false;
202 60
        if ($this->getParentWriter()->getSpreadsheet()->getIndex($pSheet) == $this->getParentWriter()->getSpreadsheet()->getActiveSheetIndex()) {
203 60
            $sheetSelected = true;
204
        }
205
206
        // sheetView
207 60
        $objWriter->startElement('sheetView');
208 60
        $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
209 60
        $objWriter->writeAttribute('workbookViewId', '0');
210
211
        // Zoom scales
212 60
        if ($pSheet->getSheetView()->getZoomScale() != 100) {
213
            $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
214
        }
215 60
        if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
216
            $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
217
        }
218
219
        // View Layout Type
220 60
        if ($pSheet->getSheetView()->getView() !== SheetView::SHEETVIEW_NORMAL) {
221 1
            $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView());
222
        }
223
224
        // Gridlines
225 60
        if ($pSheet->getShowGridlines()) {
226 60
            $objWriter->writeAttribute('showGridLines', 'true');
227
        } else {
228
            $objWriter->writeAttribute('showGridLines', 'false');
229
        }
230
231
        // Row and column headers
232 60
        if ($pSheet->getShowRowColHeaders()) {
233 60
            $objWriter->writeAttribute('showRowColHeaders', '1');
234
        } else {
235
            $objWriter->writeAttribute('showRowColHeaders', '0');
236
        }
237
238
        // Right-to-left
239 60
        if ($pSheet->getRightToLeft()) {
240
            $objWriter->writeAttribute('rightToLeft', 'true');
241
        }
242
243 60
        $activeCell = $pSheet->getActiveCell();
244
245
        // Pane
246 60
        $pane = '';
247 60
        if ($pSheet->getFreezePane()) {
248 4
            list($xSplit, $ySplit) = Coordinate::coordinateFromString($pSheet->getFreezePane());
249 4
            $xSplit = Coordinate::columnIndexFromString($xSplit);
250 4
            --$xSplit;
251 4
            --$ySplit;
252
253 4
            $topLeftCell = $pSheet->getTopLeftCell();
254 4
            $activeCell = $topLeftCell;
255
256
            // pane
257 4
            $pane = 'topRight';
258 4
            $objWriter->startElement('pane');
259 4
            if ($xSplit > 0) {
260 1
                $objWriter->writeAttribute('xSplit', $xSplit);
261
            }
262 4
            if ($ySplit > 0) {
263 4
                $objWriter->writeAttribute('ySplit', $ySplit);
264 4
                $pane = ($xSplit > 0) ? 'bottomRight' : 'bottomLeft';
265
            }
266 4
            $objWriter->writeAttribute('topLeftCell', $topLeftCell);
267 4
            $objWriter->writeAttribute('activePane', $pane);
268 4
            $objWriter->writeAttribute('state', 'frozen');
269 4
            $objWriter->endElement();
270
271 4
            if (($xSplit > 0) && ($ySplit > 0)) {
272
                //    Write additional selections if more than two panes (ie both an X and a Y split)
273 1
                $objWriter->startElement('selection');
274 1
                $objWriter->writeAttribute('pane', 'topRight');
275 1
                $objWriter->endElement();
276 1
                $objWriter->startElement('selection');
277 1
                $objWriter->writeAttribute('pane', 'bottomLeft');
278 1
                $objWriter->endElement();
279
            }
280
        }
281
282
        // Selection
283
        // Only need to write selection element if we have a split pane
284
        // We cheat a little by over-riding the active cell selection, setting it to the split cell
285 60
        $objWriter->startElement('selection');
286 60
        if ($pane != '') {
287 4
            $objWriter->writeAttribute('pane', $pane);
288
        }
289 60
        $objWriter->writeAttribute('activeCell', $activeCell);
290 60
        $objWriter->writeAttribute('sqref', $activeCell);
291 60
        $objWriter->endElement();
292
293 60
        $objWriter->endElement();
294
295 60
        $objWriter->endElement();
296 60
    }
297
298
    /**
299
     * Write SheetFormatPr.
300
     *
301
     * @param XMLWriter $objWriter XML Writer
302
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
303
     *
304
     * @throws WriterException
305
     */
306 60
    private function writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
307
    {
308
        // sheetFormatPr
309 60
        $objWriter->startElement('sheetFormatPr');
310
311
        // Default row height
312 60
        if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
313 2
            $objWriter->writeAttribute('customHeight', 'true');
314 2
            $objWriter->writeAttribute('defaultRowHeight', StringHelper::formatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
315
        } else {
316 58
            $objWriter->writeAttribute('defaultRowHeight', '14.4');
317
        }
318
319
        // Set Zero Height row
320 60
        if ((string) $pSheet->getDefaultRowDimension()->getZeroHeight() == '1' ||
321 60
            strtolower((string) $pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true') {
322
            $objWriter->writeAttribute('zeroHeight', '1');
323
        }
324
325
        // Default column width
326 60
        if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
327 1
            $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
328
        }
329
330
        // Outline level - row
331 60
        $outlineLevelRow = 0;
332 60
        foreach ($pSheet->getRowDimensions() as $dimension) {
333 11
            if ($dimension->getOutlineLevel() > $outlineLevelRow) {
334 11
                $outlineLevelRow = $dimension->getOutlineLevel();
335
            }
336
        }
337 60
        $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow);
338
339
        // Outline level - column
340 60
        $outlineLevelCol = 0;
341 60
        foreach ($pSheet->getColumnDimensions() as $dimension) {
342 21
            if ($dimension->getOutlineLevel() > $outlineLevelCol) {
343 21
                $outlineLevelCol = $dimension->getOutlineLevel();
344
            }
345
        }
346 60
        $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol);
347
348 60
        $objWriter->endElement();
349 60
    }
350
351
    /**
352
     * Write Cols.
353
     *
354
     * @param XMLWriter $objWriter XML Writer
355
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
356
     *
357
     * @throws WriterException
358
     */
359 60
    private function writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
360
    {
361
        // cols
362 60
        if (count($pSheet->getColumnDimensions()) > 0) {
363 21
            $objWriter->startElement('cols');
364
365 21
            $pSheet->calculateColumnWidths();
366
367
            // Loop through column dimensions
368 21
            foreach ($pSheet->getColumnDimensions() as $colDimension) {
369
                // col
370 21
                $objWriter->startElement('col');
371 21
                $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
372 21
                $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
373
374 21
                if ($colDimension->getWidth() < 0) {
375
                    // No width set, apply default of 10
376 2
                    $objWriter->writeAttribute('width', '9.10');
377
                } else {
378
                    // Width set
379 21
                    $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth()));
380
                }
381
382
                // Column visibility
383 21
                if ($colDimension->getVisible() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
384 3
                    $objWriter->writeAttribute('hidden', 'true');
385
                }
386
387
                // Auto size?
388 21
                if ($colDimension->getAutoSize()) {
389 8
                    $objWriter->writeAttribute('bestFit', 'true');
390
                }
391
392
                // Custom width?
393 21
                if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
394 21
                    $objWriter->writeAttribute('customWidth', 'true');
395
                }
396
397
                // Collapsed
398 21
                if ($colDimension->getCollapsed() == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
399 1
                    $objWriter->writeAttribute('collapsed', 'true');
400
                }
401
402
                // Outline level
403 21
                if ($colDimension->getOutlineLevel() > 0) {
404 1
                    $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
405
                }
406
407
                // Style
408 21
                $objWriter->writeAttribute('style', $colDimension->getXfIndex());
409
410 21
                $objWriter->endElement();
411
            }
412
413 21
            $objWriter->endElement();
414
        }
415 60
    }
416
417
    /**
418
     * Write SheetProtection.
419
     *
420
     * @param XMLWriter $objWriter XML Writer
421
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
422
     *
423
     * @throws WriterException
424
     */
425 60
    private function writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
426
    {
427
        // sheetProtection
428 60
        $objWriter->startElement('sheetProtection');
429
430 60
        if ($pSheet->getProtection()->getPassword() != '') {
431 1
            $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword());
432
        }
433
434 60
        $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false'));
435 60
        $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false'));
436 60
        $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false'));
437 60
        $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false'));
438 60
        $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false'));
439 60
        $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false'));
440 60
        $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false'));
441 60
        $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false'));
442 60
        $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false'));
443 60
        $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false'));
444 60
        $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false'));
445 60
        $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false'));
446 60
        $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false'));
447 60
        $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false'));
448 60
        $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false'));
449 60
        $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false'));
450 60
        $objWriter->endElement();
451 60
    }
452
453
    /**
454
     * Write ConditionalFormatting.
455
     *
456
     * @param XMLWriter $objWriter XML Writer
457
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
458
     *
459
     * @throws WriterException
460
     */
461 60
    private function writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
462
    {
463
        // Conditional id
464 60
        $id = 1;
465
466
        // Loop through styles in the current worksheet
467 60
        foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
468 3
            foreach ($conditionalStyles as $conditional) {
469
                // WHY was this again?
470
                // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') {
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
471
                //    continue;
472
                // }
473 3
                if ($conditional->getConditionType() != Conditional::CONDITION_NONE) {
474
                    // conditionalFormatting
475 3
                    $objWriter->startElement('conditionalFormatting');
476 3
                    $objWriter->writeAttribute('sqref', $cellCoordinate);
477
478
                    // cfRule
479 3
                    $objWriter->startElement('cfRule');
480 3
                    $objWriter->writeAttribute('type', $conditional->getConditionType());
481 3
                    $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
482 3
                    $objWriter->writeAttribute('priority', $id++);
483
484 3
                    if (($conditional->getConditionType() == Conditional::CONDITION_CELLIS || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT)
485 3
                        && $conditional->getOperatorType() != Conditional::OPERATOR_NONE) {
486 3
                        $objWriter->writeAttribute('operator', $conditional->getOperatorType());
487
                    }
488
489 3
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
490 3
                        && $conditional->getText() !== null) {
491
                        $objWriter->writeAttribute('text', $conditional->getText());
492
                    }
493
494 3
                    if ($conditional->getStopIfTrue()) {
495 1
                        $objWriter->writeAttribute('stopIfTrue', '1');
496
                    }
497
498 3
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
499 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT
500 3
                        && $conditional->getText() !== null) {
501
                        $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))');
502 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
503 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH
504 3
                        && $conditional->getText() !== null) {
505
                        $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
506 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
507 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH
508 3
                        && $conditional->getText() !== null) {
509
                        $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
510 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
511 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS
512 3
                        && $conditional->getText() !== null) {
513
                        $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))');
514 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CELLIS
515 1
                        || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
516 3
                        || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION) {
517 3
                        foreach ($conditional->getConditions() as $formula) {
518
                            // Formula
519 3
                            $objWriter->writeElement('formula', $formula);
520
                        }
521
                    }
522
523 3
                    $objWriter->endElement();
524
525 3
                    $objWriter->endElement();
526
                }
527
            }
528
        }
529 60
    }
530
531
    /**
532
     * Write DataValidations.
533
     *
534
     * @param XMLWriter $objWriter XML Writer
535
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
536
     *
537
     * @throws WriterException
538
     */
539 60
    private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
540
    {
541
        // Datavalidation collection
542 60
        $dataValidationCollection = $pSheet->getDataValidationCollection();
543
544
        // Write data validations?
545 60
        if (!empty($dataValidationCollection)) {
546 2
            $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection);
547 2
            $objWriter->startElement('dataValidations');
548 2
            $objWriter->writeAttribute('count', count($dataValidationCollection));
549
550 2
            foreach ($dataValidationCollection as $coordinate => $dv) {
551 2
                $objWriter->startElement('dataValidation');
552
553 2
                if ($dv->getType() != '') {
554 2
                    $objWriter->writeAttribute('type', $dv->getType());
555
                }
556
557 2
                if ($dv->getErrorStyle() != '') {
558 2
                    $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
559
                }
560
561 2
                if ($dv->getOperator() != '') {
562 2
                    $objWriter->writeAttribute('operator', $dv->getOperator());
563
                }
564
565 2
                $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
566 2
                $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
567 2
                $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
568 2
                $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
569
570 2
                if ($dv->getErrorTitle() !== '') {
571 2
                    $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
572
                }
573 2
                if ($dv->getError() !== '') {
574 2
                    $objWriter->writeAttribute('error', $dv->getError());
575
                }
576 2
                if ($dv->getPromptTitle() !== '') {
577 2
                    $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
578
                }
579 2
                if ($dv->getPrompt() !== '') {
580 2
                    $objWriter->writeAttribute('prompt', $dv->getPrompt());
581
                }
582
583 2
                $objWriter->writeAttribute('sqref', $coordinate);
584
585 2
                if ($dv->getFormula1() !== '') {
586 2
                    $objWriter->writeElement('formula1', $dv->getFormula1());
587
                }
588 2
                if ($dv->getFormula2() !== '') {
589 1
                    $objWriter->writeElement('formula2', $dv->getFormula2());
590
                }
591
592 2
                $objWriter->endElement();
593
            }
594
595 2
            $objWriter->endElement();
596
        }
597 60
    }
598
599
    /**
600
     * Write Hyperlinks.
601
     *
602
     * @param XMLWriter $objWriter XML Writer
603
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
604
     *
605
     * @throws WriterException
606
     */
607 60
    private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
608
    {
609
        // Hyperlink collection
610 60
        $hyperlinkCollection = $pSheet->getHyperlinkCollection();
611
612
        // Relation ID
613 60
        $relationId = 1;
614
615
        // Write hyperlinks?
616 60
        if (!empty($hyperlinkCollection)) {
617 10
            $objWriter->startElement('hyperlinks');
618
619 10
            foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
620 10
                $objWriter->startElement('hyperlink');
621
622 10
                $objWriter->writeAttribute('ref', $coordinate);
623 10
                if (!$hyperlink->isInternal()) {
624 10
                    $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
625 10
                    ++$relationId;
626
                } else {
627 7
                    $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
628
                }
629
630 10
                if ($hyperlink->getTooltip() != '') {
631 6
                    $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
632
                }
633
634 10
                $objWriter->endElement();
635
            }
636
637 10
            $objWriter->endElement();
638
        }
639 60
    }
640
641
    /**
642
     * Write ProtectedRanges.
643
     *
644
     * @param XMLWriter $objWriter XML Writer
645
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
646
     *
647
     * @throws WriterException
648
     */
649 60
    private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
650
    {
651 60
        if (count($pSheet->getProtectedCells()) > 0) {
652
            // protectedRanges
653 6
            $objWriter->startElement('protectedRanges');
654
655
            // Loop protectedRanges
656 6
            foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
657
                // protectedRange
658 6
                $objWriter->startElement('protectedRange');
659 6
                $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
660 6
                $objWriter->writeAttribute('sqref', $protectedCell);
661 6
                if (!empty($passwordHash)) {
662 6
                    $objWriter->writeAttribute('password', $passwordHash);
0 ignored issues
show
Bug introduced by
$passwordHash of type array is incompatible with the type string expected by parameter $value of XMLWriter::writeAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

662
                    $objWriter->writeAttribute('password', /** @scrutinizer ignore-type */ $passwordHash);
Loading history...
663
                }
664 6
                $objWriter->endElement();
665
            }
666
667 6
            $objWriter->endElement();
668
        }
669 60
    }
670
671
    /**
672
     * Write MergeCells.
673
     *
674
     * @param XMLWriter $objWriter XML Writer
675
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
676
     *
677
     * @throws WriterException
678
     */
679 60
    private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
680
    {
681 60
        if (count($pSheet->getMergeCells()) > 0) {
682
            // mergeCells
683 13
            $objWriter->startElement('mergeCells');
684
685
            // Loop mergeCells
686 13
            foreach ($pSheet->getMergeCells() as $mergeCell) {
687
                // mergeCell
688 13
                $objWriter->startElement('mergeCell');
689 13
                $objWriter->writeAttribute('ref', $mergeCell);
0 ignored issues
show
Bug introduced by
$mergeCell of type array is incompatible with the type string expected by parameter $value of XMLWriter::writeAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

689
                $objWriter->writeAttribute('ref', /** @scrutinizer ignore-type */ $mergeCell);
Loading history...
690 13
                $objWriter->endElement();
691
            }
692
693 13
            $objWriter->endElement();
694
        }
695 60
    }
696
697
    /**
698
     * Write PrintOptions.
699
     *
700
     * @param XMLWriter $objWriter XML Writer
701
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
702
     *
703
     * @throws WriterException
704
     */
705 60
    private function writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
706
    {
707
        // printOptions
708 60
        $objWriter->startElement('printOptions');
709
710 60
        $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true' : 'false'));
711 60
        $objWriter->writeAttribute('gridLinesSet', 'true');
712
713 60
        if ($pSheet->getPageSetup()->getHorizontalCentered()) {
714
            $objWriter->writeAttribute('horizontalCentered', 'true');
715
        }
716
717 60
        if ($pSheet->getPageSetup()->getVerticalCentered()) {
718
            $objWriter->writeAttribute('verticalCentered', 'true');
719
        }
720
721 60
        $objWriter->endElement();
722 60
    }
723
724
    /**
725
     * Write PageMargins.
726
     *
727
     * @param XMLWriter $objWriter XML Writer
728
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
729
     *
730
     * @throws WriterException
731
     */
732 60
    private function writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
733
    {
734
        // pageMargins
735 60
        $objWriter->startElement('pageMargins');
736 60
        $objWriter->writeAttribute('left', StringHelper::formatNumber($pSheet->getPageMargins()->getLeft()));
737 60
        $objWriter->writeAttribute('right', StringHelper::formatNumber($pSheet->getPageMargins()->getRight()));
738 60
        $objWriter->writeAttribute('top', StringHelper::formatNumber($pSheet->getPageMargins()->getTop()));
739 60
        $objWriter->writeAttribute('bottom', StringHelper::formatNumber($pSheet->getPageMargins()->getBottom()));
740 60
        $objWriter->writeAttribute('header', StringHelper::formatNumber($pSheet->getPageMargins()->getHeader()));
741 60
        $objWriter->writeAttribute('footer', StringHelper::formatNumber($pSheet->getPageMargins()->getFooter()));
742 60
        $objWriter->endElement();
743 60
    }
744
745
    /**
746
     * Write AutoFilter.
747
     *
748
     * @param XMLWriter $objWriter XML Writer
749
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
750
     *
751
     * @throws WriterException
752
     */
753 60
    private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
754
    {
755 60
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
756 60
        if (!empty($autoFilterRange)) {
757
            // autoFilter
758 3
            $objWriter->startElement('autoFilter');
759
760
            // Strip any worksheet reference from the filter coordinates
761 3
            $range = Coordinate::splitRange($autoFilterRange);
762 3
            $range = $range[0];
763
            //    Strip any worksheet ref
764 3
            if (strpos($range[0], '!') !== false) {
765
                list($ws, $range[0]) = explode('!', $range[0]);
766
            }
767 3
            $range = implode(':', $range);
768
769 3
            $objWriter->writeAttribute('ref', str_replace('$', '', $range));
770
771 3
            $columns = $pSheet->getAutoFilter()->getColumns();
772 3
            if (count($columns) > 0) {
773 2
                foreach ($columns as $columnID => $column) {
774 2
                    $rules = $column->getRules();
775 2
                    if (count($rules) > 0) {
776 2
                        $objWriter->startElement('filterColumn');
777 2
                        $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID));
778
779 2
                        $objWriter->startElement($column->getFilterType());
780 2
                        if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) {
781 1
                            $objWriter->writeAttribute('and', 1);
782
                        }
783
784 2
                        foreach ($rules as $rule) {
785 2
                            if (($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) &&
786 2
                                ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&
787 2
                                ($rule->getValue() === '')) {
788
                                //    Filter rule for Blanks
789 1
                                $objWriter->writeAttribute('blank', 1);
790 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
791
                                //    Dynamic Filter Rule
792 1
                                $objWriter->writeAttribute('type', $rule->getGrouping());
793 1
                                $val = $column->getAttribute('val');
794 1
                                if ($val !== null) {
795 1
                                    $objWriter->writeAttribute('val', $val);
796
                                }
797 1
                                $maxVal = $column->getAttribute('maxVal');
798 1
                                if ($maxVal !== null) {
799 1
                                    $objWriter->writeAttribute('maxVal', $maxVal);
800
                                }
801 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
802
                                //    Top 10 Filter Rule
803
                                $objWriter->writeAttribute('val', $rule->getValue());
804
                                $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
805
                                $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0'));
806
                            } else {
807
                                //    Filter, DateGroupItem or CustomFilter
808 2
                                $objWriter->startElement($rule->getRuleType());
809
810 2
                                if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
811 1
                                    $objWriter->writeAttribute('operator', $rule->getOperator());
812
                                }
813 2
                                if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
814
                                    // Date Group filters
815 1
                                    foreach ($rule->getValue() as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $rule->getValue() of type string is not traversable.
Loading history...
816 1
                                        if ($value > '') {
817 1
                                            $objWriter->writeAttribute($key, $value);
818
                                        }
819
                                    }
820 1
                                    $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
821
                                } else {
822 2
                                    $objWriter->writeAttribute('val', $rule->getValue());
823
                                }
824
825 2
                                $objWriter->endElement();
826
                            }
827
                        }
828
829 2
                        $objWriter->endElement();
830
831 2
                        $objWriter->endElement();
832
                    }
833
                }
834
            }
835 3
            $objWriter->endElement();
836
        }
837 60
    }
838
839
    /**
840
     * Write PageSetup.
841
     *
842
     * @param XMLWriter $objWriter XML Writer
843
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
844
     *
845
     * @throws WriterException
846
     */
847 60
    private function writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
848
    {
849
        // pageSetup
850 60
        $objWriter->startElement('pageSetup');
851 60
        $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
852 60
        $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
853
854 60
        if ($pSheet->getPageSetup()->getScale() !== null) {
855 60
            $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
856
        }
857 60
        if ($pSheet->getPageSetup()->getFitToHeight() !== null) {
858 60
            $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
859
        } else {
860
            $objWriter->writeAttribute('fitToHeight', '0');
861
        }
862 60
        if ($pSheet->getPageSetup()->getFitToWidth() !== null) {
863 60
            $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
864
        } else {
865
            $objWriter->writeAttribute('fitToWidth', '0');
866
        }
867 60
        if ($pSheet->getPageSetup()->getFirstPageNumber() !== null) {
868
            $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
869
            $objWriter->writeAttribute('useFirstPageNumber', '1');
870
        }
871
872 60
        $objWriter->endElement();
873 60
    }
874
875
    /**
876
     * Write Header / Footer.
877
     *
878
     * @param XMLWriter $objWriter XML Writer
879
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
880
     *
881
     * @throws WriterException
882
     */
883 60
    private function writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
884
    {
885
        // headerFooter
886 60
        $objWriter->startElement('headerFooter');
887 60
        $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
888 60
        $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
889 60
        $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
890 60
        $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
891
892 60
        $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
893 60
        $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
894 60
        $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
895 60
        $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
896 60
        $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
897 60
        $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
898 60
        $objWriter->endElement();
899 60
    }
900
901
    /**
902
     * Write Breaks.
903
     *
904
     * @param XMLWriter $objWriter XML Writer
905
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
906
     *
907
     * @throws WriterException
908
     */
909 60
    private function writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
910
    {
911
        // Get row and column breaks
912 60
        $aRowBreaks = [];
913 60
        $aColumnBreaks = [];
914 60
        foreach ($pSheet->getBreaks() as $cell => $breakType) {
915 1
            if ($breakType == PhpspreadsheetWorksheet::BREAK_ROW) {
916 1
                $aRowBreaks[] = $cell;
917
            } elseif ($breakType == PhpspreadsheetWorksheet::BREAK_COLUMN) {
918 1
                $aColumnBreaks[] = $cell;
919
            }
920
        }
921
922
        // rowBreaks
923 60
        if (!empty($aRowBreaks)) {
924 1
            $objWriter->startElement('rowBreaks');
925 1
            $objWriter->writeAttribute('count', count($aRowBreaks));
926 1
            $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
927
928 1
            foreach ($aRowBreaks as $cell) {
929 1
                $coords = Coordinate::coordinateFromString($cell);
930
931 1
                $objWriter->startElement('brk');
932 1
                $objWriter->writeAttribute('id', $coords[1]);
933 1
                $objWriter->writeAttribute('man', '1');
934 1
                $objWriter->endElement();
935
            }
936
937 1
            $objWriter->endElement();
938
        }
939
940
        // Second, write column breaks
941 60
        if (!empty($aColumnBreaks)) {
942
            $objWriter->startElement('colBreaks');
943
            $objWriter->writeAttribute('count', count($aColumnBreaks));
944
            $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
945
946
            foreach ($aColumnBreaks as $cell) {
947
                $coords = Coordinate::coordinateFromString($cell);
948
949
                $objWriter->startElement('brk');
950
                $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1);
951
                $objWriter->writeAttribute('man', '1');
952
                $objWriter->endElement();
953
            }
954
955
            $objWriter->endElement();
956
        }
957 60
    }
958
959
    /**
960
     * Write SheetData.
961
     *
962
     * @param XMLWriter $objWriter XML Writer
963
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
964
     * @param string[] $pStringTable String table
965
     *
966
     * @throws WriterException
967
     */
968 60
    private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable)
969
    {
970
        // Flipped stringtable, for faster index searching
971 60
        $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);
0 ignored issues
show
Bug introduced by
The method flipStringTable() does not exist on PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart. It seems like you code against a sub-type of PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart such as PhpOffice\PhpSpreadsheet\Writer\Xlsx\StringTable. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

971
        $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->/** @scrutinizer ignore-call */ flipStringTable($pStringTable);
Loading history...
972
973
        // sheetData
974 60
        $objWriter->startElement('sheetData');
975
976
        // Get column count
977 60
        $colCount = Coordinate::columnIndexFromString($pSheet->getHighestColumn());
978
979
        // Highest row number
980 60
        $highestRow = $pSheet->getHighestRow();
981
982
        // Loop through cells
983 60
        $cellsByRow = [];
984 60
        foreach ($pSheet->getCoordinates() as $coordinate) {
985 59
            $cellAddress = Coordinate::coordinateFromString($coordinate);
986 59
            $cellsByRow[$cellAddress[1]][] = $coordinate;
987
        }
988
989 60
        $currentRow = 0;
990 60
        while ($currentRow++ < $highestRow) {
991
            // Get row dimension
992 60
            $rowDimension = $pSheet->getRowDimension($currentRow);
993
994
            // Write current row?
995 60
            $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null;
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
996
997 60
            if ($writeCurrentRow) {
998
                // Start a new row
999 59
                $objWriter->startElement('row');
1000 59
                $objWriter->writeAttribute('r', $currentRow);
1001 59
                $objWriter->writeAttribute('spans', '1:' . $colCount);
1002
1003
                // Row dimensions
1004 59
                if ($rowDimension->getRowHeight() >= 0) {
1005 5
                    $objWriter->writeAttribute('customHeight', '1');
1006 5
                    $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight()));
1007
                }
1008
1009
                // Row visibility
1010 59
                if ($rowDimension->getVisible() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1011 2
                    $objWriter->writeAttribute('hidden', 'true');
1012
                }
1013
1014
                // Collapsed
1015 59
                if ($rowDimension->getCollapsed() == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1016
                    $objWriter->writeAttribute('collapsed', 'true');
1017
                }
1018
1019
                // Outline level
1020 59
                if ($rowDimension->getOutlineLevel() > 0) {
1021
                    $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
1022
                }
1023
1024
                // Style
1025 59
                if ($rowDimension->getXfIndex() !== null) {
1026
                    $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
1027
                    $objWriter->writeAttribute('customFormat', '1');
1028
                }
1029
1030
                // Write cells
1031 59
                if (isset($cellsByRow[$currentRow])) {
1032 59
                    foreach ($cellsByRow[$currentRow] as $cellAddress) {
1033
                        // Write cell
1034 59
                        $this->writeCell($objWriter, $pSheet, $cellAddress, $aFlippedStringTable);
1035
                    }
1036
                }
1037
1038
                // End row
1039 59
                $objWriter->endElement();
1040
            }
1041
        }
1042
1043 60
        $objWriter->endElement();
1044 60
    }
1045
1046
    /**
1047
     * Write Cell.
1048
     *
1049
     * @param XMLWriter $objWriter XML Writer
1050
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1051
     * @param Cell $pCellAddress Cell Address
1052
     * @param string[] $pFlippedStringTable String table (flipped), for faster index searching
1053
     *
1054
     * @throws WriterException
1055
     */
1056 59
    private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $pCellAddress, array $pFlippedStringTable)
1057
    {
1058
        // Cell
1059 59
        $pCell = $pSheet->getCell($pCellAddress);
1060 59
        $objWriter->startElement('c');
1061 59
        $objWriter->writeAttribute('r', $pCellAddress);
1062
1063
        // Sheet styles
1064 59
        if ($pCell->getXfIndex() != '') {
1065 32
            $objWriter->writeAttribute('s', $pCell->getXfIndex());
1066
        }
1067
1068
        // If cell value is supplied, write cell value
1069 59
        $cellValue = $pCell->getValue();
1070 59
        if (is_object($cellValue) || $cellValue !== '') {
1071
            // Map type
1072 59
            $mappedType = $pCell->getDataType();
1073
1074
            // Write data type depending on its type
1075 59
            switch (strtolower($mappedType)) {
1076 59
                case 'inlinestr':    // Inline string
1077 58
                case 's':            // String
1078 50
                case 'b':            // Boolean
1079 52
                    $objWriter->writeAttribute('t', $mappedType);
1080
1081 52
                    break;
1082 48
                case 'f':            // Formula
1083 18
                    $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?
1084 18
                        $pCell->getCalculatedValue() : $cellValue;
1085 18
                    if (is_string($calculatedValue)) {
1086 13
                        $objWriter->writeAttribute('t', 'str');
1087
                    }
1088
1089 18
                    break;
1090 47
                case 'e':            // Error
1091
                    $objWriter->writeAttribute('t', $mappedType);
1092
            }
1093
1094
            // Write data depending on its type
1095 59
            switch (strtolower($mappedType)) {
1096 59
                case 'inlinestr':    // Inline string
1097 8
                    if (!$cellValue instanceof RichText) {
1098
                        $objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
1099 8
                    } elseif ($cellValue instanceof RichText) {
1100 8
                        $objWriter->startElement('is');
1101 8
                        $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue);
0 ignored issues
show
Bug introduced by
The method writeRichText() does not exist on PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart. It seems like you code against a sub-type of PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart such as PhpOffice\PhpSpreadsheet\Writer\Xlsx\StringTable. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1101
                        $this->getParentWriter()->getWriterPart('stringtable')->/** @scrutinizer ignore-call */ writeRichText($objWriter, $cellValue);
Loading history...
1102 8
                        $objWriter->endElement();
1103
                    }
1104
1105 8
                    break;
1106 58
                case 's':            // String
1107 51
                    if (!$cellValue instanceof RichText) {
1108 51
                        if (isset($pFlippedStringTable[$cellValue])) {
1109 51
                            $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]);
1110
                        }
1111 2
                    } elseif ($cellValue instanceof RichText) {
1112 2
                        $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
1113
                    }
1114
1115 51
                    break;
1116 50
                case 'f':            // Formula
1117 18
                    $attributes = $pCell->getFormulaAttributes();
1118 18
                    if ($attributes['t'] == 'array') {
1119
                        $objWriter->startElement('f');
1120
                        $objWriter->writeAttribute('t', 'array');
1121
                        $objWriter->writeAttribute('ref', $pCellAddress);
1122
                        $objWriter->writeAttribute('aca', '1');
1123
                        $objWriter->writeAttribute('ca', '1');
1124
                        $objWriter->text(substr($cellValue, 1));
1125
                        $objWriter->endElement();
1126
                    } else {
1127 18
                        $objWriter->writeElement('f', substr($cellValue, 1));
1128
                    }
1129 18
                    if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
1130 18
                        if ($this->getParentWriter()->getPreCalculateFormulas()) {
1131 18
                            if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $calculatedValue does not seem to be defined for all execution paths leading up to this point.
Loading history...
1132 18
                                $objWriter->writeElement('v', StringHelper::formatNumber($calculatedValue));
1133
                            } else {
1134 18
                                $objWriter->writeElement('v', '0');
1135
                            }
1136
                        } else {
1137
                            $objWriter->writeElement('v', '0');
1138
                        }
1139
                    }
1140
1141 18
                    break;
1142 49
                case 'n':            // Numeric
1143
                    // force point as decimal separator in case current locale uses comma
1144 41
                    $objWriter->writeElement('v', str_replace(',', '.', $cellValue));
1145
1146 41
                    break;
1147 26
                case 'b':            // Boolean
1148 8
                    $objWriter->writeElement('v', ($cellValue ? '1' : '0'));
1149
1150 8
                    break;
1151 22
                case 'e':            // Error
1152
                    if (substr($cellValue, 0, 1) == '=') {
1153
                        $objWriter->writeElement('f', substr($cellValue, 1));
1154
                        $objWriter->writeElement('v', substr($cellValue, 1));
1155
                    } else {
1156
                        $objWriter->writeElement('v', $cellValue);
1157
                    }
1158
1159
                    break;
1160
            }
1161
        }
1162
1163 59
        $objWriter->endElement();
1164 59
    }
1165
1166
    /**
1167
     * Write Drawings.
1168
     *
1169
     * @param XMLWriter $objWriter XML Writer
1170
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1171
     * @param bool $includeCharts Flag indicating if we should include drawing details for charts
1172
     *
1173
     * @throws WriterException
1174
     */
1175 60
    private function writeDrawings(XMLWriter $objWriter = null, PhpspreadsheetWorksheet $pSheet = null, $includeCharts = false)
1176
    {
1177 60
        $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
1 ignored issue
show
Bug introduced by
The method getChartCollection() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1177
        $chartCount = ($includeCharts) ? $pSheet->/** @scrutinizer ignore-call */ getChartCollection()->count() : 0;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1178
        // If sheet contains drawings, add the relationships
1179 60
        if (($pSheet->getDrawingCollection()->count() > 0) ||
1180 60
            ($chartCount > 0)) {
1181 22
            $objWriter->startElement('drawing');
1 ignored issue
show
Bug introduced by
The method startElement() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1181
            $objWriter->/** @scrutinizer ignore-call */ 
1182
                        startElement('drawing');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1182 22
            $objWriter->writeAttribute('r:id', 'rId1');
1183 22
            $objWriter->endElement();
1184
        }
1185 60
    }
1186
1187
    /**
1188
     * Write LegacyDrawing.
1189
     *
1190
     * @param XMLWriter $objWriter XML Writer
1191
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1192
     *
1193
     * @throws WriterException
1194
     */
1195 60
    private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1196
    {
1197
        // If sheet contains comments, add the relationships
1198 60
        if (count($pSheet->getComments()) > 0) {
1199 9
            $objWriter->startElement('legacyDrawing');
1200 9
            $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
1201 9
            $objWriter->endElement();
1202
        }
1203 60
    }
1204
1205
    /**
1206
     * Write LegacyDrawingHF.
1207
     *
1208
     * @param XMLWriter $objWriter XML Writer
1209
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1210
     *
1211
     * @throws WriterException
1212
     */
1213 60
    private function writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1214
    {
1215
        // If sheet contains images, add the relationships
1216 60
        if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
1217 1
            $objWriter->startElement('legacyDrawingHF');
1218 1
            $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
1219 1
            $objWriter->endElement();
1220
        }
1221 60
    }
1222
}
1223