Add EmailLogListPage
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / DatabaseObject.class.php
CommitLineData
158bd3ca 1<?php
a9229942 2
158bd3ca 3namespace wcf\data;
a9229942 4
158bd3ca
TD
5use wcf\system\WCF;
6
7/**
8 * Abstract class for all data holder classes.
a9229942
TD
9 *
10 * @author Marcel Werk
11 * @copyright 2001-2019 WoltLab GmbH
12 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
13 * @package WoltLabSuite\Core\Data
158bd3ca 14 */
a9229942
TD
15abstract class DatabaseObject implements IIDObject, IStorableObject
16{
17 /**
18 * database table for this object
19 * @var string
20 */
21 protected static $databaseTableName = '';
22
23 /**
24 * indicates if database table index is an identity column
25 * @var bool
26 */
27 protected static $databaseTableIndexIsIdentity = true;
28
29 /**
30 * name of the primary index column
31 * @var string
32 */
33 protected static $databaseTableIndexName = '';
34
35 /**
36 * sort field
37 * @var mixed
38 */
39 protected static $sortBy = null;
40
41 /**
42 * sort order
43 * @var mixed
44 */
45 protected static $sortOrder = null;
46
47 /**
48 * object data
49 * @var array
50 */
51 protected $data;
52
53 /**
54 * Creates a new instance of the DatabaseObject class.
55 *
56 * @param mixed $id
57 * @param array $row
58 * @param DatabaseObject $object
59 */
60 public function __construct($id, ?array $row = null, ?self $object = null)
61 {
62 if ($id !== null) {
63 $sql = "SELECT *
64 FROM " . static::getDatabaseTableName() . "
65 WHERE " . static::getDatabaseTableIndexName() . " = ?";
66 $statement = WCF::getDB()->prepareStatement($sql);
67 $statement->execute([$id]);
68 $row = $statement->fetchArray();
69
70 // enforce data type 'array'
71 if ($row === false) {
72 $row = [];
73 }
74 } elseif ($object !== null) {
75 $row = $object->data;
76 }
77
78 $this->handleData($row);
79 }
80
81 /**
82 * Stores the data of a database row.
83 *
84 * @param array $data
85 */
86 protected function handleData($data)
87 {
88 // provide a logical false value for - assumed numeric - primary index
89 if (!isset($data[static::getDatabaseTableIndexName()])) {
90 $data[static::getDatabaseTableIndexName()] = 0;
91 }
92
93 $this->data = $data;
94 }
95
96 /**
97 * @inheritDoc
98 */
99 public function __get($name)
100 {
101 if (isset($this->data[$name])) {
102 return $this->data[$name];
103 } else {
104 return;
105 }
106 }
107
108 /**
109 * Returns the id of the object.
110 *
111 * @return int
112 */
113 public function getObjectID()
114 {
115 return $this->data[static::getDatabaseTableIndexName()];
116 }
117
118 /**
119 * @inheritDoc
120 */
121 public function __isset($name)
122 {
123 return isset($this->data[$name]);
124 }
125
126 /**
127 * @inheritDoc
128 */
129 public function getData()
130 {
131 return $this->data;
132 }
133
134 /**
135 * @inheritDoc
136 */
137 public static function getDatabaseTableName()
138 {
139 $className = \get_called_class();
140 $classParts = \explode('\\', $className);
141
142 if (static::$databaseTableName !== '') {
143 return $classParts[0] . WCF_N . '_' . static::$databaseTableName;
144 }
145
146 static $databaseTableNames = [];
147 if (!isset($databaseTableNames[$className])) {
148 $databaseTableNames[$className] = $classParts[0] . WCF_N . '_' . \strtolower(\implode(
149 '_',
150 \preg_split(
151 '~(?=[A-Z](?=[a-z]))~',
152 \array_pop($classParts),
153 -1,
154 \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY
155 )
156 ));
157 }
158
159 return $databaseTableNames[$className];
160 }
161
162 /**
163 * @inheritDoc
164 */
165 public static function getDatabaseTableAlias()
166 {
167 if (static::$databaseTableName !== '') {
168 return static::$databaseTableName;
169 }
170
171 $className = \get_called_class();
172 static $databaseTableAliases = [];
173 if (!isset($databaseTableAliases[$className])) {
174 $classParts = \explode('\\', $className);
175 $databaseTableAliases[$className] = \strtolower(\implode(
176 '_',
177 \preg_split(
178 '~(?=[A-Z](?=[a-z]))~',
179 \array_pop($classParts),
180 -1,
181 \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY
182 )
183 ));
184 }
185
186 return $databaseTableAliases[$className];
187 }
188
189 /**
190 * @inheritDoc
191 */
192 public static function getDatabaseTableIndexIsIdentity()
193 {
194 return static::$databaseTableIndexIsIdentity;
195 }
196
197 /**
198 * @inheritDoc
199 */
200 public static function getDatabaseTableIndexName()
201 {
202 if (static::$databaseTableIndexName !== '') {
203 return static::$databaseTableIndexName;
204 }
205
206 static $databaseTableIndexName = null;
207 if ($databaseTableIndexName === null) {
208 $className = \explode('\\', \get_called_class());
209 $parts = \preg_split(
210 '~(?=[A-Z](?=[a-z]))~',
211 \array_pop($className),
212 -1,
213 \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY
214 );
215 $databaseTableIndexName = \strtolower(\array_pop($parts)) . 'ID';
216 }
217
218 return $databaseTableIndexName;
219 }
220
221 /**
222 * Sorts a list of database objects.
223 *
224 * @param DatabaseObject[] $objects
225 * @param mixed $sortBy
226 * @param string $sortOrder
227 * @param bool $maintainIndexAssociation
228 */
229 public static function sort(&$objects, $sortBy, $sortOrder = 'ASC', $maintainIndexAssociation = true)
230 {
231 $sortArray = $objects2 = [];
232 foreach ($objects as $idx => $obj) {
233 /** @noinspection PhpVariableVariableInspection */
234 $sortArray[$idx] = $obj->{$sortBy};
235
236 // array_multisort will drop index association if key is not a string
237 if ($maintainIndexAssociation) {
238 $objects2[$idx . 'x'] = $obj;
239 }
240 }
241
242 if ($maintainIndexAssociation) {
243 $objects = [];
244 \array_multisort($sortArray, $sortOrder == 'ASC' ? \SORT_ASC : \SORT_DESC, $objects2);
245
246 $objects = [];
247 foreach ($objects2 as $idx => $obj) {
248 $objects[\substr($idx, 0, -1)] = $obj;
249 }
250 } else {
251 \array_multisort($sortArray, $sortOrder == 'ASC' ? \SORT_ASC : \SORT_DESC, $objects);
252 }
253 }
004426c2 254}