Passed
Branch v1.5.1 (a4c427)
by Wanderson
01:49
created

Orm::paginate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Win\Repositories\Database;
4
5
use Win\Repositories\Pagination;
6
use Win\Models\Model;
7
use Win\Repositories\Database\Orm\FilterTrait;
0 ignored issues
show
Bug introduced by
The type Win\Repositories\Database\Orm\FilterTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Win\Repositories\Database\Orm\PaginationTrait;
0 ignored issues
show
Bug introduced by
The type Win\Repositories\Database\Orm\PaginationTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Win\Repositories\Database\Orm\SortTrait;
0 ignored issues
show
Bug introduced by
The type Win\Repositories\Database\Orm\SortTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Win\Repositories\Database\Sql\Query;
11
12
/**
13
 * Object Relational Mapping
14
 */
15
abstract class Orm
16
{
17
	/** @var string */
18
	const TABLE = '';
19
20
	/** @var string */
21
	const TITLE = '';
22
23
	/** @var string */
24
	const PK = 'id';
25
26
	/** @var Connection */
27
	public $conn;
28
29
	/** @var Model */
30
	protected $model;
31
32
	/** @var Query */
33
	protected $query;
34
35
	/**
36
	 * @param Model $model
37
	 * @return mixed[]
38
	 */
39
	abstract public static function mapRow($model);
40
41
	abstract public static function mapModel($row);
42
43
	/**
44
	 * @param Connection $connection
45
	 */
46
	public function __construct($connection = null)
47
	{
48
		$this->conn = $connection ?: MysqlConnection::instance();
49
		$this->query = new Query(static::TABLE);
50
		$this->pagination = new Pagination();
0 ignored issues
show
Bug Best Practice introduced by
The property pagination does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
51
	}
52
53
	/**
54
	 * Prepara raw Sql
55
	 * @param string $query
56
	 * @param mixed[]
57
	 */
58
	public function rawQuery($query, $values = [])
59
	{
60
		$this->query = new Query(static::TABLE, $values, $query);
61
62
		return $this;
63
	}
64
65
	/**
66
	 * Rota do raw sql
67
	 */
68
	public function run()
69
	{
70
		$query = $this->query->raw();
71
		$values = $this->query->getValues();
72
		return $this->conn->execute($query, $values);
73
	}
74
75
	/**
76
	 * Retorna o primeiro resultado da busca
77
	 */
78
	public function one()
79
	{
80
		$this->query->limit->set(0, 1);
81
82
		$query = $this->query->select();
83
		$values = $this->query->getValues();
84
		$row = $this->conn->fetch($query, $values);
85
		$this->flush();
86
87
		return $this->mapModel($row);
88
	}
89
90
	/**
91
	 * Retorna o registro pela PK
92
	 * @param int $id
93
	 */
94
	public function find($id)
95
	{
96
		return $this->filterBy(static::PK, $id)->one();
97
	}
98
99
	/**
100
	 * Retorna o todos os resultados da busca
101
	 */
102
	public function list()
103
	{
104
		$this->applyPagination();
105
106
		$query = $this->query->select();
107
		$values = $this->query->getValues();
108
		$rows = $this->conn->fetchAll($query, $values);
109
		$this->flush();
110
111
		return array_map([$this, 'mapModel'], $rows);
112
	}
113
114
	/**
115
	 * Retorna o total de resultados da busca
116
	 * Sem aplicar LIMIT e FLUSH
117
	 */
118
	public function count()
119
	{
120
		$query = $this->query->selectCount();
121
		$values = $this->query->getValues();
122
123
		return $this->conn->fetchCount($query, $values);
124
	}
125
126
	/**
127
	 * Remove todos os registros da busca
128
	 */
129
	public function delete()
130
	{
131
		$query = $this->query->delete();
132
		$values = $this->query->getValues();
133
		$this->conn->execute($query, $values);
134
		$this->flush();
135
	}
136
137
	/**
138
	 * Remove o registro pela PK
139
	 * @param int $id
140
	 */
141
	public function destroy($id)
142
	{
143
		$this->filterBy(static::PK, $id);
144
145
		$query = $this->query->delete();
146
		$values = $this->query->getValues();
147
		$this->conn->execute($query, $values);
148
		$this->flush();
149
	}
150
151
	/**
152
	 * Salva o registro no banco
153
	 * @param Model $model
154
	 */
155
	public function save(Model $model)
156
	{
157
		$model->validate();
158
		$this->model = $model;
159
		!$this->modelExists() ? $this->insert() : $this->update();
160
161
		$this->flush();
162
163
		return $this->model;
164
	}
165
166
	/**
167
	 * Remove todos os filtros, ordenação, etc
168
	 */
169
	public function flush()
170
	{
171
		$this->query = new Query(static::TABLE);
172
173
		return $this;
174
	}
175
176
	private function insert()
177
	{
178
		$this->query = new Query(static::TABLE, $this->mapRow($this->model));
179
		$query = $this->query->insert();
180
		$values = $this->query->getValues();
181
		$this->conn->execute($query, $values);
182
183
		$this->model->id = (int) $this->conn->getLastInsertId();
184
	}
185
186
	private function update()
187
	{
188
		$this->query = new Query(static::TABLE, $this->mapRow($this->model));
189
		$this->filterBy(static::PK, $this->model->id);
190
191
		$query = $this->query->update();
192
		$values = $this->query->getValues();
193
		$this->conn->execute($query, $values);
194
		$this->flush();
195
	}
196
197
	/** @return bool */
198
	protected function modelExists()
199
	{
200
		$orm = new static($this->conn);
201
		$orm->filterBy(static::PK, $this->model->id);
202
203
		return $orm->count() > 0;
204
	}
205
206
	/**
207
	 * Aplica um filtro ($comparator aceita mais de uma regra)
208
	 * @param string $comparator
209
	 * @param mixed $value
210
	 * @example filterBy('name = ? AND email = ?', 'John', '[email protected]')
211
	 */
212
	public function filterBy($comparator, ...$values)
213
	{
214
		$this->query->where->add($comparator, ...$values);
215
216
		return $this;
217
	}
218
219
	/**
220
	 * @param int $pageSize
221
	 * @param int $pageNumber
222
	 */
223
	public function paginate($pageSize, $pageNumber = 1)
224
	{
225
		$this->pagination->setPage($pageSize, $pageNumber);
226
227
		return $this;
228
	}
229
230
	/**
231
	 * Define a paginação se necessário
232
	 */
233
	private function applyPagination()
234
	{
235
		$count = $this->count();
236
		$pagination = $this->pagination;
237
238
		if ($pagination->pageSize() && $count) {
239
			$pagination->setCount($count);
240
			$this->query->limit->set($pagination->offset(), $pagination->pageSize());
241
		}
242
	}
243
244
	/**
245
	 * Ordem por um campo
246
	 * @param string $column
247
	 * @param string $mode 'ASC' | 'DESC'
248
	 * @param int $priority
249
	 */
250
	public function sortBy($column, $mode = 'ASC', $priority = 0)
251
	{
252
		$this->query->orderBy->add($column . ' ' . $mode, $priority);
253
254
		return $this;
255
	}
256
257
	public function sortNewest()
258
	{
259
		return $this->sortBy('id', 'DESC');
260
	}
261
262
	public function sortOldest()
263
	{
264
		return $this->sortBy('id', 'ASC');
265
	}
266
267
	public function sortRand()
268
	{
269
		return $this->sortBy('RAND()');
270
	}
271
}
272