openrat-cms

# OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs

Project.class.php (30834B)


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