Completed
Push — develop ( 39b55d...e2e982 )
by Adrien
19:14
created

Escher   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 487
Duplicated Lines 10.68 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 7.36%

Importance

Changes 0
Metric Value
dl 52
loc 487
ccs 19
cts 258
cp 0.0736
rs 10
c 0
b 0
f 0
wmc 30
lcom 1
cbo 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
D close() 52 426 27
A getSpOffsets() 0 4 1
A getSpTypes() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xls;
4
5
/**
6
 * Copyright (c) 2006 - 2015 PhpSpreadsheet
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 *
22
 * @category   PhpSpreadsheet
23
 * @copyright  Copyright (c) 2006 - 2015 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
24
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
25
 * @version    ##VERSION##, ##DATE##
26
 */
27
class Escher
28
{
29
    /**
30
     * The object we are writing
31
     */
32
    private $object;
33
34
    /**
35
     * The written binary data
36
     */
37
    private $data;
38
39
    /**
40
     * Shape offsets. Positions in binary stream where a new shape record begins
41
     *
42
     * @var array
43
     */
44
    private $spOffsets;
45
46
    /**
47
     * Shape types.
48
     *
49
     * @var array
50
     */
51
    private $spTypes;
52
53
    /**
54
     * Constructor
55
     *
56
     * @param mixed
57
     */
58 10
    public function __construct($object)
59
    {
60 10
        $this->object = $object;
61 10
    }
62
63
    /**
64
     * Process the object to be written
65
     * @return string
66
     */
67 10
    public function close()
68
    {
69
        // initialize
70 10
        $this->data = '';
71
72 10
        switch (get_class($this->object)) {
73 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher':
74
                if ($dggContainer = $this->object->getDggContainer()) {
75
                    $writer = new self($dggContainer);
76
                    $this->data = $writer->close();
77
                } elseif ($dgContainer = $this->object->getDgContainer()) {
78
                    $writer = new self($dgContainer);
79
                    $this->data = $writer->close();
80
                    $this->spOffsets = $writer->getSpOffsets();
81
                    $this->spTypes = $writer->getSpTypes();
82
                }
83
                break;
84 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher\\DggContainer':
85
                // this is a container record
86
87
                // initialize
88
                $innerData = '';
89
90
                // write the dgg
91
                $recVer = 0x0;
92
                $recInstance = 0x0000;
93
                $recType = 0xF006;
94
95
                $recVerInstance = $recVer;
96
                $recVerInstance |= $recInstance << 4;
97
98
                // dgg data
99
                $dggData =
100
                    pack(
101
                        'VVVV',
102
                        $this->object->getSpIdMax(), // maximum shape identifier increased by one
103
                        $this->object->getCDgSaved() + 1, // number of file identifier clusters increased by one
104
                        $this->object->getCSpSaved(),
105
                        $this->object->getCDgSaved() // count total number of drawings saved
106
                    );
107
108
                // add file identifier clusters (one per drawing)
109
                $IDCLs = $this->object->getIDCLs();
110
111
                foreach ($IDCLs as $dgId => $maxReducedSpId) {
112
                    $dggData .= pack('VV', $dgId, $maxReducedSpId + 1);
113
                }
114
115
                $header = pack('vvV', $recVerInstance, $recType, strlen($dggData));
116
                $innerData .= $header . $dggData;
117
118
                // write the bstoreContainer
119
                if ($bstoreContainer = $this->object->getBstoreContainer()) {
120
                    $writer = new self($bstoreContainer);
121
                    $innerData .= $writer->close();
122
                }
123
124
                // write the record
125
                $recVer = 0xF;
126
                $recInstance = 0x0000;
127
                $recType = 0xF000;
128
                $length = strlen($innerData);
129
130
                $recVerInstance = $recVer;
131
                $recVerInstance |= $recInstance << 4;
132
133
                $header = pack('vvV', $recVerInstance, $recType, $length);
134
135
                $this->data = $header . $innerData;
136
                break;
137 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher\\DggContainer\\BstoreContainer':
138
                // this is a container record
139
140
                // initialize
141
                $innerData = '';
142
143
                // treat the inner data
144
                if ($BSECollection = $this->object->getBSECollection()) {
145
                    foreach ($BSECollection as $BSE) {
146
                        $writer = new self($BSE);
147
                        $innerData .= $writer->close();
148
                    }
149
                }
150
151
                // write the record
152
                $recVer = 0xF;
153
                $recInstance = count($this->object->getBSECollection());
154
                $recType = 0xF001;
155
                $length = strlen($innerData);
156
157
                $recVerInstance = $recVer;
158
                $recVerInstance |= $recInstance << 4;
159
160
                $header = pack('vvV', $recVerInstance, $recType, $length);
161
162
                $this->data = $header . $innerData;
163
                break;
164 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher\\DggContainer\\BstoreContainer\\BSE':
165
                // this is a semi-container record
166
167
                // initialize
168
                $innerData = '';
169
170
                // here we treat the inner data
171
                if ($blip = $this->object->getBlip()) {
172
                    $writer = new self($blip);
173
                    $innerData .= $writer->close();
174
                }
175
176
                // initialize
177
                $data = '';
178
179
                $btWin32 = $this->object->getBlipType();
180
                $btMacOS = $this->object->getBlipType();
181
                $data .= pack('CC', $btWin32, $btMacOS);
182
183
                $rgbUid = pack('VVVV', 0, 0, 0, 0); // todo
184
                $data .= $rgbUid;
185
186
                $tag = 0;
187
                $size = strlen($innerData);
188
                $cRef = 1;
189
                $foDelay = 0; //todo
190
                $unused1 = 0x0;
191
                $cbName = 0x0;
192
                $unused2 = 0x0;
193
                $unused3 = 0x0;
194
                $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3);
195
196
                $data .= $innerData;
197
198
                // write the record
199
                $recVer = 0x2;
200
                $recInstance = $this->object->getBlipType();
201
                $recType = 0xF007;
202
                $length = strlen($data);
203
204
                $recVerInstance = $recVer;
205
                $recVerInstance |= $recInstance << 4;
206
207
                $header = pack('vvV', $recVerInstance, $recType, $length);
208
209
                $this->data = $header;
210
211
                $this->data .= $data;
212
                break;
213 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher\\DggContainer\\BstoreContainer\\BSE\\Blip':
214
                // this is an atom record
215
216
                // write the record
217
                switch ($this->object->getParent()->getBlipType()) {
218 View Code Duplication
                    case \PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_JPEG:
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...
219
                        // initialize
220
                        $innerData = '';
221
222
                        $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo
223
                        $innerData .= $rgbUid1;
224
225
                        $tag = 0xFF; // todo
226
                        $innerData .= pack('C', $tag);
227
228
                        $innerData .= $this->object->getData();
229
230
                        $recVer = 0x0;
231
                        $recInstance = 0x46A;
232
                        $recType = 0xF01D;
233
                        $length = strlen($innerData);
234
235
                        $recVerInstance = $recVer;
236
                        $recVerInstance |= $recInstance << 4;
237
238
                        $header = pack('vvV', $recVerInstance, $recType, $length);
239
240
                        $this->data = $header;
241
242
                        $this->data .= $innerData;
243
                        break;
244
245 View Code Duplication
                    case \PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE::BLIPTYPE_PNG:
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...
246
                        // initialize
247
                        $innerData = '';
248
249
                        $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo
250
                        $innerData .= $rgbUid1;
251
252
                        $tag = 0xFF; // todo
253
                        $innerData .= pack('C', $tag);
254
255
                        $innerData .= $this->object->getData();
256
257
                        $recVer = 0x0;
258
                        $recInstance = 0x6E0;
259
                        $recType = 0xF01E;
260
                        $length = strlen($innerData);
261
262
                        $recVerInstance = $recVer;
263
                        $recVerInstance |= $recInstance << 4;
264
265
                        $header = pack('vvV', $recVerInstance, $recType, $length);
266
267
                        $this->data = $header;
268
269
                        $this->data .= $innerData;
270
                        break;
271
                }
272
                break;
273 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher\\DgContainer':
274
                // this is a container record
275
276
                // initialize
277
                $innerData = '';
278
279
                // write the dg
280
                $recVer = 0x0;
281
                $recInstance = $this->object->getDgId();
282
                $recType = 0xF008;
283
                $length = 8;
284
285
                $recVerInstance = $recVer;
286
                $recVerInstance |= $recInstance << 4;
287
288
                $header = pack('vvV', $recVerInstance, $recType, $length);
289
290
                // number of shapes in this drawing (including group shape)
291
                $countShapes = count($this->object->getSpgrContainer()->getChildren());
292
                $innerData .= $header . pack('VV', $countShapes, $this->object->getLastSpId());
293
294
                // write the spgrContainer
295
                if ($spgrContainer = $this->object->getSpgrContainer()) {
296
                    $writer = new self($spgrContainer);
297
                    $innerData .= $writer->close();
298
299
                    // get the shape offsets relative to the spgrContainer record
300
                    $spOffsets = $writer->getSpOffsets();
301
                    $spTypes = $writer->getSpTypes();
302
303
                    // save the shape offsets relative to dgContainer
304
                    foreach ($spOffsets as &$spOffset) {
305
                        $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes)
306
                    }
307
308
                    $this->spOffsets = $spOffsets;
309
                    $this->spTypes = $spTypes;
310
                }
311
312
                // write the record
313
                $recVer = 0xF;
314
                $recInstance = 0x0000;
315
                $recType = 0xF002;
316
                $length = strlen($innerData);
317
318
                $recVerInstance = $recVer;
319
                $recVerInstance |= $recInstance << 4;
320
321
                $header = pack('vvV', $recVerInstance, $recType, $length);
322
323
                $this->data = $header . $innerData;
324
                break;
325 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher\\DgContainer\\SpgrContainer':
326
                // this is a container record
327
328
                // initialize
329
                $innerData = '';
330
331
                // initialize spape offsets
332
                $totalSize = 8;
333
                $spOffsets = [];
334
                $spTypes = [];
335
336
                // treat the inner data
337
                foreach ($this->object->getChildren() as $spContainer) {
338
                    $writer = new self($spContainer);
339
                    $spData = $writer->close();
340
                    $innerData .= $spData;
341
342
                    // save the shape offsets (where new shape records begin)
343
                    $totalSize += strlen($spData);
344
                    $spOffsets[] = $totalSize;
345
346
                    $spTypes = array_merge($spTypes, $writer->getSpTypes());
347
                }
348
349
                // write the record
350
                $recVer = 0xF;
351
                $recInstance = 0x0000;
352
                $recType = 0xF003;
353
                $length = strlen($innerData);
354
355
                $recVerInstance = $recVer;
356
                $recVerInstance |= $recInstance << 4;
357
358
                $header = pack('vvV', $recVerInstance, $recType, $length);
359
360
                $this->data = $header . $innerData;
361
                $this->spOffsets = $spOffsets;
362
                $this->spTypes = $spTypes;
363
                break;
364 10
            case '\\PhpOffice\\PhpSpreadsheet\\Shared\\Escher\\DgContainer\\SpgrContainer\\SpContainer':
365
                // initialize
366
                $data = '';
367
368
                // build the data
369
370
                // write group shape record, if necessary?
371
                if ($this->object->getSpgr()) {
372
                    $recVer = 0x1;
373
                    $recInstance = 0x0000;
374
                    $recType = 0xF009;
375
                    $length = 0x00000010;
376
377
                    $recVerInstance = $recVer;
378
                    $recVerInstance |= $recInstance << 4;
379
380
                    $header = pack('vvV', $recVerInstance, $recType, $length);
381
382
                    $data .= $header . pack('VVVV', 0, 0, 0, 0);
383
                }
384
                $this->spTypes[] = ($this->object->getSpType());
385
386
                // write the shape record
387
                $recVer = 0x2;
388
                $recInstance = $this->object->getSpType(); // shape type
389
                $recType = 0xF00A;
390
                $length = 0x00000008;
391
392
                $recVerInstance = $recVer;
393
                $recVerInstance |= $recInstance << 4;
394
395
                $header = pack('vvV', $recVerInstance, $recType, $length);
396
397
                $data .= $header . pack('VV', $this->object->getSpId(), $this->object->getSpgr() ? 0x0005 : 0x0A00);
398
399
                // the options
400
                if ($this->object->getOPTCollection()) {
401
                    $optData = '';
402
403
                    $recVer = 0x3;
404
                    $recInstance = count($this->object->getOPTCollection());
405
                    $recType = 0xF00B;
406
                    foreach ($this->object->getOPTCollection() as $property => $value) {
407
                        $optData .= pack('vV', $property, $value);
408
                    }
409
                    $length = strlen($optData);
410
411
                    $recVerInstance = $recVer;
412
                    $recVerInstance |= $recInstance << 4;
413
414
                    $header = pack('vvV', $recVerInstance, $recType, $length);
415
                    $data .= $header . $optData;
416
                }
417
418
                // the client anchor
419
                if ($this->object->getStartCoordinates()) {
420
                    $clientAnchorData = '';
0 ignored issues
show
Unused Code introduced by
$clientAnchorData 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...
421
422
                    $recVer = 0x0;
423
                    $recInstance = 0x0;
424
                    $recType = 0xF010;
425
426
                    // start coordinates
427
                    list($column, $row) = \PhpOffice\PhpSpreadsheet\Cell::coordinateFromString($this->object->getStartCoordinates());
428
                    $c1 = \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString($column) - 1;
429
                    $r1 = $row - 1;
430
431
                    // start offsetX
432
                    $startOffsetX = $this->object->getStartOffsetX();
433
434
                    // start offsetY
435
                    $startOffsetY = $this->object->getStartOffsetY();
436
437
                    // end coordinates
438
                    list($column, $row) = \PhpOffice\PhpSpreadsheet\Cell::coordinateFromString($this->object->getEndCoordinates());
439
                    $c2 = \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString($column) - 1;
440
                    $r2 = $row - 1;
441
442
                    // end offsetX
443
                    $endOffsetX = $this->object->getEndOffsetX();
444
445
                    // end offsetY
446
                    $endOffsetY = $this->object->getEndOffsetY();
447
448
                    $clientAnchorData = pack('vvvvvvvvv', $this->object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY);
449
450
                    $length = strlen($clientAnchorData);
451
452
                    $recVerInstance = $recVer;
453
                    $recVerInstance |= $recInstance << 4;
454
455
                    $header = pack('vvV', $recVerInstance, $recType, $length);
456
                    $data .= $header . $clientAnchorData;
457
                }
458
459
                // the client data, just empty for now
460
                if (!$this->object->getSpgr()) {
461
                    $clientDataData = '';
462
463
                    $recVer = 0x0;
464
                    $recInstance = 0x0;
465
                    $recType = 0xF011;
466
467
                    $length = strlen($clientDataData);
468
469
                    $recVerInstance = $recVer;
470
                    $recVerInstance |= $recInstance << 4;
471
472
                    $header = pack('vvV', $recVerInstance, $recType, $length);
473
                    $data .= $header . $clientDataData;
474
                }
475
476
                // write the record
477
                $recVer = 0xF;
478
                $recInstance = 0x0000;
479
                $recType = 0xF004;
480
                $length = strlen($data);
481
482
                $recVerInstance = $recVer;
483
                $recVerInstance |= $recInstance << 4;
484
485
                $header = pack('vvV', $recVerInstance, $recType, $length);
486
487
                $this->data = $header . $data;
488
                break;
489
        }
490
491 10
        return $this->data;
492
    }
493
494
    /**
495
     * Gets the shape offsets
496
     *
497
     * @return array
498
     */
499 10
    public function getSpOffsets()
500
    {
501 10
        return $this->spOffsets;
502
    }
503
504
    /**
505
     * Gets the shape types
506
     *
507
     * @return array
508
     */
509 10
    public function getSpTypes()
510
    {
511 10
        return $this->spTypes;
512
    }
513
}
514