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.'">→<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 }