Completed
Push — master ( aeb3a4...04afb5 )
by brian
01:57
created

PartialLanguageMatcher   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 3

Test Coverage

Coverage 100%
Metric Value
wmc 10
cbo 3
dl 0
loc 81
ccs 29
cts 29
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A hasMatch() 0 4 1
A match() 0 14 2
A getMatchingIndexes() 0 12 3
A partialLangMatches() 0 18 4
1
<?php
2
3
/**
4
 * @copyright   (c) 2006-present brian ridley
5
 * @author      brian ridley <[email protected]>
6
 * @license     http://opensource.org/licenses/MIT MIT
7
 */
8
9
namespace ptlis\ConNeg\Negotiator\Matcher;
10
11
use ptlis\ConNeg\Preference\Matched\MatchedPreference;
12
use ptlis\ConNeg\Preference\Matched\MatchedPreferenceInterface;
13
use ptlis\ConNeg\Preference\PreferenceInterface;
14
15
/**
16
 * Matcher for server-provided partial languages (e.g. 'en-*').
17
 */
18
class PartialLanguageMatcher implements MatcherInterface
19
{
20
    /**
21
     * @inheritDoc
22
     */
23 54
    public function hasMatch($fromField, array $matchingList, PreferenceInterface $clientPref)
24
    {
25 54
        return count($this->getMatchingIndexes($fromField, $matchingList, $clientPref)) > 0;
26
    }
27
28
    /**
29
     * @inheritDoc
30
     */
31 6
    public function match($fromField, array $matchingList, PreferenceInterface $clientPref)
32
    {
33 6
        $matchingIndexList = $this->getMatchingIndexes($fromField, $matchingList, $clientPref);
34
35 6
        foreach ($matchingIndexList as $matchingIndex) {
36 6
            $matchingList[$matchingIndex] = new MatchedPreference(
37 6
                $fromField,
38 6
                $clientPref,
39 6
                $matchingList[$matchingIndex]->getServerPreference()
40 6
            );
41 6
        }
42
43 6
        return $matchingList;
44
    }
45
46
    /**
47
     * Returns an array of indexes for of matches of higher precedence than the existing pairing.
48
     *
49
     * @param string $fromField
50
     * @param MatchedPreferenceInterface[] $matchingList
51
     * @param PreferenceInterface $clientPref
52
     *
53
     * @return int[]
54
     */
55 54
    private function getMatchingIndexes($fromField, array $matchingList, PreferenceInterface $clientPref)
56
    {
57 54
        $matchingIndexList = array();
58
59 54
        foreach ($matchingList as $key => $matching) {
60 53
            if ($this->partialLangMatches($fromField, $matching, $clientPref)) {
61 6
                $matchingIndexList[] = $key;
62 6
            }
63 54
        }
64
65 54
        return $matchingIndexList;
66
    }
67
68
    /**
69
     * Returns true if the server preference contains a partial language that matches the language in the client
70
     * preference.
71
     *
72
     * e.g. An server variant of en-* would match en, en-US but not es-ES
73
     *
74
     * @param string $fromField
75
     * @param MatchedPreferenceInterface $matchedPreference
76
     * @param PreferenceInterface $newClientPref
77
     *
78
     * @return bool
79
     */
80 53
    private function partialLangMatches(
81
        $fromField,
82
        MatchedPreferenceInterface $matchedPreference,
83
        PreferenceInterface $newClientPref
84
    ) {
85 53
        $serverPref = $matchedPreference->getServerPreference();
86 53
        $oldClientPref = $matchedPreference->getClientPreference();
87
88
        // Note that this only supports the simplest case of (e.g.) en-* matching en-GB and en-US, additional
89
        // Language tags are explicitly ignored
90 53
        list($clientMainLang) = explode('-', $newClientPref->getVariant());
91 53
        list($serverMainLang) = explode('-', $serverPref->getVariant());
92
93 53
        return PreferenceInterface::LANGUAGE === $fromField
94 53
            && PreferenceInterface::PARTIAL_WILDCARD === $serverPref->getPrecedence()
95 53
            && $clientMainLang == $serverMainLang
96 53
            && $newClientPref->getPrecedence() > $oldClientPref->getPrecedence();
97
    }
98
}
99