Failed Conditions
Push — develop ( 11b055...32a55a )
by Adrien
30:13
created

Worksheet::writeSheetPr()   C

Complexity

Conditions 8
Paths 24

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 9.1365

Importance

Changes 0
Metric Value
cc 8
eloc 22
nc 24
nop 2
dl 0
loc 38
ccs 17
cts 23
cp 0.7391
crap 9.1365
rs 5.3846
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 56
    public function writeWorksheet(PhpspreadsheetWorksheet $pSheet, $pStringTable = null, $includeCharts = false)
36
    {
37
        // Create XML writer
38 56
        $objWriter = null;
39 56 View Code Duplication
        if ($this->getParentWriter()->getUseDiskCaching()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
40
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
41
        } else {
42 56
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
43
        }
44
45
        // XML header
46 56
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
47
48
        // Worksheet
49 56
        $objWriter->startElement('worksheet');
50 56
        $objWriter->writeAttribute('xml:space', 'preserve');
51 56
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
52 56
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
53
54
        // sheetPr
55 56
        $this->writeSheetPr($objWriter, $pSheet);
56
57
        // Dimension
58 56
        $this->writeDimension($objWriter, $pSheet);
59
60
        // sheetViews
61 56
        $this->writeSheetViews($objWriter, $pSheet);
62
63
        // sheetFormatPr
64 56
        $this->writeSheetFormatPr($objWriter, $pSheet);
65
66
        // cols
67 56
        $this->writeCols($objWriter, $pSheet);
68
69
        // sheetData
70 56
        $this->writeSheetData($objWriter, $pSheet, $pStringTable);
1 ignored issue
show
Bug introduced by
It seems like $pStringTable can also be of type null; however, parameter $pStringTable of PhpOffice\PhpSpreadsheet...sheet::writeSheetData() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

70
        $this->writeSheetData($objWriter, $pSheet, /** @scrutinizer ignore-type */ $pStringTable);
Loading history...
71
72
        // sheetProtection
73 56
        $this->writeSheetProtection($objWriter, $pSheet);
74
75
        // protectedRanges
76 56
        $this->writeProtectedRanges($objWriter, $pSheet);
77
78
        // autoFilter
79 56
        $this->writeAutoFilter($objWriter, $pSheet);
80
81
        // mergeCells
82 56
        $this->writeMergeCells($objWriter, $pSheet);
83
84
        // conditionalFormatting
85 56
        $this->writeConditionalFormatting($objWriter, $pSheet);
86
87
        // dataValidations
88 56
        $this->writeDataValidations($objWriter, $pSheet);
89
90
        // hyperlinks
91 56
        $this->writeHyperlinks($objWriter, $pSheet);
92
93
        // Print options
94 56
        $this->writePrintOptions($objWriter, $pSheet);
95
96
        // Page margins
97 56
        $this->writePageMargins($objWriter, $pSheet);
98
99
        // Page setup
100 56
        $this->writePageSetup($objWriter, $pSheet);
101
102
        // Header / footer
103 56
        $this->writeHeaderFooter($objWriter, $pSheet);
104
105
        // Breaks
106 56
        $this->writeBreaks($objWriter, $pSheet);
107
108
        // Drawings and/or Charts
109 56
        $this->writeDrawings($objWriter, $pSheet, $includeCharts);
110
111
        // LegacyDrawing
112 56
        $this->writeLegacyDrawing($objWriter, $pSheet);
113
114
        // LegacyDrawingHF
115 56
        $this->writeLegacyDrawingHF($objWriter, $pSheet);
116
117 56
        $objWriter->endElement();
118
119
        // Return
120 56
        return $objWriter->getData();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $objWriter->getData() could also return false which is incompatible with the documented return type string. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
121
    }
122
123
    /**
124
     * Write SheetPr.
125
     *
126
     * @param XMLWriter $objWriter XML Writer
127
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
128
     *
129
     * @throws WriterException
130
     */
131 56
    private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
132
    {
133
        // sheetPr
134 56
        $objWriter->startElement('sheetPr');
135 56
        if ($pSheet->getParent()->hasMacros()) {
136
            //if the workbook have macros, we need to have codeName for the sheet
137
            if ($pSheet->hasCodeName() == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

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

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

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

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

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

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

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

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

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

Loading history...
471
                //    continue;
472
                // }
473 2
                if ($conditional->getConditionType() != Conditional::CONDITION_NONE) {
474
                    // conditionalFormatting
475 2
                    $objWriter->startElement('conditionalFormatting');
476 2
                    $objWriter->writeAttribute('sqref', $cellCoordinate);
477
478
                    // cfRule
479 2
                    $objWriter->startElement('cfRule');
480 2
                    $objWriter->writeAttribute('type', $conditional->getConditionType());
481 2
                    $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
482 2
                    $objWriter->writeAttribute('priority', $id++);
483
484 2
                    if (($conditional->getConditionType() == Conditional::CONDITION_CELLIS || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT)
485 2
                        && $conditional->getOperatorType() != Conditional::OPERATOR_NONE) {
486 2
                        $objWriter->writeAttribute('operator', $conditional->getOperatorType());
487
                    }
488
489 2
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
490 2
                        && $conditional->getText() !== null) {
491
                        $objWriter->writeAttribute('text', $conditional->getText());
492
                    }
493
494 2
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
495 2
                        && $conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT
496 2
                        && $conditional->getText() !== null) {
497
                        $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))');
498 2 View Code Duplication
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
499 2
                        && $conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH
500 2
                        && $conditional->getText() !== null) {
501
                        $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
502 2
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
503 2
                        && $conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH
504 2
                        && $conditional->getText() !== null) {
505
                        $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
506 2 View Code Duplication
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
507 2
                        && $conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS
508 2
                        && $conditional->getText() !== null) {
509
                        $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))');
510 2
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CELLIS
511
                        || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
512 2
                        || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION) {
513 2
                        foreach ($conditional->getConditions() as $formula) {
514
                            // Formula
515 2
                            $objWriter->writeElement('formula', $formula);
516
                        }
517
                    }
518
519 2
                    $objWriter->endElement();
520
521 2
                    $objWriter->endElement();
522
                }
523
            }
524
        }
525 56
    }
526
527
    /**
528
     * Write DataValidations.
529
     *
530
     * @param XMLWriter $objWriter XML Writer
531
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
532
     *
533
     * @throws WriterException
534
     */
535 56
    private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
536
    {
537
        // Datavalidation collection
538 56
        $dataValidationCollection = $pSheet->getDataValidationCollection();
539
540
        // Write data validations?
541 56
        if (!empty($dataValidationCollection)) {
542 2
            $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection);
543 2
            $objWriter->startElement('dataValidations');
544 2
            $objWriter->writeAttribute('count', count($dataValidationCollection));
545
546 2
            foreach ($dataValidationCollection as $coordinate => $dv) {
547 2
                $objWriter->startElement('dataValidation');
548
549 2
                if ($dv->getType() != '') {
550 2
                    $objWriter->writeAttribute('type', $dv->getType());
551
                }
552
553 2
                if ($dv->getErrorStyle() != '') {
554 2
                    $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
555
                }
556
557 2
                if ($dv->getOperator() != '') {
558 2
                    $objWriter->writeAttribute('operator', $dv->getOperator());
559
                }
560
561 2
                $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
562 2
                $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
563 2
                $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
564 2
                $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
565
566 2
                if ($dv->getErrorTitle() !== '') {
567 2
                    $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
568
                }
569 2
                if ($dv->getError() !== '') {
570 2
                    $objWriter->writeAttribute('error', $dv->getError());
571
                }
572 2
                if ($dv->getPromptTitle() !== '') {
573 2
                    $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
574
                }
575 2
                if ($dv->getPrompt() !== '') {
576 2
                    $objWriter->writeAttribute('prompt', $dv->getPrompt());
577
                }
578
579 2
                $objWriter->writeAttribute('sqref', $coordinate);
580
581 2
                if ($dv->getFormula1() !== '') {
582 2
                    $objWriter->writeElement('formula1', $dv->getFormula1());
583
                }
584 2
                if ($dv->getFormula2() !== '') {
585 1
                    $objWriter->writeElement('formula2', $dv->getFormula2());
586
                }
587
588 2
                $objWriter->endElement();
589
            }
590
591 2
            $objWriter->endElement();
592
        }
593 56
    }
594
595
    /**
596
     * Write Hyperlinks.
597
     *
598
     * @param XMLWriter $objWriter XML Writer
599
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
600
     *
601
     * @throws WriterException
602
     */
603 56
    private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
604
    {
605
        // Hyperlink collection
606 56
        $hyperlinkCollection = $pSheet->getHyperlinkCollection();
607
608
        // Relation ID
609 56
        $relationId = 1;
610
611
        // Write hyperlinks?
612 56
        if (!empty($hyperlinkCollection)) {
613 10
            $objWriter->startElement('hyperlinks');
614
615 10
            foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
616 10
                $objWriter->startElement('hyperlink');
617
618 10
                $objWriter->writeAttribute('ref', $coordinate);
619 10
                if (!$hyperlink->isInternal()) {
620 10
                    $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
621 10
                    ++$relationId;
622
                } else {
623 7
                    $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
624
                }
625
626 10
                if ($hyperlink->getTooltip() != '') {
627 6
                    $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
628
                }
629
630 10
                $objWriter->endElement();
631
            }
632
633 10
            $objWriter->endElement();
634
        }
635 56
    }
636
637
    /**
638
     * Write ProtectedRanges.
639
     *
640
     * @param XMLWriter $objWriter XML Writer
641
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
642
     *
643
     * @throws WriterException
644
     */
645 56
    private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
646
    {
647 56
        if (count($pSheet->getProtectedCells()) > 0) {
648
            // protectedRanges
649 6
            $objWriter->startElement('protectedRanges');
650
651
            // Loop protectedRanges
652 6
            foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
653
                // protectedRange
654 6
                $objWriter->startElement('protectedRange');
655 6
                $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
656 6
                $objWriter->writeAttribute('sqref', $protectedCell);
657 6
                if (!empty($passwordHash)) {
658 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

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

685
                $objWriter->writeAttribute('ref', /** @scrutinizer ignore-type */ $mergeCell);
Loading history...
686 12
                $objWriter->endElement();
687
            }
688
689 12
            $objWriter->endElement();
690
        }
691 56
    }
692
693
    /**
694
     * Write PrintOptions.
695
     *
696
     * @param XMLWriter $objWriter XML Writer
697
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
698
     *
699
     * @throws WriterException
700
     */
701 56
    private function writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
702
    {
703
        // printOptions
704 56
        $objWriter->startElement('printOptions');
705
706 56
        $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true' : 'false'));
707 56
        $objWriter->writeAttribute('gridLinesSet', 'true');
708
709 56
        if ($pSheet->getPageSetup()->getHorizontalCentered()) {
710
            $objWriter->writeAttribute('horizontalCentered', 'true');
711
        }
712
713 56
        if ($pSheet->getPageSetup()->getVerticalCentered()) {
714
            $objWriter->writeAttribute('verticalCentered', 'true');
715
        }
716
717 56
        $objWriter->endElement();
718 56
    }
719
720
    /**
721
     * Write PageMargins.
722
     *
723
     * @param XMLWriter $objWriter XML Writer
724
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
725
     *
726
     * @throws WriterException
727
     */
728 56
    private function writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
729
    {
730
        // pageMargins
731 56
        $objWriter->startElement('pageMargins');
732 56
        $objWriter->writeAttribute('left', StringHelper::formatNumber($pSheet->getPageMargins()->getLeft()));
733 56
        $objWriter->writeAttribute('right', StringHelper::formatNumber($pSheet->getPageMargins()->getRight()));
734 56
        $objWriter->writeAttribute('top', StringHelper::formatNumber($pSheet->getPageMargins()->getTop()));
735 56
        $objWriter->writeAttribute('bottom', StringHelper::formatNumber($pSheet->getPageMargins()->getBottom()));
736 56
        $objWriter->writeAttribute('header', StringHelper::formatNumber($pSheet->getPageMargins()->getHeader()));
737 56
        $objWriter->writeAttribute('footer', StringHelper::formatNumber($pSheet->getPageMargins()->getFooter()));
738 56
        $objWriter->endElement();
739 56
    }
740
741
    /**
742
     * Write AutoFilter.
743
     *
744
     * @param XMLWriter $objWriter XML Writer
745
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
746
     *
747
     * @throws WriterException
748
     */
749 56
    private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
750
    {
751 56
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
752 56
        if (!empty($autoFilterRange)) {
753
            // autoFilter
754 3
            $objWriter->startElement('autoFilter');
755
756
            // Strip any worksheet reference from the filter coordinates
757 3
            $range = Coordinate::splitRange($autoFilterRange);
758 3
            $range = $range[0];
759
            //    Strip any worksheet ref
760 3 View Code Duplication
            if (strpos($range[0], '!') !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
761
                list($ws, $range[0]) = explode('!', $range[0]);
762
            }
763 3
            $range = implode(':', $range);
764
765 3
            $objWriter->writeAttribute('ref', str_replace('$', '', $range));
766
767 3
            $columns = $pSheet->getAutoFilter()->getColumns();
768 3
            if (count($columns) > 0) {
769 2
                foreach ($columns as $columnID => $column) {
770 2
                    $rules = $column->getRules();
771 2
                    if (count($rules) > 0) {
772 2
                        $objWriter->startElement('filterColumn');
773 2
                        $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID));
774
775 2
                        $objWriter->startElement($column->getFilterType());
776 2
                        if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) {
777 1
                            $objWriter->writeAttribute('and', 1);
778
                        }
779
780 2
                        foreach ($rules as $rule) {
781 2
                            if (($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) &&
782 2
                                ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&
783 2
                                ($rule->getValue() === '')) {
784
                                //    Filter rule for Blanks
785 1
                                $objWriter->writeAttribute('blank', 1);
786 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
787
                                //    Dynamic Filter Rule
788 1
                                $objWriter->writeAttribute('type', $rule->getGrouping());
789 1
                                $val = $column->getAttribute('val');
790 1
                                if ($val !== null) {
791 1
                                    $objWriter->writeAttribute('val', $val);
792
                                }
793 1
                                $maxVal = $column->getAttribute('maxVal');
794 1
                                if ($maxVal !== null) {
795 1
                                    $objWriter->writeAttribute('maxVal', $maxVal);
796
                                }
797 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
798
                                //    Top 10 Filter Rule
799
                                $objWriter->writeAttribute('val', $rule->getValue());
800
                                $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
801
                                $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0'));
802
                            } else {
803
                                //    Filter, DateGroupItem or CustomFilter
804 2
                                $objWriter->startElement($rule->getRuleType());
805
806 2
                                if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
807 1
                                    $objWriter->writeAttribute('operator', $rule->getOperator());
808
                                }
809 2
                                if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
810
                                    // Date Group filters
811 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...
812 1
                                        if ($value > '') {
813 1
                                            $objWriter->writeAttribute($key, $value);
814
                                        }
815
                                    }
816 1
                                    $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
817
                                } else {
818 2
                                    $objWriter->writeAttribute('val', $rule->getValue());
819
                                }
820
821 2
                                $objWriter->endElement();
822
                            }
823
                        }
824
825 2
                        $objWriter->endElement();
826
827 2
                        $objWriter->endElement();
828
                    }
829
                }
830
            }
831 3
            $objWriter->endElement();
832
        }
833 56
    }
834
835
    /**
836
     * Write PageSetup.
837
     *
838
     * @param XMLWriter $objWriter XML Writer
839
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
840
     *
841
     * @throws WriterException
842
     */
843 56
    private function writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
844
    {
845
        // pageSetup
846 56
        $objWriter->startElement('pageSetup');
847 56
        $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
848 56
        $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
849
850 56
        if ($pSheet->getPageSetup()->getScale() !== null) {
851 56
            $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
852
        }
853 56
        if ($pSheet->getPageSetup()->getFitToHeight() !== null) {
854 56
            $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
855
        } else {
856
            $objWriter->writeAttribute('fitToHeight', '0');
857
        }
858 56
        if ($pSheet->getPageSetup()->getFitToWidth() !== null) {
859 56
            $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
860
        } else {
861
            $objWriter->writeAttribute('fitToWidth', '0');
862
        }
863 56
        if ($pSheet->getPageSetup()->getFirstPageNumber() !== null) {
864
            $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
865
            $objWriter->writeAttribute('useFirstPageNumber', '1');
866
        }
867
868 56
        $objWriter->endElement();
869 56
    }
870
871
    /**
872
     * Write Header / Footer.
873
     *
874
     * @param XMLWriter $objWriter XML Writer
875
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
876
     *
877
     * @throws WriterException
878
     */
879 56
    private function writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
880
    {
881
        // headerFooter
882 56
        $objWriter->startElement('headerFooter');
883 56
        $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
884 56
        $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
885 56
        $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
886 56
        $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
887
888 56
        $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
889 56
        $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
890 56
        $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
891 56
        $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
892 56
        $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
893 56
        $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
894 56
        $objWriter->endElement();
895 56
    }
896
897
    /**
898
     * Write Breaks.
899
     *
900
     * @param XMLWriter $objWriter XML Writer
901
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
902
     *
903
     * @throws WriterException
904
     */
905 56
    private function writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
906
    {
907
        // Get row and column breaks
908 56
        $aRowBreaks = [];
909 56
        $aColumnBreaks = [];
910 56
        foreach ($pSheet->getBreaks() as $cell => $breakType) {
911 1
            if ($breakType == PhpspreadsheetWorksheet::BREAK_ROW) {
912 1
                $aRowBreaks[] = $cell;
913
            } elseif ($breakType == PhpspreadsheetWorksheet::BREAK_COLUMN) {
914 1
                $aColumnBreaks[] = $cell;
915
            }
916
        }
917
918
        // rowBreaks
919 56 View Code Duplication
        if (!empty($aRowBreaks)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
920 1
            $objWriter->startElement('rowBreaks');
921 1
            $objWriter->writeAttribute('count', count($aRowBreaks));
922 1
            $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
923
924 1
            foreach ($aRowBreaks as $cell) {
925 1
                $coords = Coordinate::coordinateFromString($cell);
926
927 1
                $objWriter->startElement('brk');
928 1
                $objWriter->writeAttribute('id', $coords[1]);
929 1
                $objWriter->writeAttribute('man', '1');
930 1
                $objWriter->endElement();
931
            }
932
933 1
            $objWriter->endElement();
934
        }
935
936
        // Second, write column breaks
937 56 View Code Duplication
        if (!empty($aColumnBreaks)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
938
            $objWriter->startElement('colBreaks');
939
            $objWriter->writeAttribute('count', count($aColumnBreaks));
940
            $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
941
942
            foreach ($aColumnBreaks as $cell) {
943
                $coords = Coordinate::coordinateFromString($cell);
944
945
                $objWriter->startElement('brk');
946
                $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1);
947
                $objWriter->writeAttribute('man', '1');
948
                $objWriter->endElement();
949
            }
950
951
            $objWriter->endElement();
952
        }
953 56
    }
954
955
    /**
956
     * Write SheetData.
957
     *
958
     * @param XMLWriter $objWriter XML Writer
959
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
960
     * @param string[] $pStringTable String table
961
     *
962
     * @throws WriterException
963
     */
964 56
    private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable)
965
    {
966
        // Flipped stringtable, for faster index searching
967 56
        $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

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

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

1097
                        $this->getParentWriter()->getWriterPart('stringtable')->/** @scrutinizer ignore-call */ writeRichText($objWriter, $cellValue);
Loading history...
1098 8
                        $objWriter->endElement();
1099
                    }
1100
1101 8
                    break;
1102 55
                case 's':            // String
1103 50
                    if (!$cellValue instanceof RichText) {
1104 50
                        if (isset($pFlippedStringTable[$cellValue])) {
1105 50
                            $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]);
1106
                        }
1107 2
                    } elseif ($cellValue instanceof RichText) {
1108 2
                        $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
1109
                    }
1110
1111 50
                    break;
1112 48
                case 'f':            // Formula
1113 18
                    $attributes = $pCell->getFormulaAttributes();
1114 18
                    if ($attributes['t'] == 'array') {
1115
                        $objWriter->startElement('f');
1116
                        $objWriter->writeAttribute('t', 'array');
1117
                        $objWriter->writeAttribute('ref', $pCellAddress);
1118
                        $objWriter->writeAttribute('aca', '1');
1119
                        $objWriter->writeAttribute('ca', '1');
1120
                        $objWriter->text(substr($cellValue, 1));
1 ignored issue
show
Bug introduced by
It seems like substr($cellValue, 1) can also be of type false; however, parameter $content of XMLWriter::text() does only seem to accept string, 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

1120
                        $objWriter->text(/** @scrutinizer ignore-type */ substr($cellValue, 1));
Loading history...
1121
                        $objWriter->endElement();
1122
                    } else {
1123 18
                        $objWriter->writeElement('f', substr($cellValue, 1));
1 ignored issue
show
Bug introduced by
It seems like substr($cellValue, 1) can also be of type false; however, parameter $content of XMLWriter::writeElement() does only seem to accept string, 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

1123
                        $objWriter->writeElement('f', /** @scrutinizer ignore-type */ substr($cellValue, 1));
Loading history...
1124
                    }
1125 18
                    if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
1126 18
                        if ($this->getParentWriter()->getPreCalculateFormulas()) {
1127 18
                            if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $calculatedValue does not seem to be defined for all execution paths leading up to this point.
Loading history...
1128 18
                                $objWriter->writeElement('v', StringHelper::formatNumber($calculatedValue));
1129
                            } else {
1130 18
                                $objWriter->writeElement('v', '0');
1131
                            }
1132
                        } else {
1133
                            $objWriter->writeElement('v', '0');
1134
                        }
1135
                    }
1136
1137 18
                    break;
1138 47
                case 'n':            // Numeric
1139
                    // force point as decimal separator in case current locale uses comma
1140 39
                    $objWriter->writeElement('v', str_replace(',', '.', $cellValue));
1141
1142 39
                    break;
1143 26
                case 'b':            // Boolean
1144 8
                    $objWriter->writeElement('v', ($cellValue ? '1' : '0'));
1145
1146 8
                    break;
1147 22
                case 'e':            // Error
1148
                    if (substr($cellValue, 0, 1) == '=') {
1149
                        $objWriter->writeElement('f', substr($cellValue, 1));
1150
                        $objWriter->writeElement('v', substr($cellValue, 1));
1151
                    } else {
1152
                        $objWriter->writeElement('v', $cellValue);
1153
                    }
1154
1155
                    break;
1156
            }
1157
        }
1158
1159 56
        $objWriter->endElement();
1160 56
    }
1161
1162
    /**
1163
     * Write Drawings.
1164
     *
1165
     * @param XMLWriter $objWriter XML Writer
1166
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1167
     * @param bool $includeCharts Flag indicating if we should include drawing details for charts
1168
     *
1169
     * @throws WriterException
1170
     */
1171 56
    private function writeDrawings(XMLWriter $objWriter = null, PhpspreadsheetWorksheet $pSheet = null, $includeCharts = false)
1172
    {
1173 56
        $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
1 ignored issue
show
Bug introduced by
The method getChartCollection() does not exist on null. ( Ignorable by Annotation )

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

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

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

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

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

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

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

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

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

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