Completed
Push — master ( f81184...3aae6e )
by Andrii
04:04
created

Query   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 168
Duplicated Lines 14.88 %

Coupling/Cohesion

Components 3
Dependencies 1

Test Coverage

Coverage 34.21%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 32
lcom 3
cbo 1
dl 25
loc 168
ccs 26
cts 76
cp 0.3421
rs 9.6
c 1
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A instantiate() 0 6 1
A createCommand() 0 10 2
A one() 0 4 1
B all() 5 19 5
A searchAll() 0 4 1
A search() 0 4 1
A delete() 0 4 1
A count() 0 6 1
A exists() 0 4 1
A action() 0 6 1
A addAction() 0 8 2
A addOption() 0 8 2
A getOption() 0 4 2
A options() 0 6 1
A addOptions() 0 8 2
A body() 0 6 1
A innerJoin() 0 6 1
A fields() 10 10 3
A source() 10 10 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Tools to use API as ActiveRecord for Yii2
4
 *
5
 * @link      https://github.com/hiqdev/yii2-hiart
6
 * @package   yii2-hiart
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\hiart;
12
13
use yii\db\QueryInterface;
14
15
/**
16
 * Query represents API query in a way that is independent from a concrete API.
17
 * Holds API query information:
18
 * - general query data
19
 *      - action: action to be performed with this query, e.g. search, insert, update, delete
20
 *      - options: other additional options, like
21
 *          - raw: do not decode response
22
 *          - batch: batch(bulk) request
23
 *          - timeout, ...
24
 * - insert/update query data
25
 *      - body: insert or update data
26
 * - select query data
27
 *      - select: fields to select
28
 *      - count: marks count query
29
 *      - from: entity being queried, e.g. user
30
 *      - join: data how to join with other entities
31
 * - other standard query options provided with QueryTrait:
32
 *      - where, limit, offset, orderBy, indexBy.
33
 */
34
class Query extends \yii\db\Query implements QueryInterface
35
{
36
    /**
37
     * @var string action that this query performs
38
     */
39
    public $action;
40
41
    /**
42
     * @var array query options e.g. raw, batch
43
     */
44
    public $options = [];
45
46
    public $count;
47
48
    public $body = [];
49
50 1
    public static function instantiate($action, $from, array $options = [])
51
    {
52 1
        $query = new static();
53
54 1
        return $query->action($action)->from($from)->options($options);
55
    }
56
57
    public function createCommand($db = null)
58
    {
59
        if ($db === null) {
60
            throw new \Exception('no db given to Query::createCommand');
61
        }
62
63
        $commandConfig = $db->getQueryBuilder()->build($this);
64
65
        return $db->createCommand($commandConfig);
66
    }
67
68
    public function one($db = null)
69
    {
70
        return $this->limit(1)->addOption('batch', false)->search();
71
    }
72
73
    public function all($db = null)
74
    {
75
        $rows = $this->searchAll();
76
77
        if (!empty($rows) && $this->indexBy !== null) {
78
            $result = [];
79
            foreach ($rows as $row) {
80 View Code Duplication
                if ($this->indexBy instanceof \Closure) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
                    $key = call_user_func($this->indexBy, $row);
82
                } else {
83
                    $key = $row[$this->indexBy];
84
                }
85
                $result[$key] = $row;
86
            }
87
            $rows = $result;
88
        }
89
90
        return $rows;
91
    }
92
93 2
    public function searchAll($db = null)
0 ignored issues
show
Unused Code introduced by
The parameter $db 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...
94
    {
95 2
        return $this->addOption('batch', true)->search();
96
    }
97
98 2
    public function search($db = null)
99
    {
100 2
        return $this->createCommand($db)->search();
101
    }
102
103
    public function delete($db = null, $options = [])
104
    {
105
        return $this->createCommand($db)->deleteByQuery($options);
106
    }
107
108
    public function count($q = '*', $db = null)
109
    {
110
        $this->count = $q;
111
112
        return (int) $this->searchAll();
113
    }
114
115
    public function exists($db = null)
116
    {
117
        return !empty(self::one($db));
118
    }
119
120 1
    public function action($action)
121
    {
122 1
        $this->action = $action;
123
124 1
        return $this;
125
    }
126
127 2
    public function addAction($action)
128
    {
129 2
        if (empty($this->action)) {
130 2
            $this->action = $action;
131 2
        }
132
133 2
        return $this;
134
    }
135
136 2
    public function addOption($name, $value)
137
    {
138 2
        if (!isset($this->options[$name])) {
139 2
            $this->options[$name] = $value;
140 2
        }
141
142 2
        return $this;
143
    }
144
145
    public function getOption($name)
146
    {
147
        return isset($this->options[$name]) ? $this->options[$name] : null;
148
    }
149
150 1
    public function options($options)
151
    {
152 1
        $this->options = $options;
153
154 1
        return $this;
155
    }
156
157
    public function addOptions($options)
158
    {
159
        if (!empty($options)) {
160
            $this->options = array_merge($this->options, $options);
161
        }
162
163
        return $this;
164
    }
165
166 1
    public function body($body)
167
    {
168 1
        $this->body = $body;
169
170 1
        return $this;
171
    }
172
173
    public function innerJoin($table, $on = '', $params = [])
174
    {
175
        $this->join[] = (array) $table;
176
177
        return $this;
178
    }
179
180 View Code Duplication
    public function fields($fields)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
    {
182
        if (is_array($fields) || $fields === null) {
183
            $this->fields = $fields;
0 ignored issues
show
Documentation introduced by
The property fields does not exist on object<hiqdev\hiart\Query>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
184
        } else {
185
            $this->fields = func_get_args();
0 ignored issues
show
Documentation introduced by
The property fields does not exist on object<hiqdev\hiart\Query>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
186
        }
187
188
        return $this;
189
    }
190
191 View Code Duplication
    public function source($source)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192
    {
193
        if (is_array($source) || $source === null) {
194
            $this->source = $source;
0 ignored issues
show
Documentation introduced by
The property source does not exist on object<hiqdev\hiart\Query>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
195
        } else {
196
            $this->source = func_get_args();
0 ignored issues
show
Documentation introduced by
The property source does not exist on object<hiqdev\hiart\Query>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
197
        }
198
199
        return $this;
200
    }
201
}
202