openrat-cms

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

ValueGenerator.class.php (33783B)


      1 <?php
      2 
      3 
      4 namespace cms\generator;
      5 
      6 
      7 use cms\base\Configuration;
      8 use cms\base\Configuration as C;
      9 use cms\base\DB;
     10 use cms\base\Startup;
     11 use cms\generator\dsl\DslCms;
     12 use cms\generator\dsl\DslConsole;
     13 use cms\generator\dsl\DslDocument;
     14 use cms\generator\dsl\DslHttp;
     15 use cms\generator\dsl\DslJson;
     16 use cms\generator\dsl\DslMqtt;
     17 use cms\generator\dsl\DslObject;
     18 use cms\generator\dsl\DslPage;
     19 use cms\generator\dsl\DslPageContext;
     20 use cms\generator\dsl\DslProject;
     21 use cms\generator\dsl\DslWrite;
     22 use cms\macros\MacroRunner;
     23 use cms\model\BaseObject;
     24 use cms\model\Element;
     25 use cms\model\File;
     26 use cms\model\Folder;
     27 use cms\model\Image;
     28 use cms\model\Language;
     29 use cms\model\Link;
     30 use cms\model\Page;
     31 use cms\model\PageContent;
     32 use cms\model\Project;
     33 use cms\model\Template;
     34 use cms\model\Value;
     35 use dsl\context\BaseScriptableObject;
     36 use dsl\DslException;
     37 use dsl\executor\DslInterpreter;
     38 use dsl\standard\Data;
     39 use logger\Logger;
     40 use LogicException;
     41 use util\Code;
     42 use util\exception\GeneratorException;
     43 use util\exception\ObjectNotFoundException;
     44 use util\exception\PublisherException;
     45 use util\Html;
     46 use util\Http;
     47 use util\Mqtt;
     48 use util\Request;
     49 use util\Text;
     50 use util\Transformer;
     51 use util\YAML;
     52 
     53 
     54 /**
     55  * Generates a value.
     56  */
     57 class ValueGenerator extends BaseGenerator
     58 {
     59 
     60 	const CODE_PHP = 'php';
     61 	const CODE_SCRIPT = 'js';
     62 	const CODE_MUSTACHE  = 'mustache';
     63 
     64 	const INFO_DB_ID   = 'db_id';
     65 	const INFO_DB_NAME = 'db_name';
     66 	const INFO_PROJECT_ID = 'project_id';
     67 	const INFO_PROJECT_NAME = 'project_name';
     68 	const INFO_LANGUAGE_ID = 'language_id';
     69 	const INFO_LANGUAGE_ISO = 'language_iso';
     70 	const INFO_LANGUAGE_NAME = 'language_name';
     71 	const INFO_PAGE_ID = 'page_id';
     72 	const INFO_PAGE_NAME = 'page_name';
     73 	const INFO_PAGE_DESC = 'page_desc';
     74 	const INFO_PAGE_FULLFILENAME = 'page_fullfilename';
     75 	const INFO_PAGE_FILENAME = 'page_filename';
     76 	const INFO_PAGE_EXTENSION = 'page_extension';
     77 	const INFO_EDIT_URL = 'edit_url';
     78 	const INFO_EDIT_FULLURL = 'edit_fullurl';
     79 	const INFO_LASTCHANGE_USER_USERNAME = 'lastch_user_username';
     80 	const INFO_LASTCHANGE_USER_FULLNAME = 'lastch_user_fullname';
     81 	const INFO_LASTCHANGE_USER_MAIL = 'lastch_user_mail';
     82 	const INFO_LASTCHANGE_USER_DESC = 'lastch_user_desc';
     83 	const INFO_LASTCHANGE_USER_TEL = 'lastch_user_tel';
     84 	const INFO_CREATION_USER_USERNAME = 'create_user_username';
     85 	const INFO_CREATION_FULLNAME = 'create_user_fullname';
     86 	const INFO_CREATION_MAIL = 'create_user_mail';
     87 	const INFO_CREATION_DESC = 'create_user_desc';
     88 	const INFO_CREATION_TEL = 'create_user_tel';
     89 	const INFO_ACT_USERNAME = 'act_user_username';
     90 	const INFO_ACT_FULLNAME = 'act_user_fullname';
     91 	const INFO_ACT_MAIL = 'act_user_mail';
     92 	const INFO_ACT_DESC = 'act_user_desc';
     93 	const INFO_ACT_TEL = 'act_user_tel';
     94 	const INFO_PUB_USERNAME = 'pub_user_username';
     95 	const INFO_PUB_FULLNAME = 'pub_user_fullname';
     96 	const INFO_PUB_MAIL = 'pub_user_mail';
     97 	const INFO_PUB_DESC = 'pub_user_desc';
     98 	const INFO_PUB_TEL = 'pub_user_tel';
     99 	const INFO_FILENAME = 'filename';
    100 	const INFO_FULL_FILENAME = 'full_filename';
    101 
    102 	const COORD_OLC = 'olc';
    103 	const COORD_COORDINATES = 'coordinates';
    104 
    105 	const INFO_DATE_PUBLISHED = 'date_published';
    106 	const INFO_DATE_SAVED = 'date_saved';
    107 	const INFO_DATE_CREATED = 'date_created';
    108 
    109 	const INSERT_ESI = 'esi';
    110 	const INSERT_SSI = 'ssi';
    111 	const INSERT_INLINE = 'inline';
    112 
    113 
    114 	const LINK_FILE_ = 'file';
    115 	const LINK_IMAGE = 'image';
    116 	const LINK_IMAGE_DATE_URI = 'image_data_uri';
    117 	const LINK_PAGE = 'page';
    118 	const LINK_FOLDER = 'folder';
    119 	const LINK_LINK = 'link';
    120 
    121 	const LINKINFO_WIDTH = 'width';
    122 	const LINKINFO_HEIGHT = 'height';
    123 	const LINKINFO_ID = 'id';
    124 	const LINKINFO_NAME = 'name';
    125 	const LINKINFO_DESCRIPTION = 'description';
    126 	const LINKINFO_MIME_TYPE = 'mime_type';
    127 
    128 
    129 	/**
    130 	 * Constructor.
    131 	 *
    132 	 * @param $valueContext ValueContext
    133 	 */
    134 	public function __construct($valueContext )
    135 	{
    136 		$this->context = $valueContext;
    137 	}
    138 
    139 
    140 
    141 	protected function generate()
    142 	{
    143 		return $this->generateValue();
    144 	}
    145 
    146 
    147 
    148 
    149 	/**
    150 	 * Generating a page value.
    151 	 *
    152 	 * @return string
    153 	 */
    154 	private function generateValue()
    155 	{
    156 		$pageContext = $this->context->pageContext;
    157 		$page = new Page( $pageContext->objectId );
    158 		$page->load();
    159 
    160 		$element = new Element( $this->context->elementid );
    161 		$element->load();
    162 
    163 		$pageContent = new PageContent();
    164 
    165 		$pageContent->pageId     = $page->pageid;
    166 		$pageContent->elementId  = $this->context->elementid;
    167 		$pageContent->languageid = $pageContext->languageId;
    168 		$pageContent->load();
    169 
    170 		$value = new Value();
    171 		$value->contentid = $pageContent->contentId;
    172 
    173 		if   ( $this->context->scheme == Producer::SCHEME_PREVIEW )
    174 			$value->load();
    175 		else
    176 			$value->loadPublished();
    177 
    178 		if	( ! $this->isValueHasContent( $value,$element ) )
    179 		{
    180 			$pageForDefaultValue = $page->getPageAsDefault();
    181 
    182 			if   ( $pageForDefaultValue ) {
    183 
    184 				$pageContext = clone $this->context->pageContext;
    185 				$pageContext->objectId = $pageForDefaultValue->objectid;
    186 
    187 				$valueContext = clone $this->context;
    188 				$valueContext->pageContext = $pageContext;
    189 
    190 				$generator = new ValueGenerator( $valueContext );
    191 
    192 				return $generator->getCache()->get();
    193 			}
    194 		}
    195 
    196 		$inhalt = '';
    197 
    198 		switch( $element->typeid )
    199 		{
    200 			case Element::ELEMENT_TYPE_INSERT:
    201 
    202 				$objectid = $value->linkToObjectId;
    203 
    204 				if   ( ! $objectid )
    205 					$objectid = $element->defaultObjectId;
    206 
    207 				if	( ! BaseObject::available( $objectid) )
    208 					break;
    209 
    210 				$inhalt = $this->generatePageValue( $pageContext,$element,$objectid );
    211 
    212 				if	( false&& $value->publisher->isSimplePreview() )
    213 				{
    214 					$inhalt = strip_tags( $inhalt );
    215 					$inhalt = str_replace( "\n",'',$inhalt );
    216 					$inhalt = str_replace( "\r",'',$inhalt );
    217 				}
    218 
    219 				break;
    220 
    221 
    222 			case Element::ELEMENT_TYPE_LINK:
    223 
    224 				$objectid = $value->linkToObjectId;
    225 				if   ( intval($objectid) == 0 )
    226 					$objectid = $element->defaultObjectId;
    227 
    228 				if   ( $objectid==0 )
    229 				{
    230 					// Link noch nicht gefuellt
    231 					$inhalt = '';
    232 				}
    233 				elseif	 ( ! BaseObject::available($objectid) )
    234 				{
    235 					$inhalt = /*$value->publisher->isSimplePreview()?'-':*/'';
    236 				}
    237 				elseif   ( /*$value->publisher->isSimplePreview()*/false )
    238 				{
    239 					$o = new BaseObject( $objectid );
    240 					$o->load();
    241 					$inhalt = $o->filename;
    242 				}
    243 				elseif	($element->subtype == self::LINK_IMAGE_DATE_URI )
    244 				{
    245 					$context = new FileContext( $objectid,Producer::SCHEME_PUBLIC );
    246 					$generator = new FileGenerator( $context );
    247 					$file = new File($objectid);
    248 					$file->load();
    249 					$inhalt = 'data:'.$generator->getMimeType().';base64,'.base64_encode($generator->getCache()->get());
    250 				}
    251 				else
    252 				{
    253 					$sourcePage = new Page( $pageContext->sourceObjectId ); // the source page
    254 					$target     = new BaseObject( $objectid );
    255 					$target->load();
    256 
    257 					$filteredValue = $this->filterValue( new DslObject($target), $element->code );
    258 
    259 					if   ( is_string($filteredValue) ) {
    260 						$inhalt = $filteredValue;
    261 					}
    262 					else {
    263 						$linkScheme = $pageContext->getLinkScheme();
    264 						$inhalt     = $linkScheme->linkToObject( $sourcePage, $target );
    265 					}
    266 				}
    267 
    268 				break;
    269 
    270 
    271 			case Element::ELEMENT_TYPE_COPY:
    272 
    273 				list($linkElementName,$targetElementName) = explode('%',$element->name.'%');
    274 
    275 				if	( empty($targetElementName) )
    276 					break;
    277 
    278 				// TODO: missing element-id
    279 				$element = new Element();
    280 				$element->name = $linkElementName;
    281 				$element->load();
    282 
    283 				if	( intval($element->elementid)==0 )
    284 					break;
    285 
    286 				// TODO: does not work
    287 				$linkValue = new Value();
    288 				$linkValue->load();
    289 
    290 				if	( !BaseObject::available( $linkValue->linkToObjectId ) )
    291 					break;
    292 
    293 				$linkedPage = new Page( $linkValue->linkToObjectId );
    294 				$linkedPage->load();
    295 
    296 				$linkedPageTemplate = new Template( $linkedPage->templateid );
    297 				$targetElementId = array_search( $targetElementName, $linkedPageTemplate->getElementNames() );
    298 
    299 				if	( intval($targetElementId)==0 )
    300 					break;
    301 
    302 				$valueContext = new ValueContext( $pageContext );
    303 				$valueContext->elementid = $targetElementId;
    304 
    305 				$value = new ValueGenerator($valueContext);
    306 				$inhalt = $value->getCache()->get();
    307 
    308 				break;
    309 
    310 
    311 			case Element::ELEMENT_TYPE_LINKINFO:
    312 
    313 				@list( $linkElementName, $name ) = explode('%',$element->name);
    314 				if	( is_null($name) )
    315 					break;
    316 
    317 				$template = new Template( $page->templateid );
    318 				$elementId = array_search( $linkElementName, $template->getElementNames() );
    319 
    320 				$linkedElement = new Element($elementId);
    321 				$linkedElement->load();
    322 
    323 				$pageContent = new PageContent();
    324 				$pageContent->pageId     = $page->pageid;
    325 				$pageContent->languageid = $pageContext->languageId;
    326 				$pageContent->elementId  = $elementId;
    327 				$pageContent->load();
    328 
    329 				$linkValue = new Value();
    330 				$linkValue->contentid = $pageContent->contentId;
    331 				$linkValue->load();
    332 
    333 				$objectid = $linkValue->linkToObjectId;
    334 
    335 				if   ( intval($objectid) == 0 )
    336 					$objectid = $element->defaultObjectId;
    337 
    338 				if	( !BaseObject::available( $objectid ) )
    339 					break;
    340 
    341 				$linkedObject = new BaseObject( $objectid );
    342 				$linkedObject->load();
    343 
    344 				switch( $linkedElement->subtype )
    345 				{
    346 					case self::LINKINFO_WIDTH:
    347 						$f = new Image( $objectid );
    348 						$f->load();
    349 						if	( $f->typeid == BaseObject::TYPEID_IMAGE )
    350 						{
    351 							$f->getImageSize();
    352 							$inhalt = $f->width;
    353 						}
    354 						unset($f);
    355 						break;
    356 
    357 					case self::LINKINFO_HEIGHT:
    358 						$f = new Image( $objectid );
    359 						$f->load();
    360 						if	( $f->typeid == BaseObject::TYPEID_IMAGE )
    361 						{
    362 							$f->getImageSize();
    363 							$inhalt = $f->height;
    364 						}
    365 						unset($f);
    366 						break;
    367 
    368 					case self::LINKINFO_ID:
    369 						$inhalt = $objectid;
    370 						break;
    371 
    372 					case self::LINKINFO_NAME:
    373 						$inhalt = $linkedObject->getDefaultName()->getName();
    374 						break;
    375 
    376 					case self::LINKINFO_DESCRIPTION:
    377 						$inhalt = $linkedObject->getDefaultName()->description;
    378 						break;
    379 
    380 					case self::INFO_CREATION_DESC:
    381 						$user = $linkedObject->createUser;
    382 						try
    383 						{
    384 							$user->load();
    385 							$inhalt = $user->desc;
    386 						}
    387 						catch( ObjectNotFoundException $e )
    388 						{
    389 						}
    390 						break;
    391 
    392 					case self::INFO_CREATION_FULLNAME:
    393 						$user = $linkedObject->createUser;
    394 						try
    395 						{
    396 							$user->load();
    397 							$inhalt = $user->fullname;
    398 						}
    399 						catch( ObjectNotFoundException $e )
    400 						{
    401 						}
    402 						break;
    403 
    404 					case self::INFO_CREATION_MAIL:
    405 						$user = $linkedObject->createUser;
    406 						try
    407 						{
    408 							$user->load();
    409 							$inhalt = $user->mail;
    410 						}
    411 						catch( ObjectNotFoundException $e )
    412 						{
    413 						}
    414 						break;
    415 
    416 					case self::INFO_CREATION_TEL:
    417 						$user = $linkedObject->createUser;
    418 						try
    419 						{
    420 							$user->load();
    421 							$inhalt = $user->tel;
    422 						}
    423 						catch( ObjectNotFoundException $e )
    424 						{
    425 						}
    426 						break;
    427 
    428 					case self::INFO_CREATION_USER_USERNAME:
    429 						$user = $linkedObject->createUser;
    430 						try
    431 						{
    432 							$user->load();
    433 							$inhalt = $user->name;
    434 						}
    435 						catch( ObjectNotFoundException $e )
    436 						{
    437 						}
    438 						break;
    439 
    440 					case self::INFO_LASTCHANGE_USER_DESC:
    441 						$user = $linkedObject->lastchangeUser;
    442 						try
    443 						{
    444 							$user->load();
    445 							$inhalt = $user->desc;
    446 						}
    447 						catch( ObjectNotFoundException $e )
    448 						{
    449 						}
    450 						break;
    451 
    452 					case self::INFO_LASTCHANGE_USER_FULLNAME:
    453 						$user = $linkedObject->lastchangeUser;
    454 						try
    455 						{
    456 							$user->load();
    457 							$inhalt = $user->fullname;
    458 						}
    459 						catch( ObjectNotFoundException $e )
    460 						{
    461 						}
    462 						break;
    463 
    464 					case self::INFO_LASTCHANGE_USER_MAIL:
    465 						$user = $linkedObject->lastchangeUser;
    466 						try
    467 						{
    468 							$user->load();
    469 							$inhalt = $user->mail;
    470 						}
    471 						catch( ObjectNotFoundException $e )
    472 						{
    473 						}
    474 						break;
    475 
    476 					case self::INFO_LASTCHANGE_USER_TEL:
    477 						$user = $linkedObject->lastchangeUser;
    478 						try
    479 						{
    480 							$user->load();
    481 							$inhalt = $user->tel;
    482 						}
    483 						catch( ObjectNotFoundException $e )
    484 						{
    485 						}
    486 
    487 						break;
    488 
    489 					case self::INFO_LASTCHANGE_USER_USERNAME:
    490 						$user = $linkedObject->lastchangeUser;
    491 						try
    492 						{
    493 							$user->load();
    494 							$inhalt = $user->name;
    495 						}
    496 						catch( ObjectNotFoundException $e )
    497 						{
    498 						}
    499 						break;
    500 
    501 					case self::LINKINFO_MIME_TYPE:
    502 						if	( $linkedObject->isFile || $linkedObject->isImage || $linkedObject->isText  )
    503 						{
    504 							$context = new FileContext( $objectid,Producer::SCHEME_PUBLIC );
    505 							$generator = new FileGenerator( $context );
    506 							$inhalt = $generator->getMimeType();
    507 							unset($f);
    508 						}
    509 						break;
    510 
    511 					case self::INFO_FILENAME:
    512 						$inhalt = $linkedObject->filename();
    513 						break;
    514 
    515 					case self::INFO_FULL_FILENAME:
    516 						$inhalt = $linkedObject->full_filename();
    517 						break;
    518 
    519 					default:
    520 						$inhalt = '';
    521 						Logger::warn('Subtype \''.$linkedElement->subtype.'\' for element \''.$linkedElement.'\' not implemented'); // should not happen
    522 				}
    523 
    524 				break;
    525 
    526 			case Element::ELEMENT_TYPE_LINKDATE:
    527 
    528 				@list( $linkElementName, $name ) = explode('%',$element->name);
    529 				if	( is_null($name) )
    530 					break;
    531 
    532 				$template = new Template( $page->templateid );
    533 				$elementId = array_search( $linkElementName, $template->getElementNames() );
    534 
    535 				$element = new Element($elementId);
    536 				$element->load();
    537 
    538 				$pageContent = new PageContent();
    539 				$pageContent->pageId     = $page->pageid;
    540 				$pageContent->languageid = $pageContext->languageId;
    541 				$pageContent->elementId  = $elementId;
    542 				$pageContent->load();
    543 
    544 				$linkValue = new Value();
    545 				$linkValue->contentid = $pageContent->contentId;
    546 				$linkValue->load();
    547 
    548 				$objectid = $linkValue->linkToObjectId;
    549 
    550 				if   ( intval($objectid) == 0 )
    551 					$objectid = $element->defaultObjectId;
    552 
    553 				if	( !BaseObject::available( $objectid ) )
    554 					break;
    555 
    556 				$linkedObject = new BaseObject( $objectid );
    557 				$linkedObject->load();
    558 
    559 
    560 				switch( $element->subtype )
    561 				{
    562 					case self::INFO_DATE_PUBLISHED:
    563 						// START_TIME wird zu Beginn im Controller gesetzt.
    564 						// So erh�lt jede Datei das gleiche Ver�ffentlichungsdatum.
    565 						$date = Startup::getStartTime();
    566 						break;
    567 
    568 					case self::INFO_DATE_SAVED:
    569 						$date = $linkedObject->lastchangeDate;
    570 						break;
    571 
    572 					case self::INFO_DATE_CREATED:
    573 						$date = $linkedObject->createDate;
    574 						break;
    575 
    576 					default:
    577 						Logger::warn('element:'.$element->name.', '.
    578 							'type:'.$element->typeid.', '.
    579 							'unknown subtype:'.$element->subtype);
    580 						$date = Startup::getStartTime();
    581 				}
    582 
    583 				if	( strpos($element->dateformat,'%')!==FALSE )
    584 					$inhalt = strftime( $element->dateformat,$date );
    585 				else
    586 					$inhalt = date    ( $element->dateformat,$date );
    587 
    588 				$inhalt = $this->filterValue( $inhalt, $element->code );
    589 
    590 				break;
    591 
    592 			case Element::ELEMENT_TYPE_LONGTEXT:
    593 			case Element::ELEMENT_TYPE_TEXT:
    594 			case Element::ELEMENT_TYPE_SELECT:
    595 
    596 				$inhalt = $value->text;
    597 				$format = $value->format;
    598 
    599 				// Wenn Inhalt leer, dann versuchen, den Inhalt der Default-Sprache zu laden.
    600 				if   ( $inhalt == '' && Configuration::subset(['content','language'])->is('use_default_language',true) )
    601 				{
    602 					$project = new Project($page->projectid);
    603 
    604 					$otherPageContent = new PageContent();
    605 					$otherPageContent->elementId  = $pageContent->elementId;
    606 					$otherPageContent->pageId     = $pageContent->pageId;
    607 					$otherPageContent->languageid = $project->getDefaultLanguageId();
    608 					$otherPageContent->load();
    609 
    610 					if   ( $otherPageContent->isPersistent() ) {
    611 						$otherValue = new Value();
    612 						$otherValue->contentid = $pageContent->contentId;
    613 						$otherValue->load();
    614 						$inhalt = $otherValue->text;
    615 					}
    616 				}
    617 
    618 				// Wenn Inhalt leer, dann Vorbelegung verwenden
    619 				if   ( $inhalt == '' )  {
    620 
    621 					$inhalt = $element->defaultText;
    622 					$format = $element->format;
    623 				}
    624 
    625 				// Wenn HTML nicht erlaubt und Wiki-Formatierung aktiv, dann einfache HTML-Tags in Wiki umwandeln
    626 				$pageIsHtml = $this->isHtml( (new PageGenerator( $this->context->pageContext ))->getMimeType());
    627 
    628 				//
    629 				switch( $format )
    630 				{
    631 					case Element::ELEMENT_FORMAT_TEXT:
    632 					case Element::ELEMENT_FORMAT_HTML:
    633 
    634 						if   ( !$element->html )
    635 						{
    636 							// HTML not allowed.
    637 							$inhalt = Text::encodeHtml( $inhalt );
    638 							$inhalt = Text::encodeHtmlSpecialChars( $inhalt );
    639 						}
    640 
    641 						break;
    642 
    643 					case Element::ELEMENT_FORMAT_WIKI:
    644 
    645 						$wikiConfig = C::subset('editor')->subset('wiki');
    646 
    647 						if   ( $wikiConfig->is('convert_bbcode',false ) )
    648 							$inhalt = Text::bbCode2Wiki( $inhalt );
    649 
    650 						if   ( !$element->html && $wikiConfig->is('convert_html',true) && $pageIsHtml)
    651 							$inhalt = Text::html2Wiki( $inhalt );
    652 
    653 						$transformer = new Transformer();
    654 						$transformer->text    = $inhalt;
    655 						$transformer->page    = $page;
    656 						$transformer->pageContext = $pageContext;
    657 						$transformer->element = $element;
    658 
    659 						$transformer->transform();
    660 						$inhalt = $transformer->text;
    661 						break;
    662 
    663 					case Element::ELEMENT_FORMAT_MARKDOWN:
    664 
    665 						$mdConfig = C::Conf()->subset('editor')->subset('markdown');
    666 
    667 						$parser = new \util\Parsedown();
    668 						$parser->setUrlsLinked( $mdConfig->is('urls-linked',true));
    669 						$parser->setMarkupEscaped( !$element->html );
    670 
    671 						$inhalt = $parser->parse( $inhalt );
    672 						break;
    673 
    674 					default:
    675 						throw new \LogicException('Unknown format: '.$value->format );
    676 				}
    677 
    678 				/*if   ( $value->publisher->isSimplePreview() )
    679 				{
    680 					// Simple Preview with bare text.
    681 					$inhalt = strip_tags( $inhalt );
    682 					$inhalt = str_replace( "\n",'',$inhalt );
    683 					$inhalt = str_replace( "\r",'',$inhalt );
    684 				}*/
    685 
    686 				// "__OID__nnn__" ersetzen durch einen richtigen Link
    687 				foreach( Text::parseOID($inhalt) as $oid=>$t )
    688 				{
    689 					$linkFormat = $pageContext->getLinkScheme();
    690 					$target = new BaseObject($oid);
    691 					$target->load();
    692 
    693 					$sourcePage = new Page( $pageContext->sourceObjectId );
    694 					$url        = $linkFormat->linkToObject($sourcePage,$target);
    695 
    696 					foreach( $t as $match )
    697 						$inhalt = str_replace($match,$url,$inhalt);
    698 				}
    699 
    700 			switch ($element->typeid) {
    701 
    702 				case Element::ELEMENT_TYPE_TEXT:
    703 				case Element::ELEMENT_TYPE_LONGTEXT:
    704 
    705 					$inhalt = $this->filterValue($inhalt, $element->code);
    706 					break;
    707 
    708 				case Element::ELEMENT_TYPE_SELECT:
    709 					// not for selects, because the code contains the select items.
    710 				default:
    711 			}
    712 
    713 			break;
    714 
    715 
    716 			// Zahl
    717 			//
    718 			// wird im entsprechenden Format angezeigt.
    719 			case Element::ELEMENT_TYPE_CHECKBOX:
    720 
    721 				$inhalt = boolval($value->number);
    722 
    723 				$inhalt = $this->filterValue( $inhalt, $element->code );
    724 
    725 				break;
    726 
    727 			case Element::ELEMENT_TYPE_NUMBER:
    728 
    729 
    730 				if   ( $value->number == 0 )
    731 				{
    732 					// Zahl ist gleich 0, dann Default-Text
    733 					$inhalt = $element->defaultText;
    734 					break;
    735 				}
    736 
    737 				$number = $value->number / pow(10,$element->decimals);
    738 				$inhalt = number_format( $number,$element->decimals,$element->decPoint,$element->thousandSep );
    739 
    740 
    741 				$inhalt = $this->filterValue( $inhalt, $element->code );
    742 
    743 				break;
    744 
    745 
    746 			// Datum
    747 			case Element::ELEMENT_TYPE_DATE:
    748 
    749 				$date = $value->date;
    750 
    751 				if   ( intval($date) == 0 )
    752 				{
    753 					// Datum wurde noch nicht eingegeben
    754 					$inhalt = $element->defaultText;
    755 					break;
    756 				}
    757 
    758 				// Datum gemaess Elementeinstellung formatieren
    759 				if	( strpos($element->dateformat,'%')!==FALSE )
    760 					$inhalt = strftime( $element->dateformat,$date );
    761 				else
    762 					$inhalt = date    ( $element->dateformat,$date );
    763 
    764 				$inhalt = $this->filterValue( $inhalt, $element->code );
    765 
    766 				break;
    767 
    768 
    769 			// Programmcode (PHP)
    770 			case Element::ELEMENT_TYPE_CODE:
    771 
    772 				switch( $element->subtype ) {
    773 					case self::CODE_PHP:
    774 						// Die Ausführung von benutzer-erzeugtem PHP-Code kann in der
    775 						// Konfiguration aus Sicherheitsgründen deaktiviert sein.
    776 						if	( Configuration::subset('security')->is('disable_dynamic_code',false) )
    777 						{
    778 							Logger::warn("Execution of dynamic code elements is disabled by configuration. Set security/disable_dynamic_code to true to allow this");
    779 							break;
    780 						}
    781 
    782 						$page->load();
    783 
    784 						// Das Ausführen geschieht über die Klasse "Code".
    785 						// In dieser wird der Code in eine Datei geschrieben und
    786 						// von dort eingebunden.
    787 						$code = new Code();
    788 						$code->setPageContext($this->context->pageContext );
    789 						$code->code = $element->code;
    790 
    791 						ob_start();
    792 
    793 						// Jetzt ausfuehren des temporaeren PHP-Codes
    794 						$code->execute();
    795 
    796 						$output = ob_get_contents();
    797 						ob_end_clean();
    798 
    799 						// Ausgabe ermitteln.
    800 						$inhalt = $output;
    801 						break;
    802 
    803 					case self::CODE_SCRIPT:
    804 						$executor = new DslInterpreter(DslInterpreter::FLAG_THROW_ERROR + DslInterpreter::FLAG_SECURE );
    805 						$executor->addContext( [
    806 							'console'  => new DslConsole(),
    807 							'cms'      => new DslCms(),
    808 							'http'     => new DslHttp(),
    809 							'json'     => new DslJson(),
    810 							'page'     => new DslObject( $page ),
    811 							'context'  => new DslPageContext( $pageContext ),
    812 							'project'  => new DslProject( $page->getProject() ),
    813 							'Mqtt'     => new class extends BaseScriptableObject {
    814 								public static function open( $url,$user,$password ) {
    815 									return new DslMqtt( $url,$user,$password );
    816 								}
    817 							}
    818 							,
    819 						]);
    820 
    821 						try {
    822 							$executor->runCode( $element->code );
    823 						}
    824 						catch( DslException $e ) {
    825 							Logger::warn( $e );
    826 							if   ( $pageContext->scheme == Producer::SCHEME_PREVIEW )
    827 								$inhalt = $e->getMessage();
    828 							break;
    829 						}
    830 
    831 						// Ausgabe ermitteln.
    832 						$inhalt = $executor->getOutput();
    833 
    834 						break;
    835 					case self::CODE_MUSTACHE:
    836 						// TODO
    837 					default:
    838 				}
    839 
    840 
    841 				break;
    842 
    843 
    844 			// Makros (dynamische Klassen)
    845 			case Element::ELEMENT_TYPE_DYNAMIC:
    846 
    847 				/*if   ( $value->publisher->isSimplePreview() )
    848 					break;*/
    849 
    850 				$page->load();
    851 				$macroName     = $element->subtype;
    852 				$macroSettings = $element->getDynamicParameters();
    853 
    854 				$runner = new MacroRunner();
    855 				try {
    856 					$inhalt .= $runner->executeMacro( $macroName, $macroSettings,$page, $pageContext );
    857 				}
    858 				catch( \Exception $e ) {
    859 					throw new GeneratorException("Macro ".$macroName.' in value '.$value->__toString().' could not executed',$e);
    860 				}
    861 
    862 				// Wenn HTML-Ausgabe, dann Sonderzeichen in HTML �bersetzen
    863 				if   ( $this->isHtml( (new PageGenerator( $this->context->pageContext ))->getMimeType()))
    864 					$inhalt = Text::encodeHtmlSpecialChars( $inhalt );
    865 
    866 				break;
    867 
    868 
    869 			// Info-Feld als Datum
    870 			case Element::ELEMENT_TYPE_INFODATE:
    871 
    872 				/*if   ( $value->publisher->isSimplePreview() )
    873 					break;*/
    874 
    875 				switch( $element->subtype )
    876 				{
    877 					case self::INFO_DATE_PUBLISHED:
    878 						// START_TIME wird zu Beginn im Controller gesetzt.
    879 						// So erh�lt jede Datei das gleiche Ver�ffentlichungsdatum.
    880 						$date = Startup::getStartTime();
    881 						break;
    882 
    883 					case self::INFO_DATE_SAVED:
    884 						$date = $page->lastchangeDate;
    885 						break;
    886 
    887 					case self::INFO_DATE_CREATED:
    888 						$date = $page->createDate;
    889 						break;
    890 
    891 					default:
    892 						throw new PublisherException('element:'.$element->name.', '.
    893 							'type:'.$element->type.', '.
    894 							'unknown subtype:'.$element->subtype);
    895 						/*if	( !$value->publisher->isPublic() )
    896 							$inhalt = \cms\base\Language::lang('ERROR_IN_ELEMENT');*/
    897 				}
    898 
    899 				if	( strpos($element->dateformat,'%')!==FALSE )
    900 					$inhalt = strftime( $element->dateformat,$date );
    901 				else
    902 					$inhalt = date    ( $element->dateformat,$date );
    903 
    904 				$inhalt = $this->filterValue( $inhalt, $element->code );
    905 
    906 				break;
    907 
    908 
    909 			// Info-Feld
    910 			case Element::ELEMENT_TYPE_INFO:
    911 
    912 				/*if   ( $value->publisher->isSimplePreview() )
    913 					break;*/
    914 
    915 				switch( $element->subtype )
    916 				{
    917 					case self::INFO_DB_ID:
    918 						$inhalt = DB::get()->id;
    919 						break;
    920 					case self::INFO_DB_NAME:
    921 						$inhalt = @DB::get()->getLabel();
    922 						break;
    923 					case self::INFO_PROJECT_ID:
    924 						$inhalt = $page->projectid;
    925 						break;
    926 					case self::INFO_PROJECT_NAME:
    927 						$inhalt = Project::create( $page->projectid )->load()->name;
    928 						break;
    929 					case self::INFO_LANGUAGE_ID:
    930 						$inhalt = $pageContext->languageId;
    931 						break;
    932 					case self::INFO_LANGUAGE_ISO:
    933 						$language = new Language( $pageContext->languageId );
    934 						$language->load();
    935 						$inhalt = $language->isoCode;
    936 						break;
    937 					case self::INFO_LANGUAGE_NAME:
    938 						$language = new Language( $pageContext->languageId );
    939 						$language->load();
    940 						$inhalt = $language->name;
    941 						break;
    942 					case self::INFO_PAGE_ID:
    943 						$inhalt = $page->objectid;
    944 						break;
    945 					case self::INFO_PAGE_NAME:
    946 						$inhalt = $page->getNameForLanguage( $pageContext->languageId )->name;
    947 						break;
    948 					case self::INFO_PAGE_DESC:
    949 						$inhalt = $page->getNameForLanguage( $pageContext->languageId )->description;
    950 						break;
    951 					case self::INFO_PAGE_FULLFILENAME:
    952 						$inhalt = $this->getPublicFilename();
    953 						break;
    954 					case self::INFO_PAGE_FILENAME:
    955 						$inhalt = $page->filename();
    956 						break;
    957 					case self::INFO_PAGE_EXTENSION:
    958 						$inhalt = '';
    959 						break;
    960 					case self::INFO_EDIT_URL:
    961 						$raw = true;
    962 						$inhalt = Html::locationUrl('page',$page->objectid );
    963 						break;
    964 					case self::INFO_EDIT_FULLURL:
    965 						$raw = true;
    966 						$inhalt = Http::getServer();
    967 
    968 						$inhalt .= Html::locationUrl('page',$page->objectid );
    969 						break;
    970 					case self::INFO_LASTCHANGE_USER_USERNAME:
    971 						$user = $page->lastchangeUser;
    972 						if   ( $user->userid )
    973 							$user->load();
    974 						$inhalt = $user->name;
    975 						break;
    976 					case self::INFO_LASTCHANGE_USER_FULLNAME:
    977 						$user = $page->lastchangeUser;
    978 						if   ( $user->userid )
    979 							$user->load();
    980 						$inhalt = $user->fullname;
    981 						break;
    982 					case self::INFO_LASTCHANGE_USER_MAIL:
    983 						$user = $page->lastchangeUser;
    984 						if   ( $user->userid )
    985 							$user->load();
    986 						$inhalt = $user->mail;
    987 						break;
    988 					case self::INFO_LASTCHANGE_USER_DESC:
    989 						$user = $page->lastchangeUser;
    990 						if   ( $user->userid )
    991 							$user->load();
    992 						$inhalt = $user->desc;
    993 						break;
    994 					case self::INFO_LASTCHANGE_USER_TEL:
    995 						$user = $page->lastchangeUser;
    996 						if   ( $user->userid )
    997 							$user->load();
    998 						$inhalt = $user->tel;
    999 						break;
   1000 
   1001 					case self::INFO_CREATION_USER_USERNAME:
   1002 						$user = $page->createUser;
   1003 						if   ( $user->userid )
   1004 							$user->load();
   1005 						$inhalt = $user->name;
   1006 						break;
   1007 					case self::INFO_CREATION_FULLNAME:
   1008 						$user = $page->createUser;
   1009 						if   ( $user->userid )
   1010 							$user->load();
   1011 						$inhalt = $user->fullname;
   1012 						break;
   1013 					case self::INFO_CREATION_MAIL:
   1014 						$user = $page->createUser;
   1015 						if   ( $user->userid )
   1016 							$user->load();
   1017 						$inhalt = $user->mail;
   1018 						break;
   1019 					case self::INFO_CREATION_DESC:
   1020 						$user = $page->createUser;
   1021 						if   ( $user->userid )
   1022 							$user->load();
   1023 						$inhalt = $user->desc;
   1024 						break;
   1025 					case self::INFO_CREATION_TEL:
   1026 						$user = $page->createUser;
   1027 						if   ( $user->userid )
   1028 							$user->load();
   1029 						$inhalt = $user->tel;
   1030 						break;
   1031 
   1032 					case self::INFO_ACT_USERNAME:
   1033 						$user = Request::getUser();
   1034 						if   ( $user )
   1035 							$inhalt = $user->name;
   1036 						break;
   1037 					case self::INFO_ACT_FULLNAME:
   1038 						$user = Request::getUser();
   1039 						if   ( $user )
   1040 							$inhalt = $user->fullname;
   1041 						break;
   1042 					case self::INFO_ACT_MAIL:
   1043 						$user = Request::getUser();
   1044 						if   ( $user )
   1045 							$inhalt = $user->mail;
   1046 						break;
   1047 					case self::INFO_ACT_DESC:
   1048 						$user = Request::getUser();
   1049 						if   ( $user )
   1050 							$inhalt = $user->desc;
   1051 						break;
   1052 					case self::INFO_ACT_TEL:
   1053 						$user = Request::getUser();
   1054 						if   ( $user )
   1055 							$inhalt = $user->tel;
   1056 						break;
   1057 					default:
   1058 						Logger::warn('element:'.$element->name.', '.
   1059 							'type:'.$element->getTypeName().', '.
   1060 							'unknown subtype:'.$element->subtype);
   1061 					// Keine Fehlermeldung in erzeugte Seite schreiben.
   1062 				}
   1063 
   1064 				break;
   1065 
   1066 			case Element::ELEMENT_TYPE_COORD:
   1067 				$inhalt = $value->text;
   1068 				$inhalt = $this->filterValue( $inhalt, $element->code );
   1069 
   1070 				break;
   1071 
   1072 			case Element::ELEMENT_TYPE_DATA:
   1073 
   1074 				try {
   1075 					$data = YAML::parse( $value->text );
   1076 				} catch ( \Exception $e ) {
   1077 					if   ( $this->context->pageContext->scheme == Producer::SCHEME_PREVIEW )
   1078 						$inhalt = 'Invalid YAML: '.$e->getMessage();
   1079 					break;
   1080 				}
   1081 
   1082 				$inhalt = $this->filterValue( new Data($data), $element->code );
   1083 
   1084 				if   ( is_array($inhalt) )
   1085 					$inhalt = YAML::dump( $inhalt );
   1086 
   1087 				break;
   1088 			default:
   1089 				// this should never happen in production.
   1090 				// inform the user.
   1091 				throw new GeneratorException( 'Error in element '.$element->name.': '.
   1092 					'unknown type: '.$element->typeid.'');
   1093 
   1094 		}
   1095 
   1096 
   1097 		switch( $element->typeid )
   1098 		{
   1099 			case Element::ELEMENT_TYPE_LONGTEXT:
   1100 			case Element::ELEMENT_TYPE_TEXT:
   1101 			case Element::ELEMENT_TYPE_SELECT:
   1102 
   1103 				if	( Configuration::subset('publish')->is('encode_utf8_in_html') )
   1104 					// Wenn HTML-Ausgabe, dann UTF-8-Zeichen als HTML-Code uebersetzen
   1105 					if   ( $this->isHtml( (new PageGenerator( $this->context->pageContext ))->getMimeType()) )
   1106 						$inhalt = Text::translateutf8tohtml($inhalt);
   1107 				break;
   1108 
   1109 			default:
   1110 		}
   1111 
   1112 
   1113 
   1114 		if   ( $this->context->pageContext->scheme == Producer::SCHEME_PREVIEW && $element->withIcon && $this->isHtml( (new PageGenerator( $this->context->pageContext ))->getMimeType()) )
   1115 		{
   1116 			// Anklickbaren Link voranstellen.
   1117 			$iconLink = '<a href="javascript:parent.Openrat.Workbench.openNewAction(\''.$element->name.'\',\'pageelement\',\''.$page->objectid.'_'.$element->elementid.'\');" title="'.$element->desc.'">&rarr;<i class="or-image-icon or-image-icon--el-'.$element->getTypeName().'"></i></a>';
   1118 			$inhalt   = $iconLink.$inhalt;
   1119 		}
   1120 
   1121 		return $inhalt;
   1122 	}
   1123 
   1124 
   1125 	/**
   1126 	 * Determines if the value has meaningful content
   1127 	 *
   1128 	 * @param $value Value
   1129 	 */
   1130 	protected function isValueHasContent( $value,$element ) {
   1131 
   1132 		return in_array($element->typeid,[
   1133 				Element::ELEMENT_TYPE_TEXT,
   1134 				Element::ELEMENT_TYPE_LONGTEXT,
   1135 				Element::ELEMENT_TYPE_SELECT,
   1136 				Element::ELEMENT_TYPE_DATA,
   1137 				Element::ELEMENT_TYPE_COORD,
   1138 			]) && $value->text != '' && $value->text != null ||
   1139 			in_array($element->typeid,[
   1140 				Element::ELEMENT_TYPE_NUMBER
   1141 			]) && $value->number != null ||
   1142 			in_array($element->typeid,[
   1143 				Element::ELEMENT_TYPE_LINK,
   1144 				Element::ELEMENT_TYPE_INSERT,
   1145 			]) && $value->linkToObjectId != null && $value->linkToObjectId != 0 ||
   1146 			in_array($element->typeid,[
   1147 				Element::ELEMENT_TYPE_DATE,
   1148 			]) && $value->date != null && $value->date != 0 ||
   1149 			in_array($element->typeid,[
   1150 				Element::ELEMENT_TYPE_CODE,
   1151 				Element::ELEMENT_TYPE_COPY,
   1152 				Element::ELEMENT_TYPE_DYNAMIC,
   1153 				Element::ELEMENT_TYPE_INFO,
   1154 				Element::ELEMENT_TYPE_INFODATE,
   1155 				Element::ELEMENT_TYPE_LINKDATE,
   1156 				Element::ELEMENT_TYPE_LINKINFO,
   1157 			]);
   1158 	}
   1159 
   1160 
   1161 	/**
   1162 	 * A pure value does not have a public filename. Therefor, this method returns nothing.
   1163 	 * @return string
   1164 	 */
   1165 	public function getPublicFilename()
   1166 	{
   1167 		return null;
   1168 	}
   1169 
   1170 
   1171 	/**
   1172 	 * @return string always blank
   1173 	 */
   1174 	public function getMimeType()
   1175 	{
   1176 		return ''; // Values does not have a mime type.
   1177 	}
   1178 
   1179 
   1180 	protected function isHtml( $mimeType )
   1181 	{
   1182 		return $mimeType == 'text/html';
   1183 	}
   1184 
   1185 	/**
   1186 	 * @param $inhalt mixed
   1187 	 * @param $code string
   1188 	 * @return mixed|string
   1189 	 */
   1190 	protected function filterValue( $inhalt, $code)
   1191 	{
   1192 		$executor = new DslInterpreter(DslInterpreter::FLAG_THROW_ERROR + DslInterpreter::FLAG_SECURE );
   1193 
   1194 		$executor->addContext( [
   1195 			'page'     => new DslObject( (new BaseObject($this->context->pageContext->objectId))->load() ),
   1196 			'context'  => new DslPageContext( $this->context->pageContext ),
   1197 			'project'  => new DslProject( (new BaseObject($this->context->pageContext->objectId))->load()->getProject() ),
   1198 			'console'  => new DslConsole(),
   1199 			'cms'      => new DslCms(),
   1200 			'value'    => $inhalt,
   1201 			'http'     => new DslHttp(),
   1202 			'json'     => new DslJson(),
   1203 		]);
   1204 
   1205 		try {
   1206 			$executor->runCode( $code );
   1207 			$result = $executor->getOutput();
   1208 		}
   1209 		catch( DslException $e ) {
   1210 			Logger::warn($e);
   1211 			if   ( $this->context->pageContext->scheme == Producer::SCHEME_PREVIEW )
   1212 				return $e->getMessage();
   1213 			else
   1214 				return '';
   1215 		}
   1216 
   1217 		if   ( $result != null )
   1218 			return $result;
   1219 		else
   1220 			return $inhalt;
   1221 	}
   1222 
   1223 	/**
   1224 	 * @param $pageContext PageContext
   1225 	 * @param $element Element
   1226 	 * @param $oid integer
   1227 	 * @return string
   1228 	 */
   1229 	protected function generatePageValue($pageContext, $element, $oid ) {
   1230 
   1231 		$o = new BaseObject( $oid );
   1232 		$o->load();
   1233 
   1234 		switch( $o->typeid )
   1235 		{
   1236 			case BaseObject::TYPEID_FOLDER:
   1237 				$f = new Folder( $oid );
   1238 				$value = '';
   1239 				foreach( $f->getObjectIds() as $childOid ) {
   1240 					$value .= $this->generatePageValue( $pageContext,$element,$childOid );
   1241 				}
   1242 				return $value;
   1243 
   1244 			case BaseObject::TYPEID_PAGE:
   1245 
   1246 				$subtype = $element->subtype;
   1247 				if   ( $pageContext->scheme == Producer::SCHEME_PREVIEW )
   1248 					$subtype = null; // In preview the SSI/ESI are not available.
   1249 
   1250 				switch( $subtype )
   1251 				{
   1252 					case ValueGenerator::INSERT_INLINE:
   1253 					default:
   1254 
   1255 						$newPageContext = clone $pageContext;
   1256 						$newPageContext->objectId = $oid;
   1257 						$pageGenerator = new PageGenerator( $newPageContext );
   1258 
   1259 						return $pageGenerator->getCache()->get();
   1260 
   1261 					case ValueGenerator::INSERT_SSI:
   1262 						$linkScheme = $pageContext->getLinkScheme();
   1263 						return '<!--#include virtual="'.$linkScheme->linkToObject( new BaseObject($pageContext->sourceObjectId),(new BaseObject($oid))->load()).'" -->';
   1264 
   1265 					case ValueGenerator::INSERT_ESI:
   1266 						$linkScheme = $pageContext->getLinkScheme();
   1267 						return '<esi:include src="'.$linkScheme->linkToObject( new BaseObject($pageContext->sourceObjectId),(new BaseObject($oid))->load()).'"/>';
   1268 				}
   1269 
   1270 			case BaseObject::TYPEID_LINK:
   1271 				$l = new Link( $oid );
   1272 				$l->load();
   1273 
   1274 				return $this->generatePageValue( $pageContext,$element,$l->linkedObjectId );
   1275 			default:
   1276 				return '';
   1277 		}
   1278 
   1279 	}
   1280 
   1281 }