From 9787587c3817609b95f43da15120e55d693a10ee Mon Sep 17 00:00:00 2001 From: vincent-peugnet Date: Thu, 28 Mar 2019 09:57:28 +0100 Subject: new render engine for elements --- app/class/element.php | 197 ++++++++++++++++++++++++++++++++++++++++++++++ app/class/model.php | 5 +- app/class/modelart.php | 2 +- app/class/modelrender.php | 140 +++++++++++++++++++------------- index.php | 2 +- 5 files changed, 290 insertions(+), 56 deletions(-) create mode 100644 app/class/element.php diff --git a/app/class/element.php b/app/class/element.php new file mode 100644 index 0000000..fd8ac71 --- /dev/null +++ b/app/class/element.php @@ -0,0 +1,197 @@ +hydrate($datas); + $this->analyse($artid); + } + + public function hydrate($datas) + { + foreach ($datas as $key => $value) { + $method = 'set' . $key; + + if (method_exists($this, $method)) { + $this->$method($value); + } + } + } + + private function analyse(string $artid) + { + if(!empty($this->options)) { + + // Replace "!" by the real page name + $this->options = str_replace('!', $artid, $this->options); + + preg_match('~(:([a-z0-9-_+!]+))?(\/([a-z0-9-,_+=]+))?~', $this->options, $matches); + if(isset($matches[2]) && !empty($matches[2])) { + $this->sources = explode('+', $matches[2]); + } else { + $this->sources[] = $artid; + } + if(isset($matches[4])) { + $this->params = explode(',', $matches[4]); + } + + $this->readoptions(); + + } else { + $this->sources[] = $artid; + } + } + + private function readoptions() + { + if(!empty($this->params)) { + foreach ($this->params as $param ) { + preg_match('~([a-z0-9-_]+)(=(-?[0-9]+))?~', $param, $optionmatch); + if(isset($optionmatch[1])) { + $key = $optionmatch[1]; + } + if(isset($optionmatch[3])) { + $value = $optionmatch[3]; + } else { + $read = '

Rendering error :

Paramaters must have a value like : /' . $key . '=__value__ for parameter : ' . $key . '

'; + throw new Exception($read); + } + $method = 'set' . $key; + if (in_array($key, self::OPTIONS)) { + if (!$this->$method($value)) { + $read = '

Rendering error :

Invalid value input : ' . $value . ' for parameter : ' . $key . '

'; + throw new Exception($read); + + } + } else { + $read = '

Rendering error :

Parameter name : ' . $optionmatch[1] . ' does not exist

'; + throw new Exception($read); + } + } + } + } + + + + + + // __________________________________________________ G E T ____________________________________________________________ + + + public function fullmatch() + { + return $this->fullmatch; + } + + public function type() + { + return $this->type; + } + + public function options() + { + return $this->options; + } + + public function params() + { + return $this->params; + } + + public function sources() + { + return $this->sources; + } + + public function autolink() + { + return $this->autolink; + } + + public function markdown() + { + return $this->markdown; + } + + public function content() + { + return $this->content; + } + + + + + + + // __________________________________________________ S E T ____________________________________________________________ + + + public function setfullmatch(string $fullmatch) + { + $this->fullmatch = $fullmatch; + } + + public function settype(string $type) + { + $type = strtolower($type); + if(in_array($type, Model::TEXT_ELEMENTS)) { + $this->type = $type; + } + } + + public function setoptions(string $options) + { + if(!empty($options)) { + $this->options = $options; + } + } + + public function setautolink(int $level) + { + if($level >= 0 && $level <= 16) { + $this->autolink = $level; + return true; + } else { + return false; + } + } + + public function setmarkdown(int $level) + { + if($level >= 0 && $level <= 1) { + $this->markdown = $level; + return true; + } else { + return false; + } + } + + public function setcontent(string $content) + { + $this->content = $content; + } + +} + + + + +?> \ No newline at end of file diff --git a/app/class/model.php b/app/class/model.php index c8f251f..9bc5c67 100644 --- a/app/class/model.php +++ b/app/class/model.php @@ -27,8 +27,11 @@ abstract class Model const PASSWORD_MAX_LENGTH = 32; /** RENDER OPTIONS */ + // add class in html element indicating from witch page the content come. const RENDER_CLASS_ORIGIN = false; - const RENDER_EMPTY_ELEMENT = false; + // render empty CONTENT element as empty html element, if set to false, render html comment + const RENDER_EMPTY_ELEMENT = false; + /** CONFIG OPTIONS */ const HOMEPAGE = ['default', 'search', 'redirect']; diff --git a/app/class/modelart.php b/app/class/modelart.php index 45ff3c2..e9d4b86 100644 --- a/app/class/modelart.php +++ b/app/class/modelart.php @@ -70,7 +70,7 @@ class Modelart extends Modeldb if ($art !== false) { return $art->$element(); } else { - return ''; + return false; } } } diff --git a/app/class/modelrender.php b/app/class/modelrender.php index 367dac8..608960a 100644 --- a/app/class/modelrender.php +++ b/app/class/modelrender.php @@ -11,8 +11,8 @@ class Modelrender extends Modelart protected $externallinkblank = ''; const SUMMARY = '%SUMMARY%'; - const REMPLACE_SELF_ELEMENT = false; + const RENDER_VERBOSE = 1; public function __construct($router) { @@ -59,14 +59,7 @@ class Modelrender extends Modelart if (!empty($this->art->templatebody())) { $templateid = $this->art->templatebody(); $templateart = $this->get($templateid); - if (self::REMPLACE_SELF_ELEMENT) { - $templatebody = preg_replace_callback('~\%(MAIN|ASIDE|NAV|HEADER|FOOTER)!\%~', function ($match) use ($templateid) { - return '%' . $match[1] . '.' . $templateid . '%'; - }, $templateart->body()); - } else { - $templatebody = $templateart->body(); - } - $body = $templatebody; + $body = $templateart->body(); } else { $body = $this->art->body(); } @@ -76,54 +69,87 @@ class Modelrender extends Modelart return $body; } - public function getbody(string $body) + + /** + * Analyse BODY, call the corresponding CONTENTs and render everything + * + * @param string $body as the string BODY of the page + * + * @return string as the full rendered BODY of the page + */ + public function getbody(string $body) : string { - $rend = $this; - $body = preg_replace_callback('~\%(MAIN|ASIDE|NAV|HEADER|FOOTER)((:[a-z0-9-_]+|!)(\+([a-z0-9-_]+|!))*)?\%~', function ($match) use ($rend) { - $element = strtolower($match[1]); - $getelement = ''; - if (isset($match[2]) && !empty($match[2])) { - $templatelist = str_replace('!', $this->art->id(), explode('+', ltrim($match[2], ':'))); - foreach ($templatelist as $template) { - if ($template === $rend->art->id()) { - $templateelement = $rend->art->$element(); - } else { - $templateelement = $rend->getartelement($template, $element); + // Elements that can be detected + $types = ['HEADER', 'NAV', 'MAIN', 'ASIDE', 'FOOTER']; + + // First level regex + $regex = '~\%(' . implode("|", $types) . ')(\S*)\%~'; + + // Match the first level regex + preg_match_all($regex, $body, $out); + + // Create a list of all the elements that passed through the first level regex + foreach ($out[0] as $key => $match) { + $matches[$key] = ['fullmatch' => $match, 'type' => $out[1][$key], 'options' => $out[2][$key]]; + } + + // First, analyse the synthax and call the corresponding methods + foreach ($matches as $key => $match) { + $element = new Element($match, $this->art->id()); + $element->setcontent($this->getelementcontent($element)); + $element->setcontent($this->elementparser($element)); + $body = str_replace($element->fullmatch(), $element->content(), $body); + + } + + + + return $body; + + } + + public function getelementcontent(Element $element) + { + $content = ''; + $subseparator = PHP_EOL . PHP_EOL; + foreach($element->sources() as $source) + { + if($source !== $this->art->id()) { + $subcontent = $this->getartelement($source, $element->type()); + if($subcontent !== false) { + if(empty($subcontent && self::RENDER_VERBOSE > 0)) { + $subcontent = PHP_EOL . '' . PHP_EOL; } - $getelement .= $templateelement; - } - } else { - $templatelist = [$rend->art->id()]; - $getelement = $rend->art->$element(); - } - $getelement = $rend->elementparser($getelement); - $eol = "\n"; - if ($getelement == $eol && !self::RENDER_EMPTY_ELEMENT) { - $getelementblock = ''; - } else { - if (self::RENDER_CLASS_ORIGIN) { - $class = implode(' ', $templatelist); - $getelementblock = PHP_EOL . '<' . $element . ' class="' . $class . '">' . $getelement . ''; } else { - $getelementblock = PHP_EOL . '<' . $element . '>' . $getelement . ''; + $read = '

Rendering error :

The page ' . $source . ', called in '. $element->fullmatch() . ', does not exist yet.

'; + throw new Exception($read); } - } - return $getelementblock; - }, $body); - return $body; + } else { + $type = $element->type(); + $subcontent = $this->art->$type(); + } + $content .= $subseparator . $subcontent; + } + return $content . $subseparator; } - public function elementparser($element) + public function elementparser(Element $element) { - $element = $this->article($element); - $element = $this->automedialist($element); - $element = $this->autotaglistupdate($element); - $element = $this->date($element); - $element = $this->autolink($element); - $element = $this->markdown($element); - - return $element; + $content = $this->article($element->content()); + $content = $this->automedialist($content); + $content = $this->autotaglistupdate($content); + $content = $this->date($content); + if($element->autolink()) { + $content = $this->everylink($content, $element->autolink()); + } else { + $content = $this->taglink($content); + } + if($element->markdown()) { + $content = $this->markdown($content); + } + + return $content; } @@ -498,18 +524,26 @@ class Modelrender extends Modelart return $text; } - public function autolink($text) + public function taglink($text) { $rend = $this; $text = preg_replace_callback('/\%LINK\%(.*)\%LINK\%/msU', function ($matches) use ($rend) { - return $rend->everylink($matches[1]); + return $rend->everylink($matches[1], 1); }, $text); return $text; } - public function everylink($text) + /** + * Autolink Function : transform every word of more than $limit characters in internal link + * + * @var string $text The input text to be converted + * + * @return string Conversion output + */ + public function everylink(string $text, int $limit) : string { - $text = preg_replace_callback("~([\w-_éêèùïüîçà]{2,})~", function ($matches) { + $regex = '~([\w-_éêèùïüîçà]{' . $limit . ',})~'; + $text = preg_replace_callback($regex , function ($matches) { return '' . $matches[1] . ''; }, $text); return $text; diff --git a/index.php b/index.php index 65b4271..a977e73 100644 --- a/index.php +++ b/index.php @@ -21,7 +21,7 @@ try { $matchoper->match(); } catch (Exception $e) { - echo '⚠ ⚠ ⚠ Sorry, there is a little problem : ', ''.$e->getMessage().'', "\n"; + echo '

⚠ Woops ! There is a little problem :

', $e->getMessage(), "\n"; } -- cgit v1.2.3