Completed
Push — master ( 8f3d8d...5443e3 )
by Andrey
02:32
created

BaseColumn::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Itstructure\GridView\Columns;
4
5
use Exception;
6
use Itstructure\GridView\Filters\{BaseFilter, StubFilter, TextFilter};
7
use Itstructure\GridView\Formatters\{HtmlFormatter, ImageFormatter, TextFormatter, UrlFormatter};
8
use Itstructure\GridView\Interfaces\Formattable;
9
use Itstructure\GridView\Traits\{Configurable, Attributable};
10
11
/**
12
 * Class BaseColumn
13
 * @package Itstructure\GridView\Columns
14
 */
15
abstract class BaseColumn
16
{
17
    use Configurable, Attributable;
18
19
    const
20
        FORMATTER_HTML = 'html',
21
        FORMATTER_IMAGE = 'image',
22
        FORMATTER_TEXT = 'text',
23
        FORMATTER_URL = 'url',
24
25
        FORMATTER_DEFINITIONS = [
26
            self::FORMATTER_HTML => HtmlFormatter::class,
27
            self::FORMATTER_IMAGE => ImageFormatter::class,
28
            self::FORMATTER_TEXT => TextFormatter::class,
29
            self::FORMATTER_URL => UrlFormatter::class,
30
        ];
31
32
    /**
33
     * @var string
34
     */
35
    protected $label;
36
37
    /**
38
     * @var string
39
     */
40
    protected $attribute;
41
42
    /**
43
     * @var bool|null|string
44
     */
45
    protected $sort;
46
47
    /**
48
     * @var string $value
49
     */
50
    protected $value;
51
52
    /**
53
     * @var bool|null|string|BaseFilter
54
     */
55
    protected $filter;
56
57
    /**
58
     * @var string|Formattable
59
     */
60
    protected $format;
61
62
    /**
63
     * BaseColumn constructor.
64
     * @param array $config
65
     */
66
    public function __construct(array $config)
67
    {
68
        $this->loadConfig($config);
69
        $this->buildFilter();
70
        $this->buildFormatter();
71
    }
72
73
    /**
74
     * @param $row
75
     * @return mixed
76
     */
77
    public function getValue($row)
78
    {
79
    }
80
81
    /**
82
     * Render row attribute value.
83
     * @param $row
84
     * @return mixed
85
     */
86
    public function render($row)
87
    {
88
        return $this->formatTo($this->getValue($row));
89
    }
90
91
    /**
92
     * Format value with formatter.
93
     * @param $value
94
     * @return mixed
95
     */
96
    public function formatTo($value)
97
    {
98
        return $this->format->format($value);
99
    }
100
101
    /**
102
     * Get title for grid head.
103
     * @return string
104
     */
105
    public function getLabel(): string
106
    {
107
        return $this->label ?? ucfirst($this->attribute);
108
    }
109
110
    /**
111
     * Get attribute.
112
     * @return string|null
113
     */
114
    public function getAttribute()
115
    {
116
        return $this->attribute;
117
    }
118
119
    /**
120
     * @return bool|null|string
121
     */
122
    public function getSort()
123
    {
124
        if (is_null($this->sort) || $this->sort === true) {
125
            return is_null($this->attribute) ? false : $this->attribute;
126
        }
127
        return $this->sort;
128
    }
129
130
    /**
131
     * @return BaseFilter
132
     */
133
    public function getFilter()
134
    {
135
        return $this->filter;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->filter; (boolean|null|string|BaseFilter) is incompatible with the return type documented by Itstructure\GridView\Columns\BaseColumn::getFilter of type BaseFilter|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
136
    }
137
138
    /**
139
     * @param BaseFilter $filter
140
     */
141
    protected function setFilter(BaseFilter $filter): void
142
    {
143
        $this->filter = $filter;
0 ignored issues
show
Documentation Bug introduced by
It seems like $filter of type object<Itstructure\GridView\Filters\BaseFilter> is incompatible with the declared type boolean|null|string|object<BaseFilter> of property $filter.

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...
144
    }
145
146
    /**
147
     * @return void
148
     */
149
    protected function buildFilter(): void
150
    {
151
        if ($this->filter === false) {
152
            $this->filter = new StubFilter();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Itstructure\GridView\Filters\StubFilter() of type object<Itstructure\GridView\Filters\StubFilter> is incompatible with the declared type boolean|null|string|object<BaseFilter> of property $filter.

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...
153
154
        } else if (is_null($this->filter)) {
155
            $this->filter = new TextFilter([
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Itstructure\GridVie...$this->getAttribute())) of type object<Itstructure\GridView\Filters\TextFilter> is incompatible with the declared type boolean|null|string|object<BaseFilter> of property $filter.

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...
156
                'name' => $this->getAttribute(),
157
            ]);
158
159
        } else if (is_array($this->filter)) {
160
            if (isset($this->filter['class']) && class_exists($this->filter['class'])) {
161
                $this->setFilter(
162
                    new $this->filter['class'](array_merge($this->filter, empty($this->filter['name']) ? [
163
                            'name' => $this->getAttribute()
164
                        ] : [])
165
                    )
166
                );
167
            }
168
        }
169
    }
170
171
    /**
172
     * @param Formattable $formatter
173
     */
174
    protected function setFormatter(Formattable $formatter): void
175
    {
176
        $this->format = $formatter;
177
    }
178
179
    /**
180
     * @throws Exception
181
     * @return void
182
     */
183
    protected function buildFormatter(): void
184
    {
185
        if (is_null($this->format)) {
186
            $class = self::FORMATTER_DEFINITIONS[self::FORMATTER_TEXT];
187
            $this->format = new $class;
188
189
        } else if (is_string($this->format)) {
190
            $class = self::FORMATTER_DEFINITIONS[$this->format] ?? self::FORMATTER_DEFINITIONS[self::FORMATTER_TEXT];
191
            $this->format = new $class;
192
193
        } else if (is_array($this->format)) {
194
            if (isset($this->format['class']) && class_exists($this->format['class'])) {
195
                $this->setFormatter(new $this->format['class']($this->format));
196
            }
197
198
        } else if (!is_object($this->format) || !($this->format instanceof Formattable)) {
199
            throw new Exception('Incorrect formatter.');
200
        }
201
    }
202
}
203