File modules/cms/model/BaseObject.class.php
Last commit: Tue Oct 13 00:41:49 2026 +0200 Jan Dankert PHP8: Fixup old code: if there is no session entry, der return value should be null.
1 <?php 2 3 4 namespace cms\model; 5 6 use cms\base\Configuration; 7 use cms\base\DB; 8 use cms\base\Startup; 9 use cms\generator\Publisher; 10 use util\ArrayUtils; 11 use util\Request; 12 use util\text\variables\VariableResolver; 13 use util\YAML; 14 15 /** 16 * Base class for all objects in the content tree. 17 * 18 * @author Jan Dankert 19 */ 20 class BaseObject extends ModelBase 21 { 22 const TYPEID_FOLDER = 1; 23 const TYPEID_FILE = 2; 24 const TYPEID_PAGE = 3; 25 const TYPEID_LINK = 4; 26 const TYPEID_URL = 5; 27 const TYPEID_IMAGE = 6; 28 const TYPEID_TEXT = 7; 29 const TYPEID_ALIAS = 8; 30 const TYPEID_SCRIPT = 9; 31 32 33 /** 34 * Unique ID of this base object. 35 * 36 * @type Integer 37 */ 38 public $objectid; 39 40 /** 41 * Parent-Id. 42 * 43 * Object-Id of the folder, which this objects belongs to. 44 * 45 * Is 0 in case of the root folder. 46 * 47 * @see #isRoot() 48 * @type Integer 49 */ 50 public $parentid = null; 51 52 /** Filename. 53 * 54 * Technical filename of this object without any extension. This name must be unique in a folder. 55 * 56 * @type String 57 */ 58 public $filename = ''; 59 public $orderid = 0; 60 61 62 /** Zeitpunkt der Erstellung. Die Variable beinhaltet den Unix-Timestamp. 63 * @type Integer 64 */ 65 var $createDate; 66 67 /** Zeitpunkt der letzten Aenderung. Die Variable beinhaltet den Unix-Timestamp. 68 * @type Integer 69 */ 70 var $lastchangeDate; 71 72 /** Benutzer, welcher dieses Objekt erstellt hat. 73 * @type User 74 */ 75 public $createUser; 76 77 /** Benutzer, welcher dieses Objekt zuletzt geaendert hat. 78 * @type User 79 */ 80 public $lastchangeUser; 81 82 /** 83 * Benutzer, der das Objekt zuletzt veröffentlicht hat. 84 * @var User 85 */ 86 public $publishedUser; 87 /** 88 * Zeitpunkt der letzten Veröffentlichung. 89 * @var Integer 90 */ 91 public $publishedDate; 92 93 94 /** 95 * Valid from. 96 * 97 * This is a unix-timestamp. 98 * 99 * @var int 100 */ 101 public $validFromDate; 102 103 /** 104 * Valid to. 105 * 106 * This is a unix-timestamp. 107 * 108 * @var int 109 */ 110 public $validToDate; 111 112 /** 113 * Kennzeichen, ob Objekt ein Ordner ist 114 * @type Boolean 115 */ 116 var $isFolder = false; 117 118 /** 119 * Kennzeichen, ob Objekt eine binaere Datei ist 120 * @type Boolean 121 */ 122 var $isFile = false; 123 124 /** 125 * Kennzeichen, ob Objekt ein Bild ist 126 * @type Boolean 127 */ 128 var $isImage = false; 129 130 /** 131 * Kennzeichen, ob Objekt ein Text ist 132 * @type Boolean 133 */ 134 var $isText = false; 135 136 /** 137 * Kennzeichen, ob Objekt eine Seite ist 138 * @type Boolean 139 */ 140 var $isPage = false; 141 142 /** 143 * Kennzeichen, ob Objekt eine Verknuepfung (Link) ist 144 * @type Boolean 145 */ 146 var $isLink = false; 147 148 /** 149 * Kennzeichen, ob Objekt eine Verknuepfung (Url) ist 150 * @type Boolean 151 */ 152 var $isUrl = false; 153 154 /** 155 * Kennzeichen, ob Objekt ein Alias ist 156 * @type Boolean 157 */ 158 var $isAlias = false; 159 160 /** 161 * Kennzeichen, ob Objekt ein Alias ist 162 * @type Boolean 163 */ 164 var $isScript = false; 165 166 /** 167 * Kennzeichnet den Typ dieses Objektes. 168 * Muss den Inhalt OR_FILE, OR_FOLDER, OR_PAGE oder OR_LINK haben. 169 * Vorbelegung mit <code>null</code>. 170 * @type Integer 171 */ 172 var $type = null; 173 174 175 /** 176 * Projekt-ID 177 * @see Project 178 * @type Integer 179 */ 180 public $projectid; 181 182 183 public $typeid; 184 185 private $aclMask = null; 186 private $parentfolders = array(); 187 188 /** 189 * @type String 190 */ 191 public $settings; 192 193 /** 194 * Strategy for publishing objects. 195 * @var Publisher 196 */ 197 public $publisher; 198 199 /** <strong>Konstruktor</strong> 200 * F?llen des neuen Objektes mit Init-Werten 201 * Es werden die Standardwerte aus der Session benutzt, um 202 * Sprach-ID, Projektmodell-Id und Projekt-ID zu setzen 203 * 204 * @param Integer Objekt-ID (optional) 205 */ 206 function __construct($objectid = '') 207 { 208 if ( is_numeric($objectid) ) 209 { 210 $this->objectid = $objectid; 211 } 212 } 213 214 215 /** 216 * Kompletten Dateinamen des Objektes erzeugen 217 * @return String 218 */ 219 public function full_filename() 220 { 221 $path = $this->path(); 222 223 if ($path != '') 224 $path.= '/'; 225 226 $path.= $this->filename(); 227 228 return $path; 229 } 230 231 /** 232 * Pruefen einer Berechtigung zu diesem Objekt 233 */ 234 public function hasRight( $type ) 235 { 236 if ( is_null($this->aclMask) ) 237 { 238 $user = Request::getUser(); 239 240 $this->aclMask = 0; 241 242 if ( ! $user ) { 243 // Anonymous 244 245 $sql = Db::sql( <<<SQL 246 SELECT * FROM {{acl}} 247 WHERE objectid={objectid} 248 AND type = {guest} 249 SQL 250 ); 251 252 $sql->setInt ( 'objectid' ,$this->objectid ); 253 $sql->setInt ( 'guest' ,Permission::TYPE_GUEST ); 254 255 foreach($sql->getAll() as $row ) 256 { 257 $permission = new Permission(); 258 $permission->setDatabaseRow( $row ); 259 260 $this->aclMask |= $permission->getMask(); 261 } 262 263 } 264 265 elseif ( $user->isAdmin ) 266 { 267 // Administrators got all rights 268 $this->aclMask = Permission::ACL_ALL; 269 } 270 else 271 { 272 // Normal user 273 $this->aclMask = 0; 274 275 $sqlGroupClause = $user->getGroupClause(); 276 $sql = Db::sql( <<<SQL 277 SELECT * FROM {{acl}} 278 WHERE objectid={objectid} 279 /*--AND ( languageid={languageid} OR languageid IS NULL )*/ 280 AND ( type = {user} AND userid={userid} 281 OR type = {group} AND $sqlGroupClause 282 OR type = {all} 283 OR type = {guest} 284 ) 285 SQL 286 ); 287 288 $sql->setInt ( 'objectid' ,$this->objectid ); 289 $sql->setInt ( 'userid' ,$user->userid ); 290 $sql->setInt ( 'user' ,Permission::TYPE_USER ); 291 $sql->setInt ( 'group' ,Permission::TYPE_GROUP); 292 $sql->setInt ( 'all' ,Permission::TYPE_AUTH ); 293 $sql->setInt ( 'guest' ,Permission::TYPE_GUEST ); 294 295 foreach($sql->getAll() as $row ) 296 { 297 $permission = new Permission(); 298 $permission->setDatabaseRow( $row ); 299 300 $this->aclMask |= $permission->getMask(); 301 } 302 } 303 } 304 305 if ( Startup::readonly() ) 306 // System is readonly. 307 // The maximum permission is readonly. 308 $this->aclMask = Permission::ACL_READ && $this->aclMask; 309 310 // Ermittelte Maske auswerten 311 return $this->aclMask & $type; 312 } 313 314 315 /** 316 * Get the type name. 317 * 318 * @return String type of object, f.e. 'folder','file','page', ... 319 */ 320 function getType() 321 { 322 $mapTypeIdToName = [ 323 self::TYPEID_FOLDER => 'folder', 324 self::TYPEID_FILE => 'file' , 325 self::TYPEID_PAGE => 'page' , 326 self::TYPEID_LINK => 'link' , 327 self::TYPEID_URL => 'url' , 328 self::TYPEID_IMAGE => 'image' , 329 self::TYPEID_TEXT => 'text' , 330 self::TYPEID_ALIAS => 'alias' , 331 self::TYPEID_SCRIPT => 'script', 332 ]; 333 334 return @$mapTypeIdToName[ $this->getTypeid() ] ?: 'unknown typeid '.$this->getTypeid(); 335 } 336 337 338 /** 339 * Eigenschaften des Objektes. Kann durch Unterklassen erweitert werden. 340 * @return array 341 */ 342 public function getProperties() 343 { 344 return [ 345 'id' =>$this->objectid, 346 'objectid' =>$this->objectid, 347 'parentid' =>$this->parentid, 348 'filename' =>$this->filename, 349 'create_date' =>$this->createDate, 350 'create_user' =>$this->createUser->getProperties(), 351 'lastchange_date' =>$this->lastchangeDate, 352 'lastchange_user' =>$this->lastchangeUser->getProperties(), 353 'published_date' =>$this->publishedDate, 354 'published_user' =>$this->publishedUser->getProperties(), 355 'isFolder' =>$this->isFolder, 356 'isFile' =>$this->isFile, 357 'isImage' =>$this->isImage, 358 'isText' =>$this->isText, 359 'isScript' =>$this->isScript, 360 'isLink' =>$this->isLink, 361 'isUrl' =>$this->isUrl, 362 'isPage' =>$this->isPage, 363 'isRoot' =>$this->isRoot(), 364 'projectid' =>$this->projectid, 365 'settings' =>$this->settings, 366 'valid_from_date' =>$this->validFromDate, 367 'valid_to_date' =>$this->validToDate, 368 'type' =>$this->getType() 369 ]; 370 } 371 372 373 /** 374 * Ermitteln des physikalischen Dateipfades, in dem sich das Objekt befindet 375 * @return String Pfadangabe, z.B. 'pfad/zu/objekt' 376 */ 377 public function path() 378 { 379 $alias = $this->getAlias(); 380 381 if ( $alias ) 382 $folder = new Folder($alias->parentid); 383 else 384 $folder = new Folder($this->parentid); 385 386 return implode('/', $folder->parentObjectFileNames(false, true)); 387 } 388 389 390 391 /** 392 * Creates a slug url out of the filename. 393 * 394 * @param $filename String Name 395 * @return string 396 */ 397 public static function urlify( $filename ) 398 { 399 $slug = $filename; 400 401 // The hard method to replace UTF-8-chars with their alphanumeric replacement. 402 $replacements = array( 403 // German umlauts 404 "\xc3\x84" => 'ae', 405 "\xc3\xa4" => 'ae', 406 "\xc3\x9c" => 'ue', 407 "\xc3\xbc" => 'ue', 408 "\xc3\x96" => 'oe', 409 "\xc3\xb6" => 'oe', 410 "\xc3\x9f" => 'ss', 411 "\xe2\x82\xac" => 'eur', 412 // Francais 413 "\xc3\xa0" => 'a', 414 "\xc3\xa1" => 'a', 415 "\xc3\xa2" => 'a', 416 "\xc3\xa3" => 'a', 417 "\xc3\xa5" => 'a', 418 "\xc3\xa6" => 'ae', 419 "\xc3\xa7" => 'c', 420 "\xc3\xa8" => 'e', 421 "\xc3\xa9" => 'e', 422 "\xc3\xaa" => 'e', 423 "\xc3\xab" => 'e', 424 "\xc3\xac" => 'i', 425 "\xc3\xad" => 'i', 426 "\xc3\xae" => 'i', 427 "\xc3\xaf" => 'i', 428 "\xc3\xb2" => 'o', 429 "\xc3\xb3" => 'o', 430 "\xc3\xb4" => 'o', 431 "\xc3\xb5" => 'o', 432 "\xc3\xb8" => 'o', 433 "\xc3\xb9" => 'u', 434 "\xc3\xba" => 'u', 435 "\xc3\xbb" => 'u', 436 "\xc3\xbd" => 'y', 437 "\xc3\xbf" => 'y', 438 "\xc3\x80" => 'a', 439 "\xc3\x81" => 'a', 440 "\xc3\x82" => 'a', 441 "\xc3\x83" => 'a', 442 "\xc3\x85" => 'a', 443 "\xc3\x86" => 'ae', 444 "\xc3\x87" => 'c', 445 "\xc3\x88" => 'e', 446 "\xc3\x89" => 'e', 447 "\xc3\x8a" => 'e', 448 "\xc3\x8b" => 'e', 449 "\xc3\x8c" => 'i', 450 "\xc3\x8d" => 'i', 451 "\xc3\x8e" => 'i', 452 "\xc3\x8f" => 'i', 453 "\xc3\x92" => 'o', 454 "\xc3\x93" => 'o', 455 "\xc3\x94" => 'o', 456 "\xc3\x95" => 'o', 457 "\xc3\x98" => 'o', 458 "\xc3\x99" => 'u', 459 "\xc3\x9a" => 'u', 460 "\xc3\x9b" => 'u', 461 "\xc3\x9d" => 'y', 462 ); 463 464 $slug = str_replace(array_keys($replacements), array_values($replacements), $slug); 465 466 // 2nd try is to use iconv with the current locale. 467 if ( function_exists('iconv') ) { 468 Language::setLocale(Configuration::subset('language')->get('language_code', 'en')); 469 // iconv is buggy on alpine 3 and does not support TRANSLIT. So we have to catch the error here. 470 $converted = @iconv('utf-8', 'ascii//TRANSLIT', $slug); 471 if ( $converted !== false ) 472 $slug = $converted; 473 } 474 // now replace every unpleasant char with a hyphen. 475 $slug = preg_replace('/[^A-Za-z0-9-]+/', '-', $slug); 476 477 // trim and lowercase. 478 $slug = trim($slug, '-'); 479 $slug = strtolower($slug); 480 481 return $slug; 482 } 483 484 485 486 public function getParentFolderId() 487 { 488 $alias = $this->getAlias(); 489 if ( $alias ) 490 return $alias->parentid; 491 else 492 return $this->parentid; 493 } 494 495 496 /** 497 * Ermitteln des Dateinamens und Rueckgabe desselben 498 * @return String Dateiname 499 */ 500 public function filename() 501 { 502 $filenameConfig = Configuration::subset('filename'); 503 504 $filename = $this->filename; 505 506 $alias = $this->getAlias(); 507 508 if ( $alias ) 509 $filename = $alias->filename; 510 511 if ( $filenameConfig->is('edit',true) && $filename != '' && $filename != $this->objectid ) 512 { 513 // do not change the filename here - otherwise there is a danger of filename collisions. 514 return $filename; 515 } 516 517 // Filename is not edited, so we are generating a pleasant filename. 518 switch( $filenameConfig->get('style','short' ) ) 519 { 520 case 'longid': 521 // Eine etwas laengere ID als Dateinamen benutzen 522 return base_convert(str_pad($this->objectid,6,'a'),11,10); 523 break; 524 525 case 'longalpha': 526 // Eine etwas laengere ID als Dateinamen benutzen 527 return base_convert(str_pad($this->objectid,6,'a'),11,36); 528 break; 529 530 case 'short': 531 // As shortly as possible 532 // Examples: 533 // 1 -> 1 534 // 10 -> a 535 return base_convert($this->objectid,10,36); 536 537 case 'md5': // Removed, because collisions are possible. 538 case 'title': // Not possible any more because of the collision danger 539 case 'ss': // Old storyserver crap (removed) 540 case 'id': 541 default: 542 // Taking the object id as filename. 543 return $this->objectid; 544 545 } 546 } 547 548 549 550 /** 551 * Stellt fest, ob das Objekt mit der angegebenen Id existiert. 552 */ 553 public static function available( $objectid ) 554 { 555 $db = \cms\base\DB::get(); 556 557 // Vielleicht k�nnen wir uns den DB-Zugriff auch ganz sparen. 558 if ( !is_numeric($objectid) || $objectid <= 0 ) 559 return false; // Objekt-Id ung�ltig. 560 561 $sql = $db->sql('SELECT 1 FROM {{object}} '. 562 ' WHERE id={objectid}'); 563 $sql->setInt('objectid' , $objectid ); 564 565 return intval($sql->getOne()) == 1; 566 } 567 568 569 /** 570 * Lesen der Eigenschaften aus der Datenbank 571 * Es werden 572 * - die sprachunabh?ngigen Daten wie Dateiname, Typ sowie Erstellungs- und ?nderungsdatum geladen 573 * - die sprachabh?ngigen Daten wie Name und Beschreibung geladen 574 * @throws \util\exception\ObjectNotFoundException 575 */ 576 function objectLoad() 577 { 578 $db = \cms\base\DB::get(); 579 580 $stmt = $db->sql( <<<SQL 581 SELECT {{object}}.*, 582 lastchangeuser.name as lastchange_username, 583 lastchangeuser.fullname as lastchange_userfullname, 584 lastchangeuser.mail as lastchange_usermail, 585 publisheduser.name as published_username, 586 publisheduser.fullname as published_userfullname, 587 publisheduser.mail as published_usermail, 588 createuser.name as create_username, 589 createuser.fullname as create_userfullname, 590 createuser.mail as create_usermail 591 FROM {{object}} 592 LEFT JOIN {{user}} as lastchangeuser 593 ON {{object}}.lastchange_userid=lastchangeuser.id 594 LEFT JOIN {{user}} as publisheduser 595 ON {{object}}.published_userid=publisheduser.id 596 LEFT JOIN {{user}} as createuser 597 ON {{object}}.create_userid=createuser.id 598 WHERE {{object}}.id={objectid} 599 SQL 600 ); 601 $stmt->setInt('objectid' , $this->objectid ); 602 603 $row = $stmt->getRow(); 604 605 if (count($row) == 0) 606 throw new \util\exception\ObjectNotFoundException('object '.$this->objectid.' not found'); 607 608 $this->setDatabaseRow( $row ); 609 } 610 611 612 /** 613 * Lesen der Eigenschaften aus der Datenbank 614 * Es werden 615 * - die sprachunabhaengigen Daten wie Dateiname, Typ sowie Erstellungs- und Aenderungsdatum geladen 616 */ 617 function objectLoadRaw() 618 { 619 $db = \cms\base\DB::get(); 620 621 $sql = $db->sql('SELECT * FROM {{object}}'. 622 ' WHERE {{object}}.id={objectid}'); 623 $sql->setInt('objectid' , $this->objectid ); 624 $row = $sql->getRow(); 625 626 if (count($row) == 0) 627 throw new \util\exception\ObjectNotFoundException('objectid not found: '.$this->objectid); 628 629 $this->parentid = $row['parentid' ]; 630 $this->filename = $row['filename' ]; 631 $this->projectid = $row['projectid']; 632 633 $this->createDate = $row['create_date' ]; 634 $this->createUser = $row['create_userid' ]; 635 $this->lastchangeDate = $row['lastchange_date' ]; 636 $this->lastchangeUser = $row['lastchange_userid']; 637 638 $this->isFolder = ( $row['typeid'] == self::TYPEID_FOLDER ); 639 $this->isFile = ( $row['typeid'] == self::TYPEID_FILE ); 640 $this->isImage = ( $row['typeid'] == self::TYPEID_IMAGE ); 641 $this->isText = ( $row['typeid'] == self::TYPEID_TEXT ); 642 $this->isPage = ( $row['typeid'] == self::TYPEID_PAGE ); 643 $this->isLink = ( $row['typeid'] == self::TYPEID_LINK ); 644 $this->isUrl = ( $row['typeid'] == self::TYPEID_URL ); 645 $this->isAlias = ( $row['typeid'] == self::TYPEID_ALIAS ); 646 $this->isScript = ( $row['typeid'] == self::TYPEID_SCRIPT ); 647 648 } 649 650 651 /** 652 * Is this the root object in a project? 653 * 654 * @return bool 655 */ 656 public function isRoot() { 657 658 return ! $this->parentid; 659 } 660 661 /** 662 * Setzt die Eigenschaften des Objektes mit einer Datenbank-Ergebniszeile 663 * 664 * @param array Ergebniszeile aus Datenbanktabelle 665 */ 666 public function setDatabaseRow( $row ) 667 { 668 if ( count($row)==0 ) 669 throw new \LogicException('setDatabaseRow() got empty array, oid='.$this->objectid); 670 671 $this->parentid = $row['parentid' ]; 672 $this->projectid = $row['projectid']; 673 $this->filename = $row['filename' ]; 674 $this->orderid = $row['orderid' ]; 675 676 $this->createDate = $row['create_date' ]; 677 $this->lastchangeDate = $row['lastchange_date']; 678 $this->publishedDate = $row['published_date' ]; 679 680 $this->validFromDate = $row['valid_from' ]; 681 $this->validToDate = $row['valid_to' ]; 682 683 $this->createUser = new User(); 684 $this->createUser->userid = $row['create_userid' ]; 685 if ( !empty($row['create_username']) ) 686 { 687 $this->createUser->name = $row['create_username' ]; 688 $this->createUser->fullname = $row['create_userfullname' ]; 689 $this->createUser->mail = $row['create_usermail' ]; 690 } 691 692 $this->lastchangeUser = new User(); 693 $this->lastchangeUser->userid = $row['lastchange_userid' ]; 694 695 if ( !empty($row['lastchange_username']) ) 696 { 697 $this->lastchangeUser->name = $row['lastchange_username' ]; 698 $this->lastchangeUser->fullname = $row['lastchange_userfullname']; 699 $this->lastchangeUser->mail = $row['lastchange_usermail' ]; 700 } 701 702 $this->publishedUser = new User(); 703 $this->publishedUser->userid = $row['published_userid' ]; 704 705 if ( !empty($row['published_username']) ) 706 { 707 $this->publishedUser->name = $row['published_username' ]; 708 $this->publishedUser->fullname = $row['published_userfullname']; 709 $this->publishedUser->mail = $row['published_usermail' ]; 710 } 711 712 $this->typeid = $row['typeid']; 713 714 $this->isFolder = ( $row['typeid'] == self::TYPEID_FOLDER ); 715 $this->isFile = ( $row['typeid'] == self::TYPEID_FILE ); 716 $this->isImage = ( $row['typeid'] == self::TYPEID_IMAGE ); 717 $this->isText = ( $row['typeid'] == self::TYPEID_TEXT ); 718 $this->isPage = ( $row['typeid'] == self::TYPEID_PAGE ); 719 $this->isLink = ( $row['typeid'] == self::TYPEID_LINK ); 720 $this->isUrl = ( $row['typeid'] == self::TYPEID_URL ); 721 $this->isAlias = ( $row['typeid'] == self::TYPEID_ALIAS ); 722 $this->isScript = ( $row['typeid'] == self::TYPEID_SCRIPT ); 723 724 $this->settings = $row['settings']; 725 } 726 727 728 729 /** 730 * Laden des Objektes 731 */ 732 public function load() 733 { 734 self::objectLoad(); 735 return $this; 736 } 737 738 739 /** 740 * Eigenschaften des Objektes in Datenbank speichern 741 */ 742 public function save() 743 { 744 $this->setTimestamp(); 745 $this->checkFilename(); 746 747 $stmt = Db::sql( <<<SQL 748 UPDATE {{object}} SET 749 parentid = {parentid}, 750 filename = {filename}, 751 valid_from = {validFrom}, 752 valid_to = {validTo}, 753 settings = {settings} 754 WHERE id={objectid} 755 SQL 756 ); 757 758 759 if ( ! $this->parentid ) 760 $stmt->setNull('parentid'); 761 else 762 $stmt->setInt ('parentid',$this->parentid ); 763 764 765 $user = Request::getUser(); 766 $this->lastchangeUser = $user; 767 $this->lastchangeDate = Startup::now(); 768 $stmt->setString('filename' , $this->filename ); 769 $stmt->setString('settings' , $this->settings ); 770 $stmt->setInt ('validFrom', $this->validFromDate ); 771 $stmt->setInt ('validTo' , $this->validToDate ); 772 $stmt->setInt ('objectid' , $this->objectid ); 773 774 775 $stmt->execute(); 776 777 $this->setTimestamp(); 778 } 779 780 781 782 /** 783 * Aenderungsdatum auf Systemzeit setzen 784 */ 785 public function setTimestamp() 786 { 787 $db = \cms\base\DB::get(); 788 789 $sql = $db->sql('UPDATE {{object}} SET '. 790 ' lastchange_date = {time} ,'. 791 ' lastchange_userid = {userid} '. 792 ' WHERE id={objectid}'); 793 794 $user = Request::getUser(); 795 $this->lastchangeUser = $user; 796 $this->lastchangeDate = Startup::now(); 797 $userid = $this->lastchangeUser ? $this->lastchangeUser->userid : null; 798 799 $sql->setIntOrNull('userid' ,$userid ); 800 $sql->setInt ('objectid',$this->objectid ); 801 $sql->setInt ('time' ,$this->lastchangeDate ); 802 803 $sql->execute(); 804 805 } 806 807 808 public function setCreationTimestamp() 809 { 810 $db = \cms\base\DB::get(); 811 812 $sql = $db->sql('UPDATE {{object}} SET '. 813 ' create_date = {time} '. 814 ' WHERE id={objectid}'); 815 816 $sql->setInt ('objectid',$this->objectid ); 817 $sql->setInt ('time' ,$this->createDate ); 818 819 $sql->execute(); 820 } 821 822 823 public function setPublishedTimestamp() 824 { 825 $db = \cms\base\DB::get(); 826 827 $sql = $db->sql('UPDATE {{object}} SET '. 828 ' published_date = {time} ,'. 829 ' published_userid = {userid} '. 830 ' WHERE id={objectid}'); 831 832 $user = Request::getUser(); 833 $this->publishedUser = $user; 834 $this->publishedDate = Startup::now(); 835 836 $sql->setInt ('userid' ,$this->publishedUser->userid ); 837 $sql->setInt ('objectid',$this->objectid ); 838 $sql->setInt ('time' ,$this->publishedDate ); 839 840 $sql->execute(); 841 } 842 843 844 845 /** 846 * Objekt loeschen. Es muss sichergestellt sein, dass auch das Unterobjekt geloeschet wird. 847 * Diese Methode wird daher normalerweise nur vom Unterobjekt augerufen 848 * @access protected 849 */ 850 public function delete() 851 { 852 $db = \cms\base\DB::get(); 853 854 $sql = DB::sql( <<<SQL 855 UPDATE {{element}} 856 SET default_objectid=NULL 857 WHERE default_objectid={objectid} 858 SQL 859 ); 860 $sql->setInt('objectid',$this->objectid); 861 $sql->execute(); 862 863 $sql = $db->sql( <<<'SQL' 864 UPDATE {{value}} 865 SET linkobjectid=NULL 866 WHERE linkobjectid={objectid} 867 SQL 868 ); 869 $sql->setInt('objectid',$this->objectid); 870 $sql->execute(); 871 872 $sql = $db->sql( <<<'SQL' 873 UPDATE {{link}} 874 SET link_objectid=NULL 875 WHERE link_objectid={objectid} 876 SQL 877 ); 878 $sql->setInt('objectid',$this->objectid); 879 $sql->execute(); 880 881 882 // Objekt-Namen l?schen 883 $sql = $db->sql(<<<'SQL' 884 DELETE FROM {{name}} 885 WHERE objectid={objectid} 886 SQL 887 ); 888 $sql->setInt('objectid', $this->objectid); 889 $sql->execute(); 890 891 // Aliases löschen. 892 $sql = Db::sql(<<<'SQL' 893 DELETE FROM {{alias}} 894 WHERE objectid={objectid} 895 SQL 896 ); 897 $sql->setInt('objectid', $this->objectid); 898 $sql->execute(); 899 900 // ACLs loeschen 901 $this->deleteAllACLs(); 902 903 904 // Delete Tags from objects 905 $sql = Db::sql(<<<'SQL' 906 DELETE FROM {{tag_object}} 907 WHERE objectid={objectid} 908 SQL 909 ); 910 $sql->setInt('objectid', $this->objectid); 911 $sql->execute(); 912 913 // Delete bookmarks. 914 $sql = Db::sql(<<<'SQL' 915 DELETE FROM {{bookmark}} 916 WHERE objectid={objectid} 917 SQL 918 ); 919 $sql->setInt('objectid', $this->objectid); 920 $sql->execute(); 921 922 923 // Objekt l?schen 924 $sql = $db->sql(<<<'SQL' 925 DELETE FROM {{object}} 926 WHERE id={objectid} 927 SQL 928 ); 929 $sql->setInt('objectid', $this->objectid); 930 $sql->execute(); 931 932 $this->objectid = null; 933 } 934 935 /** 936 * Get all Tags for this object. 937 * 938 * @return String[] 939 */ 940 public function getTags() 941 { 942 $sql = DB::sql( <<<SQL 943 SELECT {{tag}}.id,{{tag}}.name 944 FROM {{tag_object}} 945 LEFT JOIN {{tag}} 946 ON {{tag_object}}.tagid = {{tag}}.id 947 WHERE objectid={objectid} 948 SQL 949 ); 950 $sql->setInt('objectid',$this->objectid ); 951 952 return $sql->getAssoc(); 953 } 954 955 956 /** 957 * Objekt hinzufuegen. 958 * 959 * Standardrechte und vom Elternobjekt vererbbare Berechtigungen werden gesetzt. 960 */ 961 protected function add() 962 { 963 // Neue Objekt-Id bestimmen 964 $sql = Db::sql(<<<'SQL' 965 SELECT MAX(id) FROM {{object}} 966 SQL 967 ); 968 $this->objectid = intval($sql->getOne())+1; 969 970 $this->checkFilename(); 971 $sql = Db::sql(<<<SQL 972 INSERT INTO {{object}} 973 (id,parentid,projectid,filename,orderid,create_date,create_userid,lastchange_date,lastchange_userid,typeid,settings) 974 VALUES( {objectid},{parentid},{projectid},{filename},{orderid},{time},{createuserid},{createtime},{userid},{typeid},'' ) 975 SQL 976 ); 977 978 $user = Request::getUser(); 979 $currentUserId = $user ? $user->userid : 0; 980 981 if ( !$this->parentid ) 982 $sql->setNull('parentid'); 983 else 984 $sql->setInt ('parentid',$this->parentid ); 985 986 $sql->setInt ('objectid' , $this->objectid ); 987 $sql->setString('filename' , $this->filename ); 988 $sql->setString('projectid', $this->projectid); 989 $sql->setInt ('orderid' , 99999 ); 990 $sql->setInt ('time' , Startup::now() ); 991 992 $sql->setInt ('createuserid' , $currentUserId ); 993 $sql->setInt ('createtime' , Startup::now() ); 994 $sql->setInt ('userid' , $currentUserId ); 995 996 $sql->setInt( 'typeid',$this->getTypeid()); 997 998 $sql->execute(); 999 1000 $this->grantToActualUser(); // Is this a good idea? don't know ... 1001 $this->inheritPermissions(); 1002 } 1003 1004 1005 /** 1006 * Set permissions for the actual user for the just added object. 1007 * 1008 * @return void 1009 */ 1010 private function grantToActualUser() { 1011 1012 $user = Request::getUser(); 1013 1014 if ( $user ) { // User logged in? 1015 1016 $permission = new Permission(); 1017 $permission->type = Permission::TYPE_USER; 1018 $permission->userid = $user->userid; 1019 $permission->objectid = $this->objectid; 1020 1021 $permission->read = true; 1022 $permission->write = true; 1023 $permission->prop = true; 1024 $permission->delete = true; 1025 $permission->grant = true; 1026 1027 $permission->create_file = true; 1028 $permission->create_page = true; 1029 $permission->create_folder = true; 1030 $permission->create_link = true; 1031 1032 $permission->persist(); 1033 } 1034 } 1035 1036 1037 /** 1038 * Inherit permissions from parent folder. 1039 * 1040 * @return void 1041 */ 1042 private function inheritPermissions() { 1043 $parent = new BaseObject( $this->parentid ); 1044 1045 foreach( $parent->getAllAclIds() as $aclid ) 1046 { 1047 $permission = new Permission( $aclid ); 1048 $permission->load(); 1049 1050 if ( $permission->transmit ) // ACL is vererbbar, also kopieren. 1051 { 1052 $permission->aclid = null; 1053 $permission->objectid = $this->objectid; 1054 $permission->persist(); // ... und hinzufuegen. 1055 } 1056 } 1057 } 1058 1059 /** 1060 * Pruefung auf Gueltigkeit des Dateinamens 1061 */ 1062 private function checkFilename() 1063 { 1064 if ( empty($this->filename) ) 1065 $this->filename = $this->objectid; 1066 1067 if ( $this->isRoot() ) // Beim Root-Ordner ist es egal, es gibt nur einen. 1068 return; 1069 1070 if ( !$this->filenameIsUnique( $this->filename ) ) 1071 { 1072 // Append some string to filename. 1073 $this->filename = $this->filename.'-'.base_convert(time(), 10, 36); 1074 } 1075 } 1076 1077 1078 /** 1079 * Stellt fest, dass der Dateiname im aktuellen Ordner kein weiteres Mal vorkommt. 1080 * Dies muss vor dem Speichern geprüft werden, ansonsten erfolgt eine Index-Verletzung 1081 * und der Datensatz kann nicht gespeichert werde. 1082 * 1083 * @param $filename 1084 * @return bool 1085 */ 1086 private function filenameIsUnique( $filename ) 1087 { 1088 $sql = Db::sql( <<<SQL 1089 SELECT COUNT(*) FROM {{object}} 1090 WHERE parentid={parentid} AND filename={filename} 1091 AND NOT id = {objectid} 1092 SQL 1093 ); 1094 1095 $sql->setString('parentid', $this->parentid); 1096 $sql->setString('filename', $filename ); 1097 $sql->setString('objectid', $this->objectid); 1098 1099 1100 return( intval($sql->getOne()) == 0 ); 1101 } 1102 1103 1104 function getAllAclIds() 1105 { 1106 $db = \cms\base\DB::get(); 1107 1108 $sql = $db->sql( <<<'SQL' 1109 SELECT id FROM {{acl}} 1110 WHERE objectid={objectid} 1111 ORDER BY userid,groupid ASC 1112 SQL 1113 ); 1114 $sql->setInt('objectid' ,$this->objectid); 1115 1116 return $sql->getCol(); 1117 } 1118 1119 1120 /** 1121 * Ermitteln aller Berechtigungsstufen. 1122 */ 1123 function getRelatedAclTypes() 1124 { 1125 return( array('read','write','delete','prop','release','publish','create_folder','create_file','create_page','create_link','grant','transmit') ); 1126 } 1127 1128 1129 /** 1130 * Ermitteln aller Berechtigungsstufen. 1131 */ 1132 function getAssocRelatedAclTypes() 1133 { 1134 $types = array(); 1135 1136 foreach( $this->getRelatedAclTypes() as $t ) 1137 $types[$t] = true; 1138 1139 return $types; 1140 } 1141 1142 /** 1143 * Entfernen aller ACLs zu diesem Objekt 1144 * @access private 1145 */ 1146 private function deleteAllACLs() 1147 { 1148 foreach( $this->getAllAclIds() as $aclid ) 1149 { 1150 $permission = new Permission( $aclid ); 1151 $permission->load(); 1152 $permission->delete(); 1153 } 1154 } 1155 1156 1157 1158 /** 1159 * Reihenfolge-Sequenznr. dieses Objektes neu speichern 1160 * die Nr. wird sofort in der Datenbank gespeichert. 1161 * 1162 * @param Integer neue Sequenz-Nr. 1163 */ 1164 public function setOrderId( $orderid ) 1165 { 1166 $sql = Db::sql('UPDATE {{object}} '.' SET orderid={orderid}'.' WHERE id={objectid}'); 1167 $sql->setInt('objectid', $this->objectid); 1168 $sql->setInt('orderid', $orderid); 1169 1170 $sql->execute(); 1171 } 1172 1173 1174 /** 1175 * Reads all direct children of this object. 1176 */ 1177 protected function getChildren() 1178 { 1179 $stmt = Db::sql(<<<SQL 1180 1181 SELECT id FROM {{object}} 1182 WHERE parentid={objectid} 1183 ORDER BY orderid ASC 1184 SQL 1185 ); 1186 1187 $stmt->setInt( 'objectid' ,$this->objectid ); 1188 1189 return $stmt->getCol(); 1190 } 1191 1192 1193 /** 1194 * Reads all descendants. 1195 * 1196 */ 1197 public function getAllDescendantsIds() 1198 { 1199 $descendantIds = array(); 1200 1201 foreach( $this->getChildren() as $id ) 1202 { 1203 $descendantIds[] = $id; 1204 1205 $baseObject = new BaseObject( $id ); 1206 $descendantIds = array_merge( $descendantIds, $baseObject->getAllDescendantsIds() ); 1207 } 1208 1209 return $descendantIds; 1210 } 1211 /** 1212 * ?bergeordnete Objekt-ID dieses Objektes neu speichern 1213 * die Nr. wird sofort in der Datenbank gespeichert. 1214 * 1215 * @param Integer ?bergeordnete Objekt-ID 1216 */ 1217 public function setParentId( $parentid ) 1218 { 1219 1220 $descendantsIds = $this->getAllDescendantsIds(); 1221 1222 if ( in_array($parentid,$descendantsIds) || $parentid == $this->objectid ) 1223 throw new \LogicException('new parent may not be a descendant of this node.'); 1224 1225 $db = \cms\base\DB::get(); 1226 1227 $sql = $db->sql('UPDATE {{object}} '.' SET parentid={parentid}'.' WHERE id={objectid}'); 1228 $sql->setInt('objectid', $this->objectid); 1229 $sql->setInt('parentid', $parentid); 1230 1231 $sql->execute(); 1232 } 1233 1234 1235 /** 1236 * Get all References to this object 1237 * @return array 1238 */ 1239 public function getDependentObjectIds() 1240 { 1241 $stmt = DB::sql( <<<SQL 1242 1243 SELECT {{page}}.objectid FROM {{value}} 1244 LEFT JOIN {{pagecontent}} 1245 ON {{value}}.contentid = {{pagecontent}}.contentid 1246 LEFT JOIN {{page}} 1247 ON {{pagecontent}}.pageid = {{page}}.id 1248 WHERE linkobjectid={myobjectid1} 1249 UNION 1250 SELECT objectid FROM {{link}} 1251 WHERE link_objectid={myobjectid2} 1252 SQL 1253 ); 1254 $stmt->setInt( 'myobjectid1',$this->objectid ); 1255 $stmt->setInt( 'myobjectid2',$this->objectid ); 1256 1257 return $stmt->getCol(); 1258 } 1259 1260 1261 1262 1263 /** 1264 * Liefert die Link-Ids, die auf das aktuelle Objekt verweisen. 1265 * @return array Liste der gefundenen Objekt-IDs 1266 * @see BaseObject#getDependentObjectIds 1267 */ 1268 public function getLinksToMe() 1269 { 1270 $db = \cms\base\DB::get(); 1271 1272 $sql = $db->sql( 'SELECT objectid FROM {{link}} '. 1273 ' WHERE link_objectid={myid}' ); 1274 $sql->setInt ( 'myid' ,$this->objectid ); 1275 1276 return $sql->getCol(); 1277 } 1278 1279 private function getTypeid() 1280 { 1281 if ($this->isFolder) return self::TYPEID_FOLDER; 1282 if ($this->isFile ) return self::TYPEID_FILE; 1283 if ($this->isImage ) return self::TYPEID_IMAGE; 1284 if ($this->isText ) return self::TYPEID_TEXT; 1285 if ($this->isPage ) return self::TYPEID_PAGE; 1286 if ($this->isLink ) return self::TYPEID_LINK; 1287 if ($this->isUrl ) return self::TYPEID_URL; 1288 if ($this->isAlias ) return self::TYPEID_ALIAS; 1289 if ($this->isScript ) return self::TYPEID_SCRIPT; 1290 } 1291 1292 1293 /** 1294 * Local Settings. 1295 * 1296 * @return array 1297 */ 1298 public function getSettings() 1299 { 1300 $settings = YAML::parse($this->settings); 1301 1302 $resolver = new VariableResolver(); 1303 $resolver->namespaceSeparator = ':'; 1304 1305 // Resolve config variables. 1306 $resolver->addResolver('config', function ($var) { 1307 $conf = Configuration::Conf()->getConfig(); 1308 return ArrayUtils::getSubValue($conf,explode('.',$var) ); 1309 }); 1310 1311 $settings = $resolver->resolveVariablesInArray( $settings ); 1312 1313 return $settings; 1314 } 1315 1316 /** 1317 * Inherited Settings. 1318 * 1319 * @return array 1320 */ 1321 public function getTotalSettings() 1322 { 1323 $totalSettings = array(); 1324 1325 // cumulate settings of parent objects 1326 $parentIds = array_keys( $this->parentObjectFileNames(true, false) ); 1327 foreach( $parentIds as $id ) 1328 { 1329 $parentObject = new BaseObject( $id ); 1330 $parentObject->objectLoad(); 1331 $totalSettings = array_merge($totalSettings,$parentObject->getSettings()); 1332 } 1333 1334 // add settings from this base object. 1335 $totalSettings = array_merge($totalSettings,$this->getSettings()); 1336 1337 return $totalSettings; 1338 } 1339 1340 1341 1342 /** 1343 * Liefert alle übergeordneten Ordner. 1344 * 1345 * @param bool $with_root Mit Root-Folder? 1346 * @param bool $with_self Mit dem aktuellen Ordner? 1347 * @return array 1348 */ 1349 public function parentObjectFileNames( $with_root = false, $with_self = false ) 1350 { 1351 $foid = $this->objectid; 1352 $idCache = array(); 1353 1354 while( intval($foid)!=0 ) 1355 { 1356 $sql = Db::sql( <<<SQL 1357 1358 SELECT parentid,id,filename 1359 FROM {{object}} 1360 WHERE {{object}}.id={parentid} 1361 1362 SQL 1363 ); 1364 $sql->setInt('parentid' ,$foid ); 1365 1366 $row = $sql->getRow(); 1367 1368 if ( in_array($row['id'],$idCache)) 1369 throw new \LogicException('fatal: parent-rekursion in object-id: '.$this->objectid.', double-parent-id: '.$row['id']); 1370 else 1371 $idCache[] = $row['id']; 1372 1373 $this->addParentfolder( $row['id'],$row['filename'] ); 1374 $foid = $row['parentid']; 1375 } 1376 1377 1378 $this->checkParentFolders($with_root,$with_self); 1379 1380 return $this->parentfolders; 1381 } 1382 1383 public function parentObjectNames( $with_root = false, $with_self = false ) 1384 { 1385 $foid = $this->objectid; 1386 $idCache = array(); 1387 1388 while( intval($foid)!=0 ) 1389 { 1390 $sql = Db::sql( <<<SQL 1391 SELECT {{object}}.parentid,{{object}}.id,{{object}}.filename FROM {{object}} 1392 WHERE {{object}}.id={parentid} 1393 SQL 1394 ); 1395 $sql->setInt('parentid' ,$foid ); 1396 1397 $row = $sql->getRow(); 1398 1399 if ( in_array($row['id'],$idCache)) 1400 throw new \LogicException('fatal: parent-rekursion in object-id: '.$this->objectid.', double-parent-id: '.$row['id']); 1401 else 1402 $idCache[] = $row['id']; 1403 1404 $this->addParentfolder( $row['id'],$row['filename'] ); 1405 $foid = $row['parentid']; 1406 } 1407 1408 $this->checkParentFolders($with_root,$with_self); 1409 1410 return $this->parentfolders; 1411 } 1412 1413 1414 private function addParentFolder( $id,$filename='' ) 1415 { 1416 $name = $filename; 1417 1418 if ( empty($name) ) 1419 $name = "($id)"; 1420 1421 if ( intval($id) != 0 ) 1422 $this->parentfolders[ $id ] = $name; 1423 } 1424 1425 1426 private function checkParentFolders( $with_root, $with_self ) 1427 { 1428 // Reihenfolge umdrehen 1429 $this->parentfolders = array_reverse($this->parentfolders,true); 1430 1431 // Ordner ist bereits hoechster Ordner 1432 // if ( count($this->parentfolders) == 2 && $this->isRoot && $with_root && $with_self ) 1433 // { 1434 // array_pop ( $this->parentfolders ); 1435 // return; 1436 // } 1437 1438 1439 if ( !$with_root && !empty($this->parentfolders) ) 1440 { 1441 $keys = array_keys( $this->parentfolders ); 1442 unset( $this->parentfolders[$keys[0]] ); 1443 } 1444 1445 if ( !$with_self && !empty($this->parentfolders) ) 1446 { 1447 $keys = array_keys( $this->parentfolders ); 1448 unset( $this->parentfolders[$keys[count($keys)-1]] ); 1449 } 1450 } 1451 1452 1453 /** 1454 * Liefert das Projekt-Objekt. 1455 * 1456 * @return Project 1457 * @throws \util\exception\ObjectNotFoundException 1458 */ 1459 public function getProject() { 1460 return Project::create( $this->projectid ); 1461 } 1462 1463 1464 1465 1466 /** 1467 * Es werden Objekte mit einem bestimmten Namen ermittelt 1468 * @param String Suchbegriff 1469 * @return array Liste der gefundenen Objekt-IDs 1470 */ 1471 public static function getObjectIdsByFileName( $text ) 1472 { 1473 $db = \cms\base\DB::get(); 1474 1475 $sql = $db->sql( 'SELECT id FROM {{object}} '. 1476 ' WHERE filename LIKE {filename}'. 1477 ' ORDER BY lastchange_date DESC' ); 1478 $sql->setString( 'filename','%'.$text.'%' ); 1479 1480 return $sql->getCol(); 1481 } 1482 1483 1484 /** 1485 * Es werden Objekte mit einem Namen ermittelt 1486 * @param String Suchbegriff 1487 * @return array Liste der gefundenen Objekt-IDs 1488 */ 1489 public static function getObjectIdsByName( $text ) 1490 { 1491 $db = \cms\base\DB::get(); 1492 1493 $sql = $db->sql( 'SELECT {{object}}.id FROM {{object}} '. 1494 ' LEFT JOIN {{name}} '. 1495 ' ON {{object}}.id={{name}}.objectid'. 1496 ' WHERE {{name}}.name LIKE {name}'. 1497 ' ORDER BY lastchange_date DESC' ); 1498 $sql->setString( 'name' ,'%'.$text.'%' ); 1499 1500 return $sql->getCol(); 1501 } 1502 1503 1504 /** 1505 * Es werden Objekte mit einer Beschreibung ermittelt 1506 * @param String Suchbegriff 1507 * @return array Liste der gefundenen Objekt-IDs 1508 */ 1509 public static function getObjectIdsByDescription( $text ) 1510 { 1511 $db = \cms\base\DB::get(); 1512 1513 $sql = $db->sql( 'SELECT {{object}}.id FROM {{object}} '. 1514 ' LEFT JOIN {{name}} '. 1515 ' ON {{object}}.id={{name}}.objectid'. 1516 ' WHERE {{name}}.descr LIKE {desc}'. 1517 ' ORDER BY lastchange_date DESC' ); 1518 $sql->setString( 'desc' ,'%'.$text.'%' ); 1519 1520 return $sql->getCol(); 1521 } 1522 1523 1524 /** 1525 * Es werden Objekte mit einer UserId ermittelt 1526 * @param Integer Benutzer-Id der Erstellung 1527 * @return array Liste der gefundenen Objekt-IDs 1528 */ 1529 public static function getObjectIdsByCreateUserId( $userid ) 1530 { 1531 $db = \cms\base\DB::get(); 1532 1533 $sql = $db->sql( 'SELECT id FROM {{object}} '. 1534 ' WHERE create_userid={userid}'. 1535 ' ORDER BY lastchange_date DESC' ); 1536 $sql->setInt ( 'userid' ,$userid ); 1537 1538 return $sql->getCol(); 1539 } 1540 1541 1542 /** 1543 * Es werden Objekte mit einer UserId ermittelt 1544 * @param Integer Benutzer-Id der letzten ?nderung 1545 * @return array Liste der gefundenen Objekt-IDs 1546 */ 1547 public static function getObjectIdsByLastChangeUserId( $userid ) 1548 { 1549 $db = \cms\base\DB::get(); 1550 1551 $sql = $db->sql( 'SELECT id FROM {{object}} '. 1552 ' WHERE lastchange_userid={userid}'. 1553 ' ORDER BY lastchange_date DESC' ); 1554 $sql->setInt ( 'userid' ,$userid ); 1555 1556 return $sql->getCol(); 1557 } 1558 1559 1560 /** 1561 * Stellt fest, ob das Objekt gueltig ist. 1562 */ 1563 public function isValid() 1564 { 1565 $now = time(); 1566 1567 return 1568 ($this->validFromDate == null || $this->validFromDate < $now) && 1569 ($this->validToDate == null || $this->validToDate > $now); 1570 1571 } 1572 1573 public function __toString() 1574 { 1575 return 'Object-Id '.$this->objectid.' (type='.$this->getType().',filename='.$this->filename. ')'; 1576 } 1577 1578 1579 /** 1580 * Liefert alle Name-Objekte. 1581 * @return Name[] 1582 * @throws \util\exception\ObjectNotFoundException 1583 */ 1584 public function getNames() 1585 { 1586 $names = array(); 1587 1588 foreach( $this->getProject()->getLanguages() as $languageId=>$languageName ) 1589 { 1590 $name = new Name(); 1591 $name->objectid = $this->objectid; 1592 $name->languageid = $languageId; 1593 $name->load(); 1594 1595 $names[] = $name; 1596 } 1597 1598 return $names; 1599 } 1600 1601 1602 /** 1603 * Liefert alle Name-Objekte. 1604 * @return Name 1605 * @throws \util\exception\ObjectNotFoundException 1606 */ 1607 public function getNameForLanguage( $languageId ) 1608 { 1609 $name = new Name(); 1610 $name->objectid = $this->objectid; 1611 $name->languageid = $languageId; 1612 $name->load(); 1613 1614 return $name; 1615 } 1616 1617 1618 /** 1619 * @return Name 1620 */ 1621 public function getDefaultName() 1622 { 1623 $languageId = $this->getProject()->getDefaultLanguageId(); 1624 1625 $defaultName = $this->getNameForLanguage( $languageId ); 1626 1627 if ( ! $defaultName->name ) 1628 $defaultName->name = $this->filename; 1629 1630 return $defaultName; 1631 } 1632 1633 1634 /** 1635 * Name of the object. If not exist, the filename will be used. 1636 * @return string Name 1637 */ 1638 public function getName() 1639 { 1640 $name = $this->getDefaultName()->name; 1641 1642 if ( empty($name)) 1643 $name = $this->filename; 1644 1645 return $name; 1646 } 1647 1648 1649 /** 1650 * Speichert Namen und Beschreibung für alle Sprachen. Das ist bei der Neuanlage von Objekten ganz praktisch. 1651 * 1652 * @param $nam string 1653 * @param $description string 1654 */ 1655 public function setNameForAllLanguages($nam, $description) 1656 { 1657 foreach( $this->getProject()->getLanguages() as $languageId=>$languageName ) 1658 { 1659 $name = new Name(); 1660 $name->objectid = $this->objectid; 1661 $name->languageid = $languageId; 1662 $name->load(); 1663 1664 $name->name = $nam; 1665 $name->description = $description; 1666 1667 $name->persist(); 1668 } 1669 1670 } 1671 1672 1673 /** 1674 * Returns the effective alias. If no alias exists, the actual object is returned. 1675 * 1676 * @return BaseObject 1677 */ 1678 public function getEffectiveAlias() { 1679 1680 $alias = $this->getAlias(); 1681 if ( $alias ) 1682 return $alias; 1683 else 1684 return $this; 1685 } 1686 1687 1688 1689 /** 1690 * The Alias for this Object or <code>null</code>. 1691 * 1692 * @return Alias|null 1693 * @deprecated use #getAliasForLanguage 1694 */ 1695 public function getAlias() 1696 { 1697 $alias = $this->getAliasForLanguage( $this->getProject()->getDefaultLanguageId() ); 1698 1699 if ( !$alias->isPersistent() ) 1700 $alias = $this->getAliasForLanguage( null ); 1701 1702 if ( !$alias->isPersistent() ) 1703 return null; // no alias found 1704 1705 return $alias; 1706 } 1707 1708 1709 /** 1710 * Creates an Alias for a specific language. 1711 * @param int $languageid could be null for the default alias. 1712 * @return Alias 1713 * @throws \util\exception\ObjectNotFoundException 1714 */ 1715 public function getAliasForLanguage( $languageid ) 1716 { 1717 $alias = new Alias(); 1718 $alias->projectid = $this->projectid; 1719 $alias->linkedObjectId = $this->objectid; 1720 $alias->languageid = $languageid; 1721 $alias->load(); 1722 1723 return $alias; 1724 } 1725 1726 1727 1728 public function isPersistent() 1729 { 1730 return intval( $this->objectid ) > 0; 1731 } 1732 1733 1734 /** 1735 * Gets the file size 1736 * @return int 1737 */ 1738 public function getSize() 1739 { 1740 return 0; 1741 } 1742 1743 1744 public function mimeType() 1745 { 1746 return ""; 1747 } 1748 1749 1750 public function getId() 1751 { 1752 return $this->objectid; 1753 } 1754 1755 1756 public function copyNamesFrom($sourceObjectId ) { 1757 1758 $sourceObject = new BaseObject( $sourceObjectId ); 1759 foreach ( $sourceObject->getNames() as $name ) { 1760 1761 if ( $name->isPersistent() ) { 1762 1763 $copiedName = new Name(); 1764 $copiedName->name = $name->name; 1765 $copiedName->description = $name->description; 1766 $copiedName->languageid = $name->languageid; 1767 $copiedName->objectid = $this->objectid; 1768 $copiedName->persist(); 1769 } 1770 } 1771 } 1772 } 1773 1774 1775
Downloadmodules/cms/model/BaseObject.class.php
History Tue, 13 Oct 2026 00:41:49 +0200 Jan Dankert PHP8: Fixup old code: if there is no session entry, der return value should be null. Sun, 8 Dec 2024 20:56:47 +0100 Jan Dankert New: Users are now able to store bookmarks. Thu, 16 Feb 2023 22:57:35 +0100 Jan Dankert New: More functions (adding, deleting) for tags. Thu, 16 Feb 2023 01:04:38 +0100 Jan Dankert New: Tags for base objects. Tue, 14 Feb 2023 00:23:13 +0100 Jan Dankert New filters: Robots (for robots.txt) and Sitemap. Sun, 29 Jan 2023 00:20:21 +0100 Jan Dankert New node type "Script". Sat, 25 Jun 2022 14:26:33 +0200 Jan Dankert New: Many Enhancements for the internal script language: More access to the data structure of pages, folders, templates, ... Sun, 5 Jun 2022 22:14:24 +0200 Jan Dankert Some fixups: New Icons; better support classes for DSL. Fri, 15 Apr 2022 14:51:22 +0200 dankert Refactoring: User,Config and Database info is now stored in the Request, because so there is no session required for clients which are using Basic Authorization. Mon, 7 Feb 2022 21:44:42 +0100 dankert New: Authenticate API users with the HTTP authorization header. Mon, 6 Dec 2021 22:33:10 +0100 dankert Some fixes for deleting objects. Sun, 5 Dec 2021 22:09:08 +0100 dankert Fix: The Diff function was broken. Sun, 5 Dec 2021 20:33:24 +0100 dankert Cleanup: Removed unusable properties from class 'Value' and 'BaseObject'. Fri, 3 Dec 2021 23:27:44 +0100 dankert New: Only allowed methods are shown in the dropdown menu; Some security enhancements. Wed, 17 Nov 2021 23:39:22 +0100 Jan Dankert Fix: Reading descendent pages with the content id. Tue, 9 Nov 2021 01:21:55 +0100 Jan Dankert Fix: iconv is broken on alpine 3. Tue, 9 Mar 2021 09:17:27 +0100 Jan Dankert New: Show all links ('references') to the current object. Sun, 7 Mar 2021 00:10:20 +0100 Jan Dankert Refactoring: Hopefully more performance while accessing the database resultsets. Sat, 6 Mar 2021 02:50:20 +0100 Jan Dankert New: Enable actions for guest users. Sat, 6 Mar 2021 02:31:06 +0100 Jan Dankert Fix: Inheriting rights was missing. Sat, 6 Mar 2021 02:09:25 +0100 Jan Dankert New: Allow permissions for guests only. Mon, 4 Jan 2021 23:14:09 +0100 Jan Dankert New: Groups may contain subgroups. Users within a group inherit the permissions of all parent groups. Mon, 4 Jan 2021 19:03:18 +0100 Jan Dankert Refactoring: ACL class is renamed to Permission, because most RBAC/DMAC concepts are calling it a permission. Wed, 18 Nov 2020 01:46:36 +0100 Jan Dankert Refactoring of model classes: New method persist() and some other cleanups. Fri, 13 Nov 2020 00:12:44 +0100 Jan Dankert Fixing Pagelement-History and Diff. Sun, 1 Nov 2020 03:08:55 +0100 Jan Dankert Replaced the calls to "Configuration::rawConfig()" with the OO style calls; Cleanup LoginAction. Sun, 1 Nov 2020 00:36:50 +0100 Jan Dankert Refactoring: Only using the configuration object. Wed, 21 Oct 2020 23:32:47 +0200 Jan Dankert Load the objects before using attributes. Fri, 2 Oct 2020 23:11:48 +0200 Jan Dankert Cleanup: No '.inputholder' any more, notices with links to objects. Tue, 29 Sep 2020 22:17:11 +0200 Jan Dankert Refactoring: Do not use global constants. Sat, 26 Sep 2020 18:46:36 +0200 Jan Dankert Now compatible with PHP 5.4 again. Sat, 26 Sep 2020 12:20:43 +0200 Jan Dankert Refactoring: No global variables like $SESS any more. All constants are capsulated by classes. Sat, 26 Sep 2020 10:32:02 +0200 Jan Dankert Refactoring: No global $conf array any more. Sat, 26 Sep 2020 04:26:55 +0200 Jan Dankert Refactoring: read configuration values with a class. Sat, 26 Sep 2020 03:03:47 +0200 Jan Dankert Refactoring: less global functions. Sat, 26 Sep 2020 02:26:39 +0200 Jan Dankert Refactoring: No global functions any more, the database object is read from the Db class. Fri, 18 Sep 2020 23:04:13 +0200 Jan Dankert Refactoring: Renaming module "cms/publish" to "cms/generator" Sat, 29 Aug 2020 03:23:06 +0200 Jan Dankert Refactoring: Improved Exception-Handling; New: Generating pages using a page context which considers page aliases. Wed, 13 May 2020 23:29:44 +0200 Jan Dankert Refactoring: New Variable Resolver with support for namespaces, default values and nested value expressions. Sun, 23 Feb 2020 04:01:30 +0100 Jan Dankert Refactoring with Namespaces for the cms modules, part 1: moving.