Completed
Push — master ( 0be3f5...793ac3 )
by Jan-Petter
02:16
created

RequestRateParser   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 12
Bugs 1 Features 0
Metric Value
wmc 17
c 12
b 1
f 0
lcom 1
cbo 3
dl 0
loc 130
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A add() 0 18 4
B draftParseRate() 0 23 6
A client() 0 5 1
A sort() 0 7 1
A render() 0 14 4
1
<?php
2
/**
3
 * vipnytt/RobotsTxtParser
4
 *
5
 * @link https://github.com/VIPnytt/RobotsTxtParser
6
 * @license https://github.com/VIPnytt/RobotsTxtParser/blob/master/LICENSE The MIT License (MIT)
7
 */
8
9
namespace vipnytt\RobotsTxtParser\Parser\Directives;
10
11
use vipnytt\RobotsTxtParser\Client\Directives\RequestRateClient;
12
use vipnytt\RobotsTxtParser\Handler\RenderHandler;
13
use vipnytt\RobotsTxtParser\RobotsTxtInterface;
14
15
/**
16
 * Class RequestRateParser
17
 *
18
 * @package vipnytt\RobotsTxtParser\Parser\Directives
19
 */
20
class RequestRateParser implements ParserInterface, RobotsTxtInterface
21
{
22
    use DirectiveParserTrait;
23
24
    /**
25
     * Base uri
26
     * @var string
27
     */
28
    private $base;
29
30
    /**
31
     * RequestRate array
32
     * @var array
33
     */
34
    private $requestRates = [];
35
36
    /**
37
     * RequestRate constructor.
38
     *
39
     * @param string $base
40
     */
41
    public function __construct($base)
42
    {
43
        $this->base = $base;
44
    }
45
46
    /**
47
     * Add
48
     *
49
     * @param string $line
50
     * @return bool
51
     */
52
    public function add($line)
53
    {
54
        $array = preg_split('/\s+/', $line, 2);
55
        $result = [
56
            'rate' => $this->draftParseRate($array[0]),
57
            'from' => null,
58
            'to' => null,
59
        ];
60
        if ($result['rate'] === false) {
61
            return false;
62
        } elseif (!empty($array[1]) &&
63
            ($times = $this->draftParseTime($array[1])) !== false
64
        ) {
65
            $result = array_merge($result, $times);
66
        }
67
        $this->requestRates[] = $result;
68
        return true;
69
    }
70
71
    /**
72
     * Client rate as specified in the `Robot exclusion standard` version 2.0 draft
73
     * rate = numDocuments / timeUnit
74
     * @link http://www.conman.org/people/spc/robots2.html#format.directives.request-rate
75
     *
76
     * @param string $string
77
     * @return float|int|false
78
     */
79
    private function draftParseRate($string)
80
    {
81
        $parts = array_map('trim', explode('/', $string));
82
        if (count($parts) != 2) {
83
            return false;
84
        }
85
        $multiplier = 1;
86
        switch (strtolower(substr(preg_replace('/[^A-Za-z]/', '', $parts[1]), 0, 1))) {
87
            case 'm':
88
                $multiplier = 60;
89
                break;
90
            case 'h':
91
                $multiplier = 3600;
92
                break;
93
            case 'd':
94
                $multiplier = 86400;
95
                break;
96
        }
97
        $num = floatval(preg_replace('/[^0-9]/', '', $parts[0]));
98
        $sec = floatval(preg_replace('/[^0-9.]/', '', $parts[1])) * $multiplier;
99
        $rate = $sec / $num;
100
        return $rate > 0 ? $rate : false;
101
    }
102
103
    /**
104
     * Client
105
     *
106
     * @param string $userAgent
107
     * @param float|int $fallbackValue
108
     * @return RequestRateClient
109
     */
110
    public function client($userAgent = self::USER_AGENT, $fallbackValue = 0)
111
    {
112
        $this->sort();
113
        return new RequestRateClient($this->base, $userAgent, $this->requestRates, $fallbackValue);
114
    }
115
116
    /**
117
     * Sort
118
     *
119
     * @return void
120
     */
121
    private function sort()
122
    {
123
        usort($this->requestRates, function ($requestRateA, $requestRateB) {
124
            // PHP 7: Switch to the <=> "Spaceship" operator
125
            return $requestRateB['rate'] > $requestRateA['rate'];
126
        });
127
    }
128
129
    /**
130
     * Render
131
     *
132
     * @param RenderHandler $handler
133
     * @return bool
134
     */
135
    public function render(RenderHandler $handler)
136
    {
137
        $this->sort();
138
        foreach ($this->requestRates as $array) {
139
            $suffix = 's';
140
            if (isset($array['from']) &&
141
                isset($array['to'])
142
            ) {
143
                $suffix .= ' ' . $array['from'] . '-' . $array['to'];
144
            }
145
            $handler->add(self::DIRECTIVE_REQUEST_RATE, '1/' . $array['rate'] . $suffix);
146
        }
147
        return true;
148
    }
149
}
150