Completed
Push — develop ( e67d8e...ee77db )
by Franck
15s
created

ODPresentation::loadDocumentProperties()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 23
cts 23
cp 1
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 20
nc 4
nop 0
crap 4
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\Fill;
31
use PhpOffice\PhpPresentation\Style\Font;
32
use PhpOffice\PhpPresentation\Style\Shadow;
33
use PhpOffice\PhpPresentation\Style\Alignment;
34
35
/**
36
 * Serialized format reader
37
 */
38
class ODPresentation implements ReaderInterface
39
{
40
    /**
41
     * Output Object
42
     * @var PhpPresentation
43
     */
44
    protected $oPhpPresentation;
45
    /**
46
     * Output Object
47
     * @var \ZipArchive
48
     */
49
    protected $oZip;
50
    /**
51
     * @var array[]
52
     */
53
    protected $arrayStyles = array();
54
    /**
55
     * @var array[]
56
     */
57
    protected $arrayCommonStyles = array();
58
    /**
59
     * @var \PhpOffice\Common\XMLReader
60
     */
61
    protected $oXMLReader;
62
63
    /**
64
     * Can the current \PhpOffice\PhpPresentation\Reader\ReaderInterface read the file?
65
     *
66
     * @param  string $pFilename
67
     * @throws \Exception
68
     * @return boolean
69
     */
70 2
    public function canRead($pFilename)
71
    {
72 2
        return $this->fileSupportsUnserializePhpPresentation($pFilename);
73
    }
74
75
    /**
76
     * Does a file support UnserializePhpPresentation ?
77
     *
78
     * @param  string    $pFilename
79
     * @throws \Exception
80
     * @return boolean
81
     */
82 8
    public function fileSupportsUnserializePhpPresentation($pFilename = '')
83
    {
84
        // Check if file exists
85 8
        if (!file_exists($pFilename)) {
86 2
            throw new \Exception("Could not open " . $pFilename . " for reading! File does not exist.");
87
        }
88
        
89 6
        $oZip = new ZipArchive();
90
        // Is it a zip ?
91 6
        if ($oZip->open($pFilename) === true) {
92
            // Is it an OpenXML Document ?
93
            // Is it a Presentation ?
94 4
            if (is_array($oZip->statName('META-INF/manifest.xml')) && is_array($oZip->statName('mimetype')) && $oZip->getFromName('mimetype') == 'application/vnd.oasis.opendocument.presentation') {
95 4
                return true;
96
            }
97 1
        }
98 3
        return false;
99
    }
100
101
    /**
102
     * Loads PhpPresentation Serialized file
103
     *
104
     * @param  string        $pFilename
105
     * @return \PhpOffice\PhpPresentation\PhpPresentation
106
     * @throws \Exception
107
     */
108 5
    public function load($pFilename)
109
    {
110
        // Unserialize... First make sure the file supports it!
111 5
        if (!$this->fileSupportsUnserializePhpPresentation($pFilename)) {
112 1
            throw new \Exception("Invalid file format for PhpOffice\PhpPresentation\Reader\ODPresentation: " . $pFilename . ".");
113
        }
114
115 3
        return $this->loadFile($pFilename);
116
    }
117
118
    /**
119
     * Load PhpPresentation Serialized file
120
     *
121
     * @param  string        $pFilename
122
     * @return \PhpOffice\PhpPresentation\PhpPresentation
123
     */
124 3
    protected function loadFile($pFilename)
125
    {
126 3
        $this->oPhpPresentation = new PhpPresentation();
127 3
        $this->oPhpPresentation->removeSlideByIndex();
128
        
129 3
        $this->oZip = new ZipArchive();
130 3
        $this->oZip->open($pFilename);
131
        
132 3
        $this->oXMLReader = new XMLReader();
133 3
        if ($this->oXMLReader->getDomFromZip($pFilename, 'meta.xml') !== false) {
134 3
            $this->loadDocumentProperties();
135 3
        }
136 3
        $this->oXMLReader = new XMLReader();
137 3
        if ($this->oXMLReader->getDomFromZip($pFilename, 'styles.xml') !== false) {
138 3
            $this->loadStylesFile();
139 3
        }
140 3
        $this->oXMLReader = new XMLReader();
141 3
        if ($this->oXMLReader->getDomFromZip($pFilename, 'content.xml') !== false) {
142 3
            $this->loadSlides();
143 3
        }
144
145 3
        return $this->oPhpPresentation;
146
    }
147
    
148
    /**
149
     * Read Document Properties
150
     */
151 3
    protected function loadDocumentProperties()
152
    {
153
        $arrayProperties = array(
154 3
            '/office:document-meta/office:meta/meta:initial-creator' => 'setCreator',
155 3
            '/office:document-meta/office:meta/dc:creator' => 'setLastModifiedBy',
156 3
            '/office:document-meta/office:meta/dc:title' => 'setTitle',
157 3
            '/office:document-meta/office:meta/dc:description' => 'setDescription',
158 3
            '/office:document-meta/office:meta/dc:subject' => 'setSubject',
159 3
            '/office:document-meta/office:meta/meta:keyword' => 'setKeywords',
160 3
            '/office:document-meta/office:meta/meta:creation-date' => 'setCreated',
161 3
            '/office:document-meta/office:meta/dc:date' => 'setModified',
162 3
        );
163 3
        $oProperties = $this->oPhpPresentation->getDocumentProperties();
164 3
        foreach ($arrayProperties as $path => $property) {
165 3
            $oElement = $this->oXMLReader->getElement($path);
166 3
            if ($oElement instanceof \DOMElement) {
167 3
                if (in_array($property, array('setCreated', 'setModified'))) {
168 3
                    $oDateTime = new \DateTime();
169 3
                    $oDateTime->createFromFormat(\DateTime::W3C, $oElement->nodeValue);
170 3
                    $oProperties->{$property}($oDateTime->getTimestamp());
171 3
                } else {
172 1
                    $oProperties->{$property}($oElement->nodeValue);
173
                }
174 3
            }
175 3
        }
176 3
    }
177
    
178
    /**
179
     * Extract all slides
180
     */
181 3
    protected function loadSlides()
182
    {
183 3
        foreach ($this->oXMLReader->getElements('/office:document-content/office:automatic-styles/*') as $oElement) {
184 3
            if ($oElement->hasAttribute('style:name')) {
185 3
                $this->loadStyle($oElement);
186 3
            }
187 3
        }
188 3
        foreach ($this->oXMLReader->getElements('/office:document-content/office:body/office:presentation/draw:page') as $oElement) {
189 3
            if ($oElement->nodeName == 'draw:page') {
190 3
                $this->loadSlide($oElement);
191 3
            }
192 3
        }
193 3
    }
194
    
195
    /**
196
     * Extract style
197
     * @param \DOMElement $nodeStyle
198
     */
199 3
    protected function loadStyle(\DOMElement $nodeStyle)
200
    {
201 3
        $keyStyle = $nodeStyle->getAttribute('style:name');
202
203 3
        $nodeDrawingPageProps = $this->oXMLReader->getElement('style:drawing-page-properties', $nodeStyle);
204 3
        if ($nodeDrawingPageProps instanceof \DOMElement) {
205
            // Read Background Color
206 3
            if ($nodeDrawingPageProps->hasAttribute('draw:fill-color') && $nodeDrawingPageProps->getAttribute('draw:fill') == 'solid') {
207
                $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\Color();
208
                $oColor = new Color();
209
                $oColor->setRGB(substr($nodeDrawingPageProps->getAttribute('draw:fill-color'), -6));
210
                $oBackground->setColor($oColor);
211
            }
212
            // Read Background Image
213 3
            if ($nodeDrawingPageProps->getAttribute('draw:fill') == 'bitmap' && $nodeDrawingPageProps->hasAttribute('draw:fill-image-name')) {
214
                $nameStyle = $nodeDrawingPageProps->getAttribute('draw:fill-image-name');
215
                if (!empty($this->arrayCommonStyles[$nameStyle]) && $this->arrayCommonStyles[$nameStyle]['type'] == 'image' && !empty($this->arrayCommonStyles[$nameStyle]['path'])) {
216
                    $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderODPBkg');
217
                    $contentImg = $this->oZip->getFromName($this->arrayCommonStyles[$nameStyle]['path']);
218
                    file_put_contents($tmpBkgImg, $contentImg);
219
220
                    $oBackground = new Image();
221
                    $oBackground->setPath($tmpBkgImg);
222
                }
223
            }
224 3
        }
225
226 3
        $nodeGraphicProps = $this->oXMLReader->getElement('style:graphic-properties', $nodeStyle);
227 3
        if ($nodeGraphicProps instanceof \DOMElement) {
228
            // Read Shadow
229 3
            if ($nodeGraphicProps->hasAttribute('draw:shadow') && $nodeGraphicProps->getAttribute('draw:shadow') == 'visible') {
230 1
                $oShadow = new Shadow();
231 1
                $oShadow->setVisible(true);
232 1
                if ($nodeGraphicProps->hasAttribute('draw:shadow-color')) {
233 1
                    $oShadow->getColor()->setRGB(substr($nodeGraphicProps->getAttribute('draw:shadow-color'), -6));
234 1
                }
235 1
                if ($nodeGraphicProps->hasAttribute('draw:shadow-opacity')) {
236 1
                    $oShadow->setAlpha(100 - (int)substr($nodeGraphicProps->getAttribute('draw:shadow-opacity'), 0, -1));
237 1
                }
238 1
                if ($nodeGraphicProps->hasAttribute('draw:shadow-offset-x') && $nodeGraphicProps->hasAttribute('draw:shadow-offset-y')) {
239 1
                    $offsetX = substr($nodeGraphicProps->getAttribute('draw:shadow-offset-x'), 0, -2);
240 1
                    $offsetY = substr($nodeGraphicProps->getAttribute('draw:shadow-offset-y'), 0, -2);
241 1
                    $distance = 0;
242 1
                    if ($offsetX != 0) {
243 1
                        $distance = ($offsetX < 0 ? $offsetX * -1 : $offsetX);
244 1
                    } elseif ($offsetY != 0) {
245
                        $distance = ($offsetY < 0 ? $offsetY * -1 : $offsetY);
246
                    }
247 1
                    $oShadow->setDirection(rad2deg(atan2($offsetY, $offsetX)));
248 1
                    $oShadow->setDistance(CommonDrawing::centimetersToPixels($distance));
249 1
                }
250 1
            }
251
            // Read Fill
252 3
            if ($nodeGraphicProps->hasAttribute('draw:fill')) {
253 1
                $value = $nodeGraphicProps->getAttribute('draw:fill');
254
255
                switch ($value) {
256 1
                    case 'none':
257 1
                        $oFill = new Fill();
258 1
                        $oFill->setFillType(Fill::FILL_NONE);
259 1
                        break;
260
                    case 'solid':
261
                        $oFill = new Fill();
262
                        $oFill->setFillType(Fill::FILL_SOLID);
263
                        if ($nodeGraphicProps->hasAttribute('draw:fill-color')) {
264
                            $oColor = new Color();
265
                            $oColor->setRGB(substr($nodeGraphicProps->getAttribute('draw:fill-color'), 1));
266
                            $oFill->setStartColor($oColor);
267
                        }
268
                        break;
269
                }
270 1
            }
271 3
        }
272
        
273 3
        $nodeTextProperties = $this->oXMLReader->getElement('style:text-properties', $nodeStyle);
274 3
        if ($nodeTextProperties instanceof \DOMElement) {
275 1
            $oFont = new Font();
276 1
            if ($nodeTextProperties->hasAttribute('fo:color')) {
277 1
                $oFont->getColor()->setRGB(substr($nodeTextProperties->getAttribute('fo:color'), -6));
278 1
            }
279 1
            if ($nodeTextProperties->hasAttribute('fo:font-family')) {
280 1
                $oFont->setName($nodeTextProperties->getAttribute('fo:font-family'));
281 1
            }
282 1
            if ($nodeTextProperties->hasAttribute('fo:font-weight') && $nodeTextProperties->getAttribute('fo:font-weight') == 'bold') {
283 1
                $oFont->setBold(true);
284 1
            }
285 1
            if ($nodeTextProperties->hasAttribute('fo:font-size')) {
286 1
                $oFont->setSize(substr($nodeTextProperties->getAttribute('fo:font-size'), 0, -2));
287 1
            }
288 1
        }
289
290 3
        $nodeParagraphProps = $this->oXMLReader->getElement('style:paragraph-properties', $nodeStyle);
291 3
        if ($nodeParagraphProps instanceof \DOMElement) {
292 2
            $oAlignment = new Alignment();
293 2
            if ($nodeParagraphProps->hasAttribute('fo:text-align')) {
294 2
                $oAlignment->setHorizontal($nodeParagraphProps->getAttribute('fo:text-align'));
295 2
            }
296 2
        }
297
        
298 3
        if ($nodeStyle->nodeName == 'text:list-style') {
299 2
            $arrayListStyle = array();
300 2
            foreach ($this->oXMLReader->getElements('text:list-level-style-bullet', $nodeStyle) as $oNodeListLevel) {
301 2
                $oAlignment = new Alignment();
302 2
                $oBullet = new Bullet();
303 2
                $oBullet->setBulletType(Bullet::TYPE_NONE);
304 2
                if ($oNodeListLevel->hasAttribute('text:level')) {
305 2
                    $oAlignment->setLevel((int) $oNodeListLevel->getAttribute('text:level') - 1);
306 2
                }
307 2
                if ($oNodeListLevel->hasAttribute('text:bullet-char')) {
308 2
                    $oBullet->setBulletChar($oNodeListLevel->getAttribute('text:bullet-char'));
309 2
                    $oBullet->setBulletType(Bullet::TYPE_BULLET);
310 2
                }
311
                
312 2
                $oNodeListProperties = $this->oXMLReader->getElement('style:list-level-properties', $oNodeListLevel);
313 2
                if ($oNodeListProperties instanceof \DOMElement) {
314 2
                    if ($oNodeListProperties->hasAttribute('text:min-label-width')) {
315 2
                        $oAlignment->setIndent((int)round(CommonDrawing::centimetersToPixels(substr($oNodeListProperties->getAttribute('text:min-label-width'), 0, -2))));
316 2
                    }
317 2
                    if ($oNodeListProperties->hasAttribute('text:space-before')) {
318 2
                        $iSpaceBefore = CommonDrawing::centimetersToPixels(substr($oNodeListProperties->getAttribute('text:space-before'), 0, -2));
319 2
                        $iMarginLeft = $iSpaceBefore + $oAlignment->getIndent();
320 2
                        $oAlignment->setMarginLeft($iMarginLeft);
321 2
                    }
322 2
                }
323 2
                $oNodeTextProperties = $this->oXMLReader->getElement('style:text-properties', $oNodeListLevel);
324 2
                if ($oNodeTextProperties instanceof \DOMElement) {
325 2
                    if ($oNodeTextProperties->hasAttribute('fo:font-family')) {
326 2
                        $oBullet->setBulletFont($oNodeTextProperties->getAttribute('fo:font-family'));
327 2
                    }
328 2
                }
329
                
330 2
                $arrayListStyle[$oAlignment->getLevel()] = array(
331 2
                    'alignment' => $oAlignment,
332 2
                    'bullet' => $oBullet,
333
                );
334 2
            }
335 2
        }
336
        
337 3
        $this->arrayStyles[$keyStyle] = array(
338 3
            'alignment' => isset($oAlignment) ? $oAlignment : null,
339 3
            'background' => isset($oBackground) ? $oBackground : null,
340 3
            'fill' => isset($oFill) ? $oFill : null,
341 3
            'font' => isset($oFont) ? $oFont : null,
342 3
            'shadow' => isset($oShadow) ? $oShadow : null,
343 3
            'listStyle' => isset($arrayListStyle) ? $arrayListStyle : null,
344
        );
345
        
346 3
        return true;
347
    }
348
349
    /**
350
     * Read Slide
351
     *
352
     * @param \DOMElement $nodeSlide
353
     */
354 3
    protected function loadSlide(\DOMElement $nodeSlide)
355
    {
356
        // Core
357 3
        $this->oPhpPresentation->createSlide();
358 3
        $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1);
359 3
        if ($nodeSlide->hasAttribute('draw:name')) {
360 3
            $this->oPhpPresentation->getActiveSlide()->setName($nodeSlide->getAttribute('draw:name'));
361 3
        }
362 3
        if ($nodeSlide->hasAttribute('draw:style-name')) {
363 3
            $keyStyle = $nodeSlide->getAttribute('draw:style-name');
364 3
            if (isset($this->arrayStyles[$keyStyle])) {
365 3
                $this->oPhpPresentation->getActiveSlide()->setBackground($this->arrayStyles[$keyStyle]['background']);
366 3
            }
367 3
        }
368 3
        foreach ($this->oXMLReader->getElements('draw:frame', $nodeSlide) as $oNodeFrame) {
369 3
            if ($this->oXMLReader->getElement('draw:image', $oNodeFrame)) {
370 2
                $this->loadShapeDrawing($oNodeFrame);
371 2
                continue;
372
            }
373 3
            if ($this->oXMLReader->getElement('draw:text-box', $oNodeFrame)) {
374 3
                $this->loadShapeRichText($oNodeFrame);
375 3
                continue;
376
            }
377 3
        }
378 3
        return true;
379
    }
380
    
381
    /**
382
     * Read Shape Drawing
383
     *
384
     * @param \DOMElement $oNodeFrame
385
     */
386 2
    protected function loadShapeDrawing(\DOMElement $oNodeFrame)
387
    {
388
        // Core
389 2
        $oShape = new Gd();
390 2
        $oShape->getShadow()->setVisible(false);
391
392 2
        $oNodeImage = $this->oXMLReader->getElement('draw:image', $oNodeFrame);
393 2
        if ($oNodeImage instanceof \DOMElement) {
394 2
            if ($oNodeImage->hasAttribute('xlink:href')) {
395 2
                $sFilename = $oNodeImage->getAttribute('xlink:href');
396
                // svm = StarView Metafile
397 2
                if (pathinfo($sFilename, PATHINFO_EXTENSION) == 'svm') {
398 1
                    return;
399
                }
400 2
                $imageFile = $this->oZip->getFromName($sFilename);
401 2
                if (!empty($imageFile)) {
402 2
                    $oShape->setImageResource(imagecreatefromstring($imageFile));
403 2
                }
404 2
            }
405 2
        }
406
        
407 2
        $oShape->setName($oNodeFrame->hasAttribute('draw:name') ? $oNodeFrame->getAttribute('draw:name') : '');
408 2
        $oShape->setDescription($oNodeFrame->hasAttribute('draw:name') ? $oNodeFrame->getAttribute('draw:name') : '');
409 2
        $oShape->setResizeProportional(false);
410 2
        $oShape->setWidth($oNodeFrame->hasAttribute('svg:width') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:width'), 0, -2))) : '');
411 2
        $oShape->setHeight($oNodeFrame->hasAttribute('svg:height') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:height'), 0, -2))) : '');
412 2
        $oShape->setResizeProportional(true);
413 2
        $oShape->setOffsetX($oNodeFrame->hasAttribute('svg:x') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:x'), 0, -2))) : '');
414 2
        $oShape->setOffsetY($oNodeFrame->hasAttribute('svg:y') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:y'), 0, -2))) : '');
415
        
416 2
        if ($oNodeFrame->hasAttribute('draw:style-name')) {
417 2
            $keyStyle = $oNodeFrame->getAttribute('draw:style-name');
418 2
            if (isset($this->arrayStyles[$keyStyle])) {
419 2
                $oShape->setShadow($this->arrayStyles[$keyStyle]['shadow']);
420 2
                $oShape->setFill($this->arrayStyles[$keyStyle]['fill']);
421 2
            }
422 2
        }
423
        
424 2
        $this->oPhpPresentation->getActiveSlide()->addShape($oShape);
425 2
    }
426
427
    /**
428
     * Read Shape RichText
429
     *
430
     * @param \DOMElement $oNodeFrame
431
     */
432 3
    protected function loadShapeRichText(\DOMElement $oNodeFrame)
433
    {
434
        // Core
435 3
        $oShape = $this->oPhpPresentation->getActiveSlide()->createRichTextShape();
436 3
        $oShape->setParagraphs(array());
437
        
438 3
        $oShape->setWidth($oNodeFrame->hasAttribute('svg:width') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:width'), 0, -2))) : '');
439 3
        $oShape->setHeight($oNodeFrame->hasAttribute('svg:height') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:height'), 0, -2))) : '');
440 3
        $oShape->setOffsetX($oNodeFrame->hasAttribute('svg:x') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:x'), 0, -2))) : '');
441 3
        $oShape->setOffsetY($oNodeFrame->hasAttribute('svg:y') ? (int)round(CommonDrawing::centimetersToPixels(substr($oNodeFrame->getAttribute('svg:y'), 0, -2))) : '');
442
        
443 3
        foreach ($this->oXMLReader->getElements('draw:text-box/*', $oNodeFrame) as $oNodeParagraph) {
444 2
            $this->levelParagraph = 0;
445 2
            if ($oNodeParagraph->nodeName == 'text:p') {
446 2
                $this->readParagraph($oShape, $oNodeParagraph);
447 2
            }
448 2
            if ($oNodeParagraph->nodeName == 'text:list') {
449 1
                $this->readList($oShape, $oNodeParagraph);
450 1
            }
451 3
        }
452
        
453 3
        if (count($oShape->getParagraphs()) > 0) {
454 2
            $oShape->setActiveParagraph(0);
455 2
        }
456 3
    }
457
    
458
    protected $levelParagraph = 0;
459
    
460
    /**
461
     * Read Paragraph
462
     * @param RichText $oShape
463
     * @param \DOMElement $oNodeParent
464
     */
465 2
    protected function readParagraph(RichText $oShape, \DOMElement $oNodeParent)
466
    {
467 2
        $oParagraph = $oShape->createParagraph();
468 2
        $oDomList = $this->oXMLReader->getElements('text:span', $oNodeParent);
469 2
        $oDomTextNodes = $this->oXMLReader->getElements('text()', $oNodeParent);
470 2
        foreach ($oDomTextNodes as $oDomTextNode) {
471 2
            if (trim($oDomTextNode->nodeValue) != '') {
472 1
                $oTextRun = $oParagraph->createTextRun();
473 1
                $oTextRun->setText(trim($oDomTextNode->nodeValue));
474 1
            }
475 2
        }
476 2
        foreach ($oDomList as $oNodeRichTextElement) {
477 1
            $this->readParagraphItem($oParagraph, $oNodeRichTextElement);
478 2
        }
479 2
    }
480
    
481
    /**
482
     * Read Paragraph Item
483
     * @param Paragraph $oParagraph
484
     * @param \DOMElement $oNodeParent
485
     */
486 1
    protected function readParagraphItem(Paragraph $oParagraph, \DOMElement $oNodeParent)
487
    {
488 1
        if ($this->oXMLReader->elementExists('text:line-break', $oNodeParent)) {
489 1
            $oParagraph->createBreak();
490 1
        } else {
491 1
            $oTextRun = $oParagraph->createTextRun();
492 1
            if ($oNodeParent->hasAttribute('text:style-name')) {
493 1
                $keyStyle = $oNodeParent->getAttribute('text:style-name');
494 1
                if (isset($this->arrayStyles[$keyStyle])) {
495 1
                    $oTextRun->setFont($this->arrayStyles[$keyStyle]['font']);
496 1
                }
497 1
            }
498 1
            $oTextRunLink = $this->oXMLReader->getElement('text:a', $oNodeParent);
499 1
            if ($oTextRunLink instanceof \DOMElement) {
500 1
                $oTextRun->setText($oTextRunLink->nodeValue);
501 1
                if ($oTextRunLink->hasAttribute('xlink:href')) {
502 1
                    $oTextRun->getHyperlink()->setUrl($oTextRunLink->getAttribute('xlink:href'));
503 1
                }
504 1
            } else {
505 1
                $oTextRun->setText($oNodeParent->nodeValue);
506
            }
507
        }
508 1
    }
509
510
    /**
511
     * Read List
512
     *
513
     * @param RichText $oShape
514
     * @param \DOMElement $oNodeParent
515
     */
516 1
    protected function readList(RichText $oShape, \DOMElement $oNodeParent)
517
    {
518 1
        foreach ($this->oXMLReader->getElements('text:list-item/*', $oNodeParent) as $oNodeListItem) {
519 1
            if ($oNodeListItem->nodeName == 'text:p') {
520 1
                $this->readListItem($oShape, $oNodeListItem, $oNodeParent);
521 1
            }
522 1
            if ($oNodeListItem->nodeName == 'text:list') {
523 1
                $this->levelParagraph++;
524 1
                $this->readList($oShape, $oNodeListItem);
525 1
                $this->levelParagraph--;
526 1
            }
527 1
        }
528 1
    }
529
    
530
    /**
531
     * Read List Item
532
     * @param RichText $oShape
533
     * @param \DOMElement $oNodeParent
534
     * @param \DOMElement $oNodeParagraph
535
     */
536 1
    protected function readListItem(RichText $oShape, \DOMElement $oNodeParent, \DOMElement $oNodeParagraph)
537
    {
538 1
        $oParagraph = $oShape->createParagraph();
539 1
        if ($oNodeParagraph->hasAttribute('text:style-name')) {
540 1
            $keyStyle = $oNodeParagraph->getAttribute('text:style-name');
541 1
            if (isset($this->arrayStyles[$keyStyle]) && !empty($this->arrayStyles[$keyStyle]['listStyle'])) {
542 1
                $oParagraph->setAlignment($this->arrayStyles[$keyStyle]['listStyle'][$this->levelParagraph]['alignment']);
543 1
                $oParagraph->setBulletStyle($this->arrayStyles[$keyStyle]['listStyle'][$this->levelParagraph]['bullet']);
544 1
            }
545 1
        }
546 1
        foreach ($this->oXMLReader->getElements('text:span', $oNodeParent) as $oNodeRichTextElement) {
547 1
            $this->readParagraphItem($oParagraph, $oNodeRichTextElement);
548 1
        }
549 1
    }
550
551
    /**
552
     * Load file 'styles.xml'
553
     */
554 3
    protected function loadStylesFile()
555
    {
556 3
        foreach ($this->oXMLReader->getElements('/office:document-styles/office:styles/*') as $oElement) {
557 3
            if ($oElement->nodeName == 'draw:fill-image') {
558
                $this->arrayCommonStyles[$oElement->getAttribute('draw:name')] = array(
559
                    'type' => 'image',
560
                    'path' => $oElement->hasAttribute('xlink:href') ? $oElement->getAttribute('xlink:href') : null
561
                );
562
            }
563 3
        }
564 3
    }
565
}
566