From e802d5204b96d645ec3d40b81b4a8bdc6e0ee675 Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Mon, 4 Nov 2019 23:31:31 +0100 Subject: refactor: switch to psr-4 autoloading --- app/class/Modelrender.php | 693 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 693 insertions(+) create mode 100644 app/class/Modelrender.php (limited to 'app/class/Modelrender.php') diff --git a/app/class/Modelrender.php b/app/class/Modelrender.php new file mode 100644 index 0000000..9f668d4 --- /dev/null +++ b/app/class/Modelrender.php @@ -0,0 +1,693 @@ +router = $router; + $this->pagelist = $this->getlister(); + + if(Config::internallinkblank()) { + $this->internallinkblank = ' target="_blank" '; + } + + if(Config::externallinkblank()) { + $this->externallinkblank = ' target="_blank" '; + } + } + + public function upage($id) + { + return $this->router->generate('pageread/', ['page' => $id]); + } + + + /** + * Main function + * + * @param Page $page page to render + */ + public function render(Page $page) + { + $this->page = $page; + + $this->write($this->gethmtl()); + } + + /** + * Combine body and head to create html file + * + * @return string html string + */ + public function gethmtl() + { + + $head = $this->gethead(); + $body = $this->getbody($this->readbody()); + $parsebody = $this->parser($body); + + $html = '' . PHP_EOL . '' . PHP_EOL . '' . PHP_EOL . $head . PHP_EOL . '' . PHP_EOL . $parsebody . PHP_EOL . ''; + + return $html; + } + + + public function readbody() + { + if (!empty($this->page->templatebody())) { + $templateid = $this->page->templatebody(); + $templatepage = $this->get($templateid); + if($templatepage !== false) { + $body = $templatepage->body(); + } else { + $body = $this->page->body(); + $this->page->settemplatebody(''); + } + } else { + $body = $this->page->body(); + } + $body = $this->article($body); + $body = $this->automedialist($body); + $body = $this->autotaglistupdate($body); + return $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 + { + // 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 + if(isset($matches)) { + foreach ($matches as $key => $match) { + $element = new Element($match, $this->page->id()); + $element->setcontent($this->getelementcontent($element)); + $element->setcontent($this->elementparser($element)); + $element->addtags(); + $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->page->id()) { + $subcontent = $this->getpageelement($source, $element->type()); + if($subcontent !== false) { + if(empty($subcontent && self::RENDER_VERBOSE > 0)) { + $subcontent = PHP_EOL . '' . PHP_EOL; + } + } else { + $read = '

Rendering error :

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

'; + //throw new Exception($read); + } + + } else { + $type = $element->type(); + $subcontent = $this->page->$type(); + } + $content .= $subseparator . $subcontent; + } + return $content . $subseparator; + } + + public function elementparser(Element $element) + { + $content = $this->article($element->content()); + $content = $this->automedialist($content); + $content = $this->pagelist($content); + $content = $this->autotaglistupdate($content); + $content = $this->date($content); + $content = $this->thumbnail($content); + if($element->autolink()) { + $content = str_replace('%LINK%', '' ,$content); + $content = $this->everylink($content, $element->autolink()); + } else { + $content = $this->taglink($content); + } + if($element->markdown()) { + $content = $this->markdown($content); + } + + return $content; + } + + + /** + * Write css javascript and html as files in the assets folder + */ + public function write(string $html) + { + file_put_contents(Model::HTML_RENDER_DIR . $this->page->id() . '.html', $html); + file_put_contents(Model::RENDER_DIR . $this->page->id() . '.css', $this->page->css()); + //file_put_contents(Model::RENDER_DIR . $this->page->id() . '.quick.css', $this->page->quickcss()); + file_put_contents(Model::RENDER_DIR . $this->page->id() . '.js', $this->page->javascript()); + } + + + + public function writetemplates() + { + if (array_key_exists('css', $this->page->template('array'))) { + $tempaltecsspage = $this->get($this->page->template('array')['css']); + file_put_contents(Model::RENDER_DIR . $tempaltecsspage->id() . '.css', $tempaltecsspage->css()); + } + if (array_key_exists('quickcss', $this->page->template('array'))) { + $tempaltequickcsspage = $this->get($this->page->template('array')['quickcss']); + file_put_contents(Model::RENDER_DIR . $tempaltequickcsspage->id() . '.quick.css', $tempaltequickcsspage->quickcss()); + } + if (array_key_exists('javascript', $this->page->template('array'))) { + $templatejspage = $this->get($this->page->template('array')['javascript']); + file_put_contents(Model::RENDER_DIR . $templatejspage->id() . '.js', $templatejspage->javascript()); + } + } + + + + + public function gethead() + { + + $head = ''; + + $head .= '' . PHP_EOL; + $head .= '' . $this->page->title() . '' . PHP_EOL; + if (!empty($this->page->favicon())) { + $head .= ''; + } elseif (!empty(Config::defaultfavicon())) { + $head .= ''; + } + $head .= '' . PHP_EOL; + $head .= '' . PHP_EOL; + + + $head .= '' . PHP_EOL; + $head .= '' . PHP_EOL; + + if($this->page->thumbnailexist()) { + $head .= '' . PHP_EOL; + } + + $head .= '' . PHP_EOL; + + + foreach ($this->page->externalcss() as $externalcss) { + $head .= '' . PHP_EOL; + } + + if (!empty($this->page->templatecss() && in_array('externalcss', $this->page->templateoptions()))) { + $templatecss = $this->get($this->page->templatecss()); + if($templatecss !== false) { + + foreach ($templatecss->externalcss() as $externalcss) { + $head .= '' . PHP_EOL; + } + } + } + + $head .= PHP_EOL . $this->page->customhead() . PHP_EOL; + + + $head .= '' . PHP_EOL; + $head .= '' . PHP_EOL; + + if (!empty($this->page->templatecss())) { + $tempaltecsspage = $this->page->templatecss(); + $head .= '' . PHP_EOL; + } + $head .= '' . PHP_EOL; + + if (!empty($this->page->templatejavascript())) { + $templatejspage = $this->page->templatejavascript(); + $head .= '' . PHP_EOL; + } + if (!empty($this->page->javascript())) { + $head .= '' . PHP_EOL; + } + + if (!empty(Config::analytics())) { + + $head .= PHP_EOL . ' + + + + ' . PHP_EOL; + } + + + return $head; + } + + public function desctitle($text, $desc, $title) + { + $text = str_replace('%TITLE%', $title, $text); + $text = str_replace('%DESCRIPTION%', $desc, $text); + return $text; + } + + + public function parser(string $text) + { + $text = $this->media($text); + + $text = $this->headerid($text); + + $text = str_replace(self::SUMMARY, $this->sumparser($text), $text); + + $text = $this->wurl($text); + $text = $this->wikiurl($text); + + $text = $this->desctitle($text, $this->page->description(), $this->page->title()); + + + $text = str_replace('href="http', ' class="external" target="_blank" href="http', $text); + + $text = $this->autourl($text); + + $text = $this->authenticate($text); + + return $text; + } + + public function media(string $text) : string + { + $text = preg_replace('%(src|href)="([\w-_]+(\/([\w-_])+)*\.[a-z0-9]{1,5})"%', '$1="' . Model::mediapath() . '$2" target="_blank" class="media"', $text); + if (!is_string($text)) { + //throw new Exception('Rendering error -> media module'); + } + return $text; + } + + + public function autourl($text) + { + $text = preg_replace('#( |\R|>)(https?:\/\/((\S+)\.([^< ]+)))#', '$1externallinkblank .'>$3', $text); + return $text; + } + + public function wurl(string $text) + { + $linkfrom = []; + $rend = $this; + $text = preg_replace_callback( + '%href="([\w-]+)\/?(#?[a-z-_]*)"%', + function ($matches) use ($rend, &$linkfrom) { + $matchpage = $rend->get($matches[1]); + if (!$matchpage) { + $link = 'href="' . $rend->upage($matches[1]) . '"" title="' . Config::existnot() . '" class="internal existnot"' . $this->internallinkblank; + } else { + $linkfrom[] = $matchpage->id(); + $link = 'href="' . $rend->upage($matches[1]) . $matches[2] . '" title="' . $matchpage->description() . '" class="internal exist '. $matchpage->secure('string') .'"' . $this->internallinkblank; + } + return $link; + }, + $text + ); + $this->linkfrom = array_unique(array_merge($this->linkfrom, $linkfrom)); + return $text; + } + + public function wikiurl(string $text) + { + $linkfrom = []; + $rend = $this; + $text = preg_replace_callback( + '%\[([\w-]+)\/?#?([a-z-_]*)\]%', + function ($matches) use ($rend, &$linkfrom) { + $matchpage = $rend->get($matches[1]); + if (!$matchpage) { + return 'internallinkblank .' >' . $matches[1] . ''; + } else { + $linkfrom[] = $matchpage->id(); + return 'internallinkblank .' >' . $matchpage->title() . ''; + } + }, + $text + ); + $this->linkfrom = array_unique(array_merge($this->linkfrom, $linkfrom)); + return $text; + } + + public function headerid($text) + { + $sum = []; + $text = preg_replace_callback( + '/(.+)<\/h[1-6]>/mU', + function ($matches) use (&$sum) { + $cleanid = idclean($matches[4]); + $sum[$cleanid][$matches[1]] = $matches[4]; + return '' . $matches[4] . ''; + }, + $text + ); + $this->sum = $sum; + return $text; + } + + public function markdown($text) + { + //use Michelf\MarkdownExtra; + $fortin = new Michelf\MarkdownExtra; + // id in headers + // $fortin->header_id_func = function ($header) { + // return preg_replace('/[^\w]/', '', strtolower($header)); + // }; + $fortin->hard_wrap = true; + $text = $fortin->transform($text); + return $text; + } + + + + public function article($text) + { + $pattern = '/(\R\R|^\R|^)[=]{3,}([\w-]*)\R\R(.*)(?=\R\R[=]{3,}[\w-]*\R)/sUm'; + $text = preg_replace_callback($pattern, function ($matches) { + if (!empty($matches[2])) { + $id = ' id="' . $matches[2] . '" '; + } else { + $id = ' '; + } + return '
' . PHP_EOL . PHP_EOL . $matches[3] . PHP_EOL . PHP_EOL . '
' . PHP_EOL . PHP_EOL; + }, $text); + $text = preg_replace('/\R\R[=]{3,}([\w-]*)\R/', '', $text); + return $text; + } + + /** + * Check for media list call in the text and insert media list + * @param string $text Text to scan and replace + * + * @return string Output text + */ + public function automedialist(string $text) + { + preg_match_all('~\%MEDIA\?([a-zA-Z0-9\&=\-\/\%]*)\%~', $text, $out); + + foreach ($out[0] as $key => $match) { + $matches[$key] = ['fullmatch' => $match, 'options' => $out[1][$key]]; + } + + if(isset($matches)) { + foreach ($matches as $match) { + $medialist = new Medialist($match); + $text = str_replace($medialist->fullmatch(), $medialist->content(), $text); + } + } + return $text; + } + + + function sumparser($text) + { + preg_match_all('#(.+)#iU', $text, $out); + + + $sum = $this->sum; + + + + $sumstring = ''; + $last = 0; + foreach ($sum as $title => $list) { + foreach ($list as $h => $link) { + if ($h > $last) { + for ($i = 1; $i <= ($h - $last); $i++) { + $sumstring .= '
    '; + } + $sumstring .= '
  • ' . $link . '
  • '; + } elseif ($h < $last) { + for ($i = 1; $i <= ($last - $h); $i++) { + $sumstring .= '
'; + } + $sumstring .= '
  • ' . $link . '
  • '; + } elseif ($h = $last) { + $sumstring .= '
  • ' . $link . '
  • '; + } + $last = $h; + } + } + for ($i = 1; $i <= ($last); $i++) { + $sumstring .= ''; + } + return $sumstring; + } + + + + public function autotaglist($text) + { + $pattern = "/\%TAG:([a-z0-9_-]+)\%/"; + preg_match_all($pattern, $text, $out); + return $out[1]; + + } + + public function autotaglistupdate($text) + { + $taglist = $this->autotaglist($text); + foreach ($taglist as $tag) { + $li = []; + foreach ($this->pagelist as $item) { + if (in_array($tag, $item->tag('array'))) { + $li[] = $item; + } + + } + $ul = '
      ' . PHP_EOL; + $this->pagelistsort($li, 'date', -1); + foreach ($li as $item) { + if ($item->id() === $this->page->id()) { + $actual = ' actualpage'; + } else { + $actual = ''; + } + $ul .= '
    • internallinkblank .' >' . $item->title() . '
    • ' . PHP_EOL; + } + $ul .= '
    ' . PHP_EOL; + + + $text = str_replace('%TAG:' . $tag . '%', $ul, $text); + + $li = array_map(function ($item) { + return $item->id(); + }, $li); + $this->linkfrom = array_unique(array_merge($this->linkfrom, $li)); + } + return $text; + } + + + public function date(string $text) + { + $page = $this->page; + $text = preg_replace_callback('~\%DATE\%~', function ($matches) use ($page) { + return ''; + }, $text); + $text = preg_replace_callback('~\%TIME\%~', function ($matches) use ($page) { + return ''; + }, $text); + + return $text; + } + + /** + * Render thumbnail of the page + * + * @param string $text Text to analyse + * + * @return string The rendered output + */ + public function thumbnail(string $text) : string + { + $img = '' . $this->page->title() . ''; + $img = PHP_EOL . $img . PHP_EOL; + $text = str_replace('%THUMBNAIL%', $img, $text); + + return $text; + } + + public function taglink($text) + { + $rend = $this; + $text = preg_replace_callback('/\%LINK\%(.*)\%LINK\%/msU', function ($matches) use ($rend) { + return $rend->everylink($matches[1], 1); + }, $text); + return $text; + } + + /** + * Autolink Function : transform every word of more than $limit characters in internal link + * + * @param string $text The input text to be converted + * + * @return string Conversion output + */ + public function everylink(string $text, int $limit) : string + { + $regex = '~([\w-_éêèùïüîçà]{' . $limit . ',})(?![^<]*>|[^<>]*<\/)~'; + $text = preg_replace_callback($regex , function ($matches) { + return '' . $matches[1] . ''; + }, $text); + return $text; + } + + + + /** + * @param string $text content to analyse and replace + * + * @return string text ouput + */ + public function authenticate(string $text) + { + $id = $this->page->id(); + $regex = '~\%CONNECT(\?dir=([a-zA-Z0-9-_]+))?\%~'; + $text = preg_replace_callback($regex, function ($matches) use ($id) { + if(isset($matches[2])) { + $id = $matches[2]; + } + $form = '
    + + + + +
    '; + return $form; + + }, $text); + return $text; + } + + /** + * Render pages list + */ + public function pagelist(string $text) : string + { + preg_match_all('~\%LIST\?([a-zA-Z0-9\]\[\&=\-\/\%]*)\%~', $text, $out); + + foreach ($out[0] as $key => $match) { + $matches[$key] = ['fullmatch' => $match, 'options' => $out[1][$key]]; + } + + $modelhome = new Modelhome(); + + if(isset($matches)) { + foreach ($matches as $match) { + $optlist = $modelhome->Optlistinit($this->pagelist); + $optlist->parsehydrate($match['options']); + $table2 = $modelhome->table2($this->pagelist, $optlist); + + $content = '
      ' . PHP_EOL ; + foreach ($table2 as $page ) { + $content .= '
    • ' . PHP_EOL; + $content .= '' . $page->title() . '' . PHP_EOL; + if($optlist->description()) { + $content .= '' . $page->description() . '' . PHP_EOL; + } + if($optlist->date()) { + $content .= '' . $page->date('pdate') . '' . PHP_EOL; + } + if($optlist->time()) { + $content .= '' . $page->date('ptime') . '' . PHP_EOL; + } + if($optlist->author()) { + $content .= $page->authors('string') . PHP_EOL; + } + $content .= '
    • '; + } + $content .= '
    '; + + $text = str_replace($match['fullmatch'], $content, $text); + } + } + return $text; + } + + + + + + + + + public function linkfrom() + { + sort($this->linkfrom); + $linkfrom = $this->linkfrom; + $this->linkfrom = []; + return $linkfrom; + } + + public function linkto() + { + $linkto = []; + foreach ($this->pagelist as $page) { + if (in_array($this->page->id(), $page->linkfrom())) { + $linkto[] = $page->id(); + } + } + return $linkto; + } + + + + +} + + + +?> \ No newline at end of file -- cgit v1.2.3