Completed
Push — develop ( e1f81f...539a89 )
by Adrien
16:11
created

Excel5::setTempDir()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PhpSpreadsheet\Writer;
4
5
/**
6
 * \PhpSpreadsheet\Writer\Excel5
7
 *
8
 * Copyright (c) 2006 - 2015 PhpSpreadsheet
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
 *
24
 * @category   PhpSpreadsheet
25
 * @copyright  Copyright (c) 2006 - 2015 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
26
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
27
 * @version    ##VERSION##, ##DATE##
28
 */
29
class Excel5 extends BaseWriter implements IWriter
30
{
31
    /**
32
     * PhpSpreadsheet object
33
     *
34
     * @var \PhpSpreadsheet\Spreadsheet
35
     */
36
    private $spreadsheet;
37
38
    /**
39
     * Total number of shared strings in workbook
40
     *
41
     * @var int
42
     */
43
    private $strTotal = 0;
44
45
    /**
46
     * Number of unique shared strings in workbook
47
     *
48
     * @var int
49
     */
50
    private $strUnique = 0;
51
52
    /**
53
     * Array of unique shared strings in workbook
54
     *
55
     * @var array
56
     */
57
    private $strTable = array();
58
59
    /**
60
     * Color cache. Mapping between RGB value and color index.
61
     *
62
     * @var array
63
     */
64
    private $colors;
65
66
    /**
67
     * Formula parser
68
     *
69
     * @var \PhpSpreadsheet\Writer\Excel5\Parser
70
     */
71
    private $parser;
72
73
    /**
74
     * Identifier clusters for drawings. Used in MSODRAWINGGROUP record.
75
     *
76
     * @var array
77
     */
78
    private $IDCLs;
79
80
    /**
81
     * Basic OLE object summary information
82
     *
83
     * @var array
84
     */
85
    private $summaryInformation;
86
87
    /**
88
     * Extended OLE object document summary information
89
     *
90
     * @var array
91
     */
92
    private $documentSummaryInformation;
93
94
    /**
95
     * Create a new Excel5 Writer
96
     *
97
     * @param    \PhpSpreadsheet\Spreadsheet    $spreadsheet    PhpSpreadsheet object
98
     */
99
    public function __construct(\PhpSpreadsheet\Spreadsheet $spreadsheet)
100
    {
101
        $this->spreadsheet = $spreadsheet;
102
103
        $this->parser   = new Excel5\Parser();
104
    }
105
106
    /**
107
     * Save Spreadsheet to file
108
     *
109
     * @param    string        $pFilename
110
     * @throws    \PhpSpreadsheet\Writer\Exception
111
     */
112
    public function save($pFilename = null)
113
    {
114
115
        // garbage collect
116
        $this->spreadsheet->garbageCollect();
117
118
        $saveDebugLog = \PhpSpreadsheet\Calculation::getInstance($this->spreadsheet)->getDebugLog()->getWriteDebugLog();
119
        \PhpSpreadsheet\Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog(false);
120
        $saveDateReturnType = \PhpSpreadsheet\Calculation\Functions::getReturnDateType();
121
        \PhpSpreadsheet\Calculation\Functions::setReturnDateType(\PhpSpreadsheet\Calculation\Functions::RETURNDATE_EXCEL);
122
123
        // initialize colors array
124
        $this->colors = array();
125
126
        // Initialise workbook writer
127
        $this->writerWorkbook = new Excel5\Workbook($this->spreadsheet, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser);
0 ignored issues
show
Bug introduced by
The property writerWorkbook does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
128
129
        // Initialise worksheet writers
130
        $countSheets = $this->spreadsheet->getSheetCount();
131
        for ($i = 0; $i < $countSheets; ++$i) {
132
            $this->writerWorksheets[$i] = new Excel5\Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->spreadsheet->getSheet($i));
0 ignored issues
show
Bug introduced by
The property writerWorksheets does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Documentation introduced by
$this->spreadsheet->getSheet($i) is of type object<PhpSpreadsheet\Worksheet>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
133
        }
134
135
        // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook.
136
        $this->buildWorksheetEschers();
137
        $this->buildWorkbookEscher();
138
139
        // add 15 identical cell style Xfs
140
        // for now, we use the first cellXf instead of cellStyleXf
141
        $cellXfCollection = $this->spreadsheet->getCellXfCollection();
142
        for ($i = 0; $i < 15; ++$i) {
143
            $this->writerWorkbook->addXfWriter($cellXfCollection[0], true);
144
        }
145
146
        // add all the cell Xfs
147
        foreach ($this->spreadsheet->getCellXfCollection() as $style) {
148
            $this->writerWorkbook->addXfWriter($style, false);
149
        }
150
151
        // add fonts from rich text eleemnts
152
        for ($i = 0; $i < $countSheets; ++$i) {
153
            foreach ($this->writerWorksheets[$i]->phpSheet->getCellCollection() as $cellID) {
154
                $cell = $this->writerWorksheets[$i]->phpSheet->getCell($cellID);
155
                $cVal = $cell->getValue();
156
                if ($cVal instanceof \PhpSpreadsheet\RichText) {
157
                    $elements = $cVal->getRichTextElements();
158
                    foreach ($elements as $element) {
159
                        if ($element instanceof \PhpSpreadsheet\RichText\Run) {
160
                            $font = $element->getFont();
161
                            $this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font);
162
                        }
163
                    }
164
                }
165
            }
166
        }
167
168
        // initialize OLE file
169
        $workbookStreamName = 'Workbook';
170
        $OLE = new \PhpSpreadsheet\Shared\OLE\PPS\File(\PhpSpreadsheet\Shared\OLE::ascToUcs($workbookStreamName));
171
172
        // Write the worksheet streams before the global workbook stream,
173
        // because the byte sizes of these are needed in the global workbook stream
174
        $worksheetSizes = array();
175
        for ($i = 0; $i < $countSheets; ++$i) {
176
            $this->writerWorksheets[$i]->close();
177
            $worksheetSizes[] = $this->writerWorksheets[$i]->_datasize;
178
        }
179
180
        // add binary data for global workbook stream
181
        $OLE->append($this->writerWorkbook->writeWorkbook($worksheetSizes));
182
183
        // add binary data for sheet streams
184
        for ($i = 0; $i < $countSheets; ++$i) {
185
            $OLE->append($this->writerWorksheets[$i]->getData());
186
        }
187
188
        $this->documentSummaryInformation = $this->writeDocumentSummaryInformation();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->writeDocumentSummaryInformation() of type string is incompatible with the declared type array of property $documentSummaryInformation.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
189
        // initialize OLE Document Summary Information
190 View Code Duplication
        if (isset($this->documentSummaryInformation) && !empty($this->documentSummaryInformation)) {
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...
191
            $OLE_DocumentSummaryInformation = new \PhpSpreadsheet\Shared\OLE\PPS\File(\PhpSpreadsheet\Shared\OLE::ascToUcs(chr(5) . 'DocumentSummaryInformation'));
192
            $OLE_DocumentSummaryInformation->append($this->documentSummaryInformation);
193
        }
194
195
        $this->summaryInformation = $this->writeSummaryInformation();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->writeSummaryInformation() of type string is incompatible with the declared type array of property $summaryInformation.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
196
        // initialize OLE Summary Information
197 View Code Duplication
        if (isset($this->summaryInformation) && !empty($this->summaryInformation)) {
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...
198
            $OLE_SummaryInformation = new \PhpSpreadsheet\Shared\OLE\PPS\File(\PhpSpreadsheet\Shared\OLE::ascToUcs(chr(5) . 'SummaryInformation'));
199
            $OLE_SummaryInformation->append($this->summaryInformation);
200
        }
201
202
        // define OLE Parts
203
        $arrRootData = array($OLE);
204
        // initialize OLE Properties file
205
        if (isset($OLE_SummaryInformation)) {
206
            $arrRootData[] = $OLE_SummaryInformation;
207
        }
208
        // initialize OLE Extended Properties file
209
        if (isset($OLE_DocumentSummaryInformation)) {
210
            $arrRootData[] = $OLE_DocumentSummaryInformation;
211
        }
212
213
        $root = new \PhpSpreadsheet\Shared\OLE\PPS\Root(time(), time(), $arrRootData);
214
        // save the OLE file
215
        $res = $root->save($pFilename);
0 ignored issues
show
Unused Code introduced by
$res is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
216
217
        \PhpSpreadsheet\Calculation\Functions::setReturnDateType($saveDateReturnType);
218
        \PhpSpreadsheet\Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
219
    }
220
221
    /**
222
     * Set temporary storage directory
223
     *
224
     * @deprecated
225
     * @param    string    $pValue        Temporary storage directory
226
     * @throws    \PhpSpreadsheet\Writer\Exception    when directory does not exist
227
     * @return \PhpSpreadsheet\Writer\Excel5
228
     */
229
    public function setTempDir($pValue = '')
0 ignored issues
show
Unused Code introduced by
The parameter $pValue is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
230
    {
231
        return $this;
232
    }
233
234
    /**
235
     * Build the Worksheet Escher objects
236
     *
237
     */
238
    private function buildWorksheetEschers()
239
    {
240
        // 1-based index to BstoreContainer
241
        $blipIndex = 0;
242
        $lastReducedSpId = 0;
243
        $lastSpId = 0;
244
245
        foreach ($this->spreadsheet->getAllsheets() as $sheet) {
246
            // sheet index
247
            $sheetIndex = $sheet->getParent()->getIndex($sheet);
248
249
            $escher = null;
0 ignored issues
show
Unused Code introduced by
$escher is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
250
251
            // check if there are any shapes for this sheet
252
            $filterRange = $sheet->getAutoFilter()->getRange();
253
            if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) {
254
                continue;
255
            }
256
257
            // create intermediate Escher object
258
            $escher = new \PhpSpreadsheet\Shared\Escher();
259
260
            // dgContainer
261
            $dgContainer = new \PhpSpreadsheet\Shared\Escher\DgContainer();
262
263
            // set the drawing index (we use sheet index + 1)
264
            $dgId = $sheet->getParent()->getIndex($sheet) + 1;
265
            $dgContainer->setDgId($dgId);
266
            $escher->setDgContainer($dgContainer);
267
268
            // spgrContainer
269
            $spgrContainer = new \PhpSpreadsheet\Shared\Escher\DgContainer\SpgrContainer();
270
            $dgContainer->setSpgrContainer($spgrContainer);
271
272
            // add one shape which is the group shape
273
            $spContainer = new \PhpSpreadsheet\Shared\Escher\DgContainer\SpgrContainer\SpContainer();
274
            $spContainer->setSpgr(true);
275
            $spContainer->setSpType(0);
276
            $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10);
277
            $spgrContainer->addChild($spContainer);
278
279
            // add the shapes
280
281
            $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet
0 ignored issues
show
Coding Style Comprehensibility introduced by
$countShapes was never initialized. Although not strictly required by PHP, it is generally a good practice to add $countShapes = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
282
283
            foreach ($sheet->getDrawingCollection() as $drawing) {
284
                ++$blipIndex;
285
286
                ++$countShapes[$sheetIndex];
0 ignored issues
show
Bug introduced by
The variable $countShapes does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
287
288
                // add the shape
289
                $spContainer = new \PhpSpreadsheet\Shared\Escher\DgContainer\SpgrContainer\SpContainer();
290
291
                // set the shape type
292
                $spContainer->setSpType(0x004B);
293
                // set the shape flag
294
                $spContainer->setSpFlag(0x02);
295
296
                // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
297
                $reducedSpId = $countShapes[$sheetIndex];
298
                $spId = $reducedSpId
299
                    | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
300
                $spContainer->setSpId($spId);
301
302
                // keep track of last reducedSpId
303
                $lastReducedSpId = $reducedSpId;
304
305
                // keep track of last spId
306
                $lastSpId = $spId;
307
308
                // set the BLIP index
309
                $spContainer->setOPT(0x4104, $blipIndex);
310
311
                // set coordinates and offsets, client anchor
312
                $coordinates = $drawing->getCoordinates();
313
                $offsetX = $drawing->getOffsetX();
314
                $offsetY = $drawing->getOffsetY();
315
                $width = $drawing->getWidth();
316
                $height = $drawing->getHeight();
317
318
                $twoAnchor = \PhpSpreadsheet\Shared\Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height);
319
320
                $spContainer->setStartCoordinates($twoAnchor['startCoordinates']);
321
                $spContainer->setStartOffsetX($twoAnchor['startOffsetX']);
322
                $spContainer->setStartOffsetY($twoAnchor['startOffsetY']);
323
                $spContainer->setEndCoordinates($twoAnchor['endCoordinates']);
324
                $spContainer->setEndOffsetX($twoAnchor['endOffsetX']);
325
                $spContainer->setEndOffsetY($twoAnchor['endOffsetY']);
326
327
                $spgrContainer->addChild($spContainer);
328
            }
329
330
            // AutoFilters
331
            if (!empty($filterRange)) {
332
                $rangeBounds = \PhpSpreadsheet\Cell::rangeBoundaries($filterRange);
333
                $iNumColStart = $rangeBounds[0][0];
334
                $iNumColEnd = $rangeBounds[1][0];
335
336
                $iInc = $iNumColStart;
337
                while ($iInc <= $iNumColEnd) {
338
                    ++$countShapes[$sheetIndex];
339
340
                    // create an Drawing Object for the dropdown
341
                    $oDrawing  = new \PhpSpreadsheet\Worksheet\BaseDrawing();
342
                    // get the coordinates of drawing
343
                    $cDrawing   = \PhpSpreadsheet\Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1];
344
                    $oDrawing->setCoordinates($cDrawing);
345
                    $oDrawing->setWorksheet($sheet);
346
347
                    // add the shape
348
                    $spContainer = new \PhpSpreadsheet\Shared\Escher\DgContainer\SpgrContainer\SpContainer();
349
                    // set the shape type
350
                    $spContainer->setSpType(0x00C9);
351
                    // set the shape flag
352
                    $spContainer->setSpFlag(0x01);
353
354
                    // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
355
                    $reducedSpId = $countShapes[$sheetIndex];
356
                    $spId = $reducedSpId
357
                        | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
358
                    $spContainer->setSpId($spId);
359
360
                    // keep track of last reducedSpId
361
                    $lastReducedSpId = $reducedSpId;
362
363
                    // keep track of last spId
364
                    $lastSpId = $spId;
365
366
                    $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping
367
                    $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape
368
                    $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest
369
                    $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash
370
                    $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint
371
372
                    // set coordinates and offsets, client anchor
373
                    $endCoordinates = \PhpSpreadsheet\Cell::stringFromColumnIndex($iInc - 1);
374
                    $endCoordinates .= $rangeBounds[0][1] + 1;
375
376
                    $spContainer->setStartCoordinates($cDrawing);
377
                    $spContainer->setStartOffsetX(0);
378
                    $spContainer->setStartOffsetY(0);
379
                    $spContainer->setEndCoordinates($endCoordinates);
380
                    $spContainer->setEndOffsetX(0);
381
                    $spContainer->setEndOffsetY(0);
382
383
                    $spgrContainer->addChild($spContainer);
384
                    $iInc++;
385
                }
386
            }
387
388
            // identifier clusters, used for workbook Escher object
389
            $this->IDCLs[$dgId] = $lastReducedSpId;
390
391
            // set last shape index
392
            $dgContainer->setLastSpId($lastSpId);
393
394
            // set the Escher object
395
            $this->writerWorksheets[$sheetIndex]->setEscher($escher);
396
        }
397
    }
398
399
    /**
400
     * Build the Escher object corresponding to the MSODRAWINGGROUP record
401
     */
402
    private function buildWorkbookEscher()
403
    {
404
        $escher = null;
0 ignored issues
show
Unused Code introduced by
$escher is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
405
406
        // any drawings in this workbook?
407
        $found = false;
408
        foreach ($this->spreadsheet->getAllSheets() as $sheet) {
409
            if (count($sheet->getDrawingCollection()) > 0) {
410
                $found = true;
411
                break;
412
            }
413
        }
414
415
        // nothing to do if there are no drawings
416
        if (!$found) {
417
            return;
418
        }
419
420
        // if we reach here, then there are drawings in the workbook
421
        $escher = new \PhpSpreadsheet\Shared\Escher();
422
423
        // dggContainer
424
        $dggContainer = new \PhpSpreadsheet\Shared\Escher\DggContainer();
425
        $escher->setDggContainer($dggContainer);
426
427
        // set IDCLs (identifier clusters)
428
        $dggContainer->setIDCLs($this->IDCLs);
429
430
        // this loop is for determining maximum shape identifier of all drawing
431
        $spIdMax = 0;
432
        $totalCountShapes = 0;
433
        $countDrawings = 0;
434
435
        foreach ($this->spreadsheet->getAllsheets() as $sheet) {
436
            $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet
437
438
            if (count($sheet->getDrawingCollection()) > 0) {
439
                ++$countDrawings;
440
441
                foreach ($sheet->getDrawingCollection() as $drawing) {
442
                    ++$sheetCountShapes;
443
                    ++$totalCountShapes;
444
445
                    $spId = $sheetCountShapes | ($this->spreadsheet->getIndex($sheet) + 1) << 10;
446
                    $spIdMax = max($spId, $spIdMax);
447
                }
448
            }
449
        }
450
451
        $dggContainer->setSpIdMax($spIdMax + 1);
452
        $dggContainer->setCDgSaved($countDrawings);
453
        $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing
454
455
        // bstoreContainer
456
        $bstoreContainer = new \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer();
457
        $dggContainer->setBstoreContainer($bstoreContainer);
458
459
        // the BSE's (all the images)
460
        foreach ($this->spreadsheet->getAllsheets() as $sheet) {
461
            foreach ($sheet->getDrawingCollection() as $drawing) {
462
                if ($drawing instanceof \PhpSpreadsheet\Worksheet\Drawing) {
463
                    $filename = $drawing->getPath();
464
465
                    list($imagesx, $imagesy, $imageFormat) = getimagesize($filename);
0 ignored issues
show
Unused Code introduced by
The assignment to $imagesx is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $imagesy is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
466
467
                    switch ($imageFormat) {
468
                        case 1: // GIF, not supported by BIFF8, we convert to PNG
469
                            $blipType = \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_PNG;
470
                            ob_start();
471
                            imagepng(imagecreatefromgif($filename));
472
                            $blipData = ob_get_contents();
473
                            ob_end_clean();
474
                            break;
475
                        case 2: // JPEG
476
                            $blipType = \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_JPEG;
477
                            $blipData = file_get_contents($filename);
478
                            break;
479
                        case 3: // PNG
480
                            $blipType = \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_PNG;
481
                            $blipData = file_get_contents($filename);
482
                            break;
483
                        case 6: // Windows DIB (BMP), we convert to PNG
484
                            $blipType = \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_PNG;
485
                            ob_start();
486
                            imagepng(\PhpSpreadsheet\Shared\Drawing::imagecreatefrombmp($filename));
487
                            $blipData = ob_get_contents();
488
                            ob_end_clean();
489
                            break;
490
                        default:
491
                            continue 2;
492
                    }
493
494
                    $blip = new \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE\Blip();
495
                    $blip->setData($blipData);
496
497
                    $BSE = new \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE();
498
                    $BSE->setBlipType($blipType);
499
                    $BSE->setBlip($blip);
500
501
                    $bstoreContainer->addBSE($BSE);
502
                } elseif ($drawing instanceof \PhpSpreadsheet\Worksheet\MemoryDrawing) {
503
                    switch ($drawing->getRenderingFunction()) {
504
                        case \PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_JPEG:
505
                            $blipType = \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_JPEG;
506
                            $renderingFunction = 'imagejpeg';
507
                            break;
508
                        case \PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_GIF:
509
                        case \PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_PNG:
510
                        case \PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_DEFAULT:
511
                            $blipType = \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_PNG;
512
                            $renderingFunction = 'imagepng';
513
                            break;
514
                    }
515
516
                    ob_start();
517
                    call_user_func($renderingFunction, $drawing->getImageResource());
0 ignored issues
show
Bug introduced by
The variable $renderingFunction does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
518
                    $blipData = ob_get_contents();
519
                    ob_end_clean();
520
521
                    $blip = new \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE\Blip();
522
                    $blip->setData($blipData);
523
524
                    $BSE = new \PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE();
525
                    $BSE->setBlipType($blipType);
0 ignored issues
show
Bug introduced by
The variable $blipType does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
526
                    $BSE->setBlip($blip);
527
528
                    $bstoreContainer->addBSE($BSE);
529
                }
530
            }
531
        }
532
533
        // Set the Escher object
534
        $this->writerWorkbook->setEscher($escher);
535
    }
536
537
    /**
538
     * Build the OLE Part for DocumentSummary Information
539
     * @return string
540
     */
541
    private function writeDocumentSummaryInformation()
542
    {
543
        // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
544
        $data = pack('v', 0xFFFE);
545
        // offset: 2; size: 2;
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% 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...
546
        $data .= pack('v', 0x0000);
547
        // offset: 4; size: 2; OS version
548
        $data .= pack('v', 0x0106);
549
        // offset: 6; size: 2; OS indicator
550
        $data .= pack('v', 0x0002);
551
        // offset: 8; size: 16
552
        $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
553
        // offset: 24; size: 4; section count
554
        $data .= pack('V', 0x0001);
555
556
        // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae
557
        $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9);
558
        // offset: 44; size: 4; offset of the start
559
        $data .= pack('V', 0x30);
560
561
        // SECTION
562
        $dataSection = array();
563
        $dataSection_NumProps = 0;
564
        $dataSection_Summary = '';
565
        $dataSection_Content = '';
566
567
        // GKPIDDSI_CODEPAGE: CodePage
568
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01),
569
                               'offset' => array('pack' => 'V'),
570
                               'type'     => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer
571
                               'data'    => array('data' => 1252));
572
        $dataSection_NumProps++;
573
574
        // GKPIDDSI_CATEGORY : Category
575 View Code Duplication
        if ($this->spreadsheet->getProperties()->getCategory()) {
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...
576
            $dataProp = $this->spreadsheet->getProperties()->getCategory();
577
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02),
578
                                   'offset' => array('pack' => 'V'),
579
                                   'type'     => array('pack' => 'V', 'data' => 0x1E),
580
                                   'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
581
            $dataSection_NumProps++;
582
        }
583
        // GKPIDDSI_VERSION :Version of the application that wrote the property storage
584
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17),
585
                               'offset' => array('pack' => 'V'),
586
                               'type'     => array('pack' => 'V', 'data' => 0x03),
587
                               'data'    => array('pack' => 'V', 'data' => 0x000C0000));
588
        $dataSection_NumProps++;
589
        // GKPIDDSI_SCALE : FALSE
590
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B),
591
                               'offset' => array('pack' => 'V'),
592
                               'type'     => array('pack' => 'V', 'data' => 0x0B),
593
                               'data'    => array('data' => false));
594
        $dataSection_NumProps++;
595
        // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application
596
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10),
597
                               'offset' => array('pack' => 'V'),
598
                               'type'     => array('pack' => 'V', 'data' => 0x0B),
599
                               'data'    => array('data' => false));
600
        $dataSection_NumProps++;
601
        // GKPIDDSI_SHAREDOC : FALSE
602
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13),
603
                               'offset' => array('pack' => 'V'),
604
                               'type'     => array('pack' => 'V', 'data' => 0x0B),
605
                               'data'    => array('data' => false));
606
        $dataSection_NumProps++;
607
        // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application
608
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16),
609
                               'offset' => array('pack' => 'V'),
610
                               'type'     => array('pack' => 'V', 'data' => 0x0B),
611
                               'data'    => array('data' => false));
612
        $dataSection_NumProps++;
613
614
        // GKPIDDSI_DOCSPARTS
615
        // MS-OSHARED p75 (2.3.3.2.2.1)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
616
        // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9)
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
617
        // cElements
618
        $dataProp = pack('v', 0x0001);
619
        $dataProp .= pack('v', 0x0000);
620
        // array of UnalignedLpstr
621
          // cch
622
          $dataProp .= pack('v', 0x000A);
623
          $dataProp .= pack('v', 0x0000);
624
          // value
625
          $dataProp .= 'Worksheet'.chr(0);
626
627
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D),
628
                               'offset' => array('pack' => 'V'),
629
                               'type'     => array('pack' => 'V', 'data' => 0x101E),
630
                               'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
631
        $dataSection_NumProps++;
632
633
        // GKPIDDSI_HEADINGPAIR
634
        // VtVecHeadingPairValue
635
          // cElements
636
          $dataProp = pack('v', 0x0002);
637
          $dataProp .= pack('v', 0x0000);
638
          // Array of vtHeadingPair
639
            // vtUnalignedString - headingString
640
              // stringType
641
              $dataProp .= pack('v', 0x001E);
642
              // padding
643
              $dataProp .= pack('v', 0x0000);
644
              // UnalignedLpstr
645
                // cch
646
                $dataProp .= pack('v', 0x0013);
647
                $dataProp .= pack('v', 0x0000);
648
                // value
649
                $dataProp .= 'Feuilles de calcul';
650
            // vtUnalignedString - headingParts
651
              // wType : 0x0003 = 32 bit signed integer
652
              $dataProp .= pack('v', 0x0300);
653
              // padding
654
              $dataProp .= pack('v', 0x0000);
655
              // value
656
              $dataProp .= pack('v', 0x0100);
657
              $dataProp .= pack('v', 0x0000);
658
              $dataProp .= pack('v', 0x0000);
659
              $dataProp .= pack('v', 0x0000);
660
661
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C),
662
                               'offset' => array('pack' => 'V'),
663
                               'type'     => array('pack' => 'V', 'data' => 0x100C),
664
                               'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
665
        $dataSection_NumProps++;
666
667
        //         4     Section Length
668
        //        4     Property count
669
        //        8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% 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...
670
        $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
671
        foreach ($dataSection as $dataProp) {
672
            // Summary
673
            $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
674
            // Offset
675
            $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
676
            // DataType
677
            $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
678
            // Data
679
            if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
680
                $dataSection_Content .= pack('V', $dataProp['data']['data']);
681
682
                $dataSection_Content_Offset += 4 + 4;
683
            } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
684
                $dataSection_Content .= pack('V', $dataProp['data']['data']);
685
686
                $dataSection_Content_Offset += 4 + 4;
687
            } elseif ($dataProp['type']['data'] == 0x0B) { // Boolean
688
                if ($dataProp['data']['data'] == false) {
689
                    $dataSection_Content .= pack('V', 0x0000);
690
                } else {
691
                    $dataSection_Content .= pack('V', 0x0001);
692
                }
693
                $dataSection_Content_Offset += 4 + 4;
694 View Code Duplication
            } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
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...
695
                // Null-terminated string
696
                $dataProp['data']['data'] .= chr(0);
697
                $dataProp['data']['length'] += 1;
698
                // Complete the string with null string for being a %4
699
                $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4));
700
                $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
701
702
                $dataSection_Content .= pack('V', $dataProp['data']['length']);
703
                $dataSection_Content .= $dataProp['data']['data'];
704
705
                $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
706
            } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
707
                $dataSection_Content .= $dataProp['data']['data'];
708
709
                $dataSection_Content_Offset += 4 + 8;
710
            } else {
711
                // Data Type Not Used at the moment
712
                $dataSection_Content .= $dataProp['data']['data'];
713
714
                $dataSection_Content_Offset += 4 + $dataProp['data']['length'];
715
            }
716
        }
717
        // Now $dataSection_Content_Offset contains the size of the content
718
719
        // section header
720
        // offset: $secOffset; size: 4; section length
721
        //         + x  Size of the content (summary + content)
722
        $data .= pack('V', $dataSection_Content_Offset);
723
        // offset: $secOffset+4; size: 4; property count
724
        $data .= pack('V', $dataSection_NumProps);
725
        // Section Summary
726
        $data .= $dataSection_Summary;
727
        // Section Content
728
        $data .= $dataSection_Content;
729
730
        return $data;
731
    }
732
733
    /**
734
     * Build the OLE Part for Summary Information
735
     * @return string
736
     */
737
    private function writeSummaryInformation()
738
    {
739
        // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
740
        $data = pack('v', 0xFFFE);
741
        // offset: 2; size: 2;
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% 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...
742
        $data .= pack('v', 0x0000);
743
        // offset: 4; size: 2; OS version
744
        $data .= pack('v', 0x0106);
745
        // offset: 6; size: 2; OS indicator
746
        $data .= pack('v', 0x0002);
747
        // offset: 8; size: 16
748
        $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
749
        // offset: 24; size: 4; section count
750
        $data .= pack('V', 0x0001);
751
752
        // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9
753
        $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3);
754
        // offset: 44; size: 4; offset of the start
755
        $data .= pack('V', 0x30);
756
757
        // SECTION
758
        $dataSection = array();
759
        $dataSection_NumProps = 0;
760
        $dataSection_Summary = '';
761
        $dataSection_Content = '';
762
763
        // CodePage : CP-1252
764
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01),
765
                               'offset' => array('pack' => 'V'),
766
                               'type'     => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer
767
                               'data'    => array('data' => 1252));
768
        $dataSection_NumProps++;
769
770
        //    Title
771 View Code Duplication
        if ($this->spreadsheet->getProperties()->getTitle()) {
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...
772
            $dataProp = $this->spreadsheet->getProperties()->getTitle();
773
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02),
774
                                   'offset' => array('pack' => 'V'),
775
                                   'type'     => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
776
                                   'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
777
            $dataSection_NumProps++;
778
        }
779
        //    Subject
780 View Code Duplication
        if ($this->spreadsheet->getProperties()->getSubject()) {
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...
781
            $dataProp = $this->spreadsheet->getProperties()->getSubject();
782
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03),
783
                                   'offset' => array('pack' => 'V'),
784
                                   'type'     => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
785
                                   'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
786
            $dataSection_NumProps++;
787
        }
788
        //    Author (Creator)
789 View Code Duplication
        if ($this->spreadsheet->getProperties()->getCreator()) {
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...
790
            $dataProp = $this->spreadsheet->getProperties()->getCreator();
791
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04),
792
                                   'offset' => array('pack' => 'V'),
793
                                   'type'     => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
794
                                   'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
795
            $dataSection_NumProps++;
796
        }
797
        //    Keywords
798 View Code Duplication
        if ($this->spreadsheet->getProperties()->getKeywords()) {
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...
799
            $dataProp = $this->spreadsheet->getProperties()->getKeywords();
800
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05),
801
                                   'offset' => array('pack' => 'V'),
802
                                   'type'     => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
803
                                   'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
804
            $dataSection_NumProps++;
805
        }
806
        //    Comments (Description)
807 View Code Duplication
        if ($this->spreadsheet->getProperties()->getDescription()) {
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...
808
            $dataProp = $this->spreadsheet->getProperties()->getDescription();
809
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06),
810
                                   'offset' => array('pack' => 'V'),
811
                                   'type'     => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
812
                                   'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
813
            $dataSection_NumProps++;
814
        }
815
        //    Last Saved By (LastModifiedBy)
816 View Code Duplication
        if ($this->spreadsheet->getProperties()->getLastModifiedBy()) {
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...
817
            $dataProp = $this->spreadsheet->getProperties()->getLastModifiedBy();
818
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08),
819
                                   'offset' => array('pack' => 'V'),
820
                                   'type'     => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length
821
                                   'data'    => array('data' => $dataProp, 'length' => strlen($dataProp)));
822
            $dataSection_NumProps++;
823
        }
824
        //    Created Date/Time
825 View Code Duplication
        if ($this->spreadsheet->getProperties()->getCreated()) {
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...
826
            $dataProp = $this->spreadsheet->getProperties()->getCreated();
827
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C),
828
                                   'offset' => array('pack' => 'V'),
829
                                   'type'     => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
830
                                   'data'    => array('data' => \PhpSpreadsheet\Shared\OLE::localDateToOLE($dataProp)));
831
            $dataSection_NumProps++;
832
        }
833
        //    Modified Date/Time
834 View Code Duplication
        if ($this->spreadsheet->getProperties()->getModified()) {
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...
835
            $dataProp = $this->spreadsheet->getProperties()->getModified();
836
            $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D),
837
                                   'offset' => array('pack' => 'V'),
838
                                   'type'     => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
839
                                   'data'    => array('data' => \PhpSpreadsheet\Shared\OLE::localDateToOLE($dataProp)));
840
            $dataSection_NumProps++;
841
        }
842
        //    Security
843
        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13),
844
                               'offset' => array('pack' => 'V'),
845
                               'type'     => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer
846
                               'data'    => array('data' => 0x00));
847
        $dataSection_NumProps++;
848
849
850
        //         4     Section Length
851
        //        4     Property count
852
        //        8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% 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...
853
        $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
854
        foreach ($dataSection as $dataProp) {
855
            // Summary
856
            $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
857
            // Offset
858
            $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
859
            // DataType
860
            $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
861
            // Data
862
            if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
863
                $dataSection_Content .= pack('V', $dataProp['data']['data']);
864
865
                $dataSection_Content_Offset += 4 + 4;
866
            } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
867
                $dataSection_Content .= pack('V', $dataProp['data']['data']);
868
869
                $dataSection_Content_Offset += 4 + 4;
870 View Code Duplication
            } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
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...
871
                // Null-terminated string
872
                $dataProp['data']['data'] .= chr(0);
873
                $dataProp['data']['length'] += 1;
874
                // Complete the string with null string for being a %4
875
                $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4));
876
                $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
877
878
                $dataSection_Content .= pack('V', $dataProp['data']['length']);
879
                $dataSection_Content .= $dataProp['data']['data'];
880
881
                $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
882
            } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
883
                $dataSection_Content .= $dataProp['data']['data'];
884
885
                $dataSection_Content_Offset += 4 + 8;
886
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
887
                // Data Type Not Used at the moment
888
            }
889
        }
890
        // Now $dataSection_Content_Offset contains the size of the content
891
892
        // section header
893
        // offset: $secOffset; size: 4; section length
894
        //         + x  Size of the content (summary + content)
895
        $data .= pack('V', $dataSection_Content_Offset);
896
        // offset: $secOffset+4; size: 4; property count
897
        $data .= pack('V', $dataSection_NumProps);
898
        // Section Summary
899
        $data .= $dataSection_Summary;
900
        // Section Content
901
        $data .= $dataSection_Content;
902
903
        return $data;
904
    }
905
}
906