Passed
Push — master ( 06d9dc...fb3793 )
by Adrien
11:50
created

Worksheet::writeConditionalFormatting()   D

Complexity

Conditions 28
Paths 67

Size

Total Lines 71
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 41
CRAP Score 29.0069

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 28
eloc 45
c 1
b 0
f 0
nc 67
nop 2
dl 0
loc 71
rs 4.1666
ccs 41
cts 46
cp 0.8913
crap 29.0069

How to fix   Long Method    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
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 105
    public function writeWorksheet(PhpspreadsheetWorksheet $pSheet, $pStringTable = null, $includeCharts = false)
36
    {
37
        // Create XML writer
38 105
        $objWriter = null;
39 105
        if ($this->getParentWriter()->getUseDiskCaching()) {
40
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
41
        } else {
42 105
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
43
        }
44
45
        // XML header
46 105
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
47
48
        // Worksheet
49 105
        $objWriter->startElement('worksheet');
50 105
        $objWriter->writeAttribute('xml:space', 'preserve');
51 105
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
52 105
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
53
54 105
        $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
55 105
        $objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main');
56 105
        $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
57 105
        $objWriter->writeAttribute('mc:Ignorable', 'x14ac');
58 105
        $objWriter->writeAttribute('xmlns:x14ac', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac');
59
60
        // sheetPr
61 105
        $this->writeSheetPr($objWriter, $pSheet);
62
63
        // Dimension
64 105
        $this->writeDimension($objWriter, $pSheet);
65
66
        // sheetViews
67 105
        $this->writeSheetViews($objWriter, $pSheet);
68
69
        // sheetFormatPr
70 105
        $this->writeSheetFormatPr($objWriter, $pSheet);
71
72
        // cols
73 105
        $this->writeCols($objWriter, $pSheet);
74
75
        // sheetData
76 105
        $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

76
        $this->writeSheetData($objWriter, $pSheet, /** @scrutinizer ignore-type */ $pStringTable);
Loading history...
77
78
        // sheetProtection
79 105
        $this->writeSheetProtection($objWriter, $pSheet);
80
81
        // protectedRanges
82 105
        $this->writeProtectedRanges($objWriter, $pSheet);
83
84
        // autoFilter
85 105
        $this->writeAutoFilter($objWriter, $pSheet);
86
87
        // mergeCells
88 105
        $this->writeMergeCells($objWriter, $pSheet);
89
90
        // conditionalFormatting
91 105
        $this->writeConditionalFormatting($objWriter, $pSheet);
92
93
        // dataValidations
94 105
        $this->writeDataValidations($objWriter, $pSheet);
95
96
        // hyperlinks
97 105
        $this->writeHyperlinks($objWriter, $pSheet);
98
99
        // Print options
100 105
        $this->writePrintOptions($objWriter, $pSheet);
101
102
        // Page margins
103 105
        $this->writePageMargins($objWriter, $pSheet);
104
105
        // Page setup
106 105
        $this->writePageSetup($objWriter, $pSheet);
107
108
        // Header / footer
109 105
        $this->writeHeaderFooter($objWriter, $pSheet);
110
111
        // Breaks
112 105
        $this->writeBreaks($objWriter, $pSheet);
113
114
        // Drawings and/or Charts
115 105
        $this->writeDrawings($objWriter, $pSheet, $includeCharts);
116
117
        // LegacyDrawing
118 105
        $this->writeLegacyDrawing($objWriter, $pSheet);
119
120
        // LegacyDrawingHF
121 105
        $this->writeLegacyDrawingHF($objWriter, $pSheet);
122
123
        // AlternateContent
124 105
        $this->writeAlternateContent($objWriter, $pSheet);
125
126 105
        $objWriter->endElement();
127
128
        // Return
129 105
        return $objWriter->getData();
130
    }
131
132
    /**
133
     * Write SheetPr.
134
     *
135
     * @param XMLWriter $objWriter XML Writer
136
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
137
     */
138 105
    private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
139
    {
140
        // sheetPr
141 105
        $objWriter->startElement('sheetPr');
142 105
        if ($pSheet->getParent()->hasMacros()) {
143
            //if the workbook have macros, we need to have codeName for the sheet
144 1
            if (!$pSheet->hasCodeName()) {
145
                $pSheet->setCodeName($pSheet->getTitle());
146
            }
147 1
            $objWriter->writeAttribute('codeName', $pSheet->getCodeName());
148
        }
149 105
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
150 105
        if (!empty($autoFilterRange)) {
151 3
            $objWriter->writeAttribute('filterMode', 1);
152 3
            $pSheet->getAutoFilter()->showHideRows();
153
        }
154
155
        // tabColor
156 105
        if ($pSheet->isTabColorSet()) {
157 6
            $objWriter->startElement('tabColor');
158 6
            $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
159 6
            $objWriter->endElement();
160
        }
161
162
        // outlinePr
163 105
        $objWriter->startElement('outlinePr');
164 105
        $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
165 105
        $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
166 105
        $objWriter->endElement();
167
168
        // pageSetUpPr
169 105
        if ($pSheet->getPageSetup()->getFitToPage()) {
170
            $objWriter->startElement('pageSetUpPr');
171
            $objWriter->writeAttribute('fitToPage', '1');
172
            $objWriter->endElement();
173
        }
174
175 105
        $objWriter->endElement();
176 105
    }
177
178
    /**
179
     * Write Dimension.
180
     *
181
     * @param XMLWriter $objWriter XML Writer
182
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
183
     */
184 105
    private function writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
185
    {
186
        // dimension
187 105
        $objWriter->startElement('dimension');
188 105
        $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
189 105
        $objWriter->endElement();
190 105
    }
191
192
    /**
193
     * Write SheetViews.
194
     *
195
     * @param XMLWriter $objWriter XML Writer
196
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
197
     *
198
     * @throws WriterException
199
     */
200 105
    private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
201
    {
202
        // sheetViews
203 105
        $objWriter->startElement('sheetViews');
204
205
        // Sheet selected?
206 105
        $sheetSelected = false;
207 105
        if ($this->getParentWriter()->getSpreadsheet()->getIndex($pSheet) == $this->getParentWriter()->getSpreadsheet()->getActiveSheetIndex()) {
208 105
            $sheetSelected = true;
209
        }
210
211
        // sheetView
212 105
        $objWriter->startElement('sheetView');
213 105
        $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
214 105
        $objWriter->writeAttribute('workbookViewId', '0');
215
216
        // Zoom scales
217 105
        if ($pSheet->getSheetView()->getZoomScale() != 100) {
218
            $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
219
        }
220 105
        if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
221
            $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
222
        }
223
224
        // Show zeros (Excel also writes this attribute only if set to false)
225 105
        if ($pSheet->getSheetView()->getShowZeros() === false) {
226
            $objWriter->writeAttribute('showZeros', 0);
227
        }
228
229
        // View Layout Type
230 105
        if ($pSheet->getSheetView()->getView() !== SheetView::SHEETVIEW_NORMAL) {
231 1
            $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView());
232
        }
233
234
        // Gridlines
235 105
        if ($pSheet->getShowGridlines()) {
236 105
            $objWriter->writeAttribute('showGridLines', 'true');
237
        } else {
238
            $objWriter->writeAttribute('showGridLines', 'false');
239
        }
240
241
        // Row and column headers
242 105
        if ($pSheet->getShowRowColHeaders()) {
243 105
            $objWriter->writeAttribute('showRowColHeaders', '1');
244
        } else {
245
            $objWriter->writeAttribute('showRowColHeaders', '0');
246
        }
247
248
        // Right-to-left
249 105
        if ($pSheet->getRightToLeft()) {
250
            $objWriter->writeAttribute('rightToLeft', 'true');
251
        }
252
253 105
        $activeCell = $pSheet->getActiveCell();
254 105
        $sqref = $pSheet->getSelectedCells();
255
256
        // Pane
257 105
        $pane = '';
258 105
        if ($pSheet->getFreezePane()) {
259 6
            [$xSplit, $ySplit] = Coordinate::coordinateFromString($pSheet->getFreezePane());
260 6
            $xSplit = Coordinate::columnIndexFromString($xSplit);
261 6
            --$xSplit;
262 6
            --$ySplit;
263
264 6
            $topLeftCell = $pSheet->getTopLeftCell();
265
266
            // pane
267 6
            $pane = 'topRight';
268 6
            $objWriter->startElement('pane');
269 6
            if ($xSplit > 0) {
270 1
                $objWriter->writeAttribute('xSplit', $xSplit);
271
            }
272 6
            if ($ySplit > 0) {
273 6
                $objWriter->writeAttribute('ySplit', $ySplit);
274 6
                $pane = ($xSplit > 0) ? 'bottomRight' : 'bottomLeft';
275
            }
276 6
            $objWriter->writeAttribute('topLeftCell', $topLeftCell);
277 6
            $objWriter->writeAttribute('activePane', $pane);
278 6
            $objWriter->writeAttribute('state', 'frozen');
279 6
            $objWriter->endElement();
280
281 6
            if (($xSplit > 0) && ($ySplit > 0)) {
282
                //    Write additional selections if more than two panes (ie both an X and a Y split)
283 1
                $objWriter->startElement('selection');
284 1
                $objWriter->writeAttribute('pane', 'topRight');
285 1
                $objWriter->endElement();
286 1
                $objWriter->startElement('selection');
287 1
                $objWriter->writeAttribute('pane', 'bottomLeft');
288 1
                $objWriter->endElement();
289
            }
290
        }
291
292
        // Selection
293
        // Only need to write selection element if we have a split pane
294
        // We cheat a little by over-riding the active cell selection, setting it to the split cell
295 105
        $objWriter->startElement('selection');
296 105
        if ($pane != '') {
297 6
            $objWriter->writeAttribute('pane', $pane);
298
        }
299 105
        $objWriter->writeAttribute('activeCell', $activeCell);
300 105
        $objWriter->writeAttribute('sqref', $sqref);
301 105
        $objWriter->endElement();
302
303 105
        $objWriter->endElement();
304
305 105
        $objWriter->endElement();
306 105
    }
307
308
    /**
309
     * Write SheetFormatPr.
310
     *
311
     * @param XMLWriter $objWriter XML Writer
312
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
313
     */
314 105
    private function writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
315
    {
316
        // sheetFormatPr
317 105
        $objWriter->startElement('sheetFormatPr');
318
319
        // Default row height
320 105
        if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
321 3
            $objWriter->writeAttribute('customHeight', 'true');
322 3
            $objWriter->writeAttribute('defaultRowHeight', StringHelper::formatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
323
        } else {
324 102
            $objWriter->writeAttribute('defaultRowHeight', '14.4');
325
        }
326
327
        // Set Zero Height row
328 105
        if ((string) $pSheet->getDefaultRowDimension()->getZeroHeight() === '1' ||
329 105
            strtolower((string) $pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true') {
330
            $objWriter->writeAttribute('zeroHeight', '1');
331
        }
332
333
        // Default column width
334 105
        if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
335 2
            $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
336
        }
337
338
        // Outline level - row
339 105
        $outlineLevelRow = 0;
340 105
        foreach ($pSheet->getRowDimensions() as $dimension) {
341 13
            if ($dimension->getOutlineLevel() > $outlineLevelRow) {
342
                $outlineLevelRow = $dimension->getOutlineLevel();
343
            }
344
        }
345 105
        $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow);
346
347
        // Outline level - column
348 105
        $outlineLevelCol = 0;
349 105
        foreach ($pSheet->getColumnDimensions() as $dimension) {
350 24
            if ($dimension->getOutlineLevel() > $outlineLevelCol) {
351 1
                $outlineLevelCol = $dimension->getOutlineLevel();
352
            }
353
        }
354 105
        $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol);
355
356 105
        $objWriter->endElement();
357 105
    }
358
359
    /**
360
     * Write Cols.
361
     *
362
     * @param XMLWriter $objWriter XML Writer
363
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
364
     */
365 105
    private function writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
366
    {
367
        // cols
368 105
        if (count($pSheet->getColumnDimensions()) > 0) {
369 24
            $objWriter->startElement('cols');
370
371 24
            $pSheet->calculateColumnWidths();
372
373
            // Loop through column dimensions
374 24
            foreach ($pSheet->getColumnDimensions() as $colDimension) {
375
                // col
376 24
                $objWriter->startElement('col');
377 24
                $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
378 24
                $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
379
380 24
                if ($colDimension->getWidth() < 0) {
381
                    // No width set, apply default of 10
382 2
                    $objWriter->writeAttribute('width', '9.10');
383
                } else {
384
                    // Width set
385 24
                    $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth()));
386
                }
387
388
                // Column visibility
389 24
                if ($colDimension->getVisible() === false) {
390 3
                    $objWriter->writeAttribute('hidden', 'true');
391
                }
392
393
                // Auto size?
394 24
                if ($colDimension->getAutoSize()) {
395 8
                    $objWriter->writeAttribute('bestFit', 'true');
396
                }
397
398
                // Custom width?
399 24
                if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
400 24
                    $objWriter->writeAttribute('customWidth', 'true');
401
                }
402
403
                // Collapsed
404 24
                if ($colDimension->getCollapsed() === true) {
405 1
                    $objWriter->writeAttribute('collapsed', 'true');
406
                }
407
408
                // Outline level
409 24
                if ($colDimension->getOutlineLevel() > 0) {
410 1
                    $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
411
                }
412
413
                // Style
414 24
                $objWriter->writeAttribute('style', $colDimension->getXfIndex());
415
416 24
                $objWriter->endElement();
417
            }
418
419 24
            $objWriter->endElement();
420
        }
421 105
    }
422
423
    /**
424
     * Write SheetProtection.
425
     *
426
     * @param XMLWriter $objWriter XML Writer
427
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
428
     */
429 105
    private function writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
430
    {
431
        // sheetProtection
432 105
        $objWriter->startElement('sheetProtection');
433
434 105
        if ($pSheet->getProtection()->getPassword() !== '') {
435 2
            $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword());
436
        }
437
438 105
        $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false'));
439 105
        $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false'));
440 105
        $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false'));
441 105
        $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false'));
442 105
        $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false'));
443 105
        $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false'));
444 105
        $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false'));
445 105
        $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false'));
446 105
        $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false'));
447 105
        $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false'));
448 105
        $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false'));
449 105
        $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false'));
450 105
        $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false'));
451 105
        $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false'));
452 105
        $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false'));
453 105
        $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false'));
454 105
        $objWriter->endElement();
455 105
    }
456
457
    /**
458
     * Write ConditionalFormatting.
459
     *
460
     * @param XMLWriter $objWriter XML Writer
461
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
462
     *
463
     * @throws WriterException
464
     */
465 105
    private function writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
466
    {
467
        // Conditional id
468 105
        $id = 1;
469
470
        // Loop through styles in the current worksheet
471 105
        foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
472 5
            foreach ($conditionalStyles as $conditional) {
473
                // WHY was this again?
474
                // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') {
475
                //    continue;
476
                // }
477 5
                if ($conditional->getConditionType() != Conditional::CONDITION_NONE) {
478
                    // conditionalFormatting
479 5
                    $objWriter->startElement('conditionalFormatting');
480 5
                    $objWriter->writeAttribute('sqref', $cellCoordinate);
481
482
                    // cfRule
483 5
                    $objWriter->startElement('cfRule');
484 5
                    $objWriter->writeAttribute('type', $conditional->getConditionType());
485 5
                    $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
486 5
                    $objWriter->writeAttribute('priority', $id++);
487
488 5
                    if (($conditional->getConditionType() == Conditional::CONDITION_CELLIS || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT)
489 5
                        && $conditional->getOperatorType() != Conditional::OPERATOR_NONE) {
490 4
                        $objWriter->writeAttribute('operator', $conditional->getOperatorType());
491
                    }
492
493 5
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
494 5
                        && $conditional->getText() !== null) {
495
                        $objWriter->writeAttribute('text', $conditional->getText());
496
                    }
497
498 5
                    if ($conditional->getStopIfTrue()) {
499 1
                        $objWriter->writeAttribute('stopIfTrue', '1');
500
                    }
501
502 5
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
503 5
                        && $conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT
504 5
                        && $conditional->getText() !== null) {
505
                        $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))');
506 5
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
507 5
                        && $conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH
508 5
                        && $conditional->getText() !== null) {
509
                        $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
510 5
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
511 5
                        && $conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH
512 5
                        && $conditional->getText() !== null) {
513
                        $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
514 5
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
515 5
                        && $conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS
516 5
                        && $conditional->getText() !== null) {
517
                        $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))');
518 5
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CELLIS
519 5
                        || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
520 5
                        || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION) {
521 4
                        foreach ($conditional->getConditions() as $formula) {
522
                            // Formula
523 4
                            $objWriter->writeElement('formula', $formula);
524
                        }
525 2
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSBLANKS) {
526
                        // formula copied from ms xlsx xml source file
527 2
                        $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))=0');
528 1
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_NOTCONTAINSBLANKS) {
529
                        // formula copied from ms xlsx xml source file
530 1
                        $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))>0');
531
                    }
532
533 5
                    $objWriter->endElement();
534
535 5
                    $objWriter->endElement();
536
                }
537
            }
538
        }
539 105
    }
540
541
    /**
542
     * Write DataValidations.
543
     *
544
     * @param XMLWriter $objWriter XML Writer
545
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
546
     */
547 105
    private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
548
    {
549
        // Datavalidation collection
550 105
        $dataValidationCollection = $pSheet->getDataValidationCollection();
551
552
        // Write data validations?
553 105
        if (!empty($dataValidationCollection)) {
554 2
            $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection);
555 2
            $objWriter->startElement('dataValidations');
556 2
            $objWriter->writeAttribute('count', count($dataValidationCollection));
557
558 2
            foreach ($dataValidationCollection as $coordinate => $dv) {
559 2
                $objWriter->startElement('dataValidation');
560
561 2
                if ($dv->getType() != '') {
562 2
                    $objWriter->writeAttribute('type', $dv->getType());
563
                }
564
565 2
                if ($dv->getErrorStyle() != '') {
566 2
                    $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
567
                }
568
569 2
                if ($dv->getOperator() != '') {
570 2
                    $objWriter->writeAttribute('operator', $dv->getOperator());
571
                }
572
573 2
                $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
574 2
                $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
575 2
                $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
576 2
                $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
577
578 2
                if ($dv->getErrorTitle() !== '') {
579 2
                    $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
580
                }
581 2
                if ($dv->getError() !== '') {
582 2
                    $objWriter->writeAttribute('error', $dv->getError());
583
                }
584 2
                if ($dv->getPromptTitle() !== '') {
585 2
                    $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
586
                }
587 2
                if ($dv->getPrompt() !== '') {
588 2
                    $objWriter->writeAttribute('prompt', $dv->getPrompt());
589
                }
590
591 2
                $objWriter->writeAttribute('sqref', $coordinate);
592
593 2
                if ($dv->getFormula1() !== '') {
594 2
                    $objWriter->writeElement('formula1', $dv->getFormula1());
595
                }
596 2
                if ($dv->getFormula2() !== '') {
597 1
                    $objWriter->writeElement('formula2', $dv->getFormula2());
598
                }
599
600 2
                $objWriter->endElement();
601
            }
602
603 2
            $objWriter->endElement();
604
        }
605 105
    }
606
607
    /**
608
     * Write Hyperlinks.
609
     *
610
     * @param XMLWriter $objWriter XML Writer
611
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
612
     */
613 105
    private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
614
    {
615
        // Hyperlink collection
616 105
        $hyperlinkCollection = $pSheet->getHyperlinkCollection();
617
618
        // Relation ID
619 105
        $relationId = 1;
620
621
        // Write hyperlinks?
622 105
        if (!empty($hyperlinkCollection)) {
623 10
            $objWriter->startElement('hyperlinks');
624
625 10
            foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
626 10
                $objWriter->startElement('hyperlink');
627
628 10
                $objWriter->writeAttribute('ref', $coordinate);
629 10
                if (!$hyperlink->isInternal()) {
630 10
                    $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
631 10
                    ++$relationId;
632
                } else {
633 7
                    $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
634
                }
635
636 10
                if ($hyperlink->getTooltip() !== '') {
637 6
                    $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
638 6
                    $objWriter->writeAttribute('display', $hyperlink->getTooltip());
639
                }
640
641 10
                $objWriter->endElement();
642
            }
643
644 10
            $objWriter->endElement();
645
        }
646 105
    }
647
648
    /**
649
     * Write ProtectedRanges.
650
     *
651
     * @param XMLWriter $objWriter XML Writer
652
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
653
     */
654 105
    private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
655
    {
656 105
        if (count($pSheet->getProtectedCells()) > 0) {
657
            // protectedRanges
658 6
            $objWriter->startElement('protectedRanges');
659
660
            // Loop protectedRanges
661 6
            foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
662
                // protectedRange
663 6
                $objWriter->startElement('protectedRange');
664 6
                $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
665 6
                $objWriter->writeAttribute('sqref', $protectedCell);
666 6
                if (!empty($passwordHash)) {
667 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

667
                    $objWriter->writeAttribute('password', /** @scrutinizer ignore-type */ $passwordHash);
Loading history...
668
                }
669 6
                $objWriter->endElement();
670
            }
671
672 6
            $objWriter->endElement();
673
        }
674 105
    }
675
676
    /**
677
     * Write MergeCells.
678
     *
679
     * @param XMLWriter $objWriter XML Writer
680
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
681
     */
682 105
    private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
683
    {
684 105
        if (count($pSheet->getMergeCells()) > 0) {
685
            // mergeCells
686 13
            $objWriter->startElement('mergeCells');
687
688
            // Loop mergeCells
689 13
            foreach ($pSheet->getMergeCells() as $mergeCell) {
690
                // mergeCell
691 13
                $objWriter->startElement('mergeCell');
692 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

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

965
        $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->/** @scrutinizer ignore-call */ flipStringTable($pStringTable);
Loading history...
966
967
        // sheetData
968 105
        $objWriter->startElement('sheetData');
969
970
        // Get column count
971 105
        $colCount = Coordinate::columnIndexFromString($pSheet->getHighestColumn());
972
973
        // Highest row number
974 105
        $highestRow = $pSheet->getHighestRow();
975
976
        // Loop through cells
977 105
        $cellsByRow = [];
978 105
        foreach ($pSheet->getCoordinates() as $coordinate) {
979 99
            $cellAddress = Coordinate::coordinateFromString($coordinate);
980 99
            $cellsByRow[$cellAddress[1]][] = $coordinate;
981
        }
982
983 105
        $currentRow = 0;
984 105
        while ($currentRow++ < $highestRow) {
985
            // Get row dimension
986 105
            $rowDimension = $pSheet->getRowDimension($currentRow);
987
988
            // Write current row?
989 105
            $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null;
0 ignored issues
show
introduced by
The condition $rowDimension->getXfIndex() !== null is always true.
Loading history...
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...
990
991 105
            if ($writeCurrentRow) {
992
                // Start a new row
993 99
                $objWriter->startElement('row');
994 99
                $objWriter->writeAttribute('r', $currentRow);
995 99
                $objWriter->writeAttribute('spans', '1:' . $colCount);
996
997
                // Row dimensions
998 99
                if ($rowDimension->getRowHeight() >= 0) {
999 6
                    $objWriter->writeAttribute('customHeight', '1');
1000 6
                    $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight()));
1001
                }
1002
1003
                // Row visibility
1004 99
                if (!$rowDimension->getVisible() === true) {
1005 2
                    $objWriter->writeAttribute('hidden', 'true');
1006
                }
1007
1008
                // Collapsed
1009 99
                if ($rowDimension->getCollapsed() === true) {
1010
                    $objWriter->writeAttribute('collapsed', 'true');
1011
                }
1012
1013
                // Outline level
1014 99
                if ($rowDimension->getOutlineLevel() > 0) {
1015
                    $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
1016
                }
1017
1018
                // Style
1019 99
                if ($rowDimension->getXfIndex() !== null) {
1020
                    $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
1021
                    $objWriter->writeAttribute('customFormat', '1');
1022
                }
1023
1024
                // Write cells
1025 99
                if (isset($cellsByRow[$currentRow])) {
1026 99
                    foreach ($cellsByRow[$currentRow] as $cellAddress) {
1027
                        // Write cell
1028 99
                        $this->writeCell($objWriter, $pSheet, $cellAddress, $aFlippedStringTable);
1029
                    }
1030
                }
1031
1032
                // End row
1033 99
                $objWriter->endElement();
1034
            }
1035
        }
1036
1037 105
        $objWriter->endElement();
1038 105
    }
1039
1040
    /**
1041
     * Write Cell.
1042
     *
1043
     * @param XMLWriter $objWriter XML Writer
1044
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1045
     * @param Cell $pCellAddress Cell Address
1046
     * @param string[] $pFlippedStringTable String table (flipped), for faster index searching
1047
     *
1048
     * @throws WriterException
1049
     */
1050 99
    private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $pCellAddress, array $pFlippedStringTable)
1051
    {
1052
        // Cell
1053 99
        $pCell = $pSheet->getCell($pCellAddress);
1054 99
        $objWriter->startElement('c');
1055 99
        $objWriter->writeAttribute('r', $pCellAddress);
1056
1057
        // Sheet styles
1058 99
        if ($pCell->getXfIndex() != '') {
1059 33
            $objWriter->writeAttribute('s', $pCell->getXfIndex());
1060
        }
1061
1062
        // If cell value is supplied, write cell value
1063 99
        $cellValue = $pCell->getValue();
1064 99
        if (is_object($cellValue) || $cellValue !== '') {
1065
            // Map type
1066 99
            $mappedType = $pCell->getDataType();
1067
1068
            // Write data type depending on its type
1069 99
            switch (strtolower($mappedType)) {
1070 99
                case 'inlinestr':    // Inline string
1071 98
                case 's':            // String
1072 82
                case 'b':            // Boolean
1073 66
                    $objWriter->writeAttribute('t', $mappedType);
1074
1075 66
                    break;
1076 79
                case 'f':            // Formula
1077 22
                    $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?
1078 22
                        $pCell->getCalculatedValue() : $cellValue;
1079 22
                    if (is_string($calculatedValue)) {
1080 14
                        $objWriter->writeAttribute('t', 'str');
1081 19
                    } elseif (is_bool($calculatedValue)) {
1082 5
                        $objWriter->writeAttribute('t', 'b');
1083
                    }
1084
1085 22
                    break;
1086 75
                case 'e':            // Error
1087
                    $objWriter->writeAttribute('t', $mappedType);
1088
            }
1089
1090
            // Write data depending on its type
1091 99
            switch (strtolower($mappedType)) {
1092 99
                case 'inlinestr':    // Inline string
1093 8
                    if (!$cellValue instanceof RichText) {
1094
                        $objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
1095 8
                    } elseif ($cellValue instanceof RichText) {
0 ignored issues
show
introduced by
$cellValue is always a sub-type of PhpOffice\PhpSpreadsheet\RichText\RichText.
Loading history...
1096 8
                        $objWriter->startElement('is');
1097 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

1097
                        $this->getParentWriter()->getWriterPart('stringtable')->/** @scrutinizer ignore-call */ writeRichText($objWriter, $cellValue);
Loading history...
1098 8
                        $objWriter->endElement();
1099
                    }
1100
1101 8
                    break;
1102 98
                case 's':            // String
1103 64
                    if (!$cellValue instanceof RichText) {
1104 64
                        if (isset($pFlippedStringTable[$cellValue])) {
1105 64
                            $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]);
1106
                        }
1107 2
                    } elseif ($cellValue instanceof RichText) {
0 ignored issues
show
introduced by
$cellValue is always a sub-type of PhpOffice\PhpSpreadsheet\RichText\RichText.
Loading history...
1108 2
                        $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
1109
                    }
1110
1111 64
                    break;
1112 82
                case 'f':            // Formula
1113 22
                    $attributes = $pCell->getFormulaAttributes();
1114 22
                    if (($attributes['t'] ?? null) === 'array') {
1115
                        $objWriter->startElement('f');
1116
                        $objWriter->writeAttribute('t', 'array');
1117
                        $objWriter->writeAttribute('ref', $pCellAddress);
1118
                        $objWriter->writeAttribute('aca', '1');
1119
                        $objWriter->writeAttribute('ca', '1');
1120
                        $objWriter->text(substr($cellValue, 1));
1121
                        $objWriter->endElement();
1122
                    } else {
1123 22
                        $objWriter->writeElement('f', substr($cellValue, 1));
1124
                    }
1125 22
                    if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
1126 22
                        if ($this->getParentWriter()->getPreCalculateFormulas()) {
1127 22
                            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...
1128 22
                                $objWriter->writeElement('v', StringHelper::formatNumber($calculatedValue));
1129
                            } else {
1130 22
                                $objWriter->writeElement('v', '0');
1131
                            }
1132
                        } else {
1133
                            $objWriter->writeElement('v', '0');
1134
                        }
1135
                    }
1136
1137 22
                    break;
1138 78
                case 'n':            // Numeric
1139
                    //force a decimal to be written if the type is float
1140 67
                    if (is_float($cellValue)) {
1141
                        // force point as decimal separator in case current locale uses comma
1142 28
                        $cellValue = str_replace(',', '.', (string) $cellValue);
1143 28
                        if (strpos($cellValue, '.') === false) {
1144 17
                            $cellValue = $cellValue . '.0';
1145
                        }
1146
                    }
1147 67
                    $objWriter->writeElement('v', $cellValue);
1148
1149 67
                    break;
1150 29
                case 'b':            // Boolean
1151 9
                    $objWriter->writeElement('v', ($cellValue ? '1' : '0'));
1152
1153 9
                    break;
1154 24
                case 'e':            // Error
1155
                    if (substr($cellValue, 0, 1) === '=') {
1156
                        $objWriter->writeElement('f', substr($cellValue, 1));
1157
                        $objWriter->writeElement('v', substr($cellValue, 1));
1158
                    } else {
1159
                        $objWriter->writeElement('v', $cellValue);
1160
                    }
1161
1162
                    break;
1163
            }
1164
        }
1165
1166 99
        $objWriter->endElement();
1167 99
    }
1168
1169
    /**
1170
     * Write Drawings.
1171
     *
1172
     * @param XMLWriter $objWriter XML Writer
1173
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1174
     * @param bool $includeCharts Flag indicating if we should include drawing details for charts
1175
     */
1176 105
    private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $includeCharts = false)
1177
    {
1178 105
        $unparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
1179 105
        $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']);
1180 105
        $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
1181 105
        if ($chartCount == 0 && $pSheet->getDrawingCollection()->count() == 0 && !$hasUnparsedDrawing) {
1182 80
            return;
1183
        }
1184
1185
        // If sheet contains drawings, add the relationships
1186 27
        $objWriter->startElement('drawing');
1187
1188 27
        $rId = 'rId1';
1189 27
        if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) {
1190 4
            $drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'];
1191
            // take first. In future can be overriten
1192 4
            $rId = reset($drawingOriginalIds);
1193
        }
1194
1195 27
        $objWriter->writeAttribute('r:id', $rId);
1196 27
        $objWriter->endElement();
1197 27
    }
1198
1199
    /**
1200
     * Write LegacyDrawing.
1201
     *
1202
     * @param XMLWriter $objWriter XML Writer
1203
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1204
     */
1205 105
    private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1206
    {
1207
        // If sheet contains comments, add the relationships
1208 105
        if (count($pSheet->getComments()) > 0) {
1209 10
            $objWriter->startElement('legacyDrawing');
1210 10
            $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
1211 10
            $objWriter->endElement();
1212
        }
1213 105
    }
1214
1215
    /**
1216
     * Write LegacyDrawingHF.
1217
     *
1218
     * @param XMLWriter $objWriter XML Writer
1219
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1220
     */
1221 105
    private function writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1222
    {
1223
        // If sheet contains images, add the relationships
1224 105
        if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
1225 1
            $objWriter->startElement('legacyDrawingHF');
1226 1
            $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
1227 1
            $objWriter->endElement();
1228
        }
1229 105
    }
1230
1231 105
    private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1232
    {
1233 105
        if (empty($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'])) {
1234 105
            return;
1235
        }
1236
1237 1
        foreach ($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'] as $alternateContent) {
1238 1
            $objWriter->writeRaw($alternateContent);
1239
        }
1240 1
    }
1241
}
1242