Daten aus der Datenbank der Tabelle: Kategorien
+ +-
+
+
+
+
+
+
+
- Keine Daten vorhanden. + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+| + | Preis intern | +Preis extern | +
| Rindfleich mit Bambus, Kaiserschoten und roter Paprika, dazu Mie Nudeln | +3,50 | +6,20 | +
| Spinatrisotto mit kleinen Samosateigecken und gemischter Salat | +2,90 | +5,30 | +
| ... | +... | +... | +
X Besuche
+Y Anmeldungen zum Newsletter
+Z Speisen
+Am besten zeigt man das in einer Tabelle.
+| Bedeutung | +Philosophie | +Beispiele | +
|---|---|---|
| Elektro | +Alles geht elektronisch | +
+
|
+
| Extravagant | +Es gibt auch Ausgefallenes | +Wir sind die einzige Mensa weit und breit mit +
|
+
| Effizient | +Schnell, lecker und qualitativ | +
+
|
+
Da geht natürlich noch viel mehr, siehe nur E.
Die Tabelle ist
+ aber schon ganz schön imposant so oder?
Lorem Ipsum
+ + \ No newline at end of file diff --git a/M1/beispiele/m1_4b_tabelle.html b/M1/beispiele/m1_4b_tabelle.html new file mode 100644 index 0000000..f25f45a --- /dev/null +++ b/M1/beispiele/m1_4b_tabelle.html @@ -0,0 +1,44 @@ + + + + + +| Art | +Gericht | +Preis | +Werktag | +Wochenende | +Inhaltsstoffe | +
|---|---|---|---|---|---|
| Vegetarisch | +Kürbis-Chai-Teller | +2,10€ | +Ganze Woche | ++ | |
| Pasta | +Spaghetti Carciofo | +3,50€ | +A,A1 | +||
| Bandnudeln | +3,50€ | ++ | x | +A, D, A1 | +|
+
+
\ No newline at end of file
diff --git a/M1/beispiele/m1_4d_links.html b/M1/beispiele/m1_4d_links.html
new file mode 100644
index 0000000..778a94c
--- /dev/null
+++ b/M1/beispiele/m1_4d_links.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et dolore + magna aliquyam erat, sed diam voluptua. At vero eos et accusam + et justo duo dolores et ea rebum. Stet clita kasd gubergren, + no sea takimata sanctus est Lorem ipsum dolor sit amet. +
++ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et dolore + magna aliquyam erat, sed diam voluptua. At vero eos et accusam + et justo duo dolores et ea rebum. Stet clita kasd gubergren, + no sea takimata sanctus est Lorem ipsum dolor sit amet. +
++ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore et dolore + magna aliquyam erat, sed diam voluptua. At vero eos et accusam + et justo duo dolores et ea rebum. Stet clita kasd gubergren, + no sea takimata sanctus est Lorem ipsum dolor sit amet. +
+Test
+Test
+Test
+Test
+Test
+Test
+Test
++
+ + +
+
+
+
| + | + | + | {$rating['text']} | +{$rating['stars']} | +{$rating['author']} | + "; + } + ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+| Gerichte | +Preis intern | +Preis extern | +Bild | +" . $gericht["name"] . " | " . $gericht["priceint"] . " | " . $gericht["priceex"] . " |
Besuche
+Anmeldungen zum Newsletter
+Speisen
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Besuche
+Anmeldungen zum Newsletter
++ + Speisen +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Besuche
+Anmeldungen zum Newsletter
+ + Speisen +
+
+ DOCUMENT_ROOT: {$_SERVER['DOCUMENT_ROOT']}Datei nicht gefunden: {$_SERVER['DOCUMENT_ROOT']}/../vendor/autoload.php
"; + echo "Häufigste Ursache
public/ ist nicht als Wurzelverzeichnis verwendet worden.composer update installiert.DOCUMENT_ROOT{$_SERVER['DOCUMENT_ROOT']}Error" . $ex->getMessage() . ""; +} + +use eftec\bladeone\BladeOne; + +/* Routing Script for PHP Dev Server */ +$verbosity = VERBOSITY; +if (preg_match('/\.(?:css|js|png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) { + return false; +} else { + if ($verbosity > 1) { + echo + "
Verbosity-Level: {$verbosity}" .
+ "" . print_r($_SERVER, 1) . "
Request\n", print_r($request), ""; + echo "
Path\n", print_r($path), ""; + echo "
Query\n", print_r($query), ""; + } + } + + // fix: trim slashes + $ctrlName = trim($ctrlName, '/'); + $actionName = trim($actionName, '/'); + + // $config based renaming of Controller/Action, precedes filebased convention + // $config values must use syntax
Routing Config matched request for /" . $ctrlName . "/" . $actionName . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } elseif (array_key_exists($request['path'], $config)) { + // exact match on full path, this also means "/" + $routingConfig = explode('@', $config[$request['path']]); + if ($verbosity > 0) { + echo "
Routing Config matched for full path " . $request['path'] . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } else { + if ($verbosity > 0) { + echo "Request $ctrlName/$actionName was not in \$config."; + } + + // fall back to filebased convention: match controller classes in directory + $ctrlClass = ucfirst($ctrlName . 'Controller'); + } + + $ctrlFile = ($ctrlClass . '.php'); + $validControllers = FrontController::getValidControllers($controllerDirectory); + if (!in_array($controllerDirectory . $ctrlFile, $validControllers)) { + if ($verbosity > 0) { + echo "
Controller: $ctrlFile not found in
" . print_r($validControllers, 1) . "
Config Array:
" . print_r($config, 1) . "
" .
+ "Keine entspreche Zuordnung der Route für {$ctrlName}::{$actionName} gefunden. Tippfehler in der Route?" . + "
Es konnte keine Klasse " . $ctrlFile . " gefunden werden! Request fehlgeschlagen.
" . + " Prüfen Sie die Einträge in der Datei config/web.php und gleichen Sie den getätigten Aufruf damit ab.
Stellen Sie sicher, dass die Action/der Controller existiert.
+Das Routing Config-Array hat " . count($config) . " Einträge.
+Exception text
" . $ex->getMessage() . "
Verbindung fehlgeschlagen: " . mysqli_connect_error() . ".
config/db.php:
+ ( ist Benutzer {$config['user']} an Datenbank {$config['database']} auf Server {$config['host']} korrekt?)Fehlermeldung" . mysqli_connect_error() . "", 2, true); + exit(1); + } + + return $link; +} + +function view($viewname, $viewargs = array()) +{ + $views = dirname(__DIR__) . '/views'; + $cache = dirname(__DIR__) . '/storage/cache'; + $blade = new BladeOne($views, $cache, BladeOne::MODE_DEBUG); + + return $blade->run($viewname, $viewargs); +} + +/** + * let the script die if the php minimum version is not met. + * @param $minversion + * @return void + */ +function assert_php_version($minversion = '8.0.0') +{ + $version_too_low = 0; + $minver = explode('.', $minversion); + $version = explode('.', phpversion()); + + if (intval($minver[0]) > intval($version[0])) { + $version_too_low = 1; + } elseif (intval($minver[1]) > intval($version[1])) { + $version_too_low = 1; + } elseif (intval($minver[2]) > intval($version[2])) { + $version_too_low = 1; + } + + if ($version_too_low) { + FrontController::showErrorMessage("Diese PHP-Version wird nicht unterstützt: Minimum PHP Version " . $minversion . "
Der Pfad " . $_SERVER['DOCUMENT_ROOT'] . " enthält " . $charsfound . " problematische Zeichen, die die korrekte Ausführung verhindern.
Bekannte problematische Zeichen sind
+ " . implode(" ", $chars) . " ");
+ exit(1);
+ }
+
+}
+
+function assert_blade(): void
+{
+ if (!class_exists('eftec\bladeone\BladeOne')) {
+ // #ERROR
+ FrontController::showErrorMessage("
+ Tipps für die Lösung:
+führen Sie im Terminal folgende Zeilen aus.
+php bin/composer.phar update oder php bin/composer.phar reinstall eftec/bladeonephp bin/composer.phar dump-autoloadPrüfen Sie im Anschluss: befindet sich in dem Ordner vendor/eftec/bladeone/lib/ die Datei BladeOne.php ?
Starten Sie dann den Webserver neu.
Befragen Sie gerne auch das Forum in Ilias.
Fehlermeldung
++ + + + +
Fehlermeldung
++ + + +
Fehlermeldung
++ + + +
Page 1
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 1
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 1"]); } ?> \ No newline at end of file diff --git a/M4/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec b/M4/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec new file mode 100644 index 0000000..961375a --- /dev/null +++ b/M4/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec @@ -0,0 +1,14 @@ + + +startSection("header"); ?> + +stopSection(); ?> + +startSection("body"); ?> +Page 2
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 2
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 2"]); } ?> \ No newline at end of file diff --git a/M4/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec b/M4/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec new file mode 100644 index 0000000..c54dc25 --- /dev/null +++ b/M4/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec @@ -0,0 +1,36 @@ + + +startSection("content"); ?> +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is equals to abc
+ *
+ * Example: (includeScope=true)
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is not defined
+ *
+ */
+ public $includeScope = false;
+ /**
+ * @var callable[] It allows to parse the compiled output using a function.
+ * This function doesn't require to return a value
+ * $this->compileCallbacks[]= static function (&$content, $templatename=null) {
+ * $content=strtoupper($content);
+ * };
+ *
+ */
+ public $compileCallbacks = [];
+ /** @var array All the registered extensions. */
+ protected $extensions = [];
+ /** @var array All the finished, captured sections. */
+ protected $sections = [];
+ /** @var string The template currently being compiled. For example "folder.template" */
+ protected $fileName;
+ protected $currentView;
+ protected $notFoundPath;
+ /** @var string File extension for the template files. */
+ protected $fileExtension = '.blade.php';
+ /** @var array The stack of in-progress sections. */
+ protected $sectionStack = [];
+ /** @var array The stack of in-progress loops. */
+ protected $loopsStack = [];
+ /** @var array Dictionary of variables */
+ protected $variables = [];
+ /** @var array Dictionary of global variables */
+ protected $variablesGlobal = [];
+ /** @var array All the available compiler functions. */
+ protected $compilers = [
+ 'Extensions',
+ 'Statements',
+ 'Comments',
+ 'Echos',
+ ];
+ /** @var string|null it allows to set the stack */
+ protected $viewStack;
+ /** @var array used by $this->composer() */
+ protected $composerStack = [];
+ /** @var array The stack of in-progress push sections. */
+ protected $pushStack = [];
+ /** @var array All the finished, captured push sections. */
+ protected $pushes = [];
+ /** @var int The number of active rendering operations. */
+ protected $renderCount = 0;
+ /** @var string[] Get the template path for the compiled views. */
+ protected $templatePath;
+ /** @var string Get the compiled path for the compiled views. If null then it uses the default path */
+ protected $compiledPath;
+ /** @var string the extension of the compiled file. */
+ protected $compileExtension = '.bladec';
+ /**
+ * @var string=['auto','sha1','md5'][$i] It determines how the compiled filename will be called.
+ * $this->wrapPHP('$hello'); // "< ?php echo $this->e($hello); ? >"
+ * $this->wrapPHP('$hello',''); // < ?php echo $this->e($hello); ? >
+ * $this->wrapPHP('$hello','',false); // < ?php echo $hello; ? >
+ * $this->wrapPHP('"hello"'); // "< ?php echo $this->e("hello"); ? >"
+ * $this->wrapPHP('hello()'); // "< ?php echo $this->e(hello()); ? >"
+ *
+ *
+ * @param ?string $input The input value
+ * @param string $quote The quote used (to quote the result)
+ * @param bool $parse If the result will be parsed or not. If false then it's returned without $this->e
+ * @return string
+ */
+ public function wrapPHP($input, $quote = '"', $parse = true): string
+ {
+ if($input===null) {
+ return 'null';
+ }
+ if (strpos($input, '(') !== false && !$this->isQuoted($input)) {
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+ if (strpos($input, '$') === false) {
+ if ($parse) {
+ return self::enq($input);
+ }
+
+ return $input;
+ }
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+
+ /**
+ * Returns true if the text is surrounded by quotes (double or single quote)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isQuoted($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ if ($text[0] === '"' && substr($text, -1) === '"') {
+ return true;
+ }
+ return ($text[0] === "'" && substr($text, -1) === "'");
+ }
+
+ /**
+ * Escape HTML entities in a string.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function enq($value): string
+ {
+ if (\is_array($value) || \is_object($value)) {
+ return \htmlentities(\print_r($value, true), ENT_NOQUOTES, 'UTF-8', false);
+ }
+ return \htmlentities($value??'', ENT_NOQUOTES, 'UTF-8', false);
+ }
+
+ /**
+ * @param string $view example "folder.template"
+ * @param string|null $alias example "mynewop". If null then it uses the name of the template.
+ */
+ public function addInclude($view, $alias = null): void
+ {
+ if (!isset($alias)) {
+ $alias = \explode('.', $view);
+ $alias = \end($alias);
+ }
+ $this->directive($alias, function ($expression) use ($view) {
+ $expression = $this->stripParentheses($expression) ?: '[]';
+ return "$this->phpTag echo \$this->runChild('$view', $expression); ?>";
+ });
+ }
+
+ /**
+ * Register a handler for custom directives.
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directive($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = false;
+ }
+
+ /**
+ * Strip the parentheses from the given expression.
+ *
+ * @param string|null $expression
+ * @return string
+ */
+ public function stripParentheses($expression): string
+ {
+ if (\is_null($expression)) {
+ return '';
+ }
+
+ if (static::startsWith($expression, '(')) {
+ $expression = \substr($expression, 1, -1);
+ }
+
+ return $expression;
+ }
+
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function startsWith($haystack, $needles): bool
+ {
+ foreach ((array)$needles as $needle) {
+ if ($needle != '') {
+ if (\function_exists('mb_strpos')) {
+ if ($haystack !== null && \mb_strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ } elseif ($haystack !== null && \strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * If false then the file is not compiled, and it is executed directly from the memory.Example:setPath("somefolder","otherfolder"); + * + * @param null|string|string[] $templatePath If null then it uses the current path /views folder + * @param null|string $compiledPath If null then it uses the current path /views folder + */ + public function setPath($templatePath, $compiledPath): void + { + if ($templatePath === null) { + $templatePath = \getcwd() . '/views'; + } + if ($compiledPath === null) { + $compiledPath = \getcwd() . '/compiles'; + } + $this->templatePath = (is_array($templatePath)) ? $templatePath : [$templatePath]; + $this->compiledPath = $compiledPath; + } + + /** + * @return array + */ + public function getAliasClasses(): array + { + return $this->aliasClasses; + } + + /** + * @param array $aliasClasses + */ + public function setAliasClasses($aliasClasses): void + { + $this->aliasClasses = $aliasClasses; + } + + /** + * @param string $aliasName + * @param string $classWithNS + */ + public function addAliasClasses($aliasName, $classWithNS): void + { + $this->aliasClasses[$aliasName] = $classWithNS; + } + //
+ * Text::wildCardComparison('abcdef','abc*'); // true
+ * Text::wildCardComparison('abcdef','*def'); // true
+ * Text::wildCardComparison('abcdef','*abc*'); // true
+ * Text::wildCardComparison('abcdef','*cde*'); // true
+ * Text::wildCardComparison('abcdef','*cde'); // false
+ *
+ *
+ *
+ * @param string $text
+ * @param string|null $textWithWildcard
+ *
+ * @return bool
+ */
+ protected function wildCardComparison($text, $textWithWildcard): bool
+ {
+ if (($textWithWildcard === null || $textWithWildcard === '')
+ || strpos($textWithWildcard, '*') === false
+ ) {
+ // if the text with wildcard is null or empty, or it contains two ** or it contains no * then..
+ return $text == $textWithWildcard;
+ }
+ if ($textWithWildcard === '*' || $textWithWildcard === '**') {
+ return true;
+ }
+ $c0 = $textWithWildcard[0];
+ $c1 = substr($textWithWildcard, -1);
+ $textWithWildcardClean = str_replace('*', '', $textWithWildcard);
+ $p0 = strpos($text, $textWithWildcardClean);
+ if ($p0 === false) {
+ // no matches.
+ return false;
+ }
+ if ($c0 === '*' && $c1 === '*') {
+ // $textWithWildcard='*asasasas*'
+ return true;
+ }
+ if ($c1 === '*') {
+ // $textWithWildcard='asasasas*'
+ return $p0 === 0;
+ }
+ // $textWithWildcard='*asasasas'
+ $len = strlen($textWithWildcardClean);
+ return (substr($text, -$len) === $textWithWildcardClean);
+ }
+
+ protected function methodExistsStatic($class, $method): bool
+ {
+ try {
+ return (new \ReflectionMethod($class, $method))->isStatic();
+ } catch (\ReflectionException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Compile the view at the given path.
+ *
+ * @param string $templateName The name of the template. Example folder.template
+ * @param bool $forced If the compilation will be forced (always compile) or not.
+ * @return boolean|string True if the operation was correct, or false (if not exception)
+ * if it fails. It returns a string (the content compiled) if isCompiled=false
+ * @throws Exception
+ */
+ public function compile($templateName = null, $forced = false)
+ {
+ $compiled = $this->getCompiledFile($templateName);
+ $template = $this->getTemplateFile($templateName);
+ if (!$this->isCompiled) {
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ return $contents;
+ }
+ if ($forced || $this->isExpired($templateName)) {
+ // compile the original file
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ if ($this->optimize) {
+ // removes space and tabs and replaces by a single space
+ $contents = \preg_replace('/^ {2,}/m', ' ', $contents);
+ $contents = \preg_replace('/^\t{2,}/m', ' ', $contents);
+ }
+ $ok = @\file_put_contents($compiled, $contents);
+ if ($ok === false) {
+ $this->showError(
+ 'Compiling',
+ "Unable to save the file [$compiled]. Check the compile folder is defined and has the right permission"
+ );
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get the full path of the compiled file.
+ *
+ * @param string $templateName
+ * @return string
+ */
+ public function getCompiledFile($templateName = ''): string
+ {
+ $templateName = (empty($templateName)) ? $this->fileName : $templateName;
+
+ $fullPath = $this->getTemplateFile($templateName);
+ if($fullPath == '') {
+ throw new \RuntimeException('Template not found: ' . $templateName);
+ }
+
+ $style=$this->compileTypeFileName;
+ if ($style==='auto') {
+ $style='sha1';
+ }
+ $hash = $style === 'md5' ? \md5($fullPath) : \sha1($fullPath);
+ return $this->compiledPath . '/' . basename($templateName) . '_' . $hash . $this->compileExtension;
+ }
+
+
+
+ /**
+ * Get the mode of the engine.See BladeOne::MODE_* constants
+ *
+ * @return int=[self::MODE_AUTO,self::MODE_DEBUG,self::MODE_FAST,self::MODE_SLOW][$i]
+ */
+ public function getMode(): int
+ {
+ if (\defined('BLADEONE_MODE')) {
+ $this->mode = BLADEONE_MODE;
+ }
+ return $this->mode;
+ }
+
+ /**
+ * Set the compile modeExample: getTemplateFile('.abc.def')
+ * + * @param string $templateName template name. If not template is set then it uses the base template. + * @return string + */ + public function getTemplateFile($templateName = ''): string + { + $templateName = (empty($templateName)) ? $this->fileName : $templateName; + if (\strpos($templateName, '/') !== false) { + return $this->locateTemplate($templateName); // it's a literal + } + $arr = \explode('.', $templateName); + $c = \count($arr); + if ($c == 1) { + // it's in the root of the template folder. + return $this->locateTemplate($templateName . $this->fileExtension); + } + + $file = $arr[$c - 1]; + \array_splice($arr, $c - 1, $c - 1); // delete the last element + $path = \implode('/', $arr); + return $this->locateTemplate($path . '/' . $file . $this->fileExtension); + } + + /** + * Find template file with the given name in all template paths in the order the paths were written + * + * @param string $name Filename of the template (without path) + * @return string template file + */ + protected function locateTemplate($name): string + { + $this->notFoundPath = ''; + foreach ($this->templatePath as $dir) { + $path = $dir . '/' . $name; + if (\is_file($path)) { + return $path; + } + + $this->notFoundPath .= $path . ","; + } + return ''; + } + + /** + * Get the contents of a file. + * + * @param string $fullFileName It gets the content of a filename or returns ''. + * + * @return string + */ + public function getFile($fullFileName): string + { + if (\is_file($fullFileName)) { + return \file_get_contents($fullFileName); + } + $this->showError('getFile', "File does not exist at paths (separated by comma) [$this->notFoundPath] or permission denied"); + return ''; + } + + protected function compileCallBacks(&$contents, $templateName): void + { + if (!empty($this->compileCallbacks)) { + foreach ($this->compileCallbacks as $callback) { + if (is_callable($callback)) { + $callback($contents, $templateName); + } + } + } + } + + /** + * Determine if the view has expired. + * + * @param string|null $fileName + * @return bool + */ + public function isExpired($fileName): bool + { + $compiled = $this->getCompiledFile($fileName); + $template = $this->getTemplateFile($fileName); + if (!\is_file($template)) { + if ($this->mode == self::MODE_DEBUG) { + $this->showError('Read file', 'Template not found :' . $this->fileName . " on file: $template", true); + } else { + $this->showError('Read file', 'Template not found :' . $this->fileName, true); + } + } + // If the compiled file doesn't exist we will indicate that the view is expired + // so that it can be re-compiled. Else, we will verify the last modification + // of the views is less than the modification times of the compiled views. + if (!$this->compiledPath || !\is_file($compiled)) { + return true; + } + return \filemtime($compiled) < \filemtime($template); + } + + /** + * Evaluates a text (string) using the current variables + * + * @param string $content + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluateText($content, $variables): string + { + \ob_start(); + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + eval(' ?>' . $content . $this->phpTag); + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * Handle a view exception. + * + * @param Exception $e + * @return void + * @throws $e + */ + protected function handleViewException($e): void + { + \ob_get_clean(); + throw $e; + } + + /** + * Evaluates a compiled file using the current variables + * + * @param string $compiledFile full path of the compile file. + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluatePath($compiledFile, $variables): string + { + \ob_start(); + // note, the variables are extracted locally inside this method, + // they are not global variables :-3 + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + include $compiledFile; + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * @param array $views array of views + * @param array $value + * @return string + * @throws Exception + */ + public function includeFirst($views = [], $value = []): string + { + foreach ($views as $view) { + if ($this->templateExist($view)) { + return $this->runChild($view, $value); + } + } + return ''; + } + + /** + * Returns true if the template exists. Otherwise, it returns false + * + * @param $templateName + * @return bool + */ + protected function templateExist($templateName): bool + { + $file = $this->getTemplateFile($templateName); + return \is_file($file); + } + + /** + * Convert an array such as ["class1"=>"myclass","style="mystyle"] to class1='myclass' style='mystyle' string + * + * @param array|string $array array to convert + * @return string + */ + public function convertArg($array): string + { + if (!\is_array($array)) { + return $array; // nothing to convert. + } + return \implode(' ', \array_map('static::convertArgCallBack', \array_keys($array), $array)); + } + + /** + * Returns the current token. if there is not a token then it generates a new one. + * It could require an open session. + * + * @param bool $fullToken It returns a token with the current ip. + * @param string $tokenId [optional] Name of the token. + * + * @return string + */ + public function getCsrfToken($fullToken = false, $tokenId = '_token'): string + { + if ($this->csrf_token == '') { + $this->regenerateToken($tokenId); + } + if ($fullToken) { + return $this->csrf_token . '|' . $this->ipClient(); + } + return $this->csrf_token; + } + + /** + * Regenerates the csrf token and stores in the session. + * It requires an open session. + * + * @param string $tokenId [optional] Name of the token. + */ + public function regenerateToken($tokenId = '_token'): void + { + try { + $this->csrf_token = \bin2hex(\random_bytes(10)); + } catch (Exception $e) { + $this->csrf_token = '123456789012345678901234567890'; // unable to generates a random token. + } + @$_SESSION[$tokenId] = $this->csrf_token . '|' . $this->ipClient(); + } + + public function ipClient() + { + if ( + isset($_SERVER['HTTP_X_FORWARDED_FOR']) + && \preg_match('/^(d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})$/', $_SERVER['HTTP_X_FORWARDED_FOR']) + ) { + return $_SERVER['HTTP_X_FORWARDED_FOR']; + } + return $_SERVER['REMOTE_ADDR'] ?? ''; + } + + /** + * Validates if the csrf token is valid or not.'; + \var_dump($object); + echo ''; + } else { + /** @noinspection BadExpressionStatementJS */ + /** @noinspection JSVoidFunctionReturnValueUsed */ + echo ''; + } + } + + /** + * Start injecting content into a section. + * + * @param string $section + * @param string $content + * @return void + */ + public function startSection($section, $content = ''): void + { + if ($content === '') { + \ob_start() && $this->sectionStack[] = $section; + } else { + $this->extendSection($section, $content); + } + } + + /** + * Stop injecting content into a section and append it. + * + * @return string + * @throws InvalidArgumentException + */ + public function appendSection(): string + { + if (empty($this->sectionStack)) { + $this->showError('appendSection', 'Cannot end a section without first starting one.', true, true); + } + $last = \array_pop($this->sectionStack); + if (isset($this->sections[$last])) { + $this->sections[$last] .= \ob_get_clean(); + } else { + $this->sections[$last] = \ob_get_clean(); + } + return $last; + } + + /** + * Adds a global variable. If $varname is an array then it merges all the values. + * Example: + *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable or, it is an associative array
+ * @param mixed $value
+ * @return $this
+ * @see BladeOne::share
+ */
+ public function with($varname, $value = null): BladeOne
+ {
+ return $this->share($varname, $value);
+ }
+
+ /**
+ * Adds a global variable. If $varname is an array then it merges all the values.
+ * Example:
+ *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable, or it is an associative array
+ * @param mixed $value
+ * @return $this
+ */
+ public function share($varname, $value = null): BladeOne
+ {
+ if (is_array($varname)) {
+ $this->variablesGlobal = \array_merge($this->variablesGlobal, $varname);
+ } else {
+ $this->variablesGlobal[$varname] = $value;
+ }
+ return $this;
+ }
+
+ /**
+ * Get the string contents of a section.
+ *
+ * @param string $section
+ * @param string $default
+ * @return string
+ */
+ public function yieldContent($section, $default = ''): string
+ {
+ if (isset($this->sections[$section])) {
+ return \str_replace($this->PARENTKEY, $default, $this->sections[$section]);
+ }
+
+ return $default;
+ }
+
+ /**
+ * Register a custom Blade compiler.
+ *
+ * @param callable $compiler
+ * @return void
+ */
+ public function extend(callable $compiler): void
+ {
+ $this->extensions[] = $compiler;
+ }
+
+ /**
+ * Register a handler for custom directives for run at runtime
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directiveRT($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = true;
+ }
+
+ /**
+ * Sets the escaped content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @return void
+ */
+ public function setEscapedContentTags($openTag, $closeTag): void
+ {
+ $this->setContentTags($openTag, $closeTag, true);
+ }
+
+ /**
+ * Gets the content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getContentTags(): array
+ {
+ return $this->getTags();
+ }
+
+ /**
+ * Sets the content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @param bool $escaped
+ * @return void
+ */
+ public function setContentTags($openTag, $closeTag, $escaped = false): void
+ {
+ $property = ($escaped === true) ? 'escapedTags' : 'contentTags';
+ $this->{$property} = [\preg_quote($openTag), \preg_quote($closeTag)];
+ }
+
+ /**
+ * Gets the tags used for the compiler.
+ *
+ * @param bool $escaped
+ * @return array
+ */
+ protected function getTags($escaped = false): array
+ {
+ $tags = $escaped ? $this->escapedTags : $this->contentTags;
+ return \array_map('stripcslashes', $tags);
+ }
+
+ /**
+ * Gets the escaped content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getEscapedContentTags(): array
+ {
+ return $this->getTags(true);
+ }
+
+ /**
+ * Sets the function used for resolving classes with inject.
+ *
+ * @param callable $function
+ */
+ public function setInjectResolver(callable $function): void
+ {
+ $this->injectResolver = $function;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getFileExtension(): string
+ {
+ return $this->fileExtension;
+ }
+
+ /**
+ * Set the file extension for the template files.
+ * It must include the leading dot e.g. ".blade.php"
+ *
+ * @param string $fileExtension Example: .prefix.ext
+ */
+ public function setFileExtension($fileExtension): void
+ {
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getCompiledExtension(): string
+ {
+ return $this->compileExtension;
+ }
+
+ /**
+ * Set the file extension for the compiled files.
+ * Including the leading dot for the extension is required, e.g. ".bladec"
+ *
+ * @param $fileExtension
+ */
+ public function setCompiledExtension($fileExtension): void
+ {
+ $this->compileExtension = $fileExtension;
+ }
+ /**
+ * @return string
+ * @see BladeOne::setCompileTypeFileName
+ */
+ public function getCompileTypeFileName(): string
+ {
+ return $this->compileTypeFileName;
+ }
+
+ /**
+ * It determines how the compiled filename will be called.
+ * $this->setView('folder.view')->share(['var1'=>20])->run(); // or $this->run('folder.view',['var1'=>20]);
+ *
+ *
+ * @param string $view
+ * @return BladeOne
+ */
+ public function setView($view): BladeOne
+ {
+ $this->viewStack = $view;
+ return $this;
+ }
+
+ /**
+ * It injects a function, an instance, or a method class when a view is called.
+ * $this->composer('folder.view',function($bladeOne) { $bladeOne->share('newvalue','hi there'); });
+ * $this->composer('folder.view','namespace1\namespace2\SomeClass'); // SomeClass must exist, and it must have the
+ * // method 'composer'
+ * $this->composer('folder.*',$instance); // $instance must have the method called 'composer'
+ * $this->composer(); // clear all composer.
+ *
+ *
+ * @param string|array|null $view It could contain wildcards (*). Example: 'aa.bb.cc','*.bb.cc','aa.bb.*','*.bb.*'
+ *
+ * @param callable|string|null $functionOrClass
+ * @return BladeOne
+ */
+ public function composer($view = null, $functionOrClass = null): BladeOne
+ {
+ if ($view === null && $functionOrClass === null) {
+ $this->composerStack = [];
+ return $this;
+ }
+ if (is_array($view)) {
+ foreach ($view as $v) {
+ $this->composerStack[$v] = $functionOrClass;
+ }
+ } else {
+ $this->composerStack[$view] = $functionOrClass;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Start a component rendering process.
+ *
+ * @param string $name
+ * @param array $data
+ * @return void
+ */
+ public function startComponent($name, array $data = []): void
+ {
+ if (\ob_start()) {
+ $this->componentStack[] = $name;
+
+ $this->componentData[$this->currentComponent()] = $data;
+
+ $this->slots[$this->currentComponent()] = [];
+ }
+ }
+
+ /**
+ * Get the index for the current component.
+ *
+ * @return int
+ */
+ protected function currentComponent(): int
+ {
+ return \count($this->componentStack) - 1;
+ }
+
+ /**
+ * Render the current component.
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function renderComponent(): string
+ {
+ //echo "
+ * $this->setBaseUrl('http://domain.dom/myblog');
+ * $this->setBaseUrl('http://domain.dom/corporate/erp');
+ * $this->setBaseUrl('http://domain.dom/blog.php?args=20'); // avoid this one.
+ * $this->setBaseUrl('http://another.dom');
+ *
+ *
+ * @param string $baseUrl Example http://www.web.com/folder https://www.web.com/folder/anotherfolder
+ * @return BladeOne
+ */
+ public function setBaseUrl($baseUrl): BladeOne
+ {
+ $this->baseUrl = \rtrim($baseUrl, '/'); // base with the url trimmed
+ $this->baseDomain = @parse_url($this->baseUrl)['host'];
+ $currentUrl = $this->getCurrentUrlCalculated();
+ if ($currentUrl === '') {
+ $this->relativePath = '';
+ return $this;
+ }
+ if (\strpos($currentUrl, $this->baseUrl) === 0) {
+ $part = \str_replace($this->baseUrl, '', $currentUrl);
+ $numf = \substr_count($part, '/') - 1;
+ $numf = ($numf > 10) ? 10 : $numf; // avoid overflow
+ $this->relativePath = ($numf < 0) ? '' : \str_repeat('../', $numf);
+ } else {
+ $this->relativePath = '';
+ }
+ return $this;
+ }
+
+ /**
+ * It gets the full current url calculated with the information sends by the user.
+ * // current url='http://domain.dom/page/subpage/web.php?aaa=2
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ *
+ * Note:The relative path is calculated when we set the base url.
+ *
+ * @return string
+ * @see BladeOne::setBaseUrl
+ */
+ public function getRelativePath(): string
+ {
+ return $this->relativePath;
+ }
+
+ /**
+ * It gets the full current canonical url.
+ * $this->addInsideQuote("'hello'"," world"); // 'hello world'
+ * $this->addInsideQuote("hello"," world"); // hello world
+ *
+ *
+ * @param $quoted
+ * @param $newFragment
+ * @return string
+ */
+ public function addInsideQuote($quoted, $newFragment): string
+ {
+ if ($this->isQuoted($quoted)) {
+ return substr($quoted, 0, -1) . $newFragment . substr($quoted, -1);
+ }
+ return $quoted . $newFragment;
+ }
+
+ /**
+ * Return true if the string is a php variable (it starts with $)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isVariablePHP($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ return $text[0] === '$';
+ }
+
+ /**
+ * It's the same as "@_e", however it parses the text (using sprintf).
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _ef($phrase): string
+ {
+ $argv = \func_get_args();
+ $r = $this->_e($phrase);
+ $argv[0] = $r; // replace the first argument with the translation.
+ $result = @sprintf(...$argv);
+ return !$result ? $r : $result;
+ }
+
+ /**
+ * Tries to translate the word if it's in the array defined by BladeOneLang::$dictionary
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _e($phrase): string
+ {
+ if ((!\array_key_exists($phrase, static::$dictionary))) {
+ $this->missingTranslation($phrase);
+ return $phrase;
+ }
+
+ return static::$dictionary[$phrase];
+ }
+
+ /**
+ * Log a missing translation into the file $this->missingLog.'; var_dump$expression; echo '';?>"; + } + + /** + * Execute the case tag. + * + * @param $expression + * @return string + */ + protected function compileCase($expression): string + { + if ($this->firstCaseInSwitch) { + $this->firstCaseInSwitch = false; + return 'case ' . $expression . ': ?>'; + } + return $this->phpTag . "case $expression: ?>"; + } + + /** + * Compile the while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileWhile($expression): string + { + return $this->phpTag . "while$expression: ?>"; + } + + /** + * default tag used for switch/case + * + * @return string + */ + protected function compileDefault(): string + { + if ($this->firstCaseInSwitch) { + return $this->showError('@default', '@switch without any @case', true); + } + return $this->phpTag . 'default: ?>'; + } + + protected function compileEndSwitch(): string + { + --$this->switchCount; + if ($this->switchCount < 0) { + return $this->showError('@endswitch', 'Missing @switch', true); + } + return $this->phpTag . '} // end switch ?>'; + } + + /** + * Compile while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileInject($expression): string + { + $ex = $this->stripParentheses($expression); + $p0 = \strpos($ex, ','); + if (!$p0) { + $var = $this->stripQuotes($ex); + $namespace = ''; + } else { + $var = $this->stripQuotes(\substr($ex, 0, $p0)); + $namespace = $this->stripQuotes(\substr($ex, $p0 + 1)); + } + return $this->phpTag . "\$$var = \$this->injectClass('$namespace', '$var'); ?>"; + } + + /** + * Remove first and end quote from a quoted string of text + * + * @param mixed $text + * @return null|string|string[] + */ + public function stripQuotes($text) + { + if (!$text || strlen($text) < 2) { + return $text; + } + $text = trim($text); + $p0 = $text[0]; + $p1 = \substr($text, -1); + if ($p0 === $p1 && ($p0 === '"' || $p0 === "'")) { + return \substr($text, 1, -1); + } + return $text; + } + + /** + * Execute the user defined extensions. + * + * @param string $value + * @return string + */ + protected function compileExtensions($value): string + { + foreach ($this->extensions as $compiler) { + $value = $compiler($value, $this); + } + return $value; + } + + /** + * Compile Blade comments into valid PHP. + * + * @param string $value + * @return string + */ + protected function compileComments($value): string + { + $pattern = \sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]); + return \preg_replace($pattern, $this->phpTag . '/*$1*/ ?>', $value); + } + + /** + * Compile Blade echos into valid PHP. + * + * @param string $value + * @return string + * @throws Exception + */ + protected function compileEchos($value): string + { + foreach ($this->getEchoMethods() as $method => $length) { + $value = $this->$method($value); + } + return $value; + } + + /** + * Get the echo methods in the proper order for compilation. + * + * @return array + */ + protected function getEchoMethods(): array + { + $methods = [ + 'compileRawEchos' => \strlen(\stripcslashes($this->rawTags[0])), + 'compileEscapedEchos' => \strlen(\stripcslashes($this->escapedTags[0])), + 'compileRegularEchos' => \strlen(\stripcslashes($this->contentTags[0])), + ]; + \uksort($methods, static function ($method1, $method2) use ($methods) { + // Ensure the longest tags are processed first + if ($methods[$method1] > $methods[$method2]) { + return -1; + } + if ($methods[$method1] < $methods[$method2]) { + return 1; + } + // Otherwise, give preference to raw tags (assuming they've overridden) + if ($method1 === 'compileRawEchos') { + return -1; + } + if ($method2 === 'compileRawEchos') { + return 1; + } + if ($method1 === 'compileEscapedEchos') { + return -1; + } + if ($method2 === 'compileEscapedEchos') { + return 1; + } + throw new BadMethodCallException("Method [$method1] not defined"); + }); + return $methods; + } + + /** + * Compile Blade statements that start with "@". + * + * @param string $value + * + * @return array|string|string[]|null + */ + protected function compileStatements($value) + { + /** + * @param array $match + * [0]=full expression with @ and parenthesis + * [1]=expression without @ and argument + * [2]=???? + * [3]=argument with parenthesis and without the first @ + * [4]=argument without parenthesis. + * + * @return mixed|string + */ + $callback = function ($match) { + if (static::contains($match[1], '@')) { + // @@escaped tag + $match[0] = isset($match[3]) ? $match[1] . $match[3] : $match[1]; + } else { + if (strpos($match[1], '::') !== false) { + // Someclass::method + return $this->compileStatementClass($match); + } + if (isset($this->customDirectivesRT[$match[1]])) { + if ($this->customDirectivesRT[$match[1]]) { + $match[0] = $this->compileStatementCustom($match); + } else { + $match[0] = \call_user_func( + $this->customDirectives[$match[1]], + $this->stripParentheses(static::get($match, 3)) + ); + } + } elseif (\method_exists($this, $method = 'compile' . \ucfirst($match[1]))) { + // it calls the function compile
+ * $this->parseArgs('a=2,b='a,b,c',d'); // ['a'=>'2','b'=>'a,b,c','d'=>null]
+ * $this->parseArgs('a=2,b=c,d'); // ['a'=>'2','b'=>'c','d'=>null]
+ * $this->parseArgs('a=2 b=c',' '); // ['a'=>'2','b'=>'c']
+ * $this->parseArgs('a:2 b:c',' ',':'); // ['a'=>'2','b'=>'c']
+ *
+ * Note: parseArgs('a = 2 b = c',' '); with return 4 values instead of 2.
+ *
+ * @param string $text the text to separate
+ * @param string $separator the separator of arguments
+ * @param string $assigment the character used to assign a new value
+ * @param bool $emptyKey if the argument is without value, we return it as key (true) or value (false) ?
+ * @return array
+ */
+ public function parseArgs($text, $separator = ',', $assigment = '=', $emptyKey = true): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = $text; // str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = strlen($chars);
+ $stringArr = '"\'¬';
+ $parenthesis = '([{';
+ $parenthesisClose = ')]}';
+ $insidePar = false;
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ // we check if the character is a parenthesis.
+ $pp = strpos($parenthesis, $char);
+ if ($pp !== false) {
+ // is a parenthesis, so we mark as inside a parenthesis.
+ $insidePar = $parenthesisClose[$pp];
+ }
+ if ($char === $insidePar) {
+ // we close the parenthesis.
+ $insidePar = false;
+ }
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ // we found a string initializer
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator && !$insidePar) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ // duct taping for key= argument (it has a space). however, it doesn't work with key =argument
+ /*
+ foreach ($parts as $k=>$part) {
+ if(substr($part,-1)===$assigment && isset($parts[$k+1])) {
+ var_dump('ok');
+ $parts[$k].=$parts[$k+1];
+ unset($parts[$k+1]);
+ }
+ }
+ */
+ foreach ($parts as $part) {
+ $part = trim($part);
+ if ($part) {
+ $char = $part[0];
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ if ($emptyKey) {
+ $result[$part] = null;
+ } else {
+ $result[] = $part;
+ }
+ } else {
+ $r = explode($assigment, $part, 2);
+ if (count($r) === 2) {
+ // key=value.
+ $result[trim($r[0])] = trim($r[1]);
+ } elseif ($emptyKey) {
+ $result[trim($r[0])] = null;
+ } else {
+ $result[] = trim($r[0]);
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function parseArgsOld($text, $separator = ','): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = count($chars);
+ /** @noinspection ForeachInvariantsInspection */
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ if ($char === '"' || $char === "'") {
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ foreach ($parts as $part) {
+ $r = explode('=', $part, 2);
+ $result[trim($r[0])] = count($r) === 2 ? trim($r[1]) : null;
+ }
+ return $result;
+ }
+
+ /**
+ * Compile the "raw" echo statements.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRawEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ return $matches[1] ? \substr(
+ $matches[0],
+ 1
+ ) : $this->phpTagEcho . $this->compileEchoDefaults($matches[2]) . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the default values for the echo statement.
+ * Example:
+ * {{ $test or 'test2' }} compiles to {{ isset($test) ? $test : 'test2' }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEchoDefaults($value): string
+ {
+ // Source: https://www.php.net/manual/en/language.variables.basics.php
+ $patternPHPVariableName = '\$[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*';
+
+ $result = \preg_replace('/^(' . $patternPHPVariableName . ')\s+or\s+(.+?)$/s', 'isset($1) ? $1 : $2', $value);
+ if (!$this->pipeEnable) {
+ return $this->fixNamespaceClass($result);
+ }
+ return $this->pipeDream($this->fixNamespaceClass($result));
+ }
+
+ /**
+ * It converts a string separated by pipes | into a filtered expression.
+ * $this->pipeDream('$name | strtolower | substr:0,4'); // strtolower(substr($name ,0,4)
+ * $this->pipeDream('$name| getMode') // $this->getMode($name)
+ *
+ *
+ * @param string $result
+ * @return string
+ * @\eftec\bladeone\BladeOne::$pipeEnable
+ */
+ protected function pipeDream($result): string
+ {
+ $array = preg_split('~\\\\.(*SKIP)(*FAIL)|\|~s', $result);
+ $c = count($array) - 1; // base zero.
+ if ($c === 0) {
+ return $result;
+ }
+ $prev = '';
+ for ($i = 1; $i <=$c; $i++) {
+ $r = @explode(':', $array[$i], 2);
+ $fnName = trim($r[0]);
+ $fnNameF = $fnName[0]; // first character
+ if ($fnNameF === '"' || $fnNameF === '\'' || $fnNameF === '$' || is_numeric($fnNameF)) {
+ $fnName = '!isset(' . $array[0] . ') ? ' . $fnName . ' : ';
+ } elseif (isset($this->customDirectives[$fnName])) {
+ $fnName = '$this->customDirectives[\'' . $fnName . '\']';
+ } elseif (method_exists($this, $fnName)) {
+ $fnName = '$this->' . $fnName;
+ }
+ $hasArgument=count($r) === 2;
+ if ($i === 1) {
+ $prev = $fnName . '(' . $array[0];
+ if ($hasArgument) {
+ $prev .= ',' . $r[1];
+ }
+ $prev .= ')';
+ } else {
+ $prev = $fnName . '(' . $prev;
+ if ($hasArgument) {
+ $prev .=','. $r[1] . ')';
+ } else {
+ $prev.=')';
+ }
+ }
+ }
+
+ return $prev;
+ }
+
+ /**
+ * Compile the "regular" echo statements. {{ }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRegularEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ $wrapped = \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
+ return $matches[1] ? \substr($matches[0], 1) : $this->phpTagEcho . $wrapped . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the escaped echo statements. {!! !!}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEscapedEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+
+ return $matches[1] ? $matches[0] : $this->phpTag
+ . \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2])) . '; ?>'
+ . $whitespace;
+ //return $matches[1] ? $matches[0] : $this->phpTag
+ // . 'echo static::e(' . $this->compileEchoDefaults($matches[2]) . '); ? >' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the "@each" tag into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileEach($expression): string
+ {
+ return $this->phpTagEcho . "\$this->renderEach$expression; ?>";
+ }
+
+ protected function compileSet($expression): string
+ {
+ //$segments = \explode('=', \preg_replace("/[()\\\']/", '', $expression));
+ $segments = \explode('=', $this->stripParentheses($expression));
+ $value = (\count($segments) >= 2) ? '=@' . implode('=', array_slice($segments, 1)) : '++';
+ return $this->phpTag . \trim($segments[0]) . $value . ';?>';
+ }
+
+ /**
+ * Compile the yield statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileYield($expression): string
+ {
+ return $this->phpTagEcho . "\$this->yieldContent$expression; ?>";
+ }
+
+ /**
+ * Compile the show statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileShow(): string
+ {
+ return $this->phpTagEcho . '$this->yieldSection(); ?>';
+ }
+
+ /**
+ * Compile the section statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileSection($expression): string
+ {
+ return $this->phpTag . "\$this->startSection$expression; ?>";
+ }
+
+ /**
+ * Compile the append statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileAppend(): string
+ {
+ return $this->phpTag . '$this->appendSection(); ?>';
+ }
+
+ /**
+ * Compile the auth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'if(isset($this->currentUser)): ?>';
+ }
+
+ return $this->phpTag . "if(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the elseauth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'else: ?>';
+ }
+
+ return $this->phpTag . "elseif(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the end-auth statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndAuth(): string
+ {
+ return $this->phpTag . 'endif; ?>';
+ }
+
+ protected function compileCan($expression): string
+ {
+ $v = $this->stripParentheses($expression);
+ return $this->phpTag . 'if (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ /**
+ * Compile the else statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseCan($expression = ''): string
+ {
+ $v = $this->stripParentheses($expression);
+ if ($v) {
+ return $this->phpTag . 'elseif (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ return $this->phpTag . 'else: ?>';
+ }
+ //
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCache
+ * @version 3.42 2020-04-25
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCacheRedis
+ * @version 0.1 2017-12-15 NOT YET IMPLEMENTED, ITS A WIP!!!!!!!!
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Der Controller inkludiert das benötigte Model (gerichte.php in diesem Fall)
+ und ruft die benötigte Funktion db_gerichte_select_all() zum Laden der Daten auf
Kurze Übersicht, wie die Arbeit mit dem Router und der Blade View-Engine funktioniert.
+ +Der Router nimmt den Request entgegen und zerlegt ihn in die einzelnen Teile der URI. Wichtig ist hier vor + allem der Pfad und der Querystring.
+Wenn der Pfad in der Routenkonfiguration (\$config Array aus der Datei
+ routes/web.php) gefunden wird, lädt der Router die angegebene Klasse.
Im vorliegenden Beispiel sehen Sie diese Seite ...
+DemoController.php gefunden werden konnte
+ Sie sehen: da muss einiges stimmen und vieles davon ist Konvention.
+Die Actions in den Controller-Klassen sollen per Konvention immer ein RequestData Objekt
+ entgegennehmen. Beispiel: howto(RequestData \$rd)
Dieses RequestData Objekt wird durch den Router befüllt, wenn Daten in der URL extrahiert werden konnten.
+Daten finden sich URLs...
+ +
+ im Querystring
Beispiel: rufen Sie diese mit
+ {{strtolower(explode('/',$_SERVER["SERVER_PROTOCOL"])[0])}}://{{$_SERVER["HTTP_HOST"]}}/demo?bgcolor=fefbd8&name=Remmy
+ auf, werden bgcolor und name mitsamt Werten als Query Array
+ $rd->query) übergeben
+
Probieren Sie es aus ;)
+ @if(count($rd->args)) +Argumente dieses Aufrufs:
+ + @forelse($rd->args as $a) +Keine weiteren Argumente im Request
+ @endforelse + @endif + @if(count($rd->query)) +Daten aus der Query dieses Aufrufs:
+
+ @forelse($rd->query as $k => $v)
+ $rd->query['{{$k}}']={{$v}}
+ @empty
+ Keine Querydaten
+ @endforelse
+
+ @endif
+ Blade muss installiert sein. + Die Installation ist bereits geschehen und die Bibliothek liegt unter /vendor. +
+Bei der Verwendung der View-Engine gelten einige Konventionen:
+ Die Dateien müssen <viewname>.blade.php heißen und im Ordner views liegen.
+
Sie können der View dann Daten mitgeben, indem Sie alle Daten in ein Array schreiben und dieses dann + übergeben.
+Beispiel:
+
+ view("viewtest",
+ array(
+ "texts"=>$textArray,
+ "persona"=>$persona,
+ "rd"=>$rd
+ )); // öffnet ../views/viewtest.blade.php
+
+ combined request data
+
+ {{print_r($rd->getData(),1)}}
+
+@else
+ this request contained zero parameters
+@endif + +@if(count($rd->getGetData())) +GET request data
+ {{print_r($rd->getGetData(),1)}}
+
+@endif
+
+@if(count($rd->getPostData()))
+ POST request data
+ {{print_r($rd->getPostData(),1)}}
+
+@endif
\ No newline at end of file
diff --git a/M4/emensa/views/examples/m4_7a_queryparameter.blade.php b/M4/emensa/views/examples/m4_7a_queryparameter.blade.php
new file mode 100644
index 0000000..c094999
--- /dev/null
+++ b/M4/emensa/views/examples/m4_7a_queryparameter.blade.php
@@ -0,0 +1,13 @@
+
+
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+ Page 1
+@endsection + +@section("footer") +Footer of Page 1
+@endsection \ No newline at end of file diff --git a/M4/emensa/views/examples/pages/m4_7d_page_2.blade.php b/M4/emensa/views/examples/pages/m4_7d_page_2.blade.php new file mode 100644 index 0000000..920a59a --- /dev/null +++ b/M4/emensa/views/examples/pages/m4_7d_page_2.blade.php @@ -0,0 +1,13 @@ +@extends(".layouts.m4_7d_layout",['title' => "Page 2"]) + +@section("header") + +@endsection + +@section("body") +Page 2
+@endsection + +@section("footer") +Footer of Page 2
+@endsection \ No newline at end of file diff --git a/M4/emensa/views/home.blade.php b/M4/emensa/views/home.blade.php new file mode 100644 index 0000000..474d713 --- /dev/null +++ b/M4/emensa/views/home.blade.php @@ -0,0 +1,34 @@ +@extends("layouts.layout") + +@section("content") +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
+ {{$data['beschreibung']}}
+
+ @else
+
+ @endif
+
+@endsection
+
+@section("footer")
+
+ Sie haben eine Action aufgerufen, die zu dieser View führt.
+Vervollständigen Sie die Action, sodass die Aufgabe erfüllt wird.
+@endsection \ No newline at end of file diff --git a/M5/.idea/.gitignore b/M5/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/M5/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/M5/.idea/M4.iml b/M5/.idea/M4.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/M5/.idea/M4.iml @@ -0,0 +1,8 @@ + +DOCUMENT_ROOT: {$_SERVER['DOCUMENT_ROOT']}Datei nicht gefunden: {$_SERVER['DOCUMENT_ROOT']}/../vendor/autoload.php
"; + echo "Häufigste Ursache
public/ ist nicht als Wurzelverzeichnis verwendet worden.composer update installiert.DOCUMENT_ROOT{$_SERVER['DOCUMENT_ROOT']}Error" . $ex->getMessage() . ""; +} + +use eftec\bladeone\BladeOne; + +/* Routing Script for PHP Dev Server */ +$verbosity = VERBOSITY; +if (preg_match('/\.(?:css|js|png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) { + return false; +} else { + if ($verbosity > 1) { + echo + "
Verbosity-Level: {$verbosity}" .
+ "" . print_r($_SERVER, 1) . "
Request\n", print_r($request), ""; + echo "
Path\n", print_r($path), ""; + echo "
Query\n", print_r($query), ""; + } + } + + // fix: trim slashes + $ctrlName = trim($ctrlName, '/'); + $actionName = trim($actionName, '/'); + + // $config based renaming of Controller/Action, precedes filebased convention + // $config values must use syntax
Routing Config matched request for /" . $ctrlName . "/" . $actionName . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } elseif (array_key_exists($request['path'], $config)) { + // exact match on full path, this also means "/" + $routingConfig = explode('@', $config[$request['path']]); + if ($verbosity > 0) { + echo "
Routing Config matched for full path " . $request['path'] . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } else { + if ($verbosity > 0) { + echo "Request $ctrlName/$actionName was not in \$config."; + } + + // fall back to filebased convention: match controller classes in directory + $ctrlClass = ucfirst($ctrlName . 'Controller'); + } + + $ctrlFile = ($ctrlClass . '.php'); + $validControllers = FrontController::getValidControllers($controllerDirectory); + if (!in_array($controllerDirectory . $ctrlFile, $validControllers)) { + if ($verbosity > 0) { + echo "
Controller: $ctrlFile not found in
" . print_r($validControllers, 1) . "
Config Array:
" . print_r($config, 1) . "
" .
+ "Keine entspreche Zuordnung der Route für {$ctrlName}::{$actionName} gefunden. Tippfehler in der Route?" . + "
Es konnte keine Klasse " . $ctrlFile . " gefunden werden! Request fehlgeschlagen.
" . + " Prüfen Sie die Einträge in der Datei config/web.php und gleichen Sie den getätigten Aufruf damit ab.
Stellen Sie sicher, dass die Action/der Controller existiert.
+Das Routing Config-Array hat " . count($config) . " Einträge.
+Exception text
" . $ex->getMessage() . "
Verbindung fehlgeschlagen: " . mysqli_connect_error() . ".
config/db.php:
+ ( ist Benutzer {$config['user']} an Datenbank {$config['database']} auf Server {$config['host']} korrekt?)Fehlermeldung" . mysqli_connect_error() . "", 2, true); + exit(1); + } + + return $link; +} + +function view($viewname, $viewargs = array()) +{ + $views = dirname(__DIR__) . '/views'; + $cache = dirname(__DIR__) . '/storage/cache'; + $blade = new BladeOne($views, $cache, BladeOne::MODE_DEBUG); + + return $blade->run($viewname, $viewargs); +} + +/** + * let the script die if the php minimum version is not met. + * @param $minversion + * @return void + */ +function assert_php_version($minversion = '8.0.0') +{ + $version_too_low = 0; + $minver = explode('.', $minversion); + $version = explode('.', phpversion()); + + if (intval($minver[0]) > intval($version[0])) { + $version_too_low = 1; + } elseif (intval($minver[1]) > intval($version[1])) { + $version_too_low = 1; + } elseif (intval($minver[2]) > intval($version[2])) { + $version_too_low = 1; + } + + if ($version_too_low) { + FrontController::showErrorMessage("Diese PHP-Version wird nicht unterstützt: Minimum PHP Version " . $minversion . "
Der Pfad " . $_SERVER['DOCUMENT_ROOT'] . " enthält " . $charsfound . " problematische Zeichen, die die korrekte Ausführung verhindern.
Bekannte problematische Zeichen sind
+ " . implode(" ", $chars) . " ");
+ exit(1);
+ }
+
+}
+
+function assert_blade(): void
+{
+ if (!class_exists('eftec\bladeone\BladeOne')) {
+ // #ERROR
+ FrontController::showErrorMessage("
+ Tipps für die Lösung:
+führen Sie im Terminal folgende Zeilen aus.
+php bin/composer.phar update oder php bin/composer.phar reinstall eftec/bladeonephp bin/composer.phar dump-autoloadPrüfen Sie im Anschluss: befindet sich in dem Ordner vendor/eftec/bladeone/lib/ die Datei BladeOne.php ?
Starten Sie dann den Webserver neu.
Befragen Sie gerne auch das Forum in Ilias.
Kurze Übersicht, wie die Arbeit mit dem Router und der Blade View-Engine funktioniert.
+ +Der Router nimmt den Request entgegen und zerlegt ihn in die einzelnen Teile der URI. Wichtig ist hier vor + allem der Pfad und der Querystring.
+Wenn der Pfad in der Routenkonfiguration (\$config Array aus der Datei
+ routes/web.php) gefunden wird, lädt der Router die angegebene Klasse.
Im vorliegenden Beispiel sehen Sie diese Seite ...
+DemoController.php gefunden werden konnte
+ Sie sehen: da muss einiges stimmen und vieles davon ist Konvention.
+Die Actions in den Controller-Klassen sollen per Konvention immer ein RequestData Objekt
+ entgegennehmen. Beispiel: howto(RequestData \$rd)
Dieses RequestData Objekt wird durch den Router befüllt, wenn Daten in der URL extrahiert werden konnten.
+Daten finden sich URLs...
+ +
+ im Querystring
Beispiel: rufen Sie diese mit
+ :///demo?bgcolor=fefbd8&name=Remmy
+ auf, werden bgcolor und name mitsamt Werten als Query Array
+ $rd->query) übergeben
+
Probieren Sie es aus ;)
+ args)): ?> +Argumente dieses Aufrufs:
+ + args as $a): $__empty_1 = false; ?> +Keine weiteren Argumente im Request
+ + + query)): ?> +Daten aus der Query dieses Aufrufs:
+
+ query as $k => $v): $__empty_1 = false; ?>
+ $rd->query['']=
+
+
+ Keine Querydaten
+
+
+
+ Blade muss installiert sein. + Die Installation ist bereits geschehen und die Bibliothek liegt unter /vendor. +
+Bei der Verwendung der View-Engine gelten einige Konventionen:
+ Die Dateien müssen <viewname>.blade.php heißen und im Ordner views liegen.
+
Sie können der View dann Daten mitgeben, indem Sie alle Daten in ein Array schreiben und dieses dann + übergeben.
+Beispiel:
+
+ view("viewtest",
+ array(
+ "texts"=>$textArray,
+ "persona"=>$persona,
+ "rd"=>$rd
+ )); // öffnet ../views/viewtest.blade.php
+
+ Fehlermeldung
++ + + + +
Fehlermeldung
++ + + +
Fehlermeldung
++ + + +
Page 1
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 1
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 1"]); } ?> \ No newline at end of file diff --git a/M5/Dossier/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec b/M5/Dossier/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec new file mode 100644 index 0000000..961375a --- /dev/null +++ b/M5/Dossier/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec @@ -0,0 +1,14 @@ + + +startSection("header"); ?> + +stopSection(); ?> + +startSection("body"); ?> +Page 2
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 2
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 2"]); } ?> \ No newline at end of file diff --git a/M5/Dossier/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec b/M5/Dossier/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec new file mode 100644 index 0000000..c54dc25 --- /dev/null +++ b/M5/Dossier/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec @@ -0,0 +1,36 @@ + + +startSection("content"); ?> +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is equals to abc
+ *
+ * Example: (includeScope=true)
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is not defined
+ *
+ */
+ public $includeScope = false;
+ /**
+ * @var callable[] It allows to parse the compiled output using a function.
+ * This function doesn't require to return a value
+ * $this->compileCallbacks[]= static function (&$content, $templatename=null) {
+ * $content=strtoupper($content);
+ * };
+ *
+ */
+ public $compileCallbacks = [];
+ /** @var array All the registered extensions. */
+ protected $extensions = [];
+ /** @var array All the finished, captured sections. */
+ protected $sections = [];
+ /** @var string The template currently being compiled. For example "folder.template" */
+ protected $fileName;
+ protected $currentView;
+ protected $notFoundPath;
+ /** @var string File extension for the template files. */
+ protected $fileExtension = '.blade.php';
+ /** @var array The stack of in-progress sections. */
+ protected $sectionStack = [];
+ /** @var array The stack of in-progress loops. */
+ protected $loopsStack = [];
+ /** @var array Dictionary of variables */
+ protected $variables = [];
+ /** @var array Dictionary of global variables */
+ protected $variablesGlobal = [];
+ /** @var array All the available compiler functions. */
+ protected $compilers = [
+ 'Extensions',
+ 'Statements',
+ 'Comments',
+ 'Echos',
+ ];
+ /** @var string|null it allows to set the stack */
+ protected $viewStack;
+ /** @var array used by $this->composer() */
+ protected $composerStack = [];
+ /** @var array The stack of in-progress push sections. */
+ protected $pushStack = [];
+ /** @var array All the finished, captured push sections. */
+ protected $pushes = [];
+ /** @var int The number of active rendering operations. */
+ protected $renderCount = 0;
+ /** @var string[] Get the template path for the compiled views. */
+ protected $templatePath;
+ /** @var string Get the compiled path for the compiled views. If null then it uses the default path */
+ protected $compiledPath;
+ /** @var string the extension of the compiled file. */
+ protected $compileExtension = '.bladec';
+ /**
+ * @var string=['auto','sha1','md5'][$i] It determines how the compiled filename will be called.
+ * $this->wrapPHP('$hello'); // "< ?php echo $this->e($hello); ? >"
+ * $this->wrapPHP('$hello',''); // < ?php echo $this->e($hello); ? >
+ * $this->wrapPHP('$hello','',false); // < ?php echo $hello; ? >
+ * $this->wrapPHP('"hello"'); // "< ?php echo $this->e("hello"); ? >"
+ * $this->wrapPHP('hello()'); // "< ?php echo $this->e(hello()); ? >"
+ *
+ *
+ * @param ?string $input The input value
+ * @param string $quote The quote used (to quote the result)
+ * @param bool $parse If the result will be parsed or not. If false then it's returned without $this->e
+ * @return string
+ */
+ public function wrapPHP($input, $quote = '"', $parse = true): string
+ {
+ if($input===null) {
+ return 'null';
+ }
+ if (strpos($input, '(') !== false && !$this->isQuoted($input)) {
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+ if (strpos($input, '$') === false) {
+ if ($parse) {
+ return self::enq($input);
+ }
+
+ return $input;
+ }
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+
+ /**
+ * Returns true if the text is surrounded by quotes (double or single quote)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isQuoted($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ if ($text[0] === '"' && substr($text, -1) === '"') {
+ return true;
+ }
+ return ($text[0] === "'" && substr($text, -1) === "'");
+ }
+
+ /**
+ * Escape HTML entities in a string.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function enq($value): string
+ {
+ if (\is_array($value) || \is_object($value)) {
+ return \htmlentities(\print_r($value, true), ENT_NOQUOTES, 'UTF-8', false);
+ }
+ return \htmlentities($value??'', ENT_NOQUOTES, 'UTF-8', false);
+ }
+
+ /**
+ * @param string $view example "folder.template"
+ * @param string|null $alias example "mynewop". If null then it uses the name of the template.
+ */
+ public function addInclude($view, $alias = null): void
+ {
+ if (!isset($alias)) {
+ $alias = \explode('.', $view);
+ $alias = \end($alias);
+ }
+ $this->directive($alias, function ($expression) use ($view) {
+ $expression = $this->stripParentheses($expression) ?: '[]';
+ return "$this->phpTag echo \$this->runChild('$view', $expression); ?>";
+ });
+ }
+
+ /**
+ * Register a handler for custom directives.
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directive($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = false;
+ }
+
+ /**
+ * Strip the parentheses from the given expression.
+ *
+ * @param string|null $expression
+ * @return string
+ */
+ public function stripParentheses($expression): string
+ {
+ if (\is_null($expression)) {
+ return '';
+ }
+
+ if (static::startsWith($expression, '(')) {
+ $expression = \substr($expression, 1, -1);
+ }
+
+ return $expression;
+ }
+
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function startsWith($haystack, $needles): bool
+ {
+ foreach ((array)$needles as $needle) {
+ if ($needle != '') {
+ if (\function_exists('mb_strpos')) {
+ if ($haystack !== null && \mb_strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ } elseif ($haystack !== null && \strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * If false then the file is not compiled, and it is executed directly from the memory.Example:setPath("somefolder","otherfolder"); + * + * @param null|string|string[] $templatePath If null then it uses the current path /views folder + * @param null|string $compiledPath If null then it uses the current path /views folder + */ + public function setPath($templatePath, $compiledPath): void + { + if ($templatePath === null) { + $templatePath = \getcwd() . '/views'; + } + if ($compiledPath === null) { + $compiledPath = \getcwd() . '/compiles'; + } + $this->templatePath = (is_array($templatePath)) ? $templatePath : [$templatePath]; + $this->compiledPath = $compiledPath; + } + + /** + * @return array + */ + public function getAliasClasses(): array + { + return $this->aliasClasses; + } + + /** + * @param array $aliasClasses + */ + public function setAliasClasses($aliasClasses): void + { + $this->aliasClasses = $aliasClasses; + } + + /** + * @param string $aliasName + * @param string $classWithNS + */ + public function addAliasClasses($aliasName, $classWithNS): void + { + $this->aliasClasses[$aliasName] = $classWithNS; + } + //
+ * Text::wildCardComparison('abcdef','abc*'); // true
+ * Text::wildCardComparison('abcdef','*def'); // true
+ * Text::wildCardComparison('abcdef','*abc*'); // true
+ * Text::wildCardComparison('abcdef','*cde*'); // true
+ * Text::wildCardComparison('abcdef','*cde'); // false
+ *
+ *
+ *
+ * @param string $text
+ * @param string|null $textWithWildcard
+ *
+ * @return bool
+ */
+ protected function wildCardComparison($text, $textWithWildcard): bool
+ {
+ if (($textWithWildcard === null || $textWithWildcard === '')
+ || strpos($textWithWildcard, '*') === false
+ ) {
+ // if the text with wildcard is null or empty, or it contains two ** or it contains no * then..
+ return $text == $textWithWildcard;
+ }
+ if ($textWithWildcard === '*' || $textWithWildcard === '**') {
+ return true;
+ }
+ $c0 = $textWithWildcard[0];
+ $c1 = substr($textWithWildcard, -1);
+ $textWithWildcardClean = str_replace('*', '', $textWithWildcard);
+ $p0 = strpos($text, $textWithWildcardClean);
+ if ($p0 === false) {
+ // no matches.
+ return false;
+ }
+ if ($c0 === '*' && $c1 === '*') {
+ // $textWithWildcard='*asasasas*'
+ return true;
+ }
+ if ($c1 === '*') {
+ // $textWithWildcard='asasasas*'
+ return $p0 === 0;
+ }
+ // $textWithWildcard='*asasasas'
+ $len = strlen($textWithWildcardClean);
+ return (substr($text, -$len) === $textWithWildcardClean);
+ }
+
+ protected function methodExistsStatic($class, $method): bool
+ {
+ try {
+ return (new \ReflectionMethod($class, $method))->isStatic();
+ } catch (\ReflectionException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Compile the view at the given path.
+ *
+ * @param string $templateName The name of the template. Example folder.template
+ * @param bool $forced If the compilation will be forced (always compile) or not.
+ * @return boolean|string True if the operation was correct, or false (if not exception)
+ * if it fails. It returns a string (the content compiled) if isCompiled=false
+ * @throws Exception
+ */
+ public function compile($templateName = null, $forced = false)
+ {
+ $compiled = $this->getCompiledFile($templateName);
+ $template = $this->getTemplateFile($templateName);
+ if (!$this->isCompiled) {
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ return $contents;
+ }
+ if ($forced || $this->isExpired($templateName)) {
+ // compile the original file
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ if ($this->optimize) {
+ // removes space and tabs and replaces by a single space
+ $contents = \preg_replace('/^ {2,}/m', ' ', $contents);
+ $contents = \preg_replace('/^\t{2,}/m', ' ', $contents);
+ }
+ $ok = @\file_put_contents($compiled, $contents);
+ if ($ok === false) {
+ $this->showError(
+ 'Compiling',
+ "Unable to save the file [$compiled]. Check the compile folder is defined and has the right permission"
+ );
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get the full path of the compiled file.
+ *
+ * @param string $templateName
+ * @return string
+ */
+ public function getCompiledFile($templateName = ''): string
+ {
+ $templateName = (empty($templateName)) ? $this->fileName : $templateName;
+
+ $fullPath = $this->getTemplateFile($templateName);
+ if($fullPath == '') {
+ throw new \RuntimeException('Template not found: ' . $templateName);
+ }
+
+ $style=$this->compileTypeFileName;
+ if ($style==='auto') {
+ $style='sha1';
+ }
+ $hash = $style === 'md5' ? \md5($fullPath) : \sha1($fullPath);
+ return $this->compiledPath . '/' . basename($templateName) . '_' . $hash . $this->compileExtension;
+ }
+
+
+
+ /**
+ * Get the mode of the engine.See BladeOne::MODE_* constants
+ *
+ * @return int=[self::MODE_AUTO,self::MODE_DEBUG,self::MODE_FAST,self::MODE_SLOW][$i]
+ */
+ public function getMode(): int
+ {
+ if (\defined('BLADEONE_MODE')) {
+ $this->mode = BLADEONE_MODE;
+ }
+ return $this->mode;
+ }
+
+ /**
+ * Set the compile modeExample: getTemplateFile('.abc.def')
+ * + * @param string $templateName template name. If not template is set then it uses the base template. + * @return string + */ + public function getTemplateFile($templateName = ''): string + { + $templateName = (empty($templateName)) ? $this->fileName : $templateName; + if (\strpos($templateName, '/') !== false) { + return $this->locateTemplate($templateName); // it's a literal + } + $arr = \explode('.', $templateName); + $c = \count($arr); + if ($c == 1) { + // it's in the root of the template folder. + return $this->locateTemplate($templateName . $this->fileExtension); + } + + $file = $arr[$c - 1]; + \array_splice($arr, $c - 1, $c - 1); // delete the last element + $path = \implode('/', $arr); + return $this->locateTemplate($path . '/' . $file . $this->fileExtension); + } + + /** + * Find template file with the given name in all template paths in the order the paths were written + * + * @param string $name Filename of the template (without path) + * @return string template file + */ + protected function locateTemplate($name): string + { + $this->notFoundPath = ''; + foreach ($this->templatePath as $dir) { + $path = $dir . '/' . $name; + if (\is_file($path)) { + return $path; + } + + $this->notFoundPath .= $path . ","; + } + return ''; + } + + /** + * Get the contents of a file. + * + * @param string $fullFileName It gets the content of a filename or returns ''. + * + * @return string + */ + public function getFile($fullFileName): string + { + if (\is_file($fullFileName)) { + return \file_get_contents($fullFileName); + } + $this->showError('getFile', "File does not exist at paths (separated by comma) [$this->notFoundPath] or permission denied"); + return ''; + } + + protected function compileCallBacks(&$contents, $templateName): void + { + if (!empty($this->compileCallbacks)) { + foreach ($this->compileCallbacks as $callback) { + if (is_callable($callback)) { + $callback($contents, $templateName); + } + } + } + } + + /** + * Determine if the view has expired. + * + * @param string|null $fileName + * @return bool + */ + public function isExpired($fileName): bool + { + $compiled = $this->getCompiledFile($fileName); + $template = $this->getTemplateFile($fileName); + if (!\is_file($template)) { + if ($this->mode == self::MODE_DEBUG) { + $this->showError('Read file', 'Template not found :' . $this->fileName . " on file: $template", true); + } else { + $this->showError('Read file', 'Template not found :' . $this->fileName, true); + } + } + // If the compiled file doesn't exist we will indicate that the view is expired + // so that it can be re-compiled. Else, we will verify the last modification + // of the views is less than the modification times of the compiled views. + if (!$this->compiledPath || !\is_file($compiled)) { + return true; + } + return \filemtime($compiled) < \filemtime($template); + } + + /** + * Evaluates a text (string) using the current variables + * + * @param string $content + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluateText($content, $variables): string + { + \ob_start(); + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + eval(' ?>' . $content . $this->phpTag); + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * Handle a view exception. + * + * @param Exception $e + * @return void + * @throws $e + */ + protected function handleViewException($e): void + { + \ob_get_clean(); + throw $e; + } + + /** + * Evaluates a compiled file using the current variables + * + * @param string $compiledFile full path of the compile file. + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluatePath($compiledFile, $variables): string + { + \ob_start(); + // note, the variables are extracted locally inside this method, + // they are not global variables :-3 + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + include $compiledFile; + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * @param array $views array of views + * @param array $value + * @return string + * @throws Exception + */ + public function includeFirst($views = [], $value = []): string + { + foreach ($views as $view) { + if ($this->templateExist($view)) { + return $this->runChild($view, $value); + } + } + return ''; + } + + /** + * Returns true if the template exists. Otherwise, it returns false + * + * @param $templateName + * @return bool + */ + protected function templateExist($templateName): bool + { + $file = $this->getTemplateFile($templateName); + return \is_file($file); + } + + /** + * Convert an array such as ["class1"=>"myclass","style="mystyle"] to class1='myclass' style='mystyle' string + * + * @param array|string $array array to convert + * @return string + */ + public function convertArg($array): string + { + if (!\is_array($array)) { + return $array; // nothing to convert. + } + return \implode(' ', \array_map('static::convertArgCallBack', \array_keys($array), $array)); + } + + /** + * Returns the current token. if there is not a token then it generates a new one. + * It could require an open session. + * + * @param bool $fullToken It returns a token with the current ip. + * @param string $tokenId [optional] Name of the token. + * + * @return string + */ + public function getCsrfToken($fullToken = false, $tokenId = '_token'): string + { + if ($this->csrf_token == '') { + $this->regenerateToken($tokenId); + } + if ($fullToken) { + return $this->csrf_token . '|' . $this->ipClient(); + } + return $this->csrf_token; + } + + /** + * Regenerates the csrf token and stores in the session. + * It requires an open session. + * + * @param string $tokenId [optional] Name of the token. + */ + public function regenerateToken($tokenId = '_token'): void + { + try { + $this->csrf_token = \bin2hex(\random_bytes(10)); + } catch (Exception $e) { + $this->csrf_token = '123456789012345678901234567890'; // unable to generates a random token. + } + @$_SESSION[$tokenId] = $this->csrf_token . '|' . $this->ipClient(); + } + + public function ipClient() + { + if ( + isset($_SERVER['HTTP_X_FORWARDED_FOR']) + && \preg_match('/^(d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})$/', $_SERVER['HTTP_X_FORWARDED_FOR']) + ) { + return $_SERVER['HTTP_X_FORWARDED_FOR']; + } + return $_SERVER['REMOTE_ADDR'] ?? ''; + } + + /** + * Validates if the csrf token is valid or not.'; + \var_dump($object); + echo ''; + } else { + /** @noinspection BadExpressionStatementJS */ + /** @noinspection JSVoidFunctionReturnValueUsed */ + echo ''; + } + } + + /** + * Start injecting content into a section. + * + * @param string $section + * @param string $content + * @return void + */ + public function startSection($section, $content = ''): void + { + if ($content === '') { + \ob_start() && $this->sectionStack[] = $section; + } else { + $this->extendSection($section, $content); + } + } + + /** + * Stop injecting content into a section and append it. + * + * @return string + * @throws InvalidArgumentException + */ + public function appendSection(): string + { + if (empty($this->sectionStack)) { + $this->showError('appendSection', 'Cannot end a section without first starting one.', true, true); + } + $last = \array_pop($this->sectionStack); + if (isset($this->sections[$last])) { + $this->sections[$last] .= \ob_get_clean(); + } else { + $this->sections[$last] = \ob_get_clean(); + } + return $last; + } + + /** + * Adds a global variable. If $varname is an array then it merges all the values. + * Example: + *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable or, it is an associative array
+ * @param mixed $value
+ * @return $this
+ * @see BladeOne::share
+ */
+ public function with($varname, $value = null): BladeOne
+ {
+ return $this->share($varname, $value);
+ }
+
+ /**
+ * Adds a global variable. If $varname is an array then it merges all the values.
+ * Example:
+ *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable, or it is an associative array
+ * @param mixed $value
+ * @return $this
+ */
+ public function share($varname, $value = null): BladeOne
+ {
+ if (is_array($varname)) {
+ $this->variablesGlobal = \array_merge($this->variablesGlobal, $varname);
+ } else {
+ $this->variablesGlobal[$varname] = $value;
+ }
+ return $this;
+ }
+
+ /**
+ * Get the string contents of a section.
+ *
+ * @param string $section
+ * @param string $default
+ * @return string
+ */
+ public function yieldContent($section, $default = ''): string
+ {
+ if (isset($this->sections[$section])) {
+ return \str_replace($this->PARENTKEY, $default, $this->sections[$section]);
+ }
+
+ return $default;
+ }
+
+ /**
+ * Register a custom Blade compiler.
+ *
+ * @param callable $compiler
+ * @return void
+ */
+ public function extend(callable $compiler): void
+ {
+ $this->extensions[] = $compiler;
+ }
+
+ /**
+ * Register a handler for custom directives for run at runtime
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directiveRT($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = true;
+ }
+
+ /**
+ * Sets the escaped content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @return void
+ */
+ public function setEscapedContentTags($openTag, $closeTag): void
+ {
+ $this->setContentTags($openTag, $closeTag, true);
+ }
+
+ /**
+ * Gets the content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getContentTags(): array
+ {
+ return $this->getTags();
+ }
+
+ /**
+ * Sets the content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @param bool $escaped
+ * @return void
+ */
+ public function setContentTags($openTag, $closeTag, $escaped = false): void
+ {
+ $property = ($escaped === true) ? 'escapedTags' : 'contentTags';
+ $this->{$property} = [\preg_quote($openTag), \preg_quote($closeTag)];
+ }
+
+ /**
+ * Gets the tags used for the compiler.
+ *
+ * @param bool $escaped
+ * @return array
+ */
+ protected function getTags($escaped = false): array
+ {
+ $tags = $escaped ? $this->escapedTags : $this->contentTags;
+ return \array_map('stripcslashes', $tags);
+ }
+
+ /**
+ * Gets the escaped content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getEscapedContentTags(): array
+ {
+ return $this->getTags(true);
+ }
+
+ /**
+ * Sets the function used for resolving classes with inject.
+ *
+ * @param callable $function
+ */
+ public function setInjectResolver(callable $function): void
+ {
+ $this->injectResolver = $function;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getFileExtension(): string
+ {
+ return $this->fileExtension;
+ }
+
+ /**
+ * Set the file extension for the template files.
+ * It must include the leading dot e.g. ".blade.php"
+ *
+ * @param string $fileExtension Example: .prefix.ext
+ */
+ public function setFileExtension($fileExtension): void
+ {
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getCompiledExtension(): string
+ {
+ return $this->compileExtension;
+ }
+
+ /**
+ * Set the file extension for the compiled files.
+ * Including the leading dot for the extension is required, e.g. ".bladec"
+ *
+ * @param $fileExtension
+ */
+ public function setCompiledExtension($fileExtension): void
+ {
+ $this->compileExtension = $fileExtension;
+ }
+ /**
+ * @return string
+ * @see BladeOne::setCompileTypeFileName
+ */
+ public function getCompileTypeFileName(): string
+ {
+ return $this->compileTypeFileName;
+ }
+
+ /**
+ * It determines how the compiled filename will be called.
+ * $this->setView('folder.view')->share(['var1'=>20])->run(); // or $this->run('folder.view',['var1'=>20]);
+ *
+ *
+ * @param string $view
+ * @return BladeOne
+ */
+ public function setView($view): BladeOne
+ {
+ $this->viewStack = $view;
+ return $this;
+ }
+
+ /**
+ * It injects a function, an instance, or a method class when a view is called.
+ * $this->composer('folder.view',function($bladeOne) { $bladeOne->share('newvalue','hi there'); });
+ * $this->composer('folder.view','namespace1\namespace2\SomeClass'); // SomeClass must exist, and it must have the
+ * // method 'composer'
+ * $this->composer('folder.*',$instance); // $instance must have the method called 'composer'
+ * $this->composer(); // clear all composer.
+ *
+ *
+ * @param string|array|null $view It could contain wildcards (*). Example: 'aa.bb.cc','*.bb.cc','aa.bb.*','*.bb.*'
+ *
+ * @param callable|string|null $functionOrClass
+ * @return BladeOne
+ */
+ public function composer($view = null, $functionOrClass = null): BladeOne
+ {
+ if ($view === null && $functionOrClass === null) {
+ $this->composerStack = [];
+ return $this;
+ }
+ if (is_array($view)) {
+ foreach ($view as $v) {
+ $this->composerStack[$v] = $functionOrClass;
+ }
+ } else {
+ $this->composerStack[$view] = $functionOrClass;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Start a component rendering process.
+ *
+ * @param string $name
+ * @param array $data
+ * @return void
+ */
+ public function startComponent($name, array $data = []): void
+ {
+ if (\ob_start()) {
+ $this->componentStack[] = $name;
+
+ $this->componentData[$this->currentComponent()] = $data;
+
+ $this->slots[$this->currentComponent()] = [];
+ }
+ }
+
+ /**
+ * Get the index for the current component.
+ *
+ * @return int
+ */
+ protected function currentComponent(): int
+ {
+ return \count($this->componentStack) - 1;
+ }
+
+ /**
+ * Render the current component.
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function renderComponent(): string
+ {
+ //echo "
+ * $this->setBaseUrl('http://domain.dom/myblog');
+ * $this->setBaseUrl('http://domain.dom/corporate/erp');
+ * $this->setBaseUrl('http://domain.dom/blog.php?args=20'); // avoid this one.
+ * $this->setBaseUrl('http://another.dom');
+ *
+ *
+ * @param string $baseUrl Example http://www.web.com/folder https://www.web.com/folder/anotherfolder
+ * @return BladeOne
+ */
+ public function setBaseUrl($baseUrl): BladeOne
+ {
+ $this->baseUrl = \rtrim($baseUrl, '/'); // base with the url trimmed
+ $this->baseDomain = @parse_url($this->baseUrl)['host'];
+ $currentUrl = $this->getCurrentUrlCalculated();
+ if ($currentUrl === '') {
+ $this->relativePath = '';
+ return $this;
+ }
+ if (\strpos($currentUrl, $this->baseUrl) === 0) {
+ $part = \str_replace($this->baseUrl, '', $currentUrl);
+ $numf = \substr_count($part, '/') - 1;
+ $numf = ($numf > 10) ? 10 : $numf; // avoid overflow
+ $this->relativePath = ($numf < 0) ? '' : \str_repeat('../', $numf);
+ } else {
+ $this->relativePath = '';
+ }
+ return $this;
+ }
+
+ /**
+ * It gets the full current url calculated with the information sends by the user.
+ * // current url='http://domain.dom/page/subpage/web.php?aaa=2
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ *
+ * Note:The relative path is calculated when we set the base url.
+ *
+ * @return string
+ * @see BladeOne::setBaseUrl
+ */
+ public function getRelativePath(): string
+ {
+ return $this->relativePath;
+ }
+
+ /**
+ * It gets the full current canonical url.
+ * $this->addInsideQuote("'hello'"," world"); // 'hello world'
+ * $this->addInsideQuote("hello"," world"); // hello world
+ *
+ *
+ * @param $quoted
+ * @param $newFragment
+ * @return string
+ */
+ public function addInsideQuote($quoted, $newFragment): string
+ {
+ if ($this->isQuoted($quoted)) {
+ return substr($quoted, 0, -1) . $newFragment . substr($quoted, -1);
+ }
+ return $quoted . $newFragment;
+ }
+
+ /**
+ * Return true if the string is a php variable (it starts with $)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isVariablePHP($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ return $text[0] === '$';
+ }
+
+ /**
+ * It's the same as "@_e", however it parses the text (using sprintf).
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _ef($phrase): string
+ {
+ $argv = \func_get_args();
+ $r = $this->_e($phrase);
+ $argv[0] = $r; // replace the first argument with the translation.
+ $result = @sprintf(...$argv);
+ return !$result ? $r : $result;
+ }
+
+ /**
+ * Tries to translate the word if it's in the array defined by BladeOneLang::$dictionary
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _e($phrase): string
+ {
+ if ((!\array_key_exists($phrase, static::$dictionary))) {
+ $this->missingTranslation($phrase);
+ return $phrase;
+ }
+
+ return static::$dictionary[$phrase];
+ }
+
+ /**
+ * Log a missing translation into the file $this->missingLog.'; var_dump$expression; echo '';?>"; + } + + /** + * Execute the case tag. + * + * @param $expression + * @return string + */ + protected function compileCase($expression): string + { + if ($this->firstCaseInSwitch) { + $this->firstCaseInSwitch = false; + return 'case ' . $expression . ': ?>'; + } + return $this->phpTag . "case $expression: ?>"; + } + + /** + * Compile the while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileWhile($expression): string + { + return $this->phpTag . "while$expression: ?>"; + } + + /** + * default tag used for switch/case + * + * @return string + */ + protected function compileDefault(): string + { + if ($this->firstCaseInSwitch) { + return $this->showError('@default', '@switch without any @case', true); + } + return $this->phpTag . 'default: ?>'; + } + + protected function compileEndSwitch(): string + { + --$this->switchCount; + if ($this->switchCount < 0) { + return $this->showError('@endswitch', 'Missing @switch', true); + } + return $this->phpTag . '} // end switch ?>'; + } + + /** + * Compile while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileInject($expression): string + { + $ex = $this->stripParentheses($expression); + $p0 = \strpos($ex, ','); + if (!$p0) { + $var = $this->stripQuotes($ex); + $namespace = ''; + } else { + $var = $this->stripQuotes(\substr($ex, 0, $p0)); + $namespace = $this->stripQuotes(\substr($ex, $p0 + 1)); + } + return $this->phpTag . "\$$var = \$this->injectClass('$namespace', '$var'); ?>"; + } + + /** + * Remove first and end quote from a quoted string of text + * + * @param mixed $text + * @return null|string|string[] + */ + public function stripQuotes($text) + { + if (!$text || strlen($text) < 2) { + return $text; + } + $text = trim($text); + $p0 = $text[0]; + $p1 = \substr($text, -1); + if ($p0 === $p1 && ($p0 === '"' || $p0 === "'")) { + return \substr($text, 1, -1); + } + return $text; + } + + /** + * Execute the user defined extensions. + * + * @param string $value + * @return string + */ + protected function compileExtensions($value): string + { + foreach ($this->extensions as $compiler) { + $value = $compiler($value, $this); + } + return $value; + } + + /** + * Compile Blade comments into valid PHP. + * + * @param string $value + * @return string + */ + protected function compileComments($value): string + { + $pattern = \sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]); + return \preg_replace($pattern, $this->phpTag . '/*$1*/ ?>', $value); + } + + /** + * Compile Blade echos into valid PHP. + * + * @param string $value + * @return string + * @throws Exception + */ + protected function compileEchos($value): string + { + foreach ($this->getEchoMethods() as $method => $length) { + $value = $this->$method($value); + } + return $value; + } + + /** + * Get the echo methods in the proper order for compilation. + * + * @return array + */ + protected function getEchoMethods(): array + { + $methods = [ + 'compileRawEchos' => \strlen(\stripcslashes($this->rawTags[0])), + 'compileEscapedEchos' => \strlen(\stripcslashes($this->escapedTags[0])), + 'compileRegularEchos' => \strlen(\stripcslashes($this->contentTags[0])), + ]; + \uksort($methods, static function ($method1, $method2) use ($methods) { + // Ensure the longest tags are processed first + if ($methods[$method1] > $methods[$method2]) { + return -1; + } + if ($methods[$method1] < $methods[$method2]) { + return 1; + } + // Otherwise, give preference to raw tags (assuming they've overridden) + if ($method1 === 'compileRawEchos') { + return -1; + } + if ($method2 === 'compileRawEchos') { + return 1; + } + if ($method1 === 'compileEscapedEchos') { + return -1; + } + if ($method2 === 'compileEscapedEchos') { + return 1; + } + throw new BadMethodCallException("Method [$method1] not defined"); + }); + return $methods; + } + + /** + * Compile Blade statements that start with "@". + * + * @param string $value + * + * @return array|string|string[]|null + */ + protected function compileStatements($value) + { + /** + * @param array $match + * [0]=full expression with @ and parenthesis + * [1]=expression without @ and argument + * [2]=???? + * [3]=argument with parenthesis and without the first @ + * [4]=argument without parenthesis. + * + * @return mixed|string + */ + $callback = function ($match) { + if (static::contains($match[1], '@')) { + // @@escaped tag + $match[0] = isset($match[3]) ? $match[1] . $match[3] : $match[1]; + } else { + if (strpos($match[1], '::') !== false) { + // Someclass::method + return $this->compileStatementClass($match); + } + if (isset($this->customDirectivesRT[$match[1]])) { + if ($this->customDirectivesRT[$match[1]]) { + $match[0] = $this->compileStatementCustom($match); + } else { + $match[0] = \call_user_func( + $this->customDirectives[$match[1]], + $this->stripParentheses(static::get($match, 3)) + ); + } + } elseif (\method_exists($this, $method = 'compile' . \ucfirst($match[1]))) { + // it calls the function compile
+ * $this->parseArgs('a=2,b='a,b,c',d'); // ['a'=>'2','b'=>'a,b,c','d'=>null]
+ * $this->parseArgs('a=2,b=c,d'); // ['a'=>'2','b'=>'c','d'=>null]
+ * $this->parseArgs('a=2 b=c',' '); // ['a'=>'2','b'=>'c']
+ * $this->parseArgs('a:2 b:c',' ',':'); // ['a'=>'2','b'=>'c']
+ *
+ * Note: parseArgs('a = 2 b = c',' '); with return 4 values instead of 2.
+ *
+ * @param string $text the text to separate
+ * @param string $separator the separator of arguments
+ * @param string $assigment the character used to assign a new value
+ * @param bool $emptyKey if the argument is without value, we return it as key (true) or value (false) ?
+ * @return array
+ */
+ public function parseArgs($text, $separator = ',', $assigment = '=', $emptyKey = true): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = $text; // str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = strlen($chars);
+ $stringArr = '"\'¬';
+ $parenthesis = '([{';
+ $parenthesisClose = ')]}';
+ $insidePar = false;
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ // we check if the character is a parenthesis.
+ $pp = strpos($parenthesis, $char);
+ if ($pp !== false) {
+ // is a parenthesis, so we mark as inside a parenthesis.
+ $insidePar = $parenthesisClose[$pp];
+ }
+ if ($char === $insidePar) {
+ // we close the parenthesis.
+ $insidePar = false;
+ }
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ // we found a string initializer
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator && !$insidePar) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ // duct taping for key= argument (it has a space). however, it doesn't work with key =argument
+ /*
+ foreach ($parts as $k=>$part) {
+ if(substr($part,-1)===$assigment && isset($parts[$k+1])) {
+ var_dump('ok');
+ $parts[$k].=$parts[$k+1];
+ unset($parts[$k+1]);
+ }
+ }
+ */
+ foreach ($parts as $part) {
+ $part = trim($part);
+ if ($part) {
+ $char = $part[0];
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ if ($emptyKey) {
+ $result[$part] = null;
+ } else {
+ $result[] = $part;
+ }
+ } else {
+ $r = explode($assigment, $part, 2);
+ if (count($r) === 2) {
+ // key=value.
+ $result[trim($r[0])] = trim($r[1]);
+ } elseif ($emptyKey) {
+ $result[trim($r[0])] = null;
+ } else {
+ $result[] = trim($r[0]);
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function parseArgsOld($text, $separator = ','): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = count($chars);
+ /** @noinspection ForeachInvariantsInspection */
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ if ($char === '"' || $char === "'") {
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ foreach ($parts as $part) {
+ $r = explode('=', $part, 2);
+ $result[trim($r[0])] = count($r) === 2 ? trim($r[1]) : null;
+ }
+ return $result;
+ }
+
+ /**
+ * Compile the "raw" echo statements.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRawEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ return $matches[1] ? \substr(
+ $matches[0],
+ 1
+ ) : $this->phpTagEcho . $this->compileEchoDefaults($matches[2]) . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the default values for the echo statement.
+ * Example:
+ * {{ $test or 'test2' }} compiles to {{ isset($test) ? $test : 'test2' }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEchoDefaults($value): string
+ {
+ // Source: https://www.php.net/manual/en/language.variables.basics.php
+ $patternPHPVariableName = '\$[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*';
+
+ $result = \preg_replace('/^(' . $patternPHPVariableName . ')\s+or\s+(.+?)$/s', 'isset($1) ? $1 : $2', $value);
+ if (!$this->pipeEnable) {
+ return $this->fixNamespaceClass($result);
+ }
+ return $this->pipeDream($this->fixNamespaceClass($result));
+ }
+
+ /**
+ * It converts a string separated by pipes | into a filtered expression.
+ * $this->pipeDream('$name | strtolower | substr:0,4'); // strtolower(substr($name ,0,4)
+ * $this->pipeDream('$name| getMode') // $this->getMode($name)
+ *
+ *
+ * @param string $result
+ * @return string
+ * @\eftec\bladeone\BladeOne::$pipeEnable
+ */
+ protected function pipeDream($result): string
+ {
+ $array = preg_split('~\\\\.(*SKIP)(*FAIL)|\|~s', $result);
+ $c = count($array) - 1; // base zero.
+ if ($c === 0) {
+ return $result;
+ }
+ $prev = '';
+ for ($i = 1; $i <=$c; $i++) {
+ $r = @explode(':', $array[$i], 2);
+ $fnName = trim($r[0]);
+ $fnNameF = $fnName[0]; // first character
+ if ($fnNameF === '"' || $fnNameF === '\'' || $fnNameF === '$' || is_numeric($fnNameF)) {
+ $fnName = '!isset(' . $array[0] . ') ? ' . $fnName . ' : ';
+ } elseif (isset($this->customDirectives[$fnName])) {
+ $fnName = '$this->customDirectives[\'' . $fnName . '\']';
+ } elseif (method_exists($this, $fnName)) {
+ $fnName = '$this->' . $fnName;
+ }
+ $hasArgument=count($r) === 2;
+ if ($i === 1) {
+ $prev = $fnName . '(' . $array[0];
+ if ($hasArgument) {
+ $prev .= ',' . $r[1];
+ }
+ $prev .= ')';
+ } else {
+ $prev = $fnName . '(' . $prev;
+ if ($hasArgument) {
+ $prev .=','. $r[1] . ')';
+ } else {
+ $prev.=')';
+ }
+ }
+ }
+
+ return $prev;
+ }
+
+ /**
+ * Compile the "regular" echo statements. {{ }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRegularEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ $wrapped = \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
+ return $matches[1] ? \substr($matches[0], 1) : $this->phpTagEcho . $wrapped . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the escaped echo statements. {!! !!}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEscapedEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+
+ return $matches[1] ? $matches[0] : $this->phpTag
+ . \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2])) . '; ?>'
+ . $whitespace;
+ //return $matches[1] ? $matches[0] : $this->phpTag
+ // . 'echo static::e(' . $this->compileEchoDefaults($matches[2]) . '); ? >' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the "@each" tag into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileEach($expression): string
+ {
+ return $this->phpTagEcho . "\$this->renderEach$expression; ?>";
+ }
+
+ protected function compileSet($expression): string
+ {
+ //$segments = \explode('=', \preg_replace("/[()\\\']/", '', $expression));
+ $segments = \explode('=', $this->stripParentheses($expression));
+ $value = (\count($segments) >= 2) ? '=@' . implode('=', array_slice($segments, 1)) : '++';
+ return $this->phpTag . \trim($segments[0]) . $value . ';?>';
+ }
+
+ /**
+ * Compile the yield statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileYield($expression): string
+ {
+ return $this->phpTagEcho . "\$this->yieldContent$expression; ?>";
+ }
+
+ /**
+ * Compile the show statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileShow(): string
+ {
+ return $this->phpTagEcho . '$this->yieldSection(); ?>';
+ }
+
+ /**
+ * Compile the section statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileSection($expression): string
+ {
+ return $this->phpTag . "\$this->startSection$expression; ?>";
+ }
+
+ /**
+ * Compile the append statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileAppend(): string
+ {
+ return $this->phpTag . '$this->appendSection(); ?>';
+ }
+
+ /**
+ * Compile the auth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'if(isset($this->currentUser)): ?>';
+ }
+
+ return $this->phpTag . "if(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the elseauth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'else: ?>';
+ }
+
+ return $this->phpTag . "elseif(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the end-auth statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndAuth(): string
+ {
+ return $this->phpTag . 'endif; ?>';
+ }
+
+ protected function compileCan($expression): string
+ {
+ $v = $this->stripParentheses($expression);
+ return $this->phpTag . 'if (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ /**
+ * Compile the else statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseCan($expression = ''): string
+ {
+ $v = $this->stripParentheses($expression);
+ if ($v) {
+ return $this->phpTag . 'elseif (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ return $this->phpTag . 'else: ?>';
+ }
+ //
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCache
+ * @version 3.42 2020-04-25
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCacheRedis
+ * @version 0.1 2017-12-15 NOT YET IMPLEMENTED, ITS A WIP!!!!!!!!
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Der Controller inkludiert das benötigte Model (gerichte.php in diesem Fall)
+ und ruft die benötigte Funktion db_gerichte_select_all() zum Laden der Daten auf
Kurze Übersicht, wie die Arbeit mit dem Router und der Blade View-Engine funktioniert.
+ +Der Router nimmt den Request entgegen und zerlegt ihn in die einzelnen Teile der URI. Wichtig ist hier vor + allem der Pfad und der Querystring.
+Wenn der Pfad in der Routenkonfiguration (\$config Array aus der Datei
+ routes/web.php) gefunden wird, lädt der Router die angegebene Klasse.
Im vorliegenden Beispiel sehen Sie diese Seite ...
+DemoController.php gefunden werden konnte
+ Sie sehen: da muss einiges stimmen und vieles davon ist Konvention.
+Die Actions in den Controller-Klassen sollen per Konvention immer ein RequestData Objekt
+ entgegennehmen. Beispiel: howto(RequestData \$rd)
Dieses RequestData Objekt wird durch den Router befüllt, wenn Daten in der URL extrahiert werden konnten.
+Daten finden sich URLs...
+ +
+ im Querystring
Beispiel: rufen Sie diese mit
+ {{strtolower(explode('/',$_SERVER["SERVER_PROTOCOL"])[0])}}://{{$_SERVER["HTTP_HOST"]}}/demo?bgcolor=fefbd8&name=Remmy
+ auf, werden bgcolor und name mitsamt Werten als Query Array
+ $rd->query) übergeben
+
Probieren Sie es aus ;)
+ @if(count($rd->args)) +Argumente dieses Aufrufs:
+ + @forelse($rd->args as $a) +Keine weiteren Argumente im Request
+ @endforelse + @endif + @if(count($rd->query)) +Daten aus der Query dieses Aufrufs:
+
+ @forelse($rd->query as $k => $v)
+ $rd->query['{{$k}}']={{$v}}
+ @empty
+ Keine Querydaten
+ @endforelse
+
+ @endif
+ Blade muss installiert sein. + Die Installation ist bereits geschehen und die Bibliothek liegt unter /vendor. +
+Bei der Verwendung der View-Engine gelten einige Konventionen:
+ Die Dateien müssen <viewname>.blade.php heißen und im Ordner views liegen.
+
Sie können der View dann Daten mitgeben, indem Sie alle Daten in ein Array schreiben und dieses dann + übergeben.
+Beispiel:
+
+ view("viewtest",
+ array(
+ "texts"=>$textArray,
+ "persona"=>$persona,
+ "rd"=>$rd
+ )); // öffnet ../views/viewtest.blade.php
+
+ combined request data
+
+ {{print_r($rd->getData(),1)}}
+
+@else
+ this request contained zero parameters
+@endif + +@if(count($rd->getGetData())) +GET request data
+ {{print_r($rd->getGetData(),1)}}
+
+@endif
+
+@if(count($rd->getPostData()))
+ POST request data
+ {{print_r($rd->getPostData(),1)}}
+
+@endif
\ No newline at end of file
diff --git a/M5/Dossier/emensa/views/examples/m4_7a_queryparameter.blade.php b/M5/Dossier/emensa/views/examples/m4_7a_queryparameter.blade.php
new file mode 100644
index 0000000..c094999
--- /dev/null
+++ b/M5/Dossier/emensa/views/examples/m4_7a_queryparameter.blade.php
@@ -0,0 +1,13 @@
+
+
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+ Page 1
+@endsection + +@section("footer") +Footer of Page 1
+@endsection \ No newline at end of file diff --git a/M5/Dossier/emensa/views/examples/pages/m4_7d_page_2.blade.php b/M5/Dossier/emensa/views/examples/pages/m4_7d_page_2.blade.php new file mode 100644 index 0000000..920a59a --- /dev/null +++ b/M5/Dossier/emensa/views/examples/pages/m4_7d_page_2.blade.php @@ -0,0 +1,13 @@ +@extends(".layouts.m4_7d_layout",['title' => "Page 2"]) + +@section("header") + +@endsection + +@section("body") +Page 2
+@endsection + +@section("footer") +Footer of Page 2
+@endsection \ No newline at end of file diff --git a/M5/Dossier/emensa/views/home.blade.php b/M5/Dossier/emensa/views/home.blade.php new file mode 100644 index 0000000..474d713 --- /dev/null +++ b/M5/Dossier/emensa/views/home.blade.php @@ -0,0 +1,34 @@ +@extends("layouts.layout") + +@section("content") +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
+ {{$data['beschreibung']}}
+
+ @else
+ Sie haben eine Action aufgerufen, die zu dieser View führt.
+Vervollständigen Sie die Action, sodass die Aufgabe erfüllt wird.
+@endsection \ No newline at end of file diff --git a/M5/M5.pdf b/M5/M5.pdf new file mode 100644 index 0000000..59209cb Binary files /dev/null and b/M5/M5.pdf differ diff --git a/M5/Werbeseite/besucher.txt b/M5/Werbeseite/besucher.txt new file mode 100644 index 0000000..cc4f7f3 --- /dev/null +++ b/M5/Werbeseite/besucher.txt @@ -0,0 +1 @@ +218 \ No newline at end of file diff --git a/M5/Werbeseite/fh-logo.jpg b/M5/Werbeseite/fh-logo.jpg new file mode 100644 index 0000000..33cf0b4 Binary files /dev/null and b/M5/Werbeseite/fh-logo.jpg differ diff --git a/M5/Werbeseite/gerichte.php b/M5/Werbeseite/gerichte.php new file mode 100644 index 0000000..826be87 --- /dev/null +++ b/M5/Werbeseite/gerichte.php @@ -0,0 +1,31 @@ + ['name' => 'Rindfleich mit Bambus, Kaiserschoten und roter Paprika, dazu Mie Nudeln', + 'priceint' => 3.50, + "priceex" => 6.20, + "img" =>"img/bambus.jpg" + ], + 2 => ['name' => 'Spinatrisotto mit kleinen Samosateigecken und gemischter Salat', + 'priceint' => 2.90, + "priceex" => 5.30, + "img" =>"img/risotto.jpg" + ], + 3 => ['name' => 'Spaghetti Bolognese', + 'priceint' => 3, + "priceex" => 5, + "img" =>"img/bolo.jpg" + ], + 4 => ['name' => 'Spaghetti Carbonara', + 'priceint' => 3, + "priceex" => 5, + "img" =>"img/carbonara.jpg" + ] +] +?> \ No newline at end of file diff --git a/M5/Werbeseite/img/bambus.jpg b/M5/Werbeseite/img/bambus.jpg new file mode 100644 index 0000000..83a2cb5 Binary files /dev/null and b/M5/Werbeseite/img/bambus.jpg differ diff --git a/M5/Werbeseite/img/bolo.jpg b/M5/Werbeseite/img/bolo.jpg new file mode 100644 index 0000000..5fcab51 Binary files /dev/null and b/M5/Werbeseite/img/bolo.jpg differ diff --git a/M5/Werbeseite/img/carbonara.jpg b/M5/Werbeseite/img/carbonara.jpg new file mode 100644 index 0000000..a9c990b Binary files /dev/null and b/M5/Werbeseite/img/carbonara.jpg differ diff --git a/M5/Werbeseite/img/risotto.jpg b/M5/Werbeseite/img/risotto.jpg new file mode 100644 index 0000000..a9ae088 Binary files /dev/null and b/M5/Werbeseite/img/risotto.jpg differ diff --git a/M5/Werbeseite/index.php b/M5/Werbeseite/index.php new file mode 100644 index 0000000..9bdd6b0 --- /dev/null +++ b/M5/Werbeseite/index.php @@ -0,0 +1,274 @@ + $name, + "email" => $email, + "language" => $language, + "terms" => $terms + ); + //File writing + $file = "subscriptions.json"; + $current_data = file_exists($file) ? json_decode(file_get_contents($file), true) : array(); + $current_data[] = $data; + + if (file_put_contents($file, json_encode($current_data))) { + echo ''; + + //Newsletter counter + $newletterCount++; + $newsFile = fopen("newletter.txt", "w"); + fwrite($newsFile, $newletterCount); + fclose($newsFile); + } else { + echo ''; + } + } else { + $error_string = ""; + foreach ($errors as $error) { + $error_string .= $error . '\n'; + } + + echo ''; + } +} + +?> + + + + + + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Besuche
+Anmeldungen zum Newsletter
+ + Speisen +
+
+ DOCUMENT_ROOT: {$_SERVER['DOCUMENT_ROOT']}Datei nicht gefunden: {$_SERVER['DOCUMENT_ROOT']}/../vendor/autoload.php
"; + echo "Häufigste Ursache
public/ ist nicht als Wurzelverzeichnis verwendet worden.composer update installiert.DOCUMENT_ROOT{$_SERVER['DOCUMENT_ROOT']}Error" . $ex->getMessage() . ""; +} + +use eftec\bladeone\BladeOne; + +/* Routing Script for PHP Dev Server */ +$verbosity = VERBOSITY; +if (preg_match('/\.(?:css|js|png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) { + return false; +} else { + if ($verbosity > 1) { + echo + "
Verbosity-Level: {$verbosity}" .
+ "" . print_r($_SERVER, 1) . "
Request\n", print_r($request), ""; + echo "
Path\n", print_r($path), ""; + echo "
Query\n", print_r($query), ""; + } + } + + // fix: trim slashes + $ctrlName = trim($ctrlName, '/'); + $actionName = trim($actionName, '/'); + + // $config based renaming of Controller/Action, precedes filebased convention + // $config values must use syntax
Routing Config matched request for /" . $ctrlName . "/" . $actionName . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } elseif (array_key_exists($request['path'], $config)) { + // exact match on full path, this also means "/" + $routingConfig = explode('@', $config[$request['path']]); + if ($verbosity > 0) { + echo "
Routing Config matched for full path " . $request['path'] . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } else { + if ($verbosity > 0) { + echo "Request $ctrlName/$actionName was not in \$config."; + } + + // fall back to filebased convention: match controller classes in directory + $ctrlClass = ucfirst($ctrlName . 'Controller'); + } + + $ctrlFile = ($ctrlClass . '.php'); + $validControllers = FrontController::getValidControllers($controllerDirectory); + if (!in_array($controllerDirectory . $ctrlFile, $validControllers)) { + if ($verbosity > 0) { + echo "
Controller: $ctrlFile not found in
" . print_r($validControllers, 1) . "
Config Array:
" . print_r($config, 1) . "
" .
+ "Keine entspreche Zuordnung der Route für {$ctrlName}::{$actionName} gefunden. Tippfehler in der Route?" . + "
Es konnte keine Klasse " . $ctrlFile . " gefunden werden! Request fehlgeschlagen.
" . + " Prüfen Sie die Einträge in der Datei config/web.php und gleichen Sie den getätigten Aufruf damit ab.
Stellen Sie sicher, dass die Action/der Controller existiert.
+Das Routing Config-Array hat " . count($config) . " Einträge.
+Exception text
" . $ex->getMessage() . "
Verbindung fehlgeschlagen: " . mysqli_connect_error() . ".
config/db.php:
+ ( ist Benutzer {$config['user']} an Datenbank {$config['database']} auf Server {$config['host']} korrekt?)Fehlermeldung" . mysqli_connect_error() . "", 2, true); + exit(1); + } + + return $link; +} + +function view($viewname, $viewargs = array()) +{ + $views = dirname(__DIR__) . '/views'; + $cache = dirname(__DIR__) . '/storage/cache'; + $blade = new BladeOne($views, $cache, BladeOne::MODE_DEBUG); + + return $blade->run($viewname, $viewargs); +} + +/** + * let the script die if the php minimum version is not met. + * @param $minversion + * @return void + */ +function assert_php_version($minversion = '8.0.0') +{ + $version_too_low = 0; + $minver = explode('.', $minversion); + $version = explode('.', phpversion()); + + if (intval($minver[0]) > intval($version[0])) { + $version_too_low = 1; + } elseif (intval($minver[1]) > intval($version[1])) { + $version_too_low = 1; + } elseif (intval($minver[2]) > intval($version[2])) { + $version_too_low = 1; + } + + if ($version_too_low) { + FrontController::showErrorMessage("Diese PHP-Version wird nicht unterstützt: Minimum PHP Version " . $minversion . "
Der Pfad " . $_SERVER['DOCUMENT_ROOT'] . " enthält " . $charsfound . " problematische Zeichen, die die korrekte Ausführung verhindern.
Bekannte problematische Zeichen sind
+ " . implode(" ", $chars) . " ");
+ exit(1);
+ }
+
+}
+
+function assert_blade(): void
+{
+ if (!class_exists('eftec\bladeone\BladeOne')) {
+ // #ERROR
+ FrontController::showErrorMessage("
+ Tipps für die Lösung:
+führen Sie im Terminal folgende Zeilen aus.
+php bin/composer.phar update oder php bin/composer.phar reinstall eftec/bladeonephp bin/composer.phar dump-autoloadPrüfen Sie im Anschluss: befindet sich in dem Ordner vendor/eftec/bladeone/lib/ die Datei BladeOne.php ?
Starten Sie dann den Webserver neu.
Befragen Sie gerne auch das Forum in Ilias.
Kurze Übersicht, wie die Arbeit mit dem Router und der Blade View-Engine funktioniert.
+ +Der Router nimmt den Request entgegen und zerlegt ihn in die einzelnen Teile der URI. Wichtig ist hier vor + allem der Pfad und der Querystring.
+Wenn der Pfad in der Routenkonfiguration (\$config Array aus der Datei
+ routes/web.php) gefunden wird, lädt der Router die angegebene Klasse.
Im vorliegenden Beispiel sehen Sie diese Seite ...
+DemoController.php gefunden werden konnte
+ Sie sehen: da muss einiges stimmen und vieles davon ist Konvention.
+Die Actions in den Controller-Klassen sollen per Konvention immer ein RequestData Objekt
+ entgegennehmen. Beispiel: howto(RequestData \$rd)
Dieses RequestData Objekt wird durch den Router befüllt, wenn Daten in der URL extrahiert werden konnten.
+Daten finden sich URLs...
+ +
+ im Querystring
Beispiel: rufen Sie diese mit
+ :///demo?bgcolor=fefbd8&name=Remmy
+ auf, werden bgcolor und name mitsamt Werten als Query Array
+ $rd->query) übergeben
+
Probieren Sie es aus ;)
+ args)): ?> +Argumente dieses Aufrufs:
+ + args as $a): $__empty_1 = false; ?> +Keine weiteren Argumente im Request
+ + + query)): ?> +Daten aus der Query dieses Aufrufs:
+
+ query as $k => $v): $__empty_1 = false; ?>
+ $rd->query['']=
+
+
+ Keine Querydaten
+
+
+
+ Blade muss installiert sein. + Die Installation ist bereits geschehen und die Bibliothek liegt unter /vendor. +
+Bei der Verwendung der View-Engine gelten einige Konventionen:
+ Die Dateien müssen <viewname>.blade.php heißen und im Ordner views liegen.
+
Sie können der View dann Daten mitgeben, indem Sie alle Daten in ein Array schreiben und dieses dann + übergeben.
+Beispiel:
+
+ view("viewtest",
+ array(
+ "texts"=>$textArray,
+ "persona"=>$persona,
+ "rd"=>$rd
+ )); // öffnet ../views/viewtest.blade.php
+
+ Fehlermeldung
++ + + + +
Fehlermeldung
++ + + +
Fehlermeldung
++ + + +
Page 1
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 1
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 1"]); } ?> \ No newline at end of file diff --git a/M5/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec b/M5/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec new file mode 100644 index 0000000..961375a --- /dev/null +++ b/M5/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec @@ -0,0 +1,14 @@ + + +startSection("header"); ?> + +stopSection(); ?> + +startSection("body"); ?> +Page 2
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 2
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 2"]); } ?> \ No newline at end of file diff --git a/M5/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec b/M5/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec new file mode 100644 index 0000000..c54dc25 --- /dev/null +++ b/M5/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec @@ -0,0 +1,36 @@ + + +startSection("content"); ?> +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is equals to abc
+ *
+ * Example: (includeScope=true)
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is not defined
+ *
+ */
+ public $includeScope = false;
+ /**
+ * @var callable[] It allows to parse the compiled output using a function.
+ * This function doesn't require to return a value
+ * $this->compileCallbacks[]= static function (&$content, $templatename=null) {
+ * $content=strtoupper($content);
+ * };
+ *
+ */
+ public $compileCallbacks = [];
+ /** @var array All the registered extensions. */
+ protected $extensions = [];
+ /** @var array All the finished, captured sections. */
+ protected $sections = [];
+ /** @var string The template currently being compiled. For example "folder.template" */
+ protected $fileName;
+ protected $currentView;
+ protected $notFoundPath;
+ /** @var string File extension for the template files. */
+ protected $fileExtension = '.blade.php';
+ /** @var array The stack of in-progress sections. */
+ protected $sectionStack = [];
+ /** @var array The stack of in-progress loops. */
+ protected $loopsStack = [];
+ /** @var array Dictionary of variables */
+ protected $variables = [];
+ /** @var array Dictionary of global variables */
+ protected $variablesGlobal = [];
+ /** @var array All the available compiler functions. */
+ protected $compilers = [
+ 'Extensions',
+ 'Statements',
+ 'Comments',
+ 'Echos',
+ ];
+ /** @var string|null it allows to set the stack */
+ protected $viewStack;
+ /** @var array used by $this->composer() */
+ protected $composerStack = [];
+ /** @var array The stack of in-progress push sections. */
+ protected $pushStack = [];
+ /** @var array All the finished, captured push sections. */
+ protected $pushes = [];
+ /** @var int The number of active rendering operations. */
+ protected $renderCount = 0;
+ /** @var string[] Get the template path for the compiled views. */
+ protected $templatePath;
+ /** @var string Get the compiled path for the compiled views. If null then it uses the default path */
+ protected $compiledPath;
+ /** @var string the extension of the compiled file. */
+ protected $compileExtension = '.bladec';
+ /**
+ * @var string=['auto','sha1','md5'][$i] It determines how the compiled filename will be called.
+ * $this->wrapPHP('$hello'); // "< ?php echo $this->e($hello); ? >"
+ * $this->wrapPHP('$hello',''); // < ?php echo $this->e($hello); ? >
+ * $this->wrapPHP('$hello','',false); // < ?php echo $hello; ? >
+ * $this->wrapPHP('"hello"'); // "< ?php echo $this->e("hello"); ? >"
+ * $this->wrapPHP('hello()'); // "< ?php echo $this->e(hello()); ? >"
+ *
+ *
+ * @param ?string $input The input value
+ * @param string $quote The quote used (to quote the result)
+ * @param bool $parse If the result will be parsed or not. If false then it's returned without $this->e
+ * @return string
+ */
+ public function wrapPHP($input, $quote = '"', $parse = true): string
+ {
+ if($input===null) {
+ return 'null';
+ }
+ if (strpos($input, '(') !== false && !$this->isQuoted($input)) {
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+ if (strpos($input, '$') === false) {
+ if ($parse) {
+ return self::enq($input);
+ }
+
+ return $input;
+ }
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+
+ /**
+ * Returns true if the text is surrounded by quotes (double or single quote)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isQuoted($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ if ($text[0] === '"' && substr($text, -1) === '"') {
+ return true;
+ }
+ return ($text[0] === "'" && substr($text, -1) === "'");
+ }
+
+ /**
+ * Escape HTML entities in a string.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function enq($value): string
+ {
+ if (\is_array($value) || \is_object($value)) {
+ return \htmlentities(\print_r($value, true), ENT_NOQUOTES, 'UTF-8', false);
+ }
+ return \htmlentities($value??'', ENT_NOQUOTES, 'UTF-8', false);
+ }
+
+ /**
+ * @param string $view example "folder.template"
+ * @param string|null $alias example "mynewop". If null then it uses the name of the template.
+ */
+ public function addInclude($view, $alias = null): void
+ {
+ if (!isset($alias)) {
+ $alias = \explode('.', $view);
+ $alias = \end($alias);
+ }
+ $this->directive($alias, function ($expression) use ($view) {
+ $expression = $this->stripParentheses($expression) ?: '[]';
+ return "$this->phpTag echo \$this->runChild('$view', $expression); ?>";
+ });
+ }
+
+ /**
+ * Register a handler for custom directives.
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directive($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = false;
+ }
+
+ /**
+ * Strip the parentheses from the given expression.
+ *
+ * @param string|null $expression
+ * @return string
+ */
+ public function stripParentheses($expression): string
+ {
+ if (\is_null($expression)) {
+ return '';
+ }
+
+ if (static::startsWith($expression, '(')) {
+ $expression = \substr($expression, 1, -1);
+ }
+
+ return $expression;
+ }
+
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function startsWith($haystack, $needles): bool
+ {
+ foreach ((array)$needles as $needle) {
+ if ($needle != '') {
+ if (\function_exists('mb_strpos')) {
+ if ($haystack !== null && \mb_strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ } elseif ($haystack !== null && \strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * If false then the file is not compiled, and it is executed directly from the memory.Example:setPath("somefolder","otherfolder"); + * + * @param null|string|string[] $templatePath If null then it uses the current path /views folder + * @param null|string $compiledPath If null then it uses the current path /views folder + */ + public function setPath($templatePath, $compiledPath): void + { + if ($templatePath === null) { + $templatePath = \getcwd() . '/views'; + } + if ($compiledPath === null) { + $compiledPath = \getcwd() . '/compiles'; + } + $this->templatePath = (is_array($templatePath)) ? $templatePath : [$templatePath]; + $this->compiledPath = $compiledPath; + } + + /** + * @return array + */ + public function getAliasClasses(): array + { + return $this->aliasClasses; + } + + /** + * @param array $aliasClasses + */ + public function setAliasClasses($aliasClasses): void + { + $this->aliasClasses = $aliasClasses; + } + + /** + * @param string $aliasName + * @param string $classWithNS + */ + public function addAliasClasses($aliasName, $classWithNS): void + { + $this->aliasClasses[$aliasName] = $classWithNS; + } + //
+ * Text::wildCardComparison('abcdef','abc*'); // true
+ * Text::wildCardComparison('abcdef','*def'); // true
+ * Text::wildCardComparison('abcdef','*abc*'); // true
+ * Text::wildCardComparison('abcdef','*cde*'); // true
+ * Text::wildCardComparison('abcdef','*cde'); // false
+ *
+ *
+ *
+ * @param string $text
+ * @param string|null $textWithWildcard
+ *
+ * @return bool
+ */
+ protected function wildCardComparison($text, $textWithWildcard): bool
+ {
+ if (($textWithWildcard === null || $textWithWildcard === '')
+ || strpos($textWithWildcard, '*') === false
+ ) {
+ // if the text with wildcard is null or empty, or it contains two ** or it contains no * then..
+ return $text == $textWithWildcard;
+ }
+ if ($textWithWildcard === '*' || $textWithWildcard === '**') {
+ return true;
+ }
+ $c0 = $textWithWildcard[0];
+ $c1 = substr($textWithWildcard, -1);
+ $textWithWildcardClean = str_replace('*', '', $textWithWildcard);
+ $p0 = strpos($text, $textWithWildcardClean);
+ if ($p0 === false) {
+ // no matches.
+ return false;
+ }
+ if ($c0 === '*' && $c1 === '*') {
+ // $textWithWildcard='*asasasas*'
+ return true;
+ }
+ if ($c1 === '*') {
+ // $textWithWildcard='asasasas*'
+ return $p0 === 0;
+ }
+ // $textWithWildcard='*asasasas'
+ $len = strlen($textWithWildcardClean);
+ return (substr($text, -$len) === $textWithWildcardClean);
+ }
+
+ protected function methodExistsStatic($class, $method): bool
+ {
+ try {
+ return (new \ReflectionMethod($class, $method))->isStatic();
+ } catch (\ReflectionException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Compile the view at the given path.
+ *
+ * @param string $templateName The name of the template. Example folder.template
+ * @param bool $forced If the compilation will be forced (always compile) or not.
+ * @return boolean|string True if the operation was correct, or false (if not exception)
+ * if it fails. It returns a string (the content compiled) if isCompiled=false
+ * @throws Exception
+ */
+ public function compile($templateName = null, $forced = false)
+ {
+ $compiled = $this->getCompiledFile($templateName);
+ $template = $this->getTemplateFile($templateName);
+ if (!$this->isCompiled) {
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ return $contents;
+ }
+ if ($forced || $this->isExpired($templateName)) {
+ // compile the original file
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ if ($this->optimize) {
+ // removes space and tabs and replaces by a single space
+ $contents = \preg_replace('/^ {2,}/m', ' ', $contents);
+ $contents = \preg_replace('/^\t{2,}/m', ' ', $contents);
+ }
+ $ok = @\file_put_contents($compiled, $contents);
+ if ($ok === false) {
+ $this->showError(
+ 'Compiling',
+ "Unable to save the file [$compiled]. Check the compile folder is defined and has the right permission"
+ );
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get the full path of the compiled file.
+ *
+ * @param string $templateName
+ * @return string
+ */
+ public function getCompiledFile($templateName = ''): string
+ {
+ $templateName = (empty($templateName)) ? $this->fileName : $templateName;
+
+ $fullPath = $this->getTemplateFile($templateName);
+ if($fullPath == '') {
+ throw new \RuntimeException('Template not found: ' . $templateName);
+ }
+
+ $style=$this->compileTypeFileName;
+ if ($style==='auto') {
+ $style='sha1';
+ }
+ $hash = $style === 'md5' ? \md5($fullPath) : \sha1($fullPath);
+ return $this->compiledPath . '/' . basename($templateName) . '_' . $hash . $this->compileExtension;
+ }
+
+
+
+ /**
+ * Get the mode of the engine.See BladeOne::MODE_* constants
+ *
+ * @return int=[self::MODE_AUTO,self::MODE_DEBUG,self::MODE_FAST,self::MODE_SLOW][$i]
+ */
+ public function getMode(): int
+ {
+ if (\defined('BLADEONE_MODE')) {
+ $this->mode = BLADEONE_MODE;
+ }
+ return $this->mode;
+ }
+
+ /**
+ * Set the compile modeExample: getTemplateFile('.abc.def')
+ * + * @param string $templateName template name. If not template is set then it uses the base template. + * @return string + */ + public function getTemplateFile($templateName = ''): string + { + $templateName = (empty($templateName)) ? $this->fileName : $templateName; + if (\strpos($templateName, '/') !== false) { + return $this->locateTemplate($templateName); // it's a literal + } + $arr = \explode('.', $templateName); + $c = \count($arr); + if ($c == 1) { + // it's in the root of the template folder. + return $this->locateTemplate($templateName . $this->fileExtension); + } + + $file = $arr[$c - 1]; + \array_splice($arr, $c - 1, $c - 1); // delete the last element + $path = \implode('/', $arr); + return $this->locateTemplate($path . '/' . $file . $this->fileExtension); + } + + /** + * Find template file with the given name in all template paths in the order the paths were written + * + * @param string $name Filename of the template (without path) + * @return string template file + */ + protected function locateTemplate($name): string + { + $this->notFoundPath = ''; + foreach ($this->templatePath as $dir) { + $path = $dir . '/' . $name; + if (\is_file($path)) { + return $path; + } + + $this->notFoundPath .= $path . ","; + } + return ''; + } + + /** + * Get the contents of a file. + * + * @param string $fullFileName It gets the content of a filename or returns ''. + * + * @return string + */ + public function getFile($fullFileName): string + { + if (\is_file($fullFileName)) { + return \file_get_contents($fullFileName); + } + $this->showError('getFile', "File does not exist at paths (separated by comma) [$this->notFoundPath] or permission denied"); + return ''; + } + + protected function compileCallBacks(&$contents, $templateName): void + { + if (!empty($this->compileCallbacks)) { + foreach ($this->compileCallbacks as $callback) { + if (is_callable($callback)) { + $callback($contents, $templateName); + } + } + } + } + + /** + * Determine if the view has expired. + * + * @param string|null $fileName + * @return bool + */ + public function isExpired($fileName): bool + { + $compiled = $this->getCompiledFile($fileName); + $template = $this->getTemplateFile($fileName); + if (!\is_file($template)) { + if ($this->mode == self::MODE_DEBUG) { + $this->showError('Read file', 'Template not found :' . $this->fileName . " on file: $template", true); + } else { + $this->showError('Read file', 'Template not found :' . $this->fileName, true); + } + } + // If the compiled file doesn't exist we will indicate that the view is expired + // so that it can be re-compiled. Else, we will verify the last modification + // of the views is less than the modification times of the compiled views. + if (!$this->compiledPath || !\is_file($compiled)) { + return true; + } + return \filemtime($compiled) < \filemtime($template); + } + + /** + * Evaluates a text (string) using the current variables + * + * @param string $content + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluateText($content, $variables): string + { + \ob_start(); + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + eval(' ?>' . $content . $this->phpTag); + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * Handle a view exception. + * + * @param Exception $e + * @return void + * @throws $e + */ + protected function handleViewException($e): void + { + \ob_get_clean(); + throw $e; + } + + /** + * Evaluates a compiled file using the current variables + * + * @param string $compiledFile full path of the compile file. + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluatePath($compiledFile, $variables): string + { + \ob_start(); + // note, the variables are extracted locally inside this method, + // they are not global variables :-3 + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + include $compiledFile; + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * @param array $views array of views + * @param array $value + * @return string + * @throws Exception + */ + public function includeFirst($views = [], $value = []): string + { + foreach ($views as $view) { + if ($this->templateExist($view)) { + return $this->runChild($view, $value); + } + } + return ''; + } + + /** + * Returns true if the template exists. Otherwise, it returns false + * + * @param $templateName + * @return bool + */ + protected function templateExist($templateName): bool + { + $file = $this->getTemplateFile($templateName); + return \is_file($file); + } + + /** + * Convert an array such as ["class1"=>"myclass","style="mystyle"] to class1='myclass' style='mystyle' string + * + * @param array|string $array array to convert + * @return string + */ + public function convertArg($array): string + { + if (!\is_array($array)) { + return $array; // nothing to convert. + } + return \implode(' ', \array_map('static::convertArgCallBack', \array_keys($array), $array)); + } + + /** + * Returns the current token. if there is not a token then it generates a new one. + * It could require an open session. + * + * @param bool $fullToken It returns a token with the current ip. + * @param string $tokenId [optional] Name of the token. + * + * @return string + */ + public function getCsrfToken($fullToken = false, $tokenId = '_token'): string + { + if ($this->csrf_token == '') { + $this->regenerateToken($tokenId); + } + if ($fullToken) { + return $this->csrf_token . '|' . $this->ipClient(); + } + return $this->csrf_token; + } + + /** + * Regenerates the csrf token and stores in the session. + * It requires an open session. + * + * @param string $tokenId [optional] Name of the token. + */ + public function regenerateToken($tokenId = '_token'): void + { + try { + $this->csrf_token = \bin2hex(\random_bytes(10)); + } catch (Exception $e) { + $this->csrf_token = '123456789012345678901234567890'; // unable to generates a random token. + } + @$_SESSION[$tokenId] = $this->csrf_token . '|' . $this->ipClient(); + } + + public function ipClient() + { + if ( + isset($_SERVER['HTTP_X_FORWARDED_FOR']) + && \preg_match('/^(d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})$/', $_SERVER['HTTP_X_FORWARDED_FOR']) + ) { + return $_SERVER['HTTP_X_FORWARDED_FOR']; + } + return $_SERVER['REMOTE_ADDR'] ?? ''; + } + + /** + * Validates if the csrf token is valid or not.'; + \var_dump($object); + echo ''; + } else { + /** @noinspection BadExpressionStatementJS */ + /** @noinspection JSVoidFunctionReturnValueUsed */ + echo ''; + } + } + + /** + * Start injecting content into a section. + * + * @param string $section + * @param string $content + * @return void + */ + public function startSection($section, $content = ''): void + { + if ($content === '') { + \ob_start() && $this->sectionStack[] = $section; + } else { + $this->extendSection($section, $content); + } + } + + /** + * Stop injecting content into a section and append it. + * + * @return string + * @throws InvalidArgumentException + */ + public function appendSection(): string + { + if (empty($this->sectionStack)) { + $this->showError('appendSection', 'Cannot end a section without first starting one.', true, true); + } + $last = \array_pop($this->sectionStack); + if (isset($this->sections[$last])) { + $this->sections[$last] .= \ob_get_clean(); + } else { + $this->sections[$last] = \ob_get_clean(); + } + return $last; + } + + /** + * Adds a global variable. If $varname is an array then it merges all the values. + * Example: + *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable or, it is an associative array
+ * @param mixed $value
+ * @return $this
+ * @see BladeOne::share
+ */
+ public function with($varname, $value = null): BladeOne
+ {
+ return $this->share($varname, $value);
+ }
+
+ /**
+ * Adds a global variable. If $varname is an array then it merges all the values.
+ * Example:
+ *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable, or it is an associative array
+ * @param mixed $value
+ * @return $this
+ */
+ public function share($varname, $value = null): BladeOne
+ {
+ if (is_array($varname)) {
+ $this->variablesGlobal = \array_merge($this->variablesGlobal, $varname);
+ } else {
+ $this->variablesGlobal[$varname] = $value;
+ }
+ return $this;
+ }
+
+ /**
+ * Get the string contents of a section.
+ *
+ * @param string $section
+ * @param string $default
+ * @return string
+ */
+ public function yieldContent($section, $default = ''): string
+ {
+ if (isset($this->sections[$section])) {
+ return \str_replace($this->PARENTKEY, $default, $this->sections[$section]);
+ }
+
+ return $default;
+ }
+
+ /**
+ * Register a custom Blade compiler.
+ *
+ * @param callable $compiler
+ * @return void
+ */
+ public function extend(callable $compiler): void
+ {
+ $this->extensions[] = $compiler;
+ }
+
+ /**
+ * Register a handler for custom directives for run at runtime
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directiveRT($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = true;
+ }
+
+ /**
+ * Sets the escaped content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @return void
+ */
+ public function setEscapedContentTags($openTag, $closeTag): void
+ {
+ $this->setContentTags($openTag, $closeTag, true);
+ }
+
+ /**
+ * Gets the content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getContentTags(): array
+ {
+ return $this->getTags();
+ }
+
+ /**
+ * Sets the content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @param bool $escaped
+ * @return void
+ */
+ public function setContentTags($openTag, $closeTag, $escaped = false): void
+ {
+ $property = ($escaped === true) ? 'escapedTags' : 'contentTags';
+ $this->{$property} = [\preg_quote($openTag), \preg_quote($closeTag)];
+ }
+
+ /**
+ * Gets the tags used for the compiler.
+ *
+ * @param bool $escaped
+ * @return array
+ */
+ protected function getTags($escaped = false): array
+ {
+ $tags = $escaped ? $this->escapedTags : $this->contentTags;
+ return \array_map('stripcslashes', $tags);
+ }
+
+ /**
+ * Gets the escaped content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getEscapedContentTags(): array
+ {
+ return $this->getTags(true);
+ }
+
+ /**
+ * Sets the function used for resolving classes with inject.
+ *
+ * @param callable $function
+ */
+ public function setInjectResolver(callable $function): void
+ {
+ $this->injectResolver = $function;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getFileExtension(): string
+ {
+ return $this->fileExtension;
+ }
+
+ /**
+ * Set the file extension for the template files.
+ * It must include the leading dot e.g. ".blade.php"
+ *
+ * @param string $fileExtension Example: .prefix.ext
+ */
+ public function setFileExtension($fileExtension): void
+ {
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getCompiledExtension(): string
+ {
+ return $this->compileExtension;
+ }
+
+ /**
+ * Set the file extension for the compiled files.
+ * Including the leading dot for the extension is required, e.g. ".bladec"
+ *
+ * @param $fileExtension
+ */
+ public function setCompiledExtension($fileExtension): void
+ {
+ $this->compileExtension = $fileExtension;
+ }
+ /**
+ * @return string
+ * @see BladeOne::setCompileTypeFileName
+ */
+ public function getCompileTypeFileName(): string
+ {
+ return $this->compileTypeFileName;
+ }
+
+ /**
+ * It determines how the compiled filename will be called.
+ * $this->setView('folder.view')->share(['var1'=>20])->run(); // or $this->run('folder.view',['var1'=>20]);
+ *
+ *
+ * @param string $view
+ * @return BladeOne
+ */
+ public function setView($view): BladeOne
+ {
+ $this->viewStack = $view;
+ return $this;
+ }
+
+ /**
+ * It injects a function, an instance, or a method class when a view is called.
+ * $this->composer('folder.view',function($bladeOne) { $bladeOne->share('newvalue','hi there'); });
+ * $this->composer('folder.view','namespace1\namespace2\SomeClass'); // SomeClass must exist, and it must have the
+ * // method 'composer'
+ * $this->composer('folder.*',$instance); // $instance must have the method called 'composer'
+ * $this->composer(); // clear all composer.
+ *
+ *
+ * @param string|array|null $view It could contain wildcards (*). Example: 'aa.bb.cc','*.bb.cc','aa.bb.*','*.bb.*'
+ *
+ * @param callable|string|null $functionOrClass
+ * @return BladeOne
+ */
+ public function composer($view = null, $functionOrClass = null): BladeOne
+ {
+ if ($view === null && $functionOrClass === null) {
+ $this->composerStack = [];
+ return $this;
+ }
+ if (is_array($view)) {
+ foreach ($view as $v) {
+ $this->composerStack[$v] = $functionOrClass;
+ }
+ } else {
+ $this->composerStack[$view] = $functionOrClass;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Start a component rendering process.
+ *
+ * @param string $name
+ * @param array $data
+ * @return void
+ */
+ public function startComponent($name, array $data = []): void
+ {
+ if (\ob_start()) {
+ $this->componentStack[] = $name;
+
+ $this->componentData[$this->currentComponent()] = $data;
+
+ $this->slots[$this->currentComponent()] = [];
+ }
+ }
+
+ /**
+ * Get the index for the current component.
+ *
+ * @return int
+ */
+ protected function currentComponent(): int
+ {
+ return \count($this->componentStack) - 1;
+ }
+
+ /**
+ * Render the current component.
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function renderComponent(): string
+ {
+ //echo "
+ * $this->setBaseUrl('http://domain.dom/myblog');
+ * $this->setBaseUrl('http://domain.dom/corporate/erp');
+ * $this->setBaseUrl('http://domain.dom/blog.php?args=20'); // avoid this one.
+ * $this->setBaseUrl('http://another.dom');
+ *
+ *
+ * @param string $baseUrl Example http://www.web.com/folder https://www.web.com/folder/anotherfolder
+ * @return BladeOne
+ */
+ public function setBaseUrl($baseUrl): BladeOne
+ {
+ $this->baseUrl = \rtrim($baseUrl, '/'); // base with the url trimmed
+ $this->baseDomain = @parse_url($this->baseUrl)['host'];
+ $currentUrl = $this->getCurrentUrlCalculated();
+ if ($currentUrl === '') {
+ $this->relativePath = '';
+ return $this;
+ }
+ if (\strpos($currentUrl, $this->baseUrl) === 0) {
+ $part = \str_replace($this->baseUrl, '', $currentUrl);
+ $numf = \substr_count($part, '/') - 1;
+ $numf = ($numf > 10) ? 10 : $numf; // avoid overflow
+ $this->relativePath = ($numf < 0) ? '' : \str_repeat('../', $numf);
+ } else {
+ $this->relativePath = '';
+ }
+ return $this;
+ }
+
+ /**
+ * It gets the full current url calculated with the information sends by the user.
+ * // current url='http://domain.dom/page/subpage/web.php?aaa=2
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ *
+ * Note:The relative path is calculated when we set the base url.
+ *
+ * @return string
+ * @see BladeOne::setBaseUrl
+ */
+ public function getRelativePath(): string
+ {
+ return $this->relativePath;
+ }
+
+ /**
+ * It gets the full current canonical url.
+ * $this->addInsideQuote("'hello'"," world"); // 'hello world'
+ * $this->addInsideQuote("hello"," world"); // hello world
+ *
+ *
+ * @param $quoted
+ * @param $newFragment
+ * @return string
+ */
+ public function addInsideQuote($quoted, $newFragment): string
+ {
+ if ($this->isQuoted($quoted)) {
+ return substr($quoted, 0, -1) . $newFragment . substr($quoted, -1);
+ }
+ return $quoted . $newFragment;
+ }
+
+ /**
+ * Return true if the string is a php variable (it starts with $)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isVariablePHP($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ return $text[0] === '$';
+ }
+
+ /**
+ * It's the same as "@_e", however it parses the text (using sprintf).
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _ef($phrase): string
+ {
+ $argv = \func_get_args();
+ $r = $this->_e($phrase);
+ $argv[0] = $r; // replace the first argument with the translation.
+ $result = @sprintf(...$argv);
+ return !$result ? $r : $result;
+ }
+
+ /**
+ * Tries to translate the word if it's in the array defined by BladeOneLang::$dictionary
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _e($phrase): string
+ {
+ if ((!\array_key_exists($phrase, static::$dictionary))) {
+ $this->missingTranslation($phrase);
+ return $phrase;
+ }
+
+ return static::$dictionary[$phrase];
+ }
+
+ /**
+ * Log a missing translation into the file $this->missingLog.'; var_dump$expression; echo '';?>"; + } + + /** + * Execute the case tag. + * + * @param $expression + * @return string + */ + protected function compileCase($expression): string + { + if ($this->firstCaseInSwitch) { + $this->firstCaseInSwitch = false; + return 'case ' . $expression . ': ?>'; + } + return $this->phpTag . "case $expression: ?>"; + } + + /** + * Compile the while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileWhile($expression): string + { + return $this->phpTag . "while$expression: ?>"; + } + + /** + * default tag used for switch/case + * + * @return string + */ + protected function compileDefault(): string + { + if ($this->firstCaseInSwitch) { + return $this->showError('@default', '@switch without any @case', true); + } + return $this->phpTag . 'default: ?>'; + } + + protected function compileEndSwitch(): string + { + --$this->switchCount; + if ($this->switchCount < 0) { + return $this->showError('@endswitch', 'Missing @switch', true); + } + return $this->phpTag . '} // end switch ?>'; + } + + /** + * Compile while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileInject($expression): string + { + $ex = $this->stripParentheses($expression); + $p0 = \strpos($ex, ','); + if (!$p0) { + $var = $this->stripQuotes($ex); + $namespace = ''; + } else { + $var = $this->stripQuotes(\substr($ex, 0, $p0)); + $namespace = $this->stripQuotes(\substr($ex, $p0 + 1)); + } + return $this->phpTag . "\$$var = \$this->injectClass('$namespace', '$var'); ?>"; + } + + /** + * Remove first and end quote from a quoted string of text + * + * @param mixed $text + * @return null|string|string[] + */ + public function stripQuotes($text) + { + if (!$text || strlen($text) < 2) { + return $text; + } + $text = trim($text); + $p0 = $text[0]; + $p1 = \substr($text, -1); + if ($p0 === $p1 && ($p0 === '"' || $p0 === "'")) { + return \substr($text, 1, -1); + } + return $text; + } + + /** + * Execute the user defined extensions. + * + * @param string $value + * @return string + */ + protected function compileExtensions($value): string + { + foreach ($this->extensions as $compiler) { + $value = $compiler($value, $this); + } + return $value; + } + + /** + * Compile Blade comments into valid PHP. + * + * @param string $value + * @return string + */ + protected function compileComments($value): string + { + $pattern = \sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]); + return \preg_replace($pattern, $this->phpTag . '/*$1*/ ?>', $value); + } + + /** + * Compile Blade echos into valid PHP. + * + * @param string $value + * @return string + * @throws Exception + */ + protected function compileEchos($value): string + { + foreach ($this->getEchoMethods() as $method => $length) { + $value = $this->$method($value); + } + return $value; + } + + /** + * Get the echo methods in the proper order for compilation. + * + * @return array + */ + protected function getEchoMethods(): array + { + $methods = [ + 'compileRawEchos' => \strlen(\stripcslashes($this->rawTags[0])), + 'compileEscapedEchos' => \strlen(\stripcslashes($this->escapedTags[0])), + 'compileRegularEchos' => \strlen(\stripcslashes($this->contentTags[0])), + ]; + \uksort($methods, static function ($method1, $method2) use ($methods) { + // Ensure the longest tags are processed first + if ($methods[$method1] > $methods[$method2]) { + return -1; + } + if ($methods[$method1] < $methods[$method2]) { + return 1; + } + // Otherwise, give preference to raw tags (assuming they've overridden) + if ($method1 === 'compileRawEchos') { + return -1; + } + if ($method2 === 'compileRawEchos') { + return 1; + } + if ($method1 === 'compileEscapedEchos') { + return -1; + } + if ($method2 === 'compileEscapedEchos') { + return 1; + } + throw new BadMethodCallException("Method [$method1] not defined"); + }); + return $methods; + } + + /** + * Compile Blade statements that start with "@". + * + * @param string $value + * + * @return array|string|string[]|null + */ + protected function compileStatements($value) + { + /** + * @param array $match + * [0]=full expression with @ and parenthesis + * [1]=expression without @ and argument + * [2]=???? + * [3]=argument with parenthesis and without the first @ + * [4]=argument without parenthesis. + * + * @return mixed|string + */ + $callback = function ($match) { + if (static::contains($match[1], '@')) { + // @@escaped tag + $match[0] = isset($match[3]) ? $match[1] . $match[3] : $match[1]; + } else { + if (strpos($match[1], '::') !== false) { + // Someclass::method + return $this->compileStatementClass($match); + } + if (isset($this->customDirectivesRT[$match[1]])) { + if ($this->customDirectivesRT[$match[1]]) { + $match[0] = $this->compileStatementCustom($match); + } else { + $match[0] = \call_user_func( + $this->customDirectives[$match[1]], + $this->stripParentheses(static::get($match, 3)) + ); + } + } elseif (\method_exists($this, $method = 'compile' . \ucfirst($match[1]))) { + // it calls the function compile
+ * $this->parseArgs('a=2,b='a,b,c',d'); // ['a'=>'2','b'=>'a,b,c','d'=>null]
+ * $this->parseArgs('a=2,b=c,d'); // ['a'=>'2','b'=>'c','d'=>null]
+ * $this->parseArgs('a=2 b=c',' '); // ['a'=>'2','b'=>'c']
+ * $this->parseArgs('a:2 b:c',' ',':'); // ['a'=>'2','b'=>'c']
+ *
+ * Note: parseArgs('a = 2 b = c',' '); with return 4 values instead of 2.
+ *
+ * @param string $text the text to separate
+ * @param string $separator the separator of arguments
+ * @param string $assigment the character used to assign a new value
+ * @param bool $emptyKey if the argument is without value, we return it as key (true) or value (false) ?
+ * @return array
+ */
+ public function parseArgs($text, $separator = ',', $assigment = '=', $emptyKey = true): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = $text; // str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = strlen($chars);
+ $stringArr = '"\'¬';
+ $parenthesis = '([{';
+ $parenthesisClose = ')]}';
+ $insidePar = false;
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ // we check if the character is a parenthesis.
+ $pp = strpos($parenthesis, $char);
+ if ($pp !== false) {
+ // is a parenthesis, so we mark as inside a parenthesis.
+ $insidePar = $parenthesisClose[$pp];
+ }
+ if ($char === $insidePar) {
+ // we close the parenthesis.
+ $insidePar = false;
+ }
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ // we found a string initializer
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator && !$insidePar) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ // duct taping for key= argument (it has a space). however, it doesn't work with key =argument
+ /*
+ foreach ($parts as $k=>$part) {
+ if(substr($part,-1)===$assigment && isset($parts[$k+1])) {
+ var_dump('ok');
+ $parts[$k].=$parts[$k+1];
+ unset($parts[$k+1]);
+ }
+ }
+ */
+ foreach ($parts as $part) {
+ $part = trim($part);
+ if ($part) {
+ $char = $part[0];
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ if ($emptyKey) {
+ $result[$part] = null;
+ } else {
+ $result[] = $part;
+ }
+ } else {
+ $r = explode($assigment, $part, 2);
+ if (count($r) === 2) {
+ // key=value.
+ $result[trim($r[0])] = trim($r[1]);
+ } elseif ($emptyKey) {
+ $result[trim($r[0])] = null;
+ } else {
+ $result[] = trim($r[0]);
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function parseArgsOld($text, $separator = ','): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = count($chars);
+ /** @noinspection ForeachInvariantsInspection */
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ if ($char === '"' || $char === "'") {
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ foreach ($parts as $part) {
+ $r = explode('=', $part, 2);
+ $result[trim($r[0])] = count($r) === 2 ? trim($r[1]) : null;
+ }
+ return $result;
+ }
+
+ /**
+ * Compile the "raw" echo statements.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRawEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ return $matches[1] ? \substr(
+ $matches[0],
+ 1
+ ) : $this->phpTagEcho . $this->compileEchoDefaults($matches[2]) . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the default values for the echo statement.
+ * Example:
+ * {{ $test or 'test2' }} compiles to {{ isset($test) ? $test : 'test2' }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEchoDefaults($value): string
+ {
+ // Source: https://www.php.net/manual/en/language.variables.basics.php
+ $patternPHPVariableName = '\$[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*';
+
+ $result = \preg_replace('/^(' . $patternPHPVariableName . ')\s+or\s+(.+?)$/s', 'isset($1) ? $1 : $2', $value);
+ if (!$this->pipeEnable) {
+ return $this->fixNamespaceClass($result);
+ }
+ return $this->pipeDream($this->fixNamespaceClass($result));
+ }
+
+ /**
+ * It converts a string separated by pipes | into a filtered expression.
+ * $this->pipeDream('$name | strtolower | substr:0,4'); // strtolower(substr($name ,0,4)
+ * $this->pipeDream('$name| getMode') // $this->getMode($name)
+ *
+ *
+ * @param string $result
+ * @return string
+ * @\eftec\bladeone\BladeOne::$pipeEnable
+ */
+ protected function pipeDream($result): string
+ {
+ $array = preg_split('~\\\\.(*SKIP)(*FAIL)|\|~s', $result);
+ $c = count($array) - 1; // base zero.
+ if ($c === 0) {
+ return $result;
+ }
+ $prev = '';
+ for ($i = 1; $i <=$c; $i++) {
+ $r = @explode(':', $array[$i], 2);
+ $fnName = trim($r[0]);
+ $fnNameF = $fnName[0]; // first character
+ if ($fnNameF === '"' || $fnNameF === '\'' || $fnNameF === '$' || is_numeric($fnNameF)) {
+ $fnName = '!isset(' . $array[0] . ') ? ' . $fnName . ' : ';
+ } elseif (isset($this->customDirectives[$fnName])) {
+ $fnName = '$this->customDirectives[\'' . $fnName . '\']';
+ } elseif (method_exists($this, $fnName)) {
+ $fnName = '$this->' . $fnName;
+ }
+ $hasArgument=count($r) === 2;
+ if ($i === 1) {
+ $prev = $fnName . '(' . $array[0];
+ if ($hasArgument) {
+ $prev .= ',' . $r[1];
+ }
+ $prev .= ')';
+ } else {
+ $prev = $fnName . '(' . $prev;
+ if ($hasArgument) {
+ $prev .=','. $r[1] . ')';
+ } else {
+ $prev.=')';
+ }
+ }
+ }
+
+ return $prev;
+ }
+
+ /**
+ * Compile the "regular" echo statements. {{ }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRegularEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ $wrapped = \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
+ return $matches[1] ? \substr($matches[0], 1) : $this->phpTagEcho . $wrapped . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the escaped echo statements. {!! !!}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEscapedEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+
+ return $matches[1] ? $matches[0] : $this->phpTag
+ . \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2])) . '; ?>'
+ . $whitespace;
+ //return $matches[1] ? $matches[0] : $this->phpTag
+ // . 'echo static::e(' . $this->compileEchoDefaults($matches[2]) . '); ? >' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the "@each" tag into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileEach($expression): string
+ {
+ return $this->phpTagEcho . "\$this->renderEach$expression; ?>";
+ }
+
+ protected function compileSet($expression): string
+ {
+ //$segments = \explode('=', \preg_replace("/[()\\\']/", '', $expression));
+ $segments = \explode('=', $this->stripParentheses($expression));
+ $value = (\count($segments) >= 2) ? '=@' . implode('=', array_slice($segments, 1)) : '++';
+ return $this->phpTag . \trim($segments[0]) . $value . ';?>';
+ }
+
+ /**
+ * Compile the yield statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileYield($expression): string
+ {
+ return $this->phpTagEcho . "\$this->yieldContent$expression; ?>";
+ }
+
+ /**
+ * Compile the show statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileShow(): string
+ {
+ return $this->phpTagEcho . '$this->yieldSection(); ?>';
+ }
+
+ /**
+ * Compile the section statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileSection($expression): string
+ {
+ return $this->phpTag . "\$this->startSection$expression; ?>";
+ }
+
+ /**
+ * Compile the append statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileAppend(): string
+ {
+ return $this->phpTag . '$this->appendSection(); ?>';
+ }
+
+ /**
+ * Compile the auth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'if(isset($this->currentUser)): ?>';
+ }
+
+ return $this->phpTag . "if(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the elseauth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'else: ?>';
+ }
+
+ return $this->phpTag . "elseif(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the end-auth statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndAuth(): string
+ {
+ return $this->phpTag . 'endif; ?>';
+ }
+
+ protected function compileCan($expression): string
+ {
+ $v = $this->stripParentheses($expression);
+ return $this->phpTag . 'if (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ /**
+ * Compile the else statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseCan($expression = ''): string
+ {
+ $v = $this->stripParentheses($expression);
+ if ($v) {
+ return $this->phpTag . 'elseif (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ return $this->phpTag . 'else: ?>';
+ }
+ //
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCache
+ * @version 3.42 2020-04-25
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCacheRedis
+ * @version 0.1 2017-12-15 NOT YET IMPLEMENTED, ITS A WIP!!!!!!!!
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Der Controller inkludiert das benötigte Model (gerichte.php in diesem Fall)
+ und ruft die benötigte Funktion db_gerichte_select_all() zum Laden der Daten auf
Kurze Übersicht, wie die Arbeit mit dem Router und der Blade View-Engine funktioniert.
+ +Der Router nimmt den Request entgegen und zerlegt ihn in die einzelnen Teile der URI. Wichtig ist hier vor + allem der Pfad und der Querystring.
+Wenn der Pfad in der Routenkonfiguration (\$config Array aus der Datei
+ routes/web.php) gefunden wird, lädt der Router die angegebene Klasse.
Im vorliegenden Beispiel sehen Sie diese Seite ...
+DemoController.php gefunden werden konnte
+ Sie sehen: da muss einiges stimmen und vieles davon ist Konvention.
+Die Actions in den Controller-Klassen sollen per Konvention immer ein RequestData Objekt
+ entgegennehmen. Beispiel: howto(RequestData \$rd)
Dieses RequestData Objekt wird durch den Router befüllt, wenn Daten in der URL extrahiert werden konnten.
+Daten finden sich URLs...
+ +
+ im Querystring
Beispiel: rufen Sie diese mit
+ {{strtolower(explode('/',$_SERVER["SERVER_PROTOCOL"])[0])}}://{{$_SERVER["HTTP_HOST"]}}/demo?bgcolor=fefbd8&name=Remmy
+ auf, werden bgcolor und name mitsamt Werten als Query Array
+ $rd->query) übergeben
+
Probieren Sie es aus ;)
+ @if(count($rd->args)) +Argumente dieses Aufrufs:
+ + @forelse($rd->args as $a) +Keine weiteren Argumente im Request
+ @endforelse + @endif + @if(count($rd->query)) +Daten aus der Query dieses Aufrufs:
+
+ @forelse($rd->query as $k => $v)
+ $rd->query['{{$k}}']={{$v}}
+ @empty
+ Keine Querydaten
+ @endforelse
+
+ @endif
+ Blade muss installiert sein. + Die Installation ist bereits geschehen und die Bibliothek liegt unter /vendor. +
+Bei der Verwendung der View-Engine gelten einige Konventionen:
+ Die Dateien müssen <viewname>.blade.php heißen und im Ordner views liegen.
+
Sie können der View dann Daten mitgeben, indem Sie alle Daten in ein Array schreiben und dieses dann + übergeben.
+Beispiel:
+
+ view("viewtest",
+ array(
+ "texts"=>$textArray,
+ "persona"=>$persona,
+ "rd"=>$rd
+ )); // öffnet ../views/viewtest.blade.php
+
+ combined request data
+
+ {{print_r($rd->getData(),1)}}
+
+@else
+ this request contained zero parameters
+@endif + +@if(count($rd->getGetData())) +GET request data
+ {{print_r($rd->getGetData(),1)}}
+
+@endif
+
+@if(count($rd->getPostData()))
+ POST request data
+ {{print_r($rd->getPostData(),1)}}
+
+@endif
\ No newline at end of file
diff --git a/M5/emensa/views/examples/m4_7a_queryparameter.blade.php b/M5/emensa/views/examples/m4_7a_queryparameter.blade.php
new file mode 100644
index 0000000..c094999
--- /dev/null
+++ b/M5/emensa/views/examples/m4_7a_queryparameter.blade.php
@@ -0,0 +1,13 @@
+
+
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+ Page 1
+@endsection + +@section("footer") +Footer of Page 1
+@endsection \ No newline at end of file diff --git a/M5/emensa/views/examples/pages/m4_7d_page_2.blade.php b/M5/emensa/views/examples/pages/m4_7d_page_2.blade.php new file mode 100644 index 0000000..920a59a --- /dev/null +++ b/M5/emensa/views/examples/pages/m4_7d_page_2.blade.php @@ -0,0 +1,13 @@ +@extends(".layouts.m4_7d_layout",['title' => "Page 2"]) + +@section("header") + +@endsection + +@section("body") +Page 2
+@endsection + +@section("footer") +Footer of Page 2
+@endsection \ No newline at end of file diff --git a/M5/emensa/views/home.blade.php b/M5/emensa/views/home.blade.php new file mode 100644 index 0000000..474d713 --- /dev/null +++ b/M5/emensa/views/home.blade.php @@ -0,0 +1,34 @@ +@extends("layouts.layout") + +@section("content") +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
+ {{$data['beschreibung']}}
+
+ @else
+ Sie haben eine Action aufgerufen, die zu dieser View führt.
+Vervollständigen Sie die Action, sodass die Aufgabe erfüllt wird.
+@endsection \ No newline at end of file diff --git a/M5/gerichte.zip b/M5/gerichte.zip new file mode 100644 index 0000000..c966121 Binary files /dev/null and b/M5/gerichte.zip differ diff --git a/M5/vendor/autoload.php b/M5/vendor/autoload.php new file mode 100644 index 0000000..b9bd78e --- /dev/null +++ b/M5/vendor/autoload.php @@ -0,0 +1,25 @@ + + * Jordi BoggianoDOCUMENT_ROOT: {$_SERVER['DOCUMENT_ROOT']}Datei nicht gefunden: {$_SERVER['DOCUMENT_ROOT']}/../vendor/autoload.php
"; + echo "Häufigste Ursache
public/ ist nicht als Wurzelverzeichnis verwendet worden.composer update installiert.DOCUMENT_ROOT{$_SERVER['DOCUMENT_ROOT']}Error" . $ex->getMessage() . ""; +} + +use eftec\bladeone\BladeOne; + +/* Routing Script for PHP Dev Server */ +$verbosity = VERBOSITY; +if (preg_match('/\.(?:css|js|png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) { + return false; +} else { + if ($verbosity > 1) { + echo + "
Verbosity-Level: {$verbosity}" .
+ "" . print_r($_SERVER, 1) . "
Request\n", print_r($request), ""; + echo "
Path\n", print_r($path), ""; + echo "
Query\n", print_r($query), ""; + } + } + + // fix: trim slashes + $ctrlName = trim($ctrlName, '/'); + $actionName = trim($actionName, '/'); + + // $config based renaming of Controller/Action, precedes filebased convention + // $config values must use syntax
Routing Config matched request for /" . $ctrlName . "/" . $actionName . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } elseif (array_key_exists($request['path'], $config)) { + // exact match on full path, this also means "/" + $routingConfig = explode('@', $config[$request['path']]); + if ($verbosity > 0) { + echo "
Routing Config matched for full path " . $request['path'] . ":
routing config is
" . print_r($routingConfig, 1) . ''; + } + // important: overwriting controller and action name + $ctrlClass = $routingConfig[0]; + $actionName = $routingConfig[1]; + } else { + if ($verbosity > 0) { + echo "Request $ctrlName/$actionName was not in \$config."; + } + + // fall back to filebased convention: match controller classes in directory + $ctrlClass = ucfirst($ctrlName . 'Controller'); + } + + $ctrlFile = ($ctrlClass . '.php'); + $validControllers = FrontController::getValidControllers($controllerDirectory); + if (!in_array($controllerDirectory . $ctrlFile, $validControllers)) { + if ($verbosity > 0) { + echo "
Controller: $ctrlFile not found in
" . print_r($validControllers, 1) . "
Config Array:
" . print_r($config, 1) . "
" .
+ "Keine entspreche Zuordnung der Route für {$ctrlName}::{$actionName} gefunden. Tippfehler in der Route?" . + "
Es konnte keine Klasse " . $ctrlFile . " gefunden werden! Request fehlgeschlagen.
" . + " Prüfen Sie die Einträge in der Datei config/web.php und gleichen Sie den getätigten Aufruf damit ab.
Stellen Sie sicher, dass die Action/der Controller existiert.
+Das Routing Config-Array hat " . count($config) . " Einträge.
+Exception text
" . $ex->getMessage() . "
Verbindung fehlgeschlagen: " . mysqli_connect_error() . ".
config/db.php:
+ ( ist Benutzer {$config['user']} an Datenbank {$config['database']} auf Server {$config['host']} korrekt?)Fehlermeldung" . mysqli_connect_error() . "", 2, true); + exit(1); + } + + return $link; +} + +function view($viewname, $viewargs = array()) +{ + $views = dirname(__DIR__) . '/views'; + $cache = dirname(__DIR__) . '/storage/cache'; + $blade = new BladeOne($views, $cache, BladeOne::MODE_DEBUG); + + return $blade->run($viewname, $viewargs); +} + +/** + * let the script die if the php minimum version is not met. + * @param $minversion + * @return void + */ +function assert_php_version($minversion = '8.0.0') +{ + $version_too_low = 0; + $minver = explode('.', $minversion); + $version = explode('.', phpversion()); + + if (intval($minver[0]) > intval($version[0])) { + $version_too_low = 1; + } elseif (intval($minver[1]) > intval($version[1])) { + $version_too_low = 1; + } elseif (intval($minver[2]) > intval($version[2])) { + $version_too_low = 1; + } + + if ($version_too_low) { + FrontController::showErrorMessage("Diese PHP-Version wird nicht unterstützt: Minimum PHP Version " . $minversion . "
Der Pfad " . $_SERVER['DOCUMENT_ROOT'] . " enthält " . $charsfound . " problematische Zeichen, die die korrekte Ausführung verhindern.
Bekannte problematische Zeichen sind
+ " . implode(" ", $chars) . " ");
+ exit(1);
+ }
+
+}
+
+function assert_blade(): void
+{
+ if (!class_exists('eftec\bladeone\BladeOne')) {
+ // #ERROR
+ FrontController::showErrorMessage("
+ Tipps für die Lösung:
+führen Sie im Terminal folgende Zeilen aus.
+php bin/composer.phar update oder php bin/composer.phar reinstall eftec/bladeonephp bin/composer.phar dump-autoloadPrüfen Sie im Anschluss: befindet sich in dem Ordner vendor/eftec/bladeone/lib/ die Datei BladeOne.php ?
Starten Sie dann den Webserver neu.
Befragen Sie gerne auch das Forum in Ilias.
Kurze Übersicht, wie die Arbeit mit dem Router und der Blade View-Engine funktioniert.
+ +Der Router nimmt den Request entgegen und zerlegt ihn in die einzelnen Teile der URI. Wichtig ist hier vor + allem der Pfad und der Querystring.
+Wenn der Pfad in der Routenkonfiguration (\$config Array aus der Datei
+ routes/web.php) gefunden wird, lädt der Router die angegebene Klasse.
Im vorliegenden Beispiel sehen Sie diese Seite ...
+DemoController.php gefunden werden konnte
+ Sie sehen: da muss einiges stimmen und vieles davon ist Konvention.
+Die Actions in den Controller-Klassen sollen per Konvention immer ein RequestData Objekt
+ entgegennehmen. Beispiel: howto(RequestData \$rd)
Dieses RequestData Objekt wird durch den Router befüllt, wenn Daten in der URL extrahiert werden konnten.
+Daten finden sich URLs...
+ +
+ im Querystring
Beispiel: rufen Sie diese mit
+ :///demo?bgcolor=fefbd8&name=Remmy
+ auf, werden bgcolor und name mitsamt Werten als Query Array
+ $rd->query) übergeben
+
Probieren Sie es aus ;)
+ args)): ?> +Argumente dieses Aufrufs:
+ + args as $a): $__empty_1 = false; ?> +Keine weiteren Argumente im Request
+ + + query)): ?> +Daten aus der Query dieses Aufrufs:
+
+ query as $k => $v): $__empty_1 = false; ?>
+ $rd->query['']=
+
+
+ Keine Querydaten
+
+
+
+ Blade muss installiert sein. + Die Installation ist bereits geschehen und die Bibliothek liegt unter /vendor. +
+Bei der Verwendung der View-Engine gelten einige Konventionen:
+ Die Dateien müssen <viewname>.blade.php heißen und im Ordner views liegen.
+
Sie können der View dann Daten mitgeben, indem Sie alle Daten in ein Array schreiben und dieses dann + übergeben.
+Beispiel:
+
+ view("viewtest",
+ array(
+ "texts"=>$textArray,
+ "persona"=>$persona,
+ "rd"=>$rd
+ )); // öffnet ../views/viewtest.blade.php
+
+ Fehlermeldung
++ + + + +
Fehlermeldung
++ + + +
Fehlermeldung
++ + + +
Page 1
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 1
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 1"]); } ?> \ No newline at end of file diff --git a/M6/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec b/M6/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec new file mode 100644 index 0000000..961375a --- /dev/null +++ b/M6/emensa/storage/cache/examples.pages.m4_7d_page_2_ed122779e3e904882984750d979c216b1e98ea8d.bladec @@ -0,0 +1,14 @@ + + +startSection("header"); ?> + +stopSection(); ?> + +startSection("body"); ?> +Page 2
+stopSection(); ?> + +startSection("footer"); ?> +Footer of Page 2
+stopSection(); ?> +runChild(".layouts.m4_7d_layout",['title' => "Page 2"]); } ?> \ No newline at end of file diff --git a/M6/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec b/M6/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec new file mode 100644 index 0000000..c54dc25 --- /dev/null +++ b/M6/emensa/storage/cache/home_be3f101c28919ade210629435b0b22d1f6f23f27.bladec @@ -0,0 +1,36 @@ + + +startSection("content"); ?> +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + +
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
++ + + + + +stopSection(); ?> + +startSection("footer"); ?> + +
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is equals to abc
+ *
+ * Example: (includeScope=true)
+ * @include("template",['a1'=>'abc']) // a1 is equals to abc
+ * @include("template",[]) // a1 is not defined
+ *
+ */
+ public $includeScope = false;
+ /**
+ * @var callable[] It allows to parse the compiled output using a function.
+ * This function doesn't require to return a value
+ * $this->compileCallbacks[]= static function (&$content, $templatename=null) {
+ * $content=strtoupper($content);
+ * };
+ *
+ */
+ public $compileCallbacks = [];
+ /** @var array All the registered extensions. */
+ protected $extensions = [];
+ /** @var array All the finished, captured sections. */
+ protected $sections = [];
+ /** @var string The template currently being compiled. For example "folder.template" */
+ protected $fileName;
+ protected $currentView;
+ protected $notFoundPath;
+ /** @var string File extension for the template files. */
+ protected $fileExtension = '.blade.php';
+ /** @var array The stack of in-progress sections. */
+ protected $sectionStack = [];
+ /** @var array The stack of in-progress loops. */
+ protected $loopsStack = [];
+ /** @var array Dictionary of variables */
+ protected $variables = [];
+ /** @var array Dictionary of global variables */
+ protected $variablesGlobal = [];
+ /** @var array All the available compiler functions. */
+ protected $compilers = [
+ 'Extensions',
+ 'Statements',
+ 'Comments',
+ 'Echos',
+ ];
+ /** @var string|null it allows to set the stack */
+ protected $viewStack;
+ /** @var array used by $this->composer() */
+ protected $composerStack = [];
+ /** @var array The stack of in-progress push sections. */
+ protected $pushStack = [];
+ /** @var array All the finished, captured push sections. */
+ protected $pushes = [];
+ /** @var int The number of active rendering operations. */
+ protected $renderCount = 0;
+ /** @var string[] Get the template path for the compiled views. */
+ protected $templatePath;
+ /** @var string Get the compiled path for the compiled views. If null then it uses the default path */
+ protected $compiledPath;
+ /** @var string the extension of the compiled file. */
+ protected $compileExtension = '.bladec';
+ /**
+ * @var string=['auto','sha1','md5'][$i] It determines how the compiled filename will be called.
+ * $this->wrapPHP('$hello'); // "< ?php echo $this->e($hello); ? >"
+ * $this->wrapPHP('$hello',''); // < ?php echo $this->e($hello); ? >
+ * $this->wrapPHP('$hello','',false); // < ?php echo $hello; ? >
+ * $this->wrapPHP('"hello"'); // "< ?php echo $this->e("hello"); ? >"
+ * $this->wrapPHP('hello()'); // "< ?php echo $this->e(hello()); ? >"
+ *
+ *
+ * @param ?string $input The input value
+ * @param string $quote The quote used (to quote the result)
+ * @param bool $parse If the result will be parsed or not. If false then it's returned without $this->e
+ * @return string
+ */
+ public function wrapPHP($input, $quote = '"', $parse = true): string
+ {
+ if($input===null) {
+ return 'null';
+ }
+ if (strpos($input, '(') !== false && !$this->isQuoted($input)) {
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+ if (strpos($input, '$') === false) {
+ if ($parse) {
+ return self::enq($input);
+ }
+
+ return $input;
+ }
+ if ($parse) {
+ return $quote . $this->phpTagEcho . '$this->e(' . $input . ');?>' . $quote;
+ }
+ return $quote . $this->phpTagEcho . $input . ';?>' . $quote;
+ }
+
+ /**
+ * Returns true if the text is surrounded by quotes (double or single quote)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isQuoted($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ if ($text[0] === '"' && substr($text, -1) === '"') {
+ return true;
+ }
+ return ($text[0] === "'" && substr($text, -1) === "'");
+ }
+
+ /**
+ * Escape HTML entities in a string.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function enq($value): string
+ {
+ if (\is_array($value) || \is_object($value)) {
+ return \htmlentities(\print_r($value, true), ENT_NOQUOTES, 'UTF-8', false);
+ }
+ return \htmlentities($value??'', ENT_NOQUOTES, 'UTF-8', false);
+ }
+
+ /**
+ * @param string $view example "folder.template"
+ * @param string|null $alias example "mynewop". If null then it uses the name of the template.
+ */
+ public function addInclude($view, $alias = null): void
+ {
+ if (!isset($alias)) {
+ $alias = \explode('.', $view);
+ $alias = \end($alias);
+ }
+ $this->directive($alias, function ($expression) use ($view) {
+ $expression = $this->stripParentheses($expression) ?: '[]';
+ return "$this->phpTag echo \$this->runChild('$view', $expression); ?>";
+ });
+ }
+
+ /**
+ * Register a handler for custom directives.
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directive($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = false;
+ }
+
+ /**
+ * Strip the parentheses from the given expression.
+ *
+ * @param string|null $expression
+ * @return string
+ */
+ public function stripParentheses($expression): string
+ {
+ if (\is_null($expression)) {
+ return '';
+ }
+
+ if (static::startsWith($expression, '(')) {
+ $expression = \substr($expression, 1, -1);
+ }
+
+ return $expression;
+ }
+
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function startsWith($haystack, $needles): bool
+ {
+ foreach ((array)$needles as $needle) {
+ if ($needle != '') {
+ if (\function_exists('mb_strpos')) {
+ if ($haystack !== null && \mb_strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ } elseif ($haystack !== null && \strpos($haystack, $needle) === 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * If false then the file is not compiled, and it is executed directly from the memory.Example:setPath("somefolder","otherfolder"); + * + * @param null|string|string[] $templatePath If null then it uses the current path /views folder + * @param null|string $compiledPath If null then it uses the current path /views folder + */ + public function setPath($templatePath, $compiledPath): void + { + if ($templatePath === null) { + $templatePath = \getcwd() . '/views'; + } + if ($compiledPath === null) { + $compiledPath = \getcwd() . '/compiles'; + } + $this->templatePath = (is_array($templatePath)) ? $templatePath : [$templatePath]; + $this->compiledPath = $compiledPath; + } + + /** + * @return array + */ + public function getAliasClasses(): array + { + return $this->aliasClasses; + } + + /** + * @param array $aliasClasses + */ + public function setAliasClasses($aliasClasses): void + { + $this->aliasClasses = $aliasClasses; + } + + /** + * @param string $aliasName + * @param string $classWithNS + */ + public function addAliasClasses($aliasName, $classWithNS): void + { + $this->aliasClasses[$aliasName] = $classWithNS; + } + //
+ * Text::wildCardComparison('abcdef','abc*'); // true
+ * Text::wildCardComparison('abcdef','*def'); // true
+ * Text::wildCardComparison('abcdef','*abc*'); // true
+ * Text::wildCardComparison('abcdef','*cde*'); // true
+ * Text::wildCardComparison('abcdef','*cde'); // false
+ *
+ *
+ *
+ * @param string $text
+ * @param string|null $textWithWildcard
+ *
+ * @return bool
+ */
+ protected function wildCardComparison($text, $textWithWildcard): bool
+ {
+ if (($textWithWildcard === null || $textWithWildcard === '')
+ || strpos($textWithWildcard, '*') === false
+ ) {
+ // if the text with wildcard is null or empty, or it contains two ** or it contains no * then..
+ return $text == $textWithWildcard;
+ }
+ if ($textWithWildcard === '*' || $textWithWildcard === '**') {
+ return true;
+ }
+ $c0 = $textWithWildcard[0];
+ $c1 = substr($textWithWildcard, -1);
+ $textWithWildcardClean = str_replace('*', '', $textWithWildcard);
+ $p0 = strpos($text, $textWithWildcardClean);
+ if ($p0 === false) {
+ // no matches.
+ return false;
+ }
+ if ($c0 === '*' && $c1 === '*') {
+ // $textWithWildcard='*asasasas*'
+ return true;
+ }
+ if ($c1 === '*') {
+ // $textWithWildcard='asasasas*'
+ return $p0 === 0;
+ }
+ // $textWithWildcard='*asasasas'
+ $len = strlen($textWithWildcardClean);
+ return (substr($text, -$len) === $textWithWildcardClean);
+ }
+
+ protected function methodExistsStatic($class, $method): bool
+ {
+ try {
+ return (new \ReflectionMethod($class, $method))->isStatic();
+ } catch (\ReflectionException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Compile the view at the given path.
+ *
+ * @param string $templateName The name of the template. Example folder.template
+ * @param bool $forced If the compilation will be forced (always compile) or not.
+ * @return boolean|string True if the operation was correct, or false (if not exception)
+ * if it fails. It returns a string (the content compiled) if isCompiled=false
+ * @throws Exception
+ */
+ public function compile($templateName = null, $forced = false)
+ {
+ $compiled = $this->getCompiledFile($templateName);
+ $template = $this->getTemplateFile($templateName);
+ if (!$this->isCompiled) {
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ return $contents;
+ }
+ if ($forced || $this->isExpired($templateName)) {
+ // compile the original file
+ $contents = $this->compileString($this->getFile($template));
+ $this->compileCallBacks($contents, $templateName);
+ if ($this->optimize) {
+ // removes space and tabs and replaces by a single space
+ $contents = \preg_replace('/^ {2,}/m', ' ', $contents);
+ $contents = \preg_replace('/^\t{2,}/m', ' ', $contents);
+ }
+ $ok = @\file_put_contents($compiled, $contents);
+ if ($ok === false) {
+ $this->showError(
+ 'Compiling',
+ "Unable to save the file [$compiled]. Check the compile folder is defined and has the right permission"
+ );
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get the full path of the compiled file.
+ *
+ * @param string $templateName
+ * @return string
+ */
+ public function getCompiledFile($templateName = ''): string
+ {
+ $templateName = (empty($templateName)) ? $this->fileName : $templateName;
+
+ $fullPath = $this->getTemplateFile($templateName);
+ if($fullPath == '') {
+ throw new \RuntimeException('Template not found: ' . $templateName);
+ }
+
+ $style=$this->compileTypeFileName;
+ if ($style==='auto') {
+ $style='sha1';
+ }
+ $hash = $style === 'md5' ? \md5($fullPath) : \sha1($fullPath);
+ return $this->compiledPath . '/' . basename($templateName) . '_' . $hash . $this->compileExtension;
+ }
+
+
+
+ /**
+ * Get the mode of the engine.See BladeOne::MODE_* constants
+ *
+ * @return int=[self::MODE_AUTO,self::MODE_DEBUG,self::MODE_FAST,self::MODE_SLOW][$i]
+ */
+ public function getMode(): int
+ {
+ if (\defined('BLADEONE_MODE')) {
+ $this->mode = BLADEONE_MODE;
+ }
+ return $this->mode;
+ }
+
+ /**
+ * Set the compile modeExample: getTemplateFile('.abc.def')
+ * + * @param string $templateName template name. If not template is set then it uses the base template. + * @return string + */ + public function getTemplateFile($templateName = ''): string + { + $templateName = (empty($templateName)) ? $this->fileName : $templateName; + if (\strpos($templateName, '/') !== false) { + return $this->locateTemplate($templateName); // it's a literal + } + $arr = \explode('.', $templateName); + $c = \count($arr); + if ($c == 1) { + // it's in the root of the template folder. + return $this->locateTemplate($templateName . $this->fileExtension); + } + + $file = $arr[$c - 1]; + \array_splice($arr, $c - 1, $c - 1); // delete the last element + $path = \implode('/', $arr); + return $this->locateTemplate($path . '/' . $file . $this->fileExtension); + } + + /** + * Find template file with the given name in all template paths in the order the paths were written + * + * @param string $name Filename of the template (without path) + * @return string template file + */ + protected function locateTemplate($name): string + { + $this->notFoundPath = ''; + foreach ($this->templatePath as $dir) { + $path = $dir . '/' . $name; + if (\is_file($path)) { + return $path; + } + + $this->notFoundPath .= $path . ","; + } + return ''; + } + + /** + * Get the contents of a file. + * + * @param string $fullFileName It gets the content of a filename or returns ''. + * + * @return string + */ + public function getFile($fullFileName): string + { + if (\is_file($fullFileName)) { + return \file_get_contents($fullFileName); + } + $this->showError('getFile', "File does not exist at paths (separated by comma) [$this->notFoundPath] or permission denied"); + return ''; + } + + protected function compileCallBacks(&$contents, $templateName): void + { + if (!empty($this->compileCallbacks)) { + foreach ($this->compileCallbacks as $callback) { + if (is_callable($callback)) { + $callback($contents, $templateName); + } + } + } + } + + /** + * Determine if the view has expired. + * + * @param string|null $fileName + * @return bool + */ + public function isExpired($fileName): bool + { + $compiled = $this->getCompiledFile($fileName); + $template = $this->getTemplateFile($fileName); + if (!\is_file($template)) { + if ($this->mode == self::MODE_DEBUG) { + $this->showError('Read file', 'Template not found :' . $this->fileName . " on file: $template", true); + } else { + $this->showError('Read file', 'Template not found :' . $this->fileName, true); + } + } + // If the compiled file doesn't exist we will indicate that the view is expired + // so that it can be re-compiled. Else, we will verify the last modification + // of the views is less than the modification times of the compiled views. + if (!$this->compiledPath || !\is_file($compiled)) { + return true; + } + return \filemtime($compiled) < \filemtime($template); + } + + /** + * Evaluates a text (string) using the current variables + * + * @param string $content + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluateText($content, $variables): string + { + \ob_start(); + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + eval(' ?>' . $content . $this->phpTag); + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * Handle a view exception. + * + * @param Exception $e + * @return void + * @throws $e + */ + protected function handleViewException($e): void + { + \ob_get_clean(); + throw $e; + } + + /** + * Evaluates a compiled file using the current variables + * + * @param string $compiledFile full path of the compile file. + * @param array $variables + * @return string + * @throws Exception + */ + protected function evaluatePath($compiledFile, $variables): string + { + \ob_start(); + // note, the variables are extracted locally inside this method, + // they are not global variables :-3 + \extract($variables); + // We'll evaluate the contents of the view inside a try/catch block, so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + include $compiledFile; + } catch (Exception $e) { + $this->handleViewException($e); + } + return \ltrim(\ob_get_clean()); + } + + /** + * @param array $views array of views + * @param array $value + * @return string + * @throws Exception + */ + public function includeFirst($views = [], $value = []): string + { + foreach ($views as $view) { + if ($this->templateExist($view)) { + return $this->runChild($view, $value); + } + } + return ''; + } + + /** + * Returns true if the template exists. Otherwise, it returns false + * + * @param $templateName + * @return bool + */ + protected function templateExist($templateName): bool + { + $file = $this->getTemplateFile($templateName); + return \is_file($file); + } + + /** + * Convert an array such as ["class1"=>"myclass","style="mystyle"] to class1='myclass' style='mystyle' string + * + * @param array|string $array array to convert + * @return string + */ + public function convertArg($array): string + { + if (!\is_array($array)) { + return $array; // nothing to convert. + } + return \implode(' ', \array_map('static::convertArgCallBack', \array_keys($array), $array)); + } + + /** + * Returns the current token. if there is not a token then it generates a new one. + * It could require an open session. + * + * @param bool $fullToken It returns a token with the current ip. + * @param string $tokenId [optional] Name of the token. + * + * @return string + */ + public function getCsrfToken($fullToken = false, $tokenId = '_token'): string + { + if ($this->csrf_token == '') { + $this->regenerateToken($tokenId); + } + if ($fullToken) { + return $this->csrf_token . '|' . $this->ipClient(); + } + return $this->csrf_token; + } + + /** + * Regenerates the csrf token and stores in the session. + * It requires an open session. + * + * @param string $tokenId [optional] Name of the token. + */ + public function regenerateToken($tokenId = '_token'): void + { + try { + $this->csrf_token = \bin2hex(\random_bytes(10)); + } catch (Exception $e) { + $this->csrf_token = '123456789012345678901234567890'; // unable to generates a random token. + } + @$_SESSION[$tokenId] = $this->csrf_token . '|' . $this->ipClient(); + } + + public function ipClient() + { + if ( + isset($_SERVER['HTTP_X_FORWARDED_FOR']) + && \preg_match('/^(d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})$/', $_SERVER['HTTP_X_FORWARDED_FOR']) + ) { + return $_SERVER['HTTP_X_FORWARDED_FOR']; + } + return $_SERVER['REMOTE_ADDR'] ?? ''; + } + + /** + * Validates if the csrf token is valid or not.'; + \var_dump($object); + echo ''; + } else { + /** @noinspection BadExpressionStatementJS */ + /** @noinspection JSVoidFunctionReturnValueUsed */ + echo ''; + } + } + + /** + * Start injecting content into a section. + * + * @param string $section + * @param string $content + * @return void + */ + public function startSection($section, $content = ''): void + { + if ($content === '') { + \ob_start() && $this->sectionStack[] = $section; + } else { + $this->extendSection($section, $content); + } + } + + /** + * Stop injecting content into a section and append it. + * + * @return string + * @throws InvalidArgumentException + */ + public function appendSection(): string + { + if (empty($this->sectionStack)) { + $this->showError('appendSection', 'Cannot end a section without first starting one.', true, true); + } + $last = \array_pop($this->sectionStack); + if (isset($this->sections[$last])) { + $this->sections[$last] .= \ob_get_clean(); + } else { + $this->sections[$last] = \ob_get_clean(); + } + return $last; + } + + /** + * Adds a global variable. If $varname is an array then it merges all the values. + * Example: + *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable or, it is an associative array
+ * @param mixed $value
+ * @return $this
+ * @see BladeOne::share
+ */
+ public function with($varname, $value = null): BladeOne
+ {
+ return $this->share($varname, $value);
+ }
+
+ /**
+ * Adds a global variable. If $varname is an array then it merges all the values.
+ * Example:
+ *
+ * $this->share('variable',10.5);
+ * $this->share('variable2','hello');
+ * // or we could add the two variables as:
+ * $this->share(['variable'=>10.5,'variable2'=>'hello']);
+ *
+ *
+ * @param string|array $varname It is the name of the variable, or it is an associative array
+ * @param mixed $value
+ * @return $this
+ */
+ public function share($varname, $value = null): BladeOne
+ {
+ if (is_array($varname)) {
+ $this->variablesGlobal = \array_merge($this->variablesGlobal, $varname);
+ } else {
+ $this->variablesGlobal[$varname] = $value;
+ }
+ return $this;
+ }
+
+ /**
+ * Get the string contents of a section.
+ *
+ * @param string $section
+ * @param string $default
+ * @return string
+ */
+ public function yieldContent($section, $default = ''): string
+ {
+ if (isset($this->sections[$section])) {
+ return \str_replace($this->PARENTKEY, $default, $this->sections[$section]);
+ }
+
+ return $default;
+ }
+
+ /**
+ * Register a custom Blade compiler.
+ *
+ * @param callable $compiler
+ * @return void
+ */
+ public function extend(callable $compiler): void
+ {
+ $this->extensions[] = $compiler;
+ }
+
+ /**
+ * Register a handler for custom directives for run at runtime
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directiveRT($name, callable $handler): void
+ {
+ $this->customDirectives[$name] = $handler;
+ $this->customDirectivesRT[$name] = true;
+ }
+
+ /**
+ * Sets the escaped content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @return void
+ */
+ public function setEscapedContentTags($openTag, $closeTag): void
+ {
+ $this->setContentTags($openTag, $closeTag, true);
+ }
+
+ /**
+ * Gets the content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getContentTags(): array
+ {
+ return $this->getTags();
+ }
+
+ /**
+ * Sets the content tags used for the compiler.
+ *
+ * @param string $openTag
+ * @param string $closeTag
+ * @param bool $escaped
+ * @return void
+ */
+ public function setContentTags($openTag, $closeTag, $escaped = false): void
+ {
+ $property = ($escaped === true) ? 'escapedTags' : 'contentTags';
+ $this->{$property} = [\preg_quote($openTag), \preg_quote($closeTag)];
+ }
+
+ /**
+ * Gets the tags used for the compiler.
+ *
+ * @param bool $escaped
+ * @return array
+ */
+ protected function getTags($escaped = false): array
+ {
+ $tags = $escaped ? $this->escapedTags : $this->contentTags;
+ return \array_map('stripcslashes', $tags);
+ }
+
+ /**
+ * Gets the escaped content tags used for the compiler.
+ *
+ * @return array
+ */
+ public function getEscapedContentTags(): array
+ {
+ return $this->getTags(true);
+ }
+
+ /**
+ * Sets the function used for resolving classes with inject.
+ *
+ * @param callable $function
+ */
+ public function setInjectResolver(callable $function): void
+ {
+ $this->injectResolver = $function;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getFileExtension(): string
+ {
+ return $this->fileExtension;
+ }
+
+ /**
+ * Set the file extension for the template files.
+ * It must include the leading dot e.g. ".blade.php"
+ *
+ * @param string $fileExtension Example: .prefix.ext
+ */
+ public function setFileExtension($fileExtension): void
+ {
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * Get the file extension for template files.
+ *
+ * @return string
+ */
+ public function getCompiledExtension(): string
+ {
+ return $this->compileExtension;
+ }
+
+ /**
+ * Set the file extension for the compiled files.
+ * Including the leading dot for the extension is required, e.g. ".bladec"
+ *
+ * @param $fileExtension
+ */
+ public function setCompiledExtension($fileExtension): void
+ {
+ $this->compileExtension = $fileExtension;
+ }
+ /**
+ * @return string
+ * @see BladeOne::setCompileTypeFileName
+ */
+ public function getCompileTypeFileName(): string
+ {
+ return $this->compileTypeFileName;
+ }
+
+ /**
+ * It determines how the compiled filename will be called.
+ * $this->setView('folder.view')->share(['var1'=>20])->run(); // or $this->run('folder.view',['var1'=>20]);
+ *
+ *
+ * @param string $view
+ * @return BladeOne
+ */
+ public function setView($view): BladeOne
+ {
+ $this->viewStack = $view;
+ return $this;
+ }
+
+ /**
+ * It injects a function, an instance, or a method class when a view is called.
+ * $this->composer('folder.view',function($bladeOne) { $bladeOne->share('newvalue','hi there'); });
+ * $this->composer('folder.view','namespace1\namespace2\SomeClass'); // SomeClass must exist, and it must have the
+ * // method 'composer'
+ * $this->composer('folder.*',$instance); // $instance must have the method called 'composer'
+ * $this->composer(); // clear all composer.
+ *
+ *
+ * @param string|array|null $view It could contain wildcards (*). Example: 'aa.bb.cc','*.bb.cc','aa.bb.*','*.bb.*'
+ *
+ * @param callable|string|null $functionOrClass
+ * @return BladeOne
+ */
+ public function composer($view = null, $functionOrClass = null): BladeOne
+ {
+ if ($view === null && $functionOrClass === null) {
+ $this->composerStack = [];
+ return $this;
+ }
+ if (is_array($view)) {
+ foreach ($view as $v) {
+ $this->composerStack[$v] = $functionOrClass;
+ }
+ } else {
+ $this->composerStack[$view] = $functionOrClass;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Start a component rendering process.
+ *
+ * @param string $name
+ * @param array $data
+ * @return void
+ */
+ public function startComponent($name, array $data = []): void
+ {
+ if (\ob_start()) {
+ $this->componentStack[] = $name;
+
+ $this->componentData[$this->currentComponent()] = $data;
+
+ $this->slots[$this->currentComponent()] = [];
+ }
+ }
+
+ /**
+ * Get the index for the current component.
+ *
+ * @return int
+ */
+ protected function currentComponent(): int
+ {
+ return \count($this->componentStack) - 1;
+ }
+
+ /**
+ * Render the current component.
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function renderComponent(): string
+ {
+ //echo "
+ * $this->setBaseUrl('http://domain.dom/myblog');
+ * $this->setBaseUrl('http://domain.dom/corporate/erp');
+ * $this->setBaseUrl('http://domain.dom/blog.php?args=20'); // avoid this one.
+ * $this->setBaseUrl('http://another.dom');
+ *
+ *
+ * @param string $baseUrl Example http://www.web.com/folder https://www.web.com/folder/anotherfolder
+ * @return BladeOne
+ */
+ public function setBaseUrl($baseUrl): BladeOne
+ {
+ $this->baseUrl = \rtrim($baseUrl, '/'); // base with the url trimmed
+ $this->baseDomain = @parse_url($this->baseUrl)['host'];
+ $currentUrl = $this->getCurrentUrlCalculated();
+ if ($currentUrl === '') {
+ $this->relativePath = '';
+ return $this;
+ }
+ if (\strpos($currentUrl, $this->baseUrl) === 0) {
+ $part = \str_replace($this->baseUrl, '', $currentUrl);
+ $numf = \substr_count($part, '/') - 1;
+ $numf = ($numf > 10) ? 10 : $numf; // avoid overflow
+ $this->relativePath = ($numf < 0) ? '' : \str_repeat('../', $numf);
+ } else {
+ $this->relativePath = '';
+ }
+ return $this;
+ }
+
+ /**
+ * It gets the full current url calculated with the information sends by the user.
+ * // current url='http://domain.dom/page/subpage/web.php?aaa=2
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ * $this->setBaseUrl('http://domain.dom/');
+ * $this->getRelativePath(); // '../../'
+ *
+ * Note:The relative path is calculated when we set the base url.
+ *
+ * @return string
+ * @see BladeOne::setBaseUrl
+ */
+ public function getRelativePath(): string
+ {
+ return $this->relativePath;
+ }
+
+ /**
+ * It gets the full current canonical url.
+ * $this->addInsideQuote("'hello'"," world"); // 'hello world'
+ * $this->addInsideQuote("hello"," world"); // hello world
+ *
+ *
+ * @param $quoted
+ * @param $newFragment
+ * @return string
+ */
+ public function addInsideQuote($quoted, $newFragment): string
+ {
+ if ($this->isQuoted($quoted)) {
+ return substr($quoted, 0, -1) . $newFragment . substr($quoted, -1);
+ }
+ return $quoted . $newFragment;
+ }
+
+ /**
+ * Return true if the string is a php variable (it starts with $)
+ *
+ * @param string|null $text
+ * @return bool
+ */
+ public function isVariablePHP($text): bool
+ {
+ if (!$text || strlen($text) < 2) {
+ return false;
+ }
+ return $text[0] === '$';
+ }
+
+ /**
+ * It's the same as "@_e", however it parses the text (using sprintf).
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _ef($phrase): string
+ {
+ $argv = \func_get_args();
+ $r = $this->_e($phrase);
+ $argv[0] = $r; // replace the first argument with the translation.
+ $result = @sprintf(...$argv);
+ return !$result ? $r : $result;
+ }
+
+ /**
+ * Tries to translate the word if it's in the array defined by BladeOneLang::$dictionary
+ * If the operation fails then, it returns the original expression without translation.
+ *
+ * @param $phrase
+ *
+ * @return string
+ */
+ public function _e($phrase): string
+ {
+ if ((!\array_key_exists($phrase, static::$dictionary))) {
+ $this->missingTranslation($phrase);
+ return $phrase;
+ }
+
+ return static::$dictionary[$phrase];
+ }
+
+ /**
+ * Log a missing translation into the file $this->missingLog.'; var_dump$expression; echo '';?>"; + } + + /** + * Execute the case tag. + * + * @param $expression + * @return string + */ + protected function compileCase($expression): string + { + if ($this->firstCaseInSwitch) { + $this->firstCaseInSwitch = false; + return 'case ' . $expression . ': ?>'; + } + return $this->phpTag . "case $expression: ?>"; + } + + /** + * Compile the while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileWhile($expression): string + { + return $this->phpTag . "while$expression: ?>"; + } + + /** + * default tag used for switch/case + * + * @return string + */ + protected function compileDefault(): string + { + if ($this->firstCaseInSwitch) { + return $this->showError('@default', '@switch without any @case', true); + } + return $this->phpTag . 'default: ?>'; + } + + protected function compileEndSwitch(): string + { + --$this->switchCount; + if ($this->switchCount < 0) { + return $this->showError('@endswitch', 'Missing @switch', true); + } + return $this->phpTag . '} // end switch ?>'; + } + + /** + * Compile while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileInject($expression): string + { + $ex = $this->stripParentheses($expression); + $p0 = \strpos($ex, ','); + if (!$p0) { + $var = $this->stripQuotes($ex); + $namespace = ''; + } else { + $var = $this->stripQuotes(\substr($ex, 0, $p0)); + $namespace = $this->stripQuotes(\substr($ex, $p0 + 1)); + } + return $this->phpTag . "\$$var = \$this->injectClass('$namespace', '$var'); ?>"; + } + + /** + * Remove first and end quote from a quoted string of text + * + * @param mixed $text + * @return null|string|string[] + */ + public function stripQuotes($text) + { + if (!$text || strlen($text) < 2) { + return $text; + } + $text = trim($text); + $p0 = $text[0]; + $p1 = \substr($text, -1); + if ($p0 === $p1 && ($p0 === '"' || $p0 === "'")) { + return \substr($text, 1, -1); + } + return $text; + } + + /** + * Execute the user defined extensions. + * + * @param string $value + * @return string + */ + protected function compileExtensions($value): string + { + foreach ($this->extensions as $compiler) { + $value = $compiler($value, $this); + } + return $value; + } + + /** + * Compile Blade comments into valid PHP. + * + * @param string $value + * @return string + */ + protected function compileComments($value): string + { + $pattern = \sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]); + return \preg_replace($pattern, $this->phpTag . '/*$1*/ ?>', $value); + } + + /** + * Compile Blade echos into valid PHP. + * + * @param string $value + * @return string + * @throws Exception + */ + protected function compileEchos($value): string + { + foreach ($this->getEchoMethods() as $method => $length) { + $value = $this->$method($value); + } + return $value; + } + + /** + * Get the echo methods in the proper order for compilation. + * + * @return array + */ + protected function getEchoMethods(): array + { + $methods = [ + 'compileRawEchos' => \strlen(\stripcslashes($this->rawTags[0])), + 'compileEscapedEchos' => \strlen(\stripcslashes($this->escapedTags[0])), + 'compileRegularEchos' => \strlen(\stripcslashes($this->contentTags[0])), + ]; + \uksort($methods, static function ($method1, $method2) use ($methods) { + // Ensure the longest tags are processed first + if ($methods[$method1] > $methods[$method2]) { + return -1; + } + if ($methods[$method1] < $methods[$method2]) { + return 1; + } + // Otherwise, give preference to raw tags (assuming they've overridden) + if ($method1 === 'compileRawEchos') { + return -1; + } + if ($method2 === 'compileRawEchos') { + return 1; + } + if ($method1 === 'compileEscapedEchos') { + return -1; + } + if ($method2 === 'compileEscapedEchos') { + return 1; + } + throw new BadMethodCallException("Method [$method1] not defined"); + }); + return $methods; + } + + /** + * Compile Blade statements that start with "@". + * + * @param string $value + * + * @return array|string|string[]|null + */ + protected function compileStatements($value) + { + /** + * @param array $match + * [0]=full expression with @ and parenthesis + * [1]=expression without @ and argument + * [2]=???? + * [3]=argument with parenthesis and without the first @ + * [4]=argument without parenthesis. + * + * @return mixed|string + */ + $callback = function ($match) { + if (static::contains($match[1], '@')) { + // @@escaped tag + $match[0] = isset($match[3]) ? $match[1] . $match[3] : $match[1]; + } else { + if (strpos($match[1], '::') !== false) { + // Someclass::method + return $this->compileStatementClass($match); + } + if (isset($this->customDirectivesRT[$match[1]])) { + if ($this->customDirectivesRT[$match[1]]) { + $match[0] = $this->compileStatementCustom($match); + } else { + $match[0] = \call_user_func( + $this->customDirectives[$match[1]], + $this->stripParentheses(static::get($match, 3)) + ); + } + } elseif (\method_exists($this, $method = 'compile' . \ucfirst($match[1]))) { + // it calls the function compile
+ * $this->parseArgs('a=2,b='a,b,c',d'); // ['a'=>'2','b'=>'a,b,c','d'=>null]
+ * $this->parseArgs('a=2,b=c,d'); // ['a'=>'2','b'=>'c','d'=>null]
+ * $this->parseArgs('a=2 b=c',' '); // ['a'=>'2','b'=>'c']
+ * $this->parseArgs('a:2 b:c',' ',':'); // ['a'=>'2','b'=>'c']
+ *
+ * Note: parseArgs('a = 2 b = c',' '); with return 4 values instead of 2.
+ *
+ * @param string $text the text to separate
+ * @param string $separator the separator of arguments
+ * @param string $assigment the character used to assign a new value
+ * @param bool $emptyKey if the argument is without value, we return it as key (true) or value (false) ?
+ * @return array
+ */
+ public function parseArgs($text, $separator = ',', $assigment = '=', $emptyKey = true): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = $text; // str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = strlen($chars);
+ $stringArr = '"\'¬';
+ $parenthesis = '([{';
+ $parenthesisClose = ')]}';
+ $insidePar = false;
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ // we check if the character is a parenthesis.
+ $pp = strpos($parenthesis, $char);
+ if ($pp !== false) {
+ // is a parenthesis, so we mark as inside a parenthesis.
+ $insidePar = $parenthesisClose[$pp];
+ }
+ if ($char === $insidePar) {
+ // we close the parenthesis.
+ $insidePar = false;
+ }
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ // we found a string initializer
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator && !$insidePar) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ // duct taping for key= argument (it has a space). however, it doesn't work with key =argument
+ /*
+ foreach ($parts as $k=>$part) {
+ if(substr($part,-1)===$assigment && isset($parts[$k+1])) {
+ var_dump('ok');
+ $parts[$k].=$parts[$k+1];
+ unset($parts[$k+1]);
+ }
+ }
+ */
+ foreach ($parts as $part) {
+ $part = trim($part);
+ if ($part) {
+ $char = $part[0];
+ if (strpos($stringArr, $char) !== false) { // if ($char === '"' || $char === "'" || $char === "¬") {
+ if ($emptyKey) {
+ $result[$part] = null;
+ } else {
+ $result[] = $part;
+ }
+ } else {
+ $r = explode($assigment, $part, 2);
+ if (count($r) === 2) {
+ // key=value.
+ $result[trim($r[0])] = trim($r[1]);
+ } elseif ($emptyKey) {
+ $result[trim($r[0])] = null;
+ } else {
+ $result[] = trim($r[0]);
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function parseArgsOld($text, $separator = ','): array
+ {
+ if ($text === null || $text === '') {
+ return []; //nothing to convert.
+ }
+ $chars = str_split($text);
+ $parts = [];
+ $nextpart = '';
+ $strL = count($chars);
+ /** @noinspection ForeachInvariantsInspection */
+ for ($i = 0; $i < $strL; $i++) {
+ $char = $chars[$i];
+ if ($char === '"' || $char === "'") {
+ $inext = strpos($text, $char, $i + 1);
+ $inext = $inext === false ? $strL : $inext;
+ $nextpart .= substr($text, $i, $inext - $i + 1);
+ $i = $inext;
+ } else {
+ $nextpart .= $char;
+ }
+ if ($char === $separator) {
+ $parts[] = substr($nextpart, 0, -1);
+ $nextpart = '';
+ }
+ }
+ if ($nextpart !== '') {
+ $parts[] = $nextpart;
+ }
+ $result = [];
+ foreach ($parts as $part) {
+ $r = explode('=', $part, 2);
+ $result[trim($r[0])] = count($r) === 2 ? trim($r[1]) : null;
+ }
+ return $result;
+ }
+
+ /**
+ * Compile the "raw" echo statements.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRawEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ return $matches[1] ? \substr(
+ $matches[0],
+ 1
+ ) : $this->phpTagEcho . $this->compileEchoDefaults($matches[2]) . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the default values for the echo statement.
+ * Example:
+ * {{ $test or 'test2' }} compiles to {{ isset($test) ? $test : 'test2' }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEchoDefaults($value): string
+ {
+ // Source: https://www.php.net/manual/en/language.variables.basics.php
+ $patternPHPVariableName = '\$[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*';
+
+ $result = \preg_replace('/^(' . $patternPHPVariableName . ')\s+or\s+(.+?)$/s', 'isset($1) ? $1 : $2', $value);
+ if (!$this->pipeEnable) {
+ return $this->fixNamespaceClass($result);
+ }
+ return $this->pipeDream($this->fixNamespaceClass($result));
+ }
+
+ /**
+ * It converts a string separated by pipes | into a filtered expression.
+ * $this->pipeDream('$name | strtolower | substr:0,4'); // strtolower(substr($name ,0,4)
+ * $this->pipeDream('$name| getMode') // $this->getMode($name)
+ *
+ *
+ * @param string $result
+ * @return string
+ * @\eftec\bladeone\BladeOne::$pipeEnable
+ */
+ protected function pipeDream($result): string
+ {
+ $array = preg_split('~\\\\.(*SKIP)(*FAIL)|\|~s', $result);
+ $c = count($array) - 1; // base zero.
+ if ($c === 0) {
+ return $result;
+ }
+ $prev = '';
+ for ($i = 1; $i <=$c; $i++) {
+ $r = @explode(':', $array[$i], 2);
+ $fnName = trim($r[0]);
+ $fnNameF = $fnName[0]; // first character
+ if ($fnNameF === '"' || $fnNameF === '\'' || $fnNameF === '$' || is_numeric($fnNameF)) {
+ $fnName = '!isset(' . $array[0] . ') ? ' . $fnName . ' : ';
+ } elseif (isset($this->customDirectives[$fnName])) {
+ $fnName = '$this->customDirectives[\'' . $fnName . '\']';
+ } elseif (method_exists($this, $fnName)) {
+ $fnName = '$this->' . $fnName;
+ }
+ $hasArgument=count($r) === 2;
+ if ($i === 1) {
+ $prev = $fnName . '(' . $array[0];
+ if ($hasArgument) {
+ $prev .= ',' . $r[1];
+ }
+ $prev .= ')';
+ } else {
+ $prev = $fnName . '(' . $prev;
+ if ($hasArgument) {
+ $prev .=','. $r[1] . ')';
+ } else {
+ $prev.=')';
+ }
+ }
+ }
+
+ return $prev;
+ }
+
+ /**
+ * Compile the "regular" echo statements. {{ }}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRegularEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+ $wrapped = \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
+ return $matches[1] ? \substr($matches[0], 1) : $this->phpTagEcho . $wrapped . '; ?>' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the escaped echo statements. {!! !!}
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEscapedEchos($value): string
+ {
+ $pattern = \sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3] . $matches[3];
+
+ return $matches[1] ? $matches[0] : $this->phpTag
+ . \sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2])) . '; ?>'
+ . $whitespace;
+ //return $matches[1] ? $matches[0] : $this->phpTag
+ // . 'echo static::e(' . $this->compileEchoDefaults($matches[2]) . '); ? >' . $whitespace;
+ };
+ return \preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the "@each" tag into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileEach($expression): string
+ {
+ return $this->phpTagEcho . "\$this->renderEach$expression; ?>";
+ }
+
+ protected function compileSet($expression): string
+ {
+ //$segments = \explode('=', \preg_replace("/[()\\\']/", '', $expression));
+ $segments = \explode('=', $this->stripParentheses($expression));
+ $value = (\count($segments) >= 2) ? '=@' . implode('=', array_slice($segments, 1)) : '++';
+ return $this->phpTag . \trim($segments[0]) . $value . ';?>';
+ }
+
+ /**
+ * Compile the yield statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileYield($expression): string
+ {
+ return $this->phpTagEcho . "\$this->yieldContent$expression; ?>";
+ }
+
+ /**
+ * Compile the show statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileShow(): string
+ {
+ return $this->phpTagEcho . '$this->yieldSection(); ?>';
+ }
+
+ /**
+ * Compile the section statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileSection($expression): string
+ {
+ return $this->phpTag . "\$this->startSection$expression; ?>";
+ }
+
+ /**
+ * Compile the append statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileAppend(): string
+ {
+ return $this->phpTag . '$this->appendSection(); ?>';
+ }
+
+ /**
+ * Compile the auth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'if(isset($this->currentUser)): ?>';
+ }
+
+ return $this->phpTag . "if(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the elseauth statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseAuth($expression = ''): string
+ {
+ $role = $this->stripParentheses($expression);
+ if ($role == '') {
+ return $this->phpTag . 'else: ?>';
+ }
+
+ return $this->phpTag . "elseif(isset(\$this->currentUser) && \$this->currentRole==$role): ?>";
+ }
+
+ /**
+ * Compile the end-auth statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndAuth(): string
+ {
+ return $this->phpTag . 'endif; ?>';
+ }
+
+ protected function compileCan($expression): string
+ {
+ $v = $this->stripParentheses($expression);
+ return $this->phpTag . 'if (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ /**
+ * Compile the else statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseCan($expression = ''): string
+ {
+ $v = $this->stripParentheses($expression);
+ if ($v) {
+ return $this->phpTag . 'elseif (call_user_func($this->authCallBack,' . $v . ')): ?>';
+ }
+
+ return $this->phpTag . 'else: ?>';
+ }
+ //
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCache
+ * @version 3.42 2020-04-25
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo
+ * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
+ * // cache expired, so we should do some stuff (such as read from the database)
+ * }
+ *
+ *
+ * @package BladeOneCacheRedis
+ * @version 0.1 2017-12-15 NOT YET IMPLEMENTED, ITS A WIP!!!!!!!!
+ * @link https://github.com/EFTEC/BladeOne
+ * @author Jorge Patricio Castro Castillo
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Der Controller inkludiert das benötigte Model (gerichte.php in diesem Fall)
+ und ruft die benötigte Funktion db_gerichte_select_all() zum Laden der Daten auf
Kurze Übersicht, wie die Arbeit mit dem Router und der Blade View-Engine funktioniert.
+ +Der Router nimmt den Request entgegen und zerlegt ihn in die einzelnen Teile der URI. Wichtig ist hier vor + allem der Pfad und der Querystring.
+Wenn der Pfad in der Routenkonfiguration (\$config Array aus der Datei
+ routes/web.php) gefunden wird, lädt der Router die angegebene Klasse.
Im vorliegenden Beispiel sehen Sie diese Seite ...
+DemoController.php gefunden werden konnte
+ Sie sehen: da muss einiges stimmen und vieles davon ist Konvention.
+Die Actions in den Controller-Klassen sollen per Konvention immer ein RequestData Objekt
+ entgegennehmen. Beispiel: howto(RequestData \$rd)
Dieses RequestData Objekt wird durch den Router befüllt, wenn Daten in der URL extrahiert werden konnten.
+Daten finden sich URLs...
+ +
+ im Querystring
Beispiel: rufen Sie diese mit
+ {{strtolower(explode('/',$_SERVER["SERVER_PROTOCOL"])[0])}}://{{$_SERVER["HTTP_HOST"]}}/demo?bgcolor=fefbd8&name=Remmy
+ auf, werden bgcolor und name mitsamt Werten als Query Array
+ $rd->query) übergeben
+
Probieren Sie es aus ;)
+ @if(count($rd->args)) +Argumente dieses Aufrufs:
+ + @forelse($rd->args as $a) +Keine weiteren Argumente im Request
+ @endforelse + @endif + @if(count($rd->query)) +Daten aus der Query dieses Aufrufs:
+
+ @forelse($rd->query as $k => $v)
+ $rd->query['{{$k}}']={{$v}}
+ @empty
+ Keine Querydaten
+ @endforelse
+
+ @endif
+ Blade muss installiert sein. + Die Installation ist bereits geschehen und die Bibliothek liegt unter /vendor. +
+Bei der Verwendung der View-Engine gelten einige Konventionen:
+ Die Dateien müssen <viewname>.blade.php heißen und im Ordner views liegen.
+
Sie können der View dann Daten mitgeben, indem Sie alle Daten in ein Array schreiben und dieses dann + übergeben.
+Beispiel:
+
+ view("viewtest",
+ array(
+ "texts"=>$textArray,
+ "persona"=>$persona,
+ "rd"=>$rd
+ )); // öffnet ../views/viewtest.blade.php
+
+ combined request data
+
+ {{print_r($rd->getData(),1)}}
+
+@else
+ this request contained zero parameters
+@endif + +@if(count($rd->getGetData())) +GET request data
+ {{print_r($rd->getGetData(),1)}}
+
+@endif
+
+@if(count($rd->getPostData()))
+ POST request data
+ {{print_r($rd->getPostData(),1)}}
+
+@endif
\ No newline at end of file
diff --git a/M6/emensa/views/examples/m4_7a_queryparameter.blade.php b/M6/emensa/views/examples/m4_7a_queryparameter.blade.php
new file mode 100644
index 0000000..c094999
--- /dev/null
+++ b/M6/emensa/views/examples/m4_7a_queryparameter.blade.php
@@ -0,0 +1,13 @@
+
+
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+
+ Fehlermeldung
+ {{$data['beschreibung']}}
+
+@else
+
+ Page 1
+@endsection + +@section("footer") +Footer of Page 1
+@endsection \ No newline at end of file diff --git a/M6/emensa/views/examples/pages/m4_7d_page_2.blade.php b/M6/emensa/views/examples/pages/m4_7d_page_2.blade.php new file mode 100644 index 0000000..920a59a --- /dev/null +++ b/M6/emensa/views/examples/pages/m4_7d_page_2.blade.php @@ -0,0 +1,13 @@ +@extends(".layouts.m4_7d_layout",['title' => "Page 2"]) + +@section("header") + +@endsection + +@section("body") +Page 2
+@endsection + +@section("footer") +Footer of Page 2
+@endsection \ No newline at end of file diff --git a/M6/emensa/views/home.blade.php b/M6/emensa/views/home.blade.php new file mode 100644 index 0000000..474d713 --- /dev/null +++ b/M6/emensa/views/home.blade.php @@ -0,0 +1,34 @@ +@extends("layouts.layout") + +@section("content") +
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet + clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, + consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, + sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no + sea takimata sanctus est Lorem ipsum dolor sit amet.
+Fehlermeldung
+ {{$data['beschreibung']}}
+
+ @else
+ Sie haben eine Action aufgerufen, die zu dieser View führt.
+Vervollständigen Sie die Action, sodass die Aufgabe erfüllt wird.
+@endsection \ No newline at end of file diff --git a/M6/emensamobile/.editorconfig b/M6/emensamobile/.editorconfig new file mode 100644 index 0000000..8f0de65 --- /dev/null +++ b/M6/emensamobile/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/M6/emensamobile/.env.example b/M6/emensamobile/.env.example new file mode 100644 index 0000000..ea0665b --- /dev/null +++ b/M6/emensamobile/.env.example @@ -0,0 +1,59 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://localhost + +LOG_CHANNEL=stack +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=laravel +DB_USERNAME=root +DB_PASSWORD= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DISK=local +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +MEMCACHED_HOST=127.0.0.1 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailpit +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="hello@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_HOST= +PUSHER_PORT=443 +PUSHER_SCHEME=https +PUSHER_APP_CLUSTER=mt1 + +VITE_APP_NAME="${APP_NAME}" +VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +VITE_PUSHER_HOST="${PUSHER_HOST}" +VITE_PUSHER_PORT="${PUSHER_PORT}" +VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" +VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" diff --git a/M6/emensamobile/.gitattributes b/M6/emensamobile/.gitattributes new file mode 100644 index 0000000..fcb21d3 --- /dev/null +++ b/M6/emensamobile/.gitattributes @@ -0,0 +1,11 @@ +* text=auto eol=lf + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore +.styleci.yml export-ignore diff --git a/M6/emensamobile/.gitignore b/M6/emensamobile/.gitignore new file mode 100644 index 0000000..7fe978f --- /dev/null +++ b/M6/emensamobile/.gitignore @@ -0,0 +1,19 @@ +/.phpunit.cache +/node_modules +/public/build +/public/hot +/public/storage +/storage/*.key +/vendor +.env +.env.backup +.env.production +.phpunit.result.cache +Homestead.json +Homestead.yaml +auth.json +npm-debug.log +yarn-error.log +/.fleet +/.idea +/.vscode diff --git a/M6/emensamobile/README.md b/M6/emensamobile/README.md new file mode 100644 index 0000000..1824fc1 --- /dev/null +++ b/M6/emensamobile/README.md @@ -0,0 +1,66 @@ + + + + +## About Laravel + +Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as: + +- [Simple, fast routing engine](https://laravel.com/docs/routing). +- [Powerful dependency injection container](https://laravel.com/docs/container). +- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage. +- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent). +- Database agnostic [schema migrations](https://laravel.com/docs/migrations). +- [Robust background job processing](https://laravel.com/docs/queues). +- [Real-time event broadcasting](https://laravel.com/docs/broadcasting). + +Laravel is accessible, powerful, and provides tools required for large, robust applications. + +## Learning Laravel + +Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. + +You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch. + +If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library. + +## Laravel Sponsors + +We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com). + +### Premium Partners + +- **[Vehikl](https://vehikl.com/)** +- **[Tighten Co.](https://tighten.co)** +- **[WebReinvent](https://webreinvent.com/)** +- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)** +- **[64 Robots](https://64robots.com)** +- **[Curotec](https://www.curotec.com/services/technologies/laravel/)** +- **[Cyber-Duck](https://cyber-duck.co.uk)** +- **[DevSquad](https://devsquad.com/hire-laravel-developers)** +- **[Jump24](https://jump24.co.uk)** +- **[Redberry](https://redberry.international/laravel/)** +- **[Active Logic](https://activelogic.com)** +- **[byte5](https://byte5.de)** +- **[OP.GG](https://op.gg)** + +## Contributing + +Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). + +## Code of Conduct + +In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct). + +## Security Vulnerabilities + +If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed. + +## License + +The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/M6/emensamobile/app/Console/Kernel.php b/M6/emensamobile/app/Console/Kernel.php new file mode 100644 index 0000000..e6b9960 --- /dev/null +++ b/M6/emensamobile/app/Console/Kernel.php @@ -0,0 +1,27 @@ +command('inspire')->hourly(); + } + + /** + * Register the commands for the application. + */ + protected function commands(): void + { + $this->load(__DIR__.'/Commands'); + + require base_path('routes/console.php'); + } +} diff --git a/M6/emensamobile/app/Exceptions/Handler.php b/M6/emensamobile/app/Exceptions/Handler.php new file mode 100644 index 0000000..56af264 --- /dev/null +++ b/M6/emensamobile/app/Exceptions/Handler.php @@ -0,0 +1,30 @@ + + */ + protected $dontFlash = [ + 'current_password', + 'password', + 'password_confirmation', + ]; + + /** + * Register the exception handling callbacks for the application. + */ + public function register(): void + { + $this->reportable(function (Throwable $e) { + // + }); + } +} diff --git a/M6/emensamobile/app/Http/Controllers/AnmeldungController.php b/M6/emensamobile/app/Http/Controllers/AnmeldungController.php new file mode 100644 index 0000000..4b71017 --- /dev/null +++ b/M6/emensamobile/app/Http/Controllers/AnmeldungController.php @@ -0,0 +1,86 @@ +isMethod("post")){ + $data = $rd;} + + $email = $data["email"] ?? NULL; + $passwort = $data["passwort"] ?? NULL; + + $benutzer = new Benutzer(); + $anmeldung = $benutzer->anmelden($email, sha1($passwort)); + + if($anmeldung){ + Log::info('Anmeldung erfolgreich!'); + } + else{ + Log::info('Anmeldung fehlgeschlagen!'); + } + + return view( + 'm5_a1.anmeldung_verifizieren', + [ + 'email' => $email, + 'passwort' => $passwort, + 'anmeldung' => $anmeldung + ] + ); + } + + public function check(Request $rd){ + + $data = $rd; + + $email = $data->email ?? NULL; + $passwort = $data->passwort ?? NULL; + $anmeldung = $data->anmeldung ?? NULL; + Session::put("anmeldung", 1); + + return view( + 'm5_a1.anmeldung', + [ + 'email' => $email, + 'passwort' => $passwort, + 'anmeldung' => $anmeldung, + 'data' => $data + ] + ); + } + + + function abmelden(){ + + session()->pull("anmeldung"); + session()->pull("start"); + session()->pull("name"); + session()->pull("uid"); + session()->pull("email"); + session()->pull("bewertung"); + + session()->regenerate(); + + + Log::info('Abmeldung erfolgreich!'); + + return view('m5_a1.abmeldung', []); + } +} diff --git a/M6/emensamobile/app/Http/Controllers/Controller.php b/M6/emensamobile/app/Http/Controllers/Controller.php new file mode 100644 index 0000000..77ec359 --- /dev/null +++ b/M6/emensamobile/app/Http/Controllers/Controller.php @@ -0,0 +1,12 @@ +db_gericht_select_karte(); + + $bewertung = new bewertungen(); + $bewertungen = $bewertung->hervorgehobene_bewertungen(); + + return view('main.index', [ + 'data'=>$data, + "bewertungen" => $bewertungen, + 'url' => 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" + ]); + } + + public function bewertung(Request $rd) { + /* + Wenn Sie hier landen: + bearbeiten Sie diese Action, + so dass Sie die Aufgabe löst + */ + + if(session("start",0)== 0){ + session(["bewertung" => 1]); + return view('m5_a1.anmeldung', [ + 'url' => 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}" + ]); + } + + $b = new bewertungen(); + + if($rd->isMethod("get")) { + $data = $rd; + + if ($data["gerichtid"] != null) { + + $gericht = new Gerichte(); + $g = $gericht->db_gericht_bewertung($data["gerichtid"]); + + return view('main.bewertung', [ + "gericht" => $g, + "data" => $data, + 'url' => 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" + ]); + } + + if($data["hervorheben"]!=null){ + $b->hervorheben($data["hervorheben"]); + return redirect('/bewertung'); + } + if($data["dehervorheben"]!=null){ + $b->dehervorheben($data["dehervorheben"]); + return redirect('/bewertung'); + } + } + + + $bewertungen = $b->bewertungen(); + + $benutzer = new benutzer(); + $admin = $benutzer->isAdmin(session("benutzer_id"),0); + + return view('main.bewertung', [ + "admin" => $admin, + "bewertungen" => $bewertungen, + 'url' => 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" + ]); + } + + + public function bewertung_abschicken(Request $rd) { + if($rd->isMethod("post")){ + $data = $rd;} + + $id = $data["gericht_id"] ?? NULL; + $sterne = $data["sterne"] ?? NULL; + $bemerkung = $data["bemerkung"] ?? NULL; + $benutzer = session("benutzer_id",0); + + + $b = new bewertungen(); + $check = $b->bewerten($benutzer,$id,$sterne, $bemerkung); + + $bewertungen = $b->bewertungen(); + return redirect('/bewertung'); + } + + public function meinebewertungen(Request $rd){ + if(session("start",0)== 0){ + return redirect('/bewertung'); + } + + $benutzer_id = session("benutzer_id",0); + if($benutzer_id == 0){ + return view('main.index', [ + 'url' => 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" + ]); + } + + $b = new bewertungen(); + + if($rd->isMethod("get")) { + $data = $rd; + + if ($data["loschen"] != null) { + $check = $b->loschen($data["loschen"]); + return redirect('/meinebewertungen'); + } + + } + + + + $meine = $b->meine_bewertungen($benutzer_id); + + return view('main.meine_bewertungen', [ + "meine_bewertungen" => $meine, + 'url' => 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}./bewertungen" + ]); + } + +} diff --git a/M6/emensamobile/app/Http/Kernel.php b/M6/emensamobile/app/Http/Kernel.php new file mode 100644 index 0000000..494c050 --- /dev/null +++ b/M6/emensamobile/app/Http/Kernel.php @@ -0,0 +1,68 @@ + + */ + protected $middleware = [ + // \App\Http\Middleware\TrustHosts::class, + \App\Http\Middleware\TrustProxies::class, + \Illuminate\Http\Middleware\HandleCors::class, + \App\Http\Middleware\PreventRequestsDuringMaintenance::class, + \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, + \App\Http\Middleware\TrimStrings::class, + \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, + ]; + + /** + * The application's route middleware groups. + * + * @var array