Failed Conditions
Push — develop ( 064076...83c759 )
by Adrien
63:09
created

Worksheet::writeSheetFormatPr()   D

Complexity

Conditions 9
Paths 72

Size

Total Lines 43
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 9.0117

Importance

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

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

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

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

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