Completed
Push — develop ( a92196...990136 )
by Stéphane
02:11
created

Rule::lastFilledIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Bee4\RobotsTxt;
4
5
/**
6
 * Class Rule
7
 * Represent a Ruleset inside a Robots.txt file
8
 *
9
 * @copyright Bee4 2015
10
 * @author    Stephane HULARD <[email protected]>
11
 */
12
class Rule
13
{
14
    const COMPILED = 'compiled';
15
    const DIRTY    = 'dirty';
16
17
    /**
18
     * Rule status (compiled or dirty)
19
     * @var string
20
     */
21
    private $state;
22
23
    /**
24
     * Expression collection with allow / disallow segments
25
     * @var array
26
     */
27
    private $exp = [
28
        'allow'    => [],
29
        'disallow' => []
30
    ];
31
32
    /**
33
     * Compiled regex pattern with allow / disallow segments
34
     * @var array
35
     */
36
    private $patterns = [
37
        'allow'    => '',
38
        'disallow' => ''
39
    ];
40
41
    /**
42
     * Add a pattern to match in the current rule by allowing
43
     * @param string $pattern
44
     * @return Rule
45
     */
46
    public function allow($pattern)
47
    {
48
        return $this->addExpression(new Expression($pattern), 'allow');
49
    }
50
51
    /**
52
     * Add a pattern to match in the current rule by disallowing
53
     * @param string $pattern
54
     * @return Rule
55
     */
56 3
    public function disallow($pattern)
57
    {
58 3
        return $this->addExpression(new Expression($pattern), 'disallow');
59
    }
60
61
    /**
62
     * Add an expression in the current rule
63
     * @param string $pattern Expression raw pattern
0 ignored issues
show
Bug introduced by
There is no parameter named $pattern. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
64
     * @param string $mode    Expression mode (allow / disallow)
65
     * @return Expression
66
     */
67
    private function addExpression(Expression $exp, $mode)
68
    {
69
        $this->state = self::DIRTY;
70
        $this->exp[$mode][] = $exp;
71
        return $this;
72
    }
73
74
    /**
75
     * Compile expressions to a global pattern
76
     * @return boolean
77
     */
78 1
    public function compile()
79
    {
80 1
        if( self::COMPILED === $this->state ) {
81
            return true;
82
        }
83
84
        $process = function(array &$patterns) {
85 1
            usort($patterns, function($a, $b) {
86
                return strlen($a->getRaw()) < strlen($b->getRaw());
87 1
            });
88
89 1
            return '/^(('.implode(')|(', $patterns).'))$/';
90 1
        };
91 1
        $this->patterns['allow'] = $process($this->exp['allow']);
92 1
        $this->patterns['disallow'] = $process($this->exp['disallow']);
93 1
    }
94
95
    /**
96
     * Check if the URL is allowed or not
97
     * @param string $url
98
     * @return boolean
99
     */
100 1
    public function match($url)
101
    {
102 1
        $this->compile();
103
104 1
        if( 1 === preg_match($this->patterns['disallow'], $url, $disallowed) ) {
105
            if( 1 === preg_match($this->patterns['allow'], $url, $allowed) ) {
106
                $a = $this->lastFilledIndex($allowed);
107
                $d = $this->lastFilledIndex($disallowed);
108
                return strlen($this->exp['allow'][$a-2]->getRaw()) >= strlen($this->exp['disallow'][$d-2]->getRaw());
109
            }
110
111
            return false;
112
        }
113
114 1
        return true;
115
    }
116
117
    /**
118
     * Retrieve the last filled index in a given array
119
     * @param  array  $data
120
     * @return integer
121
     */
122
    private function lastFilledIndex(array $data)
123
    {
124
        return key( array_slice( array_filter($data), -1, 1, true ) );
125
    }
126
}
127