Passed
Push — develop ( e3fb16...4c09d4 )
by Adrien
28:18
created

Worksheet::writeCols()   B

Complexity

Conditions 9
Paths 66

Size

Total Lines 55
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 24
nc 66
nop 2
dl 0
loc 55
ccs 24
cts 24
cp 1
crap 9
rs 7.2446
c 0
b 0
f 0

How to fix   Long Method   

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

657
                    $objWriter->writeAttribute('password', /** @scrutinizer ignore-type */ $passwordHash);
Loading history...
658
                }
659 6
                $objWriter->endElement();
660
            }
661
662 6
            $objWriter->endElement();
663
        }
664 78
    }
665
666
    /**
667
     * Write MergeCells.
668
     *
669
     * @param XMLWriter $objWriter XML Writer
670
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
671
     */
672 78
    private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
673
    {
674 78
        if (count($pSheet->getMergeCells()) > 0) {
675
            // mergeCells
676 13
            $objWriter->startElement('mergeCells');
677
678
            // Loop mergeCells
679 13
            foreach ($pSheet->getMergeCells() as $mergeCell) {
680
                // mergeCell
681 13
                $objWriter->startElement('mergeCell');
682 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

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

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

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