openrat-cms

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

Page.class.php (21558B)


      1 <?php
      2 namespace cms\model;
      3 // OpenRat Content Management System
      4 // Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de
      5 //
      6 // This program is free software; you can redistribute it and/or
      7 // modify it under the terms of the GNU General Public License
      8 // as published by the Free Software Foundation; either version 2
      9 // of the License, or (at your option) any later version.
     10 //
     11 // This program is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 //
     16 // You should have received a copy of the GNU General Public License
     17 // along with this program; if not, write to the Free Software
     18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     19 use cms\mustache\Mustache;
     20 use cms\publish\PublishPreview;use cms\publish\PublishPublic;
     21 use http\Exception\RuntimeException;
     22 use Logger;
     23 use util\FileCache;
     24 
     25 
     26 /**
     27  * Darstellen einer Seite
     28  *
     29  * @author Jan Dankert
     30  * @package openrat.objects
     31  */
     32 
     33 class Page extends BaseObject
     34 {
     35 	var $enclosingObjectId = -1;    //Id der Seite in die diese Seite im Rahmen der Generierung eingefügt wird
     36 						     //Wichtig für include-Values
     37 	var $pageid;
     38 	var $templateid;
     39 
     40 	/**
     41 	 * @var Template
     42 	 */
     43 	var $template;
     44 
     45     /**
     46      * @deprecated
     47      */
     48 	var $simple = false;
     49 
     50     /**
     51 	 * @deprecated replaced by publish->isPublic()
     52      */
     53 	var $public = false;
     54 
     55 	var $el = array();
     56 
     57 	/**
     58 	 * Stellt fest, ob die Editier-Icons angezeigt werden sollen. Dies ist
     59 	 * nur der Fall, wenn die Seite auch zum Bearbeiten generiert wird.
     60 	 * Wird die Seite zum Veröffentlichen generiert, muss diese Eigenschaft
     61 	 * natürlich "false" sein.
     62 	 * @var boolean
     63 	 */
     64 	var $icons = false;
     65 	var $src   = '';
     66 	var $edit  = false;
     67 
     68 	var $content_negotiation = false;
     69 	var $cut_index           = false;
     70 	var $default_language    = false;
     71 //	var $withLanguage        = false;
     72 	var $withLanguage        = true;
     73 	var $withModel           = true;
     74 //	var $withModel           = false;
     75 	var $link                = false;
     76 	var $fullFilename = '';
     77 
     78 	var $log_filenames       = array();
     79 	var $modelid = 0;
     80 
     81     /**
     82      * @var Value[]
     83      */
     84     public $values;
     85 
     86     /**
     87      * Inhalt der Seite.
     88      */
     89     public $value;
     90 
     91     function __construct( $objectid='' )
     92 	{
     93 		parent::__construct( $objectid );
     94 		$this->isPage = true;
     95 		$this->typeid = BaseObject::TYPEID_PAGE;
     96 
     97 		$this->publisher = new PublishPreview();
     98 
     99     }
    100 
    101 
    102     /**
    103      * @return FileCache
    104      */
    105     public function getCache() {
    106         $cacheKey =  array('db'=>db()->id,
    107             'page' =>$this->objectid,
    108             'language' =>$this->languageid,
    109             'model' =>$this->modelid,
    110             'publish' =>\ClassUtils::getSimpleClassName($this->publisher) );
    111 
    112         return new FileCache( $cacheKey,function() {
    113             return $this->generateValue();
    114         }, $this->lastchangeDate );
    115 
    116     }
    117 
    118 	/**
    119 	 * Ermitteln der Objekt-ID (Tabelle object) anhand der Seiten-ID (Tablle page)
    120 	 *
    121 	 * @deprecated pageid sollte nicht mehr benutzt werden
    122 	 * @return Integer objectid
    123 	 */
    124 	function getObjectIdFromPageId( $pageid )
    125 	{
    126 		$db = db_connection();
    127 
    128 		$sql  = $db->sql( 'SELECT objectid FROM {{page}} '.
    129 		                 '  WHERE id={pageid}' );
    130 		$sql->setInt('pageid',$pageid);
    131 
    132 		return $sql->getOne();
    133 	}
    134 
    135 
    136 	/**
    137 	 * Ermitteln der Seiten-ID anhand der Objekt-ID
    138 	 *
    139 	 * @deprecated pageid sollte nicht mehr benutzt werden
    140 	 * @return Integer pageid
    141 	 */
    142 	public static function getPageIdFromObjectId( $objectid )
    143 	{
    144 		$sql  = db()->sql( 'SELECT id FROM {{page}} '.
    145 		                 '  WHERE objectid={objectid}' );
    146 		$sql->setInt('objectid',$objectid);
    147 
    148 		return $sql->getOne();
    149 	}
    150 
    151 
    152 	/**
    153 	  * Ermitteln aller Eigenschaften
    154 	  *
    155 	  * @return Array
    156 	  */
    157 	function getProperties()
    158 	{
    159 		return array_merge( parent::getProperties(),
    160 		                    array('full_filename'=>$this->realFilename(),
    161 		                          'pageid'       =>$this->pageid,
    162 		                          'templateid'   =>$this->templateid,
    163 		                          'mime_type'    =>$this->mimeType() ) );
    164 	}
    165 
    166 
    167 	/**
    168 	 * Ermitteln der Ordner, in dem sich die Seite befindet
    169 	 * @return array
    170 	 */
    171 	function parentfolder()
    172 	{
    173 		$folder = new Folder();
    174 		$folder->folderid = $this->parentid;
    175 		
    176 		return $folder->parentObjectFileNames( false,true );
    177 	}
    178 
    179 
    180 
    181 
    182 	/**
    183 	  * Ermittelt den Pfad zu einem beliebigen Objekt
    184 	  *
    185 	  * @param Integer Objekt-ID des Zielobjektes
    186 	  * @return String Relative Link-angabe, Beispiel: '../../pfad/datei.jpeg'
    187 	  */
    188 	public function path_to_object( $objectid )
    189 	{
    190 		if	( ! BaseObject::available( $objectid) )
    191 			return 'about:blank';
    192 			
    193         $to = new BaseObject($objectid);
    194         $to->load();
    195         $inhalt = $this->publisher->linkToObject( $this, $to );
    196 
    197 		return $inhalt;
    198 	}
    199 
    200 
    201 
    202 
    203 	/**
    204 	 * Eine Seite hinzufuegen
    205 	 */
    206 	function add()
    207 	{
    208 		parent::add(); // Hinzuf?gen von Objekt (dabei wird Objekt-ID ermittelt)
    209 
    210 		$sql = db()->sql('SELECT MAX(id) FROM {{page}}');
    211 		$this->pageid = intval($sql->getOne())+1;
    212 
    213 		$sql = db()->sql(<<<SQL
    214 	INSERT INTO {{page}}
    215 	            (id,objectid,templateid)
    216 	       VALUES( {pageid},{objectid},{templateid} )
    217 SQL
    218 		);
    219 		$sql->setInt   ('pageid'    ,$this->pageid     );
    220 		$sql->setInt   ('objectid'  ,$this->objectid   );
    221 		$sql->setInt   ('templateid',$this->templateid );
    222 
    223 		$sql->query();
    224 	}
    225 
    226 
    227 	/**
    228 	  * Seite laden
    229 	  */
    230 	function load()
    231 	{
    232 		$sql  = db()->sql( 'SELECT * FROM {{page}} '.
    233 		                 '  WHERE objectid={objectid}' );
    234 		$sql->setInt('objectid',$this->objectid);
    235 		$row = $sql->getRow();
    236 
    237 		if   ( count($row)==0 )
    238 			throw new \ObjectNotFoundException("Page with Id $this->objectid not found.");
    239 
    240 		$this->pageid      = $row['id'        ];
    241 		$this->templateid  = $row['templateid'];
    242 
    243 		$this->objectLoad();
    244 	}
    245 
    246 
    247 	function delete()
    248 	{
    249 		$db = db_connection();
    250 
    251 		$sql = $db->sql( 'DELETE FROM {{value}} '.
    252 		                '  WHERE pageid={pageid}' );
    253 		$sql->setInt('pageid',$this->pageid);
    254 		$sql->query();
    255 
    256 		$sql = $db->sql( 'DELETE FROM {{page}} '.
    257 		                '  WHERE objectid={objectid}' );
    258 		$sql->setInt('objectid',$this->objectid);
    259 		$sql->query();
    260 		
    261 		$this->objectDelete();
    262 	}
    263 
    264 
    265 	/**
    266 	 * Kopieren der Inhalts von einer anderen Seite
    267 	 * @param $otherpageid integer ID der Seite, von der der Inhalt kopiert werden soll
    268 	 */
    269 	function copyValuesFromPage( $otherpageid )
    270 	{
    271 		$this->load();
    272 
    273 		foreach( $this->getElementIds() as $elementid )
    274 		{
    275 			$project = new Project( $this->projectid );
    276 			foreach( $project->getLanguages() as $lid=>$lname )
    277 			{
    278 				$val = new Value();
    279 				$val->element = new Element( $elementid );
    280 	
    281 				$val->objectid   = $otherpageid;
    282 				$val->pageid     = Page::getPageIdFromObjectId( $otherpageid );
    283 				$val->languageid = $lid;
    284 				$val->load();
    285 
    286 				// Inhalt nur speichern, wenn vorher vorhanden	
    287 				if	( $val->valueid != 0 )
    288 				{
    289 					$val->objectid   = $this->objectid;
    290 					$val->pageid     = Page::getPageIdFromObjectId( $this->objectid );
    291 					$val->save();
    292 				}
    293 			}
    294 		}
    295 	}
    296 
    297 
    298 
    299 
    300 	function save()
    301 	{
    302 		$db = db_connection();
    303 
    304 		$sql = $db->sql('UPDATE {{page}}'.
    305 		               '  SET templateid ={templateid}'.
    306 		               '  WHERE objectid={objectid}' );
    307 		$sql->setInt('templateid' ,$this->templateid);
    308 		$sql->setInt('objectid'   ,$this->objectid  );
    309 		$sql->query();
    310 
    311 		$this->objectSave();
    312 	}
    313 
    314 
    315 	
    316 	function replaceTemplate( $newTemplateId,$replaceElementMap )
    317 	{
    318 		$oldTemplateId = $this->templateid;
    319 
    320 		$db = db_connection();
    321 
    322 		// Template-id dieser Seite aendern
    323 		$this->templateid = $newTemplateId;
    324 
    325 		$sql = $db->sql('UPDATE {{page}}'.
    326 		               '  SET templateid ={templateid}'.
    327 		               '  WHERE objectid={objectid}' );
    328 		$sql->setInt('templateid' ,$this->templateid);
    329 		$sql->setInt('objectid'   ,$this->objectid  );
    330 		$sql->query();
    331 
    332 
    333 		// Inhalte umschluesseln, d.h. die Element-Ids aendern
    334 		$template = new Template( $oldTemplateId );
    335 		foreach( $template->getElementIds() as $oldElementId )
    336 		{
    337 			if	( !isset($replaceElementMap[$oldElementId])  ||
    338 			      intval($replaceElementMap[$oldElementId]) < 1 )
    339 			{
    340 				\Logger::debug( 'deleting value of elementid '.$oldElementId );
    341 				$sql = $db->sql('DELETE FROM {{value}}'.
    342 				               '  WHERE pageid={pageid}'.
    343 				               '    AND elementid={elementid}' );
    344 				$sql->setInt('pageid'   ,$this->pageid);
    345 				$sql->setInt('elementid',$oldElementId      );
    346 				
    347 				$sql->query();
    348 			}
    349 			else
    350 			{
    351 				$newElementId = intval($replaceElementMap[$oldElementId]);
    352 
    353 				\Logger::debug( 'updating elementid '.$oldElementId.' -> '.$newElementId );
    354 				$sql = $db->sql('UPDATE {{value}}'.
    355 				               '  SET elementid ={newelementid}'.
    356 				               '  WHERE pageid   ={pageid}'.
    357 				               '    AND elementid={oldelementid}' );
    358 				$sql->setInt('pageid'      ,$this->pageid);
    359 				$sql->setInt('oldelementid',$oldElementId      );
    360 				$sql->setInt('newelementid',$newElementId      );
    361 				$sql->query();
    362 			}
    363 		}
    364 	}
    365 
    366 
    367 	
    368 	/**
    369 	  * Ermitteln des Dateinamens dieser Seite.
    370 	  * 
    371 	  * Wenn '$this->content_negotiation' auf 'true' steht, wird der Dateiname ggf. gekürzt,
    372 	  * so wie er für HTML-Links verwendet wird. Sonst wird immer der echte Dateiname
    373 	  * ermittelt.
    374 	  *
    375 	  * @return String Kompletter Dateiname, z.B. '/pfad/seite.en.html'
    376 	  */
    377 	function full_filename()
    378 	{
    379 		$filename = $this->path().'/'.$this->getFilename();
    380 
    381 		$this->fullFilename = $filename;
    382 		return $filename;
    383 	}
    384 
    385 
    386 	/**
    387 	  * Ermitteln des Dateinamens dieser Seite.
    388 	  *
    389 	  * Wenn '$this->content_negotiation' auf 'true' steht, wird der Dateiname ggf. gekürzt,
    390 	  * so wie er für HTML-Links verwendet wird. Sonst wird immer der echte Dateiname
    391 	  * ermittelt.
    392 	  *
    393 	  * @return String Kompletter Dateiname, z.B. '/pfad/seite.en.html'
    394 	  */
    395 	function getFilename()
    396 	{
    397 		return self::filename();
    398 	}
    399 
    400 
    401 
    402     /**
    403      * Ermitteln des Dateinamens dieser Seite.
    404      *
    405      * Wenn '$this->content_negotiation' auf 'true' steht, wird der Dateiname ggf. gekürzt,
    406      * so wie er für HTML-Links verwendet wird. Sonst wird immer der echte Dateiname
    407      * ermittelt.
    408      *
    409      * @return String Kompletter Dateiname, z.B. '/pfad/seite.en.html'
    410      */
    411     function filename()
    412     {
    413         if	( $this->cut_index && $this->filename == config('publish','default') )
    414         {
    415             return ''; // Link auf Index-Datei, der Dateiname bleibt leer.
    416         }
    417         else
    418         {
    419             $format = config('publish','format');
    420             $format = str_replace('{filename}',parent::filename(),$format );
    421 
    422             if	( !$this->withLanguage || $this->content_negotiation && config('publish','negotiation','page_negotiate_language' ) )
    423             {
    424                 $format = str_replace('{language}'    ,'',$format );
    425                 $format = str_replace('{language_sep}','',$format );
    426             }
    427             else
    428             {
    429                 $l = new Language( $this->languageid );
    430                 $l->load();
    431                 $format = str_replace('{language}'    ,$l->isoCode                     ,$format );
    432                 $format = str_replace('{language_sep}',config('publish','language_sep'),$format );
    433             }
    434 
    435             if	( !$this->withModel || $this->content_negotiation && config('publish','negotiation','page_negotiate_type' ) )
    436             {
    437                 $format = str_replace('{type}'    ,'',$format );
    438                 $format = str_replace('{type_sep}','',$format );
    439             }
    440             else
    441             {
    442                 $t = new Template( $this->templateid );
    443                 $t->modelid = $this->modelid;
    444                 $t->load();
    445                 $format = str_replace('{type}'    ,$t->extension               ,$format );
    446                 $format = str_replace('{type_sep}',config('publish','type_sep'),$format );
    447             }
    448             return $format;
    449         }
    450     }
    451 
    452 
    453 
    454 //	function language_filename()
    455 //	{
    456 //		global $SESS;
    457 //		
    458 //		$db = db_connection();
    459 //
    460 //		$sql  = $db->sql( 'SELECT COUNT(*) FROM {{language}}'.
    461 //		                 ' WHERE projectid={projectid}' );
    462 //		$sql->setInt('projectid',$SESS['projectid']);
    463 //
    464 //		if   ( $sql->getOne( $sql ) == 1 )
    465 //		{
    466 //			// Wenn es nur eine Sprache gibt, keine Sprachangabe im Dateinamen
    467 //			return '';
    468 //		}
    469 //		else
    470 //		{
    471 //			$sql = $db->sql( 'SELECT isocode FROM {{language}}'.
    472 //			                ' WHERE id={languageid}' );
    473 //			$sql->setInt('languageid',$this->languageid);
    474 //			$isocode = $sql->getOne( $sql );
    475 //
    476 //			return strtolower( $isocode );
    477 //		}		
    478 //	}
    479 
    480 
    481 	/**
    482 	  * Erzeugen der Inhalte zu allen Elementen dieser Seite
    483 	  * wird von generate() aufgerufen
    484 	  *
    485 	  * @access private 
    486 	  */
    487 	function getElementIds()
    488 	{
    489 		$t = new Template( $this->templateid );
    490 		
    491 		return $t->getElementIds();
    492 	}
    493 
    494 
    495 
    496 	/**
    497 	  * Erzeugen der Inhalte zu allen Elementen dieser Seite
    498 	  * wird von generate() aufgerufen
    499 	  *
    500 	  * @access private 
    501 	  */
    502 	function getElements()
    503 	{
    504 		if	( !isset($this->template) )
    505 			$this->template = new Template( $this->templateid );
    506 		
    507 		return $this->template->getElements();
    508 	}
    509 
    510 
    511 
    512 	/**
    513 	  * Erzeugen der Inhalte zu allen Elementen dieser Seite
    514 	  * wird von generate() aufgerufen
    515 	  *
    516 	  * @access private 
    517 	  */
    518 	function getWritableElements()
    519 	{
    520 		if	( !isset($this->template) )
    521 			$this->template = new Template( $this->templateid );
    522 		
    523 		return $this->template->getWritableElements();
    524 	}
    525 
    526 
    527 
    528 	/**
    529 	  * Erzeugen der Inhalte zu allen Elementen dieser Seite
    530 	  * wird von generate() aufgerufen
    531 	  */
    532 	public function generate_elements()
    533 	{
    534 		$this->values = array();
    535 		
    536 		if	( $this->publisher->isSimplePreview() )
    537 			$elements = $this->getWritableElements();
    538 		else
    539 			$elements = $this->getElements();
    540 			
    541 		foreach( $elements as $elementid=>$element )
    542 		{
    543 			// neues Inhaltobjekt erzeugen
    544 			$val = new Value();
    545 			$val->element = $element;
    546 
    547 			$val->publisher  = $this->publisher;
    548 			$val->objectid   = $this->objectid;
    549 			$val->pageid     = $this->pageid;
    550 			$val->languageid = $this->languageid;
    551 			$val->modelid    = $this->modelid;
    552 			$val->page       = $this;
    553 			try {
    554 				$val->generate();
    555 			} catch( \Exception $e ) {
    556 				// Unrecoverable Error while generating the content.
    557 
    558 				Logger::warn('Could not generate Value '.$val->__toString() . ': '.$e->getMessage() );
    559 
    560 				if   ( $this->publisher->isPublic() )
    561 					$val->value = '';
    562 				else
    563 					$val->value = '[Warning: '.$e->getMessage().']';
    564 			}
    565 
    566 			$this->values[$elementid] = $val;
    567 		}
    568 	}
    569 
    570 
    571 
    572 	public function generate() {
    573 
    574 		return $this->getCache()->get();
    575 	}
    576 
    577 	/**
    578 	  * Erzeugen des Inhaltes der gesamten Seite.
    579 	  * 
    580 	  * @return String Inhalt
    581 	  */
    582 	private function generateValue()
    583 	{
    584 		global $conf;
    585 		
    586 		// Setzen der 'locale', damit sprachabhängige Systemausgaben (wie z.B. die
    587 		// Ausgabe von strftime()) in der korrekten Sprache dargestellt werden.
    588 		$language = new Language($this->languageid);
    589 		$language->load();
    590 
    591 		$language->setCurrentLocale();
    592 		
    593 
    594 		$this->template = new Template( $this->templateid );
    595 		$this->template->modelid = $this->modelid;
    596 		$this->template->load();
    597 		$this->ext = $this->template->extension;
    598 
    599 		$this->generate_elements();
    600 
    601 		// Get a List with ElementId->ElementName
    602 		$elements = array_map(function($element) {
    603 			return $element->name;
    604 		},$this->getElements() );
    605 		 
    606 		$templatemodel = new TemplateModel( $this->template->templateid, $this->modelid );
    607 		$templatemodel->load();
    608 		$src = $templatemodel->src;
    609 
    610 		$data = array();
    611 
    612 		// Template should have access to the page properties.
    613 		// Template should have access to the settings of this node object.
    614 		$data['_page'         ] = $this->getProperties()   ;
    615 		$data['_localsettings'] = $this->getSettings()     ;
    616 		$data['_settings'     ] = $this->getTotalSettings();
    617 
    618 		// No we are collecting the data and are fixing some old stuff.
    619 
    620 		foreach( $elements as $elementId=>$elementName )
    621 		{
    622 			$data[ $elementName ] = $this->values[$elementId]->generate();
    623 
    624 			// The following code is for old template values:
    625 
    626 			// convert {{<id>}} to {{<name>}}
    627 			$src = str_replace( '{{'.$elementId.'}}','{{'.$elementName.'}}',$src );
    628 
    629             $src = str_replace( '{{IFNOTEMPTY:'.$elementId.':BEGIN}}','{{#'.$elementName.'}}',$src );
    630             $src = str_replace( '{{IFNOTEMPTY:'.$elementId.':END}}'  ,'{{/'.$elementName.'}}',$src );
    631             $src = str_replace( '{{IFEMPTY:'   .$elementId.':BEGIN}}','{{^'.$elementName.'}}',$src );
    632             $src = str_replace( '{{IFEMPTY:'   .$elementId.':END}}'  ,'{{/'.$elementName.'}}',$src );
    633 
    634 			if   ( $this->icons )
    635 				$src = str_replace( '{{->'.$elementId.'}}','<a href="javascript:parent.openNewAction(\''.$elementName.'\',\'pageelement\',\''.$this->objectid.'_'.$value->element->elementid.'\');" title="'.$value->element->desc.'"><img src="'.OR_THEMES_DIR.$conf['interface']['theme'].'/images/icon_el_'.$value->element->type.IMG_ICON_EXT.'" border="0" align="left"></a>',$src );
    636 			else
    637 				$src = str_replace( '{{->'.$elementId.'}}','',$src );
    638 		}
    639 
    640 		Logger::trace( 'pagedata: '.print_r($data,true) );
    641 
    642 		// Now we have collected all data, lets call the template engine:
    643 
    644         $template = new Mustache();
    645 		$template->escape = null; // No HTML escaping, this is the job of this CMS ;)
    646 		$template->partialLoader = function( $name ) {
    647 
    648 		 	if   ( substr($name,0,5) == 'file:') {
    649 		 	 	$fileid = intval( substr($name,5) );
    650 		 	 	$file = new File( $fileid );
    651 		 	 	return $file->loadValue();
    652 			}
    653 
    654 
    655 		 	$project       = new Project($this->projectid);
    656 		 	$templateid    = array_search($name,$project->getTemplates() );
    657 
    658 			if   ( ! $templateid )
    659 			 	return $this->publisher->isPublic()?'':"template '$name' not found";
    660 
    661 			if   ( $templateid == $this->template->templateid )
    662 				return $this->publisher->isPublic()?'':'Template recursion is not supported';
    663 
    664 
    665 			$templatemodel = new TemplateModel( $templateid, $this->modelid );
    666 			$templatemodel->load();
    667 
    668 			return $templatemodel->src;
    669 		};
    670 
    671         try {
    672         	$template->parse($src);
    673         } catch (\Exception $e) {
    674 			// Should we throw it to the caller?
    675 			// No, because it is not a technical error. So let's only log it.
    676 			Logger::warn("Template rendering failed: ".$e->getMessage() );
    677 			return $e->getMessage();
    678         }
    679         $src = $template->render( $data );
    680 
    681         // now we have the fully generated source.
    682 
    683 		// should we do a UTF-8-escaping here?
    684 		// Default should be off, because if you are fully using utf-8 (you should do), this is unnecessary.
    685 		if	( config('publish','escape_8bit_characters') )
    686 			if	( substr($this->mimeType(),-4) == 'html' )
    687 			{
    688 				/*
    689 				 * 
    690 				$src = htmlentities($src,ENT_NOQUOTES,'UTF-8');
    691 				$src = str_replace('&lt;' , '<', $src);
    692 				$src = str_replace('&gt;' , '>', $src);
    693 				$src = str_replace('&amp;', '&', $src);
    694 				 */
    695 				$src = translateutf8tohtml($src);
    696 			}
    697 		
    698 		return $src;
    699 	}
    700 
    701 
    702 	/**
    703 	  * Schreiben des Seiteninhaltes in die temporaere Datei
    704 	  */
    705 	public function write()
    706 	{
    707 			$this->getCache()->load();
    708 	}
    709 
    710 
    711 	/**
    712 	 * Generieren dieser Seite in Dateisystem und/oder auf FTP-Server
    713 	 */
    714 	public function publish()
    715 	{
    716 		$project = Project::create( $this->projectid );
    717 
    718 		$allLanguages = $project->getLanguageIds();
    719 		$allModels    = $project->getModelIds();
    720 		
    721 		// Schleife ueber alle Sprachvarianten
    722 		foreach( $allLanguages as $languageid )
    723 		{
    724 			$this->languageid   = $languageid;
    725 			$this->withLanguage = count($allLanguages) > 1 || config('publish','filename_language') == 'always';
    726 			$this->withModel    = count($allModels   ) > 1 || config('publish','filename_type'    ) == 'always';
    727 			
    728 			// Schleife ueber alle Projektvarianten
    729 			foreach( $allModels as $projectmodelid )
    730 			{
    731 				$this->modelid = $projectmodelid;
    732 			
    733 				$this->load();
    734 				$this->getCache()->load();
    735 
    736 				// Vorlage ermitteln.
    737 				$t = new Template( $this->templateid );
    738 				$t->modelid = $this->modelid;
    739 				$t->load();
    740 				
    741 				// Nur wenn eine Datei-Endung vorliegt wird die Seite veroeffentlicht
    742 				if	( !empty($t->extension) )
    743 				{ 	
    744 					$this->publisher->copy( $this->getCache()->getFilename(),$this->full_filename() );
    745 					$this->publisher->publishedObjects[] = $this->getProperties();
    746 				}
    747 			}
    748 		}
    749 
    750 		parent::setPublishedTimestamp();
    751 
    752 	}
    753 	
    754 
    755 	/**
    756 	 * Ermittelt den Mime-Type zu dieser Seite
    757 	 *
    758 	 * @return String Mime-Type  
    759 	 */
    760 	function mimeType()
    761 	{
    762 		if	( ! is_object($this->template) )
    763 		{
    764 			$this->template = new Template( $this->templateid );
    765 			$this->template->modelid = $this->modelid;
    766 			$this->template->load();
    767 		}
    768 
    769 		$this->mime_type = $this->template->mimeType();
    770 			
    771 		return( $this->mime_type );
    772 	}
    773 
    774 	
    775 	
    776 	function setTimestamp()
    777 	{
    778 		$this->getCache()->invalidate();
    779 
    780 		parent::setTimestamp();
    781 	}
    782 	
    783 	
    784 	/**
    785 	 * Ermittelt den Dateinamen dieser Seite, so wie sie auch im Dateisystem steht.
    786 	 */
    787 	function realFilename()
    788 	{
    789 		$project = new Project( $this->projectid );
    790 		$this->withLanguage = config('publish','filename_language') == 'always' || count($project->getLanguageIds()) > 1;
    791 		$this->withModel    = config('publish','filename_type'    ) == 'always' || count($project->getModelIds()   ) > 1;
    792 		
    793 		return $this->full_filename();
    794 	}
    795 
    796 	
    797 	/**
    798 	 * Stellt fest, ob diese Seite im HTML-Format veröffentlicht wird.
    799 	 * @return boolean
    800 	 */
    801 	public function isHtml()
    802 	{
    803 		return $this->mimeType()=='text/html';
    804 	}
    805 
    806     public function __toString()
    807     {
    808     	return 'Id '.$this->pageid.' (filename='.$this->filename.',language='.$this->languageid.', modelid='.$this->modelid.', templateid='.$this->templateid.')';
    809     }
    810 }
    811 
    812 
    813 ?>