Passed
Push — sheepy/introspection ( e91b37...a56939 )
by Simon
04:24
created

DataResolver::cannotIdentifyException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Firesphere\SolrSearch\Helpers;
4
5
use Exception;
6
use SilverStripe\Core\ClassInfo;
7
use SilverStripe\ORM\ArrayList;
8
use SilverStripe\ORM\DataObject;
9
use SilverStripe\ORM\FieldType\DBField;
10
use SilverStripe\ORM\SS_List;
11
use SilverStripe\View\ArrayData;
12
13
class DataResolver
14
{
15
    /**
16
     * @var DataObject|ArrayList|SS_List|DBField
17
     */
18
    protected $component;
19
    /**
20
     * @var array
21
     */
22
    protected $columns = [];
23
    /**
24
     * @var mixed|string|null
25
     */
26
    protected $columnName = '';
27
    /**
28
     * Supported object types
29
     * @var array map of objects to methods
30
     */
31
    private static $objTypes = [
32
        DataObject::class => 'DataObject',
33
        ArrayData::class  => 'ArrayData',
34
        SS_List::class    => 'List',
35
        DBField::class    => 'Field'
36
    ];
37
38
    /**
39
     * DataResolver constructor.
40
     * @param DataObject|ArrayList|SS_List $component
41
     * @param array|string $columns
42
     */
43 16
    public function __construct($component, $columns = [])
44
    {
45 16
        if (!is_array($columns)) {
46 14
            $columns = array_filter(explode('.', $columns));
47
        }
48 16
        $this->columns = $columns;
49 16
        $this->component = $component;
50 16
        $this->columnName = $this->columns ? array_shift($this->columns) : null;
51 16
    }
52
53
    /**
54
     * @param DataObject|ArrayData|SS_List|DBField $obj
55
     * @param array|string $columns
56
     *
57
     * @return mixed
58
     * @throws Exception
59
     */
60 17
    public static function identify($obj, $columns = [])
61
    {
62 17
        foreach (static::$objTypes as $type => $method) {
0 ignored issues
show
Bug introduced by
Since $objTypes is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $objTypes to at least protected.
Loading history...
63 17
            if ($obj instanceof $type) {
64 16
                $method = 'resolve' . $method;
65
66 17
                return (new self($obj, $columns))->{$method}();
0 ignored issues
show
Bug introduced by
It seems like $obj can also be of type SilverStripe\ORM\FieldType\DBField and SilverStripe\View\ArrayData; however, parameter $component of Firesphere\SolrSearch\He...Resolver::__construct() does only seem to accept SilverStripe\ORM\ArrayLi...ilverStripe\ORM\SS_List, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

66
                return (new self(/** @scrutinizer ignore-type */ $obj, $columns))->{$method}();
Loading history...
67
            }
68
        }
69
70 1
        throw new Exception(sprintf('Class: %s, is not supported.', ClassInfo::shortName($obj)));
71
    }
72
73
    /**
74
     * @param DataObject|ArrayData|SS_List $component
75
     * @param array $columns
76
     *
77
     * @return void
78
     * @throws Exception
79
     */
80 7
    protected function cannotIdentifyException($component, $columns = [])
81
    {
82 7
        throw new Exception(
83 7
            sprintf(
84 7
                'Cannot identify, "%s" from class "%s"',
85 7
                implode('.', $columns),
86 7
                ClassInfo::shortName($component)
87
            )
88
        );
89
    }
90
91
    /**
92
     * Resolves a Single field in the database.
93
     * @return mixed
94
     * @throws Exception
95
     */
96 8
    protected function resolveField()
97
    {
98 8
        if ($this->columnName) {
99 4
            if ($this->component->hasMethod($this->columnName)) {
1 ignored issue
show
Bug introduced by
The method hasMethod() does not exist on SilverStripe\ORM\SS_List. It seems like you code against a sub-type of said class. However, the method does not exist in SilverStripe\ORM\Sortable or SilverStripe\ORM\Filterable or SilverStripe\ORM\Relation or SilverStripe\ORM\Limitable or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

99
            if ($this->component->/** @scrutinizer ignore-call */ hasMethod($this->columnName)) {
Loading history...
100 3
                $method = $this->columnName;
101 2
            } elseif ($this->component->hasMethod("get{$this->columnName}")) {
102 1
                $method = "get{$this->columnName}";
103
            } else {
104 1
                throw new Exception(
105 1
                    sprintf('Method, "%s" not found on "%s"', $this->columnName, ClassInfo::shortName($this->component))
106
                );
107
            }
108 3
            $value = $this->component->$method();
109
        } else {
110 6
            $value = $this->component->getValue();
1 ignored issue
show
Bug introduced by
The method getValue() does not exist on SilverStripe\ORM\SS_List. It seems like you code against a sub-type of said class. However, the method does not exist in SilverStripe\ORM\Sortable or SilverStripe\ORM\Filterable or SilverStripe\ORM\Relation or SilverStripe\ORM\Limitable or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
            /** @scrutinizer ignore-call */ 
111
            $value = $this->component->getValue();
Loading history...
111
        }
112 7
        if (!empty($this->columns)) {
113 1
            $this->cannotIdentifyException($this->component, $this->columns);
0 ignored issues
show
Bug introduced by
It seems like $this->component can also be of type SilverStripe\ORM\FieldType\DBField; however, parameter $component of Firesphere\SolrSearch\He...nnotIdentifyException() does only seem to accept SilverStripe\ORM\DataObj...erStripe\View\ArrayData, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

113
            $this->cannotIdentifyException(/** @scrutinizer ignore-type */ $this->component, $this->columns);
Loading history...
114
        }
115
116 6
        return $value;
117
    }
118
119
    /**
120
     * Resolves a DataObject value
121
     * @return mixed
122
     * @throws Exception
123
     */
124 12
    protected function resolveDataObject()
125
    {
126 12
        if (empty($this->columnName)) {
127 2
            return $this->component->toMap();
1 ignored issue
show
Bug introduced by
The method toMap() does not exist on SilverStripe\ORM\SS_List. It seems like you code against a sub-type of said class. However, the method does not exist in SilverStripe\ORM\Sortable or SilverStripe\ORM\Filterable or SilverStripe\ORM\Relation or SilverStripe\ORM\Limitable or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

127
            return $this->component->/** @scrutinizer ignore-call */ toMap();
Loading history...
128
        }
129
        // Inspect component for element $relation
130 11
        if ($this->component->hasMethod($this->columnName)) {
131 1
            $relation = $this->columnName;
132
133 1
            return self::identify($this->component->$relation(), $this->columns);
134
        }
135
        // Inspect component has attribute
136 11
        if ($this->component->hasField($this->columnName)) {
0 ignored issues
show
Bug introduced by
The method hasField() does not exist on SilverStripe\ORM\SS_List. It seems like you code against a sub-type of said class. However, the method does not exist in SilverStripe\ORM\Sortable or SilverStripe\ORM\Filterable or SilverStripe\ORM\Relation or SilverStripe\ORM\Limitable or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation or SilverStripe\ORM\Relation. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

136
        if ($this->component->/** @scrutinizer ignore-call */ hasField($this->columnName)) {
Loading history...
137 10
            $data = $this->component->{$this->columnName};
138 10
            $dbObject = $this->component->dbObject($this->columnName);
1 ignored issue
show
Bug introduced by
The method dbObject() does not exist on SilverStripe\ORM\SS_List. It seems like you code against a sub-type of said class. However, the method does not exist in SilverStripe\ORM\Sortable or SilverStripe\ORM\Filterable or SilverStripe\ORM\Limitable. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

138
            /** @scrutinizer ignore-call */ 
139
            $dbObject = $this->component->dbObject($this->columnName);
Loading history...
139 10
            if ($dbObject) {
140 8
                $dbObject->setValue($data);
141
142 8
                return self::identify($dbObject, $this->columns);
143
            }
144
145 2
            return $data;
146
        }
147 5
        $this->cannotIdentifyException($this->component, [$this->columnName]);
0 ignored issues
show
Bug introduced by
It seems like $this->component can also be of type SilverStripe\ORM\FieldType\DBField; however, parameter $component of Firesphere\SolrSearch\He...nnotIdentifyException() does only seem to accept SilverStripe\ORM\DataObj...erStripe\View\ArrayData, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

147
        $this->cannotIdentifyException(/** @scrutinizer ignore-type */ $this->component, [$this->columnName]);
Loading history...
148
    }
149
150
    /**
151
     * Resolves an ArrayData value
152
     * @return mixed
153
     * @throws Exception
154
     */
155 4
    public function resolveArrayData()
156
    {
157 4
        if (empty($this->columnName)) {
158 1
            return $this->component->toMap();
159
        }
160
        // Inspect component has attribute
161 3
        if ($this->component->hasField($this->columnName) && empty($this->columns)) {
162 2
            return $this->component->{$this->columnName};
163
        }
164 1
        $this->cannotIdentifyException($this->component, array_merge([$this->columnName], $this->columns));
0 ignored issues
show
Bug introduced by
It seems like $this->component can also be of type SilverStripe\ORM\FieldType\DBField; however, parameter $component of Firesphere\SolrSearch\He...nnotIdentifyException() does only seem to accept SilverStripe\ORM\DataObj...erStripe\View\ArrayData, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
        $this->cannotIdentifyException(/** @scrutinizer ignore-type */ $this->component, array_merge([$this->columnName], $this->columns));
Loading history...
165
    }
166
167
    /**
168
     * Resolves a DataList values
169
     * @return array|mixed
170
     * @throws Exception
171
     */
172 3
    public function resolveList()
173
    {
174 3
        if (empty($this->columnName)) {
175 3
            return $this->component->toNestedArray();
176
        }
177
        // Inspect $component for element $relation
178 2
        if ($this->component->hasMethod($this->columnName)) {
179 2
            $relation = $this->columnName;
180
181 2
            return self::identify($this->component->$relation(), $this->columns);
182
        }
183 1
        $data = [];
184 1
        array_unshift($this->columns, $this->columnName);
185 1
        foreach ($this->component as $component) {
186 1
            $data[] = self::identify($component, $this->columns);
187
        }
188
189 1
        return $data;
190
    }
191
}
192