Completed
Branch 2.0-dev (2690fb)
by Jan-Petter
02:15
created

UserAgentParser::add()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
namespace vipnytt\RobotsTxtParser\Parser\Directives;
3
4
use vipnytt\RobotsTxtParser\Client\Directives\UserAgentClient;
5
use vipnytt\RobotsTxtParser\RobotsTxtInterface;
6
use vipnytt\UserAgentParser as UAStringParser;
7
8
/**
9
 * Class UserAgentParser
10
 *
11
 * @package vipnytt\RobotsTxtParser\Parser\Directives
12
 */
13
class UserAgentParser implements ParserInterface, RobotsTxtInterface
14
{
15
    use DirectiveParserCommons;
16
17
    /**
18
     * Sub directives white list
19
     */
20
    const SUB_DIRECTIVES = [
21
        self::DIRECTIVE_ALLOW => 'allow',
22
        self::DIRECTIVE_CACHE_DELAY => 'cacheDelay',
23
        self::DIRECTIVE_COMMENT => 'comment',
24
        self::DIRECTIVE_CRAWL_DELAY => 'crawlDelay',
25
        self::DIRECTIVE_DISALLOW => 'disallow',
26
        self::DIRECTIVE_REQUEST_RATE => 'requestRate',
27
        self::DIRECTIVE_ROBOT_VERSION => 'robotVersion',
28
        self::DIRECTIVE_VISIT_TIME => 'visitTime',
29
    ];
30
31
    /**
32
     * Directive
33
     */
34
    const DIRECTIVE = self::DIRECTIVE_USER_AGENT;
35
36
    /**
37
     * Base Uri
38
     * @var string
39
     */
40
    private $base;
41
42
    /**
43
     * User-agent handler
44
     * @var SubDirectiveHandler[]
45
     */
46
    private $handler = [];
47
48
    /**
49
     * User-agent(s)
50
     * @var string[]
51
     */
52
    private $userAgent = [self::USER_AGENT];
53
54
    /**
55
     * User-agent client cache
56
     * @var UserAgentClient
57
     */
58
    private $client;
59
60
    /**
61
     * UserAgent constructor.
62
     *
63
     * @param string $base
64
     */
65
    public function __construct($base)
66
    {
67
        $this->base = $base;
68
        $this->set();
69
    }
70
71
    /**
72
     * Set new User-agent
73
     *
74
     * @param array $array
75
     * @return bool
76
     */
77
    public function set(array $array = [self::USER_AGENT])
78
    {
79
        $this->userAgent = array_map('mb_strtolower', $array);
80
        foreach ($this->userAgent as $userAgent) {
81
            if (!in_array($userAgent, array_keys($this->handler))) {
82
                $this->handler[$userAgent] = new SubDirectiveHandler($this->base, $userAgent);
83
            }
84
        }
85
        return true;
86
    }
87
88
    /**
89
     * Add
90
     *
91
     * @param string $line
92
     * @return bool
93
     */
94
    public function add($line)
95
    {
96
        $result = [];
97
        if (($pair = $this->generateRulePair($line, array_keys(self::SUB_DIRECTIVES))) === false) {
98
            return false;
99
        }
100
        foreach ($this->userAgent as $userAgent) {
101
            $result[] = $this->handler[$userAgent]->{self::SUB_DIRECTIVES[$pair['directive']]}()->add($pair['value']);
102
        }
103
        return in_array(true, $result, true);
104
    }
105
106
    /**
107
     * Client
108
     *
109
     * @param string $userAgent
110
     * @param int|null $statusCode
111
     * @return UserAgentClient
112
     */
113
    public function client($userAgent = self::USER_AGENT, $statusCode = null)
114
    {
115
        if (isset($this->client[$userAgent])) {
116
            return $this->client[$userAgent];
117
        }
118
        $userAgent = mb_strtolower($userAgent);
119
        $userAgentParser = new UAStringParser($userAgent);
120
        if (($userAgentMatch = $userAgentParser->match($this->getUserAgents())) === false) {
121
            $userAgentMatch = self::USER_AGENT;
122
        }
123
        return $this->client[$userAgent] = new UserAgentClient($this->handler[$userAgentMatch], $this->base, $statusCode);
124
    }
125
126
    /**
127
     * User-agent list
128
     *
129
     * @return string[]
130
     */
131
    public function getUserAgents()
132
    {
133
        return array_keys($this->handler);
134
    }
135
136
    /**
137
     * Rule array
138
     *
139
     * @return array
140
     */
141
    public function getRules()
142
    {
143
        $result = [];
144
        foreach ($this->getUserAgents() as $userAgent) {
145
            $current = array_merge(
146
                $this->handler[$userAgent]->robotVersion()->getRules(),
147
                $this->handler[$userAgent]->visitTime()->getRules(),
148
                $this->handler[$userAgent]->disallow()->getRules(),
149
                $this->handler[$userAgent]->allow()->getRules(),
150
                $this->handler[$userAgent]->crawlDelay()->getRules(),
151
                $this->handler[$userAgent]->cacheDelay()->getRules(),
152
                $this->handler[$userAgent]->requestRate()->getRules(),
153
                $this->handler[$userAgent]->comment()->getRules()
154
            );
155
            if (!empty($current)) {
156
                $result[$userAgent] = $current;
157
            }
158
        }
159
        return empty($result) ? [] : [self::DIRECTIVE => $result];
160
    }
161
162
    /**
163
     * Render
164
     *
165
     * @return string[]
166
     */
167
    public function render()
168
    {
169
        $userAgents = $this->getUserAgents();
170
        sort($userAgents);
171
        $result = [];
172
        foreach ($userAgents as $userAgent) {
173
            $current = array_merge(
174
                $this->handler[$userAgent]->robotVersion()->render(),
175
                $this->handler[$userAgent]->visitTime()->render(),
176
                $this->handler[$userAgent]->disallow()->render(),
177
                $this->handler[$userAgent]->allow()->render(),
178
                $this->handler[$userAgent]->crawlDelay()->render(),
179
                $this->handler[$userAgent]->cacheDelay()->render(),
180
                $this->handler[$userAgent]->requestRate()->render(),
181
                $this->handler[$userAgent]->comment()->render()
182
            );
183
            if (!empty($current)) {
184
                $result = array_merge($result, [self::DIRECTIVE . ':' . $userAgent], $current);
185
            }
186
        }
187
        return $result;
188
    }
189
}
190