Completed
Pull Request — master (#157)
by
unknown
01:35
created

DriverNameMatcher::identifyByLabelExactly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
1
<?php
2
3
namespace Drupal\Component\Utility;
4
5
/**
6
 * Defines a utility class for matching text input with entities using their
7
 * machine names or labels.
8
 */
9
class DriverNameMatcher
10
{
11
12
  /**
13
   * A set of items needing to be identified. The key is some human-friendly
14
   * name, the value is preserved and is not used for identification.
15
   *
16
   * @var array
17
   */
18
    protected $targets;
19
20
  /**
21
   * A set of items where the keys are the items machine names and the values
22
   * are the items labels.
23
   *
24
   * @var array
25
   */
26
    protected $candidates;
27
28
  /**
29
   * A string that may precede the candidate's machine names and should be
30
   * ignored for identification purposes.
31
   *
32
   * @var string
33
   */
34
    protected $prefix;
35
36
  /**
37
   * A set of successfully matched items
38
   *
39
   * @var array
40
   */
41
    protected $results;
42
43
  /**
44
   * Construct a driver name matcher object.
45
   *
46
   * @param array $candidates
47
   *   A set of candidate items where the keys are the items labels
48
   *   and the values are the items machine names.
49
   * @param string $prefix
50
   *   A string that may precede the candidate's machine names and should be
51
   *   ignored for identification purposes.
52
   */
53
    public function __construct($candidates, $prefix = null)
54
    {
55
        if (is_array($candidates)) {
56
            $this->candidates = $candidates;
57
        } else {
58
            throw new \Exception("Candidates for identification must be passed as an array with the machine names as the keys and the labels as the values.");
59
        }
60
61
        $this->prefix = $prefix;
62
        $this->results = [];
63
    }
64
65
  /**
66
   * Identifies a target from the pool of candidates.
67
   *
68
   * @param string $target
69
   *   A single string needing to be identified as an item in the candidates.
70
   *
71
   * @return string
72
   *   The machine name of the matching candidate, or NULL if none matched.
73
   */
74
    public function identify($target)
75
    {
76
        // Wrap the target in the appropriate array for identifySet().
77
        $targets = [$target => $target];
78
        $results = $this->identifySet($targets);
79
        // Get the first key of the results.
80
        reset($results);
81
        return key($results);
82
    }
83
84
    /**
85
   * Identifies the targets from the pool of candidates.
86
   *
87
   * @param array $targets
88
   *   A set of items needing to be identified. The key is some human-friendly
89
   *   name, the value is preserved and is not used for identification.
90
   *
91
   * @return array
92
   *   For each matched target, the key will be replaced with the machine name
93
   *  of the matching candidate, & the value will be preserved. Order may vary.
94
   */
95
    public function identifySet($targets)
96
    {
97
        if (is_array($targets)) {
98
            $this->targets = $targets;
99
        } else {
100
            throw new \Exception("Targets to be identified must be passed as an array with their human-friendly name as the keys and anything as the values.");
101
        }
102
103
        $mayHavePrefix = !is_null($this->prefix);
104
        $this->identifyByMethod("MachineNameExactly");
105
        $this->identifyByMethod("LabelExactly");
106
        if ($mayHavePrefix) {
107
            $this->identifyByMethod("MachineNameWithoutPrefix");
108
        }
109
        $this->identifyByMethod("MachineNameWithoutUnderscores");
110
        if ($mayHavePrefix) {
111
            $this->identifyByMethod("MachineNameWithoutPrefixAndUnderscores");
112
        }
113
        return $this->results;
114
    }
115
116
  /**
117
   * Gets the candidates that were not a match for any target.
118
   *
119
   * @return array
120
   *   An array of candidates.
121
   */
122
    public function getUnmatchedCandidates()
123
    {
124
        return $this->candidates;
125
    }
126
127
  /**
128
   * Gets the targets that were not a match for any candidate.
129
   *
130
   * @return array
131
   *   An array of targets.
132
   */
133
    public function getUnmatchedTargets()
134
    {
135
        return $this->targets;
136
    }
137
138
  /**
139
   * Iterates over candidates and targets looking for a match.
140
   *
141
   * @param string $method
142
   *   The last part of the name of a method of matching.
143
   */
144
    protected function identifyByMethod($method)
145
    {
146
        $methodFunctionName = "identifyBy" . $method;
147
        $matchedCandidates = [];
148
        foreach ($this->targets as $identifier => $value) {
149
            foreach ($this->candidates as $label => $machineName) {
150
                // Skip over candidates that describe fields already matched.
151
                if (in_array($machineName, $matchedCandidates)) {
152
                    continue;
153
                }
154
                // If the identification method determines a match, remove the candidate
155
                // and target from future consideration, and save the result.
156
                if ($this->$methodFunctionName($identifier, $machineName, $label)) {
157
                    //$this->candidates = array_filter($this->candidates, function ($value, $key) use ($machineName) {
158
                     // return $value === $machineName;
159
                    //}, ARRAY_FILTER_USE_BOTH);
160
                    $matchedCandidates[] = $machineName;
161
                    //unset($this->candidates[$label]);
162
                    unset($this->targets[$identifier]);
163
                    $this->results[$machineName] = $value;
164
                    break;
165
                }
166
            }
167
        }
168
169
        // Strip out the successfully matched candidates.
170
        $this->candidates = array_filter($this->candidates, function ($machineName, $label) use ($matchedCandidates) {
0 ignored issues
show
Unused Code introduced by
The parameter $label is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
171
            return !in_array($machineName, $matchedCandidates);
172
        }, ARRAY_FILTER_USE_BOTH);
173
    }
174
175
  /**
176
   * Matches an identifer against a machine name exactly.
177
   *
178
   * @param string $identifer
0 ignored issues
show
Documentation introduced by
There is no parameter named $identifer. Did you maybe mean $identifier?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
179
   *   The human-friendly name of the target.
180
   * @param string $machineName
181
   *   The machine name of the candidate.
182
   * @param string $label
183
   *   The label of the candidate.
184
   *
185
   * @return boolean
186
   *   Whether a match was found using the identifier.
187
   */
188
    protected function identifyByMachineNameExactly($identifier, $machineName, $label)
0 ignored issues
show
Unused Code introduced by
The parameter $label is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
189
    {
190
        return (mb_strtolower($identifier) === mb_strtolower($machineName));
191
    }
192
193
  /**
194
   * Matches an identifer against a label exactly.
195
   *
196
   * @param string $identifer
0 ignored issues
show
Documentation introduced by
There is no parameter named $identifer. Did you maybe mean $identifier?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
197
   *   The human-friendly name of the target.
198
   * @param string $machineName
199
   *   The machine name of the candidate.
200
   * @param string $label
201
   *   The label of the candidate.
202
   *
203
   * @return boolean
204
   *   Whether a match was found using the identifier.
205
   */
206
    protected function identifyByLabelExactly($identifier, $machineName, $label)
0 ignored issues
show
Unused Code introduced by
The parameter $machineName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
207
    {
208
        return (mb_strtolower($identifier) === mb_strtolower($label));
209
    }
210
211
  /**
212
   * Matches an identifer against a machine name removing the prefix.
213
   *
214
   * @param string $identifer
0 ignored issues
show
Documentation introduced by
There is no parameter named $identifer. Did you maybe mean $identifier?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
215
   *   The human-friendly name of the target.
216
   * @param string $machineName
217
   *   The machine name of the candidate.
218
   * @param string $label
219
   *   The label of the candidate.
220
   *
221
   * @return boolean
222
   *   Whether a match was found using the identifier.
223
   */
224
    protected function identifyByMachineNameWithoutPrefix($identifier, $machineName, $label)
0 ignored issues
show
Unused Code introduced by
The parameter $label is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
225
    {
226
        if (substr($machineName, 0, 6) === $this->prefix) {
227
            $machineName = substr($machineName, 6);
228
        }
229
        return (mb_strtolower($identifier) === mb_strtolower($machineName));
230
    }
231
232
  /**
233
   * Matches an identifer against a machine name removing underscores from it.
234
   *
235
   * @param string $identifer
0 ignored issues
show
Documentation introduced by
There is no parameter named $identifer. Did you maybe mean $identifier?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
236
   *   The human-friendly name of the target.
237
   * @param string $machineName
238
   *   The machine name of the candidate.
239
   * @param string $label
240
   *   The label of the candidate.
241
   *
242
   * @return boolean
243
   *   Whether a match was found using the identifier.
244
   */
245
    protected function identifyByMachineNameWithoutUnderscores($identifier, $machineName, $label)
0 ignored issues
show
Unused Code introduced by
The parameter $label is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
246
    {
247
        $machineName = str_replace('_', ' ', $machineName);
248
        return (mb_strtolower($identifier) === mb_strtolower($machineName));
249
    }
250
251
  /**
252
   * Matches an identifer against a machine name, removing prefix & underscores.
253
   *
254
   * @param string $identifer
0 ignored issues
show
Documentation introduced by
There is no parameter named $identifer. Did you maybe mean $identifier?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
255
   *   The human-friendly name of the target.
256
   * @param string $machineName
257
   *   The machine name of the candidate.
258
   * @param string $label
259
   *   The label of the candidate.
260
   *
261
   * @return boolean
262
   *   Whether a match was found using the identifier.
263
   */
264
    protected function identifyByMachineNameWithoutPrefixAndUnderscores($identifier, $machineName, $label)
0 ignored issues
show
Unused Code introduced by
The parameter $label is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
265
    {
266
        if (substr($machineName, 0, 6) === "field_") {
267
            $machineName = substr($machineName, 6);
268
        }
269
        $machineName = str_replace('_', ' ', $machineName);
270
        return (mb_strtolower($identifier) === mb_strtolower($machineName));
271
    }
272
}
273