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