Completed
Push — master ( 8bd8be...0f36fe )
by Oscar
03:22
created

SimpleCrud::save()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 22
rs 8.9197
cc 4
eloc 13
nc 4
nop 2
1
<?php
2
3
namespace Folk\Entities;
4
5
use Folk\SearchQuery;
6
use SimpleCrud\Row;
7
use SimpleCrud\Scheme\Scheme;
8
9
abstract class SimpleCrud extends AbstractEntity implements EntityInterface
10
{
11
    protected $searchFields;
12
    protected $firstField;
13
14
    /**
15
     * Returns the simple-crud table.
16
     * 
17
     * @return SimpleCrud\Table
18
     */
19
    abstract protected function getTable();
20
21
    protected function getQuery(SearchQuery $search)
22
    {
23
        $table = $this->getTable();
24
25
        $query = $table->select();
26
27
        //Filter by id
28
        if (count($search->getIds())) {
29
            $query->byId($search->getIds());
30
        }
31
        
32
        if ($search->getPage() !== null) {
33
            $limit = $search->getLimit();
34
35
            $query->offset(($search->getPage() * $limit) - $limit)->limit($limit);
36
        }
37
38
        if ($this->searchFields === null) {
39
            $this->searchFields = [$this->getFirstField()];
40
        }
41
42
        $orderBy = $search->getSort();
43
44
        if (!empty($orderBy) && isset($table->getScheme()['fields'][$orderBy])) {
45
            $query->orderBy("`{$table->name}`.`{$orderBy}`", $search->getDirection());
46
        } else {
47
            $query->orderBy("`{$table->name}`.`id`", 'DESC');
48
        }
49
50
        //Filter by words
51
        foreach ($search->getWords() as $k => $word) {
52
            foreach ($this->searchFields as $field) {
53
                $query->where("`{$table->name}`.`{$field}` LIKE :w{$k}", [":w{$k}" => "%{$word}%"]);
54
            }
55
        }
56
57
        //Filter by relations
58
        $db = $table->getDatabase();
59
60
        foreach ($search->getConditions() as $name => $value) {
61
            $related = $db->$name
62
                ->select()
63
                ->by('id', $value)
64
                ->run();
65
66
            $query->relatedWith($related);
67
        }
68
69
        return $query;
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function search(SearchQuery $search)
76
    {
77
        $result = [];
78
79
        foreach ($this->getQuery($search)->run() as $row) {
80
            $result[$row->id] = $row->toArray();
81
        }
82
83
        return $result;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function create(array $data)
90
    {
91
        $row = $this->getTable()->create();
92
93
        $this->save($row, $data);
94
95
        return $row->id;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function read($id)
102
    {
103
        $table = $this->getTable();
104
105
        $row = $table[$id];
106
107
        if (empty($row)) {
108
            return;
109
        }
110
111
        $relations = $table->getScheme()['relations'];
112
        $array = $row->toArray();
113
114
        foreach ($relations as $name => $relation) {
115
            if ($relation[0] === Scheme::HAS_MANY || $relation[0] === Scheme::HAS_MANY_TO_MANY) {
116
                $array[$name] = array_values($row->$name->id);
117
            }
118
        }
119
120
        return $array;
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126
    public function update($id, array $data)
127
    {
128
        $row = $this->getTable()[$id];
129
130
        $this->save($row, $data);
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function delete($id)
137
    {
138
        $table = $this->getTable();
139
140
        unset($table[$id]);
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function getLabel($id, array $data)
147
    {
148
        return "{$id} - ".$data[$this->getFirstField()];
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    protected function getFirstField()
155
    {
156
        if ($this->firstField === null) {
157
            foreach (array_keys($this->getTable()->getScheme()['fields']) as $field) {
158
                if ($field !== 'id') {
159
                    return $this->firstField = $field;
160
                }
161
            }
162
        }
163
164
        return $this->firstField;
165
    }
166
167
    protected function save(Row $row, array $data)
168
    {
169
        $table = $this->getTable();
170
        $db = $table->getDatabase();
171
        $scheme = $table->getScheme();
172
173
        foreach ($data as $name => $value) {
174
            if (isset($scheme['relations'][$name])) {
175
                $row->unrelateAll($db->$name);
176
177
                $rows = $db->$name->select()->by('id', $value)->run();
178
179
                foreach ($rows as $r) {
180
                    $row->relate($r);
181
                }
182
            } else {
183
                $row->$name = $value;
184
            }
185
        }
186
187
        $row->save();
188
    }
189
}
190