FilterExtension::isFiltered()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 3
nc 4
nop 3
1
<?php
2
3
namespace whm\Smoke\Extensions\SmokeFilter;
4
5
use phm\HttpWebdriverClient\Http\Response\UriAwareResponse;
6
use phmLabs\Components\Annovent\Event\Event;
7
use whm\Html\Uri;
8
use whm\Smoke\Extensions\SmokeResponseRetriever\Retriever\Retriever;
9
use whm\Smoke\Yaml\EnvAwareYaml;
10
11
/**
12
 * Class FilterExtension.
13
 *
14
 * @example for filter file
15
 *
16
 * filters:
17
 *   _HttpHeaderSuccessStatus:
18
 *     - http://www.wunderweib.de/tag/
19
 *     - http://www.amilio.de/old-but-mandatory-file/
20
 *     - http://www.amilio.de/images/(.*)
21
 *
22
 * exclusive:
23
 *   _HttpHeaderSuccessStatus:
24
 *     - http://www.wunderweib.de/tag/
25
 *     - http://www.amilio.de/old-but-mandatory-file/
26
 */
27
class FilterExtension
28
{
29
    /**
30
     * @var Retriever
31
     */
32
    private $retriever;
33
34
    private $filters = array();
35
    private $exclusives = array();
36
37
    private $currentModus = self::MODUS_FILTER;
38
39
    const MODUS_FILTER = 'filter';
40
    const MODUS_EXCLUSIVE = 'exclusive';
41
42
    public function init($filters = array(), $filterFile = '', $exclusive = array())
43
    {
44
        if (count($exclusive) > 0 && (count($filters) > 0 || $filterFile !== '')) {
45
            throw new \RuntimeException("It's not possible to define filter lists and an exclusive list at the same time [Extension: " . get_class($this) . '].');
46
        }
47
48
        if ($filterFile !== '') {
49
            if (!file_exists($filterFile)) {
50
                throw new \RuntimeException('Filter file not found: ' . $filterFile);
51
            }
52
53
            $filterElements = EnvAwareYaml::parse(file_get_contents($filterFile));
54
55
            foreach ($filterElements['filters'] as $rule => $uris) {
56
                foreach ($uris as $uri) {
57
                    $this->filters[] = array('rule' => $rule, 'uri' => $uri);
58
                }
59
            }
60
        } elseif (!is_null($filters)) {
61
            foreach ($filters as $rule => $filteredUrls) {
62
                if (!is_null($filteredUrls)) {
63
                    foreach ($filteredUrls as $uri) {
64
                        $this->filters[] = array('rule' => $rule, 'uri' => $uri);
65
                    }
66
                }
67
            }
68
        }
69
70
        if (count($exclusive) > 0) {
71
            foreach ($exclusive as $rule => $urls) {
72
                if (is_array($urls)) {
73
                    foreach ($urls as $url) {
74
                        $uri = new Uri($url);
75
                        $this->exclusives[$rule][] = (string)$uri;
76
                    }
77
                }
78
            }
79
            $this->currentModus = self::MODUS_EXCLUSIVE;
80
        }
81
    }
82
83
    /**
84
     * @Event("Scanner.Init.ResponseRetriever")
85
     */
86
    public function getResponseRetriever(Retriever $responseRetriever)
87
    {
88
        $this->retriever = $responseRetriever;
89
    }
90
91
    /**
92
     * @Event("Scanner.CheckResponse.isFiltered")
93
     */
94
    public function isFiltered(Event $event, $ruleName, UriAwareResponse $response)
95
    {
96
        $uri = (string)$this->retriever->getOriginUri($response->getUri());
97
98
        if ($this->currentModus === self::MODUS_FILTER) {
99
            $isFiltered = $this->isFilteredByFilter($ruleName, $uri);
100
        } else {
101
            $isFiltered = $this->isFilteredByExclusives($ruleName, $uri);
102
        }
103
104
        if ($isFiltered) {
105
            $event->setProcessed();
106
            return true;
107
        } else {
108
            return false;
109
        }
110
    }
111
112
    private function isFilteredByFilter($ruleName, $uri)
113
    {
114
        foreach ($this->filters as $filter) {
115
            if ($ruleName === $filter['rule'] && 0 < preg_match('$' . $filter['uri'] . '$', $uri)) {
116
                return true;
117
            }
118
        }
119
120
121
        return false;
122
    }
123
124
    private function isFilteredByExclusives($ruleName, $uri)
125
    {
126
        if (array_key_exists($ruleName, $this->exclusives)) {
127
            if (is_array($this->exclusives[$ruleName])) {
128
                if (in_array($uri, $this->exclusives[$ruleName], true)) {
129
                    return false;
130
                }
131
            }
132
        }
133
134
        return true;
135
    }
136
}
137