openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

BaseObject.class.php (46055B)


      1 <?php
      2 
      3 
      4 namespace cms\model;
      5 
      6 use cms\base\Configuration;
      7 use cms\base\DB as Db;
      8 use cms\base\Startup;
      9 use cms\generator\Publisher;
     10 use util\ArrayUtils;
     11 use phpseclib\Math\BigInteger;
     12 use util\Request;
     13 use util\text\variables\VariableResolver;
     14 use util\YAML;
     15 
     16 /**
     17  * Base class for all objects in the content tree.
     18  *
     19  * @author Jan Dankert
     20  */
     21 class BaseObject extends ModelBase
     22 {
     23     const TYPEID_FOLDER = 1;
     24     const TYPEID_FILE   = 2;
     25     const TYPEID_PAGE   = 3;
     26     const TYPEID_LINK   = 4;
     27     const TYPEID_URL    = 5;
     28     const TYPEID_IMAGE  = 6;
     29     const TYPEID_TEXT   = 7;
     30     const TYPEID_ALIAS  = 8;
     31     const TYPEID_MACRO  = 9;
     32 
     33 
     34     /**
     35 	 * Unique ID of this base object.
     36 	 *
     37      * @type Integer
     38      */
     39     public $objectid;
     40 
     41     /**
     42 	 * Parent-Id.
     43 	 *
     44 	 * Object-Id of the folder, which this objects belongs to.
     45 	 *
     46      * Is 0 in case of the root folder.
     47 	 *
     48      * @see #isRoot()
     49      * @type Integer
     50      */
     51     public $parentid = null;
     52 
     53     /** Filename.
     54 	 *
     55 	 * Technical filename of this object without any extension. This name must be unique in a folder.
     56 	 *
     57      * @type String
     58      */
     59     public $filename = '';
     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 $isMacro = 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_MACRO  => 'macro' ,
    332 		];
    333 
    334 		return @$mapTypeIdToName[ $this->getTypeid() ] ?: 'unknown';
    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             '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->isMacro  = ( $row['typeid'] == self::TYPEID_MACRO  );
    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->isMacro  = ( $row['typeid'] == self::TYPEID_MACRO  );
    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     /**
    916      * Objekt hinzufuegen.
    917      *
    918      * Standardrechte und vom Elternobjekt vererbbare Berechtigungen werden gesetzt.
    919      */
    920     protected function add()
    921     {
    922         // Neue Objekt-Id bestimmen
    923         $sql = Db::sql(<<<'SQL'
    924 			SELECT MAX(id) FROM {{object}}
    925 SQL
    926 		);
    927         $this->objectid = intval($sql->getOne())+1;
    928 
    929         $this->checkFilename();
    930         $sql = Db::sql(<<<SQL
    931 			INSERT INTO {{object}}
    932                     (id,parentid,projectid,filename,orderid,create_date,create_userid,lastchange_date,lastchange_userid,typeid,settings)
    933             VALUES( {objectid},{parentid},{projectid},{filename},{orderid},{time},{createuserid},{createtime},{userid},{typeid},'' )
    934 SQL
    935 		);
    936 
    937 		$user = Request::getUser();
    938 		$currentUserId = $user ? $user->userid : 0;
    939 
    940 		if	( !$this->parentid )
    941             $sql->setNull('parentid');
    942         else
    943 			$sql->setInt ('parentid',$this->parentid );
    944 
    945         $sql->setInt   ('objectid' , $this->objectid );
    946         $sql->setString('filename' , $this->filename );
    947         $sql->setString('projectid', $this->projectid);
    948         $sql->setInt   ('orderid'  , 99999           );
    949         $sql->setInt   ('time'     , Startup::now()        );
    950 
    951         $sql->setInt   ('createuserid'   , $currentUserId  );
    952         $sql->setInt   ('createtime'     , Startup::now()  );
    953         $sql->setInt   ('userid'   , $currentUserId );
    954 
    955         $sql->setInt(  'typeid',$this->getTypeid());
    956 
    957         $sql->execute();
    958 
    959 		$this->grantToActualUser(); // Is this a good idea? don't know ...
    960 		$this->inheritPermissions();
    961     }
    962 
    963 
    964 	/**
    965 	 * Set permissions for the actual user for the just added object.
    966 	 *
    967 	 * @return void
    968 	 */
    969 	private function grantToActualUser() {
    970 
    971 		$user = Request::getUser();
    972 
    973 		if   ( $user ) {  // User logged in?
    974 
    975 			$permission = new Permission();
    976 			$permission->type = Permission::TYPE_USER;
    977 			$permission->userid = $user->userid;
    978 			$permission->objectid = $this->objectid;
    979 
    980 			$permission->read   = true;
    981 			$permission->write  = true;
    982 			$permission->prop   = true;
    983 			$permission->delete = true;
    984 			$permission->grant  = true;
    985 
    986 			$permission->create_file   = true;
    987 			$permission->create_page   = true;
    988 			$permission->create_folder = true;
    989 			$permission->create_link   = true;
    990 
    991 			$permission->persist();
    992 		}
    993 	}
    994 
    995 
    996 	/**
    997 	 * Inherit permissions from parent folder.
    998 	 *
    999 	 * @return void
   1000 	 */
   1001 	private function inheritPermissions() {
   1002 		$parent = new BaseObject( $this->parentid );
   1003 
   1004 		foreach( $parent->getAllAclIds() as $aclid )
   1005 		{
   1006 			$permission = new Permission( $aclid );
   1007 			$permission->load();
   1008 
   1009 			if	( $permission->transmit ) // ACL is vererbbar, also kopieren.
   1010 			{
   1011 				$permission->aclid = null;
   1012 				$permission->objectid = $this->objectid;
   1013 				$permission->persist(); // ... und hinzufuegen.
   1014 			}
   1015 		}
   1016 	}
   1017 
   1018     /**
   1019      * Pruefung auf Gueltigkeit des Dateinamens
   1020      */
   1021     private function checkFilename()
   1022     {
   1023         if	( empty($this->filename) )
   1024             $this->filename = $this->objectid;
   1025 
   1026         if	( $this->isRoot() )  // Beim Root-Ordner ist es egal, es gibt nur einen.
   1027             return;
   1028 
   1029         if	( !$this->filenameIsUnique( $this->filename ) )
   1030         {
   1031             // Append some string to filename.
   1032             $this->filename = $this->filename.'-'.base_convert(time(), 10, 36);
   1033         }
   1034     }
   1035 
   1036 
   1037     /**
   1038      * Stellt fest, dass der Dateiname im aktuellen Ordner kein weiteres Mal vorkommt.
   1039      * Dies muss vor dem Speichern geprüft werden, ansonsten erfolgt eine Index-Verletzung
   1040      * und der Datensatz kann nicht gespeichert werde.
   1041      *
   1042      * @param $filename
   1043      * @return bool
   1044      */
   1045     private function filenameIsUnique( $filename )
   1046     {
   1047         $sql = Db::sql( <<<SQL
   1048 SELECT COUNT(*) FROM {{object}}
   1049 WHERE parentid={parentid} AND filename={filename}
   1050 AND NOT id = {objectid}
   1051 SQL
   1052         );
   1053 
   1054         $sql->setString('parentid', $this->parentid);
   1055         $sql->setString('filename', $filename      );
   1056         $sql->setString('objectid', $this->objectid);
   1057 
   1058 
   1059         return( intval($sql->getOne()) == 0 );
   1060     }
   1061 
   1062 
   1063     function getAllAclIds()
   1064     {
   1065         $db = \cms\base\DB::get();
   1066 
   1067         $sql = $db->sql( <<<'SQL'
   1068 			SELECT id FROM {{acl}} 
   1069              WHERE objectid={objectid}
   1070              ORDER BY userid,groupid ASC
   1071 SQL
   1072  );
   1073         $sql->setInt('objectid'  ,$this->objectid);
   1074 
   1075         return $sql->getCol();
   1076     }
   1077 
   1078 
   1079     /**
   1080      * Ermitteln aller Berechtigungsstufen.
   1081      */
   1082     function getRelatedAclTypes()
   1083     {
   1084         return( array('read','write','delete','prop','release','publish','create_folder','create_file','create_page','create_link','grant','transmit') );
   1085     }
   1086 
   1087 
   1088     /**
   1089      * Ermitteln aller Berechtigungsstufen.
   1090      */
   1091     function getAssocRelatedAclTypes()
   1092     {
   1093         $types  = array();
   1094 
   1095         foreach( $this->getRelatedAclTypes() as $t )
   1096             $types[$t] = true;
   1097 
   1098         return $types;
   1099     }
   1100 
   1101     /**
   1102      * Entfernen aller ACLs zu diesem Objekt
   1103      * @access private
   1104      */
   1105     private function deleteAllACLs()
   1106     {
   1107         foreach( $this->getAllAclIds() as $aclid )
   1108         {
   1109             $permission = new Permission( $aclid );
   1110             $permission->load();
   1111             $permission->delete();
   1112         }
   1113     }
   1114 
   1115 
   1116 
   1117     /**
   1118      * Reihenfolge-Sequenznr. dieses Objektes neu speichern
   1119      * die Nr. wird sofort in der Datenbank gespeichert.
   1120      *
   1121      * @param Integer neue Sequenz-Nr.
   1122      */
   1123     public function setOrderId( $orderid )
   1124     {
   1125         $sql = Db::sql('UPDATE {{object}} '.'  SET orderid={orderid}'.'  WHERE id={objectid}');
   1126         $sql->setInt('objectid', $this->objectid);
   1127         $sql->setInt('orderid', $orderid);
   1128 
   1129         $sql->execute();
   1130     }
   1131 
   1132 
   1133 	/**
   1134 	 * Reads all direct children of this object.
   1135 	 */
   1136 	protected function getChildren()
   1137 	{
   1138 		$stmt = Db::sql(<<<SQL
   1139 
   1140 SELECT id FROM {{object}}
   1141 		                 WHERE parentid={objectid}
   1142 		                 ORDER BY orderid ASC
   1143 SQL
   1144 		);
   1145 
   1146 		$stmt->setInt( 'objectid' ,$this->objectid        );
   1147 
   1148 		return $stmt->getCol();
   1149 	}
   1150 
   1151 
   1152 	/**
   1153 	 * Reads all descendants.
   1154 	 *
   1155 	 */
   1156 	public function getAllDescendantsIds()
   1157 	{
   1158 		$descendantIds = array();
   1159 
   1160 		foreach( $this->getChildren() as $id )
   1161 		{
   1162 			$descendantIds[] = $id;
   1163 
   1164 			$baseObject = new BaseObject( $id );
   1165 			$descendantIds = array_merge( $descendantIds, $baseObject->getAllDescendantsIds() );
   1166 		}
   1167 
   1168 		return $descendantIds;
   1169 	}
   1170     /**
   1171      * ?bergeordnete Objekt-ID dieses Objektes neu speichern
   1172      * die Nr. wird sofort in der Datenbank gespeichert.
   1173      *
   1174      * @param Integer ?bergeordnete Objekt-ID
   1175      */
   1176     public function setParentId( $parentid )
   1177     {
   1178 
   1179 		$descendantsIds = $this->getAllDescendantsIds();
   1180 
   1181 		if	( in_array($parentid,$descendantsIds) || $parentid == $this->objectid )
   1182 			throw new \LogicException('new parent may not be a descendant of this node.');
   1183 
   1184         $db = \cms\base\DB::get();
   1185 
   1186         $sql = $db->sql('UPDATE {{object}} '.'  SET parentid={parentid}'.'  WHERE id={objectid}');
   1187         $sql->setInt('objectid', $this->objectid);
   1188         $sql->setInt('parentid', $parentid);
   1189 
   1190         $sql->execute();
   1191     }
   1192 
   1193 
   1194 	/**
   1195 	 * Get all References to this object
   1196 	 * @return array
   1197 	 */
   1198     public function getDependentObjectIds()
   1199     {
   1200         $stmt = DB::sql( <<<SQL
   1201 
   1202 SELECT {{page}}.objectid FROM {{value}}
   1203               LEFT JOIN {{pagecontent}}
   1204                 ON {{value}}.contentid = {{pagecontent}}.contentid
   1205               LEFT JOIN {{page}}
   1206                 ON {{pagecontent}}.pageid = {{page}}.id
   1207               WHERE linkobjectid={myobjectid1}
   1208 UNION
   1209        SELECT objectid FROM {{link}}
   1210              WHERE link_objectid={myobjectid2}
   1211 SQL
   1212 		);
   1213         $stmt->setInt( 'myobjectid1',$this->objectid );
   1214         $stmt->setInt( 'myobjectid2',$this->objectid );
   1215 
   1216         return $stmt->getCol();
   1217     }
   1218 
   1219 
   1220 
   1221 
   1222     /**
   1223      * Liefert die Link-Ids, die auf das aktuelle Objekt verweisen.
   1224      * @return array Liste der gefundenen Objekt-IDs
   1225 	 * @see BaseObject#getDependentObjectIds
   1226      */
   1227     public function getLinksToMe()
   1228     {
   1229         $db = \cms\base\DB::get();
   1230 
   1231         $sql = $db->sql( 'SELECT objectid FROM {{link}} '.
   1232             ' WHERE link_objectid={myid}' );
   1233         $sql->setInt   ( 'myid'   ,$this->objectid );
   1234 
   1235         return $sql->getCol();
   1236     }
   1237 
   1238     private function getTypeid()
   1239     {
   1240         if ($this->isFolder) return self::TYPEID_FOLDER;
   1241         if ($this->isFile  ) return self::TYPEID_FILE;
   1242         if ($this->isImage ) return self::TYPEID_IMAGE;
   1243         if ($this->isText  ) return self::TYPEID_TEXT;
   1244         if ($this->isPage  ) return self::TYPEID_PAGE;
   1245         if ($this->isLink  ) return self::TYPEID_LINK;
   1246         if ($this->isUrl   ) return self::TYPEID_URL;
   1247         if ($this->isAlias ) return self::TYPEID_ALIAS;
   1248         if ($this->isMacro ) return self::TYPEID_MACRO;
   1249     }
   1250 
   1251 
   1252     /**
   1253      * Local Settings.
   1254      *
   1255      * @return array
   1256      */
   1257     public function getSettings()
   1258     {
   1259         $settings = YAML::parse($this->settings);
   1260 
   1261         $resolver = new VariableResolver();
   1262         $resolver->namespaceSeparator = ':';
   1263 
   1264         // Resolve config variables.
   1265 		$resolver->addResolver('config', function ($var) {
   1266                 $conf = Configuration::Conf()->getConfig();
   1267                 return ArrayUtils::getSubValue($conf,explode('.',$var) );
   1268 		});
   1269 
   1270 		$settings = $resolver->resolveVariablesInArray( $settings );
   1271 
   1272         return $settings;
   1273     }
   1274 
   1275     /**
   1276      * Inherited Settings.
   1277      *
   1278      * @return array
   1279      */
   1280     public function getTotalSettings()
   1281     {
   1282         $totalSettings = array();
   1283 
   1284         // cumulate settings of parent objects
   1285         $parentIds = array_keys( $this->parentObjectFileNames(true, false) );
   1286         foreach( $parentIds as $id )
   1287         {
   1288             $parentObject = new BaseObject( $id );
   1289             $parentObject->objectLoad();
   1290             $totalSettings = array_merge($totalSettings,$parentObject->getSettings());
   1291         }
   1292 
   1293         // add settings from this base object.
   1294         $totalSettings = array_merge($totalSettings,$this->getSettings());
   1295 
   1296         return $totalSettings;
   1297     }
   1298 
   1299 
   1300 
   1301     /**
   1302      * Liefert alle übergeordneten Ordner.
   1303      *
   1304      * @param bool $with_root Mit Root-Folder?
   1305      * @param bool $with_self Mit dem aktuellen Ordner?
   1306      * @return array
   1307      */
   1308     public function parentObjectFileNames(  $with_root = false, $with_self = false  )
   1309     {
   1310         $foid = $this->objectid;
   1311         $idCache = array();
   1312 
   1313         while( intval($foid)!=0 )
   1314         {
   1315             $sql = Db::sql( <<<SQL
   1316             
   1317 SELECT parentid,id,filename
   1318   FROM {{object}}
   1319  WHERE {{object}}.id={parentid}
   1320 
   1321 SQL
   1322             );
   1323             $sql->setInt('parentid'  ,$foid            );
   1324 
   1325             $row = $sql->getRow();
   1326 
   1327             if	( in_array($row['id'],$idCache))
   1328                 throw new \LogicException('fatal: parent-rekursion in object-id: '.$this->objectid.', double-parent-id: '.$row['id']);
   1329             else
   1330                 $idCache[] = $row['id'];
   1331 
   1332             $this->addParentfolder( $row['id'],$row['filename'] );
   1333             $foid = $row['parentid'];
   1334         }
   1335 
   1336 
   1337         $this->checkParentFolders($with_root,$with_self);
   1338 
   1339         return $this->parentfolders;
   1340     }
   1341 
   1342     public function parentObjectNames( $with_root = false, $with_self = false )
   1343     {
   1344         $foid = $this->objectid;
   1345         $idCache = array();
   1346 
   1347         while( intval($foid)!=0 )
   1348         {
   1349             $sql = Db::sql( <<<SQL
   1350 				SELECT {{object}}.parentid,{{object}}.id,{{object}}.filename FROM {{object}}
   1351 				 WHERE {{object}}.id={parentid}
   1352 SQL
   1353             );
   1354             $sql->setInt('parentid'  ,$foid            );
   1355 
   1356             $row = $sql->getRow();
   1357 
   1358             if	( in_array($row['id'],$idCache))
   1359                 throw new \LogicException('fatal: parent-rekursion in object-id: '.$this->objectid.', double-parent-id: '.$row['id']);
   1360             else
   1361                 $idCache[] = $row['id'];
   1362 
   1363             $this->addParentfolder( $row['id'],$row['filename'] );
   1364             $foid = $row['parentid'];
   1365         }
   1366 
   1367         $this->checkParentFolders($with_root,$with_self);
   1368 
   1369         return $this->parentfolders;
   1370     }
   1371 
   1372 
   1373     private function addParentFolder( $id,$filename='' )
   1374     {
   1375         $name = $filename;
   1376 
   1377         if  ( empty($name) )
   1378             $name = "($id)";
   1379 
   1380         if	( intval($id) != 0 )
   1381             $this->parentfolders[ $id ] = $name;
   1382     }
   1383 
   1384 
   1385     private function checkParentFolders( $with_root, $with_self )
   1386     {
   1387         // Reihenfolge umdrehen
   1388         $this->parentfolders = array_reverse($this->parentfolders,true);
   1389 
   1390         // Ordner ist bereits hoechster Ordner
   1391 //		if   ( count($this->parentfolders) == 2 && $this->isRoot && $with_root && $with_self )
   1392 //		{
   1393 //			array_pop  ( $this->parentfolders );
   1394 //			return;
   1395 //		}
   1396 
   1397 
   1398         if   ( !$with_root && !empty($this->parentfolders) )
   1399         {
   1400             $keys = array_keys( $this->parentfolders );
   1401             unset( $this->parentfolders[$keys[0]] );
   1402         }
   1403 
   1404         if   ( !$with_self && !empty($this->parentfolders) )
   1405         {
   1406             $keys = array_keys( $this->parentfolders );
   1407             unset( $this->parentfolders[$keys[count($keys)-1]] );
   1408         }
   1409     }
   1410 
   1411 
   1412     /**
   1413      * Liefert das Projekt-Objekt.
   1414      *
   1415      * @return Project
   1416      * @throws \util\exception\ObjectNotFoundException
   1417      */
   1418     public function getProject() {
   1419         return Project::create( $this->projectid );
   1420     }
   1421 
   1422 
   1423 
   1424 
   1425     /**
   1426      * Es werden Objekte mit einem bestimmten Namen ermittelt
   1427      * @param String Suchbegriff
   1428      * @return array Liste der gefundenen Objekt-IDs
   1429      */
   1430     public static function getObjectIdsByFileName( $text )
   1431     {
   1432         $db = \cms\base\DB::get();
   1433 
   1434         $sql = $db->sql( 'SELECT id FROM {{object}} '.
   1435             ' WHERE filename LIKE {filename}'.
   1436             '  ORDER BY lastchange_date DESC' );
   1437         $sql->setString( 'filename','%'.$text.'%' );
   1438 
   1439         return $sql->getCol();
   1440     }
   1441 
   1442 
   1443     /**
   1444      * Es werden Objekte mit einem Namen ermittelt
   1445      * @param String Suchbegriff
   1446      * @return array Liste der gefundenen Objekt-IDs
   1447      */
   1448     public static function getObjectIdsByName( $text )
   1449     {
   1450         $db = \cms\base\DB::get();
   1451 
   1452         $sql = $db->sql( 'SELECT {{object}}.id FROM {{object}} '.
   1453             ' LEFT JOIN {{name}} '.
   1454             '   ON {{object}}.id={{name}}.objectid'.
   1455             ' WHERE {{name}}.name LIKE {name}'.
   1456             '  ORDER BY lastchange_date DESC' );
   1457         $sql->setString( 'name'      ,'%'.$text.'%' );
   1458 
   1459         return $sql->getCol();
   1460     }
   1461 
   1462 
   1463     /**
   1464      * Es werden Objekte mit einer Beschreibung ermittelt
   1465      * @param String Suchbegriff
   1466      * @return array Liste der gefundenen Objekt-IDs
   1467      */
   1468     public static function getObjectIdsByDescription( $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}}.descr LIKE {desc}'.
   1476             '  ORDER BY lastchange_date DESC' );
   1477         $sql->setString( 'desc'      ,'%'.$text.'%' );
   1478 
   1479         return $sql->getCol();
   1480     }
   1481 
   1482 
   1483     /**
   1484      * Es werden Objekte mit einer UserId ermittelt
   1485      * @param Integer Benutzer-Id der Erstellung
   1486      * @return array Liste der gefundenen Objekt-IDs
   1487      */
   1488     public static function getObjectIdsByCreateUserId( $userid )
   1489     {
   1490         $db = \cms\base\DB::get();
   1491 
   1492         $sql = $db->sql( 'SELECT id FROM {{object}} '.
   1493             ' WHERE create_userid={userid}'.
   1494             '  ORDER BY lastchange_date DESC' );
   1495         $sql->setInt   ( 'userid'   ,$userid          );
   1496 
   1497         return $sql->getCol();
   1498     }
   1499 
   1500 
   1501     /**
   1502      * Es werden Objekte mit einer UserId ermittelt
   1503      * @param Integer Benutzer-Id der letzten ?nderung
   1504      * @return array Liste der gefundenen Objekt-IDs
   1505      */
   1506     public static function getObjectIdsByLastChangeUserId( $userid )
   1507     {
   1508         $db = \cms\base\DB::get();
   1509 
   1510         $sql = $db->sql( 'SELECT id FROM {{object}} '.
   1511             ' WHERE lastchange_userid={userid}'.
   1512             '  ORDER BY lastchange_date DESC' );
   1513         $sql->setInt   ( 'userid'   ,$userid          );
   1514 
   1515         return $sql->getCol();
   1516     }
   1517 
   1518 
   1519     /**
   1520      * Stellt fest, ob das Objekt gueltig ist.
   1521      */
   1522     public function isValid()
   1523     {
   1524         $now = time();
   1525 
   1526         return
   1527             ($this->validFromDate == null || $this->validFromDate < $now) &&
   1528             ($this->validToDate   == null || $this->validToDate   > $now);
   1529 
   1530     }
   1531 
   1532     public function __toString()
   1533     {
   1534         return 'Object-Id '.$this->objectid.' (type='.$this->getType().',filename='.$this->filename. ')';
   1535     }
   1536 
   1537 
   1538     /**
   1539      * Liefert alle Name-Objekte.
   1540      * @return Name[]
   1541      * @throws \util\exception\ObjectNotFoundException
   1542      */
   1543     public function getNames()
   1544     {
   1545         $names = array();
   1546 
   1547         foreach( $this->getProject()->getLanguages() as $languageId=>$languageName )
   1548         {
   1549             $name = new Name();
   1550             $name->objectid   = $this->objectid;
   1551             $name->languageid = $languageId;
   1552             $name->load();
   1553 
   1554             $names[] = $name;
   1555         }
   1556 
   1557         return $names;
   1558     }
   1559 
   1560 
   1561     /**
   1562      * Liefert alle Name-Objekte.
   1563      * @return Name
   1564      * @throws \util\exception\ObjectNotFoundException
   1565      */
   1566     public function getNameForLanguage( $languageId )
   1567     {
   1568         $name = new Name();
   1569         $name->objectid   = $this->objectid;
   1570         $name->languageid = $languageId;
   1571         $name->load();
   1572 
   1573         return $name;
   1574     }
   1575 
   1576 
   1577     /**
   1578      * @return Name
   1579      */
   1580     public function getDefaultName()
   1581     {
   1582         $languageId = $this->getProject()->getDefaultLanguageId();
   1583 
   1584         $defaultName = $this->getNameForLanguage( $languageId );
   1585 
   1586 		if  ( ! $defaultName->name )
   1587 			$defaultName->name = $this->filename;
   1588 
   1589 		return $defaultName;
   1590     }
   1591 
   1592 
   1593     /**
   1594      * Name of the object. If not exist, the filename will be used.
   1595      * @return string Name
   1596      */
   1597     public function getName()
   1598     {
   1599         $name = $this->getDefaultName()->name;
   1600 
   1601         if  ( empty($name))
   1602             $name = $this->filename;
   1603 
   1604         return $name;
   1605     }
   1606 
   1607 
   1608     /**
   1609      * Speichert Namen und Beschreibung für alle Sprachen. Das ist bei der Neuanlage von Objekten ganz praktisch.
   1610      *
   1611      * @param $nam string
   1612      * @param $description string
   1613      */
   1614     public function setNameForAllLanguages($nam, $description)
   1615     {
   1616         foreach( $this->getProject()->getLanguages() as $languageId=>$languageName )
   1617         {
   1618             $name = new Name();
   1619             $name->objectid   = $this->objectid;
   1620             $name->languageid = $languageId;
   1621             $name->load();
   1622 
   1623             $name->name        = $nam;
   1624             $name->description = $description;
   1625 
   1626             $name->persist();
   1627         }
   1628 
   1629     }
   1630 
   1631 
   1632 	/**
   1633 	 * Returns the effective alias. If no alias exists, the actual object is returned.
   1634 	 *
   1635 	 * @return BaseObject
   1636 	 */
   1637     public function getEffectiveAlias() {
   1638 
   1639 		$alias = $this->getAlias();
   1640 		if   ( $alias )
   1641 			return $alias;
   1642 		else
   1643 			return $this;
   1644 	}
   1645 
   1646 
   1647 
   1648     /**
   1649      * The Alias for this Object or <code>null</code>.
   1650      *
   1651      * @return Alias|null
   1652 	 * @deprecated use #getAliasForLanguage
   1653      */
   1654     public function getAlias()
   1655     {
   1656         $alias = $this->getAliasForLanguage( $this->getProject()->getDefaultLanguageId() );
   1657 
   1658         if   ( !$alias->isPersistent() )
   1659             $alias = $this->getAliasForLanguage( null );
   1660 
   1661         if   ( !$alias->isPersistent() )
   1662             return null; // no alias found
   1663 
   1664         return $alias;
   1665     }
   1666 
   1667 
   1668     /**
   1669      * Creates an Alias for a specific language.
   1670      * @param int $languageid could be null for the default alias.
   1671      * @return Alias
   1672      * @throws \util\exception\ObjectNotFoundException
   1673      */
   1674     public function getAliasForLanguage( $languageid )
   1675     {
   1676         $alias = new Alias();
   1677         $alias->projectid      = $this->projectid;
   1678         $alias->linkedObjectId = $this->objectid;
   1679         $alias->languageid     = $languageid;
   1680         $alias->load();
   1681 
   1682         return $alias;
   1683     }
   1684 
   1685 
   1686 
   1687     public function isPersistent()
   1688     {
   1689         return intval( $this->objectid ) > 0;
   1690     }
   1691 
   1692 
   1693 	/**
   1694 	 * Gets the file size
   1695 	 * @return int
   1696 	 */
   1697 	public function getSize()
   1698 	{
   1699 		return 0;
   1700 	}
   1701 
   1702 
   1703 	public function mimeType()
   1704 	{
   1705 		return "";
   1706 	}
   1707 
   1708 
   1709 	public function getId()
   1710 	{
   1711 		return $this->objectid;
   1712 	}
   1713 
   1714 
   1715 	public function copyNamesFrom($sourceObjectId ) {
   1716 
   1717 		$sourceObject = new BaseObject( $sourceObjectId );
   1718 		foreach ( $sourceObject->getNames() as $name ) {
   1719 
   1720 			if   ( $name->isPersistent() ) {
   1721 
   1722 				$copiedName = new Name();
   1723 				$copiedName->name        = $name->name;
   1724 				$copiedName->description = $name->description;
   1725 				$copiedName->languageid  = $name->languageid;
   1726 				$copiedName->objectid    = $this->objectid;
   1727 				$copiedName->persist();
   1728 			}
   1729 		}
   1730 	}
   1731 }
   1732 
   1733 
   1734