Failed Conditions
Push — master ( 27d83b...a2771e )
by Adrien
35:04
created

Rels::writeRelationship()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.016

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 3
nop 5
dl 0
loc 16
rs 9.2
c 0
b 0
f 0
ccs 9
cts 10
cp 0.9
crap 4.016
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 60
    public function writeRelationships(Spreadsheet $spreadsheet)
22
    {
23
        // Create XML writer
24 60
        $objWriter = null;
25 60
        if ($this->getParentWriter()->getUseDiskCaching()) {
26
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
27
        } else {
28 60
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
29
        }
30
31
        // XML header
32 60
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
33
34
        // Relationships
35 60
        $objWriter->startElement('Relationships');
36 60
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
37
38 60
        $customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
39 60
        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 60
        $this->writeRelationship(
51 60
            $objWriter,
52 60
            3,
53 60
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
54 60
            'docProps/app.xml'
55
        );
56
57
        // Relationship docProps/core.xml
58 60
        $this->writeRelationship(
59 60
            $objWriter,
60 60
            2,
61 60
            'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
62 60
            'docProps/core.xml'
63
        );
64
65
        // Relationship xl/workbook.xml
66 60
        $this->writeRelationship(
67 60
            $objWriter,
68 60
            1,
69 60
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
70 60
            'xl/workbook.xml'
71
        );
72
        // a custom UI in workbook ?
73 60
        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 60
        $objWriter->endElement();
83
84 60
        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 60
    public function writeWorkbookRelationships(Spreadsheet $spreadsheet)
97
    {
98
        // Create XML writer
99 60
        $objWriter = null;
100 60
        if ($this->getParentWriter()->getUseDiskCaching()) {
101
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
102
        } else {
103 60
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
104
        }
105
106
        // XML header
107 60
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
108
109
        // Relationships
110 60
        $objWriter->startElement('Relationships');
111 60
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
112
113
        // Relationship styles.xml
114 60
        $this->writeRelationship(
115 60
            $objWriter,
116 60
            1,
117 60
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
118 60
            'styles.xml'
119
        );
120
121
        // Relationship theme/theme1.xml
122 60
        $this->writeRelationship(
123 60
            $objWriter,
124 60
            2,
125 60
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
126 60
            'theme/theme1.xml'
127
        );
128
129
        // Relationship sharedStrings.xml
130 60
        $this->writeRelationship(
131 60
            $objWriter,
132 60
            3,
133 60
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings',
134 60
            'sharedStrings.xml'
135
        );
136
137
        // Relationships with sheets
138 60
        $sheetCount = $spreadsheet->getSheetCount();
139 60
        for ($i = 0; $i < $sheetCount; ++$i) {
140 60
            $this->writeRelationship(
141 60
                $objWriter,
142 60
                ($i + 1 + 3),
143 60
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
144 60
                'worksheets/sheet' . ($i + 1) . '.xml'
145
            );
146
        }
147
        // Relationships for vbaProject if needed
148
        // id : just after the last sheet
149 60
        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 60
        $objWriter->endElement();
160
161 60
        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 60
    public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, $pWorksheetId = 1, $includeCharts = false)
180
    {
181
        // Create XML writer
182 60
        $objWriter = null;
183 60
        if ($this->getParentWriter()->getUseDiskCaching()) {
184
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
185
        } else {
186 60
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
187
        }
188
189
        // XML header
190 60
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
191
192
        // Relationships
193 60
        $objWriter->startElement('Relationships');
194 60
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
195
196
        // Write drawing relationships?
197 60
        $d = 0;
198 60
        if ($includeCharts) {
199 14
            $charts = $pWorksheet->getChartCollection();
200
        } else {
201 47
            $charts = [];
202
        }
203 60
        if (($pWorksheet->getDrawingCollection()->count() > 0) ||
204 60
            (count($charts) > 0)) {
205 22
            $this->writeRelationship(
206 22
                $objWriter,
207
                ++$d,
208 22
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',
209 22
                '../drawings/drawing' . $pWorksheetId . '.xml'
210
            );
211
        }
212
213
        // Write hyperlink relationships?
214 60
        $i = 1;
215 60
        foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) {
216 10
            if (!$hyperlink->isInternal()) {
217 10
                $this->writeRelationship(
218 10
                    $objWriter,
219 10
                    '_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

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