Completed
Push — master ( 18b228...aeb1e8 )
by Wanderson
02:50
created

DAO::validateObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
nc 2
cc 2
eloc 3
nop 0
1
<?php
2
3
namespace Win\DAO;
4
5
use Win\Mvc\Application;
6
use Win\Connection\MySQL;
7
8
/**
9
 * Data Access Object
10
 */
11
abstract class DAO implements DAOInterface {
12
13
	/** @var \PDO */
14
	protected $pdo;
15
16
	/** @var string */
17
	protected $selectedCollumns;
18
19
	/**
20
	 * Retorna um objeto a partir da linha da tabela
21
	 * @param array[] $row
22
	 */
23
	abstract protected function mapObject($row);
24
25
	/** Retorna a linha da tabela a partir de um objeto
26
	 * @param object $obj
27
	 */
28
	abstract protected function mapRow($obj);
29
30
	/** Inicia o DAO */
31
	public function __construct() {
32
		$this->pdo = MySQL::instance()->getPDO();
33
		$this->selectedCollumns = '*';
34
	}
35
36
	/**
37
	 * Define uma conexão manualmente
38
	 * @param \PDO $pdo
39
	 */
40
	public function setPDO($pdo) {
41
		$this->pdo = $pdo;
42
	}
43
44
	/**
45
	 * Define quais colunas serão consultadas nos comandos SELECT
46
	 * @param string $collumns
47
	 */
48
	public function selectedCollumns($collumns) {
49
		$this->selectedCollumns = $collumns;
50
	}
51
52
	/**
53
	 * Salva o registro
54
	 * @param object $obj
55
	 */
56
	public function save($obj) {
57
		$this->obj = $obj;
0 ignored issues
show
Bug introduced by
The property obj does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
58
		if (!$this->objExists()) {
59
			$this->insert();
60
			if ($this->pdo) {
61
				$this->obj->setId($this->pdo->lastInsertId());
62
			}
63
		} else {
64
			$this->update();
65
		}
66
	}
67
68
	/** Insere o registro */
69
	protected function insert() {
70
		$mapRow = $this->mapRow($this->obj);
71
		$keys = array_keys($mapRow);
72
		$values = array_values($mapRow);
73
		$params = str_split(str_repeat('?', count($keys)));
74
75
		$sql = 'INSERT INTO ' . static::TABLE . ' (' . implode(',', $keys) . ') VALUES (' . implode(', ', $params) . ') ';
76
		if ($this->pdo) {
77
			$stmt = $this->pdo->prepare($sql);
78
			$stmt->execute($values);
79
		}
80
	}
81
82
	/** Atualiza o registro */
83
	protected function update() {
84
		$mapRow = $this->mapRow($this->obj);
85
		$keys = array_keys($mapRow);
86
		$values = array_values($mapRow);
87
		$params = [];
88
		foreach ($keys as $key):
89
			$params[] = $key . ' = ?';
90
		endforeach;
91
		$values[] = $this->obj->getId();
92
93
		$sql = 'UPDATE ' . static::TABLE . ' SET ' . implode(', ', $params) . ' WHERE id = ? ';
94
		if ($this->pdo) {
95
			$stmt = $this->pdo->prepare($sql);
96
			$stmt->execute($values);
97
		}
98
	}
99
100
	/**
101
	 * Exclui o registro
102
	 * @param object $obj
103
	 */
104
	public function delete($obj) {
105
		$this->deleteById($obj->getId());
106
	}
107
108
	/**
109
	 * Exclui o registro por id
110
	 * @param int $id
111
	 */
112
	public function deleteById($id) {
113
		$sql = 'DELETE FROM ' . static::TABLE . ' WHERE id = :id';
114
		if ($this->pdo) {
115
			$stmt = $this->pdo->prepare($sql);
116
			$stmt->bindValue(':id', $id);
117
			$stmt->execute();
118
		}
119
	}
120
121
	/**
122
	 * Busca o objeto pelo id
123
	 * @param int $id
124
	 */
125
	public function fetchById($id) {
126
		return $this->fetchByField('id', $id);
127
	}
128
129
	/**
130
	 * Busca o objeto por um campo/atributo específico
131
	 * @param string $name Nome do atributo
132
	 * @param mixed $value Valor do atributo
133
	 */
134
	public function fetchByField($name, $value) {
135
		return $this->fetch([$name . ' = ?' => $value]);
136
	}
137
138
	/**
139
	 * Busca o objeto
140
	 * @param string[] $filter Array de filtros
141
	 * @param string $option [Order by, Limit, etc]
142
	 */
143
	public function fetch($filter, $option = '') {
144
		if (!is_array($filter)):
145
			throw new \Exception("Filter: '{$filter}' must be a array");
146
		endif;
147
		$sql = $sql = $this->selectSQL() . ' ' . $this->whereSQL($filter) . ' ' . $option;
148
		$result = [];
149
		if ($this->pdo) {
150
			$stmt = $this->pdo->prepare($sql);
151
			$stmt->execute(array_values($filter));
152
153
			$result = $stmt->fetch();
154
		}
155
		return $this->mapObject($result);
156
	}
157
158
	/**
159
	 * Retorna todos os registros
160
	 *
161
	 * <code>
162
	 * $dao->fetchAll( ['id = ?' => 10]);
163
	 * </code>
164
	 * @param string[] $filter Array de filtros
165
	 * @param string $option [Order by, Limit, etc]
166
	 */
167
	public function fetchAll($filter = [], $option = '') {
168
		$array = [];
169
		if (!is_array($filter)):
170
			throw new \Exception("Filter: '{$filter}' must be a array");
171
		endif;
172
173
		$sql = $this->selectSQL() . ' ' . $this->whereSQL($filter) . ' ' . $option;
174
		if ($this->pdo) {
175
			$stmt = $this->pdo->prepare($sql);
176
			$stmt->execute(array_values($filter));
177
178
			$results = $stmt->fetchAll();
179
180
			foreach ($results as $result):
181
				$array[] = $this->mapObject($result);
182
			endforeach;
183
		}
184
		return $array;
185
	}
186
187
	/**
188
	 * Retorna comando SELECT
189
	 * @return string
190
	 * @example "SELECT * FROM user"
191
	 */
192
	protected function selectSQL() {
193
		return 'SELECT ' . $this->selectedCollumns . ' FROM ' . static::TABLE;
194
	}
195
196
	/**
197
	 * Retorna comando WHERE
198
	 * @param string[] $filter
199
	 * @return string
200
	 */
201
	private function whereSQL(&$filter) {
202
		$keys = array_keys($filter);
203
		return ($keys) ? 'WHERE ' . implode(' AND ', $keys) : '';
204
	}
205
206
	/**
207
	 * Retorna True se objeto existir
208
	 * @return boolean
209
	 */
210
	protected function objExists() {
211
		return ($this->obj->getId() > 0);
212
	}
213
214
	/** Define como Página 404 se o objeto não existir */
215
	public function validateObject() {
216
		if (!$this->objExists()) {
217
			Application::app()->pageNotFound();
218
		}
219
	}
220
221
}
222