Completed
Push — develop ( 985c50...159711 )
by Franck
12s
created

ContentTypes::getImageMimeType()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 36
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 7.4822

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 36
ccs 22
cts 28
cp 0.7856
rs 6.7272
cc 7
eloc 28
nc 7
nop 1
crap 7.4822
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
    /**
33
     * @return \PhpOffice\Common\Adapter\Zip\ZipInterface
34
     * @throws \Exception
35
     */
36 91
    public function render()
37
    {
38 91
        $oLayoutPack = new PowerPoint2007\LayoutPack\PackDefault();
39
40
        // Create XML writer
41 91
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
42
43
        // XML header
44 91
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
45
46
        // Types
47 91
        $objWriter->startElement('Types');
48 91
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types');
49
50
        // Rels
51 91
        $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml');
52
53
        // XML
54 91
        $this->writeDefaultContentType($objWriter, 'xml', 'application/xml');
55
56
        // Themes
57 91
        $masterSlides = $oLayoutPack->getMasterSlides();
58 91
        foreach ($masterSlides as $masterSlide) {
59 91
            $this->writeOverrideContentType($objWriter, '/ppt/theme/theme' . $masterSlide['masterid'] . '.xml', 'application/vnd.openxmlformats-officedocument.theme+xml');
60 91
        }
61
62
        // Presentation
63 91
        $this->writeOverrideContentType($objWriter, '/ppt/presentation.xml', 'application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml');
64
65
        // PptProps
66 91
        $this->writeOverrideContentType($objWriter, '/ppt/presProps.xml', 'application/vnd.openxmlformats-officedocument.presentationml.presProps+xml');
67 91
        $this->writeOverrideContentType($objWriter, '/ppt/tableStyles.xml', 'application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml');
68 91
        $this->writeOverrideContentType($objWriter, '/ppt/viewProps.xml', 'application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml');
69
70
        // DocProps
71 91
        $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml');
72 91
        $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml');
73 91
        $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml');
74
75
        // Slide masters
76 91
        $masterSlides = $oLayoutPack->getMasterSlides();
77 91
        foreach ($masterSlides as $masterSlide) {
78 91
            $this->writeOverrideContentType($objWriter, '/ppt/slideMasters/slideMaster' . $masterSlide['masterid'] . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml');
79 91
        }
80
81
        // Slide layouts
82 91
        $slideLayouts = $oLayoutPack->getLayouts();
83 91
        $numSlideLayouts = count($slideLayouts);
84 91
        for ($i = 0; $i < $numSlideLayouts; ++$i) {
85 91
            $this->writeOverrideContentType($objWriter, '/ppt/slideLayouts/slideLayout' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml');
86 91
        }
87
88
        // Slides
89 91
        $slideCount = $this->oPresentation->getSlideCount();
90 91
        for ($i = 0; $i < $slideCount; ++$i) {
91 91
            $this->writeOverrideContentType($objWriter, '/ppt/slides/slide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml');
92 91
            if ($this->oPresentation->getSlide($i)->getNote()->getShapeCollection()->count() > 0) {
93 1
                $this->writeOverrideContentType($objWriter, '/ppt/notesSlides/notesSlide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml');
94 1
            }
95 91
        }
96
97
        // Add layoutpack content types
98 91
        $otherRelations = $oLayoutPack->getMasterSlideRelations();
99 91
        foreach ($otherRelations as $otherRelation) {
100
            if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') {
101
                $this->writeOverrideContentType($objWriter, '/ppt/slideMasters/' . $otherRelation['target'], $otherRelation['contentType']);
102
            }
103 91
        }
104 91
        $otherRelations = $oLayoutPack->getThemeRelations();
105 91
        foreach ($otherRelations as $otherRelation) {
106
            if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') {
107
                $this->writeOverrideContentType($objWriter, '/ppt/theme/' . $otherRelation['target'], $otherRelation['contentType']);
108
            }
109 91
        }
110 91
        $otherRelations = $oLayoutPack->getLayoutRelations();
111 91
        foreach ($otherRelations as $otherRelation) {
112
            if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') {
113
                $this->writeOverrideContentType($objWriter, '/ppt/slideLayouts/' . $otherRelation['target'], $otherRelation['contentType']);
114
            }
115 91
        }
116
117
        // Add media content-types
118 91
        $aMediaContentTypes = array();
119
120
        // GIF, JPEG, PNG
121 91
        $aMediaContentTypes['gif']  = 'image/gif';
122 91
        $aMediaContentTypes['jpg']  = 'image/jpeg';
123 91
        $aMediaContentTypes['jpeg'] = 'image/jpeg';
124 91
        $aMediaContentTypes['png']  = 'image/png';
125 91
        foreach ($aMediaContentTypes as $key => $value) {
126 91
            $this->writeDefaultContentType($objWriter, $key, $value);
127 91
        }
128
129
        // XLSX
130 91
        $this->writeDefaultContentType($objWriter, 'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
131
132
        // Other media content types
133 91
        $mediaCount = $this->getDrawingHashTable()->count();
134 91
        for ($i = 0; $i < $mediaCount; ++$i) {
135 33
            $extension = '';
136 33
            $mimeType  = '';
137
138 33
            $shapeIndex = $this->getDrawingHashTable()->getByIndex($i);
139 33
            if ($shapeIndex instanceof ShapeChart) {
140
                // Chart content type
141 24
                $this->writeOverrideContentType($objWriter, '/ppt/charts/chart' . $shapeIndex->getImageIndex() . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
142 24
            } else {
143 9
                if ($shapeIndex instanceof ShapeDrawing) {
144 8
                    $extension = strtolower($shapeIndex->getExtension());
145 8
                    $mimeType  = $this->getImageMimeType($shapeIndex->getPath());
146 7
                } elseif ($shapeIndex instanceof MemoryDrawing) {
147 1
                    $extension = strtolower($shapeIndex->getMimeType());
148 1
                    $extension = explode('/', $extension);
149 1
                    $extension = $extension[1];
150
151 1
                    $mimeType = $shapeIndex->getMimeType();
152 1
                }
153
154 7
                if (!isset($aMediaContentTypes[$extension])) {
155 1
                    $aMediaContentTypes[$extension] = $mimeType;
156
157 1
                    $this->writeDefaultContentType($objWriter, $extension, $mimeType);
158 1
                }
159
            }
160 31
        }
161
162 89
        $objWriter->endElement();
163
164 89
        $this->oZip->addFromString('[Content_Types].xml', $objWriter->getData());
165
166 89
        return $this->oZip;
167
    }
168
169
    /**
170
     * Get image mime type
171
     *
172
     * @param  string    $pFile Filename
173
     * @return string    Mime Type
174
     * @throws \Exception
175
     */
176 8
    private function getImageMimeType($pFile = '')
177
    {
178 8
        if (strpos($pFile, 'zip://') === 0) {
179 2
            $pZIPFile = str_replace('zip://', '', $pFile);
180 2
            $pZIPFile = substr($pZIPFile, 0, strpos($pZIPFile, '#'));
181 2
            if (!File::fileExists($pZIPFile)) {
182 1
                throw new \Exception("File $pFile does not exist");
183
            }
184 1
            $pImgFile = substr($pFile, strpos($pFile, '#') + 1);
185 1
            $oArchive = new \ZipArchive();
186 1
            $oArchive->open($pZIPFile);
187 1
            if (!function_exists('getimagesizefromstring')) {
188
                $uri = 'data://application/octet-stream;base64,' . base64_encode($oArchive->getFromName($pImgFile));
189
                $image = getimagesize($uri);
190
            } else {
191 1
                $image = getimagesizefromstring($oArchive->getFromName($pImgFile));
192
            }
193 7
        } elseif (strpos($pFile, 'data:image/') === 0) {
194 1
            $sImage = $pFile;
195 1
            list(, $sImage) = explode(';', $sImage);
196 1
            list(, $sImage) = explode(',', $sImage);
197 1
            if (!function_exists('getimagesizefromstring')) {
198
                $uri = 'data://application/octet-stream;base64,' . base64_encode($sImage);
199
                $image = getimagesize($uri);
200
            } else {
201 1
                $image = getimagesizefromstring($sImage);
202
            }
203 1
        } else {
204 5
            if (!File::fileExists($pFile)) {
205 1
                throw new \Exception("File $pFile does not exist");
206
            }
207 4
            $image = getimagesize($pFile);
208
        }
209
210 6
        return image_type_to_mime_type($image[2]);
211
    }
212
213
    /**
214
     * Write Default content type
215
     *
216
     * @param  \PhpOffice\Common\XMLWriter $objWriter    XML Writer
217
     * @param  string                         $pPartname    Part name
218
     * @param  string                         $pContentType Content type
219
     * @throws \Exception
220
     */
221 91
    private function writeDefaultContentType(XMLWriter $objWriter, $pPartname = '', $pContentType = '')
222
    {
223 91
        if ($pPartname != '' && $pContentType != '') {
224
            // Write content type
225 91
            $objWriter->startElement('Default');
226 91
            $objWriter->writeAttribute('Extension', $pPartname);
227 91
            $objWriter->writeAttribute('ContentType', $pContentType);
228 91
            $objWriter->endElement();
229 91
        } else {
230
            throw new \Exception("Invalid parameters passed.");
231
        }
232 91
    }
233
234
    /**
235
     * Write Override content type
236
     *
237
     * @param  \PhpOffice\Common\XMLWriter $objWriter    XML Writer
238
     * @param  string                         $pPartname    Part name
239
     * @param  string                         $pContentType Content type
240
     * @throws \Exception
241
     */
242 91
    private function writeOverrideContentType(XMLWriter $objWriter, $pPartname = '', $pContentType = '')
243
    {
244 91
        if ($pPartname != '' && $pContentType != '') {
245
            // Write content type
246 91
            $objWriter->startElement('Override');
247 91
            $objWriter->writeAttribute('PartName', $pPartname);
248 91
            $objWriter->writeAttribute('ContentType', $pContentType);
249 91
            $objWriter->endElement();
250 91
        } else {
251
            throw new \Exception("Invalid parameters passed.");
252
        }
253 91
    }
254
}
255