Completed
Pull Request — develop (#322)
by Thomas
08:13 queued 03:00
created

ODPresentation::canRead()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
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\Reader;
19
20
use ZipArchive;
21
use PhpOffice\Common\XMLReader;
22
use PhpOffice\Common\Drawing as CommonDrawing;
23
use PhpOffice\PhpPresentation\PhpPresentation;
24
use PhpOffice\PhpPresentation\Shape\Drawing\Gd;
25
use PhpOffice\PhpPresentation\Shape\RichText;
26
use PhpOffice\PhpPresentation\Shape\RichText\Paragraph;
27
use PhpOffice\PhpPresentation\Slide\Background\Image;
28
use PhpOffice\PhpPresentation\Style\Bullet;
29
use PhpOffice\PhpPresentation\Style\Color;
30
use PhpOffice\PhpPresentation\Style\Font;
31
use PhpOffice\PhpPresentation\Style\Shadow;
32
use PhpOffice\PhpPresentation\Style\Alignment;
33
34
/**
35
 * Serialized format reader
36
 */
37
class ODPresentation implements ReaderInterface
38
{
39
    /**
40
     * Output Object
41
     * @var PhpPresentation
42
     */
43
    protected $oPhpPresentation;
44
    /**
45
     * Output Object
46
     * @var \ZipArchive
47
     */
48
    protected $oZip;
49
    /**
50
     * @var array[]
51
     */
52
    protected $arrayStyles = array();
53
    /**
54
     * @var array[]
55
     */
56
    protected $arrayCommonStyles = array();
57
    /**
58
     * @var \PhpOffice\Common\XMLReader
59
     */
60
    protected $oXMLReader;
61
62
    /**
63
     * Can the current \PhpOffice\PhpPresentation\Reader\ReaderInterface read the file?
64
     *
65
     * @param  string $pFilename
66
     * @throws \Exception
67
     * @return boolean
68
     */
69 2
    public function canRead($pFilename)
70
    {
71 2
        return $this->fileSupportsUnserializePhpPresentation($pFilename);
72
    }
73
74
    /**
75
     * Does a file support UnserializePhpPresentation ?
76
     *
77
     * @param  string    $pFilename
78
     * @throws \Exception
79
     * @return boolean
80
     */
81 8
    public function fileSupportsUnserializePhpPresentation($pFilename = '')
82
    {
83
        // Check if file exists
84 8
        if (!file_exists($pFilename)) {
85 2
            throw new \Exception("Could not open " . $pFilename . " for reading! File does not exist.");
86
        }
87
        
88 6
        $oZip = new ZipArchive();
89
        // Is it a zip ?
90 6
        if ($oZip->open($pFilename) === true) {
91
            // Is it an OpenXML Document ?
92
            // Is it a Presentation ?
93 4
            if (is_array($oZip->statName('META-INF/manifest.xml')) && is_array($oZip->statName('mimetype')) && $oZip->getFromName('mimetype') == 'application/vnd.oasis.opendocument.presentation') {
94 4
                return true;
95
            }
96 1
        }
97 3
        return false;
98
    }
99
100
    /**
101
     * Loads PhpPresentation Serialized file
102
     *
103
     * @param  string        $pFilename
104
     * @return \PhpOffice\PhpPresentation\PhpPresentation
105
     * @throws \Exception
106
     */
107 5
    public function load($pFilename)
108
    {
109
        // Unserialize... First make sure the file supports it!
110 5
        if (!$this->fileSupportsUnserializePhpPresentation($pFilename)) {
111 1
            throw new \Exception("Invalid file format for PhpOffice\PhpPresentation\Reader\ODPresentation: " . $pFilename . ".");
112
        }
113
114 3
        return $this->loadFile($pFilename);
115
    }
116
117
    /**
118
     * Load PhpPresentation Serialized file
119
     *
120
     * @param  string        $pFilename
121
     * @return \PhpOffice\PhpPresentation\PhpPresentation
122
     */
123 3
    protected function loadFile($pFilename)
124
    {
125 3
        $this->oPhpPresentation = new PhpPresentation();
126 3
        $this->oPhpPresentation->removeSlideByIndex();
127
        
128 3
        $this->oZip = new ZipArchive();
129 3
        $this->oZip->open($pFilename);
130
        
131 3
        $this->oXMLReader = new XMLReader();
132 3
        if ($this->oXMLReader->getDomFromZip($pFilename, 'meta.xml') !== false) {
133 3
            $this->loadDocumentProperties();
134 3
        }
135 3
        $this->oXMLReader = new XMLReader();
136 3
        if ($this->oXMLReader->getDomFromZip($pFilename, 'styles.xml') !== false) {
137 3
            $this->loadStylesFile();
138 3
        }
139 3
        $this->oXMLReader = new XMLReader();
140 3
        if ($this->oXMLReader->getDomFromZip($pFilename, 'content.xml') !== false) {
141 3
            $this->loadSlides();
142 3
        }
143
144 3
        return $this->oPhpPresentation;
145
    }
146
    
147
    /**
148
     * Read Document Properties
149
     */
150 3
    protected function loadDocumentProperties()
151
    {
152
        $arrayProperties = array(
153 3
            '/office:document-meta/office:meta/meta:initial-creator' => 'setCreator',
154 3
            '/office:document-meta/office:meta/dc:creator' => 'setLastModifiedBy',
155 3
            '/office:document-meta/office:meta/dc:title' => 'setTitle',
156 3
            '/office:document-meta/office:meta/dc:description' => 'setDescription',
157 3
            '/office:document-meta/office:meta/dc:subject' => 'setSubject',
158 3
            '/office:document-meta/office:meta/meta:keyword' => 'setKeywords',
159 3
            '/office:document-meta/office:meta/meta:creation-date' => 'setCreated',
160 3
            '/office:document-meta/office:meta/dc:date' => 'setModified',
161 3
        );
162 3
        $oProperties = $this->oPhpPresentation->getDocumentProperties();
163 3
        foreach ($arrayProperties as $path => $property) {
164 3
            if (is_object($oElement = $this->oXMLReader->getElement($path))) {
165 3
                if (in_array($property, array('setCreated', 'setModified'))) {
166 3
                    $oDateTime = new \DateTime();
167 3
                    $oDateTime->createFromFormat(\DateTime::W3C, $oElement->nodeValue);
168 3
                    $oProperties->{$property}($oDateTime->getTimestamp());
169 3
                } else {
170 1
                    $oProperties->{$property}($oElement->nodeValue);
171
                }
172 3
            }
173 3
        }
174 3
    }
175
    
176
    /**
177
     * Extract all slides
178
     */
179 3
    protected function loadSlides()
180
    {
181 3
        foreach ($this->oXMLReader->getElements('/office:document-content/office:automatic-styles/*') as $oElement) {
182 3
            if ($oElement->hasAttribute('style:name')) {
183 3
                $this->loadStyle($oElement);
184 3
            }
185 3
        }
186 3
        foreach ($this->oXMLReader->getElements('/office:document-content/office:body/office:presentation/draw:page') as $oElement) {
187 3
            if ($oElement->nodeName == 'draw:page') {
188 3
                $this->loadSlide($oElement);
189 3
            }
190 3
        }
191 3
    }
192
    
193
    /**
194
     * Extract style
195
     * @param \DOMElement $nodeStyle
196
     */
197 3
    protected function loadStyle(\DOMElement $nodeStyle)
198
    {
199 3
        $keyStyle = $nodeStyle->getAttribute('style:name');
200
201 3
        $nodeDrawingPageProps = $this->oXMLReader->getElement('style:drawing-page-properties', $nodeStyle);
202 3
        if ($nodeDrawingPageProps) {
203
            // Read Background Color
204 3
            if ($nodeDrawingPageProps->hasAttribute('draw:fill-color') && $nodeDrawingPageProps->getAttribute('draw:fill') == 'solid') {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
205
                $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\Color();
206
                $oColor = new Color();
207
                $oColor->setRGB(substr($nodeDrawingPageProps->getAttribute('draw:fill-color'), -6));
208
                $oBackground->setColor($oColor);
209
            }
210
            // Read Background Image
211 3
            if ($nodeDrawingPageProps->getAttribute('draw:fill') == 'bitmap' && $nodeDrawingPageProps->hasAttribute('draw:fill-image-name')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
212
                $nameStyle = $nodeDrawingPageProps->getAttribute('draw:fill-image-name');
213
                if (!empty($this->arrayCommonStyles[$nameStyle]) && $this->arrayCommonStyles[$nameStyle]['type'] == 'image' && !empty($this->arrayCommonStyles[$nameStyle]['path'])) {
214
                    $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderODPBkg');
215
                    $contentImg = $this->oZip->getFromName($this->arrayCommonStyles[$nameStyle]['path']);
216
                    file_put_contents($tmpBkgImg, $contentImg);
217
218
                    $oBackground = new Image();
219
                    $oBackground->setPath($tmpBkgImg);
220
                }
221
            }
222 3
        }
223
224 3
        $nodeGraphicProps = $this->oXMLReader->getElement('style:graphic-properties', $nodeStyle);
225 3
        if ($nodeGraphicProps) {
226
            // Read Shadow
227 3
            if ($nodeGraphicProps->hasAttribute('draw:shadow') && $nodeGraphicProps->getAttribute('draw:shadow') == 'visible') {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
228 1
                $oShadow = new Shadow();
229 1
                $oShadow->setVisible(true);
230 1
                if ($nodeGraphicProps->hasAttribute('draw:shadow-color')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
231 1
                    $oShadow->getColor()->setRGB(substr($nodeGraphicProps->getAttribute('draw:shadow-color'), -6));
232 1
                }
233 1
                if ($nodeGraphicProps->hasAttribute('draw:shadow-opacity')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
234 1
                    $oShadow->setAlpha(100 - (int)substr($nodeGraphicProps->getAttribute('draw:shadow-opacity'), 0, -1));
235 1
                }
236 1
                if ($nodeGraphicProps->hasAttribute('draw:shadow-offset-x') && $nodeGraphicProps->hasAttribute('draw:shadow-offset-y')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
237 1
                    $offsetX = substr($nodeGraphicProps->getAttribute('draw:shadow-offset-x'), 0, -2);
238 1
                    $offsetY = substr($nodeGraphicProps->getAttribute('draw:shadow-offset-y'), 0, -2);
239 1
                    $distance = 0;
240 1
                    if ($offsetX != 0) {
241 1
                        $distance = ($offsetX < 0 ? $offsetX * -1 : $offsetX);
242 1
                    } elseif ($offsetY != 0) {
243
                        $distance = ($offsetY < 0 ? $offsetY * -1 : $offsetY);
244
                    }
245 1
                    $oShadow->setDirection(rad2deg(atan2($offsetY, $offsetX)));
246 1
                    $oShadow->setDistance(CommonDrawing::centimetersToPixels($distance));
247 1
                }
248 1
            }
249 3
        }
250
        
251 3
        $nodeTextProperties = $this->oXMLReader->getElement('style:text-properties', $nodeStyle);
252 3
        if ($nodeTextProperties) {
253 1
            $oFont = new Font();
254 1
            if ($nodeTextProperties->hasAttribute('fo:color')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
255 1
                $oFont->getColor()->setRGB(substr($nodeTextProperties->getAttribute('fo:color'), -6));
256 1
            }
257 1
            if ($nodeTextProperties->hasAttribute('fo:font-family')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
258 1
                $oFont->setName($nodeTextProperties->getAttribute('fo:font-family'));
259 1
            }
260 1
            if ($nodeTextProperties->hasAttribute('fo:font-weight') && $nodeTextProperties->getAttribute('fo:font-weight') == 'bold') {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
261 1
                $oFont->setBold(true);
262 1
            }
263 1
            if ($nodeTextProperties->hasAttribute('fo:font-size')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
264 1
                $oFont->setSize(substr($nodeTextProperties->getAttribute('fo:font-size'), 0, -2));
265 1
            }
266 1
        }
267
268 3
        $nodeParagraphProps = $this->oXMLReader->getElement('style:paragraph-properties', $nodeStyle);
269 3
        if ($nodeParagraphProps) {
270 2
            $oAlignment = new Alignment();
271 2
            if ($nodeParagraphProps->hasAttribute('fo:text-align')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
272 2
                $oAlignment->setHorizontal($nodeParagraphProps->getAttribute('fo:text-align'));
273 2
            }
274 2
        }
275
        
276 3
        if ($nodeStyle->nodeName == 'text:list-style') {
277 2
            $arrayListStyle = array();
278 2
            foreach ($this->oXMLReader->getElements('text:list-level-style-bullet', $nodeStyle) as $oNodeListLevel) {
279 2
                $oAlignment = new Alignment();
280 2
                $oBullet = new Bullet();
281 2
                $oBullet->setBulletType(Bullet::TYPE_NONE);
282 2
                if ($oNodeListLevel->hasAttribute('text:level')) {
283 2
                    $oAlignment->setLevel((int) $oNodeListLevel->getAttribute('text:level') - 1);
284 2
                }
285 2
                if ($oNodeListLevel->hasAttribute('text:bullet-char')) {
286 2
                    $oBullet->setBulletChar($oNodeListLevel->getAttribute('text:bullet-char'));
287 2
                    $oBullet->setBulletType(Bullet::TYPE_BULLET);
288 2
                }
289
                
290 2
                $oNodeListProperties = $this->oXMLReader->getElement('style:list-level-properties', $oNodeListLevel);
291 2
                if ($oNodeListProperties) {
292 2
                    if ($oNodeListProperties->hasAttribute('text:min-label-width')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
293 2
                        $oAlignment->setIndent((int)round(CommonDrawing::centimetersToPixels(substr($oNodeListProperties->getAttribute('text:min-label-width'), 0, -2))));
294 2
                    }
295 2
                    if ($oNodeListProperties->hasAttribute('text:space-before')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
296 2
                        $iSpaceBefore = CommonDrawing::centimetersToPixels(substr($oNodeListProperties->getAttribute('text:space-before'), 0, -2));
297 2
                        $iMarginLeft = $iSpaceBefore + $oAlignment->getIndent();
298 2
                        $oAlignment->setMarginLeft($iMarginLeft);
299 2
                    }
300 2
                }
301 2
                $oNodeTextProperties = $this->oXMLReader->getElement('style:text-properties', $oNodeListLevel);
302 2
                if ($oNodeTextProperties) {
303 2
                    if ($oNodeTextProperties->hasAttribute('fo:font-family')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
304 2
                        $oBullet->setBulletFont($oNodeTextProperties->getAttribute('fo:font-family'));
305 2
                    }
306 2
                }
307
                
308 2
                $arrayListStyle[$oAlignment->getLevel()] = array(
309 2
                    'alignment' => $oAlignment,
310 2
                    'bullet' => $oBullet,
311
                );
312 2
            }
313 2
        }
314
        
315 3
        $this->arrayStyles[$keyStyle] = array(
316 3
            'alignment' => isset($oAlignment) ? $oAlignment : null,
317 3
            'background' => isset($oBackground) ? $oBackground : null,
318 3
            'font' => isset($oFont) ? $oFont : null,
319 3
            'shadow' => isset($oShadow) ? $oShadow : null,
320 3
            'listStyle' => isset($arrayListStyle) ? $arrayListStyle : null,
321
        );
322
        
323 3
        return true;
324
    }
325
326
    /**
327
     * Read Slide
328
     *
329
     * @param \DOMElement $nodeSlide
330
     */
331 3
    protected function loadSlide(\DOMElement $nodeSlide)
332
    {
333
        // Core
334 3
        $this->oPhpPresentation->createSlide();
335 3
        $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1);
336 3
        if ($nodeSlide->hasAttribute('draw:name')) {
337 3
            $this->oPhpPresentation->getActiveSlide()->setName($nodeSlide->getAttribute('draw:name'));
338 3
        }
339 3
        if ($nodeSlide->hasAttribute('draw:style-name')) {
340 3
            $keyStyle = $nodeSlide->getAttribute('draw:style-name');
341 3
            if (isset($this->arrayStyles[$keyStyle])) {
342 3
                $this->oPhpPresentation->getActiveSlide()->setBackground($this->arrayStyles[$keyStyle]['background']);
343 3
            }
344 3
        }
345 3
        foreach ($this->oXMLReader->getElements('draw:frame', $nodeSlide) as $oNodeFrame) {
346 3
            if ($this->oXMLReader->getElement('draw:image', $oNodeFrame)) {
347 2
                $this->loadShapeDrawing($oNodeFrame);
348 2
                continue;
349
            }
350 3
            if ($this->oXMLReader->getElement('draw:text-box', $oNodeFrame)) {
351 3
                $this->loadShapeRichText($oNodeFrame);
352 3
                continue;
353
            }
354 3
        }
355 3
        return true;
356
    }
357
    
358
    /**
359
     * Read Shape Drawing
360
     *
361
     * @param \DOMElement $oNodeFrame
362
     */
363 2
    protected function loadShapeDrawing(\DOMElement $oNodeFrame)
364
    {
365
        // Core
366 2
        $oShape = new Gd();
367 2
        $oShape->getShadow()->setVisible(false);
368
369 2
        $oNodeImage = $this->oXMLReader->getElement('draw:image', $oNodeFrame);
370 2
        if ($oNodeImage) {
371 2
            if ($oNodeImage->hasAttribute('xlink:href')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
372 2
                $sFilename = $oNodeImage->getAttribute('xlink:href');
373
                // svm = StarView Metafile
374 2
                if (pathinfo($sFilename, PATHINFO_EXTENSION) == 'svm') {
375 1
                    return;
376
                }
377 2
                $imageFile = $this->oZip->getFromName($sFilename);
378 2
                if (!empty($imageFile)) {
379 2
                    $oShape->setImageResource(imagecreatefromstring($imageFile));
380 2
                }
381 2
            }
382 2
        }
383
        
384 2
        $oShape->setName($oNodeFrame->hasAttribute('draw:name') ? $oNodeFrame->getAttribute('draw:name') : '');
385 2
        $oShape->setDescription($oNodeFrame->hasAttribute('draw:name') ? $oNodeFrame->getAttribute('draw:name') : '');
386 2
        $oShape->setResizeProportional(false);
387 2
        $oShape->setWidth($oNodeFrame->hasAttribute('svg:width') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:width'), 0, -2))) : '');
388 2
        $oShape->setHeight($oNodeFrame->hasAttribute('svg:height') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:height'), 0, -2))) : '');
389 2
        $oShape->setResizeProportional(true);
390 2
        $oShape->setOffsetX($oNodeFrame->hasAttribute('svg:x') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:x'), 0, -2))) : '');
391 2
        $oShape->setOffsetY($oNodeFrame->hasAttribute('svg:y') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:y'), 0, -2))) : '');
392
        
393 2
        if ($oNodeFrame->hasAttribute('draw:style-name')) {
394 2
            $keyStyle = $oNodeFrame->getAttribute('draw:style-name');
395 2
            if (isset($this->arrayStyles[$keyStyle])) {
396 2
                $oShape->setShadow($this->arrayStyles[$keyStyle]['shadow']);
397 2
            }
398 2
        }
399
        
400 2
        $this->oPhpPresentation->getActiveSlide()->addShape($oShape);
401 2
    }
402
403
    /**
404
     * Read Shape RichText
405
     *
406
     * @param \DOMElement $oNodeFrame
407
     */
408 3
    protected function loadShapeRichText(\DOMElement $oNodeFrame)
409
    {
410
        // Core
411 3
        $oShape = $this->oPhpPresentation->getActiveSlide()->createRichTextShape();
412 3
        $oShape->setParagraphs(array());
413
        
414 3
        $oShape->setWidth($oNodeFrame->hasAttribute('svg:width') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:width'), 0, -2))) : '');
415 3
        $oShape->setHeight($oNodeFrame->hasAttribute('svg:height') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:height'), 0, -2))) : '');
416 3
        $oShape->setOffsetX($oNodeFrame->hasAttribute('svg:x') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:x'), 0, -2))) : '');
417 3
        $oShape->setOffsetY($oNodeFrame->hasAttribute('svg:y') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:y'), 0, -2))) : '');
418
        
419 3
        foreach ($this->oXMLReader->getElements('draw:text-box/*', $oNodeFrame) as $oNodeParagraph) {
420 2
            $this->levelParagraph = 0;
421 2
            if ($oNodeParagraph->nodeName == 'text:p') {
422 2
                $this->readParagraph($oShape, $oNodeParagraph);
423 2
            }
424 2
            if ($oNodeParagraph->nodeName == 'text:list') {
425 1
                $this->readList($oShape, $oNodeParagraph);
426 1
            }
427 3
        }
428
        
429 3
        if (count($oShape->getParagraphs()) > 0) {
430 2
            $oShape->setActiveParagraph(0);
431 2
        }
432 3
    }
433
    
434
    protected $levelParagraph = 0;
435
    
436
    /**
437
     * Read Paragraph
438
     * @param RichText $oShape
439
     * @param \DOMElement $oNodeParent
440
     */
441 2
    protected function readParagraph(RichText $oShape, \DOMElement $oNodeParent)
442
    {
443 2
        $oParagraph = $oShape->createParagraph();
444 2
        $oDomList = $this->oXMLReader->getElements('text:span', $oNodeParent);
445 2
        if ($oDomList->length == 0) {
446 1
            $this->readParagraphItem($oParagraph, $oNodeParent);
447 1
        } else {
448 1
            foreach ($oDomList as $oNodeRichTextElement) {
449 1
                $this->readParagraphItem($oParagraph, $oNodeRichTextElement);
450 1
            }
451
        }
452 2
    }
453
    
454
    /**
455
     * Read Paragraph Item
456
     * @param RichText $oShape
0 ignored issues
show
Bug introduced by
There is no parameter named $oShape. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
457
     * @param \DOMElement $oNodeParent
458
     */
459 2
    protected function readParagraphItem(Paragraph $oParagraph, \DOMElement $oNodeParent)
460
    {
461 2
        if ($this->oXMLReader->elementExists('text:line-break', $oNodeParent)) {
462 1
            $oParagraph->createBreak();
463 1
        } else {
464 2
            $oTextRun = $oParagraph->createTextRun();
465 2
            if ($oNodeParent->hasAttribute('text:style-name')) {
466 1
                $keyStyle = $oNodeParent->getAttribute('text:style-name');
467 1
                if (isset($this->arrayStyles[$keyStyle])) {
468 1
                    $oTextRun->setFont($this->arrayStyles[$keyStyle]['font']);
469 1
                }
470 1
            }
471 2
            if ($oTextRunLink = $this->oXMLReader->getElement('text:a', $oNodeParent)) {
472 1
                $oTextRun->setText($oTextRunLink->nodeValue);
473 1
                if ($oTextRunLink->hasAttribute('xlink:href')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
474 1
                    $oTextRun->getHyperlink()->setUrl($oTextRunLink->getAttribute('xlink:href'));
475 1
                }
476 1
            } else {
477 2
                $oTextRun->setText($oNodeParent->nodeValue);
478
            }
479
        }
480 2
    }
481
482
    /**
483
     * Read List
484
     *
485
     * @param RichText $oShape
486
     * @param \DOMElement $oNodeParent
487
     */
488 1
    protected function readList(RichText $oShape, \DOMElement $oNodeParent)
489
    {
490 1
        foreach ($this->oXMLReader->getElements('text:list-item/*', $oNodeParent) as $oNodeListItem) {
491 1
            if ($oNodeListItem->nodeName == 'text:p') {
492 1
                $this->readListItem($oShape, $oNodeListItem, $oNodeParent);
493 1
            }
494 1
            if ($oNodeListItem->nodeName == 'text:list') {
495 1
                $this->levelParagraph++;
496 1
                $this->readList($oShape, $oNodeListItem);
497 1
                $this->levelParagraph--;
498 1
            }
499 1
        }
500 1
    }
501
    
502
    /**
503
     * Read List Item
504
     * @param RichText $oShape
505
     * @param \DOMElement $oNodeParent
506
     * @param \DOMElement $oNodeParagraph
507
     */
508 1
    protected function readListItem(RichText $oShape, \DOMElement $oNodeParent, \DOMElement $oNodeParagraph)
509
    {
510 1
        $oParagraph = $oShape->createParagraph();
511 1
        if ($oNodeParagraph->hasAttribute('text:style-name')) {
512 1
            $keyStyle = $oNodeParagraph->getAttribute('text:style-name');
513 1
            if (isset($this->arrayStyles[$keyStyle]) && !empty($this->arrayStyles[$keyStyle]['listStyle'])) {
514 1
                $oParagraph->setAlignment($this->arrayStyles[$keyStyle]['listStyle'][$this->levelParagraph]['alignment']);
515 1
                $oParagraph->setBulletStyle($this->arrayStyles[$keyStyle]['listStyle'][$this->levelParagraph]['bullet']);
516 1
            }
517 1
        }
518 1
        foreach ($this->oXMLReader->getElements('text:span', $oNodeParent) as $oNodeRichTextElement) {
519 1
            $this->readParagraphItem($oParagraph, $oNodeRichTextElement);
520 1
        }
521 1
    }
522
523
    /**
524
     * Load file 'styles.xml'
525
     */
526 3
    protected function loadStylesFile()
527
    {
528 3
        foreach ($this->oXMLReader->getElements('/office:document-styles/office:styles/*') as $oElement) {
529 3
            if ($oElement->nodeName == 'draw:fill-image') {
530
                $this->arrayCommonStyles[$oElement->getAttribute('draw:name')] = array(
531
                    'type' => 'image',
532
                    'path' => $oElement->hasAttribute('xlink:href') ? $oElement->getAttribute('xlink:href') : null
533
                );
534
            }
535 3
        }
536 3
    }
537
}
538