openrat-cms

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

Project.class.php (29223B)


      1 <?php
      2 
      3 namespace cms\model;
      4 
      5 use cms\base\DB;
      6 use database\Database;
      7 use logger\Logger;
      8 use util\FileUtils;
      9 use util\Request;
     10 use util\Session;
     11 
     12 
     13 /**
     14  * Darstellen eines Projektes
     15  *
     16  * @author Jan Dankert
     17  * @package openrat.objects
     18  */
     19 class Project extends ModelBase
     20 {
     21 
     22     const FLAG_CUT_INDEX               = 1;
     23     const FLAG_CONTENT_NEGOTIATION     = 2;
     24     const FLAG_PUBLISH_FILE_EXTENSION  = 4;
     25     const FLAG_PUBLISH_PAGE_EXTENSION  = 8;
     26     const FLAG_LINK_ABSOLUTE           = 16;
     27 
     28     // Eigenschaften
     29 	public $projectid;
     30 	public $name;
     31 	public $target_dir;
     32 	public $ftp_url;
     33 
     34     /**
     35      * Hostname
     36      * @var string
     37      */
     38 	public $url;
     39 
     40 	public $ftp_passive;
     41 	public $cmd_after_publish;
     42 
     43 
     44     /**
     45      * @var boolean
     46      */
     47 	public $content_negotiation = false;
     48 
     49     /**
     50 	 * Should links to index pages contain the filename?
     51 	 *
     52      * @var boolean
     53      */
     54 	public $cut_index = false;
     55 
     56     /**
     57 	 * Link to files with extension
     58 	 *
     59      * @var boolean
     60      */
     61     public $publishFileExtension = true;
     62 
     63     /**
     64 	 * link to pages with extension
     65      * @var boolean
     66      */
     67     public $publishPageExtension = true;
     68 
     69 	public $linkAbsolute;
     70 
     71 
     72 	
     73 	// Konstruktor
     74 	public function  __construct( $projectid='' )
     75 	{
     76 		if   ( intval($projectid) != 0 )
     77 			$this->projectid = $projectid;
     78 	}
     79 
     80 
     81     private static $cache = array();
     82 
     83     /**
     84      * @param $projectid
     85      * @return Project
     86      * @throws \util\exception\ObjectNotFoundException
     87      */
     88     public static function create($projectid)
     89     {
     90         if   ( empty( Project::$cache[ $projectid ] ) )
     91         {
     92             $project = new Project( $projectid );
     93 
     94             Project::$cache[ $projectid ] = $project->load();
     95         }
     96         return Project::$cache[ $projectid ];
     97     }
     98 
     99 
    100     /**
    101 	 * Stellt fest, ob die angegebene Projekt-Id existiert.
    102      * @param $id int Projekt-Id
    103      * @return boolean
    104      *
    105 	 */
    106 	public function isAvailable($id )
    107 	{
    108 		$db = \cms\base\DB::get();
    109 
    110 		$sql = $db->sql('SELECT 1 FROM {{project}} '.
    111 		               ' WHERE id={id}');
    112 		$sql->setInt('id' ,$id  );
    113 
    114 		return intval($sql->getOne()) == 1;
    115 	}
    116 	
    117 
    118     /**
    119      * Liefert alle verf?gbaren Projekte.
    120      * @return array
    121      */
    122     public static function getAllProjects()
    123 	{
    124 		$db = \cms\base\DB::get();
    125 		$sql = $db->sql( 'SELECT id,name FROM {{project}} '.
    126 		                '   ORDER BY name' );
    127 
    128 		return $sql->getAssoc();
    129 	}
    130 
    131 
    132     // Liefert alle verf?gbaren Projekt-Ids
    133     public function getAllProjectIds()
    134 	{
    135 		$db = \cms\base\DB::get();
    136 		$sql = $db->sql( 'SELECT id FROM {{project}} '.
    137 		                '   ORDER BY name' );
    138 
    139 		return $sql->getCol();
    140 	}
    141 
    142 
    143     /**
    144      * Liefert die Sprachen des Projektes.
    145      *
    146      * @return array Id->Name
    147      */
    148     public function getLanguages()
    149 	{
    150 		$db = \cms\base\DB::get();
    151 
    152 		$sql = $db->sql( 'SELECT id,name FROM {{language}}'.
    153 		                '  WHERE projectid={projectid} '.
    154 		                '  ORDER BY name' );
    155 		$sql->setInt   ('projectid',$this->projectid);
    156 
    157 		return $sql->getAssoc();
    158 	}
    159 
    160 
    161 	/**
    162 	 * @return int[]
    163 	 */
    164 	public function getLanguageIds()
    165 	{
    166 		return array_keys( $this->getLanguages() );
    167 	}
    168 
    169 
    170     /**
    171      * Liefert die Projektmodelle als Array mit ID->Name.
    172      *
    173      * @return array
    174      */
    175 	public function getModels()
    176 	{
    177 		$db = \cms\base\DB::get();
    178 
    179 		$sql = $db->sql( 'SELECT id,name FROM {{projectmodel}}'.
    180 		                '  WHERE projectid= {projectid} '.
    181 		                '  ORDER BY name' );
    182 		$sql->setInt   ('projectid',$this->projectid);
    183 
    184 		return $sql->getAssoc();
    185 	}
    186 
    187 
    188 	public function getModelIds()
    189 	{
    190 		return array_keys( $this->getModels() );
    191 	}
    192 
    193 
    194     public function  getTemplateIds()
    195 	{
    196 		$db = \cms\base\DB::get();
    197 
    198 		$sql = $db->sql( 'SELECT id FROM {{template}}'.
    199 		                '  WHERE projectid= {projectid} ' );
    200 		$sql->setInt   ('projectid',$this->projectid);
    201 
    202 		return $sql->getCol();
    203 	}
    204 
    205 
    206     public function  getTemplates()
    207 	{
    208 		$sql = Db::sql( 'SELECT id,name FROM {{template}}'.
    209 		                '  WHERE projectid= {projectid} ' );
    210 		$sql->setInt   ('projectid',$this->projectid);
    211 
    212 		return $sql->getAssoc();
    213 	}
    214 
    215 
    216 	/**
    217 	 * Ermitteln des Wurzel-Ordners fuer dieses Projekt.
    218 	 * 
    219 	 * Der Wurzelordner ist der einzige Ordnerhat in diesem
    220 	 * Projekt, der kein Elternelement besitzt.
    221 	 * 
    222 	 * @return Objekt-Id des Wurzelordners
    223 	 */
    224     public function  getRootObjectId()
    225 	{
    226 		$db = \cms\base\DB::get();
    227 		
    228 		$sql = $db->sql('SELECT id FROM {{object}}'.
    229 		               '  WHERE parentid IS NULL'.
    230 		               '    AND projectid={projectid}' );
    231 
    232 		$sql->setInt('projectid',$this->projectid);
    233 		
    234 		return( $sql->getOne() );
    235 	}
    236 
    237 	
    238 
    239 	// Laden
    240 
    241     /**
    242      * @throws \util\exception\ObjectNotFoundException
    243      */
    244     public function load()
    245 	{
    246 		$sql = Db::sql( 'SELECT * FROM {{project}} '.
    247 		                '   WHERE id={projectid}' );
    248 		$sql->setInt( 'projectid',$this->projectid );
    249 
    250 		$row = $sql->getRow();
    251 
    252 		if	( empty($row) )
    253 			throw new \util\exception\ObjectNotFoundException('project '.$this->projectid.' not found');
    254 			
    255 		$this->name                = $row['name'               ];
    256 		$this->url                 = $row['url'                ];
    257 		$this->target_dir          = $row['target_dir'         ];
    258 		$this->ftp_url             = $row['ftp_url'            ];
    259 		$this->ftp_passive         = $row['ftp_passive'        ];
    260 		$this->cmd_after_publish   = $row['cmd_after_publish'  ];
    261         $this->cut_index           = $row['flags']&self::FLAG_CUT_INDEX;
    262         $this->content_negotiation = $row['flags']&self::FLAG_CONTENT_NEGOTIATION;
    263         $this->publishFileExtension = $row['flags']&self::FLAG_PUBLISH_FILE_EXTENSION;
    264         $this->publishPageExtension = $row['flags']&self::FLAG_PUBLISH_PAGE_EXTENSION;
    265         $this->linkAbsolute         = $row['flags']&self::FLAG_LINK_ABSOLUTE;
    266 
    267         return $this;
    268 	}
    269 
    270 
    271 
    272 	// Speichern
    273 	public function save()
    274 	{
    275 		$stmt = DB::sql( <<<SQL
    276 				UPDATE {{project}}
    277                   SET name                = {name},
    278                       target_dir          = {target_dir},
    279                       ftp_url             = {ftp_url}, 
    280                       ftp_passive         = {ftp_passive}, 
    281                       url                 = {url}, 
    282                       flags               = {flags}, 
    283                       cmd_after_publish   = {cmd_after_publish} 
    284                 WHERE id= {projectid}
    285 SQL
    286 );
    287 
    288 		$stmt->setString('ftp_url'            ,$this->ftp_url );
    289 		$stmt->setString('url'                ,$this->url );
    290 		$stmt->setString('name'               ,$this->name );
    291 		$stmt->setString('target_dir'         ,$this->target_dir );
    292 		$stmt->setInt   ('ftp_passive'        ,$this->ftp_passive );
    293 		$stmt->setString('cmd_after_publish'  ,$this->cmd_after_publish );
    294 
    295         $flags = 0;
    296         if( $this->cut_index           ) $flags |= self::FLAG_CUT_INDEX;
    297         if( $this->content_negotiation ) $flags |= self::FLAG_CONTENT_NEGOTIATION;
    298         if( $this->publishFileExtension) $flags |= self::FLAG_PUBLISH_FILE_EXTENSION;
    299         if( $this->publishPageExtension) $flags |= self::FLAG_PUBLISH_PAGE_EXTENSION;
    300         if( $this->linkAbsolute        ) $flags |= self::FLAG_LINK_ABSOLUTE;
    301 
    302         $stmt->setInt   ('flags'              ,$flags );
    303 		$stmt->setInt   ('projectid'          ,$this->projectid );
    304 
    305 		$stmt->execute();
    306 
    307 		try
    308 		{
    309 			$rootFolder = new Folder( $this->getRootObjectId() );
    310 			$rootFolder->load();
    311 			$rootFolder->filename = $this->name;
    312 			$rootFolder->save();
    313 		}
    314 		catch( \Exception $e )
    315 		{
    316 			Logger::warn('Project '.$this->projectid.' has not a root folder'."\n".$e->getTraceAsString());
    317 		}
    318 	}
    319 
    320 
    321 	/**
    322      * Liefert alle Eigenschaften des Projektes.
    323 	*/
    324 	public function getProperties()
    325 	{
    326 		return parent::getProperties();
    327 	}
    328 
    329 
    330     /**
    331      * Add a project to the database.
    332      */
    333     public function add()
    334 	{
    335 		$db = \cms\base\DB::get();
    336 
    337 		$sql = $db->sql('SELECT MAX(id) FROM {{project}}');
    338 		$this->projectid = intval($sql->getOne())+1;
    339 
    340 
    341 		// Projekt hinzuf?gen
    342 		$sql = $db->sql( 'INSERT INTO {{project}} (id,name,target_dir,ftp_url,ftp_passive,cmd_after_publish,flags) '.
    343 		                "  VALUES( {projectid},{name},'','',0,'',0 ) " );
    344 		$sql->setInt   ('projectid',$this->projectid );
    345 		$sql->setString('name'     ,$this->name      );
    346 
    347 		$sql->execute();
    348 
    349 		// Every projects needs a root folder. The root folder has no parent.
    350 		$folder = new Folder();
    351 		$folder->projectid  = $this->projectid;
    352 		$folder->filename   = $this->name;
    353 		$folder->persist();
    354 	}
    355 
    356 
    357 	// Projekt aus Datenbank entfernen
    358 	public function delete()
    359 	{
    360 		$db = \cms\base\DB::get();
    361 
    362 		// Root-Ordner rekursiv samt Inhalten loeschen
    363 		$folder = new Folder( $this->getRootObjectId() );
    364 		$folder->deleteAll();
    365 
    366 
    367 		foreach( $this->getLanguageIds() as $languageid )
    368 		{
    369 			$language = new Language( $languageid );
    370 			$language->delete();
    371 		}
    372 		
    373 
    374 		foreach( $this->getTemplateIds() as $templateid )
    375 		{
    376 			$template = new Template( $templateid );
    377 			$template->delete();
    378 		}
    379 		
    380 
    381 		foreach( $this->getModelIds() as $modelid )
    382 		{
    383 			$model = new Model( $modelid );
    384 			$model->delete();
    385 		}
    386 		
    387 
    388 		// Deleting the project
    389 		$sql = $db->sql( 'DELETE FROM {{project}}'.
    390 		                '  WHERE id= {projectid} ' );
    391 		$sql->setInt( 'projectid',$this->projectid );
    392 		$sql->execute();
    393 	}
    394 
    395 
    396     /**
    397      * Liefert die Standard-Sprach-Id. If there is no default language, the first language-id will be used.
    398      * @return String
    399      */
    400 	public function getDefaultLanguageId()
    401 	{
    402 		// ORDER BY deswegen, damit immer mind. eine Sprache
    403 		// gelesen wird
    404 		$sql = \cms\base\Db::sql( 'SELECT id FROM {{language}} '.
    405 		                '  WHERE projectid={projectid}'.
    406 		                '   ORDER BY is_default DESC, name ASC' );
    407 
    408 		$sql->setInt('projectid',$this->projectid );
    409 		
    410 		return $sql->getOne();
    411 	}
    412 
    413 
    414 	public function getDefaultModelId()
    415 	{
    416 		// ORDER BY deswegen, damit immer mind. eine Sprache
    417 		// gelesen wird
    418 		$sql = \cms\base\Db::sql( 'SELECT id FROM {{projectmodel}} '.
    419 		                '  WHERE projectid={projectid}'.
    420 		                '   ORDER BY is_default DESC' );
    421 		$sql->setInt('projectid',$this->projectid );
    422 		
    423 		return $sql->getOne();
    424 	}
    425 
    426 	
    427 	
    428 	/**
    429 	 * Entfernt nicht mehr notwendige Inhalte aus dem Archiv.
    430 	 */
    431 	public function checkLimit()
    432 	{
    433 		// not necessary any more.
    434 		// this is done while saving a value!
    435 	}
    436 
    437 	
    438 
    439 	/**
    440 	 * Testet die Integrität der Datenbank.
    441 	 *
    442 	 * @return array activities (empty if nothing bad found)
    443 	 */
    444 	public function checkLostFiles()
    445 	{
    446 		$log = array();
    447 		
    448 		// Ordnerstruktur prüfen.
    449 		$stmt = \cms\base\Db::sql( <<<EOF
    450 SELECT thistab.id FROM {{object}} AS thistab
    451  LEFT JOIN {{object}} AS parenttab
    452         ON parenttab.id = thistab.parentid
    453   WHERE thistab.projectid={projectid} AND thistab.parentid IS NOT NULL AND parenttab.id IS NULL
    454 EOF
    455 );
    456 		$stmt->setInt('projectid',$this->projectid);
    457 
    458 		$idList = $stmt->getCol();
    459 		
    460 		if	( count( $idList ) > 0 )
    461 		{
    462 			$lostAndFoundFolder = new Folder();
    463 			$lostAndFoundFolder->projectid = $this->projectid;
    464 			$lostAndFoundFolder->filename = "lostandfound";
    465 			$lostAndFoundFolder->parentid = $this->getRootObjectId();
    466 			$lostAndFoundFolder->persist();
    467 			
    468 			foreach( $idList as $id )
    469 			{
    470 				$log[] = 'Lost file! Moving '.$id.' to lost+found.';
    471 				$obj = new BaseObject( $id );
    472 				$obj->setParentId( $lostAndFoundFolder->objectid );
    473 			}
    474 		}
    475 
    476 		
    477 		// Prüfe, ob die Verbindung Projekt->Template->Templatemodell->Projectmodell->Projekt konsistent ist. 
    478 		$stmt = \cms\base\Db::sql( <<<EOF
    479 SELECT DISTINCT projectid FROM {{projectmodel}} WHERE id IN (SELECT projectmodelid from {{templatemodel}} WHERE templateid in (SELECT id from {{template}} WHERE projectid={projectid}))
    480 EOF
    481 );
    482 		$stmt->setInt('projectid',$this->projectid);
    483 
    484 		$idList = $stmt->getCol();
    485 		
    486 		if	( count( $idList ) > 1 )
    487 		{
    488 			Logger::warn('Inconsistence found: Reference circle project<->template<->templatemodel<->projectmodel<->project is not consistent.');
    489 			$log[] = 'Inconsistence found: Reference circle project<->template<->templatemodel<->projectmodel<->project is not consistent.';
    490 		}
    491 
    492 		return $log;
    493 	}
    494 
    495 
    496 
    497     /**
    498      * Kopiert ein Projekt von einer Datenbank zu einer anderen.<br>
    499      * <br>
    500      * Alle Projektinhalte werden kopiert, die Fremdschluesselbeziehungen werden entsprechend angepasst.<br>
    501      * <br>
    502      * Alle Beziehungen zu Benutzern, z.B. "Zuletzt geaendert von", "angelegt von" sowie<br>
    503      * alle Berechtigungsinformationen gehen verloren!<br>
    504      *
    505      * @param string $dbid_destination ID der Ziel-Datenbank
    506      * @param string $name
    507      */
    508 	public function copy( $dbid_destination,$name='' )
    509 	{
    510 		Logger::debug( 'Copying project '.$this->name.' to database '.$dbid_destination );
    511 		
    512 		$conf = \cms\base\Configuration::rawConfig();
    513 		$zeit = date('Y-m-d\TH:i:sO');
    514 		
    515 		$db_src  = \cms\base\DB::get();
    516 		$db_dest = new Database( $conf['database'][$dbid_destination] );
    517 		$db_dest->id = $dbid_destination;
    518 		$db_dest->start();
    519 		
    520 		$sameDB = ( $db_dest->id == $db_src->id );
    521 		
    522 		// -------------------------------------------------------
    523 		$mapping = array();
    524 		$ids = array('project'      => array('foreign_keys'=>array(),
    525 		                                     'primary_key' =>'id',
    526 		                                     'unique_idx'  =>'name',
    527 		                                     'erase'       =>array()
    528 		                                    ),
    529 		             'language'     => array('foreign_keys'=>array('projectid'=>'project'),
    530 		                                     'primary_key' =>'id'
    531 		                                    ),
    532 		             'projectmodel' => array('foreign_keys'=>array('projectid'=>'project'),
    533 		                                     'primary_key' =>'id'
    534 		                                    ),
    535 		             'template'     => array('foreign_keys'=>array('projectid'=>'project'),
    536 		                                     'primary_key' =>'id'
    537 		                                     ),
    538 		             'object'       => array('foreign_keys'=>array('projectid'  =>'project' ),
    539 		                                     'self_key'    =>'parentid',
    540 		                                     'primary_key' =>'id',
    541 		                                     'erase'       =>array('create_userid','lastchange_userid')
    542 		                                     ),
    543 		             'element'      => array('foreign_keys'=>array('templateid'      =>'template',
    544 			                                                       'folderobjectid'  =>'object',
    545 		                                                           'default_objectid'=>'object'   ),
    546 		                                     'primary_key' =>'id'
    547 		                                     ),
    548 		             'templatemodel'=> array('foreign_keys'=>array('projectmodelid'=>'projectmodel',
    549 		                                                           'templateid'    =>'template'     ),
    550 		                                     'primary_key' =>'id',
    551 		                                     'replace'     =>array('text'=>'element')
    552 		                                     ),
    553 		             'name'         => array('foreign_keys'=>array('objectid'  =>'object',
    554 		                                                           'languageid'=>'language'   ),
    555 		                                     'primary_key' =>'id'
    556 		                                     ),
    557 		             'page'         => array('foreign_keys'=>array('objectid'  =>'object',
    558 		                                                           'templateid'=>'template' ),
    559 		                                     'primary_key' =>'id'
    560 		                                     ),
    561 		             'value'         => array('foreign_keys'=>array('pageid'   =>'page',
    562 		                                                           'languageid'=>'language',
    563 		                                                           'elementid'=>'element',
    564 		                                                           'linkobjectid'=>'object'  ),
    565 		                                     'erase'       =>array('lastchange_userid'),
    566 		                                     'replace'     =>array('text'=>'object'),
    567 		                                     'primary_key' =>'id'
    568 		                                     ),
    569 		             'link'         => array('foreign_keys'=>array('objectid'     =>'object',
    570 		                                                           'link_objectid'=>'object'   ),
    571 		                                     'primary_key' =>'id'
    572 		                                     ),
    573 		             'folder'         => array('foreign_keys'=>array('objectid'  =>'object' ),
    574 		                                     'primary_key' =>'id'
    575 		                                     ),
    576 		             'file'         => array('foreign_keys'=>array('objectid'  =>'object'   ),
    577 		                                     'primary_key' =>'id',
    578 		                                     'binary'      =>'value'
    579 		                                     ),
    580 		             
    581 		);
    582 		
    583 		if	( $sameDB )
    584 			$ids['acl'] = array('foreign_keys'=>array('objectid'   => 'object',
    585 		                                              'languageid' => 'language' ),
    586 		                        'primary_key' =>'id'
    587 		                        );
    588 			 
    589 		foreach( $ids as $tabelle=>$data )
    590 		{
    591 			Logger::debug( 'Copying table '.$tabelle.' ...' );
    592 			$mapping[$tabelle] = array();
    593 			$idcolumn = $data['primary_key'];
    594 
    595 			// Naechste freie Id in der Zieltabelle ermitteln.
    596 			$stmt = $db_dest->sql( 'SELECT MAX('.$idcolumn.') FROM {t_'.$tabelle.'}');
    597 			$maxid = intval($stmt->getOne());
    598 			$nextid = $maxid;
    599 
    600 			// Zu �bertragende IDs ermitteln.
    601 			if	( count($data['foreign_keys'])==0 )
    602 			{
    603 				$where = ' WHERE id='.$this->projectid;
    604 			}
    605 			else
    606 			{
    607 				foreach( $data['foreign_keys'] as $fkey_column=>$target_tabelle )
    608 				{
    609 					$where = ' WHERE '.$fkey_column.' IN ('.join(array_keys($mapping[$target_tabelle]),',').')';
    610 					break;
    611 				}
    612 			}
    613 			$stmt = $db_src->sql( 'SELECT '.$idcolumn.' FROM {t_'.$tabelle.'} '.$where);
    614 
    615 			foreach( $stmt->getCol() as $srcid )
    616 			{
    617 				Logger::debug('Id '.$srcid.' of table '.$tabelle);
    618 				$mapping[$tabelle][$srcid] = ++$nextid;
    619 
    620 				$stmt = $db_src->sql( 'SELECT * FROM {t_'.$tabelle.'} WHERE id={id}');
    621 				$stmt->setInt('id',$srcid);
    622 				$row = $stmt->getRow();
    623 
    624 				// Wert des Prim�rschl�ssels �ndern.
    625 				$row[$idcolumn] = $mapping[$tabelle][$srcid];
    626 
    627 				// Fremdschl�sselbeziehungen auf neue IDn korrigieren.
    628 				foreach( $data['foreign_keys'] as $fkey_column=>$target_tabelle)
    629 				{
    630 					Logger::debug($fkey_column.' '.$target_tabelle.' '.$row[$fkey_column]);
    631 					
    632 					if	( intval($row[$fkey_column]) != 0 )
    633 						$row[$fkey_column] = $mapping[$target_tabelle][$row[$fkey_column]];
    634 				}
    635 				
    636 				foreach( array_keys($row) as $key )
    637 				{
    638 					if	( isset($data['unique_idx']) && $key == $data['unique_idx'] )
    639 					{
    640 						// Nachschauen, ob es einen UNIQUE-Key in der Zieltabelle schon gibt.
    641 						$stmt = $db_dest->sql( 'SELECT 1 FROM {t_'.$tabelle.'} WHERE '.$key."='".$row[$key]."'");
    642 						
    643 						if	( intval($stmt->getOne()) == 1 )
    644 							$row[$key] = $row[$key].$zeit;
    645 
    646 					}
    647 
    648 					if	( !$sameDB && isset($data['erase']) && in_array($key,$data['erase']) )
    649 						$row[$key] = null;
    650 
    651 					if	( isset($data['self_key']) && $key == $data['self_key'] && intval($row[$key]) > 0 )
    652 						$row[$key] = $row[$key]+$maxid;
    653 				}
    654 				
    655 				if	( isset($data['replace']) )
    656 				{
    657 					foreach( $data['replace'] as $repl_column=>$repl_tabelle)
    658 						foreach( $mapping[$repl_tabelle] as $oldid=>$newid)
    659 						{
    660 							$row[$repl_column] = str_replace('{'.$oldid.'}','{'.$newid.'}'  ,$row[$repl_column]);
    661 							$row[$repl_column] = str_replace('"'.$oldid.'"','"'.$newid.'"'  ,$row[$repl_column]);
    662 							$row[$repl_column] = str_replace('->'.$oldid   ,'->"'.$newid.'"',$row[$repl_column]);
    663 						}
    664 				}
    665 				
    666 				if	( isset($data['binary']) )
    667 				{
    668 					if	( !$db_src->conf['base64'] && $db_dest->conf['base64'] )
    669 						$row[$data['binary']] = base64_encode($row[$data['binary']]);
    670 					elseif	( $db_src->conf['base64'] && !$db_dest->conf['base64'] )
    671 						$row[$data['binary']] = base64_decode($row[$data['binary']]);
    672 				}
    673 				
    674 				// Daten in Zieltabelle einf�gen.
    675 				$stmt = $db_dest->sql( 'INSERT INTO {t_'.$tabelle.'} ('.join(array_keys($row),',').') VALUES({'.join(array_keys($row),'},{').'})',$dbid_destination);
    676 				foreach( $row as $key=>$value )
    677 				{
    678 					if	( !$sameDB && isset($data['erase']) && in_array($key,$data['erase']) )
    679 						$stmt->setNull($key);
    680 					else
    681                     {
    682                         if(is_bool($value))
    683                             $stmt->setBoolean($key,$value);
    684                         elseif(is_int($value))
    685                             $stmt->setInt($key,$value);
    686                         elseif(is_string($value))
    687                             $stmt->setString($key,$value);
    688                     }
    689 				}
    690 				//$sql = $db->sql( 'INSERT INTO {t_'.$tabelle.'} ('.join(array_keys($row),',').') VALUES('.join($row,',').')',$dbid_destination);
    691                 $stmt->execute();
    692 			}
    693 
    694 			if	( isset($data['self_key']) )
    695 			{
    696 				foreach( $mapping[$tabelle] as $oldid=>$newid )
    697 				{
    698 					$stmt = $db_dest->sql( 'UPDATE {t_'.$tabelle.'} SET '.$data['self_key'].'='.$newid.' WHERE '.$data['self_key'].'='.($oldid+$maxid),$dbid_destination );
    699 					$stmt->execute();
    700 				}
    701 			}
    702 		}
    703 		
    704 		Logger::debug( 'Finished copying project' );
    705 		
    706 		$db_dest->commit();
    707 	}
    708 
    709 	
    710 
    711 	/**
    712 	 * Ermittelt die Anzahl aller Objekte in diesem Projekt.
    713 	 * @return int Anzahl
    714 	 */
    715 	public function countObjects()
    716 	{
    717 		$db = \cms\base\DB::get();
    718 		$sql = $db->sql( 'SELECT COUNT(*) FROM {{object}} '.
    719 		                '   WHERE projectid = {projectid}' );
    720 		$sql->setInt( 'projectid', $this->projectid );
    721 
    722 		return $sql->getOne();
    723 		
    724 	}
    725 
    726 	
    727 	
    728 	/**
    729 	 * Ermittelt die Gr��e aller Dateien in diesem Projekt.
    730 	 * @return int Summe aller Dateigroessen
    731 	 */
    732 	public function size()
    733 	{
    734 		$db = \cms\base\DB::get();
    735 		
    736 		$sql = $db->sql( <<<SQL
    737 		SELECT SUM(size) FROM {{file}}
    738 		  LEFT JOIN {{object}}
    739 		         ON {{file}}.objectid = {{object}}.id
    740 		      WHERE projectid = {projectid}
    741 SQL
    742 );
    743 		$sql->setInt( 'projectid', $this->projectid );
    744 
    745 		return $sql->getOne();
    746 	}
    747 	
    748 	
    749 	
    750 	/**
    751 	 * Liefert alle verf?gbaren Projekt-Ids
    752 	 */
    753 	public function info()
    754 	{
    755 		$info = array();
    756 		
    757 		$info['count_objects'] = $this->countObjects();
    758 		$info['sum_filesize' ] = $this->size();
    759 		
    760 		
    761 		return $info;
    762 	}
    763 	
    764 	
    765 	
    766 
    767 	/**
    768 	 * Ermittelt projektübergreifend die letzten Änderungen des angemeldeten Benutzers.
    769 	 *  
    770 	 * @return array <string, unknown>
    771 	 */
    772 	public function getMyLastChanges()
    773 	{
    774 		
    775 		$db = \cms\base\DB::get();
    776 
    777 
    778 		$sql = $db->sql( <<<SQL
    779 		SELECT {{object}}.id    as objectid,
    780 		       {{object}}.filename as filename,
    781 		       {{object}}.typeid as typeid,
    782 		       {{object}}.lastchange_date as lastchange_date,			
    783 		       {{name}}.name as name				
    784 		  FROM {{object}}
    785 		  LEFT JOIN {{name}}
    786 		         ON {{name}}.objectid = {{object}}.id
    787 				AND {{name}}.languageid = {languageid}
    788 		  LEFT JOIN {{project}}
    789 		         ON {{object}}.projectid = {{project}}.id
    790 			  WHERE {{object}}.projectid         = {projectid}
    791 				AND {{object}}.lastchange_userid = {userid}
    792 		   ORDER BY {{object}}.lastchange_date DESC;
    793 SQL
    794 		);
    795 		
    796 		// Variablen setzen.
    797 		$sql->setInt( 'projectid', $this->projectid );
    798 		
    799 		$sql->setInt( 'languageid', 0 );
    800 		
    801 		$user = Request::getUser();
    802 		$sql->setInt( 'userid', $user->userid );
    803 		
    804 		return $sql->getAll();
    805 	}
    806 	
    807 
    808 	/**
    809 	 * Ermittelt projektübergreifend die letzten Änderungen.
    810 	 *  
    811 	 * @return array
    812 	 */
    813 	public static function getAllLastChanges()
    814 	{
    815 		$db = \cms\base\DB::get();
    816 
    817 		$sql = $db->sql( <<<SQL
    818 		SELECT {{object}}.id    as objectid,
    819 		       {{object}}.lastchange_date as lastchange_date,
    820 		       {{object}}.filename as filename,
    821 		       {{project}}.id   as projectid,
    822 			   {{project}}.name as projectname,
    823 		       {{user}}.name       as username,
    824 		       {{user}}.id         as userid,
    825 		       {{user}}.mail       as usermail,
    826 		       {{user}}.fullname   as userfullname
    827 		  FROM {{object}}
    828 		  LEFT JOIN {{project}}
    829 		         ON {{object}}.projectid = {{project}}.id
    830 		  LEFT JOIN {{user}}
    831 		         ON {{user}}.id = {{object}}.lastchange_userid
    832 		  ORDER BY {{object}}.lastchange_date DESC
    833 		  LIMIT 50
    834 SQL
    835 		);
    836 		
    837 		return $sql->getAll();
    838 	}
    839 	
    840 
    841 
    842 	/**
    843 	 * Ermittelt die letzten Änderung im Projekt.
    844 	 * @return array
    845 	 */
    846 	public function  getLastChanges()
    847 	{
    848 		
    849 		$db = \cms\base\DB::get();
    850 		
    851 		$sql = $db->sql( <<<SQL
    852 		SELECT {{object}}.id       as objectid,
    853 		       {{object}}.lastchange_date as lastchange_date,
    854 		       {{object}}.filename as filename,
    855 		       {{object}}.typeid   as typeid,
    856 		       {{name}}.name       as name,
    857 		       {{user}}.name       as username,
    858 		       {{user}}.id         as userid,
    859 		       {{user}}.mail       as usermail,
    860 		       {{user}}.fullname   as userfullname
    861 		  FROM {{object}}
    862 		  LEFT JOIN {{name}}
    863 		         ON {{name}}.objectid = {{object}}.id
    864 				AND {{name}}.languageid = {languageid}
    865 		  LEFT JOIN {{user}}
    866 		         ON {{user}}.id = {{object}}.lastchange_userid
    867 			  WHERE {{object}}.projectid = {projectid}
    868 		   ORDER BY {{object}}.lastchange_date DESC
    869 SQL
    870 		);
    871 		
    872 		// Variablen setzen.
    873 		$sql->setInt( 'projectid', $this->projectid );
    874 		
    875 		$languageid = $this->getDefaultLanguageId();
    876 		$sql->setInt( 'languageid', $languageid );
    877 		
    878 		return $sql->getAll();
    879 	}
    880 
    881     /**
    882      * Ermittelt alle Objekte vom gew�nschten Typ, die sic in
    883      * diesem Projekt befinden.
    884      *
    885      * @see objectClasses/Object#getAllObjectIds()
    886      * @param array types Array
    887      * @return array Liste von Object-Ids
    888      */
    889     public function getAllObjectIds( $types=array('folder','page','link','file','image','url','text') )
    890     {
    891         $stmt = \cms\base\Db::sql( <<<SQL
    892           SELECT id FROM {{object}}
    893               WHERE projectid={projectid}
    894                 AND (    typeid  ={is_folder}
    895                       OR typeid  ={is_file}
    896                       OR typeid  ={is_image}
    897                       OR typeid  ={is_text}
    898                       OR typeid  ={is_page}
    899                       OR typeid  ={is_link}
    900                       OR typeid  ={is_url} )
    901              ORDER BY orderid ASC
    902 SQL
    903         );
    904 
    905         $stmt->setInt('projectid',$this->projectid );
    906         $stmt->setInt('is_folder',in_array('folder',$types)?BaseObject::TYPEID_FOLDER:0);
    907         $stmt->setInt('is_file'  ,in_array('file'  ,$types)?BaseObject::TYPEID_FILE  :0);
    908         $stmt->setInt('is_image' ,in_array('image' ,$types)?BaseObject::TYPEID_IMAGE :0);
    909         $stmt->setInt('is_text'  ,in_array('text'  ,$types)?BaseObject::TYPEID_TEXT  :0);
    910         $stmt->setInt('is_page'  ,in_array('page'  ,$types)?BaseObject::TYPEID_PAGE  :0);
    911         $stmt->setInt('is_link'  ,in_array('link'  ,$types)?BaseObject::TYPEID_LINK  :0);
    912         $stmt->setInt('is_url'   ,in_array('url'   ,$types)?BaseObject::TYPEID_URL   :0);
    913 
    914         return( $stmt->getCol() );
    915     }
    916 
    917 
    918     /**
    919      * Liefert die Ids aller Ordner in diesem Projekt.
    920      *
    921      * @return array
    922      */
    923     public function getAllFolders()
    924     {
    925         $stmt = DB::sql( <<<SQL
    926 			SELECT id FROM {{object}}
    927               WHERE typeid={typeid}
    928                 AND projectid={projectid}
    929 SQL
    930 		);
    931         $stmt->setInt( 'typeid'   ,BaseObject::TYPEID_FOLDER );
    932         $stmt->setInt( 'projectid',$this->projectid                 );
    933 
    934         return( $stmt->getCol() );
    935     }
    936 
    937 
    938     /**
    939      * @return array
    940      */
    941     public function getAllFlatFolders() {
    942 
    943         $folders = array();
    944 
    945         foreach( $this->getAllFolders() as $id )
    946         {
    947             $o = new BaseObject( $id );
    948             $o->load();
    949 
    950             $folders[ $id ] = '';
    951             if	( !$o->isRoot() )
    952             {
    953                 $f = new Folder( $o->parentid );
    954                 $f->load();
    955                 $names = $f->parentObjectNames(true,true);
    956                 foreach( $names as $fid=>$name )
    957                     $names[$fid] = \util\Text::maxLength($name,15,'..',STR_PAD_BOTH);
    958                 $folders[ $id ] = implode( \util\Text::FILE_SEP,$names );
    959                 $folders[ $id ] .= \util\Text::FILE_SEP;
    960             }
    961             $folders[ $id ] .= $o->getName();
    962         }
    963 
    964         asort( $folders ); // Sortieren
    965 
    966         return $folders;
    967     }
    968 
    969     public function getName()
    970     {
    971         return $this->name;
    972     }
    973 
    974 
    975 	/**
    976 	 * Cleans up the target url.
    977 	 */
    978 	public function getCleanTarget()
    979 	{
    980 		$target = parse_url( $this->target_dir );
    981 
    982 		$scheme   = isset($target['scheme']) ? $target['scheme'] . '://' : '';
    983 		if   ( empty($scheme) )
    984 			$scheme = 'file:/';
    985 
    986 		$host     = isset($target['host']) ? $target['host'] : '';
    987 		$port     = isset($target['port']) ? ':' . $target['port'] : '';
    988 		$user     = isset($target['user']) ? $target['user'] : '';
    989 		$pass     = isset($target['pass']) ? ':' . $target['pass']  : '';
    990 		$pass     = ($user || $pass) ? "$pass@" : '';
    991 		$path     = isset($target['path']) ? $target['path'] : '';
    992 		$query    = isset($target['query']) ? '?' . $target['query'] : '';
    993 		$fragment = isset($target['fragment']) ? '#' . $target['fragment'] : '';
    994 
    995 		return "$scheme$user$pass$host$port$path$query$fragment";
    996 	}
    997 
    998 
    999 
   1000 	public function getId()
   1001 	{
   1002 		return $this->projectid;
   1003 	}
   1004 
   1005 
   1006 }
   1007