Passed
Pull Request — master (#77)
by Marco
04:31 queued 02:43
created

DataResolver::resolveDataObject()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

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