Complex classes like ODPresentation often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ODPresentation, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
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) |
|
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 = '') |
|
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) |
|
117 | |||
118 | /** |
||
119 | * Load PhpPresentation Serialized file |
||
120 | * |
||
121 | * @param string $pFilename |
||
122 | * @return \PhpOffice\PhpPresentation\PhpPresentation |
||
123 | * @throws \Exception |
||
124 | */ |
||
125 | 3 | protected function loadFile($pFilename) |
|
148 | |||
149 | /** |
||
150 | * Read Document Properties |
||
151 | */ |
||
152 | 3 | protected function loadDocumentProperties() |
|
178 | |||
179 | /** |
||
180 | * Extract all slides |
||
181 | */ |
||
182 | 3 | protected function loadSlides() |
|
195 | |||
196 | /** |
||
197 | * Extract style |
||
198 | * @param \DOMElement $nodeStyle |
||
199 | * @return bool |
||
200 | * @throws \Exception |
||
201 | */ |
||
202 | 3 | protected function loadStyle(\DOMElement $nodeStyle) |
|
203 | { |
||
204 | 3 | $keyStyle = $nodeStyle->getAttribute('style:name'); |
|
205 | |||
206 | 3 | $nodeDrawingPageProps = $this->oXMLReader->getElement('style:drawing-page-properties', $nodeStyle); |
|
207 | 3 | if ($nodeDrawingPageProps instanceof \DOMElement) { |
|
208 | // Read Background Color |
||
209 | 3 | if ($nodeDrawingPageProps->hasAttribute('draw:fill-color') && $nodeDrawingPageProps->getAttribute('draw:fill') == 'solid') { |
|
210 | $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\Color(); |
||
211 | $oColor = new Color(); |
||
212 | $oColor->setRGB(substr($nodeDrawingPageProps->getAttribute('draw:fill-color'), -6)); |
||
213 | $oBackground->setColor($oColor); |
||
214 | } |
||
215 | // Read Background Image |
||
216 | 3 | if ($nodeDrawingPageProps->getAttribute('draw:fill') == 'bitmap' && $nodeDrawingPageProps->hasAttribute('draw:fill-image-name')) { |
|
217 | $nameStyle = $nodeDrawingPageProps->getAttribute('draw:fill-image-name'); |
||
218 | if (!empty($this->arrayCommonStyles[$nameStyle]) && $this->arrayCommonStyles[$nameStyle]['type'] == 'image' && !empty($this->arrayCommonStyles[$nameStyle]['path'])) { |
||
219 | $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderODPBkg'); |
||
220 | $contentImg = $this->oZip->getFromName($this->arrayCommonStyles[$nameStyle]['path']); |
||
221 | file_put_contents($tmpBkgImg, $contentImg); |
||
222 | |||
223 | $oBackground = new Image(); |
||
224 | $oBackground->setPath($tmpBkgImg); |
||
225 | } |
||
226 | } |
||
227 | } |
||
228 | |||
229 | 3 | $nodeGraphicProps = $this->oXMLReader->getElement('style:graphic-properties', $nodeStyle); |
|
230 | 3 | if ($nodeGraphicProps instanceof \DOMElement) { |
|
231 | // Read Shadow |
||
232 | 3 | if ($nodeGraphicProps->hasAttribute('draw:shadow') && $nodeGraphicProps->getAttribute('draw:shadow') == 'visible') { |
|
233 | 1 | $oShadow = new Shadow(); |
|
234 | 1 | $oShadow->setVisible(true); |
|
235 | 1 | if ($nodeGraphicProps->hasAttribute('draw:shadow-color')) { |
|
236 | 1 | $oShadow->getColor()->setRGB(substr($nodeGraphicProps->getAttribute('draw:shadow-color'), -6)); |
|
237 | } |
||
238 | 1 | if ($nodeGraphicProps->hasAttribute('draw:shadow-opacity')) { |
|
239 | 1 | $oShadow->setAlpha(100 - (int)substr($nodeGraphicProps->getAttribute('draw:shadow-opacity'), 0, -1)); |
|
240 | } |
||
241 | 1 | if ($nodeGraphicProps->hasAttribute('draw:shadow-offset-x') && $nodeGraphicProps->hasAttribute('draw:shadow-offset-y')) { |
|
242 | 1 | $offsetX = substr($nodeGraphicProps->getAttribute('draw:shadow-offset-x'), 0, -2); |
|
243 | 1 | $offsetY = substr($nodeGraphicProps->getAttribute('draw:shadow-offset-y'), 0, -2); |
|
244 | 1 | $distance = 0; |
|
245 | 1 | if ($offsetX != 0) { |
|
246 | 1 | $distance = ($offsetX < 0 ? $offsetX * -1 : $offsetX); |
|
247 | } elseif ($offsetY != 0) { |
||
248 | $distance = ($offsetY < 0 ? $offsetY * -1 : $offsetY); |
||
249 | } |
||
250 | 1 | $oShadow->setDirection(rad2deg(atan2($offsetY, $offsetX))); |
|
251 | 1 | $oShadow->setDistance(CommonDrawing::centimetersToPixels($distance)); |
|
252 | } |
||
253 | } |
||
254 | // Read Fill |
||
255 | 3 | if ($nodeGraphicProps->hasAttribute('draw:fill')) { |
|
256 | 1 | $value = $nodeGraphicProps->getAttribute('draw:fill'); |
|
257 | |||
258 | 1 | switch ($value) { |
|
259 | 1 | case 'none': |
|
260 | 1 | $oFill = new Fill(); |
|
261 | 1 | $oFill->setFillType(Fill::FILL_NONE); |
|
262 | 1 | break; |
|
263 | case 'solid': |
||
264 | $oFill = new Fill(); |
||
265 | $oFill->setFillType(Fill::FILL_SOLID); |
||
266 | if ($nodeGraphicProps->hasAttribute('draw:fill-color')) { |
||
267 | $oColor = new Color(); |
||
268 | $oColor->setRGB(substr($nodeGraphicProps->getAttribute('draw:fill-color'), 1)); |
||
269 | $oFill->setStartColor($oColor); |
||
270 | } |
||
271 | break; |
||
272 | } |
||
273 | } |
||
274 | } |
||
275 | |||
276 | 3 | $nodeTextProperties = $this->oXMLReader->getElement('style:text-properties', $nodeStyle); |
|
277 | 3 | if ($nodeTextProperties instanceof \DOMElement) { |
|
278 | 1 | $oFont = new Font(); |
|
279 | 1 | if ($nodeTextProperties->hasAttribute('fo:color')) { |
|
280 | 1 | $oFont->getColor()->setRGB(substr($nodeTextProperties->getAttribute('fo:color'), -6)); |
|
281 | } |
||
282 | 1 | if ($nodeTextProperties->hasAttribute('fo:font-family')) { |
|
283 | 1 | $oFont->setName($nodeTextProperties->getAttribute('fo:font-family')); |
|
284 | } |
||
285 | 1 | if ($nodeTextProperties->hasAttribute('fo:font-weight') && $nodeTextProperties->getAttribute('fo:font-weight') == 'bold') { |
|
286 | 1 | $oFont->setBold(true); |
|
287 | } |
||
288 | 1 | if ($nodeTextProperties->hasAttribute('fo:font-size')) { |
|
289 | 1 | $oFont->setSize(substr($nodeTextProperties->getAttribute('fo:font-size'), 0, -2)); |
|
290 | } |
||
291 | } |
||
292 | |||
293 | 3 | $nodeParagraphProps = $this->oXMLReader->getElement('style:paragraph-properties', $nodeStyle); |
|
294 | 3 | if ($nodeParagraphProps instanceof \DOMElement) { |
|
295 | 2 | $oAlignment = new Alignment(); |
|
296 | 2 | if ($nodeParagraphProps->hasAttribute('fo:text-align')) { |
|
297 | 2 | $oAlignment->setHorizontal($nodeParagraphProps->getAttribute('fo:text-align')); |
|
298 | } |
||
299 | } |
||
300 | |||
301 | 3 | if ($nodeStyle->nodeName == 'text:list-style') { |
|
302 | 2 | $arrayListStyle = array(); |
|
303 | 2 | foreach ($this->oXMLReader->getElements('text:list-level-style-bullet', $nodeStyle) as $oNodeListLevel) { |
|
304 | 2 | $oAlignment = new Alignment(); |
|
305 | 2 | $oBullet = new Bullet(); |
|
306 | 2 | $oBullet->setBulletType(Bullet::TYPE_NONE); |
|
307 | 2 | if ($oNodeListLevel->hasAttribute('text:level')) { |
|
308 | 2 | $oAlignment->setLevel((int) $oNodeListLevel->getAttribute('text:level') - 1); |
|
309 | } |
||
310 | 2 | if ($oNodeListLevel->hasAttribute('text:bullet-char')) { |
|
311 | 2 | $oBullet->setBulletChar($oNodeListLevel->getAttribute('text:bullet-char')); |
|
312 | 2 | $oBullet->setBulletType(Bullet::TYPE_BULLET); |
|
313 | } |
||
314 | |||
315 | 2 | $oNodeListProperties = $this->oXMLReader->getElement('style:list-level-properties', $oNodeListLevel); |
|
316 | 2 | if ($oNodeListProperties instanceof \DOMElement) { |
|
317 | 2 | if ($oNodeListProperties->hasAttribute('text:min-label-width')) { |
|
318 | 2 | $oAlignment->setIndent((int)round(CommonDrawing::centimetersToPixels(substr($oNodeListProperties->getAttribute('text:min-label-width'), 0, -2)))); |
|
319 | } |
||
320 | 2 | if ($oNodeListProperties->hasAttribute('text:space-before')) { |
|
321 | 2 | $iSpaceBefore = CommonDrawing::centimetersToPixels(substr($oNodeListProperties->getAttribute('text:space-before'), 0, -2)); |
|
322 | 2 | $iMarginLeft = $iSpaceBefore + $oAlignment->getIndent(); |
|
323 | 2 | $oAlignment->setMarginLeft($iMarginLeft); |
|
324 | } |
||
325 | } |
||
326 | 2 | $oNodeTextProperties = $this->oXMLReader->getElement('style:text-properties', $oNodeListLevel); |
|
327 | 2 | if ($oNodeTextProperties instanceof \DOMElement) { |
|
328 | 2 | if ($oNodeTextProperties->hasAttribute('fo:font-family')) { |
|
329 | 2 | $oBullet->setBulletFont($oNodeTextProperties->getAttribute('fo:font-family')); |
|
330 | } |
||
331 | } |
||
332 | |||
333 | 2 | $arrayListStyle[$oAlignment->getLevel()] = array( |
|
334 | 2 | 'alignment' => $oAlignment, |
|
335 | 2 | 'bullet' => $oBullet, |
|
336 | ); |
||
337 | } |
||
338 | } |
||
339 | |||
340 | 3 | $this->arrayStyles[$keyStyle] = array( |
|
341 | 3 | 'alignment' => isset($oAlignment) ? $oAlignment : null, |
|
342 | 'background' => isset($oBackground) ? $oBackground : null, |
||
343 | 1 | 'fill' => isset($oFill) ? $oFill : null, |
|
344 | 1 | 'font' => isset($oFont) ? $oFont : null, |
|
345 | 1 | 'shadow' => isset($oShadow) ? $oShadow : null, |
|
346 | 2 | 'listStyle' => isset($arrayListStyle) ? $arrayListStyle : null, |
|
347 | ); |
||
348 | |||
349 | 3 | return true; |
|
350 | } |
||
351 | |||
352 | /** |
||
353 | * Read Slide |
||
354 | * |
||
355 | * @param \DOMElement $nodeSlide |
||
356 | * @return bool |
||
357 | * @throws \Exception |
||
358 | */ |
||
359 | 3 | protected function loadSlide(\DOMElement $nodeSlide) |
|
385 | |||
386 | /** |
||
387 | * Read Shape Drawing |
||
388 | * |
||
389 | * @param \DOMElement $oNodeFrame |
||
390 | * @throws \Exception |
||
391 | */ |
||
392 | 2 | protected function loadShapeDrawing(\DOMElement $oNodeFrame) |
|
432 | |||
433 | /** |
||
434 | * Read Shape RichText |
||
435 | * |
||
436 | * @param \DOMElement $oNodeFrame |
||
437 | * @throws \Exception |
||
438 | */ |
||
439 | 3 | protected function loadShapeRichText(\DOMElement $oNodeFrame) |
|
464 | |||
465 | protected $levelParagraph = 0; |
||
466 | |||
467 | /** |
||
468 | * Read Paragraph |
||
469 | * @param RichText $oShape |
||
470 | * @param \DOMElement $oNodeParent |
||
471 | * @throws \Exception |
||
472 | */ |
||
473 | 2 | protected function readParagraph(RichText $oShape, \DOMElement $oNodeParent) |
|
488 | |||
489 | /** |
||
490 | * Read Paragraph Item |
||
491 | * @param Paragraph $oParagraph |
||
492 | * @param \DOMElement $oNodeParent |
||
493 | * @throws \Exception |
||
494 | */ |
||
495 | 1 | protected function readParagraphItem(Paragraph $oParagraph, \DOMElement $oNodeParent) |
|
518 | |||
519 | /** |
||
520 | * Read List |
||
521 | * |
||
522 | * @param RichText $oShape |
||
523 | * @param \DOMElement $oNodeParent |
||
524 | * @throws \Exception |
||
525 | */ |
||
526 | 1 | protected function readList(RichText $oShape, \DOMElement $oNodeParent) |
|
539 | |||
540 | /** |
||
541 | * Read List Item |
||
542 | * @param RichText $oShape |
||
543 | * @param \DOMElement $oNodeParent |
||
544 | * @param \DOMElement $oNodeParagraph |
||
545 | * @throws \Exception |
||
546 | */ |
||
547 | 1 | protected function readListItem(RichText $oShape, \DOMElement $oNodeParent, \DOMElement $oNodeParagraph) |
|
561 | |||
562 | /** |
||
563 | * Load file 'styles.xml' |
||
564 | */ |
||
565 | 3 | protected function loadStylesFile() |
|
576 | } |
||
577 |