Completed
Push — master ( bcbde7...9c8e56 )
by Paul
03:11
created

CopyImageProcess::setHtmlFromDomDocument()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 15
ccs 9
cts 9
cp 1
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
crap 1
1
<?php
2
namespace Bookdown\Bookdown\Process\Resource;
3
4
use Bookdown\Bookdown\Config\RootConfig;
5
use Psr\Log\LoggerInterface;
6
use Bookdown\Bookdown\Content\Page;
7
use Bookdown\Bookdown\Fsio;
8
use Bookdown\Bookdown\Process\ProcessInterface;
9
use DomDocument;
10
use DomNode;
11
use DomXpath;
12
13
class CopyImageProcess implements ProcessInterface
14
{
15
    /**
16
     * @var Page
17
     */
18
    protected $page;
19
20
    /**
21
     * @var RootConfig
22
     */
23
    protected $config;
24
25
    /**
26
     * @var string
27
     */
28
    protected $html;
29
30
    /**
31
     * @var DomDocument
32
     */
33
    protected $doc;
34
35
    /**
36
     * @var Fsio
37
     */
38
    protected $fsio;
39
40
    /**
41
     * @var LoggerInterface
42
     */
43
    protected $logger;
44
45 3
    public function __construct(
46
        LoggerInterface $logger,
47
        Fsio $fsio,
48
        RootConfig $config
49
    ) {
50 3
        $this->logger = $logger;
51 3
        $this->fsio = $fsio;
52 3
        $this->config = $config;
53 3
    }
54
55 2
    public function __invoke(Page $page)
56
    {
57 2
        $this->logger->info("    Processing copy images for {$page->getTarget()}");
58
59 2
        $this->reset($page);
60
61 2
        $this->loadHtml();
62 2
        if ($this->html) {
63 2
            $this->loadDomDocument();
64 2
            $this->processImageNodes();
65 2
            $this->saveHtml();
66 2
        }
67 2
    }
68
69 2
    protected function reset(Page $page)
70
    {
71 2
        $this->page = $page;
72 2
        $this->html = null;
73 2
        $this->doc = null;
74 2
    }
75
76 2
    protected function loadHtml()
77
    {
78 2
        $this->html = $this->fsio->get($this->page->getTarget());
79 2
    }
80
81 2
    protected function saveHtml()
82
    {
83 2
        $this->fsio->put($this->page->getTarget(), $this->html);
84 2
    }
85
86 2
    protected function loadDomDocument()
87
    {
88 2
        $this->doc = new DomDocument();
89 2
        $this->doc->formatOutput = true;
90 2
        $this->doc->loadHtml(mb_convert_encoding($this->html, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NODEFDTD);
91 2
    }
92
93 2
    protected function processImageNodes()
94
    {
95 2
        $nodes = $this->getImageNodes();
96 2
        $this->addImages($nodes);
97 2
        $this->setHtmlFromDomDocument();
98 2
    }
99
100 2
    protected function getImageNodes()
101
    {
102 2
        $xpath = new DomXpath($this->doc);
103 2
        $query = '//img';
104 2
        return $xpath->query($query);
105
    }
106
107 2
    protected function addImages($nodes)
108
    {
109 2
        foreach ($nodes as $node) {
110 1
            $this->addImage($node);
111 2
        }
112 2
    }
113
114 1
    protected function addImage(DomNode $node)
115
    {
116 1
        if ($src = $this->downloadImage($node)) {
117 1
            $node->attributes->getNamedItem('src')->nodeValue = $src;
118 1
        }
119 1
    }
120
121 1
    protected function downloadImage(DomNode $node)
122
    {
123 1
        $image = $node->attributes->getNamedItem('src')->nodeValue;
124
125
        # no image or absolute URI
126 1
        if (!$image || preg_match('#^(http(s)?|//)#', $image)) {
127 1
            return '';
128
        }
129 1
        $imageName = basename($image);
130 1
        $originFile = dirname($this->page->getOrigin()) . '/' . ltrim($image, '/');
131
132 1
        $dir = dirname($this->page->getTarget()) . '/img/';
133 1
        $file = $dir . $imageName;
134
135 1
        if (!$this->fsio->isDir($dir)) {
136 1
            $this->fsio->mkdir($dir);
137 1
        }
138 1
        $this->fsio->put($file, $this->fsio->get($originFile));
139 1
        return $this->config->getRootHref() . (str_replace($this->config->getTarget(), '', $dir)) . $imageName;
140
    }
141
142 2
    protected function setHtmlFromDomDocument()
143
    {
144
        // retain the modified html
145 2
        $this->html = trim($this->doc->saveHtml($this->doc->documentElement));
146
147
        // strip the html and body tags added by DomDocument
148 2
        $this->html = substr(
149 2
            $this->html,
150 2
            strlen('<html><body>'),
151 2
            -1 * strlen('</body></html>')
152 2
        );
153
154
        // still may be whitespace all about
155 2
        $this->html = trim($this->html) . PHP_EOL;
156 2
    }
157
}
158