Passed
Push — master ( abdb51...0ee754 )
by Dev
16:27 queued 01:19
created

PageScannerService   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 47
c 1
b 0
f 0
dl 0
loc 97
rs 10
ccs 0
cts 63
cp 0
wmc 19

6 Methods

Rating   Name   Duplication   Size   Complexity  
A addError() 0 5 1
A checkLinkedDocs() 0 5 3
A __construct() 0 10 1
A getLinkedDocs() 0 14 4
A scan() 0 20 3
B uriExist() 0 19 7
1
<?php
2
3
namespace PiedWeb\CMSBundle\Service;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use PiedWeb\CMSBundle\Entity\PageInterface as Page;
7
use Twig\Environment as Twig_Environment;
8
9
/**
10
 * Permit to find error in image or link.
11
 */
12
class PageScannerService
13
{
14
    protected $em;
15
    protected $pageHtml;
16
    protected $twig;
17
    protected $defaultTemplate;
18
    protected $currentPage;
19
    protected $webDir;
20
    protected $errors = [];
21
    protected $everChecked = [];
22
23
    public function __construct(
24
        Twig_Environment $twig,
25
        EntityManagerInterface $em,
26
        string $defaultTemplate,
27
        string $webDir
28
    ) {
29
        $this->twig = $twig;
30
        $this->em = $em;
31
        $this->defaultTemplate = $defaultTemplate;
32
        $this->webDir = $webDir;
33
    }
34
35
    public function scan(Page $page)
36
    {
37
        $this->currentPage = $page;
38
        $this->errors = [];
39
        $this->pageHtml = '';
40
41
        if (false !== $page->getRedirection()) {
42
            // check $page->getRedirection() return 20X
43
44
            return true; // or status code
45
        }
46
47
        //$template = null !== $page->getTemplate() ? $page->getTemplate() : $this->defaultTemplate;
48
        $this->pageHtml = $this->twig->render($this->defaultTemplate, ['page' => $page]);
49
50
        // 2. Je récupère tout les liens et je les check
51
        // href="", data-rot="" data-img="", src="", data-bg
52
        $this->checkLinkedDocs($this->getLinkedDocs());
53
54
        return empty($this->errors) ? true : $this->errors;
55
    }
56
57
    protected function addError($message)
58
    {
59
        $this->errors[] = [
60
            'message' => $message,
61
            'page' => $this->currentPage,
62
        ];
63
    }
64
65
    protected function getLinkedDocs(): array
66
    {
67
        preg_match_all('/(href|data-rot|src|data-img|data-bg)=("\/[^"]*|\/[^\s>]*)/i', $this->pageHtml, $matches);
68
69
        $linkedDocs = [];
70
        foreach ($matches[0] as $k => $match) {
71
            $uri = ltrim('data-rot' == $matches[1][$k] ? str_rot13($matches[2][$k]) : $matches[2][$k], '"');
72
            $uri = strtok($uri, '#');
73
            if ('' !== $uri) {
74
                $linkedDocs[] = $uri;
75
            }
76
        }
77
78
        return array_unique($linkedDocs);
79
    }
80
81
    protected function checkLinkedDocs(array $linkedDocs)
82
    {
83
        foreach ($linkedDocs as $uri) {
84
            if (!$this->uriExist($uri)) {
85
                $this->addError('<code>'.$uri.'</code> introuvable');
86
            }
87
        }
88
    }
89
90
    protected function uriExist($uri)
91
    {
92
        $slug = ltrim($uri, '/');
93
94
        if (isset($this->everChecked[$slug])) {
95
            return $this->everChecked[$slug];
96
        }
97
98
        $checkDatabase = 0 !== strpos($slug, 'media/'); // we avoid to check in db the media, file exists is enough
99
        $page = true !== $checkDatabase ? null : $this->em->getRepository(get_class($this->currentPage))
100
            ->findOneBy(['slug' => '' == $slug ? 'homepage' : $slug]);
101
102
        $this->everChecked[$slug] = (
103
                null === $page
104
                && !file_exists($this->webDir.'/'.$slug)
105
                && 'feed.xml' !== $slug
106
            ) ? false : true;
107
108
        return $this->everChecked[$slug];
109
    }
110
}
111