1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace LRC\Repository; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Base class for database-backed soft-deletion-aware repositories for data access. |
7
|
|
|
*/ |
8
|
|
|
class SoftDbRepository extends DbRepository implements SoftRepositoryInterface |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* @var string Soft deletion attribute. |
12
|
|
|
*/ |
13
|
|
|
protected $deleted; |
14
|
|
|
|
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Constructor. |
18
|
|
|
* |
19
|
|
|
* @param \Anax\Database\DatabaseQueryBuilder $db Database service. |
20
|
|
|
* @param string $table Database table name. |
21
|
|
|
* @param string $modelClass Model class name. |
22
|
|
|
* @param string $deleted Soft deletion attribute. |
23
|
|
|
* @param string $key Primary key column. |
24
|
|
|
*/ |
25
|
15 |
|
public function __construct($db, $table, $modelClass, $deleted = 'deleted', $key = 'id') |
26
|
|
|
{ |
27
|
15 |
|
parent::__construct($db, $table, $modelClass, $key); |
28
|
15 |
|
$this->deleted = $deleted; |
29
|
15 |
|
} |
30
|
|
|
|
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Return the name of the attribute used to mark soft deletion. |
34
|
|
|
*/ |
35
|
3 |
|
public function getDeletedAttribute() |
36
|
|
|
{ |
37
|
3 |
|
return $this->deleted; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Find and return first entry by key, ignoring soft-deleted entries. |
43
|
|
|
* |
44
|
|
|
* @param string|null $column Key column name (pass null to use registered primary key). |
45
|
|
|
* @param mixed $value Key value. |
46
|
|
|
* |
47
|
|
|
* @return mixed Model instance. |
48
|
|
|
*/ |
49
|
8 |
|
public function findSoft($column, $value) |
50
|
|
|
{ |
51
|
8 |
|
return $this->getFirstSoft((is_null($column) ? $this->key : $column) . ' = ?', [$value]); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Retrieve first entry ignoring soft-deleted ones, optionally filtered by search criteria. |
57
|
|
|
* |
58
|
|
|
* @param string $conditions Where conditions. |
59
|
|
|
* @param array $values Array of condition values to bind. |
60
|
|
|
* @param array $options Query options. |
61
|
|
|
* |
62
|
|
|
* @return mixed Model instance. |
63
|
|
|
*/ |
64
|
9 |
View Code Duplication |
public function getFirstSoft($conditions = null, $values = [], $options = []) |
|
|
|
|
65
|
|
|
{ |
66
|
9 |
|
$query = $this->executeQuerySoft(null, $conditions, $values, $options); |
67
|
9 |
|
if (!empty($this->fetchRefs)) { |
68
|
2 |
|
$res = $query->fetch(); |
69
|
2 |
|
$model = ($res ? $this->populateModelFromJoin($res) : $res); |
|
|
|
|
70
|
2 |
|
} else { |
71
|
7 |
|
$model = $query->fetchClass($this->modelClass); |
|
|
|
|
72
|
|
|
} |
73
|
9 |
|
if ($model && isset($this->manager)) { |
74
|
4 |
|
$this->manager->manageModel($model); |
|
|
|
|
75
|
4 |
|
} |
76
|
9 |
|
$this->fetchReferences(false); |
77
|
9 |
|
return $model; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Retrieve all entries ignoring soft-deleted ones, optionally filtered by search criteria. |
83
|
|
|
* |
84
|
|
|
* @param string $conditions Where conditions. |
85
|
|
|
* @param array $values Array of condition values to bind. |
86
|
|
|
* @param array $options Query options. |
87
|
|
|
* |
88
|
|
|
* @return array Array of all matching entries. |
89
|
|
|
*/ |
90
|
2 |
View Code Duplication |
public function getAllSoft($conditions = null, $values = [], $options = []) |
|
|
|
|
91
|
|
|
{ |
92
|
2 |
|
$query = $this->executeQuerySoft(null, $conditions, $values, $options); |
93
|
2 |
|
if (!empty($this->fetchRefs)) { |
94
|
1 |
|
$models = []; |
95
|
1 |
|
foreach ($query->fetchAll() as $model) { |
96
|
1 |
|
$models[] = $this->populateModelFromJoin($model); |
97
|
1 |
|
} |
98
|
1 |
|
} else { |
99
|
1 |
|
$models = $query->fetchAllClass($this->modelClass); |
|
|
|
|
100
|
|
|
} |
101
|
2 |
|
if (isset($this->manager)) { |
102
|
1 |
|
foreach ($models as $model) { |
103
|
1 |
|
$this->manager->manageModel($model); |
104
|
1 |
|
} |
105
|
1 |
|
} |
106
|
2 |
|
$this->fetchReferences(false); |
107
|
2 |
|
return $models; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Soft delete entry. |
113
|
|
|
* |
114
|
|
|
* @param mixed $model Model instance. |
115
|
|
|
*/ |
116
|
1 |
|
public function deleteSoft($model) |
117
|
|
|
{ |
118
|
1 |
|
$model->deleted = date('Y-m-d H:i:s'); |
119
|
1 |
|
$this->save($model); |
120
|
1 |
|
} |
121
|
|
|
|
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Restore soft-deleted entry. |
125
|
|
|
* |
126
|
|
|
* @param mixed $model Model instance. |
127
|
|
|
*/ |
128
|
1 |
|
public function restoreSoft($model) |
129
|
|
|
{ |
130
|
1 |
|
$model->deleted = null; |
131
|
1 |
|
$this->save($model); |
132
|
1 |
|
} |
133
|
|
|
|
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Count entries ignoring soft-deleted ones, optionally filtered by search criteria. |
137
|
|
|
* |
138
|
|
|
* @param string $conditions Where conditions. |
139
|
|
|
* @param array $values Array of condition values to bind. |
140
|
|
|
* |
141
|
|
|
* @return int Number of entries. |
142
|
|
|
*/ |
143
|
1 |
|
public function countSoft($conditions = null, $values = []) |
144
|
|
|
{ |
145
|
1 |
|
$res = $this->executeQuerySoft('COUNT(' . $this->key . ') AS num', $conditions, $values) |
146
|
1 |
|
->fetch(); |
147
|
1 |
|
return (isset($res->num) ? (int)$res->num : 0); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Execute soft-deletion-aware query for selection methods. |
153
|
|
|
* |
154
|
|
|
* @param string $select Selection criteria. |
155
|
|
|
* @param string $conditions Where conditions. |
156
|
|
|
* @param array $values Array of where condition values to bind. |
157
|
|
|
* @param array $options Query options. |
158
|
|
|
* |
159
|
|
|
* @return \Anax\Database\DatabaseQueryBuilder Database service instance with executed internal query. |
160
|
|
|
*/ |
161
|
11 |
|
protected function executeQuerySoft($select = null, $conditions = null, $values = [], $options = []) |
162
|
|
|
{ |
163
|
11 |
|
$delCond = $this->deleted . ' IS NULL'; |
164
|
11 |
|
$conditions = (is_null($conditions) ? $delCond : "($conditions) AND $delCond"); |
165
|
11 |
|
return $this->executeQuery($select, $conditions, $values, $options); |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
|
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.