Completed
Push — master ( efdf8d...2fd22e )
by Michael
02:24
created

AbstractActiveRecord::setActiveRecordData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
crap 3
1
<?php
2
3
/**
4
 * This file is part of the miBadger package.
5
 *
6
 * @author Michael Webbers <[email protected]>
7
 * @license http://opensource.org/licenses/Apache-2.0 Apache v2 License
8
 * @version 1.0.0
9
 */
10
11
namespace miBadger\ActiveRecord;
12
13
/**
14
 * The abstract active record class.
15
 *
16
 * @since 1.0.0
17
 */
18
abstract class AbstractActiveRecord implements ActiveRecordInterface
19
{
20
	/** @var \PDO The PDO object. */
21
	private $pdo;
22
23
	/** @var null|int The ID. */
24
	private $id;
25
26
	/**
27
	 * Construct an abstract pdo active record with the given pdo.
28
	 *
29
	 * @param \PDO $pdo
30
	 */
31 21
	public function __construct(\PDO $pdo)
32
	{
33 21
		$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
34 21
		$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
35
36 21
		$this->setPdo($pdo);
37 21
	}
38
39
	/**
40
	 * {@inheritdoc}
41
	 */
42 3
	public function create()
43
	{
44
		try {
45 3
			$pdoStatement = $this->getPdo()->prepare($this->getCreateQuery());
46 1
			$pdoStatement->execute($this->getActiveRecordData());
47
48 1
			$this->setId(intval($this->getPdo()->lastInsertId()));
49 3
		} catch(\PDOException $e) {
50 2
			throw new ActiveRecordException('Can\'t create the record.', 0, $e);
51
		}
52
53 1
		return $this;
54
	}
55
56
	/**
57
	 * Returns the create query.
58
	 *
59
	 * @return string the create query.
60
	 */
61 3 View Code Duplication
	private function getCreateQuery()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
	{
63 3
		$columns = array_keys($this->getActiveRecordData());
64 3
		$values = [];
65
66 3
		foreach ($columns as $key => $value) {
67 3
			$values[] = ':' . $value;
68 3
		}
69
70 3
		return sprintf('INSERT INTO %s (%s) VALUES (%s)', $this->getActiveRecordName(), implode(', ', $columns), implode(', ', $values));
71
	}
72
73
	/**
74
	 * {@inheritdoc}
75
	 */
76 6
	public function read($id)
77
	{
78
		try {
79 6
			$pdoStatement = $this->getPdo()->prepare($this->getReadQuery());
80 5
			$pdoStatement->execute(['id' => $id]);
81
82 5
			$this->setActiveRecordData($pdoStatement->fetch());
83 4
			$this->setId($id);
84 6
		} catch (\PDOException $e) {
85 1
			throw new ActiveRecordException('Can\'t read the record.', 0, $e);
86
		}
87
88 4
		return $this;
89
	}
90
91
	/**
92
	 * Returns the read query.
93
	 *
94
	 * @return string the read query.
95
	 */
96 6
	private function getReadQuery()
97
	{
98 6
		return sprintf('SELECT * FROM `%s` WHERE `id` = :id', $this->getActiveRecordName());
99
	}
100
101
	/**
102
	 * {@inheritdoc}
103
	 */
104 4 View Code Duplication
	public function update()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
105
	{
106 4
		if (!$this->exists()) {
107 1
			throw new ActiveRecordException('Can\'t update a non-existent record.');
108
		}
109
110
		try {
111 3
			$pdoStatement = $this->getPdo()->prepare($this->getUpdateQuery());
112 1
			$pdoStatement->execute(['id' => $this->getId()] + $this->getActiveRecordData());
113 3
		} catch (\PDOException $e) {
114 2
			throw new ActiveRecordException('Can\'t update the record.', 0, $e);
115
		}
116
117 1
		return $this;
118
	}
119
120
	/**
121
	 * Returns the update query.
122
	 *
123
	 * @return string the update query.
124
	 */
125 3 View Code Duplication
	private function getUpdateQuery()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
	{
127 3
		$values = [];
128
129 3
		foreach (array_keys($this->getActiveRecordData()) as $key => $value) {
130 3
			$values[] = $value . ' = :' . $value;
131 3
		}
132
133 3
		return sprintf('UPDATE %s SET %s WHERE `id` = :id', $this->getActiveRecordName(), implode(', ', $values));
134
	}
135
136
	/**
137
	 * {@inheritdoc}
138
	 */
139 3 View Code Duplication
	public function delete()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
140
	{
141 3
		if (!$this->exists()) {
142 1
			throw new ActiveRecordException('Can\'t delete a non-existent record.');
143
		}
144
145
		try {
146 2
			$pdoStatement = $this->getPdo()->prepare($this->getDeleteQuery());
147 1
			$pdoStatement->execute(['id' => $this->getId()]);
148
149 1
			$this->setId(null);
150 2
		} catch (\PDOException $e) {
151 1
			throw new ActiveRecordException('Can\'t delete the record.', 0, $e);
152
		}
153
154 1
		return $this;
155
	}
156
157
	/**
158
	 * Returns the delete query.
159
	 *
160
	 * @return string the delete query.
161
	 */
162 2
	private function getDeleteQuery()
163
	{
164 2
		return sprintf('DELETE FROM %s WHERE `id` = :id', $this->getActiveRecordName());
165
	}
166
167
	/**
168
	 * {@inheritdoc}
169
	 */
170 8
	public function exists()
171
	{
172 8
		return $this->getId() !== null;
173
	}
174
175
	/**
176
	 * Returns the PDO.
177
	 *
178
	 * @return \PDO the PDO.
179
	 */
180 19
	public function getPdo()
181
	{
182 19
		return $this->pdo;
183
	}
184
185
	/**
186
	 * Set the PDO.
187
	 *
188
	 * @param \PDO $pdo
189
	 * @return $this
190
	 */
191 21
	protected function setPdo($pdo)
192
	{
193 21
		$this->pdo = $pdo;
194
195 21
		return $this;
196
	}
197
198
	/**
199
	 * Returns the ID.
200
	 *
201
	 * @return null|int The ID.
202
	 */
203 6
	public function getId()
204
	{
205 6
		return $this->id;
206
	}
207
208
	/**
209
	 * Set the ID.
210
	 *
211
	 * @param int $id
212
	 * @return $this
213
	 */
214 8
	protected function setId($id)
215
	{
216 8
		$this->id = $id;
217
218 8
		return $this;
219
	}
220
221
	/**
222
	 * Returns the active record name.
223
	 *
224
	 * @return string the active record name.
225
	 */
226
	abstract protected function getActiveRecordName();
227
228
	/**
229
	 * Returns the active record data.
230
	 *
231
	 * @return array the active record data.
232
	 */
233
	abstract protected function getActiveRecordData();
234
235
	/**
236
	 * Set the active record data.
237
	 *
238
	 * @param array $fetch
239
	 * @return null
240
	 */
241 8
	protected function setActiveRecordData(array $fetch)
242
	{
243 8
		$data = $this->getActiveRecordData();
244
245 8
		foreach ($data as $key => &$value) {
246 8
			if (!isset($fetch[$key])) {
247 1
				throw new ActiveRecordException(sprintf('Can\'t read the expected column "%s". It\'s not returnd by the database', $key));
248
			}
249
250 8
			$value = $fetch[$key];
251 8
		}
252 7
	}
253
}
254