Completed
Push — master ( be2db5...c83fb2 )
by
03:24
created

AutoWithTrait::parseColumnsParam()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 2
Metric Value
dl 0
loc 23
rs 8.7972
c 4
b 0
f 2
cc 4
eloc 13
nc 6
nop 0
1
<?php
2
3
/**
4
 * Created by PhpStorm.
5
 * User: xuan
6
 * Date: 9/22/15
7
 * Time: 12:06 AM.
8
 */
9
namespace PHPHub\Repositories\Eloquent\Traits;
10
11
use Exception;
12
use Input;
13
use PHPHub\Transformers\IncludeManager\IncludeManager;
14
15
trait AutoWithTrait
16
{
17
    /**
18
     * 用户请求引入字段.
19
     *
20
     * @var array
21
     */
22
    protected $param_columns = null;
23
24
    /**
25
     * 根节点的字段.
26
     *
27
     * @var array
28
     */
29
    protected $param_root_columns = [];
30
31
    /**
32
     * 自动 with include 的关联.
33
     *
34
     * @return $this
35
     */
36
    public function autoWith()
37
    {
38
        $include_manager = app(IncludeManager::class);
39
40
        $param_columns = $this->parseColumnsParam();
41
        $which_includes = $include_manager->figureOutWhichIncludes();
42
43
        foreach ($which_includes as $include_name) {
44
            $include = $include_manager->getIncludable($include_name);
45
            $include->setColumns(array_get($param_columns, $include_name, []));
46
47
            if (! $include->getForeignKey()) {
48
                $this->with($include->getRelation());
0 ignored issues
show
Bug introduced by
It seems like with() 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...
49
            } else {
50
                $this->withOnly($include->getRelation(), $include->figureOutWhichColumns(), $include->isWithTrashed());
0 ignored issues
show
Bug introduced by
It seems like withOnly() 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...
51
            }
52
        }
53
54
        return $this;
55
    }
56
57
    /**
58
     * 添加一个可用的引入项.
59
     *
60
     * @param $name
61
     * @param $default_columns
62
     *
63
     * @return $this
64
     *
65
     * @throws Exception
66
     */
67
    public function addAvailableInclude($name, $default_columns)
68
    {
69
        $method_name = camel_case('include_'.str_replace('.', '_', $name));
70
71
        if (! method_exists($this, $method_name)) {
72
            throw new Exception("You should define $method_name in your repository");
73
        }
74
75
        call_user_func([$this, $method_name], $default_columns);
76
77
        return $this;
78
    }
79
80
    /**
81
     * 设置数据要查询的字段,自动绑定 include 关联的外键.
82
     *
83
     * @param $columns
84
     *
85
     * @return $this
86
     */
87
    public function autoWithRootColumns($columns)
88
    {
89
        $this->parseColumnsParam();
90
91
        $include_manager = app(IncludeManager::class);
92
        $this->model = $this->model
0 ignored issues
show
Bug introduced by
The property model does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
93
            ->select(array_merge($this->param_root_columns, $columns, $include_manager->getForeignKeys()));
94
95
        return $this;
96
    }
97
98
    /**
99
     * 解析 columns 参数,用于指定 include 关联的字段
100
     * eg. ?include=user&columns=user(name,avatar,gender).
101
     *
102
     * @return array
103
     */
104
    private function parseColumnsParam()
105
    {
106
        if (null !== $this->param_columns) {
107
            $this->param_columns;
108
        }
109
        $result = [];
110
        $items = explode(',', Input::get('columns'));
111
112
        foreach ($items as $item) {
113
            $arr = explode('(', $item);
114
            if (count($arr) !== 2) {
115
                continue;
116
            }
117
118
            list($include, $columns_str) = $arr;
119
120
            $result[$include] = explode(':', trim($columns_str, ')'));
121
        }
122
123
        $this->param_root_columns = array_get($result, 'root', []);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_get($result, 'root', array()) of type * is incompatible with the declared type array of property $param_root_columns.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
124
125
        return $this->param_columns = array_except($result, ['root']);
126
    }
127
}
128