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

Rels::writeHeaderFooterDrawingRelationships()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 31
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3.0067

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 4
nop 1
dl 0
loc 31
rs 8.8571
c 0
b 0
f 0
ccs 10
cts 11
cp 0.9091
crap 3.0067
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
6
use PhpOffice\PhpSpreadsheet\Spreadsheet;
7
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
8
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
9
10
class Rels extends WriterPart
11
{
12
    /**
13
     * Write relationships to XML format.
14
     *
15
     * @param Spreadsheet $spreadsheet
16
     *
17
     * @throws WriterException
18
     *
19
     * @return string XML Output
20
     */
21 73
    public function writeRelationships(Spreadsheet $spreadsheet)
22
    {
23
        // Create XML writer
24 73
        $objWriter = null;
25 73
        if ($this->getParentWriter()->getUseDiskCaching()) {
26
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
27
        } else {
28 73
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
29
        }
30
31
        // XML header
32 73
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
33
34
        // Relationships
35 73
        $objWriter->startElement('Relationships');
36 73
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
37
38 73
        $customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
39 73
        if (!empty($customPropertyList)) {
40
            // Relationship docProps/app.xml
41 2
            $this->writeRelationship(
42 2
                $objWriter,
43 2
                4,
44 2
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',
45 2
                'docProps/custom.xml'
46
            );
47
        }
48
49
        // Relationship docProps/app.xml
50 73
        $this->writeRelationship(
51 73
            $objWriter,
52 73
            3,
53 73
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
54 73
            'docProps/app.xml'
55
        );
56
57
        // Relationship docProps/core.xml
58 73
        $this->writeRelationship(
59 73
            $objWriter,
60 73
            2,
61 73
            'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
62 73
            'docProps/core.xml'
63
        );
64
65
        // Relationship xl/workbook.xml
66 73
        $this->writeRelationship(
67 73
            $objWriter,
68 73
            1,
69 73
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
70 73
            'xl/workbook.xml'
71
        );
72
        // a custom UI in workbook ?
73 73
        if ($spreadsheet->hasRibbon()) {
74
            $this->writeRelationShip(
75
                $objWriter,
76
                5,
77
                'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility',
78
                $spreadsheet->getRibbonXMLData('target')
79
            );
80
        }
81
82 73
        $objWriter->endElement();
83
84 73
        return $objWriter->getData();
85
    }
86
87
    /**
88
     * Write workbook relationships to XML format.
89
     *
90
     * @param Spreadsheet $spreadsheet
91
     *
92
     * @throws WriterException
93
     *
94
     * @return string XML Output
95
     */
96 73
    public function writeWorkbookRelationships(Spreadsheet $spreadsheet)
97
    {
98
        // Create XML writer
99 73
        $objWriter = null;
100 73
        if ($this->getParentWriter()->getUseDiskCaching()) {
101
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
102
        } else {
103 73
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
104
        }
105
106
        // XML header
107 73
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
108
109
        // Relationships
110 73
        $objWriter->startElement('Relationships');
111 73
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
112
113
        // Relationship styles.xml
114 73
        $this->writeRelationship(
115 73
            $objWriter,
116 73
            1,
117 73
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
118 73
            'styles.xml'
119
        );
120
121
        // Relationship theme/theme1.xml
122 73
        $this->writeRelationship(
123 73
            $objWriter,
124 73
            2,
125 73
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
126 73
            'theme/theme1.xml'
127
        );
128
129
        // Relationship sharedStrings.xml
130 73
        $this->writeRelationship(
131 73
            $objWriter,
132 73
            3,
133 73
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings',
134 73
            'sharedStrings.xml'
135
        );
136
137
        // Relationships with sheets
138 73
        $sheetCount = $spreadsheet->getSheetCount();
139 73
        for ($i = 0; $i < $sheetCount; ++$i) {
140 73
            $this->writeRelationship(
141 73
                $objWriter,
142 73
                ($i + 1 + 3),
143 73
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
144 73
                'worksheets/sheet' . ($i + 1) . '.xml'
145
            );
146
        }
147
        // Relationships for vbaProject if needed
148
        // id : just after the last sheet
149 73
        if ($spreadsheet->hasMacros()) {
150
            $this->writeRelationShip(
151
                $objWriter,
152
                ($i + 1 + 3),
153
                'http://schemas.microsoft.com/office/2006/relationships/vbaProject',
154
                'vbaProject.bin'
155
            );
156
            ++$i; //increment i if needed for an another relation
157
        }
158
159 73
        $objWriter->endElement();
160
161 73
        return $objWriter->getData();
162
    }
163
164
    /**
165
     * Write worksheet relationships to XML format.
166
     *
167
     * Numbering is as follows:
168
     *     rId1                 - Drawings
169
     *  rId_hyperlink_x     - Hyperlinks
170
     *
171
     * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet
172
     * @param int $pWorksheetId
173
     * @param bool $includeCharts Flag indicating if we should write charts
174
     *
175
     * @throws WriterException
176
     *
177
     * @return string XML Output
178
     */
179 73
    public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, $pWorksheetId = 1, $includeCharts = false)
180
    {
181
        // Create XML writer
182 73
        $objWriter = null;
183 73
        if ($this->getParentWriter()->getUseDiskCaching()) {
184
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
185
        } else {
186 73
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
187
        }
188
189
        // XML header
190 73
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
191
192
        // Relationships
193 73
        $objWriter->startElement('Relationships');
194 73
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
195
196
        // Write drawing relationships?
197 73
        $d = 0;
198 73
        $drawingOriginalIds = [];
199 14
        if (isset($pWorksheet->getParent()->getUnparsedLoadedData()['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) {
200
            $drawingOriginalIds = $pWorksheet->getParent()->getUnparsedLoadedData()['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'];
201 60
        }
202
203 73
        if ($includeCharts) {
204 73
            $charts = $pWorksheet->getChartCollection();
205 22
        } else {
206 22
            $charts = [];
207
        }
208 22
209 22
        if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) {
210
            $relPath = '../drawings/drawing' . $pWorksheetId . '.xml';
211
            $rId = ++$d;
212
213
            if (isset($drawingOriginalIds[$relPath])) {
214 73
                $rId = (int) (substr($drawingOriginalIds[$relPath], 3));
215 73
            }
216 10
217 10
            $this->writeRelationship(
218 10
                $objWriter,
219 10
                $rId,
220 10
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',
221 10
                $relPath
222 10
            );
223
        }
224
225 10
        // Write hyperlink relationships?
226
        $i = 1;
227
        foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) {
228
            if (!$hyperlink->isInternal()) {
229
                $this->writeRelationship(
230 73
                    $objWriter,
231 73
                    '_hyperlink_' . $i,
0 ignored issues
show
Bug introduced by
'_hyperlink_' . $i of type string is incompatible with the type integer expected by parameter $pId of PhpOffice\PhpSpreadsheet...ls::writeRelationship(). ( Ignorable by Annotation )

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

231
                    /** @scrutinizer ignore-type */ '_hyperlink_' . $i,
Loading history...
232 9
                    'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
233 9
                    $hyperlink->getUrl(),
234 9
                    'External'
235 9
                );
236 9
237
                ++$i;
238
            }
239 9
        }
240 9
241 9
        // Write comments relationship?
242 9
        $i = 1;
243 9
        if (count($pWorksheet->getComments()) > 0) {
244
            $this->writeRelationship(
245
                $objWriter,
246
                '_comments_vml' . $i,
247
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
248 73
                '../drawings/vmlDrawing' . $pWorksheetId . '.vml'
249 73
            );
250 1
251 1
            $this->writeRelationship(
252 1
                $objWriter,
253 1
                '_comments' . $i,
254 1
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments',
255
                '../comments' . $pWorksheetId . '.xml'
256
            );
257
        }
258 73
259
        // Write header/footer relationship?
260 73
        $i = 1;
261
        if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) {
262
            $this->writeRelationship(
263
                $objWriter,
264
                '_headerfooter_vml' . $i,
265
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
266
                '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml'
267
            );
268
        }
269
270
        $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'ctrlProps', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp');
271
        $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'vmlDrawings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing');
272
        $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'printerSettings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings');
273
274 22
        $objWriter->endElement();
275
276
        return $objWriter->getData();
277 22
    }
278 22
279
    private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, XMLWriter $objWriter, $relationship, $type)
280
    {
281 22
        if (!isset($pWorksheet->getParent()->getUnparsedLoadedData()['sheets'][$pWorksheet->getCodeName()][$relationship])) {
282
            return;
283
        }
284
285 22
        foreach ($pWorksheet->getParent()->getUnparsedLoadedData()['sheets'][$pWorksheet->getCodeName()][$relationship] as $rId => $value) {
286
            $this->writeRelationship(
287
                $objWriter,
288 22
                $rId,
289 22
                $type,
290
                $value['relFilePath']
291
            );
292 22
        }
293 22
    }
294 22
295 10
    /**
296 10
     * Write drawing relationships to XML format.
297
     *
298 10
     * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet
299 10
     * @param int &$chartRef Chart ID
300 10
     * @param bool $includeCharts Flag indicating if we should write charts
301 10
     *
302 10
     * @throws WriterException
303
     *
304
     * @return string XML Output
305
     */
306 10
    public function writeDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, &$chartRef, $includeCharts = false)
307 10
    {
308
        // Create XML writer
309
        $objWriter = null;
310 22
        if ($this->getParentWriter()->getUseDiskCaching()) {
311
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
312 13
        } else {
313 13
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
314 13
        }
315 13
316 13
        // XML header
317 13
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
318 13
319 13
        // Relationships
320
        $objWriter->startElement('Relationships');
321
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
322
323
        // Loop through images and write relationships
324
        $i = 1;
325 22
        $iterator = $pWorksheet->getDrawingCollection()->getIterator();
326
        while ($iterator->valid()) {
327 22
            if ($iterator->current() instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing
328
                || $iterator->current() instanceof MemoryDrawing) {
329
                // Write relationship for image drawing
330
                $this->writeRelationship(
331
                    $objWriter,
332
                    $i,
333
                    'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
334
                    '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename())
335
                );
336
            }
337
338
            $iterator->next();
339 1
            ++$i;
340
        }
341
342 1
        if ($includeCharts) {
343 1
            // Loop through charts and write relationships
344
            $chartCount = $pWorksheet->getChartCount();
345
            if ($chartCount > 0) {
346 1
                for ($c = 0; $c < $chartCount; ++$c) {
347
                    $this->writeRelationship(
348
                        $objWriter,
349
                        $i++,
350 1
                        'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
351
                        '../charts/chart' . ++$chartRef . '.xml'
352
                    );
353 1
                }
354 1
            }
355
        }
356
357 1
        $objWriter->endElement();
358
359 1
        return $objWriter->getData();
360 1
    }
361 1
362 1
    /**
363 1
     * Write header/footer drawing relationships to XML format.
364
     *
365
     * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet
366
     *
367 1
     * @throws WriterException
368
     *
369 1
     * @return string XML Output
370
     */
371
    public function writeHeaderFooterDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
372
    {
373
        // Create XML writer
374
        $objWriter = null;
375
        if ($this->getParentWriter()->getUseDiskCaching()) {
376
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
377
        } else {
378
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
379
        }
380
381
        // XML header
382
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
383 73
384
        // Relationships
385 73
        $objWriter->startElement('Relationships');
386
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
387 73
388 73
        // Loop through images and write relationships
389 73
        foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) {
390 73
            // Write relationship for image drawing
391
            $this->writeRelationship(
392 73
                $objWriter,
393 10
                $key,
394
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
395
                '../media/' . $value->getIndexedFilename()
396 73
            );
397
        }
398
399
        $objWriter->endElement();
400 73
401
        return $objWriter->getData();
402
    }
403
404
    /**
405
     * Write Override content type.
406
     *
407
     * @param XMLWriter $objWriter XML Writer
408
     * @param int $pId Relationship ID. rId will be prepended!
409
     * @param string $pType Relationship type
410
     * @param string $pTarget Relationship target
411
     * @param string $pTargetMode Relationship target mode
412
     *
413
     * @throws WriterException
414
     */
415
    private function writeRelationship(XMLWriter $objWriter, $pId, $pType, $pTarget, $pTargetMode = '')
416
    {
417
        if ($pType != '' && $pTarget != '') {
418
            // Write relationship
419
            $objWriter->startElement('Relationship');
420
            $objWriter->writeAttribute('Id', 'rId' . $pId);
421
            $objWriter->writeAttribute('Type', $pType);
422
            $objWriter->writeAttribute('Target', $pTarget);
423
424
            if ($pTargetMode != '') {
425
                $objWriter->writeAttribute('TargetMode', $pTargetMode);
426
            }
427
428
            $objWriter->endElement();
429
        } else {
430
            throw new WriterException('Invalid parameters passed.');
431
        }
432
    }
433
}
434