Passed
Push — sheepy/introspection ( 17782f...ab3d0e )
by Marco
03:03
created

DataResolver::resolveList()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 10
c 1
b 0
f 0
dl 0
loc 16
ccs 11
cts 11
cp 1
rs 9.9332
cc 4
nc 4
nop 0
crap 4
1
<?php
2
3
namespace Firesphere\SolrSearch\Helpers;
4
5
use Exception;
6
use SilverStripe\Core\ClassInfo;
7
use SilverStripe\Dev\Debug;
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
    protected $component;
16
    protected $columns = [];
17
    protected $columnName = '';
18
19 13
    public function __construct($component, $columns = [])
20
    {
21 13
        if (!is_array($columns)) {
22 11
            $columns = array_filter(explode('.', $columns));
23
        }
24 13
        $this->columns = $columns;
25 13
        $this->component = $component;
26 13
        $this->columnName = $this->columns ? array_shift($this->columns) : null;
27 13
    }
28
29
    /**
30
     * @param DataObject|ArrayData|SS_List $obj
31
     * @param array|string $columns
32
     *
33
     * @return mixed
34
     * @throws Exception
35
     */
36 13
    public static function identify($obj, $columns = [])
37
    {
38 13
        $instance = new self($obj, $columns);
39 13
        if ($obj instanceof DataObject) {
40 8
            return $instance->resolveDataObject();
41
        }
42 10
        if ($obj instanceof ArrayData) {
43 4
            return $instance->resolveArrayData();
44
        }
45 7
        if ($obj instanceof SS_List) {
0 ignored issues
show
introduced by
$obj is always a sub-type of SilverStripe\ORM\SS_List.
Loading history...
46 3
            return $instance->resolveList();
47
        }
48 5
        if ($obj instanceof DBField) {
49 4
            return $instance->resolveField();
50
        }
51 1
        throw new Exception(sprintf('Class: %s, is not supported.', ClassInfo::shortName($obj)));
52
    }
53
54
    /**
55
     * @param DataObject|ArrayData|SS_List $component
56
     * @param array $columns
57
     *
58
     * @return void
59
     * @throws Exception
60
     */
61 3
    protected function cannotIdentifyException($component, $columns = [])
62
    {
63 3
        throw new Exception(
64 3
            sprintf(
65 3
                'Cannot identify, "%s" from class "%s"',
66 3
                implode('.', $columns),
67 3
                ClassInfo::shortName($component)
68
            )
69
        );
70
    }
71
72
    /**
73
     * Resolves a Single field in the database.
74
     * @return mixed
75
     * @throws Exception
76
     */
77 4
    protected function resolveField()
78
    {
79 4
        if ($this->columnName) {
80 4
            if ($this->component->hasMethod($this->columnName)) {
81 3
                $method = $this->columnName;
82 2
            } elseif ($this->component->hasMethod("get{$this->columnName}")) {
83 1
                $method = "get{$this->columnName}";
84
            } else {
85 1
                throw new Exception(
86 1
                    sprintf('Method, "%s" not found on "%s"', $this->columnName, ClassInfo::shortName($this->component))
87
                );
88
            }
89 3
            $value = $this->component->$method();
90
        } else {
91 2
            $value = $this->component->getValue();
92
        }
93 3
        if ($this->columns) {
94 1
            $this->cannotIdentifyException($this->component, $this->columns);
95
        }
96 2
        return $value;
97
    }
98
99
    /**
100
     * Resolves a DataObject value
101
     * @return mixed
102
     * @throws Exception
103
     */
104 8
    protected function resolveDataObject()
105
    {
106 8
        if (empty($this->columnName)) {
107 2
            return $this->component->toMap();
108
        }
109
        // Inspect component for element $relation
110 7
        if ($this->component->hasMethod($this->columnName)) {
111 1
            $relation = $this->columnName;
112 1
            return self::identify($this->component->$relation(), $this->columns);
113
        }
114
        // Inspect component has attribute
115 7
        if ($this->component->hasField($this->columnName)) {
116 6
            $data = $this->component->{$this->columnName};
117 6
            $dbObject = $this->component->dbObject($this->columnName);
118 6
            if ($dbObject) {
119 4
                $dbObject->setValue($data);
120 4
                return self::identify($dbObject, $this->columns);
121
            }
122 2
            return $data;
123
        }
124 1
        $this->cannotIdentifyException($this->component, [$this->columnName]);
125
    }
126
127
    /**
128
     * Resolves an ArrayData value
129
     * @return mixed
130
     * @throws Exception
131
     */
132 4
    public function resolveArrayData()
133
    {
134 4
        if (empty($this->columnName)) {
135 1
            return $this->component->toMap();
136
        }
137
        // Inspect component has attribute
138 3
        if ($this->component->hasField($this->columnName) && empty($this->columns)) {
139 2
            return $this->component->{$this->columnName};
140
        }
141 1
        $this->cannotIdentifyException($this->component, array_merge([$this->columnName], $this->columns));
142
    }
143
144
    /**
145
     * Resolves a DataList values
146
     * @return array|mixed
147
     * @throws Exception
148
     */
149 3
    public function resolveList()
150
    {
151 3
        if (empty($this->columnName)) {
152 3
            return $this->component->toNestedArray();
153
        }
154
        // Inspect $component for element $relation
155 2
        if ($this->component->hasMethod($this->columnName)) {
156 2
            $relation = $this->columnName;
157 2
            return self::identify($this->component->$relation(), $this->columns);
158
        }
159 1
        $data = [];
160 1
        array_unshift($this->columns, $this->columnName);
161 1
        foreach ($this->component as $component) {
162 1
            $data[] = self::identify($component, $this->columns);
163
        }
164 1
        return $data;
165
    }
166
}
167