1 <?php
2
3 4 5 6 7
8 abstract class rex_structure_element
9 {
10 use rex_instance_pool_trait;
11 use rex_instance_list_pool_trait;
12
13 14 15
16 protected $id = '';
17 protected $parent_id = '';
18 protected $clang_id = '';
19 protected $name = '';
20 protected $catname = '';
21 protected $template_id = '';
22 protected $path = '';
23 protected $priority = '';
24 protected $catpriority = '';
25 protected $startarticle = '';
26 protected $status = '';
27 protected $updatedate = '';
28 protected $createdate = '';
29 protected $updateuser = '';
30 protected $createuser = '';
31
32 protected static $classVars;
33
34 35 36 37 38
39 protected function __construct(array $params)
40 {
41 foreach (self::getClassVars() as $var) {
42 if (isset($params[$var])) {
43 $this->$var = $params[$var];
44 }
45 }
46 }
47
48 49 50 51 52 53 54
55 public function getValue($value)
56 {
57
58
59
60 foreach (['', 'art_', 'cat_'] as $prefix) {
61 $val = $prefix . $value;
62 if (isset($this->$val)) {
63 return $this->$val;
64 }
65 }
66 return null;
67 }
68
69 70 71 72 73 74
75 protected static function _hasValue($value, array $prefixes = [])
76 {
77 $values = self::getClassVars();
78
79 if (in_array($value, $values)) {
80 return true;
81 }
82
83 foreach ($prefixes as $prefix) {
84 if (in_array($prefix . $value, $values)) {
85 return true;
86 }
87 }
88
89 return false;
90 }
91
92 93 94 95 96
97 public static function getClassVars()
98 {
99 if (empty(self::$classVars)) {
100 self::$classVars = [];
101
102 $startId = rex_article::getSiteStartArticleId();
103 $file = rex_path::addonCache('structure', $startId . '.1.article');
104 if (!rex::isBackend() && file_exists($file)) {
105
106 $genVars = rex_file::getCache($file);
107 unset($genVars['last_update_stamp']);
108 foreach ($genVars as $name => $value) {
109 self::$classVars[] = $name;
110 }
111 } else {
112
113 $sql = rex_sql::factory();
114 $sql->setQuery('SELECT * FROM ' . rex::getTablePrefix() . 'article LIMIT 0');
115 foreach ($sql->getFieldnames() as $field) {
116 self::$classVars[] = $field;
117 }
118 }
119 }
120
121 return self::$classVars;
122 }
123
124 public static function resetClassVars()
125 {
126 self::$classVars = null;
127 }
128
129 130 131 132 133 134 135 136 137
138 public static function get($id, $clang = null)
139 {
140 $id = (int) $id;
141
142 if ($id <= 0) {
143 return null;
144 }
145
146 if (!$clang) {
147 $clang = rex_clang::getCurrentId();
148 }
149
150 $class = static::class;
151 return static::getInstance([$id, $clang], function ($id, $clang) use ($class) {
152 $article_path = rex_path::addonCache('structure', $id . '.' . $clang . '.article');
153
154
155 $metadata = rex_file::getCache($article_path);
156
157
158 if (!$metadata) {
159 rex_article_cache::generateMeta($id, $clang);
160 $metadata = rex_file::getCache($article_path);
161 }
162
163
164 if (!$metadata) {
165 return null;
166 }
167
168
169 if (!$metadata['startarticle'] && (rex_category::class === static::class || is_subclass_of(static::class, rex_category::class))) {
170 return null;
171 }
172
173 return new $class($metadata);
174 });
175 }
176
177 178 179 180 181 182 183 184
185 protected static function getChildElements($parentId, $listType, $ignoreOfflines = false, $clang = null)
186 {
187 $parentId = (int) $parentId;
188
189 if (0 > $parentId) {
190 return [];
191 }
192 if (!$clang) {
193 $clang = rex_clang::getCurrentId();
194 }
195
196 $class = static::class;
197 return static::getInstanceList(
198
199 [$parentId, $listType],
200
201 function ($id) use ($class, $ignoreOfflines, $clang) {
202 if ($instance = $class::get($id, $clang)) {
203 return !$ignoreOfflines || $instance->isOnline() ? $instance : null;
204 }
205 return null;
206 },
207
208 function ($parentId, $listType) {
209 $listFile = rex_path::addonCache('structure', $parentId . '.' . $listType);
210
211 $list = rex_file::getCache($listFile);
212 if (!$list) {
213 rex_article_cache::generateLists($parentId);
214 $list = rex_file::getCache($listFile);
215 }
216 return $list;
217 }
218 );
219 }
220
221 222 223 224 225 226 227
228 public function getClang()
229 {
230 return $this->clang_id;
231 }
232
233 234 235 236 237
238 public function getClangId()
239 {
240 return $this->clang_id;
241 }
242
243 244 245 246 247 248 249 250
251 public function getUrl(array $params = [], $divider = '&')
252 {
253 return rex_getUrl($this->getId(), $this->getClang(), $params, $divider);
254 }
255
256 257 258 259 260
261 public function getId()
262 {
263 return $this->id;
264 }
265
266 267 268 269 270
271 public function getParentId()
272 {
273 return $this->parent_id;
274 }
275
276 277 278 279 280
281 abstract public function getPath();
282
283 284 285 286 287
288 public function getPathAsArray()
289 {
290 $path = explode('|', $this->getPath());
291 return array_values(array_map('intval', array_filter($path)));
292 }
293
294 295 296 297 298
299 abstract public function getParent();
300
301 302 303 304 305
306 public function getName()
307 {
308 return $this->name;
309 }
310
311 312 313 314 315
316 public function getPriority()
317 {
318 return $this->priority;
319 }
320
321 322 323 324 325
326 public function getUpdateUser()
327 {
328 return $this->updateuser;
329 }
330
331 332 333 334 335
336 public function getUpdateDate()
337 {
338 return $this->updatedate;
339 }
340
341 342 343 344 345
346 public function getCreateUser()
347 {
348 return $this->createuser;
349 }
350
351 352 353 354 355
356 public function getCreateDate()
357 {
358 return $this->createdate;
359 }
360
361 362 363 364 365
366 public function isOnline()
367 {
368 return $this->status == 1;
369 }
370
371 372 373 374 375
376 public function getTemplateId()
377 {
378 return $this->template_id;
379 }
380
381 382 383 384 385
386 public function hasTemplate()
387 {
388 return $this->template_id > 0;
389 }
390
391 392 393 394 395
396 abstract public function isPermitted();
397
398 399 400 401 402 403 404 405 406 407
408 public function toLink(array $params = [], array $attributes = [], $sorroundTag = null, array $sorroundAttributes = [])
409 {
410 $name = $this->getName();
411 $link = '<a href="' . $this->getUrl($params) . '"' . $this->_toAttributeString($attributes) . ' title="' . rex_escape($name) . '">' . rex_escape($name) . '</a>';
412
413 if ($sorroundTag !== null && is_string($sorroundTag)) {
414 $link = '<' . $sorroundTag . $this->_toAttributeString($sorroundAttributes) . '>' . $link . '</' . $sorroundTag . '>';
415 }
416
417 return $link;
418 }
419
420 421 422 423 424
425 protected function _toAttributeString(array $attributes)
426 {
427 $attr = '';
428
429 if ($attributes !== null && is_array($attributes)) {
430 foreach ($attributes as $name => $value) {
431 $attr .= ' ' . $name . '="' . $value . '"';
432 }
433 }
434
435 return $attr;
436 }
437
438 439 440 441 442 443
444 public function getParentTree()
445 {
446 $return = [];
447
448 if ($this->path) {
449 if ($this->isStartArticle()) {
450 $explode = explode('|', $this->path . $this->id . '|');
451 } else {
452 $explode = explode('|', $this->path);
453 }
454
455 if (is_array($explode)) {
456 foreach ($explode as $var) {
457 if ($var != '') {
458 $return[] = rex_category::get($var, $this->clang_id);
459 }
460 }
461 }
462 }
463
464 return $return;
465 }
466
467 468 469 470 471 472 473
474 public function inParentTree(self $anObj)
475 {
476 $tree = $this->getParentTree();
477 foreach ($tree as $treeObj) {
478 if ($treeObj == $anObj) {
479 return true;
480 }
481 }
482 return false;
483 }
484
485 486 487 488 489
490 public function isStartArticle()
491 {
492 return $this->startarticle;
493 }
494
495 496 497 498 499
500 public function isSiteStartArticle()
501 {
502 return $this->id == rex_article::getSiteStartArticleId();
503 }
504
505 506 507 508 509
510 public function isNotFoundArticle()
511 {
512 return $this->id == rex_article::getNotfoundArticleId();
513 }
514 }
515