Completed
Pull Request — develop (#187)
by Franck
08:38
created

ContentTypes::render()   F

Complexity

Conditions 21
Paths 10368

Size

Total Lines 132
Code Lines 72

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 462

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 132
ccs 0
cts 90
cp 0
rs 2
cc 21
eloc 72
nc 10368
nop 0
crap 462

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of PHPPresentation - A pure PHP library for reading and writing
4
 * presentations documents.
5
 *
6
 * PHPPresentation is free software distributed under the terms of the GNU Lesser
7
 * General Public License version 3 as published by the Free Software Foundation.
8
 *
9
 * For the full copyright and license information, please read the LICENSE
10
 * file that was distributed with this source code. For the full list of
11
 * contributors, visit https://github.com/PHPOffice/PHPPresentation/contributors.
12
 *
13
 * @link        https://github.com/PHPOffice/PHPPresentation
14
 * @copyright   2009-2015 PHPPresentation contributors
15
 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16
 */
17
18
namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007;
19
20
use PhpOffice\PhpPresentation\Shape\Chart as ShapeChart;
21
use PhpOffice\PhpPresentation\Shape\Drawing as ShapeDrawing;
22
use PhpOffice\PhpPresentation\Shape\MemoryDrawing;
23
use PhpOffice\Common\File;
24
use PhpOffice\Common\XMLWriter;
25
use PhpOffice\PhpPresentation\Writer\PowerPoint2007;
26
27
/**
28
 * \PhpOffice\PhpPresentation\Writer\PowerPoint2007\ContentTypes
29
 */
30
class ContentTypes extends AbstractDecoratorWriter
31
{
32
    public function render()
33
    {
34
        $oLayoutPack = new PowerPoint2007\LayoutPack\PackDefault();
35
36
        // Create XML writer
37
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
38
39
        // XML header
40
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
41
42
        // Types
43
        $objWriter->startElement('Types');
44
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types');
45
46
        // Rels
47
        $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml');
48
49
        // XML
50
        $this->writeDefaultContentType($objWriter, 'xml', 'application/xml');
51
52
        // Themes
53
        $masterSlides = $oLayoutPack->getMasterSlides();
54
        foreach ($masterSlides as $masterSlide) {
55
            $this->writeOverrideContentType($objWriter, '/ppt/theme/theme' . $masterSlide['masterid'] . '.xml', 'application/vnd.openxmlformats-officedocument.theme+xml');
56
        }
57
58
        // Presentation
59
        $this->writeOverrideContentType($objWriter, '/ppt/presentation.xml', 'application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml');
60
61
        // PptProps
62
        $this->writeOverrideContentType($objWriter, '/ppt/presProps.xml', 'application/vnd.openxmlformats-officedocument.presentationml.presProps+xml');
63
        $this->writeOverrideContentType($objWriter, '/ppt/tableStyles.xml', 'application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml');
64
        $this->writeOverrideContentType($objWriter, '/ppt/viewProps.xml', 'application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml');
65
66
        // DocProps
67
        $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml');
68
        $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml');
69
        $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml');
70
71
        // Slide masters
72
        $masterSlides = $oLayoutPack->getMasterSlides();
73
        foreach ($masterSlides as $masterSlide) {
74
            $this->writeOverrideContentType($objWriter, '/ppt/slideMasters/slideMaster' . $masterSlide['masterid'] . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml');
75
        }
76
77
        // Slide layouts
78
        $slideLayouts = $oLayoutPack->getLayouts();
79
        $numSlideLayouts = count($slideLayouts);
80
        for ($i = 0; $i < $numSlideLayouts; ++$i) {
81
            $this->writeOverrideContentType($objWriter, '/ppt/slideLayouts/slideLayout' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml');
82
        }
83
84
        // Slides
85
        $slideCount = $this->oPresentation->getSlideCount();
86
        for ($i = 0; $i < $slideCount; ++$i) {
87
            $this->writeOverrideContentType($objWriter, '/ppt/slides/slide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml');
88
            if ($this->oPresentation->getSlide($i)->getNote()->getShapeCollection()->count() > 0) {
89
                $this->writeOverrideContentType($objWriter, '/ppt/notesSlides/notesSlide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml');
90
            }
91
        }
92
93
        // Add layoutpack content types
94
        $otherRelations = $oLayoutPack->getMasterSlideRelations();
95
        foreach ($otherRelations as $otherRelation) {
96
            if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') {
97
                $this->writeOverrideContentType($objWriter, '/ppt/slideMasters/' . $otherRelation['target'], $otherRelation['contentType']);
98
            }
99
        }
100
        $otherRelations = $oLayoutPack->getThemeRelations();
101
        foreach ($otherRelations as $otherRelation) {
102
            if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') {
103
                $this->writeOverrideContentType($objWriter, '/ppt/theme/' . $otherRelation['target'], $otherRelation['contentType']);
104
            }
105
        }
106
        $otherRelations = $oLayoutPack->getLayoutRelations();
107
        foreach ($otherRelations as $otherRelation) {
108
            if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') {
109
                $this->writeOverrideContentType($objWriter, '/ppt/slideLayouts/' . $otherRelation['target'], $otherRelation['contentType']);
110
            }
111
        }
112
113
        // Add media content-types
114
        $aMediaContentTypes = array();
115
116
        // GIF, JPEG, PNG
117
        $aMediaContentTypes['gif']  = 'image/gif';
118
        $aMediaContentTypes['jpg']  = 'image/jpeg';
119
        $aMediaContentTypes['jpeg'] = 'image/jpeg';
120
        $aMediaContentTypes['png']  = 'image/png';
121
        foreach ($aMediaContentTypes as $key => $value) {
122
            $this->writeDefaultContentType($objWriter, $key, $value);
123
        }
124
125
        // XLSX
126
        $this->writeDefaultContentType($objWriter, 'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
127
128
        // Other media content types
129
        $mediaCount = $this->getDrawingHashTable()->count();
130
        for ($i = 0; $i < $mediaCount; ++$i) {
131
            $extension = '';
132
            $mimeType  = '';
133
134
            $shapeIndex = $this->getDrawingHashTable()->getByIndex($i);
135
            if ($shapeIndex instanceof ShapeChart) {
136
                // Chart content type
137
                $this->writeOverrideContentType($objWriter, '/ppt/charts/chart' . $shapeIndex->getImageIndex() . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
138
            } else {
139
                if ($shapeIndex instanceof ShapeDrawing) {
140
                    $extension = strtolower($shapeIndex->getExtension());
141
                    $mimeType  = $this->getImageMimeType($shapeIndex->getPath());
142
                } elseif ($shapeIndex instanceof MemoryDrawing) {
143
                    $extension = strtolower($shapeIndex->getMimeType());
144
                    $extension = explode('/', $extension);
145
                    $extension = $extension[1];
146
147
                    $mimeType = $shapeIndex->getMimeType();
148
                }
149
150
                if (!isset($aMediaContentTypes[$extension])) {
151
                    $aMediaContentTypes[$extension] = $mimeType;
152
153
                    $this->writeDefaultContentType($objWriter, $extension, $mimeType);
154
                }
155
            }
156
        }
157
158
        $objWriter->endElement();
159
160
        $this->oZip->addFromString('[Content_Types].xml', $objWriter->getData());
161
162
        return $this->oZip;
163
    }
164
165
    /**
166
     * Get image mime type
167
     *
168
     * @param  string    $pFile Filename
169
     * @return string    Mime Type
170
     * @throws \Exception
171
     */
172
    private function getImageMimeType($pFile = '')
173
    {
174
        if (strpos($pFile, 'zip://') === 0) {
175
            $pZIPFile = str_replace('zip://', '', $pFile);
176
            $pZIPFile = substr($pZIPFile, 0, strpos($pZIPFile, '#'));
177
            if (!File::fileExists($pZIPFile)) {
178
                throw new \Exception("File $pFile does not exist");
179
            }
180
            $pImgFile = substr($pFile, strpos($pFile, '#') + 1);
181
            $oArchive = new \ZipArchive();
182
            $oArchive->open($pZIPFile);
183
            $image = getimagesizefromstring($oArchive->getFromName($pImgFile));
184
        } else {
185
            if (!File::fileExists($pFile)) {
186
                throw new \Exception("File $pFile does not exist");
187
            }
188
            $image = getimagesize($pFile);
189
        }
190
191
        return image_type_to_mime_type($image[2]);
192
    }
193
194
    /**
195
     * Write Default content type
196
     *
197
     * @param  \PhpOffice\Common\XMLWriter $objWriter    XML Writer
198
     * @param  string                         $pPartname    Part name
199
     * @param  string                         $pContentType Content type
200
     * @throws \Exception
201
     */
202
    private function writeDefaultContentType(XMLWriter $objWriter, $pPartname = '', $pContentType = '')
203
    {
204
        if ($pPartname != '' && $pContentType != '') {
205
            // Write content type
206
            $objWriter->startElement('Default');
207
            $objWriter->writeAttribute('Extension', $pPartname);
208
            $objWriter->writeAttribute('ContentType', $pContentType);
209
            $objWriter->endElement();
210
        } else {
211
            throw new \Exception("Invalid parameters passed.");
212
        }
213
    }
214
215
    /**
216
     * Write Override content type
217
     *
218
     * @param  \PhpOffice\Common\XMLWriter $objWriter    XML Writer
219
     * @param  string                         $pPartname    Part name
220
     * @param  string                         $pContentType Content type
221
     * @throws \Exception
222
     */
223
    private function writeOverrideContentType(XMLWriter $objWriter, $pPartname = '', $pContentType = '')
224
    {
225
        if ($pPartname != '' && $pContentType != '') {
226
            // Write content type
227
            $objWriter->startElement('Override');
228
            $objWriter->writeAttribute('PartName', $pPartname);
229
            $objWriter->writeAttribute('ContentType', $pContentType);
230
            $objWriter->endElement();
231
        } else {
232
            throw new \Exception("Invalid parameters passed.");
233
        }
234
    }
235
}
236