Passed
Pull Request — master (#125)
by MusikAnimal
03:53
created

AutomatedEditsHelper::getTool()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 2
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 4
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file contains only the AutomatedEditsHelper class.
4
 */
5
6
namespace AppBundle\Helper;
7
8
use Symfony\Component\DependencyInjection\ContainerInterface;
9
10
/**
11
 * Helper class for fetching semi-automated definitions.
12
 */
13
class AutomatedEditsHelper extends HelperBase
14
{
15
16
    /** @var string[] The list of tools that are considered reverting. */
17
    protected $revertTools = [];
18
19
    /** @var string[] The list of tool names and their regexes. */
20
    protected $tools = [];
21
22
    /**
23
     * AutomatedEditsHelper constructor.
24
     * @param ContainerInterface $container
25
     */
26 11
    public function __construct(ContainerInterface $container)
27
    {
28 11
        $this->container = $container;
0 ignored issues
show
Documentation Bug introduced by
$container is of type Symfony\Component\Depend...tion\ContainerInterface, but the property $container was declared to be of type Symfony\Component\DependencyInjection\Container. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
29 11
    }
30
31
    /**
32
     * Get the tool that matched the given edit summary.
33
     * This only works for tools defined with regular expressions, not tags.
34
     * @param  string $summary Edit summary
35
     * @param  string $projectDomain Such as en.wikipedia.org
36
     * @return string|bool Tool entry including key for 'name', or false if nothing was found
37
     */
38 7
    public function getTool($summary, $projectDomain)
39
    {
40 7
        foreach ($this->getTools($projectDomain) as $tool => $values) {
41 7
            if (isset($values['regex']) && preg_match('/'.$values['regex'].'/', $summary)) {
42 7
                return array_merge([
43 7
                    'name' => $tool,
44 7
                ], $values);
0 ignored issues
show
Bug introduced by
$values of type string is incompatible with the type array expected by parameter $arrays of array_merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

44
                ], /** @scrutinizer ignore-type */ $values);
Loading history...
45
            }
46
        }
47
48 5
        return false;
49
    }
50
51
    /**
52
     * Was the edit (semi-)automated, based on the edit summary?
53
     * This only works for tools defined with regular expressions, not tags.
54
     * @param  string $summary Edit summary
55
     * @param  string $projectDomain Such as en.wikipedia.org
56
     * @return bool
57
     */
58 1
    public function isAutomated($summary, $projectDomain)
59
    {
60 1
        return (bool) $this->getTool($summary, $projectDomain);
61
    }
62
63
    /**
64
     * Get list of automated tools and their associated info for the
65
     *   given project. This defaults to the 'default_project' if
66
     *   entries for the given project are not found.
67
     * @param  string $projectDomain Such as en.wikipedia.org
68
     * @return string[] Each tool with the tool name as the key,
69
     *   and 'link', 'regex' and/or 'tag' as the subarray keys.
70
     */
71 11
    public function getTools($projectDomain)
72
    {
73 11
        if (isset($this->tools[$projectDomain])) {
74 5
            return $this->tools[$projectDomain];
75
        }
76
77
        // Load the semi-automated edit types.
78 11
        $toolsByWiki = $this->container->getParameter('automated_tools');
79
80
        // Default to default project (e.g. en.wikipedia.org) if wiki not configured
81 11
        if (isset($toolsByWiki[$projectDomain])) {
82 8
            $this->tools[$projectDomain] = $toolsByWiki[$projectDomain];
83
        } else {
84 3
            $this->tools[$projectDomain] = $toolsByWiki[$this->container->getParameter('default_project')];
85
        }
86
87
        // Merge wiki-specific rules into the global rules
88 11
        $this->tools[$projectDomain] = array_merge_recursive(
89 11
            $toolsByWiki['global'],
90 11
            $this->tools[$projectDomain]
91
        );
92
93 11
        return $this->tools[$projectDomain];
94
    }
95
96
    /**
97
     * Get only tools that are used to revert edits.
98
     * Revert detection happens only by testing against a regular expression,
99
     *   and not by checking tags.
100
     * @param  string $projectDomain Such as en.wikipedia.org
101
     * @return string[] Each tool with the tool name as the key,
102
     *   and 'link' and 'regex' as the subarray keys.
103
     */
104 5
    public function getRevertTools($projectDomain)
105
    {
106 5
        if (isset($this->revertTools[$projectDomain])) {
107 5
            return $this->revertTools[$projectDomain];
108
        }
109
110 5
        $revertEntries = array_filter(
111 5
            $this->getTools($projectDomain),
112
            function ($tool) {
113 5
                return isset($tool['revert']);
114 5
            }
115
        );
116
117
        // If 'revert' is set to `true`, the use 'regex' as the regular expression,
118
        //  otherwise 'revert' is assumed to be the regex string.
119 5
        $this->revertTools[$projectDomain] = array_map(function ($revertTool) {
120
            return [
121 5
                'link' => $revertTool['link'],
122 5
                'regex' => $revertTool['revert'] === true ? $revertTool['regex'] : $revertTool['revert']
123
            ];
124 5
        }, $revertEntries);
125
126 5
        return $this->revertTools[$projectDomain];
127
    }
128
129
    /**
130
     * Was the edit a revert, based on the edit summary?
131
     * This only works for tools defined with regular expressions, not tags.
132
     * @param  string $summary Edit summary
133
     * @param  string $projectDomain Such as en.wikipedia.org
134
     * @return bool
135
     */
136 5
    public function isRevert($summary, $projectDomain)
137
    {
138 5
        foreach ($this->getRevertTools($projectDomain) as $tool => $values) {
139 5
            if (preg_match('/'.$values['regex'].'/', $summary)) {
140 5
                return true;
141
            }
142
        }
143
144 5
        return false;
145
    }
146
}
147