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