Completed
Pull Request — develop (#209)
by Franck
07:03
created

MetaInfManifest   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
c 1
b 0
f 0
lcom 1
cbo 11
dl 0
loc 155
ccs 0
cts 117
cp 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
C render() 0 104 11
C getImageMimeType() 0 36 7
1
<?php
2
3
namespace PhpOffice\PhpPresentation\Writer\ODPresentation;
4
5
use PhpOffice\Common\Adapter\Zip\ZipInterface;
6
use PhpOffice\Common\File;
7
use PhpOffice\Common\XMLWriter;
8
use PhpOffice\PhpPresentation\Shape\Drawing as ShapeDrawing;
9
use PhpOffice\PhpPresentation\Shape\MemoryDrawing;
10
use PhpOffice\PhpPresentation\Slide\Background\Image;
11
use PhpOffice\PhpPresentation\Writer\ODPresentation;
12
13
class MetaInfManifest extends AbstractDecoratorWriter
14
{
15
    /**
16
     * @return ZipInterface
17
     */
18
    public function render()
19
    {
20
        // Create XML writer
21
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
22
23
        // XML header
24
        $objWriter->startDocument('1.0', 'UTF-8');
25
26
        // manifest:manifest
27
        $objWriter->startElement('manifest:manifest');
28
        $objWriter->writeAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0');
29
        $objWriter->writeAttribute('manifest:version', '1.2');
30
31
        // manifest:file-entry
32
        $objWriter->startElement('manifest:file-entry');
33
        $objWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.presentation');
34
        $objWriter->writeAttribute('manifest:full-path', '/');
35
        $objWriter->writeAttribute('manifest:version', '1.2');
36
        $objWriter->endElement();
37
        // manifest:file-entry
38
        $objWriter->startElement('manifest:file-entry');
39
        $objWriter->writeAttribute('manifest:media-type', 'text/xml');
40
        $objWriter->writeAttribute('manifest:full-path', 'content.xml');
41
        $objWriter->endElement();
42
        // manifest:file-entry
43
        $objWriter->startElement('manifest:file-entry');
44
        $objWriter->writeAttribute('manifest:media-type', 'text/xml');
45
        $objWriter->writeAttribute('manifest:full-path', 'meta.xml');
46
        $objWriter->endElement();
47
        // manifest:file-entry
48
        $objWriter->startElement('manifest:file-entry');
49
        $objWriter->writeAttribute('manifest:media-type', 'text/xml');
50
        $objWriter->writeAttribute('manifest:full-path', 'styles.xml');
51
        $objWriter->endElement();
52
53
        // Charts
54
        foreach ($this->getArrayChart() as $key => $shape) {
55
            $objWriter->startElement('manifest:file-entry');
56
            $objWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.chart');
57
            $objWriter->writeAttribute('manifest:full-path', 'Object '.$key.'/');
58
            $objWriter->endElement();
59
            $objWriter->startElement('manifest:file-entry');
60
            $objWriter->writeAttribute('manifest:media-type', 'text/xml');
61
            $objWriter->writeAttribute('manifest:full-path', 'Object '.$key.'/content.xml');
62
            $objWriter->endElement();
63
        }
64
65
        $arrMedia = array();
66
        for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {
67
            $shape = $this->getDrawingHashTable()->getByIndex($i);
68
            if ($shape instanceof ShapeDrawing) {
69
                if (!in_array(md5($shape->getPath()), $arrMedia)) {
70
                    $arrMedia[] = md5($shape->getPath());
71
                    $mimeType   = $this->getImageMimeType($shape->getPath());
72
73
                    $objWriter->startElement('manifest:file-entry');
74
                    $objWriter->writeAttribute('manifest:media-type', $mimeType);
75
                    $objWriter->writeAttribute('manifest:full-path', 'Pictures/' . md5($shape->getPath()) . '.' . $shape->getExtension());
76
                    $objWriter->endElement();
77
                }
78
            } elseif ($shape instanceof MemoryDrawing) {
79
                if (!in_array(str_replace(' ', '_', $shape->getIndexedFilename()), $arrMedia)) {
80
                    $arrMedia[] = str_replace(' ', '_', $shape->getIndexedFilename());
81
                    $mimeType = $shape->getMimeType();
82
83
                    $objWriter->startElement('manifest:file-entry');
84
                    $objWriter->writeAttribute('manifest:media-type', $mimeType);
85
                    $objWriter->writeAttribute('manifest:full-path', 'Pictures/' . str_replace(' ', '_', $shape->getIndexedFilename()));
86
                    $objWriter->endElement();
87
                }
88
            }
89
        }
90
91
        foreach ($this->getPresentation()->getAllSlides() as $numSlide => $oSlide) {
92
            $oBkgImage = $oSlide->getBackground();
93
            if ($oBkgImage instanceof Image) {
94
                $mimeType   = $this->getImageMimeType($oBkgImage->getPath());
95
96
                $objWriter->startElement('manifest:file-entry');
97
                $objWriter->writeAttribute('manifest:media-type', $mimeType);
98
                $objWriter->writeAttribute('manifest:full-path', 'Pictures/' . str_replace(' ', '_', $oBkgImage->getIndexedFilename($numSlide)));
99
                $objWriter->endElement();
100
            }
101
        }
102
103
        if ($this->getPresentation()->getPresentationProperties()->getThumbnailPath()) {
104
            $pathThumbnail = $this->getPresentation()->getPresentationProperties()->getThumbnailPath();
105
            // Size : 128x128 pixel
106
            // PNG : 8bit, non-interlaced with full alpha transparency
107
            $gdImage = imagecreatefromstring(file_get_contents($pathThumbnail));
108
            if ($gdImage) {
109
                imagedestroy($gdImage);
110
                $objWriter->startElement('manifest:file-entry');
111
                $objWriter->writeAttribute('manifest:media-type', 'image/png');
112
                $objWriter->writeAttribute('manifest:full-path', 'Thumbnails/thumbnail.png');
113
                $objWriter->endElement();
114
            }
115
        }
116
117
        $objWriter->endElement();
118
119
        $this->getZip()->addFromString('META-INF/manifest.xml', $objWriter->getData());
120
        return $this->getZip();
121
    }
122
123
    /**
124
     * Get image mime type
125
     *
126
     * @param  string    $pFile Filename
127
     * @return string    Mime Type
128
     * @throws \Exception
129
     * @todo PowerPoint2007\ContentTypes duplicate Code : getImageMimeType
130
     */
131
    private function getImageMimeType($pFile = '')
132
    {
133
        if (strpos($pFile, 'zip://') === 0) {
134
            $pZIPFile = str_replace('zip://', '', $pFile);
135
            $pZIPFile = substr($pZIPFile, 0, strpos($pZIPFile, '#'));
136
            if (!File::fileExists($pZIPFile)) {
137
                throw new \Exception("File $pFile does not exist");
138
            }
139
            $pImgFile = substr($pFile, strpos($pFile, '#') + 1);
140
            $oArchive = new \ZipArchive();
141
            $oArchive->open($pZIPFile);
142
            if (!function_exists('getimagesizefromstring')) {
143
                $uri = 'data://application/octet-stream;base64,' . base64_encode($oArchive->getFromName($pImgFile));
144
                $image = getimagesize($uri);
145
            } else {
146
                $image = getimagesizefromstring($oArchive->getFromName($pImgFile));
147
            }
148
        } elseif (strpos($pFile, 'data:image/') === 0) {
149
            $sImage = $pFile;
150
            list(, $sImage) = explode(';', $sImage);
151
            list(, $sImage) = explode(',', $sImage);
152
            if (!function_exists('getimagesizefromstring')) {
153
                $uri = 'data://application/octet-stream;base64,' . base64_encode($sImage);
154
                $image = getimagesize($uri);
155
            } else {
156
                $image = getimagesizefromstring($sImage);
157
            }
158
        } else {
159
            if (!File::fileExists($pFile)) {
160
                throw new \Exception("File $pFile does not exist");
161
            }
162
            $image = getimagesize($pFile);
163
        }
164
165
        return image_type_to_mime_type($image[2]);
166
    }
167
}
168