openrat-cms

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

TemplateGenerator.class.php (4981B)


      1 <?php
      2 
      3 
      4 namespace cms\generator;
      5 
      6 
      7 use cms\base\Configuration;
      8 use cms\generator\dsl\DslCms;
      9 use cms\generator\dsl\DslConsole;
     10 use cms\generator\dsl\DslHttp;
     11 use cms\generator\dsl\DslJson;
     12 use cms\generator\dsl\DslPage;
     13 use cms\generator\PageContext;
     14 use cms\model\File;
     15 use cms\model\Folder;
     16 use cms\model\Language;
     17 use cms\model\Page;
     18 use cms\model\Project;
     19 use cms\model\Template;
     20 use cms\model\TemplateModel;
     21 use cms\model\Value;
     22 use dsl\DslException;
     23 use dsl\DslTemplate;
     24 use dsl\executor\DslInterpreter;
     25 use logger\Logger;
     26 use util\exception\GeneratorException;
     27 use util\Mustache;
     28 use util\text\TextMessage;
     29 
     30 
     31 class TemplateGenerator
     32 {
     33 
     34 	private $templateId;
     35 	private $modelId;
     36 	private $scheme;
     37 
     38 	public function __construct($templateId, $modelId, $scheme )
     39 	{
     40 		$this->templateId = $templateId;
     41 		$this->modelId = $modelId;
     42 		$this->scheme = $scheme;
     43 	}
     44 
     45 
     46 	/**
     47 	 * Generates the template content.
     48 	 *
     49 	 * @param $data array values
     50 	 * @return String Inhalt
     51 	 */
     52 	public function generateValue( $data )
     53 	{
     54 		$template = new Template( $this->templateId );
     55 		$template->load();
     56 
     57 		// Get a List with ElementId->ElementName
     58 		$elements = array_map(function($element) {
     59 			return $element->name;
     60 		},$template->getElements() );
     61 
     62 		$templatemodel = new TemplateModel( $template->templateid, $this->modelId );
     63 		if   ( $this->scheme == Producer::SCHEME_PREVIEW )
     64 			$templatemodel->load();
     65 		else
     66 			$templatemodel->loadForPublic();
     67 
     68 		$src = $templatemodel->src;
     69 
     70 		// No we are collecting the data and are fixing some old stuff.
     71 
     72 		foreach( $elements as $elementId=>$elementName )
     73 		{
     74 			// The following code is for old template values:
     75 
     76 			// convert {{<id>}} to {{<name>}}
     77 			$src = str_replace( '{{'.$elementId.'}}','{{'.$elementName.'}}',$src );
     78 
     79 			$src = str_replace( '{{IFNOTEMPTY:'.$elementId.':BEGIN}}','{{#'.$elementName.'}}',$src );
     80 			$src = str_replace( '{{IFNOTEMPTY:'.$elementId.':END}}'  ,'{{/'.$elementName.'}}',$src );
     81 			$src = str_replace( '{{IFEMPTY:'   .$elementId.':BEGIN}}','{{^'.$elementName.'}}',$src );
     82 			$src = str_replace( '{{IFEMPTY:'   .$elementId.':END}}'  ,'{{/'.$elementName.'}}',$src );
     83 
     84 			$src = str_replace( '{{->'.$elementId.'}}','',$src );
     85 		}
     86 
     87 		if ( DEVELOPMENT )
     88 			Logger::trace( 'generating template with data: '.print_r($data,true) );
     89 
     90 		// Now we have collected all data, lets call the template engine:
     91 
     92 		$mustache = new Mustache();
     93 		$mustache->escape = null; // No HTML escaping, this is the job of this CMS ;)
     94 		$mustache->partialLoader = function( $name ) use ($template) {
     95 
     96 			if   ( substr($name,0,5) == 'file:') {
     97 				$fileid = intval( substr($name,5) );
     98 				$file = new File( $fileid );
     99 				return $file->loadValue();
    100 			}
    101 
    102 
    103 			$project       = Project::create( $template->projectid );
    104 			$templateid    = array_search($name,$project->getTemplates() );
    105 
    106 			if   ( ! $templateid )
    107 				throw new \InvalidArgumentException( TextMessage::create('template ${name} not found',['name'=>$name]) );
    108 
    109 			if   ( $templateid == $template->templateid )
    110 				throw new \InvalidArgumentException('Template recursion detected on template-id '.$templateid);
    111 
    112 
    113 			$templatemodel = new TemplateModel( $templateid, $this->modelId );
    114 			$templatemodel->load();
    115 
    116 			return $templatemodel->src;
    117 		};
    118 
    119 		try {
    120 			$mustache->parse($src);
    121 		} catch (\Exception $e) {
    122 			// Should we throw it to the caller?
    123 			// No, because it is not a technical error. So let's only log it.
    124 			Logger::warn("Template rendering failed: ".$e->getMessage() );
    125 			return $e->getMessage();
    126 		}
    127 		$src = $mustache->render( $data );
    128 
    129 		// now we have the fully generated source.
    130 
    131 		try {
    132 
    133 			$templateParser = new DslTemplate();
    134 			$templateParser->parseTemplate($src);
    135 			if ($templateParser->tagsFound) {
    136 				$executor = new DslInterpreter( DslInterpreter::FLAG_THROW_ERROR + DslInterpreter::FLAG_SECURE );
    137 				$executor->addContext([
    138 					'console' => new DslConsole(),
    139 					'cms'  => new DslCms(),
    140 					'http' => new DslHttp(),
    141 					'json' => new DslJson(),
    142 				]);
    143 				$executor->addContext( $data );
    144 
    145 				$executor->runCode($templateParser->script);
    146 
    147 				// Ausgabe ermitteln.
    148 				$src = $executor->getOutput();
    149 			}
    150 		} catch (DslException $e) {
    151 			Logger::warn($e);
    152 			$src = $e->getMessage()."\nscript source:\n".$templateParser->script;
    153 		}
    154 
    155 		// should we do a UTF-8-escaping here?
    156 		// Default should be off, because if you are fully using utf-8 (you should do), this is unnecessary.
    157 		if	( Configuration::subset('publish' )->is('escape_8bit_characters') )
    158 			if	( substr($this->mimeType(),-4) == 'html' )
    159 			{
    160 				/*
    161 				 *
    162 				$src = htmlentities($src,ENT_NOQUOTES,'UTF-8');
    163 				$src = str_replace('&lt;' , '<', $src);
    164 				$src = str_replace('&gt;' , '>', $src);
    165 				$src = str_replace('&amp;', '&', $src);
    166 				 */
    167 				$src = translateutf8tohtml($src);
    168 			}
    169 
    170 		return $src;
    171 	}
    172 
    173 
    174 	public function getMimeType()
    175 	{
    176 		$templateModel = new TemplateModel( $this->templateId,$this->modelId );
    177 		$templateModel->load();
    178 
    179 		return $templateModel->mimeType();
    180 	}
    181 }