Completed
Pull Request — develop (#178)
by
unknown
09:34
created

TemplateBased   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Test Coverage

Coverage 67.27%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 29
c 1
b 0
f 0
lcom 0
cbo 1
dl 0
loc 180
ccs 74
cts 110
cp 0.6727
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
D __construct() 0 127 22
A cmpMaster() 0 8 3
A absoluteZipPath() 0 21 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\Writer\PowerPoint2007\LayoutPack;
19
20
use PhpOffice\PhpPresentation\Writer\PowerPoint2007\AbstractLayoutPack;
21
22
/**
23
 * \PhpOffice\PhpPresentation\Writer\PowerPoint2007\LayoutPack\TemplateBased
24
 */
25
class TemplateBased extends AbstractLayoutPack
26
{
27
    /**
28
     * \PhpOffice\PhpPresentation\Writer\PowerPoint2007\LayoutPack\TemplateBased
29
     *
30
     * @param string $fileName
31
     * @throws \Exception
32
     */
33 7
    public function __construct($fileName = '')
34
    {
35
        // Check if file exists
36 7
        if (!file_exists($fileName)) {
37
            throw new \Exception("Could not open " . $fileName . " for reading! File does not exist.");
38
        }
39
40
        // Master slide relations
41 7
        $this->masterSlideRels = array();
42
43
        // Theme relations
44 7
        $this->themeRelations = array();
45
46
        // Layout relations
47 7
        $this->layoutRelations = array();
48
49
        // Open package
50 7
        $package = new \ZipArchive;
51 7
        $package->open($fileName);
52
53
        // Read relations and search for officeDocument
54 7
        $relations = simplexml_load_string($package->getFromName("_rels/.rels"));
55 7
        foreach ($relations->Relationship as $rel) {
56 7
            if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") {
57
                // Found office document! Search for master slide...
58 7
                $presentationRels = simplexml_load_string($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/_rels/" . basename($rel["Target"]) . ".rels")));
59 7
                foreach ($presentationRels->Relationship as $presRel) {
60 7
                    if ($presRel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster") {
61
                        // Found slide master!
62 7
                        $slideMasterId         = str_replace('slideMaster', '', basename($presRel["Target"], '.xml'));
63 7
                        $this->masterSlides[] = array(
64 7
                            'masterid' => $slideMasterId,
65 7
                            'body' => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . basename($presRel["Target"])))
66 7
                        );
67
68
                        // Search for theme & slide layouts
69 7
                        $masterRelations = simplexml_load_string($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/_rels/" . basename($presRel["Target"]) . ".rels")));
70 7
                        foreach ($masterRelations->Relationship as $masterRel) {
71 7
                            if ($masterRel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme") {
72
                                // Found theme!
73 7
                                $themeId                     = str_replace('theme', '', basename($masterRel["Target"], '.xml'));
74 7
                                $this->themes[$themeId - 1] = array(
75 7
                                    'masterid' => $slideMasterId,
76 7
                                    'body' => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/" . basename($masterRel["Target"])))
77 7
                                );
78
79
                                // Search for theme relations
80 7
                                $themeRelations = @simplexml_load_string($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/_rels/" . basename($masterRel["Target"]) . ".rels")));
81 7
                                if ($themeRelations && $themeRelations->Relationship) {
82
                                    foreach ($themeRelations->Relationship as $themeRel) {
83
                                        if ($themeRel["Type"] != "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" && $themeRel["Type"] != "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" && $themeRel["Type"] != "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme") {
84
                                            // Theme relation
85
                                            $this->themeRelations[] = array(
86
                                                'masterid' => $slideMasterId,
87
                                                'id' => $themeRel["Id"],
88
                                                'type' => $themeRel["Type"],
89
                                                'contentType' => '',
90
                                                'target' => $themeRel["Target"],
91
                                                'contents' => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/" . dirname($themeRel["Target"]) . "/" . basename($themeRel["Target"])))
92
                                            );
93
                                        }
94
                                    }
95
                                }
96 7
                            } elseif ($masterRel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout") {
97
                                // Found slide layout!
98 7
                                $layoutId  = str_replace('slideLayout', '', basename($masterRel["Target"], '.xml'));
99
                                $layout    = array(
100 7
                                    'id'        => $layoutId,
101 7
                                    'masterid'  => $slideMasterId,
102 7
                                    'name'      => '-unknown-',
103 7
                                    'body'      => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/" . basename($masterRel["Target"])))
104 7
                                );
105 7
                                if (utf8_encode(utf8_decode($layout['body'])) == $layout['body']) {
106 7
                                    $layoutXml = simplexml_load_string($layout['body']);
107 7
                                } else {
108 2
                                    $layoutXml = simplexml_load_string(utf8_encode($layout['body']));
109
                                }
110 7
                                $layoutXml->registerXPathNamespace("p", "http://schemas.openxmlformats.org/presentationml/2006/main");
111 7
                                $slide                     = $layoutXml->xpath('/p:sldLayout/p:cSld');
112 7
                                $layout['name']            = (string) $slide[0]['name'];
113 7
                                $this->layouts[$layoutId] = $layout;
114
115
                                // Search for slide layout relations
116 7
                                $layoutRelations = @simplexml_load_string($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/_rels/" . basename($masterRel["Target"]) . ".rels")));
117 7
                                if ($layoutRelations && $layoutRelations->Relationship) {
118 7
                                    foreach ($layoutRelations->Relationship as $layoutRel) {
119 7
                                        if ($layoutRel["Type"] != "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" && $layoutRel["Type"] != "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" && $layoutRel["Type"] != "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme") {
120
                                            // Layout relation
121
                                            $this->layoutRelations[] = array(
122
                                                'layoutId' => $layoutId,
123
                                                'id' => $layoutRel["Id"],
124
                                                'type' => $layoutRel["Type"],
125
                                                'contentType' => '',
126
                                                'target' => $layoutRel["Target"],
127
                                                'contents' => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/" . dirname($layoutRel["Target"]) . "/" . basename($layoutRel["Target"])))
128
                                            );
129
                                        }
130 7
                                    }
131 7
                                }
132 7
                            } else {
133
                                // Master slide relation
134
                                $this->masterSlideRels[] = array(
135
                                    'masterid' => $slideMasterId,
136
                                    'id' => $masterRel["Id"],
137
                                    'type' => $masterRel["Type"],
138
                                    'contentType' => '',
139
                                    'target' => $masterRel["Target"],
140
                                    'contents' => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/" . basename($masterRel["Target"])))
141
                                );
142
                            }
143 7
                        }
144 7
                    }
145 7
                }
146
147 7
                break;
148
            }
149 7
        }
150
151
        // Sort master slides
152 7
        usort($this->masterSlides, array(
153 7
            "\PhpOffice\PhpPresentation\Writer\PowerPoint2007\LayoutPack\TemplateBased",
154
            "cmpMaster"
155 7
        ));
156
157
        // Close package
158 7
        $package->close();
159 7
    }
160
161
    /**
162
     * Compare master slides
163
     *
164
     * @param array $firstSlide
165
     * @param array $secondSlide
166
     * @return int
167
     */
168
    public static function cmpMaster($firstSlide, $secondSlide)
169
    {
170
        if ($firstSlide['masterid'] == $secondSlide['masterid']) {
171
            return 0;
172
        }
173
174
        return ($firstSlide['masterid'] < $secondSlide['masterid']) ? -1 : 1;
175
    }
176
177
    /**
178
     * Determine absolute zip path
179
     *
180
     * @param  string $path
181
     * @return string
182
     */
183 7
    protected function absoluteZipPath($path)
184
    {
185 7
        $path      = str_replace(array(
186 7
            '/',
187
            '\\'
188 7
        ), DIRECTORY_SEPARATOR, $path);
189 7
        $parts     = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
190 7
        $absolutes = array();
191 7
        foreach ($parts as $part) {
192 7
            if ('.' == $part) {
193
                continue;
194
            }
195 7
            if ('..' == $part) {
196 7
                array_pop($absolutes);
197 7
            } else {
198 7
                $absolutes[] = $part;
199
            }
200 7
        }
201
202 7
        return implode('/', $absolutes);
203
    }
204
}
205