Parser   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 118
rs 10
c 0
b 0
f 0
wmc 11
lcom 2
cbo 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A parseWeights() 0 8 2
A addMissingWeights() 0 14 3
A stripWildcards() 0 4 1
A parseQuery() 0 10 2
A splitString() 0 6 1
A addWildcards() 0 8 1
1
<?php
2
3
namespace Sofa\Eloquence\Searchable;
4
5
use Sofa\Eloquence\Contracts\Searchable\Parser as ParserContract;
6
7
class Parser implements ParserContract
8
{
9
    /**
10
     * Default search weight.
11
     *
12
     * @var integer
13
     */
14
    protected $weight;
15
16
    /**
17
     * Wildcard token.
18
     *
19
     * @var string
20
     */
21
    protected $wildcard;
22
23
    /**
24
     * Create new parser instance.
25
     *
26
     * @param integer $weight
27
     */
28
    public function __construct($weight = 1, $wildcard = '*')
29
    {
30
        $this->weight   = $weight;
31
        $this->wildcard = $wildcard;
32
    }
33
34
    /**
35
     * Parse searchable columns.
36
     *
37
     * @param  array|string $columns
38
     * @return array
39
     */
40
    public function parseWeights($columns)
41
    {
42
        if (is_string($columns)) {
43
            $columns = func_get_args();
44
        }
45
46
        return $this->addMissingWeights($columns);
47
    }
48
49
    /**
50
     * Add search weight to the columns if missing.
51
     *
52
     * @param array $columns
53
     */
54
    protected function addMissingWeights(array $columns)
55
    {
56
        $parsed = [];
57
58
        foreach ($columns as $column => $weight) {
59
            if (is_numeric($column)) {
60
                list($column, $weight) = [$weight, $this->weight];
61
            }
62
63
            $parsed[$column] = $weight;
64
        }
65
66
        return $parsed;
67
    }
68
69
    /**
70
     * Strip wildcard tokens from the word.
71
     *
72
     * @param  string $word
73
     * @return string
74
     */
75
    public function stripWildcards($word)
76
    {
77
        return str_replace($this->wildcard, '%', trim($word, $this->wildcard));
78
    }
79
80
    /**
81
     * Parse query string into separate words with wildcards if applicable.
82
     *
83
     * @param  string  $query
84
     * @param  boolean $fulltext
85
     * @return array
86
     */
87
    public function parseQuery($query, $fulltext = true)
88
    {
89
        $words = $this->splitString($query);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->splitString($query); of type string[]|false adds false to the return on line 95 which is incompatible with the return type declared by the interface Sofa\Eloquence\Contracts...able\Parser::parseQuery of type array. It seems like you forgot to handle an error condition.
Loading history...
90
91
        if ($fulltext) {
92
            $words = $this->addWildcards($words);
0 ignored issues
show
Security Bug introduced by
It seems like $words can also be of type false; however, Sofa\Eloquence\Searchable\Parser::addWildcards() does only seem to accept array, did you maybe forget to handle an error condition?
Loading history...
93
        }
94
95
        return $words;
96
    }
97
98
    /**
99
     * Split query string into words/phrases to be searched.
100
     *
101
     * @param  string $query
102
     * @return array
103
     */
104
    protected function splitString($query)
105
    {
106
        preg_match_all('/(?<=")[\w ][^"]+(?=")|(?<=\s|^)[^\s"]+(?=\s|$)/u', $query, $matches);
107
108
        return reset($matches);
109
    }
110
111
    /**
112
     * Add wildcard tokens to the words.
113
     *
114
     * @param array $words
115
     */
116
    protected function addWildcards(array $words)
117
    {
118
        $token = $this->wildcard;
119
120
        return array_map(function ($word) use ($token) {
121
            return preg_replace('/\*+/', '*', "{$token}{$word}{$token}");
122
        }, $words);
123
    }
124
}
125