Completed
Push — master ( 3c8880...e2c218 )
by Dmitry
06:42 queued 02:46
created

SearchModelTrait::scenarios()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
ccs 0
cts 3
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * HiPanel core package
5
 *
6
 * @link      https://hipanel.com/
7
 * @package   hipanel-core
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2014-2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hipanel\base;
13
14
use hiqdev\hiart\ActiveQuery;
15
use hiqdev\hiart\ActiveRecord;
16
use yii\data\ActiveDataProvider;
17
use yii\helpers\ArrayHelper;
18
19
/**
20
 * Trait SearchModelTrait
21
 * Basic behavior for search models.
22
 */
23
trait SearchModelTrait
24
{
25
    public static $filterConditions = ['in', 'like', 'gt', 'ge', 'lt', 'le'];
26
27
    public function attributes()
28
    {
29
        return $this->searchAttributes();
30
    }
31
32
    protected function searchAttributes()
33
    {
34
        static $attributes = [];
35
36
        if ($attributes === []) {
37
            foreach (parent::attributes() as $attribute) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (attributes() instead of searchAttributes()). Are you sure this is correct? If so, you might want to change this to $this->attributes().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
38
                $attributes = array_merge($attributes, $this->buildAttributeConditions($attribute));
39
            }
40
        }
41
42
        return $attributes;
43
    }
44
45
    /**
46
     * Builds all possible $attribute names using [[$filterConditions]].
47
     *
48
     * @param $attribute
49
     * @return array
50
     */
51
    protected function buildAttributeConditions($attribute)
52
    {
53
        $attributes = [];
54
        foreach (array_merge([''], static::$filterConditions) as $condition) {
55
            $attributes[] = $attribute . ($condition === '' ? '' : "_$condition");
56
        }
57
        return $attributes;
58
    }
59
60
    public function rules()
61
    {
62
        $rules = parent::rules();
63
        $rules[] = [$this->searchAttributes(), 'safe'];
64
65
        return $rules;
66
    }
67
68
    public function scenarios()
69
    {
70
        // bypass scenarios() implementation in the parent class
71
        return \yii\base\Model::scenarios();
72
    }
73
74
    /**
75
     * Creates data provider instance with search query applied.
76
     * @param $params
77
     * @param array $dataProviderConfig
78
     * @throws \yii\base\InvalidConfigException
79
     * @return ActiveDataProvider
80
     */
81
    public function search($params, $dataProviderConfig = [])
82
    {
83
        /**
84
         * @var ActiveRecord
85
         * @var ActiveRecord $class
86
         * @var ActiveQuery $query
87
         */
88
        $class = get_parent_class();
89
        $query = $class::find(); // $class::find()->orderBy($sort->orders)->all(); if $sort is Sort
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
90
91
        $dataProvider = new ActiveDataProvider(ArrayHelper::merge(['query' => $query], $dataProviderConfig));
92
93
        if (!($this->load($params) && $this->validate())) {
0 ignored issues
show
Bug introduced by
It seems like load() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
Bug introduced by
It seems like validate() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
94
            return $dataProvider;
95
        }
96
97
        foreach ($this->attributes() as $attribute) {
98
            if (($value = $this->{$attribute}) === null) {
99
                continue;
100
            }
101
            /*
102
             * Extracts underscore suffix from the key.
103
             *
104
             * Examples:
105
             * client_id -> 0 - client_id, 1 - client, 2 - _id, 3 - id
106
             * server_owner_like -> 0 - server_owner_like, 1 - server_owner, 2 - _like, 3 - like
107
             */
108
            preg_match('/^(.*?)(_((?:.(?!_))+))?$/', $attribute, $matches);
109
110
            /// If the suffix is in the list of acceptable suffix filer conditions
111
            if ($matches[3] && in_array($matches[3], static::$filterConditions, true)) {
112
                $cmp = $matches[3];
113
                $attribute = $matches[1];
114
            } else {
115
                $cmp = 'eq';
116
            }
117
            $query->andFilterWhere([$cmp, $attribute, $value]);
118
        }
119
120
        return $dataProvider;
121
    }
122
}
123