Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.31% covered (success)
92.31%
24 / 26
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Serialized
92.31% covered (success)
92.31%
24 / 26
75.00% covered (warning)
75.00%
3 / 4
13.08
0.00% covered (danger)
0.00%
0 / 1
 canRead
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fileSupportsUnserializePhpPresentation
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 load
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 loadSerialized
88.24% covered (warning)
88.24%
15 / 17
0.00% covered (danger)
0.00%
0 / 1
7.08
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 * @see        https://github.com/PHPOffice/PHPPresentation
14 *
15 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16 */
17
18declare(strict_types=1);
19
20namespace PhpOffice\PhpPresentation\Reader;
21
22use PhpOffice\Common\File;
23use PhpOffice\PhpPresentation\Exception\FileNotFoundException;
24use PhpOffice\PhpPresentation\Exception\InvalidFileFormatException;
25use PhpOffice\PhpPresentation\PhpPresentation;
26use PhpOffice\PhpPresentation\Shape\Drawing\AbstractDrawingAdapter;
27use PhpOffice\PhpPresentation\Shape\Drawing\File as DrawingFile;
28use ZipArchive;
29
30/**
31 * Serialized format reader.
32 */
33class Serialized implements ReaderInterface
34{
35    /**
36     * Can the current \PhpOffice\PhpPresentation\Reader\ReaderInterface read the file?
37     */
38    public function canRead(string $pFilename): bool
39    {
40        return $this->fileSupportsUnserializePhpPresentation($pFilename);
41    }
42
43    /**
44     * Does a file support UnserializePhpPresentation ?
45     */
46    public function fileSupportsUnserializePhpPresentation(string $pFilename): bool
47    {
48        // Check if file exists
49        if (!file_exists($pFilename)) {
50            throw new FileNotFoundException($pFilename);
51        }
52
53        // File exists, does it contain PhpPresentation.xml?
54        return File::fileExists("zip://$pFilename#PhpPresentation.xml");
55    }
56
57    /**
58     * Loads PhpPresentation Serialized file.
59     */
60    public function load(string $pFilename): PhpPresentation
61    {
62        // Check if file exists
63        if (!file_exists($pFilename)) {
64            throw new FileNotFoundException($pFilename);
65        }
66
67        // Unserialize... First make sure the file supports it!
68        if (!$this->fileSupportsUnserializePhpPresentation($pFilename)) {
69            throw new InvalidFileFormatException($pFilename, self::class);
70        }
71
72        return $this->loadSerialized($pFilename);
73    }
74
75    /**
76     * Load PhpPresentation Serialized file.
77     */
78    private function loadSerialized(string $pFilename): PhpPresentation
79    {
80        $oArchive = new ZipArchive();
81        if (true !== $oArchive->open($pFilename)) {
82            throw new InvalidFileFormatException($pFilename, self::class);
83        }
84
85        $xmlContent = $oArchive->getFromName('PhpPresentation.xml');
86        if (empty($xmlContent)) {
87            throw new InvalidFileFormatException($pFilename, self::class, 'The file PhpPresentation.xml is malformed');
88        }
89
90        $xmlData = simplexml_load_string($xmlContent);
91        $file = unserialize(base64_decode((string) $xmlData->data));
92
93        // Update media links
94        for ($i = 0; $i < $file->getSlideCount(); ++$i) {
95            foreach ($file->getSlide($i)->getShapeCollection() as $shape) {
96                if ($shape instanceof AbstractDrawingAdapter) {
97                    $imgPath = 'zip://' . $pFilename . '#media/' . $shape->getImageIndex() . '/' . pathinfo($shape->getPath(), PATHINFO_BASENAME);
98                    if ($shape instanceof DrawingFile) {
99                        $shape->setPath($imgPath, false);
100                    } else {
101                        $shape->setPath($imgPath);
102                    }
103                }
104            }
105        }
106
107        $oArchive->close();
108
109        return $file;
110    }
111}