openrat-cms

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

commit 5d55cbb8f0efe95d9b34be88cde95662aa7a1a8a
parent 360996d7a715e9023c1e82569c2cab594b0d2b21
Author: Jan Dankert <develop@jandankert.de>
Date:   Wed, 25 May 2022 22:47:17 +0200

New: DSL (domain specific language) for code elements. The old way with PHP code ist not sandboxed and unsecure. This approach is a minimalistic, javascript-like, scripting engine. For now only simple function calls are possible, for example: alert("example");

Diffstat:
Mmodules/cms/action/element/ElementAdvancedAction.class.php | 8++++++++
Mmodules/cms/generator/ValueGenerator.class.php | 68+++++++++++++++++++++++++++++++++++++++++++++++---------------------
Amodules/cms/generator/dsl/DslAlert.class.php | 15+++++++++++++++
Amodules/cms/generator/dsl/DslConsole.class.php | 32++++++++++++++++++++++++++++++++
Amodules/cms/generator/dsl/DslDocument.class.php | 13+++++++++++++
Mmodules/cms/model/Element.class.php | 2+-
Amodules/dsl/DslAstParser.class.php | 29+++++++++++++++++++++++++++++
Amodules/dsl/DslLexer.class.php | 197+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/dsl/DslToken.class.php | 46++++++++++++++++++++++++++++++++++++++++++++++
Amodules/dsl/ast/DslAssignment.class.php | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/dsl/ast/DslElement.class.php | 9+++++++++
Amodules/dsl/ast/DslExpression.class.php | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/dsl/ast/DslFor.class.php | 17+++++++++++++++++
Amodules/dsl/ast/DslFunction.class.php | 27+++++++++++++++++++++++++++
Amodules/dsl/ast/DslFunctionCall.class.php | 27+++++++++++++++++++++++++++
Amodules/dsl/ast/DslIf.class.php | 17+++++++++++++++++
Amodules/dsl/ast/DslInitialisation.class.php | 17+++++++++++++++++
Amodules/dsl/ast/DslReturn.class.php | 17+++++++++++++++++
Amodules/dsl/ast/DslStatement.class.php | 13+++++++++++++
Amodules/dsl/ast/DslStatementList.class.php | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/dsl/context/DslFunction.class.php | 8++++++++
Amodules/dsl/context/DslObject.class.php | 9+++++++++
Amodules/dsl/executor/DslExecutor.class.php | 34++++++++++++++++++++++++++++++++++
Mmodules/language/Language_CN.class.php | 5++++-
Mmodules/language/Language_DE.class.php | 5++++-
Mmodules/language/Language_EN.class.php | 5++++-
Mmodules/language/Language_ES.class.php | 5++++-
Mmodules/language/Language_FR.class.php | 5++++-
Mmodules/language/Language_IT.class.php | 5++++-
Mmodules/language/Language_RU.class.php | 5++++-
Mmodules/language/Messages.class.php | 3+++
Mmodules/language/language.yml | 14+++++++++-----
32 files changed, 814 insertions(+), 34 deletions(-)

diff --git a/modules/cms/action/element/ElementAdvancedAction.class.php b/modules/cms/action/element/ElementAdvancedAction.class.php @@ -105,6 +105,14 @@ class ElementAdvancedAction extends ElementAction implements Method { $convertToLang = true; break; + case Element::ELEMENT_TYPE_CODE: + $subtypes = [ + 'php', + 'js', + ]; + $convertToLang = true; + break; + case Element::ELEMENT_TYPE_LINKINFO: $subtypes = Array('width', 'height', diff --git a/modules/cms/generator/ValueGenerator.class.php b/modules/cms/generator/ValueGenerator.class.php @@ -8,6 +8,9 @@ use cms\base\Configuration; use cms\base\Configuration as C; use cms\base\DB; use cms\base\Startup; +use cms\generator\dsl\DslAlert; +use cms\generator\dsl\DslConsole; +use cms\generator\dsl\DslDocument; use cms\macros\MacroRunner; use cms\model\BaseObject; use cms\model\Element; @@ -21,6 +24,7 @@ use cms\model\PageContent; use cms\model\Project; use cms\model\Template; use cms\model\Value; +use dsl\executor\DslExecutor; use logger\Logger; use LogicException; use util\Code; @@ -753,33 +757,55 @@ class ValueGenerator extends BaseGenerator // Programmcode (PHP) case Element::ELEMENT_TYPE_CODE: - // Die Ausführung von benutzer-erzeugtem PHP-Code kann in der - // Konfiguration aus Sicherheitsgründen deaktiviert sein. - if ( Configuration::subset('security')->is('disable_dynamic_code',false) ) - { - Logger::warn("Execution of dynamic code elements is disabled by configuration. Set security/disable_dynamic_code to true to allow this"); - break; - } + switch( $element->subtype ) { + case 'php': + // Die Ausführung von benutzer-erzeugtem PHP-Code kann in der + // Konfiguration aus Sicherheitsgründen deaktiviert sein. + if ( Configuration::subset('security')->is('disable_dynamic_code',false) ) + { + Logger::warn("Execution of dynamic code elements is disabled by configuration. Set security/disable_dynamic_code to true to allow this"); + break; + } - $page->load(); + $page->load(); + + // Das Ausführen geschieht über die Klasse "Code". + // In dieser wird der Code in eine Datei geschrieben und + // von dort eingebunden. + $code = new Code(); + $code->setPageContext($this->context->pageContext ); + $code->code = $element->code; - // Das Ausführen geschieht über die Klasse "Code". - // In dieser wird der Code in eine Datei geschrieben und - // von dort eingebunden. - $code = new Code(); - $code->setPageContext($this->context->pageContext ); - $code->code = $element->code; + ob_start(); - ob_start(); + // Jetzt ausfuehren des temporaeren PHP-Codes + $code->execute(); - // Jetzt ausfuehren des temporaeren PHP-Codes - $code->execute(); + $output = ob_get_contents(); + ob_end_clean(); - $output = ob_get_contents(); - ob_end_clean(); + // Ausgabe ermitteln. + $inhalt = $output; + break; - // Ausgabe ermitteln. - $inhalt = $output; + case 'js': + ob_start(); + $executor = new DslExecutor(); + $executor->setContext( [ + 'console' => new DslConsole(), + 'document' => new DslDocument(), + 'alert' => new DslAlert(), + 'page' => $page + ]); + + $executor->runCode( $element->code ); + $output = ob_get_contents(); + ob_end_clean(); + + // Ausgabe ermitteln. + $inhalt = $output; + break; + } break; diff --git a/modules/cms/generator/dsl/DslAlert.class.php b/modules/cms/generator/dsl/DslAlert.class.php @@ -0,0 +1,14 @@ +<?php + +namespace cms\generator\dsl; + +use dsl\context\DslFunction; + +class DslAlert implements DslFunction +{ + + public function execute( $text ) + { + echo 'alert: !'.$text.'!'; + } +} +\ No newline at end of file diff --git a/modules/cms/generator/dsl/DslConsole.class.php b/modules/cms/generator/dsl/DslConsole.class.php @@ -0,0 +1,31 @@ +<?php + +namespace cms\generator\dsl; + +use dsl\context\DslObject; +use logger\Logger; + +class DslConsole implements DslObject +{ + + public function log( $text ) + { + Logger::info( $text ); + } + public function debug( $text ) + { + Logger::debug( $text ); + } + public function info( $text ) + { + Logger::info( $text ); + } + public function warn( $text ) + { + Logger::warn( $text ); + } + public function error( $text ) + { + Logger::error( $text ); + } +} +\ No newline at end of file diff --git a/modules/cms/generator/dsl/DslDocument.class.php b/modules/cms/generator/dsl/DslDocument.class.php @@ -0,0 +1,12 @@ +<?php + +namespace cms\generator\dsl; + +use dsl\context\DslObject; + +class DslDocument implements DslObject +{ + public function write( $text ) { + echo $text; + } +} +\ No newline at end of file diff --git a/modules/cms/model/Element.class.php b/modules/cms/model/Element.class.php @@ -436,7 +436,7 @@ SQL 'copy' =>array('inherit','prefix','name','defaultText'), 'linkinfo'=>array('prefix','subtype','defaultText'), 'linkdate'=>array('prefix','subtype','dateformat'), - 'code' =>array('code'), + 'code' =>array('code','subtype'), 'dynamic' =>array('subtype','code'), 'info' =>array('subtype'), 'infodate'=>array('subtype','dateformat') ); diff --git a/modules/dsl/DslAstParser.class.php b/modules/dsl/DslAstParser.class.php @@ -0,0 +1,28 @@ +<?php +namespace dsl; + +use dsl\ast\DslStatementList; + +class DslAstParser +{ + /** + * @var DslStatementList + */ + public $statements; + + /** + * @throws \Exception + */ + public function parse($tokens ) { + + //echo "Token: <pre>"; var_dump( $tokens ); echo "</pre>"; + + $this->statements = new DslStatementList(); + $this->statements->parse( $tokens ); + } + + + public function execute($context) { + $this->statements->execute( $context ); + } +} +\ No newline at end of file diff --git a/modules/dsl/DslLexer.class.php b/modules/dsl/DslLexer.class.php @@ -0,0 +1,196 @@ +<?php +namespace dsl; + +class DslLexer +{ + private $token = []; + + + const KEYWORDS = [ + 'function' => DslToken::T_FUNCTION, + 'for' => DslToken::T_FOR, + 'if' => DslToken::T_IF, + 'else' => DslToken::T_ELSE, + 'let' => DslToken::T_LET, + 'const' => DslToken::T_LET, + 'var' => DslToken::T_LET, + 'return' => DslToken::T_RETURN, + ]; + + /** + * @param $code + * @return array(DslToken) + */ + public function tokenize( $code ) { + + //echo "Code: <pre>".$code."</pre>"; + + $line = 1; + + // mb_str_split only available since PHP 7.4 + $chars = array_reverse(str_split($code)); + + while( true ) { + $char = array_pop($chars); + + if ( $char == null ) + break; + + if ( ( $char == ' ' )) + continue; + + if ( ( $char == "\n" )) { + //$this->addToken($line,DslToken::T_STATEMENT_END); // line-end is implicite end of statement + // oh, not so good on "if" constructs. + $line++; + continue; + } + + // Text + if ( $char == '"' || $char == "'" ) { + $textEncloser = $char; + $value = ''; + while( true ) { + $char = array_pop($chars); + if ( $char == '\\') { + $char = array_pop($chars); + $value .= $char; + } + elseif ($char != $textEncloser) { + $value .= $char; + continue; + } else { + $this->addToken($line, DslToken::T_TEXT, $value); + break; + } + } + continue; + } + + // Comments + if ( $char == '/' ) { + $nextChar = array_pop($chars); + if ( $nextChar == '/' ) { // Comment after "//" + + while( true ) { + $c = array_pop($chars); + if ($c == "\n" || $c == null ) + continue 2; + } + + } + elseif ( $nextChar == '*' ) { // Comment after "/*" + + $lastChar = null; + while( true ) { + $c = array_pop($chars); + if ( $c == null ) + break 2; + if ( $lastChar == '*' && $c == '/') + continue 2; + $lastChar = $c; + continue; + } + + } + else { + array_push($chars,$nextChar); // this is no comment + } + } + + // String + if ( ( $char >= 'a' && $char <= 'z') || + ( $char >= 'A' && $char <= 'Z') || + $char == '_' || + $char == '$' ) { + $value = $char; + while( true ) { + $char = array_pop( $chars ); + if ( ( $char >= 'a' && $char <= 'z') || + ( $char >= 'A' && $char <= 'Z') || + ( $char >= '0' && $char <= '9') || + $char == '_' || + $char == '$' ) { + $value .= $char; + } else { + $type = DslToken::T_STRING; + + if ( array_key_exists($value,self::KEYWORDS ) ) + $type = self::KEYWORDS[$value]; // it is a keyword + + $this->addToken( $line,$type,$value ); + array_push($chars,$char); + break; + } + } + continue; + } + + // Numbers + if ( $char >= '0' && $char <= '9') { + $value = $char; + while( true ) { + $char = array_pop( $chars ); + if ( ( $char >= '0' && $char <= '9') || + $char == '.' ) { + $value .= $char; + } else { + $this->addToken( $line,DslToken::T_NUMBER,$value ); + array_push($chars,$char); + break; + } + } + continue; + } + + if ( $char == '+' || $char == '-' || $char == '/' || $char == '*' || $char == '=' || $char == '|' || $char == '&' ) { + + $value = $char; + while( true ) { + $char = array_pop( $chars ); + if ( $char == '+' || $char == '-' || $char == '/' || $char == '*' || $char == '=' || $char == '|' || $char == '&' ) { + $value .= $char; + } else { + $type = DslToken::T_OPERATOR; + $this->addToken( $line,$type,$value ); + array_push($chars,$char); + continue 2; + } + } + continue; + } + + if ( $char == "\r" ) + continue; + elseif ( $char == '!' ) + $this->addToken( $line,DslToken::T_NEGATION,$char); + elseif ( $char == ';' ) + $this->addToken( $line,DslToken::T_STATEMENT_END,$char); + elseif ( $char == '.' ) + $this->addToken( $line,DslToken::T_DOT,$char); + elseif ( $char == ',' ) + $this->addToken( $line,DslToken::T_COMMA,$char); + elseif ( $char == '(' ) + $this->addToken( $line,DslToken::T_BRACKET_OPEN,$char); + elseif ( $char == ')' ) + $this->addToken( $line,DslToken::T_BRACKET_CLOSE,$char); + elseif ( $char == '{' ) + $this->addToken( $line,DslToken::T_BLOCK_BEGIN,$char); + elseif ( $char == '}' ) + $this->addToken( $line,DslToken::T_BLOCK_END,$char); + else { + throw new \Exception('Unknown character \''.$char.'\' on line '.$line.'.'); + } + } + + + return $this->token; + } + + private function addToken(int $line, $type, $value=null) + { + $this->token[] = new DslToken( $line, $type, $value ); + } + + +} +\ No newline at end of file diff --git a/modules/dsl/DslToken.class.php b/modules/dsl/DslToken.class.php @@ -0,0 +1,45 @@ +<?php +namespace dsl; + +class DslToken +{ + + + const T_NONE = 0; + const T_STRING = 1; + const T_BRACKET_OPEN = 3; + const T_BRACKET_CLOSE = 4; + const T_BLOCK_BEGIN = 5; + const T_BLOCK_END = 6; + const T_TEXT = 7; + const T_NUMBER = 8; + const T_OPERATOR = 9; + const T_FUNCTION = 10; + const T_FOR = 11; + const T_IF = 12; + const T_ELSE = 13; + const T_LET = 14; + const T_RETURN = 15; + const T_DOT = 16; + const T_STATEMENT_END = 17; + const T_NEGATION = 18; + const T_COMMA = 19; + + public $lineNumber; + public $type; + public $value; + + /** + * DslToken constructor. + * @param $lineNumber + * @param $type + * @param $value + */ + public function __construct($lineNumber, $type, $value) + { + $this->lineNumber = $lineNumber; + $this->type = $type; + $this->value = $value; + } + +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslAssignment.class.php b/modules/dsl/ast/DslAssignment.class.php @@ -0,0 +1,49 @@ +<?php + +namespace dsl\ast; + +use dsl\DslToken; + +class DslAssignment implements DslStatement +{ + private $target = []; + private $value; + + public function execute( $context ) { + + // todo make assignment to target + $this->value->execute( $context ); + } + + public function parse($tokens) + { + //echo "<h2>Assignment-Parser</h2><pre>"; var_dump( $tokens ); echo "</pre>"; + $this->target = new DslExpression(); + $this->value = new DslExpression(); + + $assignmentOperatorFound = false; + $targetToken = []; + $valueToken = []; + + foreach( $tokens as $token ) { + + if ( $token->type == DslToken::T_OPERATOR && in_array($token->value,['=','+='.'-=']) ) { + $assignmentOperatorFound = true; + continue; + } + + if ( ! $assignmentOperatorFound ) + $targetToken[] = $token; + else + $valueToken[] = $token; + } + + if ( $assignmentOperatorFound ) { + $this->target->parse( $targetToken ); + $this->value ->parse( $valueToken ); + } else { + $this->value->parse( $targetToken ); + $this->target = null; + } + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslElement.class.php b/modules/dsl/ast/DslElement.class.php @@ -0,0 +1,8 @@ +<?php + +namespace dsl\ast; + +class DslElement +{ + +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslExpression.class.php b/modules/dsl/ast/DslExpression.class.php @@ -0,0 +1,48 @@ +<?php + +namespace dsl\ast; + +use dsl\DslToken; + +class DslExpression implements DslStatement +{ + private $value = []; + + public function execute( $context ) { + + //echo "ausführen expression: "; var_dump($this->value); + foreach( $this->value as $v) + $v->execute( $context ); + } + + public function parse($tokens) + { + $depth = 0; + + //echo "<h2>Expression</h2><pre>"; var_dump( $tokens ); echo "</pre>"; + while( true ) { + + $token = array_pop( $tokens ); + + if ( $token == null ) { + break; + } + + if ( $token->type == DslToken::T_STRING ) + { + $nextToken = array_pop( $tokens ); + if ( $nextToken->type == DslToken::T_BRACKET_OPEN ) + { + $nextToken = array_pop( $tokens ); + if ( $nextToken->type == DslToken::T_TEXT ) { + + $functionCall = new DslFunctionCall(); + $functionCall->name = $token->value; + $functionCall->parse( $nextToken ); + $this->value[] = $functionCall; + } + } + } + } + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslFor.class.php b/modules/dsl/ast/DslFor.class.php @@ -0,0 +1,16 @@ +<?php + +namespace dsl\ast; + +class DslFor implements DslStatement +{ + private $statements; + + public function execute( $context ) { + + } + + public function parse($tokens) + { + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslFunction.class.php b/modules/dsl/ast/DslFunction.class.php @@ -0,0 +1,26 @@ +<?php + +namespace dsl\ast; + +use dsl\DslToken; + +class DslFunction implements DslStatement +{ + private $statements; + + public function execute( $context ) { + + } + + public function parse($tokens) + { + $functionName = array_pop( $tokens ); + if ( $functionName->type != DslToken::T_STRING ) + throw new \Exception('function must be named' ); + $bracketOpen = array_pop( $tokens ); + $bracketClose = array_pop( $tokens ); + $blockBegin = array_pop( $tokens ); + if ( $blockBegin->type != DslToken::T_BLOCK_BEGIN ) + throw new \Exception('function must be followed by a block' ); + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslFunctionCall.class.php b/modules/dsl/ast/DslFunctionCall.class.php @@ -0,0 +1,26 @@ +<?php + +namespace dsl\ast; + +class DslFunctionCall implements DslStatement +{ + private $statements; + public $name; + + public function execute( $context ) { + + //echo "ausführen function"; echo "<pre>"; var_dump($this); echo "</pre>"; + //var_dump($this->name); + //echo "<pre>"; var_dump($context); echo "</pre>"; + $function = @$context[$this->name]; + if ( $function instanceof \dsl\context\DslFunction ) + $function->execute( $this->statements[0]->value ); + //else + //throw new \Exception('function \''.$this->name.'\' not found.'); + } + + public function parse($tokens) + { + $this->statements[] = $tokens; + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslIf.class.php b/modules/dsl/ast/DslIf.class.php @@ -0,0 +1,16 @@ +<?php + +namespace dsl\ast; + +class DslIf implements DslStatement +{ + private $statements; + + public function execute( $context ) { + + } + + public function parse($tokens) + { + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslInitialisation.class.php b/modules/dsl/ast/DslInitialisation.class.php @@ -0,0 +1,16 @@ +<?php + +namespace dsl\ast; + +class DslInitialisation implements DslStatement +{ + private $statements; + + public function execute( $context ) { + + } + + public function parse($tokens) + { + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslReturn.class.php b/modules/dsl/ast/DslReturn.class.php @@ -0,0 +1,16 @@ +<?php + +namespace dsl\ast; + +class DslReturn implements DslStatement +{ + private $statements; + + public function execute( $context ) { + + } + + public function parse($tokens) + { + } +} +\ No newline at end of file diff --git a/modules/dsl/ast/DslStatement.class.php b/modules/dsl/ast/DslStatement.class.php @@ -0,0 +1,13 @@ +<?php + +namespace dsl\ast; + +use dsl\DslToken; + +interface DslStatement +{ + public function parse($tokens); + + public function execute($context); + +} diff --git a/modules/dsl/ast/DslStatementList.class.php b/modules/dsl/ast/DslStatementList.class.php @@ -0,0 +1,91 @@ +<?php + +namespace dsl\ast; + +use dsl\DslToken; + +class DslStatementList implements DslStatement +{ + private $statements = []; + + public function parse( $tokens ) { + + + $tokens = array_reverse( $tokens,true ); + + //echo "Token 2: <pre>"; var_dump( $tokens ); echo "</pre>"; + + + $tokensPerStatement = []; + $depth = 0; + + while( true ) { + $token = array_pop( $tokens ); + + if ( $token == null ) { + $this->createStatementFromTokens( $tokensPerStatement ); + break; + } + + $tokensPerStatement[] = $token; + + if ( $token->type == DslToken::T_BRACKET_OPEN ) + $depth++; + if ( $token->type == DslToken::T_BRACKET_CLOSE ) + $depth--; + if ( $token->type == DslToken::T_BLOCK_BEGIN ) + $depth++; + if ( $token->type == DslToken::T_BLOCK_END ) + $depth--; + + if ( $depth == 0 && $token->type === DslToken::T_STATEMENT_END ) { + + $this->createStatementFromTokens( $tokensPerStatement ); + $tokensPerStatement = []; + } + } + + } + + public function execute($context) + { + foreach( $this->statements as $statement ) + $statement->execute( $context ); + } + + private function createStatementFromTokens( $tokensPerStatement ) + { + if ( ! $tokensPerStatement ) + return; + + $tokensPerStatement = array_reverse( $tokensPerStatement,true); + + $firstToken = array_pop( $tokensPerStatement ); + $statement = null; + + if ( $firstToken->type == DslToken::T_LET ) + $statement = new DslInitialisation(); + + elseif ( $firstToken->type == DslToken::T_RETURN ) + $statement = new DslReturn(); + + elseif ( $firstToken->type == DslToken::T_FUNCTION ) + $statement = new DslFunction(); + + elseif ( $firstToken->type == DslToken::T_IF ) + $statement = new DslIf(); + + elseif ( $firstToken->type == DslToken::T_FOR ) + $statement = new DslFor(); + + else { + array_push( $tokensPerStatement,$firstToken ); + $statement = new DslAssignment(); + } + + if ( $statement ) { + $statement->parse( $tokensPerStatement ); + $this->statements[] = $statement; + } + } +} +\ No newline at end of file diff --git a/modules/dsl/context/DslFunction.class.php b/modules/dsl/context/DslFunction.class.php @@ -0,0 +1,7 @@ +<?php + +namespace dsl\context; + +interface DslFunction +{ +} +\ No newline at end of file diff --git a/modules/dsl/context/DslObject.class.php b/modules/dsl/context/DslObject.class.php @@ -0,0 +1,8 @@ +<?php + +namespace dsl\context; + +interface DslObject +{ + +} +\ No newline at end of file diff --git a/modules/dsl/executor/DslExecutor.class.php b/modules/dsl/executor/DslExecutor.class.php @@ -0,0 +1,33 @@ +<?php + +namespace dsl\executor; + +use dsl\DslAstParser; +use dsl\DslLexer; + +class DslExecutor +{ + private $context = []; + + public function setContext( $context ) { + $this->context = $context; + } + + + public function run( $ast ) { + $ast->execute( $this->context ); + } + + /** + * @throws \Exception + */ + public function runCode($code ) { + $lexer = new DslLexer(); + $token = $lexer->tokenize( $code ); + + $parser = new DslAstParser(); + $parser->parse( $token ); + + $parser->execute( $this->context ); + } +} +\ No newline at end of file diff --git a/modules/language/Language_CN.class.php b/modules/language/Language_CN.class.php @@ -160,7 +160,9 @@ public function get() { return [ 'EDITOR_PROMPT_TABLE_CELL_FIRST_COLUMN'=>'Please enter a text for the first table cell. Space End of table.', 'EDITOR_SHOW_LANGUAGE'=>'Show language', 'EL_CODE_DESC'=>'This PHP-code-element contains PHP-Code which is executed while publishing the page. Only for experienced PHP Programmers!', -'EL_CODE'=>'PHP Code', +'EL_CODE'=>'Code', +'EL_CODE_PHP'=>'PHP', +'EL_CODE_JS'=>'Javascript', 'EL_COPY_DESC'=>'Copy a Value out of an element of a linked page', 'EL_COPY'=>'Copy', 'EL_DATE'=>'Date', @@ -1039,6 +1041,7 @@ Thank you.', 'CONCURRENT_VALUE_CHANGE'=>'While your edit session another user has changed this content at ${last_change_time}. Your changes where saved, but you should check the archive if the overwritten content should be merged.', 'COPIED'=>'was copied', 'DUPLICATE_INPUT'=>'Duplicate Input detected.', +'DUPLICATE_NAME_EXISTS'=>'The name is already in use', 'DATABASE_CONNECTION_ERROR'=>'The connection to the database could not be established.', 'ERROR_DATABASE'=>'The database query could not executed.', 'DELETED'=>'was deleted', diff --git a/modules/language/Language_DE.class.php b/modules/language/Language_DE.class.php @@ -160,7 +160,9 @@ public function get() { return [ 'EDITOR_PROMPT_TABLE_CELL_FIRST_COLUMN'=>'Bitte geben Sie einen Text für die erste Tabellenzelle ein. Leer=Ende der Tabelle.', 'EDITOR_SHOW_LANGUAGE'=>'Sprache anzeigen', 'EL_CODE_DESC'=>'Das <strong>PHP Code</strong>-Platzhalter enthält PHP-Code, welcher während der Generierung vom System ausgeführt wird. Mit diesem Platzhalter kann eine Seite sehr dynamisch aufgebaut werden, bleibt nach der Generierung aber statisch. Dieser Platzhaltertyp verlangt Kenntnisse in der Programmierung von PHP-Code!', -'EL_CODE'=>'PHP Code', +'EL_CODE'=>'Code', +'EL_CODE_PHP'=>'PHP', +'EL_CODE_JS'=>'Javascript', 'EL_COPY_DESC'=>'Einen Wert aus einem Platzhalter einer verlinkten Seite kopieren', 'EL_COPY'=>'Kopie', 'EL_DATE'=>'Datum', @@ -1044,6 +1046,7 @@ Vielen Dank.', 'CONCURRENT_VALUE_CHANGE'=>'Während Ihrer Bearbeitung ist dieser Inhalt von einem anderen Benutzer um ${last_change_time} geändert worden. Ihre Änderungen wurden gespeichert, prüfen Sie jedoch über das Archiv, ob gemachte Änderungen von Ihnen übernommen werden müssen.', 'COPIED'=>'wurde kopiert.', 'DUPLICATE_INPUT'=>'Ihre Eingabe muss eindeutig sein.', +'DUPLICATE_NAME_EXISTS'=>'Der Name existiert bereits', 'DATABASE_CONNECTION_ERROR'=>'Es konnte keine Verbindung zur Datenbank hergestellt werden.', 'ERROR_DATABASE'=>'Es gab einen Fehler bei der Durchführung einer Datenbankanfrage.', 'DELETED'=>'wurde gelöscht.', diff --git a/modules/language/Language_EN.class.php b/modules/language/Language_EN.class.php @@ -160,7 +160,9 @@ public function get() { return [ 'EDITOR_PROMPT_TABLE_CELL_FIRST_COLUMN'=>'Please enter a text for the first table cell. Space End of table.', 'EDITOR_SHOW_LANGUAGE'=>'Show language', 'EL_CODE_DESC'=>'This PHP-code-element contains PHP-Code which is executed while publishing the page. Only for experienced PHP Programmers!', -'EL_CODE'=>'PHP Code', +'EL_CODE'=>'Code', +'EL_CODE_PHP'=>'PHP', +'EL_CODE_JS'=>'Javascript', 'EL_COPY_DESC'=>'Copy a Value out of an element of a linked page', 'EL_COPY'=>'Copy', 'EL_DATE'=>'Date', @@ -1039,6 +1041,7 @@ Thank you.', 'CONCURRENT_VALUE_CHANGE'=>'While your edit session another user has changed this content at ${last_change_time}. Your changes where saved, but you should check the archive if the overwritten content should be merged.', 'COPIED'=>'was copied', 'DUPLICATE_INPUT'=>'Duplicate Input detected.', +'DUPLICATE_NAME_EXISTS'=>'The name is already in use', 'DATABASE_CONNECTION_ERROR'=>'The connection to the database could not be established.', 'ERROR_DATABASE'=>'The database query could not executed.', 'DELETED'=>'was deleted', diff --git a/modules/language/Language_ES.class.php b/modules/language/Language_ES.class.php @@ -160,7 +160,9 @@ public function get() { return [ 'EDITOR_PROMPT_TABLE_CELL_FIRST_COLUMN'=>'Please enter a text for the first table cell. Space=End of table.', 'EDITOR_SHOW_LANGUAGE'=>'Show language', 'EL_CODE_DESC'=>'Este <strong>PHP code</strong>-element contiene el PHP-Código se ejecuta que mientras que publica la página. ¡Solamente para los programadores experimentados de PHP!', -'EL_CODE'=>'Código de PHP', +'EL_CODE'=>'Código', +'EL_CODE_PHP'=>'PHP', +'EL_CODE_JS'=>'Javascript', 'EL_COPY_DESC'=>'Copy a Value out of an element of a linked page', 'EL_COPY'=>'Copy', 'EL_DATE'=>'Fecha', @@ -1064,6 +1066,7 @@ MENU_INDEX_ADMINISTRATION_DESC =', 'CONCURRENT_VALUE_CHANGE'=>'While your edit session another user has changed this content at ${last_change_time}. Your changes where saved, but you should check the archive if the overwritten content should be merged.', 'COPIED'=>'fue copiada', 'DUPLICATE_INPUT'=>'Duplicate Input detected.', +'DUPLICATE_NAME_EXISTS'=>'The name is already in use', 'DATABASE_CONNECTION_ERROR'=>'The connection to the database could not be established.', 'ERROR_DATABASE'=>'The database query could not executed.', 'DELETED'=>'fue suprimida', diff --git a/modules/language/Language_FR.class.php b/modules/language/Language_FR.class.php @@ -160,7 +160,9 @@ public function get() { return [ 'EDITOR_PROMPT_TABLE_CELL_FIRST_COLUMN'=>'Please enter a text for the first table cell. Space=End of table.', 'EDITOR_SHOW_LANGUAGE'=>'Show language', 'EL_CODE_DESC'=>'Ce <strong>PHP code</strong>-element contient le PHP-Code qui est exécuté tout en éditant la page. Seulement pour les programmeurs expérimentés de PHP !', -'EL_CODE'=>'Code de PHP', +'EL_CODE'=>'Code', +'EL_CODE_PHP'=>'PHP', +'EL_CODE_JS'=>'Javascript', 'EL_COPY_DESC'=>'Copy a Value out of an element of a linked page', 'EL_COPY'=>'Copy', 'EL_DATE'=>'Date', @@ -1040,6 +1042,7 @@ Merci.', 'CONCURRENT_VALUE_CHANGE'=>'While your edit session another user has changed this content at ${last_change_time}. Your changes where saved, but you should check the archive if the overwritten content should be merged.', 'COPIED'=>'a été copié', 'DUPLICATE_INPUT'=>'Duplicate Input detected.', +'DUPLICATE_NAME_EXISTS'=>'The name is already in use', 'DATABASE_CONNECTION_ERROR'=>'The connection to the database could not be established.', 'ERROR_DATABASE'=>'The database query could not executed.', 'DELETED'=>'a été supprimé', diff --git a/modules/language/Language_IT.class.php b/modules/language/Language_IT.class.php @@ -160,7 +160,9 @@ public function get() { return [ 'EDITOR_PROMPT_TABLE_CELL_FIRST_COLUMN'=>'Please enter a text for the first table cell. Space=End of table.', 'EDITOR_SHOW_LANGUAGE'=>'Show language', 'EL_CODE_DESC'=>'che questo <strong>PHP code</strong>-element contiene il PHP-Codice che è eseguito mentre pubblica la pagina. Soltanto per i programmatori con esperienza di PHP!', -'EL_CODE'=>'codice di PHP', +'EL_CODE'=>'codice', +'EL_CODE_PHP'=>'PHP', +'EL_CODE_JS'=>'Javascript', 'EL_COPY_DESC'=>'Copy a Value out of an element of a linked page', 'EL_COPY'=>'La data del copy', 'EL_DATE'=>'Date', @@ -1040,6 +1042,7 @@ Gracias.', 'CONCURRENT_VALUE_CHANGE'=>'While your edit session another user has changed this content at ${last_change_time}. Your changes where saved, but you should check the archive if the overwritten content should be merged.', 'COPIED'=>'è stata copiata', 'DUPLICATE_INPUT'=>'Duplicate Input detected.', +'DUPLICATE_NAME_EXISTS'=>'The name is already in use', 'DATABASE_CONNECTION_ERROR'=>'The connection to the database could not be established.', 'ERROR_DATABASE'=>'The database query could not executed.', 'DELETED'=>'è stata cancellata', diff --git a/modules/language/Language_RU.class.php b/modules/language/Language_RU.class.php @@ -160,7 +160,9 @@ public function get() { return [ 'EDITOR_PROMPT_TABLE_CELL_FIRST_COLUMN'=>'Please enter a text for the first table cell. Space=End of table.', 'EDITOR_SHOW_LANGUAGE'=>'Show language', 'EL_CODE_DESC'=>'Кодекс Это <strong> PHP-код </strong> - элемент содержит PHP кодекса, который выполняется при публикации страницы. Только для опытных программистов PHP! Копировать', -'EL_CODE'=>'PHP Code', +'EL_CODE'=>'Code', +'EL_CODE_PHP'=>'PHP', +'EL_CODE_JS'=>'Javascript', 'EL_COPY_DESC'=>'Copy a Value out of an element of a linked page', 'EL_COPY'=>'Copy', 'EL_DATE'=>'Дата', @@ -1040,6 +1042,7 @@ if you do not know where this mail comes from, please ignore it.', 'CONCURRENT_VALUE_CHANGE'=>'While your edit session another user has changed this content at ${last_change_time}. Your changes where saved, but you should check the archive if the overwritten content should be merged.', 'COPIED'=>'копирования', 'DUPLICATE_INPUT'=>'Duplicate Input detected.', +'DUPLICATE_NAME_EXISTS'=>'The name is already in use', 'DATABASE_CONNECTION_ERROR'=>'The connection to the database could not be established.', 'ERROR_DATABASE'=>'The database query could not executed.', 'DELETED'=>'удалена', diff --git a/modules/language/Messages.class.php b/modules/language/Messages.class.php @@ -161,6 +161,8 @@ class Messages { const EDITOR_SHOW_LANGUAGE = 'EDITOR_SHOW_LANGUAGE'; const EL_CODE_DESC = 'EL_CODE_DESC'; const EL_CODE = 'EL_CODE'; + const EL_CODE_PHP = 'EL_CODE_PHP'; + const EL_CODE_JS = 'EL_CODE_JS'; const EL_COPY_DESC = 'EL_COPY_DESC'; const EL_COPY = 'EL_COPY'; const EL_DATE = 'EL_DATE'; @@ -993,6 +995,7 @@ class Messages { const CONCURRENT_VALUE_CHANGE = 'CONCURRENT_VALUE_CHANGE'; const COPIED = 'COPIED'; const DUPLICATE_INPUT = 'DUPLICATE_INPUT'; + const DUPLICATE_NAME_EXISTS = 'DUPLICATE_NAME_EXISTS'; const DATABASE_CONNECTION_ERROR = 'DATABASE_CONNECTION_ERROR'; const ERROR_DATABASE = 'ERROR_DATABASE'; const DELETED = 'DELETED'; diff --git a/modules/language/language.yml b/modules/language/language.yml @@ -694,11 +694,15 @@ EL_CODE_DESC: it: 'che questo <strong>PHP code</strong>-element contiene il PHP-Codice che è eseguito mentre pubblica la pagina. Soltanto per i programmatori con esperienza di PHP!' ru: 'Кодекс Это <strong> PHP-код </strong> - элемент содержит PHP кодекса, который выполняется при публикации страницы. Только для опытных программистов PHP! Копировать' EL_CODE: - de: PHP Code - en: PHP Code - es: Código de PHP - fr: Code de PHP - it: codice di PHP + de: Code + en: Code + es: Código + fr: Code + it: codice +EL_CODE_PHP: + en: PHP +EL_CODE_JS: + en: Javascript EL_COPY_DESC: de: Einen Wert aus einem Platzhalter einer verlinkten Seite kopieren en: Copy a Value out of an element of a linked page