aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorvincent-peugnet <v.peugnet@free.fr>2018-11-11 17:19:26 +0100
committervincent-peugnet <v.peugnet@free.fr>2018-11-11 17:19:26 +0100
commitd7f3313ff4514e38c9f53439cd1a1287e56e45f7 (patch)
treeabff39ab11cb317f5fcd2db558da1c59bdae9239 /app
parent2f363e8fa26ab849539e64ff7caa21bd164e8979 (diff)
downloadwcms-d7f3313ff4514e38c9f53439cd1a1287e56e45f7.tar.gz
wcms-d7f3313ff4514e38c9f53439cd1a1287e56e45f7.zip
reboot folder
Diffstat (limited to 'app')
-rw-r--r--app/class/aff.php1018
-rw-r--r--app/class/app4.php657
-rw-r--r--app/class/application.php90
-rw-r--r--app/class/art2.php618
-rw-r--r--app/class/backrouter.php74
-rw-r--r--app/class/config.php186
-rw-r--r--app/class/configtest.php22
-rw-r--r--app/class/controller.php96
-rw-r--r--app/class/controlleradmin.php28
-rw-r--r--app/class/controllerart.php159
-rw-r--r--app/class/controllerconnect.php18
-rw-r--r--app/class/controllerdb.php45
-rw-r--r--app/class/controllerhome.php66
-rw-r--r--app/class/controllermedia.php37
-rw-r--r--app/class/launcher.php20
-rw-r--r--app/class/media.php173
-rw-r--r--app/class/model.php17
-rw-r--r--app/class/modelanalyse.php73
-rw-r--r--app/class/modelart.php178
-rw-r--r--app/class/modelconfig.php39
-rw-r--r--app/class/modeldb.php54
-rw-r--r--app/class/modelhome.php70
-rw-r--r--app/class/modelmassedit.php0
-rw-r--r--app/class/modelmedia.php95
-rw-r--r--app/class/modelrender.php277
-rw-r--r--app/class/modeluser.php61
-rw-r--r--app/class/opt.php272
-rw-r--r--app/class/quickcss.php291
-rw-r--r--app/class/record.php116
-rw-r--r--app/class/route.php84
-rw-r--r--app/class/routes.php34
-rw-r--r--app/class/sleekdbw.php180
-rw-r--r--app/class/user.php58
-rw-r--r--app/class/w.article.php32
-rw-r--r--app/class/w.home.php85
-rw-r--r--app/class/w.menu.php56
-rw-r--r--app/fn/fn.php155
-rw-r--r--app/oldindex.php327
-rw-r--r--app/view/templates/arthead.php6
-rw-r--r--app/view/templates/body.php0
-rw-r--r--app/view/templates/connect.php30
-rw-r--r--app/view/templates/delete.php44
-rw-r--r--app/view/templates/edit.php35
-rw-r--r--app/view/templates/edithelp.php27
-rw-r--r--app/view/templates/editleftbar.php70
-rw-r--r--app/view/templates/editrightbar.php20
-rw-r--r--app/view/templates/edittabs.php19
-rw-r--r--app/view/templates/edittopbar.php29
-rw-r--r--app/view/templates/home.php109
-rw-r--r--app/view/templates/homeopt.php84
-rw-r--r--app/view/templates/layout.php20
-rw-r--r--app/view/templates/media.php4
-rw-r--r--app/view/templates/navart.php85
-rw-r--r--app/view/templates/navback.php54
-rw-r--r--app/view/templates/read.php67
-rw-r--r--app/view/templates/readart.php25
-rw-r--r--app/view/templates/readcreate.php5
-rw-r--r--app/view/templates/readerlayout.php15
58 files changed, 6609 insertions, 0 deletions
diff --git a/app/class/aff.php b/app/class/aff.php
new file mode 100644
index 0000000..6f9f07e
--- /dev/null
+++ b/app/class/aff.php
@@ -0,0 +1,1018 @@
+<?php
+
+class Aff
+{
+
+
+ // ____________________________________________________ C O N F I G ______________________________________________
+
+
+ public function configform()
+ {
+ ?>
+ <p>Config file does not exist yet, or maybe you deleted it ? Anyway, it is time to set it :</p>
+ <form action="" method="post">
+ <input type="hidden" name="config" value="create">
+ Database settings</br>
+ <input type="text" name="host" id="" placeholder="host"></br>
+ <input type="text" name="dbname" id="" placeholder="dbname"></br>
+ <input type="text" name="user" id="" placeholder="user"></br>
+ <input type="text" name="password" id="" placeholder="password"></br>
+ Domain name settings</br>
+ <input type="text" name="domain" id="" placeholder="domain"></br>
+ W_cms settings</br>
+ <input type="text" name="admin" id="" placeholder="W admin password" required></br>
+ <input type="hidden" name="editor" id="" value="editor">
+ <input type="hidden" name="invite" id="" value="invite">
+ <input type="hidden" name="read" id="" value="read">
+ <input type="hidden" name="cssread" id="" value="">
+ (You can change everything later, set at least your admin password, and don't forget it !)</br>
+ <input type="submit" value="create config file">
+ </form>
+ <?php
+
+ }
+
+
+
+
+
+
+
+ // ____________________________________________________ F U N ______________________________________________
+
+
+
+
+
+
+
+ public function edit(Art2 $art, App $app, $list, $fontsize, $imagelist)
+ {
+
+ if ($app->session() >= $app::EDITOR) {
+
+ ?>
+
+ <form action="?id=<?= $art->id() ?>" method="post" id="artedit">
+
+ <?php
+ echo '<style>textarea{font-size: ' . $fontsize . '}</style>';
+ $tablist = ['section' => $art->md(), 'css' => $art->css(), 'aside' => $art->aside(), 'footer' => $art->footer()];
+
+ $this->tabs($tablist, 'section');
+
+ ?>
+
+ <div id="submit">
+ <input type="submit" name="action" value="home" accesskey="w" onclick="document.getElementById('artedit').submit();" form="artedit">
+ <input type="submit" name="action" value="update" accesskey="x" onclick="document.getElementById('artedit').submit();" form="artedit">
+ <input type="submit" name="action" value="display" accesskey="c" onclick="document.getElementById('artedit').submit();" form="artedit">
+ <input type="submit" name="action" value="delete" onclick="confirmSubmit(event, 'Delete this article', 'artedit')" form="artedit">
+ <a href="?id=<?= $art->id() ?>" target="_blank">👁</a>
+
+ <span id="headid"><?= $art->id() ?></span>
+
+ <label for="fontsize">Font-size</label>
+ <input type="number" name="fontsize" value="<?= $fontsize ?>" id="fontsize">
+ </div>
+ <div class="sidebar">
+ <details id="editinfo" open>
+ <summary>Infos</summary>
+ <fieldset>
+ <label for="title">title :</label>
+ <input type="text" name="title" id="title" value="<?= $art->title(); ?>">
+ <label for="description">Description :</label>
+ <input type="text" name="description" id="description" value="<?= $art->description(); ?>">
+ <label for="tag">Tag(s) :</label>
+ <input type="text" name="tag" id="tag" value="<?= $art->tag('string'); ?>">
+ <label for="secure">Niveau de sécurité :</label>
+ <select name="secure" id="secure">
+ <option value="0" <?= $art->secure() == 0 ? 'selected' : '' ?>>0</option>
+ <option value="1" <?= $art->secure() == 1 ? 'selected' : '' ?>>1</option>
+ <option value="2" <?= $art->secure() == 2 ? 'selected' : '' ?>>2</option>
+ </select>
+ <label for="template">Template :</label>
+ <select name="template" id="template">
+ <?php
+ if ($art->template() == 'NULL') {
+ echo '<option value="" selected >No template</option>';
+ } else {
+ echo '<option value="" >No template</option>';
+ }
+ foreach ($list as $item) {
+
+ if ($item->id() == $art->template()) {
+ echo '<option value="' . $item->id() . '" selected >' . $item->title() . '</option>';
+ } else {
+ echo '<option value="' . $item->id() . '">' . $item->title() . '</option>';
+ }
+ }
+ ?>
+ </select>
+ </fieldset>
+ </details>
+ <details>
+ <summary>Advanced</summary>
+ <fieldset>
+ <h3>Template options</h3>
+ <p>NOT WORKING</p>
+ </fieldset>
+ </details>
+ <details id="editcss" open>
+ <summary>Quick CSS</summary>
+
+ </details>
+ <details>
+ <summary>Help</summary>
+ <div id="help">
+ <?= $this->editorhelp() ?>
+ </div>
+ </details>
+
+
+ </div>
+
+
+ <input type="hidden" name="datecreation" value="<?= $art->datecreation('string'); ?>">
+ <input type="hidden" name="id" value="<?= $art->id() ?>">
+
+ </form>
+
+
+ <?php
+
+}
+
+}
+
+
+public function tabs($tablist, $opentab)
+{
+ echo '<div class="tabs">';
+ foreach ($tablist as $key => $value) {
+ echo '<div class="tab">';
+ if ($key == $opentab) {
+ echo '<input name="checkbox-tabs-group" type="radio" id="tab' . $key . '" class="checkboxtab" checked>';
+ } else {
+ echo '<input name="checkbox-tabs-group" type="radio" id="tab' . $key . '" class="checkboxtab">';
+ }
+ echo '<label for="tab' . $key . '">' . $key . '</label>';
+ echo '<div class="content">';
+ echo '<textarea name="' . $key . '" id="' . $key . '" >' . $value . '</textarea>';
+ echo '</div>';
+ echo '</div>';
+ }
+
+ echo '</div>';
+}
+
+public function editorhelp()
+{
+ ?>
+ <h2>Help !</h2>
+ <p>To save your article, press the HOME, UPDATE, or DISPLAY buttons. You can use the keyboard shortcuts as well.</p>
+ <pre><span class="i">ALT + W</span> : home</pre>
+ <pre><span class="i">ALT + X</span> : update</pre>
+ <pre><span class="i">ALT + C</span> : display</pre>
+ <h3>Markdown</h3>
+ <p>The html section use <a href="https://daringfireball.net/projects/markdown/syntax" target="_blank">Markdown encoding</a>. Actualy, W is using Michel Fortin's <a href="https://michelf.ca/projects/php-markdown/extra/" target="_blank">Markdown Extra</a>.</p>
+ <h3>Links</h3>
+ <pre>[text](=<span class="i">article_id</span>)</pre>
+ <p>where article_id is the article's id you want to point to.</p>
+ <h3>Images</h3>
+ <pre>[altimage](/<span class="i">img_id.extension</span>)</pre>
+ <p>Where img_id is the id of your image and its extension.</p>
+ <h3>Shortcuts</h3>
+ <pre>%TITLE%</pre>
+ <p>Show the title of your article.</p>
+ <pre>%DESCRIPTION%</pre>
+ <p>Show the description of your article.</p>
+ <pre>%SUMMARY%</pre>
+ <p>Generate a <strong>summary</strong>, the list of all your head titles using #, ##, ###...</p>
+ <pre>%%<span class="i">tag_name</span>%%</pre>
+ <p>Generate a <strong>menu</strong>, a list of links to all articles under this tag.</p>
+ <p>vv</p>
+ <p>vv</p>
+ <p>vv</p>
+ <p></p>
+ <?php
+}
+
+
+
+public function head($title, $tool, $color4)
+{
+ ?>
+ <head>
+ <meta charset="utf8" />
+ <meta name="viewport" content="width=device-width" />
+ <link rel="shortcut icon" href="./media/logo.png" type="image/x-icon">
+ <link href="./rsc/css/stylebase.css" rel="stylesheet" />
+ <link href="./rsc/css/style<?= $tool ?>.css" rel="stylesheet" />
+ <style>
+ :root {
+ --color4: <?= $color4 ?>;
+ }
+ </style>
+ <title><?= $title ?></title>
+ <script src="./rsc/js/app.js"></script>
+ </head>
+ <?php
+
+}
+
+public function arthead(Art2 $art, $globalcss, $edit = 0)
+{
+ ?>
+ <head>
+ <meta charset="utf8" />
+ <meta name="description" content="<?= $art->description() ?>" />
+ <meta name="viewport" content="width=device-width" />
+ <link rel="shortcut icon" href="./media/logo.png" type="image/x-icon">
+ <link href="./rsc/css/stylebase.css" rel="stylesheet" />
+ <?= $edit == 0 ? '<link href="' . $globalcss . '" rel="stylesheet" />' : '<link href="./rsc/css/styleedit.css" rel="stylesheet" />' ?>
+ <title><?= $edit == 1 ? '✏' : '' ?> <?= $art->title() ?></title>
+ <script src="./rsc/js/app.js"></script>
+ </head>
+ <?php
+
+}
+
+public function noarthead($id, $globalcss)
+{
+ ?>
+ <head>
+ <meta charset="utf8" />
+ <meta name="description" content="This article does not exist yet." />
+ <meta name="viewport" content="width=device-width" />
+ <link rel="shortcut icon" href="./media/logo.png" type="image/x-icon">
+ <link href="./rsc/css/stylebase.css" rel="stylesheet" />
+ <link href="<?= $globalcss ?>" rel="stylesheet" />
+ <title>❓ <?= $id ?></title>
+ <script src="./rsc/js/app.js"></script>
+ </head>
+ <?php
+
+}
+
+
+
+
+public function search()
+{
+ ?>
+ <div id="search">
+ <form action="./" method="get">
+ <input type="text" name="id" id="id" placeholder="identifiant article" required>
+ <input type="submit" value="accéder">
+ </form>
+ </div>
+ <?php
+
+}
+
+public function tag($getlist, $tag, $app)
+{
+ echo '<div class="tag">';
+ echo '<ul>';
+ foreach ($getlist as $item) {
+ if (in_array($tag, $item->tag('array'))) {
+ echo '<li><a href="?id=' . $item->id() . '">' . $item->title() . '</a> - ' . $item->description();
+ if ($app->session() >= $app::EDITOR) {
+ echo ' - <a href="?id=' . $item->id() . '&edit=1">modifier</a></li>';
+ } else {
+ echo '</li>';
+ }
+ }
+ }
+ echo ' </ul> ';
+ echo ' </div> ';
+}
+
+public function linkfrom($getlist, $linkfrom, App $app)
+{
+ echo '<div class="linkfrom">';
+ echo '<ul>';
+ foreach ($getlist as $item) {
+ if (in_array($linkfrom, $item->linkfrom('array'))) {
+ echo '<li><a href="?id=' . $item->id() . '">' . $item->title() . '</a> - ' . $item->description();
+ if ($app->session() >= $app::EDITOR) {
+ echo ' - <a href="?id=' . $item->id() . '&edit=1">modifier</a> - <a href="?linkfrom=' . $item->id() . '">linkfroms</a></li>';
+ } else {
+ echo '</li>';
+ }
+ }
+ }
+ echo ' </ul> ';
+ echo ' </div> ';
+}
+
+public function dump($getlist)
+{
+ echo '<ul>';
+ foreach ($getlist as $item) {
+ echo '<li>';
+ var_dump($item);
+ echo '</li>';
+ }
+ echo ' </ul> ';
+}
+
+public function header()
+{
+ echo '<header>';
+ $this->search();
+ echo '</header>';
+}
+
+
+public function home2table(App $app, $getlist, $masslist)
+{
+ echo '<div id="main">';
+ echo '<h2>Articles</h2>';
+ echo '<form action="./" method="post">';
+
+ ?>
+ <div id="massedit">
+ <h3>Mass Edit</h3>
+ <select name="massedit" required>
+ <option value="public">set as public</option>
+ <option value="private">set as private</option>
+ <option value="not published">set as not published</option>
+ <option value="erasetag">erase all tags</option>
+ <option value="erasetemplate">erase template</option>
+ <option value="delete">delete</option>
+ </select>
+
+ <input type="submit" name="massaction" value="do" onclick="confirmSubmit(event, 'Are you sure')" >
+
+ <input type="text" name="targettag" placeholder="add tag">
+ <input type="submit" name="massaction" value="add tag" onclick="confirmSubmit(event, 'Are you sure')" >
+
+ <select name="masstemplate">
+ <?php
+ foreach ($masslist as $art) {
+ echo '<option value="' . $art->id() . '">' . $art->id() . '</option>';
+ }
+ ?>
+ </select>
+
+ <input type="submit" name="massaction" value="set template" onclick="confirmSubmit(event, 'Are you sure')" >
+
+ <input type="hidden" name="action" value="massedit">
+ </div>
+
+ <?php
+ if ($app->session() >= $app::EDITOR) {
+ echo '<table id="home2table">';
+ echo '<tr><th>x</th><th>title</th><th>tag</th><th>summary</th><th>↘ to</th><th>↗ from</th><th>last modification</th><th>date of creation</th><th>privacy</th><th>display</th></tr>';
+ foreach ($getlist as $item) {
+ echo '<tr>';
+ echo '<td><input type="checkbox" name="id[]" value=' . $item->id() . '></td>';
+ echo '<td><a href="?id=' . $item->id() . '&edit=1">' . $item->title() . '</a></td>';
+ echo '<td>' . $item->tag('sort') . '</td>';
+ echo '<td>' . $item->description() . '</td>';
+ echo '<td><a href="?linkfrom=' . $item->id() . '">' . $item->linkto('sort') . '</a></td>';
+ echo '<td>' . $item->linkfrom('sort') . '</td>';
+ echo '<td>' . $item->datemodif('hrdi') . '</td>';
+ echo '<td>' . $item->datecreation('hrdi') . '</td>';
+ echo '<td>' . $item->secure('string') . '</td>';
+ echo '<td><a href="?id=' . $item->id() . '" target="_blank">👁</a></td>';
+ echo '</tr>';
+ }
+ echo ' </table> ';
+ echo ' </form> ';
+ echo '</div>';
+ }
+}
+
+public function option(App $app, Opt $opt)
+{
+ if ($app->session() >= $app::EDITOR) {
+ echo '<div id="options">';
+ echo '<h2>Options</h2>';
+ echo '<form action="./" method="get" >';
+ echo '<input type="submit" name="submit" value="filter">';
+ echo '⬅<input type="submit" name="submit" value="reset">';
+
+
+ $this->optionsort($opt);
+ $this->optionprivacy($opt);
+ $this->optiontag($opt);
+
+ if ($opt->invert() == 1) {
+ echo '<input type="checkbox" name="invert" value="1" id="invert" checked>';
+ } else {
+ echo '<input type="checkbox" name="invert" value="1" id="invert">';
+ }
+ echo '<label for="invert">invert</></br>';
+
+
+ echo '<input type="submit" name="submit" value="filter">';
+ echo '⬅<input type="submit" name="submit" value="reset">';
+
+ echo '</form></div>';
+
+ }
+
+}
+
+public function optiontag(Opt $opt)
+{
+
+ echo '<fieldset><legend>Tag</legend><ul>';
+
+
+ echo '<input type="radio" id="OR" name="tagcompare" value="OR" ' . ($opt->tagcompare() == "OR" ? "checked" : "") . ' ><label for="OR">OR</label>';
+ echo '<input type="radio" id="AND" name="tagcompare" value="AND" ' . ($opt->tagcompare() == "AND" ? "checked" : "") . '><label for="AND">AND</label>';
+
+ //echo '<input type="hidden" name="tagfilter[]" value="">';
+
+ $in = false;
+ $out = false;
+ $limit = 1;
+ foreach ($opt->taglist() as $tagfilter => $count) {
+
+ if ($count > $limit && $in == false) {
+ echo '<details open><summary>>' . $limit . '</summary>';
+ $in = true;
+ }
+ if ($count == $limit && $in == true && $out == false) {
+ echo '</details><details><summary>' . $limit . '</summary>';
+ $out = true;
+ }
+
+ if (in_array($tagfilter, $opt->tagfilter())) {
+
+ echo '<li><input type="checkbox" name="tagfilter[]" id="' . $tagfilter . '" value="' . $tagfilter . '" checked /><label for="' . $tagfilter . '">' . $tagfilter . ' (' . $count . ')</label></li>';
+ } else {
+ echo '<li><input type="checkbox" name="tagfilter[]" id="' . $tagfilter . '" value="' . $tagfilter . '" /><label for="' . $tagfilter . '">' . $tagfilter . ' (' . $count . ')</label></li>';
+ }
+ }
+ if ($in = true || $out = true) {
+ echo '</details>';
+ }
+ echo '</ul></fieldset>';
+
+}
+
+public function optionprivacy(Opt $opt)
+{
+ echo '<fieldset><legend>Privacity</legend><ul>';
+ echo '<li><input type="radio" id="4" name="secure" value="4" ' . ($opt->secure() == 4 ? "checked" : "") . ' /><label for="4">all</label></li>';
+ echo '<li><input type="radio" id="2" name="secure" value="2" ' . ($opt->secure() == 2 ? "checked" : "") . ' /><label for="2">not published</label></li>';
+ echo '<li><input type="radio" id="1" name="secure" value="1" ' . ($opt->secure() == 1 ? "checked" : "") . ' /><label for="1">private</label></li>';
+ echo '<li><input type="radio" id="0" name="secure" value="0" ' . ($opt->secure() == 0 ? "checked" : "") . ' /><label for="0">public</label></li>';
+ echo '</ul></fieldset>';
+}
+
+public function optionsort(Opt $opt)
+{
+ echo '<fieldset><legend>Sort</legend>';
+ echo '<select name="sortby" id="sortby">';
+ foreach ($opt->col('array') as $key => $col) {
+ echo '<option value="' . $col . '" ' . ($opt->sortby() == $col ? "selected" : "") . '>' . $col . '</option>';
+ }
+ echo '</select>';
+ echo '</br>';
+ echo '<input type="radio" id="asc" name="order" value="1" ' . ($opt->order() == '1' ? "checked" : "") . ' /><label for="asc">ascending</label>';
+ echo '</br>';
+ echo '<input type="radio" id="desc" name="order" value="-1" ' . ($opt->order() == '-1' ? "checked" : "") . ' /><label for="desc">descending</label>';
+
+ echo '</fieldset>';
+
+}
+
+public function mapheader()
+{
+ $selectcurve = isset($_GET['curve']) ? $_GET['curve'] : 'basis';
+ $selectorient = isset($_GET['orient']) ? $_GET['orient'] : 'TD';
+ $curves = ['linear', 'basis', 'natural', 'step', 'stepAfter', 'stepBefore', 'monotoneX', 'monotoneY'];
+ $orients = ['TD', 'LR', 'BT', 'RL'];
+ ?>
+ <h2>Map</h2>
+
+ <form action="./" method="get">
+ <label for="curve">Curve style</label>
+ <select name="curve" id="curve">
+ <?php
+ foreach ($curves as $curve) {
+ ?>
+ <option value="<?= $curve ?>" <?= $selectcurve == $curve ? 'selected' : '' ?>><?= $curve ?></option>
+ <?php
+
+ }
+ ?>
+ </select>
+ <label for="orient">Orientation</label>
+ <select name="orient" id="orient">
+ <?php
+ foreach ($orients as $orient) {
+ ?>
+ <option value="<?= $orient ?>" <?= $selectorient == $orient ? 'selected' : '' ?>><?= $orient ?></option>
+ <?php
+
+ }
+ ?>
+ </select>
+ <input type="submit" value="draw" name="map">
+ </form>
+ <?php
+
+}
+
+public function mermaid(string $map)
+{
+ $curve = isset($_GET['curve']) ? $_GET['curve'] : 'basis';
+ $orient = isset($_GET['orient']) ? $_GET['orient'] : 'TD';
+
+
+ ?>
+
+ <script src="./rsc/js/mermaid.min.js"></script>
+
+ <script>
+ mermaid.initialize({
+ startOnLoad:true,
+ themeCSS: ".node circle, .node rect , .node polygon { fill: var(--color1); stroke: var(--color4);} ",
+ flowchart: {
+ curve: '<?= $curve ?>'
+ }
+ });
+
+ </script>
+
+
+ <div class="mermaid">
+
+ graph <?= $orient ?>
+ <?= $map ?>
+ </div>
+
+
+ <?php
+
+}
+
+public function aside(App $app)
+{
+ if ($app->session() >= $app::EDITOR) {
+ echo '<div id="linklist">Links<div id="roll"><ul>';
+ foreach ($app->lister() as $item) {
+ echo '<li><a href="?id=' . $item['id'] . '&edit=1">' . $item['title'] . '</a> - <input type="text" value="[' . $item['title'] . '](?id=' . $item['id'] . ')">';
+
+
+ }
+ echo ' </ul></div></div> ';
+ }
+}
+
+public function nav($app)
+{
+ echo '<nav>';
+ echo $app->session();
+ echo '<div id="menu">';
+
+ echo '<a class="button" href="?">home</a>';
+
+ if ($app->session() == $app::FREE) {
+ if (isset($_GET['id'])) {
+ echo '<form action="./?id=' . $_GET['id'] . '" method="post">';
+ } else {
+ echo '<form action="." method="post">';
+ }
+ ?>
+ <input type="hidden" name="action" value="login">
+ <input type="password" name="pass" id="loginpass" placeholder="password">
+ <input type="submit" value="login">
+ </form>
+ <?php
+
+ }
+ if ($app->session() > $app::FREE) {
+ if (isset($_GET['id'])) {
+ echo '<form action="./?id=' . $_GET['id'] . '" method="post">';
+ } else {
+ echo '<form action="." method="post">';
+ }
+ ?>
+ <input type="hidden" name="action" value="logout">
+ <input type="submit" value="logout">
+ </form>
+ <?php
+
+ }
+ if ($app->session() >= $app::EDITOR && isset($_GET['id']) && $app->exist($_GET['id'])) {
+ if (isset($_GET['edit']) && $_GET['edit'] == 1) {
+ echo '<a class="button" href="?id=' . $_GET['id'] . '" target="_blank">display</a>';
+ } else {
+ echo '<a class="button" href="?id=' . $_GET['id'] . '&edit=1" >edit</a>';
+ }
+ }
+ if ($app->session() >= $app::EDITOR) {
+ echo '<a class="button" href="?aff=media" >Media</a>';
+ echo '<a class="button" href="?aff=record" >Record</a>';
+ if ($app->session() >= $app::ADMIN) {
+ echo '<a class="button" href="?aff=admin" >Admin</a>';
+ }
+ }
+
+
+
+
+ ?>
+ </div>
+ </nav>
+ <?php
+
+ }
+
+ // ____________________________________________________ M E D ________________________________________________
+
+
+ public function addmedia($app)
+ {
+ if ($app->session() >= $app::EDITOR) {
+
+ ?>
+ <details close>
+ <summary>Add Media</summary>
+ <form action="./" method="post" enctype="multipart/form-data">
+ <input type="hidden" name="action" value="addmedia">
+ <input type="file" accept="*" name="media" required>
+ <input type="text" name="id" id="" placeholder="nom du fichier" required>
+ <input type="submit" value="envoi">
+ </form>
+ </details>
+ <?php
+
+ }
+ }
+
+ public function medialist(array $getlistermedia, $dir)
+ {
+ ?>
+ <details open>
+ <summary>Media List</summary>
+
+ <form action="" method="post">
+
+ <table id=mediatable>
+ <tr><th>x</th><th>Name</th><th>extension</th><th>width</th><th>height</th><th>size</th><th>code</th><th>thumbnail</th></tr>
+ <?php
+
+
+ foreach ($getlistermedia as $item) {
+ $filepath = $dir . $item->id() . '.' . $item->extension();
+ echo '<tr>';
+ echo '<td><input type="checkbox" name="id[]" value=' . $item->id() . ' id="' . $item->id() . '"></td>';
+ echo '<td><label for="' . $item->id() . '">' . $item->id() . '</label></td>';
+ echo '<td>' . $item->extension() . '</td>';
+ echo '<td>' . $item->width() . '</td>';
+ echo '<td>' . $item->height() . '</td>';
+ echo '<td>' . readablesize($item->size()) . '</td>';
+ if ($item->type() == 'image') {
+ echo '<td><input type="text" value="![' . $item->id() . '](/' . $item->id() . '.' . $item->extension() . ')"></td>';
+ echo '<td class="tooltip">👁<span class="infobulle"><a href="' . $filepath . '" target="_blank" ><img class="thumbnail" src="' . $filepath . '" alt="' . $item->id() . '"></a></span></td>';
+ } elseif ($item->type() == 'sound') {
+ echo '<td><input type="text" value="[' . $item->id() . '](' . $filepath . ')"></td>';
+ echo '<td><a href="' . $filepath . '" target="_blank" >♪</a></td>';
+ } else {
+ echo '<td><input type="text" value="[' . $item->id() . '](' . $filepath . ')"></td>';
+ echo '<td><a href="' . $filepath . '" target="_blank" >∞</a></td>';
+ }
+ echo '</tr>';
+ echo '';
+
+ }
+
+
+ ?>
+
+
+ </table>
+
+ <select name="action" id="">
+ <option value="">compress /2</option>
+ <option value="">downscale /2</option>
+ <option value="">upscale *2</option>
+ </select>
+ <input type="submit" value="edit">
+ <input type="submit" value="delete">
+ </form>
+ </div>
+
+ </details>
+
+
+ <?php
+
+ }
+
+
+ //______________________________________________________ R E C _________________________________________________
+
+
+ public function recordlist(App $app, $dir = "../ACRRecordings/")
+ {
+ echo '<details open>';
+ echo '<summary>Media List</summary>';
+
+ echo '<article class="gest">';
+
+ echo '<form action="" method="post">';
+
+ echo '<ul>';
+
+ foreach ($app->getlisterrecord($dir) as $item) {
+ echo '<li>';
+
+ ?>
+ <input type="checkbox" id="<?= $item->id() ?>" name="<?= $item->id() ?>" value="1">
+ <label for="<?= $item->id() ?>"><?= $item->id() ?></label>
+ <input type="hidden" name="id" value="<?= $item->id() ?>">
+
+ <?php
+
+ $filepathurl = $dir . urlencode($item->id()) . '.' . $item->extension();
+
+ echo '<br/>';
+ var_dump($item->size());
+ var_dump(intval($item->size()));
+ echo 'filesize = ' . readablesize(intval($item->size()));
+ echo '<br/>';
+ echo 'extension = ' . $item->extension();
+ echo '<br/>';
+
+ ?>
+
+ <audio controls>
+ <source src="<?= $filepathurl ?>" type="audio/mpeg">
+ </audio>
+
+
+
+ <?php
+
+
+
+
+ echo '</li>';
+ }
+
+ echo '</ul>';
+
+ ?>
+ <select name="action" id="">
+ <option value="">compress /2</option>
+ <option value="">downscale /2</option>
+ <option value="">upscale *2</option>
+ </select>
+ <input type="submit" value="edit">
+ <input type="submit" value="delete">
+ </form>
+ </div>
+
+
+ <?php
+
+
+ echo '</article>';
+ echo '</details>';
+
+
+ }
+
+
+ //______________________________________________________ A D M _________________________________________________
+
+
+
+ public function admincss(Config $config, $app)
+ {
+ ?>
+ <article>
+ <h2>CSS</h2>
+
+ <p>CSS file :</p>
+
+ <p><code> <?= $app::GLOBAL_CSS_DIR ?></code></p>
+
+ <?php
+ $cssfile = $app::GLOBAL_CSS_DIR;
+ if (is_file($cssfile)) {
+ $cssread = file_get_contents($cssfile);
+ echo '<details>';
+ echo '<summary>Edit current CSS</summary>';
+ echo '<form action="./" method="post">';
+ echo '<textarea name="editcss" id="cssarea">' . $cssread . '</textarea>';
+ echo '<input type="hidden" name="action" value="editcss">';
+ echo '<input type="submit" value="edit">';
+ echo '</form>';
+ echo '</details>';
+ }
+
+ ?>
+
+ </article>
+ <?php
+
+ }
+
+ public function admindb($config)
+ {
+ ?>
+
+ <article>
+
+
+ <h2>Database</h2>
+
+ <details>
+ <summary>Database credentials</summary>
+
+ <p>Fill this sections with the database settings you want to connect to</p>
+
+ <form action="./" method="post">
+ <input type="hidden" name="action" value="editconfig">
+ <label for="host">Host</label>
+ <input title="host" type="text" name="host" id="host" value="<?= $config->host() ?>">
+ <label for="dbname">DataBase name</label>
+ <input title="dbname" type="text" name="dbname" id="dbname" value="<?= $config->dbname() ?>">
+ <label for="user">User name</label>
+ <input title="user" type="text" name="user" id="user" value="<?= $config->user() ?>">
+ <label for="password">Password</label>
+ <input title="password" type="text" name="password" id="password" value="<?= $config->password() ?>">
+ <input type="submit" value="edit" id="">
+ </form>
+
+ </details>
+
+
+ </article>
+
+ <?php
+
+ }
+
+ public function adminpassword(Config $config)
+ {
+ ?>
+ <article>
+
+ <h2>Passwords</h2>
+
+ <details>
+ <summary>Admin</summary>
+
+ <p>Edit your own admin password. You can find it in the config.w.json file, in the root of your website folder.</p>
+
+ <form action="./" method="post">
+ <input type="hidden" name="action" value="editconfig">
+ <label for="admin">Administrator password (10)</label>
+ <input title="admin password" type="password" name="admin" id="admin" value="<?= $config->admin() ?>" >
+ <input type="submit" value="edit" id="">
+ </form>
+
+ </details>
+ <details>
+ <summary>Others</summary>
+
+ <p>Use this section to set all the others users passwords. They cant access this page, so they cant change it by themselves.</p>
+
+ <form action="./" method="post">
+ <input type="hidden" name="action" value="editconfig">
+ <label for="editor">Editor password (3)</label>
+ <input title="editor" type="text" name="editor" id="editor" value="<?= $config->editor() ?>">
+ <label for="invite">Invite password (2)</label>
+ <input title="invite" type="text" name="invite" id="invite" value="<?= $config->invite() ?>" >
+ <label for="read">Reader password (1)</label>
+ <input title="read" type="text" name="read" id="read" value="<?= $config->read() ?>">
+ <input type="submit" value="edit" id="">
+ </form>
+
+ </details>
+ </article>
+
+
+
+
+ <?php
+
+ }
+
+ public function admintable(Config $config, string $status, array $arttables)
+ {
+ ?>
+
+ <article>
+
+ <h2>Table</h2>
+
+
+
+ <p>Database status : <strong><?= $status ?></strong></p>
+
+
+ <p>Current Table : <strong><?= $config->arttable(); ?></strong></p>
+ <details>
+ <summary>Select Table</summary>
+ <p>The table is where all your articles are stored, select the one you want to use.</p>
+
+ <form action="./" method="post">
+ <select name="arttable" required>
+
+ <?php
+ foreach ($arttables as $arttable) {
+ if ($arttable == $config->arttable()) {
+ echo '<option value="' . $arttable . '" " selected >' . $arttable . '</option>';
+ } else {
+ echo '<option value="' . $arttable . '">' . $arttable . '</option>';
+ }
+ }
+ ?>
+ </select>
+ <input type="hidden" name="action" value="editconfig">
+ <input type="submit" value="choose">
+ </form>
+
+ </details>
+
+ <details>
+ <summary>Add table</summary>
+
+ <p>Create new table in your database. You need at least one to use W_cms</p>
+
+ <form action="./" method="post">
+ <input type="hidden" name="actiondb" value="addtable">
+ <input type="text" name="tablename" placeholder="table name" maxlength="30" required>
+ <input type="submit" value="create">
+ </form>
+
+ </details>
+
+ <details>
+ <summary>Duplicate Table</summary>
+ <p>If you want to save versions of your work.</p>
+
+ <form action="./" method="post">
+ <label for="arttable">Select the table you want to copy.</label>
+ <select name="arttable" id="arttable" required>
+
+ <?php
+ foreach ($arttables as $arttable) {
+ if ($arttable == $config->arttable()) {
+ echo '<option value="' . $arttable . '" " selected >' . $arttable . '</option>';
+ } else {
+ echo '<option value="' . $arttable . '">' . $arttable . '</option>';
+ }
+ }
+ ?>
+ </select>
+ <label for="tablename">Choose a name for the copy</label>
+ <input type="text" name="tablename" id="tablename" required>
+ <input type="hidden" name="actiondb" value="duplicatetable">
+ <input type="submit" value="Duplicate">
+ </form>
+
+ </details>
+
+ </article>
+
+ <?php
+
+ }
+
+ public function admindisplay($color4)
+ {
+ ?>
+ <article>
+ <h2>Display</h2>
+ <details>
+ <summary>Update favicon</summary>
+ <form action="./" method="post" enctype="multipart/form-data">
+ <input type="file" name="favicon" id="favicon">
+ <input type="submit" value="update">
+ </form>
+ </details>
+ <details>
+ <summary>Change desktop background color</summary>
+ <form action="./" method="post">
+ <label for="color4">Background color</label>
+ <input type="color" name="color4" id="color4" value="<?= $color4 ?>">
+ <input type="hidden" name="action" value="editconfig">
+ <input type="submit" value="color my life">
+ </form>
+ </details>
+ </article>
+ <?php
+
+ }
+
+
+}
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/app4.php b/app/class/app4.php
new file mode 100644
index 0000000..b791846
--- /dev/null
+++ b/app/class/app4.php
@@ -0,0 +1,657 @@
+<?php
+class App
+{
+ private $bdd;
+ private $session;
+ private $arttable;
+
+
+ const CONFIG_FILE = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'w.config.json';
+ const GLOBAL_CSS_DIR = '.' . DIRECTORY_SEPARATOR . 'css' . DIRECTORY_SEPARATOR . 'global' . DIRECTORY_SEPARATOR . 'global.css';
+ const MEDIA_DIR = '.' . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR;
+ const MEDIA_EXTENSIONS = array('jpeg', 'jpg', 'JPG', 'png', 'gif', 'mp3', 'mp4', 'mov', 'wav', 'flac', 'pdf');
+ const MEDIA_TYPES = ['image', 'video', 'sound', 'other'];
+
+
+ const ADMIN = 10;
+ const EDITOR = 3;
+ const INVITE = 2;
+ const READ = 1;
+ const FREE = 0;
+
+
+// _____________________________________ C O N S T R U C T _________________________________
+
+
+
+ public function __construct()
+ {
+ $this->setsession($this::FREE);
+ }
+
+ public function setbdd(Config $config)
+ {
+ $caught = true;
+
+ try {
+ $this->bdd = new PDO('mysql:host=' . $config->host() . ';dbname=' . $config->dbname() . ';charset=utf8', $config->user(), $config->password(), array(PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT));
+ //$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ } catch (PDOException $e) {
+ $caught = false;
+ echo '<h1>Error 500, database offline</h1>';
+ if ($this->session() >= self::EDITOR) {
+ echo '<p>Error : ' . $e->getMessage() . '</p>';
+ if ($this->session() == self::ADMIN) {
+ echo '<p>Go to the <a href="?aff=admin">Admin Panel</a> to edit your database credentials</p>';
+ } else {
+ echo '<p>Logout and and come back with an <strong>admin password</strong> to edit the database connexions settings.</p>';
+ }
+ } else {
+ echo '<p><a href=".">Homepage for admin login</a> (connect on the top right side)</p>';
+ }
+ exit;
+ }
+
+ return $caught;
+
+ }
+
+ public function settable(Config $config)
+ {
+ if (!empty($config->arttable())) {
+ $this->arttable = $config->arttable();
+ } else {
+ echo '<h1>Table Error</h1>';
+
+ if ($this->session() >= self::EDITOR) {
+ if ($this->session() == self::ADMIN) {
+ echo '<p>Go to the <a href="?aff=admin">Admin Panel</a> to select or add an Article table</p>';
+ } else {
+ echo '<p>Logout and and come back with an <strong>admin password</strong> to edit table settings.</p>';
+ }
+ } else {
+ echo '<p><a href=".">Homepage for admin login</a> (connect on the top right side)</p>';
+ }
+ $caught = false;
+ exit;
+ }
+ }
+
+ public function bddinit(Config $config)
+ {
+ $test = $this->setbdd($config);
+ if ($test) {
+ $this->settable($config);
+ }
+ }
+
+
+// _________________________________________ C O N F I G ____________________________________
+
+ public function readconfig()
+ {
+ if (file_exists(self::CONFIG_FILE)) {
+ $current = file_get_contents(self::CONFIG_FILE);
+ $donnees = json_decode($current, true);
+ return new Config($donnees);
+ } else {
+ return 0;
+ }
+
+ }
+
+ public function createconfig(array $donnees)
+ {
+ return new Config($donnees);
+ }
+
+
+ public function savejson(string $json)
+ {
+ file_put_contents(self::CONFIG_FILE, $json);
+ }
+
+
+
+
+
+
+// ___________________________________________ A R T ____________________________________
+
+
+ public function add(Art2 $art)
+ {
+
+ if ($this->exist($art->id())) {
+ echo '<span class="alert">idalreadyexist</span>';
+ } else {
+
+ var_dump($art);
+
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+
+ $request = 'INSERT INTO ' . $this->arttable . '(id, title, description, tag, date, datecreation, datemodif, daterender, css, quickcss, javascript, html, header, section, nav, aside, footer, render, secure, invitepassword, interface, linkfrom, template, affcount, editcount)
+ VALUES(:id, :title, :description, :tag, :date, :datecreation, :datemodif, :daterender, :css, :quickcss, :javascript, :html, :header, :section, :nav, :aside, :footer, :render, :secure, :invitepassword, :interface, :linkfrom, :template, :affcount, :editcount)';
+
+ $q = $this->bdd->prepare($request);
+
+ $q->bindValue(':id', $art->id());
+ $q->bindValue(':title', $art->title());
+ $q->bindValue(':description', $art->description());
+ $q->bindValue(':tag', $art->tag('string'));
+ $q->bindValue(':date', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':datecreation', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':datemodif', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':daterender', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':css', $art->css());
+ $q->bindValue(':quickcss', $art->quickcss('json'));
+ $q->bindValue(':javascript', $art->javascript());
+ $q->bindValue(':html', $art->html());
+ $q->bindValue(':header', $art->header());
+ $q->bindValue(':section', $art->md());
+ $q->bindValue(':nav', $art->nav());
+ $q->bindValue(':aside', $art->aside());
+ $q->bindValue(':footer', $art->footer());
+ $q->bindValue(':render', $art->render());
+ $q->bindValue(':secure', $art->secure());
+ $q->bindValue(':invitepassword', $art->invitepassword());
+ $q->bindValue(':interface', $art->interface());
+ $q->bindValue(':linkfrom', $art->linkfrom('json'));
+ $q->bindValue(':template', $art->template('json'));
+ $q->bindValue(':affcount', $art->affcount());
+ $q->bindValue(':editcount', $art->editcount());
+
+ $q->execute();
+ }
+ }
+
+ public function delete(Art2 $art)
+ {
+ $req = $this->bdd->prepare('DELETE FROM ' . $this->arttable . ' WHERE id = :id ');
+ $req->execute(array('id' => $art->id()));
+ $req->closeCursor();
+ }
+
+ public function get($id)
+ {
+ $req = $this->bdd->prepare('SELECT * FROM ' . $this->arttable . ' WHERE id = :id ');
+ $req->execute(array('id' => $id));
+ $donnees = $req->fetch(PDO::FETCH_ASSOC);
+
+ return new Art2($donnees);
+
+ $req->closeCursor();
+
+ }
+
+
+
+
+
+ public function update(Art2 $art)
+ {
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+
+ //$request = 'UPDATE ' . $this->arttable . '(id, title, description, tag, date, datecreation, datemodif, daterender, css, quickcss, javascript, html, header, section, nav, aside, footer, render, secure, invitepassword, interface, linkfrom, template, affcount, editcount) VALUES(:id, :title, :description, :tag, :date, :datecreation, :datemodif, :daterender, :css, :quickcss, :javascript, :html, :header, :section, :nav, :aside, :footer, :render, :secure, :invitepassword, :interface, :linkfrom, :template, :affcount, :editcount) WHERE id = :id';
+
+ $request = 'UPDATE ' . $this->arttable . ' SET id = :id, title = :title, description = :description, tag = :tag, date = :date, datecreation = :datecreation, datemodif = :datemodif, daterender = :daterender, css = :css, quickcss = :quickcss, javascript = :javascript, html = :html, header = :header, section = :section, nav = :nav, aside = :aside, footer = :footer, render = :footer, secure = :secure, invitepassword = :invitepassword, interface = :interface, linkfrom = :linkfrom, template = :template, affcount = :affcount, editcount = :editcount WHERE id = :id';
+
+ $q = $this->bdd->prepare($request);
+
+ $q->bindValue(':id', $art->id());
+ $q->bindValue(':title', $art->title());
+ $q->bindValue(':description', $art->description());
+ $q->bindValue(':tag', $art->tag('string'));
+ $q->bindValue(':date', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':datecreation', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':datemodif', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':daterender', $now->format('Y-m-d H:i:s'));
+ $q->bindValue(':css', $art->css());
+ $q->bindValue(':quickcss', $art->quickcss('json'));
+ $q->bindValue(':javascript', $art->javascript());
+ $q->bindValue(':html', $art->html());
+ $q->bindValue(':header', $art->header());
+ $q->bindValue(':section', $art->md());
+ $q->bindValue(':nav', $art->nav());
+ $q->bindValue(':aside', $art->aside());
+ $q->bindValue(':footer', $art->footer());
+ $q->bindValue(':render', $art->render());
+ $q->bindValue(':secure', $art->secure());
+ $q->bindValue(':invitepassword', $art->invitepassword());
+ $q->bindValue(':interface', $art->interface());
+ $q->bindValue(':linkfrom', $art->linkfrom('json'));
+ $q->bindValue(':template', $art->template('json'));
+ $q->bindValue(':affcount', $art->affcount());
+ $q->bindValue(':editcount', $art->editcount());
+
+ $q->execute();
+ }
+
+ public function exist($id)
+ {
+ $req = $this->bdd->prepare(' SELECT COUNT(*) FROM ' . $this->arttable . ' WHERE id = :id ');
+ $req->execute(array('id' => $id));
+ $donnees = $req->fetch(PDO::FETCH_ASSOC);
+
+ return (bool)$donnees['COUNT(*)'];
+ }
+
+
+
+
+
+ //____________________________________________ L S T ______________________________
+
+
+
+ public function getlister(array $selection = ['id'], array $opt = [])
+ {
+ // give an array using SELECTION columns and sort and desc OPTIONS
+
+ $default = ['tri' => 'id', 'desc' => 'DESC'];
+ $opt = array_update($default, $opt);
+
+ $list = [];
+ $option = ['datecreation', 'title', 'id', 'description', 'datemodif', 'tag', 'secure'];
+ if (is_array($selection) && is_string($opt['tri']) && strlen($opt['tri']) < 16 && is_string($opt['desc']) && strlen($opt['desc']) < 5 && in_array($opt['tri'], $option)) {
+
+ $selection = implode(", ", $selection);
+
+ $select = 'SELECT ' . $selection . ' FROM ' . $this->arttable . ' ORDER BY ' . $opt['tri'] . ' ' . $opt['desc'];
+ $req = $this->bdd->query($select);
+ while ($donnees = $req->fetch(PDO::FETCH_ASSOC)) {
+ $list[] = new Art2($donnees);
+ }
+ return $list;
+ }
+ }
+
+
+
+
+
+
+ public function getlisteropt(Opt $opt)
+ {
+
+ $artlist = [];
+
+ $select = 'SELECT ' . $opt->col('string') . ' FROM ' . $this->arttable;
+ $req = $this->bdd->query($select);
+ while ($donnees = $req->fetch(PDO::FETCH_ASSOC)) {
+ $artlist[] = new Art2($donnees);
+ }
+ return $artlist;
+
+ }
+
+ public function listcalclinkfrom(&$artlist)
+ {
+ foreach ($artlist as $art) {
+ $art->calclinkto($artlist);
+ }
+ }
+
+ public function artcompare($art1, $art2, $method = 'id', $order = 1)
+ {
+ $result = ($art1->$method('sort') <=> $art2->$method('sort'));
+ return $result * $order;
+
+ }
+
+ public function buildsorter($sortby, $order)
+ {
+ return function ($art1, $art2) use ($sortby, $order) {
+ $result = $this->artcompare($art1, $art2, $sortby, $order);
+ return $result;
+ };
+ }
+
+
+
+ public function artlistsort(&$artlist, $sortby, $order = 1)
+ {
+ return usort($artlist, $this->buildsorter($sortby, $order));
+ }
+
+
+
+
+
+
+ public function filtertagfilter(array $artlist, array $tagchecked, $tagcompare = 'OR')
+ {
+
+ $filteredlist = [];
+ foreach ($artlist as $art) {
+ if (empty($tagchecked)) {
+ $filteredlist[] = $art->id();
+ } else {
+ $inter = (array_intersect($art->tag('array'), $tagchecked));
+ if ($tagcompare == 'OR') {
+ if (!empty($inter)) {
+ $filteredlist[] = $art->id();
+ }
+ } elseif ($tagcompare == 'AND') {
+ if (!array_diff($tagchecked, $art->tag('array'))) {
+ $filteredlist[] = $art->id();
+ }
+ }
+ }
+ }
+ return $filteredlist;
+ }
+
+ public function filtersecure(array $artlist, $secure)
+ {
+ $filteredlist = [];
+ foreach ($artlist as $art) {
+ if ($art->secure() == intval($secure)) {
+ $filteredlist[] = $art->id();
+ } elseif (intval($secure) >= 4) {
+ $filteredlist[] = $art->id();
+ }
+ }
+ return $filteredlist;
+ }
+
+
+ public function lister()
+ {
+ $req = $this->bdd->query(' SELECT * FROM ' . $this->arttable . ' ORDER BY id ');
+ $donnees = $req->fetchAll(PDO::FETCH_ASSOC);
+ $req->closeCursor();
+ return $donnees;
+
+ }
+
+ public function tag(array $artlist, $tagchecked)
+ {
+ $artcheckedlist = [];
+ foreach ($artlist as $art) {
+ if (in_array($tagchecked, $art->tag('array'))) {
+ $artcheckedlist[] = $art;
+ }
+ }
+ return $artcheckedlist;
+ }
+
+ public function taglist(array $artlist, array $tagcheckedlist)
+ {
+ $taglist = [];
+ foreach ($tagcheckedlist as $tag) {
+ $taglist[$tag] = $this->tag($artlist, $tag);
+ }
+ return $taglist;
+ }
+
+ public function count()
+ {
+ return $this->bdd->query(' SELECT COUNT(*) FROM ' . $this->arttable . ' ')->fetchColumn();
+ }
+
+
+
+ // __________________________________________ T A B L E ________________________________________________________
+
+
+ public function tableexist($dbname, $tablename)
+ {
+
+ $req = $this->bdd->prepare('SELECT COUNT(*)
+ FROM information_schema.tables
+ WHERE table_schema = :dbname AND
+ table_name like :tablename');
+ $req->execute(array(
+ 'dbname' => $dbname,
+ 'tablename' => $tablename
+ ));
+ $donnees = $req->fetch(PDO::FETCH_ASSOC);
+ $req->closeCursor();
+ $exist = intval($donnees['COUNT(*)']);
+ return $exist;
+
+
+
+
+ }
+
+ public function tablelist($dbname)
+ {
+ $request = 'SHOW TABLES IN ' . $dbname;
+ $req = $this->bdd->query($request);
+ $donnees = $req->fetchAll(PDO::FETCH_ASSOC);
+ $req->closeCursor();
+
+ $arttables = [];
+ foreach ($donnees as $table) {
+ $arttables[] = $table['Tables_in_' . $dbname];
+ }
+ return $arttables;
+
+
+ }
+
+
+
+
+
+ public function tableduplicate($dbname, $arttable, $tablename)
+ {
+ $arttable = strip_tags($arttable);
+ $tablename = str_clean($tablename);
+ if ($this->tableexist($dbname, $arttable) && !$this->tableexist($dbname, $tablename)) {
+ $duplicate = " CREATE TABLE `$tablename` LIKE `$arttable`;";
+ $alter = "ALTER TABLE `$tablename` ADD PRIMARY KEY (`id`);";
+ $insert = "INSERT `$tablename` SELECT * FROM `$arttable`;";
+
+
+ $req = $this->bdd->query($duplicate . $alter . $insert);
+
+ return 'tableduplicated';
+ } else {
+ return 'tablealreadyexist';
+ }
+ }
+
+
+
+
+// __________________________________________ M E D ________________________________________________________
+
+ public function addmedia(array $file, $maxsize = 2 ** 24, $id)
+ {
+ $message = 'runing';
+ $id = strtolower(strip_tags($id));
+ $id = str_replace(' ', '_', $id);
+ if (isset($file) and $file['media']['error'] == 0 and $file['media']['size'] < $maxsize) {
+ $infosfichier = pathinfo($file['media']['name']);
+ $extension_upload = $infosfichier['extension'];
+ $extensions_autorisees = $this::MEDIA_EXTENSIONS;
+ if (in_array($extension_upload, $extensions_autorisees)) {
+ if (!file_exists($this::MEDIA_DIR . $id . '.' . $extension_upload)) {
+
+ $extension_upload = strtolower($extension_upload);
+ $uploadok = move_uploaded_file($file['media']['tmp_name'], $this::MEDIA_DIR . $id . '.' . $extension_upload);
+ if ($uploadok) {
+ $message = 'uploadok';
+ } else {
+ $message = 'uploaderror';
+ }
+ } else {
+ $message = 'filealreadyexist';
+
+ }
+ }
+ } else {
+ $message = 'filetoobig';
+
+ }
+
+ return $message;
+ }
+
+
+ public function getmedia($entry, $dir)
+ {
+ $fileinfo = pathinfo($entry);
+
+ $filepath = $fileinfo['dirname'] . '.' . $fileinfo['extension'];
+
+ $donnees = array(
+ 'id' => str_replace('.' . $fileinfo['extension'], '', $fileinfo['filename']),
+ 'path' => $dir,
+ 'extension' => $fileinfo['extension']
+ );
+
+
+
+ return new Media($donnees);
+
+ }
+
+ public function getlistermedia($dir, $type = "all")
+ {
+ if ($handle = opendir($dir)) {
+ $list = [];
+ while (false !== ($entry = readdir($handle))) {
+ if ($entry != "." && $entry != "..") {
+
+ $media = $this->getmedia($entry, $dir);
+
+
+ $media->analyse();
+
+ if (in_array($type, self::MEDIA_TYPES)) {
+ if ($media->type() == $type) {
+ $list[] = $media;
+ }
+ } else {
+ $list[] = $media;
+ }
+
+
+ }
+ }
+ return $list;
+ }
+
+ return $list;
+
+ }
+
+
+
+
+ //_________________________________________________________ R E C ________________________________________________________
+
+
+ public function getlisterrecord($dir)
+ {
+ if ($handle = opendir($dir)) {
+ $list = [];
+ while (false !== ($entry = readdir($handle))) {
+ if ($entry != "." && $entry != "..") {
+ $fileinfo = pathinfo($entry);
+
+ $filepath = $dir . $fileinfo['filename'] . '.' . $fileinfo['extension'];
+
+ list($width, $height, $type, $attr) = getimagesize($filepath);
+ $filesize = filesize($filepath);
+
+ $donnees = array(
+ 'id' => str_replace('.' . $fileinfo['extension'], '', $fileinfo['filename']),
+ 'path' => $fileinfo['dirname'],
+ 'extension' => $fileinfo['extension'],
+ 'size' => $filesize
+ );
+
+ $list[] = new Record($donnees);
+
+ }
+ }
+ }
+
+ return $list;
+
+
+
+ }
+
+
+
+
+ // ________________________________________________________ M A P ________________________________________________________
+
+
+ public function map(array $getlister, $lb = PHP_EOL)
+ {
+
+ $map = "";
+ $link = "";
+ $style = "";
+ foreach ($getlister as $item) {
+ if($item->secure() == 2) {
+ $style = $style . $lb . $item->id() . '{' . $item->title() . '}';
+ } elseif ($item->secure() == 1) {
+ $style = $style . $lb . $item->id() . '(' . $item->title() . ')';
+
+ } else {
+ $style = $style . $lb . $item->id() . '((' . $item->title() . '))';
+ }
+ foreach ($item->linkfrom('array') as $linkfrom) {
+ $map = $map . $lb . $item->id() . ' --> ' . $linkfrom;
+ $link = $link . $lb . 'click ' . $linkfrom . ' "./?id=' . $linkfrom . '"';
+
+ }
+ $link = $link . $lb . 'click ' . $item->id() . ' "./?id=' . $item->id() . '"';
+ }
+ return $map . $link . $style;
+
+ }
+
+
+
+
+
+ //_________________________________________________________ S E S ________________________________________________________
+
+ public function login($pass, $config)
+ {
+ if (strip_tags($pass) == $config->admin()) {
+ return $level = self::ADMIN;
+ } elseif (strip_tags($pass) == $config->read()) {
+ return $level = self::READ;
+ } elseif (strip_tags($pass) == $config->editor()) {
+ return $level = self::EDITOR;
+ } elseif (strip_tags($pass) == $config->invite()) {
+ return $level = self::INVITE;
+ }
+ }
+
+ public function logout()
+ {
+ return $level = 0;
+ }
+
+ // ________________________________________________________ S E T ___________________________________________________
+
+
+ public function setsession($session)
+ {
+ $this->session = $session;
+ }
+
+
+
+
+ //_________________________________________________________ G E T ________________________________________________________
+
+ public function session()
+ {
+ return $this->session;
+ }
+
+
+}
+?> \ No newline at end of file
diff --git a/app/class/application.php b/app/class/application.php
new file mode 100644
index 0000000..2872695
--- /dev/null
+++ b/app/class/application.php
@@ -0,0 +1,90 @@
+<?php
+
+class Application
+{
+ public function __construct() {
+
+ }
+
+ public function wakeup()
+ {
+ if(isset($_POST['configinit'])) {
+ Config::createconfig($_POST['configinit']);
+ if(!Config::savejson()) {
+ echo 'Cant write config file';
+ exit;
+ } else{
+ header('Location: ./');
+ exit;
+ }
+ } else {
+ if(Config::readconfig()) {
+ if(!Config::checkcmspath() || empty(Config::admin()) || empty(Config::arttable())) {
+ echo '<ul>';
+ if(!Config::checkcmspath()) {
+ echo '<li>Wrong path</li>';
+ }
+ if(empty(Config::admin())) {
+ echo '<li>Wrong admin password</li>';
+ }
+ if(empty(Config::arttable())) {
+ echo '<li>Unset table name</li>';
+ }
+ echo '</ul>';
+ $this->configform();
+ exit;
+ }
+ } else {
+ echo 'Missing config file';
+ $this->configform();
+ exit;
+ }
+ }
+ }
+
+ public function configform()
+ {
+ ?>
+ <h1>Configuration</h1>
+ <form action="" method="post">
+ <div>
+ <h2>
+ <label for="cmspath">Path to W-CMS</label>
+ </h2>
+ <input type="text" name="configinit[cmspath]" value="<?= Config::cmspath() ?>" id="cmspath">
+ <p><i>Leave it empty if W-CMS is in your root folder, otherwise, indicate the subfolder(s) in witch you installed the CMS</i></p>
+ </div>
+ <div>
+ <div>
+ <h2>
+ <label for="admin">Admin Password</label>
+ </h2>
+ <input type="password" name="configinit[admin]" value="<?= Config::admin() ?>" id="admin" minlength="4" maxlength="64">
+ <p><i>The main password for administration, you can change it later.</i></p>
+ </div>
+ <h2>
+ <label for="arttable">Name of your database table</label>
+ </h2>
+ <input type="text" name="configinit[arttable]" value="<?= Config::arttable() ?>" id="arttable">
+ <p><i>Set the name of the first folder that is going to store all your work</i></p>
+ </div>
+ <input type="submit" value="set">
+ </form>
+
+ <?php
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/art2.php b/app/class/art2.php
new file mode 100644
index 0000000..867b17a
--- /dev/null
+++ b/app/class/art2.php
@@ -0,0 +1,618 @@
+<?php
+
+class Art2
+{
+ protected $id;
+ protected $title;
+ protected $description;
+ protected $tag;
+ protected $date;
+ protected $datecreation;
+ protected $datemodif;
+ protected $daterender;
+ protected $css;
+ protected $quickcss;
+ protected $javascript;
+ protected $html;
+ protected $header;
+ protected $section;
+ protected $nav;
+ protected $aside;
+ protected $footer;
+ protected $render;
+ protected $secure;
+ protected $invitepassword;
+ protected $interface;
+ protected $linkfrom;
+ protected $linkto;
+ protected $template;
+ protected $affcount;
+ protected $editcount;
+
+
+ const LEN = 255;
+ const LENTEXT = 20000;
+ const SECUREMAX = 2;
+ const LENCOULEUR = 7;
+ const DEBUT = '(?id=';
+ const FIN = ')';
+ const TABS = ['section', 'css', 'header', 'html', 'nav', 'aside', 'footer', 'javascript'];
+ const VAR_DATE = ['date', 'datecreation', 'datemodif', 'daterender'];
+
+
+
+
+// _____________________________________________________ F U N ____________________________________________________
+
+ public function __construct($donnees)
+ {
+ $this->hydrate($donnees);
+ }
+
+ public function hydrate($donnees)
+ {
+ foreach ($donnees as $key => $value) {
+ $method = 'set' . $key;
+
+ if (method_exists($this, $method)) {
+ $this->$method($value);
+ }
+ }
+ }
+
+ public function reset()
+ {
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+
+ $this->settitle($this->id());
+ $this->setdescription('');
+ $this->settag([]);
+ $this->setdate($now);
+ $this->setdatecreation($now);
+ $this->setdatecreation($now);
+ $this->setdatemodif($now);
+ $this->setdaterender($now);
+ $this->setcss('');
+ $this->setquickcss([]);
+ $this->setjavascript('');
+ $this->sethtml('');
+ $this->setheader('');
+ $this->setsection('');
+ $this->setnav('');
+ $this->setaside('');
+ $this->setfooter('');
+ $this->setrender('');
+ $this->setsecure(3);
+ $this->setinvitepassword('invitepassword');
+ $this->setinterface('section');
+ $this->setlinkfrom([]);
+ $this->setlinkto([]);
+ $this->settemplate([]);
+ $this->setaffcount(0);
+ $this->seteditcount(0);
+ }
+
+
+
+ public static function classvarlist()
+ {
+ $classvarlist = [];
+ foreach (get_class_vars(__class__) as $var => $default) {
+ $classvarlist[] = $var;
+ }
+ return ['artvarlist' => $classvarlist];
+ }
+
+ public function dry()
+ {
+ $array = [];
+ foreach (get_class_vars(__class__) as $var => $value) {
+ if(in_array($var, self::VAR_DATE)) {
+ $array[$var] = $this->$var('string');
+ } else {
+ $array[$var] = $this->$var();
+ }
+ }
+ return $array;
+ }
+
+
+ // _____________________________________________________ G E T ____________________________________________________
+
+ public function id($type = 'string')
+ {
+ return $this->id;
+ }
+
+ public function title($type = 'string')
+ {
+ return $this->title;
+ }
+
+ public function description($type = 'string')
+ {
+ return $this->description;
+ }
+
+ public function tag($option = 'array')
+ {
+ if ($option == 'string') {
+ return implode(", ", $this->tag);
+ } elseif ($option == 'array') {
+ return $this->tag;
+ } elseif ($option == 'sort') {
+ return count($this->tag);
+ }
+ }
+
+ public function date($option = 'date')
+ {
+ if ($option == 'string') {
+ return $this->date->format(DateTime::ISO8601);
+ } elseif ($option == 'date' || $option == 'sort') {
+ return $this->date;
+ } elseif ($option == 'hrdi') {
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+ return hrdi($this->date->diff($now));
+ }
+
+
+ }
+
+ public function datecreation($option = 'date')
+ {
+ if ($option == 'string') {
+ return $this->datecreation->format(DateTime::ISO8601);
+ } elseif ($option == 'date' || $option == 'sort') {
+ return $this->datecreation;
+ } elseif ($option == 'hrdi') {
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+ return hrdi($this->datecreation->diff($now));
+ }
+ }
+
+
+ public function datemodif($option = 'date')
+ {
+ if ($option == 'string') {
+ return $this->datemodif->format(DateTime::ISO8601);
+ } elseif ($option == 'date' || $option == 'sort') {
+ return $this->datemodif;
+ } elseif ($option == 'hrdi') {
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+ return hrdi($this->datemodif->diff($now));
+ }
+ }
+
+ public function daterender($option = 'date')
+ {
+ if ($option == 'string') {
+ return $this->daterender->format(DateTime::ISO8601);
+ } elseif ($option == 'date' || $option == 'sort') {
+ return $this->daterender;
+ } elseif ($option == 'hrdi') {
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+ return hrdi($this->daterender->diff($now));
+ }
+ }
+
+ public function css($type = 'string')
+ {
+ return $this->css;
+ }
+
+ public function quickcss($type = 'array')
+ {
+ if ($type == 'json') {
+ return json_encode($this->quickcss);
+ } elseif ($type == 'array') {
+ return $this->quickcss;
+ }
+ }
+
+
+ public function csstemplate(App $app)
+ {
+ $data = [];
+ $temp = '';
+ if (!empty($this->template())) {
+ if ($app->exist($this->template()) and !in_array($this->template(), $data)) {
+ $template = $app->get($this->template());
+ $temp = $temp . $template->css($app);
+ $data[] = $template->id();
+
+ }
+
+ }
+ $cssprint = str_replace('url(/', 'url(' . $app::MEDIA_DIR, $temp . $this->css);
+ return $cssprint;
+ }
+
+
+ public function javascript($type = 'string')
+ {
+ return $this->javascript;
+ }
+
+ public function html($type = 'string')
+ {
+ return $this->html;
+ }
+
+ public function header($type = 'string')
+ {
+ return $this->header;
+ }
+
+ public function md($expand = false)
+ {
+ if ($expand == true) {
+ $md = str_replace('](=', '](?id=', $this->section);
+ } else {
+ $md = $this->section;
+ }
+ return $md;
+ }
+
+ public function section($type = 'string')
+ {
+ return $this->section;
+ }
+
+ public function nav($type = "string")
+ {
+ return $this->nav;
+ }
+
+ public function aside($type = "string")
+ {
+ return $this->aside;
+ }
+
+ public function footer($type = "string")
+ {
+ return $this->footer;
+ }
+
+ public function render($type = 'string')
+ {
+ if($type == 'string') {
+ return $this->render;
+ }
+ }
+
+ public function secure($type = 'int')
+ {
+ if ($type == 'string') {
+ if ($this->secure == 0) $secure = 'public';
+ if ($this->secure == 1) $secure = 'private';
+ if ($this->secure == 2) $secure = 'not published';
+ return $secure;
+ } else {
+ return $this->secure;
+ }
+ }
+
+ public function invitepassword($type = 'string')
+ {
+ return $this->invitepassword;
+ }
+
+ public function interface($type = 'string')
+ {
+ return $this->interface;
+ }
+
+ public function linkfrom($option = 'array')
+ {
+ if ($option == 'json') {
+ $linkfrom = json_encode($this->linkfrom);
+ } elseif ($option == 'array') {
+ $linkfrom = $this->linkfrom;
+ } elseif ($option == 'sort') {
+ return count($this->linkfrom);
+ }
+ return $linkfrom;
+
+ }
+
+ public function linkto($option = 'array')
+ {
+ if ($option == 'json') {
+ $linkto = json_encode($this->linkto);
+ } elseif ($option == 'array') {
+ $linkto = $this->linkto;
+ } elseif ($option == 'sort') {
+ return count($this->linkto);
+ }
+ return $linkto;
+
+ }
+
+ public function template($type = 'array')
+ {
+ if ($type == 'json') {
+ return json_encode($this->template);
+ } elseif ($type = 'array') {
+ return $this->template;
+ }
+ }
+
+ public function affcount($type = 'int')
+ {
+ return $this->affcount;
+ }
+
+ public function editcount($type = 'int')
+ {
+ return $this->editcount;
+ }
+
+
+
+
+
+ // _____________________________________________________ S E T ____________________________________________________
+
+ public function setid($id)
+ {
+ if (strlen($id) < self::LEN and is_string($id)) {
+ $this->id = strip_tags(strtolower(str_replace(" ", "", $id)));
+ }
+ }
+
+ public function settitle($title)
+ {
+ if (strlen($title) < self::LEN and is_string($title)) {
+ $this->title = strip_tags(trim($title));
+ }
+ }
+
+ public function setdescription($description)
+ {
+ if (strlen($description) < self::LEN and is_string($description)) {
+ $this->description = strip_tags(trim($description));
+ }
+ }
+
+ public function settag($tag)
+ {
+ if (is_string($tag)) {
+
+ if (strlen($tag) < self::LEN and is_string($tag)) {
+ $tag = strip_tags(trim(strtolower($tag)));
+ $tag = str_replace('*', '', $tag);
+ $tag = str_replace(' ', '', $tag);
+
+ $taglist = explode(",", $tag);
+ $taglist = array_filter($taglist);
+ $this->tag = $taglist;
+ }
+ } elseif (is_array($tag)) {
+ $this->tag = $tag;
+ }
+ }
+
+ public function setdate($date)
+ {
+ if ($date instanceof DateTimeImmutable) {
+ $this->date = $date;
+ } else {
+ $this->date = DateTimeImmutable::createFromFormat(DateTime::ISO8601, $date, new DateTimeZone('Europe/Paris'));
+ }
+ }
+
+ public function setdatecreation($datecreation)
+ {
+ if ($datecreation instanceof DateTimeImmutable) {
+ $this->datecreation = $datecreation;
+ } else {
+ $this->datecreation = DateTimeImmutable::createFromFormat(DateTime::ISO8601, $datecreation, new DateTimeZone('Europe/Paris'));
+ }
+ }
+
+ public function setdatemodif($datemodif)
+ {
+ if ($datemodif instanceof DateTimeImmutable) {
+ $this->datemodif = $datemodif;
+ } else {
+ $this->datemodif = DateTimeImmutable::createFromFormat(DateTime::ISO8601, $datemodif, new DateTimeZone('Europe/Paris'));
+ }
+ }
+
+ public function setdaterender($daterender)
+ {
+ if ($daterender instanceof DateTimeImmutable) {
+ $this->daterender = $daterender;
+ } else {
+ $this->daterender = DateTimeImmutable::createFromFormat(DateTime::ISO8601, $daterender, new DateTimeZone('Europe/Paris'));
+ }
+ }
+
+
+ public function setcss($css)
+ {
+ if (strlen($css) < self::LENTEXT and is_string($css)) {
+ $this->css = strip_tags(trim(strtolower($css)));
+ }
+ }
+
+
+ public function setquickcss($quickcss)
+ {
+ if (is_string($quickcss)) {
+ $quickcss = json_decode($quickcss, true);
+ }
+ if (is_array($quickcss)) {
+ $this->quickcss = $quickcss;
+ }
+ }
+
+ public function setjavascript($javascript)
+ {
+ if (strlen($javascript < self::LENTEXT && is_string($javascript))) {
+ $this->javascript = $javascript;
+ }
+ }
+
+
+ public function sethtml($html)
+ {
+ if (strlen($html < self::LENTEXT && is_string($html))) {
+ $this->html = $html;
+ }
+ }
+
+ public function setheader($header)
+ {
+ if (strlen($header < self::LENTEXT && is_string($header))) {
+ $this->header = $header;
+ }
+ }
+
+ public function setsection($section)
+ {
+ if (strlen($section) < self::LENTEXT and is_string($section)) {
+ $this->section = $section;
+ }
+ }
+
+ public function setnav($nav)
+ {
+ if (strlen($nav) < self::LENTEXT and is_string($nav)) {
+ $this->nav = $nav;
+ }
+ }
+
+ public function setaside($aside)
+ {
+ if (strlen($aside) < self::LENTEXT and is_string($aside)) {
+ $this->aside = $aside;
+ }
+ }
+
+ public function setfooter($footer)
+ {
+ if (strlen($footer) < self::LENTEXT and is_string($footer)) {
+ $this->footer = $footer;
+ }
+ }
+
+ public function setrender(string $render)
+ {
+ $this->render = $render;
+ }
+
+ public function setsecure($secure)
+ {
+ if ($secure >= 0 and $secure <= self::SECUREMAX) {
+ $this->secure = intval($secure);
+ }
+ }
+
+ public function setinvitepassword($invitepassword)
+ {
+ if (is_string($invitepassword) && strlen($invitepassword) < self::LEN) {
+ $this->invitepassword = $invitepassword;
+ }
+ }
+
+ public function setinterface($interface)
+ {
+ if (in_array($interface, self::TABS)) {
+ $this->interface = $interface;
+ }
+ }
+
+ public function setlinkfrom($linkfrom)
+ {
+ if(is_array($linkfrom)) {
+ $this->linkfrom = $linkfrom;
+ } elseif(is_string($linkfrom)) {
+ $linkfromjson = json_decode($linkfrom);
+ if(is_array($linkfromjson)) {
+ $this->linkfrom = $linkfromjson;
+ }
+ } elseif ($linkfrom === null) {
+ $this->linkfrom = [];
+ }
+ }
+
+ public function setlinkto($linkto)
+ {
+ if(is_array($linkto)) {
+ $this->linkto = $linkto;
+ } elseif(is_string($linkto)) {
+ $linktojson = json_decode($linkto);
+ if(is_array($linktojson)) {
+ $this->linkto = $linktojson;
+ }
+ } elseif ($linkto === null) {
+ $this->linkto = [];
+ }
+ }
+
+ public function settemplate($template)
+ {
+ if (is_string($template)) {
+ $templatearray = json_decode($template, true);
+ }
+ if (is_array($template)) {
+ $templatearray = $template;
+ }
+ if(is_object($template)) {
+ $templatearray = (array) $template;
+ }
+ $this->template = array_map(function ($value) {
+ if(empty($value)) {
+ return null;
+ } else {
+ return $value;
+ }
+ }, $templatearray);
+ }
+
+ public function setaffcount($affcount)
+ {
+ if (is_int($affcount)) {
+ $this->affcount = $affcount;
+ } elseif (is_numeric($affcount)) {
+ $this->affcount = intval($affcount);
+ }
+ }
+
+ public function seteditcount($editcount)
+ {
+ if (is_int($editcount)) {
+ $this->editcount = $editcount;
+ } elseif (is_numeric($editcount)) {
+ $this->editcount = intval($editcount);
+ }
+ }
+
+
+ // __________________________________ C O U N T E R S ______________________________
+
+
+ public function addeditcount()
+ {
+ $this->editcount ++;
+ }
+
+ public function addaffcount()
+ {
+ $this->affcount ++;
+ }
+
+ public function updateedited()
+ {
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+ $this->setdatemodif($now);
+ $this->addeditcount();
+ }
+
+
+}
+
+
+?> \ No newline at end of file
diff --git a/app/class/backrouter.php b/app/class/backrouter.php
new file mode 100644
index 0000000..bcd1202
--- /dev/null
+++ b/app/class/backrouter.php
@@ -0,0 +1,74 @@
+<?php
+
+
+class Backrouter
+{
+ protected $route;
+
+ const ROUTES = [
+ 'art' => ['art', 'read'],
+ 'art aff=read' => ['art', 'read'],
+ 'art aff=edit' => ['art', 'edit'],
+ 'art aff=log' => ['art', 'log'],
+ 'art action=update' => ['art', 'update'],
+ 'art action=update home' => ['art', 'update', 'home'],
+ 'art action=add' => ['art', 'add'],
+ 'art action=delete' => ['art', 'delete'],
+ 'aff=home action=massedit',
+ 'aff=home' => ['home', 'desktop'],
+ '' => ['home', 'desktop'],
+ 'aff=home action=massedit' => ['home', 'massedit'],
+ 'action=massedit' => ['home', 'massedit'],
+ 'action=analyseall' => ['home', 'analyseall'],
+ 'aff=home action=analyseall' => ['home', 'analyseall'],
+ 'art action=login' => ['art', 'login', 'art'],
+ 'home action=login' => ['home', 'login', 'home'],
+ 'action=login' => ['home', 'login'],
+ 'art action=logout' => ['art', 'logout', 'art'],
+ 'home action=logout' => ['home', 'logout', 'home'],
+ 'action=logout' => ['home', 'logout'],
+ 'aff=db' => ['db', 'desktop'],
+ 'aff=db action=add' => ['db', 'add'],
+ 'aff=media' => ['media', 'desktop'],
+ 'aff=media action=addmedia' => ['media', 'addmedia'],
+ 'aff=admin' => ['admin', 'desktop'],
+ 'aff=co' => ['connect', 'desktop'],
+ ];
+
+ public function run() {
+ if($this->matchroute()) {
+ $this->callmethod();
+ } else {
+ echo '<h1>404 Error</h1>';
+ }
+ }
+
+ public function matchroute()
+ {
+ $this->route = new route($_GET);
+ $match = array_key_exists($this->route->tostring(), self::ROUTES);
+ return $match;
+
+ }
+
+ public function callmethod()
+ {
+ $method = self::ROUTES[$this->route->tostring()];
+
+ $class = 'controller' . $method[0];
+ $function = $method[1];
+ $controller = new $class($this->route->id());
+ $params = array_slice($method, 2);
+ $controller->$function(...$params);
+ }
+
+
+
+}
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/config.php b/app/class/config.php
new file mode 100644
index 0000000..7f18166
--- /dev/null
+++ b/app/class/config.php
@@ -0,0 +1,186 @@
+<?php
+
+
+
+abstract class Config
+{
+ protected static $arttable = 'artstore';
+ protected static $domain;
+ protected static $admin;
+ protected static $editor;
+ protected static $invite;
+ protected static $read;
+ protected static $color4;
+ protected static $fontsize = 6;
+ protected static $cmspath = '';
+
+
+// _______________________________________ F U N _______________________________________
+
+
+
+ public static function hydrate(array $datas)
+ {
+ foreach ($datas as $key => $value) {
+ $method = 'set' . $key;
+ if (method_exists(get_called_class(), $method)) {
+ self::$method($value);
+ }
+ }
+ }
+
+ public static function readconfig()
+ {
+ if (file_exists(Model::CONFIG_FILE)) {
+ $current = file_get_contents(Model::CONFIG_FILE);
+ $datas = json_decode($current, true);
+ self::hydrate($datas);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static function createconfig(array $datas)
+ {
+ self::hydrate($datas);
+ }
+
+
+ public static function savejson()
+ {
+ $json = self::tojson();
+ return file_put_contents(Model::CONFIG_FILE, $json);
+ }
+
+
+ public static function tojson()
+ {
+ $arr = get_class_vars(__class__);
+ $json = json_encode($arr, JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
+ return $json;
+ }
+
+ public static function checkcmspath()
+ {
+ $path = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . self::cmspath() . 'w' . DIRECTORY_SEPARATOR . 'w.config.json';
+ return (file_exists($path));
+ }
+
+// ________________________________________ G E T _______________________________________
+
+ public static function arttable()
+ {
+ return self::$arttable;
+ }
+
+ public static function domain()
+ {
+ return self::$domain;
+ }
+
+ public static function admin()
+ {
+ return self::$admin;
+ }
+
+ public static function editor()
+ {
+ return self::$editor;
+ }
+
+ public static function invite()
+ {
+ return self::$invite;
+ }
+
+ public static function read()
+ {
+ return self::$read;
+ }
+
+ public static function color4()
+ {
+ return self::$color4;
+ }
+
+ public static function fontsize()
+ {
+ return self::$fontsize;
+ }
+
+ public static function cmspath()
+ {
+ return self::$cmspath;
+ }
+
+
+
+// __________________________________________ S E T ______________________________________
+
+ public static function setarttable($arttable)
+ {
+ self::$arttable = strip_tags($arttable);
+ }
+
+ public static function setdomain($domain)
+ {
+ self::$domain = strip_tags($domain);
+ }
+
+ public static function setadmin($admin)
+ {
+ if(is_string($admin) && strlen($admin) >= 4 && strlen($admin) <= 64) {
+ self::$admin = strip_tags($admin);
+ }
+ }
+
+ public static function seteditor($editor)
+ {
+ self::$editor = strip_tags($editor);
+ }
+
+ public static function setinvite($invite)
+ {
+ self::$invite = strip_tags($invite);
+ }
+
+ public static function setread($read)
+ {
+ self::$read = strip_tags($read);
+ }
+
+ public static function setcolor4($color4)
+ {
+ if (strlen($color4) <= 8) {
+ self::$color4 = $color4;
+ }
+ }
+
+ public static function setfontsize($fontsize)
+ {
+ $fontsize = intval($fontsize);
+ if ($fontsize > 1) {
+ self::$fontsize = $fontsize;
+ }
+ }
+
+ public static function setcmspath($cmspath)
+ {
+ self::$cmspath = strip_tags($cmspath);
+ }
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/configtest.php b/app/class/configtest.php
new file mode 100644
index 0000000..cd72753
--- /dev/null
+++ b/app/class/configtest.php
@@ -0,0 +1,22 @@
+<?php
+
+abstract class Configtest
+{
+ protected static $info;
+
+ public static function setinfo($info)
+ {
+ self::$info = $info;
+ }
+
+ public static function info()
+ {
+ return self::$info;
+ }
+}
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/controller.php b/app/class/controller.php
new file mode 100644
index 0000000..c97c99f
--- /dev/null
+++ b/app/class/controller.php
@@ -0,0 +1,96 @@
+<?php
+
+class Controller
+{
+
+ protected $user;
+ protected $usermanager;
+ protected $plates;
+
+ public function __construct() {
+ $this->setuser();
+ $this->initplates();
+ $this->initconfig();
+ }
+
+ public function setuser()
+ {
+ $this->usermanager = new Modeluser;
+ $this->user = $this->usermanager->readsession();
+ }
+
+ public function initplates()
+ {
+ $this->plates = new League\Plates\Engine(Model::TEMPLATES_DIR);
+ }
+
+ public function useriseditor()
+ {
+ if ($this->user->level() >= $this->usermanager::EDITOR) {
+ echo '<h3>Editor access</h3>';
+ return true;
+ } else {
+ echo '<h3>Not enought rights to see more...</h3>';
+ return false;
+ }
+ }
+
+ public function initconfig()
+ {
+ Config::readconfig();
+ }
+
+ public function showtemplate($template, $params)
+ {
+ $params = array_merge($this->commonsparams(), $params);
+ echo $this->plates->render($template, $params);
+ }
+
+ public function commonsparams()
+ {
+ $commonsparams = [];
+ $commonsparams['user'] = $this->user;
+ return $commonsparams;
+ }
+
+ public function login($redirect = 'home')
+ {
+ if(isset($_POST['pass'])) {
+ $this->user = $this->usermanager->login($_POST['pass']);
+ $this->usermanager->writesession($this->user);
+ }
+ if($redirect == 'art') {
+ $this->redirect('?id=' . $this->art->id());
+ } else {
+ $this->redirect('?aff=' . $redirect);
+ }
+ }
+
+ public function logout($redirect = 'home')
+ {
+ $this->user = $this->usermanager->logout();
+ $this->usermanager->writesession($this->user);
+ if($redirect == 'art') {
+ $this->redirect('?id=' . $this->art->id());
+ } else {
+ $this->redirect('?aff=' . $redirect);
+ }
+ }
+
+
+
+
+ public function redirect($url)
+ {
+ header('Location: ' . $url);
+ }
+
+
+
+}
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/controlleradmin.php b/app/class/controlleradmin.php
new file mode 100644
index 0000000..42a0f65
--- /dev/null
+++ b/app/class/controlleradmin.php
@@ -0,0 +1,28 @@
+<?php
+
+class Controlleradmin extends Controllerdb
+{
+
+ public function desktop()
+ {
+ echo '<h1>Admin</h1>';
+ }
+
+ public function addtable()
+ {
+
+ }
+
+
+
+ public function duplicatetable()
+ {
+
+ }
+
+}
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/controllerart.php b/app/class/controllerart.php
new file mode 100644
index 0000000..334f550
--- /dev/null
+++ b/app/class/controllerart.php
@@ -0,0 +1,159 @@
+<?php
+
+class Controllerart extends Controllerdb
+{
+ /** @var Art2 */
+ protected $art;
+ protected $artmanager;
+ protected $renderengine;
+
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->artmanager = new Modelart();
+ $this->renderengine = new Modelrender();
+
+ }
+
+ public function setart($id)
+ {
+ $this->art = new Art2(['id' => $id]);
+ }
+
+ public function importart()
+ {
+ $art = $this->artmanager->get($this->art);
+ if ($art !== false) {
+ $this->art = $art;
+ //$this->art->autotaglistupdate($this->artmanager->taglist($this->artmanager->getlister(['id', 'title', 'description', 'tag']), $this->art->autotaglist()));
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function read($id)
+ {
+ $this->setart($id);
+ $now = new DateTimeImmutable(null, timezone_open("Europe/Paris"));
+
+
+ $artexist = $this->importart();
+ $canread = $this->user->level() >= $this->art->secure();
+ $cancreate = $this->user->cancreate();
+ $alerts = ['alertnotexist' => 'This page does not exist yet', 'alertprivate' => 'You cannot see this page'];
+ $body = '';
+ $head = '';
+
+
+
+ if ($artexist) {
+
+ if ($this->art->daterender() < $this->art->datemodif()) {
+ $body = $this->renderengine->renderbody($this->art);
+ $this->art->setrender($body);
+ $this->art->setdaterender($now);
+ $this->artmanager->update($this->art);
+ } else {
+ $body = $this->art->render();
+ }
+
+ $head = $this->renderengine->renderhead($this->art);
+
+ $this->art->addaffcount();
+ $this->artmanager->update($this->art);
+
+ }
+
+
+ $data = array_merge($alerts, ['art' => $this->art, 'artexist' => $artexist, 'canread' => $canread, 'cancreate' => $cancreate, 'readernav' => true, 'body' => $body, 'head' => $head]);
+
+
+ $this->showtemplate('read', $data);
+
+
+
+ }
+
+ public function edit($id)
+ {
+ $this->setart($id);
+
+
+ if ($this->importart() && $this->user->canedit()) {
+ $tablist = ['section' => $this->art->md(), 'css' => $this->art->css(), 'header' => $this->art->header(), 'nav' => $this->art->nav(), 'aside' => $this->art->aside(), 'footer' => $this->art->footer(), 'html' => $this->art->html(), 'javascript' => $this->art->javascript()];
+
+ $artlist = $this->artmanager->list();
+
+ if(isset($_SESSION['workspace'])) {
+ $showleftpanel = $_SESSION['workspace']['showleftpanel'];
+ $showrightpanel = $_SESSION['workspace']['showrightpanel'];
+ } else {
+ $showleftpanel = false;
+ $showrightpanel = false;
+ }
+
+
+ $this->showtemplate('edit', ['art' => $this->art, 'artexist' => true, 'tablist' => $tablist, 'artlist' => $artlist, 'showleftpanel' => $showleftpanel, 'showrightpanel' => $showrightpanel]);
+ } else {
+ $this->redirect('?id=' . $this->art->id());
+ }
+
+ }
+
+ public function log($id)
+ {
+ $this->setart($id);
+ $this->importart();
+ var_dump($this->art);
+ }
+
+ public function add($id)
+ {
+ $this->setart($id);
+ $this->art->reset();
+ $this->artmanager->add($this->art);
+ $this->redirect('?id=' . $this->art->id() . '&aff=edit');
+ }
+
+ public function delete($id)
+ {
+ $this->setart($id);
+ if ($this->user->canedit() && $this->importart()) {
+
+ if (isset($_POST['deleteconfirm']) && $_POST['deleteconfirm'] == true) {
+ $this->artmanager->delete($this->art);
+ $this->redirect('?id=' . $this->art->id());
+ } else {
+ $this->showtemplate('delete', ['art' => $this->art, 'artexist' => true]);
+ }
+ } else {
+ $this->redirect('?id=' . $this->art->id());
+ }
+ }
+
+ public function update($id)
+ {
+ $this->setart($id);
+ $_SESSION['workspace']['showrightpanel'] = isset($_POST['workspace']['showrightpanel']);
+ $_SESSION['workspace']['showleftpanel'] = isset($_POST['workspace']['showleftpanel']);
+
+ if ($this->importart() && $this->user->canedit()) {
+ $this->art->hydrate($_POST);
+ $this->art->updateedited();
+ $this->artmanager->update($this->art);
+
+ }
+
+ $this->redirect('?id=' . $this->art->id() . '&aff=edit');
+
+
+
+ }
+}
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/controllerconnect.php b/app/class/controllerconnect.php
new file mode 100644
index 0000000..2bda1b0
--- /dev/null
+++ b/app/class/controllerconnect.php
@@ -0,0 +1,18 @@
+<?php
+
+class Controllerconnect extends Controller
+{
+
+ public function desktop()
+ {
+ $this->showtemplate('connect', ['user' => $this->user]);
+ }
+
+}
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/controllerdb.php b/app/class/controllerdb.php
new file mode 100644
index 0000000..54a9de1
--- /dev/null
+++ b/app/class/controllerdb.php
@@ -0,0 +1,45 @@
+<?php
+
+class Controllerdb extends Controller
+{
+
+ protected $artmanager;
+ protected $database;
+ protected $artstore;
+
+
+ public function __construct()
+ {
+ parent::__construct();
+
+
+ }
+
+
+
+
+ // if (isset($_POST['actiondb'])) {
+ // $app->setbdd($config);
+
+ // switch ($_POST['actiondb']) {
+
+ // case 'addtable':
+ // if (isset($_POST['tablename'])) {
+ // $message = Modeldb::addtable($config->dbname(), $_POST['tablename']);
+ // header('Location: ./?aff=admin&message=' . $message);
+ // }
+ // break;
+
+ // case 'duplicatetable':
+ // $message = Modeldb::tableduplicate($config->dbname(), $_POST['arttable'], $_POST['tablename']);
+ // header('Location: ./?aff=admin&message=' . $message);
+ // break;
+
+ // }
+ // }
+}
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/controllerhome.php b/app/class/controllerhome.php
new file mode 100644
index 0000000..31d27c3
--- /dev/null
+++ b/app/class/controllerhome.php
@@ -0,0 +1,66 @@
+<?php
+
+class Controllerhome extends Controllerdb
+{
+
+ protected $modelhome;
+ protected $opt;
+
+ public function __construct() {
+ parent::__construct();
+ $this->modelhome = new Modelhome;
+ }
+
+
+
+
+ public function desktop()
+ {
+
+ $this->table2();
+ }
+
+ public function table2()
+ {
+ $table = $this->modelhome->getlister();
+ $this->opt = $this->modelhome->optinit($table);
+
+ $table2 = $this->modelhome->table2($table, $this->opt);
+
+ $this->showtemplate('home', ['user' => $this->user, 'table2' => $table2, 'opt' =>$this->opt]);
+
+
+ }
+
+ public function analyseall()
+ {
+ if($this->user->level() >= Modeluser::EDITOR) {
+ $scan = new Modelanalyse;
+ $scan->analyseall();
+ $this->redirect('./');
+
+ }
+ }
+
+ public function massedit()
+ {
+ echo '<h2>Mass Edit</h2>';
+
+ }
+
+
+
+
+
+
+
+}
+
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/controllermedia.php b/app/class/controllermedia.php
new file mode 100644
index 0000000..6bd22cd
--- /dev/null
+++ b/app/class/controllermedia.php
@@ -0,0 +1,37 @@
+<?php
+
+class Controllermedia extends Controller
+{
+ protected $medialist;
+ protected $mediamanager;
+
+ public function __construct() {
+ parent::__construct();
+
+ $this->mediamanager = new Modelmedia;
+
+ }
+
+ public function desktop()
+ {
+
+ if($this->useriseditor()) {
+
+
+
+ }
+ }
+
+ public function addmedia()
+ {
+ echo $this->templates->render('media', ['interface' => 'addmedia']);
+
+ //$message = $this->mediamanager->addmedia($_FILES, 2 ** 24, $_POST['id']);
+
+ }
+
+
+}
+
+
+?> \ No newline at end of file
diff --git a/app/class/launcher.php b/app/class/launcher.php
new file mode 100644
index 0000000..de97462
--- /dev/null
+++ b/app/class/launcher.php
@@ -0,0 +1,20 @@
+<?php
+
+class Launcher
+{
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/media.php b/app/class/media.php
new file mode 100644
index 0000000..2d27be7
--- /dev/null
+++ b/app/class/media.php
@@ -0,0 +1,173 @@
+<?php
+
+class Media
+{
+ private $id;
+ private $path;
+ private $extension;
+ private $type;
+ private $size;
+ private $width;
+ private $height;
+ private $length;
+
+ const IMAGE = array('jpg', 'jpeg', 'gif', 'png');
+ const SOUND = array('mp3', 'flac');
+ const VIDEO = array('mp4', 'mov', 'avi');
+
+
+
+// _____________________________________________________ F U N ____________________________________________________
+
+ public function __construct(array $donnees)
+ {
+ $this->hydrate($donnees);
+ }
+
+ public function hydrate(array $donnees)
+ {
+ foreach ($donnees as $key => $value) {
+ $method = 'set' . $key;
+
+ if (method_exists($this, $method)) {
+ $this->$method($value);
+ }
+ }
+ }
+
+
+ public function analyse()
+ {
+ $this->settype();
+
+ $filepath = $this->path . $this->id . '.' . $this->extension;
+
+ $this->size = filesize($filepath);
+
+ if ($this->type == 'image') {
+ list($width, $height, $type, $attr) = getimagesize($filepath);
+ $this->width = $width;
+ $this->height = $height;
+ }
+
+
+ }
+
+
+
+// _________________________________________________ G E T ____________________________________________________
+
+ public function id()
+ {
+ return $this->id;
+ }
+
+ public function path()
+ {
+ return $this->path;
+ }
+
+ public function extension()
+ {
+ return $this->extension;
+ }
+
+ public function type()
+ {
+ return $this->type;
+ }
+
+ public function size()
+ {
+ return $this->size;
+ }
+
+ public function width()
+ {
+ return $this->width;
+ }
+
+ public function height()
+ {
+ return $this->height;
+ }
+
+ public function length()
+ {
+ return $this->length;
+ }
+
+// ___________________________________________________ S E T __________________________________________________
+
+ public function setid($id)
+ {
+ if (strlen($id) < 40 and is_string($id)) {
+ $this->id = strip_tags(strtolower($id));
+ }
+ }
+
+ public function setpath($path)
+ {
+ if (strlen($path) < 40 and is_string($path)) {
+ $this->path = strip_tags(strtolower($path));
+ }
+ }
+
+ public function setextension($extension)
+ {
+ if (strlen($extension) < 7 and is_string($extension)) {
+ $this->extension = strip_tags(strtolower($extension));
+ }
+ }
+
+ public function settype()
+ {
+ if (isset($this->extension)) {
+ if (in_array($this->extension, $this::IMAGE)) {
+ $this->type = "image";
+ } elseif (in_array($this->extension, $this::SOUND)) {
+ $this->type = "sound";
+ } elseif (in_array($this->extension, $this::VIDEO)) {
+ $this->type = "video";
+ } else {
+ $this->type = "other";
+ }
+ }
+ }
+
+ public function setsize($size)
+ {
+ if (40 and is_int($size)) {
+ $this->size = strip_tags(strtolower($size));
+ }
+ }
+
+ public function setwidth($width)
+ {
+ if (is_int($width)) {
+ $this->width = strip_tags(strtolower($width));
+ }
+ }
+
+ public function setheight($height)
+ {
+ if (is_int($height)) {
+ $this->height = strip_tags(strtolower($height));
+ }
+ }
+
+ public function setlength($length)
+ {
+ if ($this->type == 'sound') {
+ $this->length = $length;
+ }
+ }
+
+
+
+
+
+
+}
+
+?> \ No newline at end of file
diff --git a/app/class/model.php b/app/class/model.php
new file mode 100644
index 0000000..d037aba
--- /dev/null
+++ b/app/class/model.php
@@ -0,0 +1,17 @@
+<?php
+class Model
+{
+
+ const CONFIG_FILE = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'w.config.json';
+ const GLOBAL_CSS_DIR = '.' . DIRECTORY_SEPARATOR . 'css' . DIRECTORY_SEPARATOR . 'global' . DIRECTORY_SEPARATOR . 'global.css';
+ const MEDIA_DIR = '.' . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR;
+ const TEMPLATES_DIR = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'templates';
+ const RENDER_DIR = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '/w_render/';
+ const MEDIA_EXTENSIONS = array('jpeg', 'jpg', 'JPG', 'png', 'gif', 'mp3', 'mp4', 'mov', 'wav', 'flac', 'pdf');
+ const MEDIA_TYPES = ['image', 'video', 'sound', 'other'];
+
+ const TEXT_ELEMENTS = ['header', 'nav', 'section', 'aside', 'footer'];
+
+
+
+}
diff --git a/app/class/modelanalyse.php b/app/class/modelanalyse.php
new file mode 100644
index 0000000..379c41a
--- /dev/null
+++ b/app/class/modelanalyse.php
@@ -0,0 +1,73 @@
+<?php
+
+
+
+class Modelanalyse extends Modelart
+{
+
+
+ public function __construct() {
+ parent::__construct();
+ }
+
+ public function analyseall()
+ {
+ $artlist = $this->getlister();
+
+ $artlist2 = [];
+ foreach ($artlist as $art) {
+ $art->setlinkfrom($this->analyselinkfrom($art));
+ $artlist2[] = $art;
+ }
+ foreach ($artlist2 as $art) {
+ $art->setlinkto($this->analyselinkto($art->id(), $artlist));
+ $this->update($art);
+ }
+ }
+
+
+ public function analyse(Art2 $art)
+ {
+ $art->setlinkfrom($this->analyselinkfrom($art));
+
+ $artlist = $this->getlister();
+ $art->setlinkto($this->analyselinkto($art->id(), $artlist));
+
+ return $art;
+ }
+
+
+
+
+ public function analyselinkto($id, $artlist)
+ {
+ //analyse les liens vers cet article en fouillant tout les linkfrom de la bdd, génere un tableau à stocker dans l'article
+ $linkto = [];
+ foreach ($artlist as $link) {
+ if (in_array($id, $link->linkfrom('array')) && $id != $link->id()) {
+ $linkto[] = $link->id();
+ }
+ }
+ return $linkto;
+ }
+
+ public function analyselinkfrom(Art2 $art)
+ {
+ $linkfrom = [];
+ foreach (self::TEXT_ELEMENTS as $element) {
+ preg_match_all('#\]\((\?id=|=)(\w+)\)#', $art->$element(), $out);
+ $linkfrom = array_merge($linkfrom, $out[2]);
+ }
+ return array_unique($linkfrom);
+
+ }
+
+}
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/modelart.php b/app/class/modelart.php
new file mode 100644
index 0000000..ef4d61d
--- /dev/null
+++ b/app/class/modelart.php
@@ -0,0 +1,178 @@
+<?php
+class Modelart extends Modeldb
+{
+
+ const SELECT = ['title', 'id', 'description', 'tag', 'date', 'datecreation', 'datemodif', 'daterender', 'css', 'quickcss', 'javascript', 'html', 'header', 'section', 'nav', 'aside', 'footer', 'render', 'secure', 'invitepassword', 'interface', 'linkfrom', 'linkto', 'template', 'affcount', 'editcount'];
+ const BY = ['datecreation', 'title', 'id', 'description', 'datemodif', 'secure'];
+ const ORDER = ['DESC', 'ASC'];
+
+
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+
+
+ public function exist(Art2 $art)
+ {
+ $artdata = $this->artstore->get($art->id());
+ if($artdata === false) {
+ return false;
+ } else {
+ return true;
+ }
+
+ }
+
+
+ public function add(Art2 $art)
+ {
+
+ $artdata = new \JamesMoss\Flywheel\Document($art->dry());
+ $artdata->setId($art->id());
+ $this->artstore->store($artdata);
+ }
+
+ public function get($id)
+ {
+ if($id instanceof Art2) {
+ $id = $id->id();
+ }
+ if(is_string($id)) {
+ $artdata = $this->artstore->findById($id);
+ if($artdata !== false) {
+ return new Art2($artdata);
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public function delete(Art2 $art)
+ {
+ $this->artstore->delete($art->id());
+ }
+
+ public function update(Art2 $art)
+ {
+ $artdata = new \JamesMoss\Flywheel\Document($art->dry());
+ $artdata->setId($art->id());
+ $this->artstore->store($artdata);
+ }
+
+ public function getlisteropt(Opt $opt)
+ {
+
+ $artlist = [];
+
+ $select = 'SELECT ' . $opt->col('string') . ' FROM ' . Config::arttable();
+ $req = $this->bdd->query($select);
+ while ($donnees = $req->fetch(PDO::FETCH_ASSOC)) {
+ $artlist[] = new Art2($donnees);
+ }
+ return $artlist;
+
+ }
+
+ public function artcompare($art1, $art2, $method = 'id', $order = 1)
+ {
+ $result = ($art1->$method('sort') <=> $art2->$method('sort'));
+ return $result * $order;
+
+ }
+
+ public function buildsorter($sortby, $order)
+ {
+ return function ($art1, $art2) use ($sortby, $order) {
+ $result = $this->artcompare($art1, $art2, $sortby, $order);
+ return $result;
+ };
+ }
+
+
+
+ public function artlistsort(&$artlist, $sortby, $order = 1)
+ {
+ return usort($artlist, $this->buildsorter($sortby, $order));
+ }
+
+
+
+
+
+
+ public function filtertagfilter(array $artlist, array $tagchecked, $tagcompare = 'OR')
+ {
+
+ $filteredlist = [];
+ foreach ($artlist as $art) {
+ if (empty($tagchecked)) {
+ $filteredlist[] = $art->id();
+ } else {
+ $inter = (array_intersect($art->tag('array'), $tagchecked));
+ if ($tagcompare == 'OR') {
+ if (!empty($inter)) {
+ $filteredlist[] = $art->id();
+ }
+ } elseif ($tagcompare == 'AND') {
+ if (!array_diff($tagchecked, $art->tag('array'))) {
+ $filteredlist[] = $art->id();
+ }
+ }
+ }
+ }
+ return $filteredlist;
+ }
+
+ public function filtersecure(array $artlist, $secure)
+ {
+ $filteredlist = [];
+ foreach ($artlist as $art) {
+ if ($art->secure() == intval($secure)) {
+ $filteredlist[] = $art->id();
+ } elseif (intval($secure) >= 4) {
+ $filteredlist[] = $art->id();
+ }
+ }
+ return $filteredlist;
+ }
+
+
+ public function lister()
+ {
+ $req = $this->bdd->query(' SELECT * FROM ' . Config::arttable() . ' ORDER BY id ');
+ $donnees = $req->fetchAll(PDO::FETCH_ASSOC);
+ $req->closeCursor();
+ return $donnees;
+
+ }
+
+ public function tag(array $artlist, $tagchecked)
+ {
+ $artcheckedlist = [];
+ foreach ($artlist as $art) {
+ if (in_array($tagchecked, $art->tag('array'))) {
+ $artcheckedlist[] = $art;
+ }
+ }
+ return $artcheckedlist;
+ }
+
+ public function taglist(array $artlist, array $tagcheckedlist)
+ {
+ $taglist = [];
+ foreach ($tagcheckedlist as $tag) {
+ $taglist[$tag] = $this->tag($artlist, $tag);
+ }
+ return $taglist;
+ }
+
+ public function count()
+ {
+ return $this->bdd->query(' SELECT COUNT(*) FROM ' . $this->arttable . ' ')->fetchColumn();
+ }
+
+}
diff --git a/app/class/modelconfig.php b/app/class/modelconfig.php
new file mode 100644
index 0000000..7c5fc18
--- /dev/null
+++ b/app/class/modelconfig.php
@@ -0,0 +1,39 @@
+<?php
+
+abstract class Modelconfig extends Model
+{
+ public static function readconfig()
+ {
+ if (file_exists(self::CONFIG_FILE)) {
+ $current = file_get_contents(self::CONFIG_FILE);
+ $donnees = json_decode($current, true);
+ return new Config($donnees);
+ } else {
+ return 0;
+ }
+
+ }
+
+ public static function createconfig(array $donnees)
+ {
+ return new Config($donnees);
+ }
+
+
+ public static function savejson(string $json)
+ {
+ file_put_contents(self::CONFIG_FILE, $json);
+ }
+
+
+
+
+}
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/modeldb.php b/app/class/modeldb.php
new file mode 100644
index 0000000..a5ebf6f
--- /dev/null
+++ b/app/class/modeldb.php
@@ -0,0 +1,54 @@
+<?php
+class Modeldb extends Model
+{
+ /** @var PDO */
+ protected $bdd;
+ protected $arttable;
+ protected $database;
+ protected $artstore;
+
+
+ public function __construct()
+ {
+ $this->dbinit();
+ }
+
+
+ public function dbinit()
+ {
+ $this->database = new \JamesMoss\Flywheel\Config(__DIR__ .'/../../w_database');
+ $this->artstore = new \JamesMoss\Flywheel\Repository(Config::arttable(), $this->database);
+ }
+
+
+ public function getlister()
+ {
+ $artlist = [];
+ $list = $this->artstore->findAll();
+ foreach ($list as $artdata) {
+ $artlist[$artdata->id] = new Art2($artdata);
+ }
+ return $artlist;
+ }
+
+ public function list()
+ {
+ return $this->artstore->getAllIds();
+ }
+
+ public function getlisterid(array $idlist = [])
+ {
+ $artdatalist = $this->artstore->query()
+ ->where('__id', 'IN', $idlist)
+ ->execute();
+
+ $artlist = [];
+ foreach ($artdatalist as $id => $artdata) {
+ $artlist[$id] = new Art2($artdata);
+ }
+ return $artlist;
+ }
+
+
+
+}
diff --git a/app/class/modelhome.php b/app/class/modelhome.php
new file mode 100644
index 0000000..3ff72c7
--- /dev/null
+++ b/app/class/modelhome.php
@@ -0,0 +1,70 @@
+<?php
+
+class Modelhome extends Modeldb
+{
+
+ public function __construct() {
+ parent::__construct();
+ }
+
+ public function optinit($table)
+ {
+
+ $opt = new Opt(Art2::classvarlist());
+ $opt->setcol(['id', 'tag', 'linkfrom', 'linkto', 'description', 'title', 'datemodif', 'datecreation', 'secure']);
+ //$table = $listmanager->getlisteropt($opt);
+ //$listmanager->listcalclinkfrom($table);
+ $opt->settaglist($table);
+ $opt->submit();
+
+
+
+ return $opt;
+ }
+
+ public function optupdate()
+ {
+
+ }
+
+
+ public function table2($table, $opt)
+ {
+ $listmanager = new Modelart;
+
+
+ $filtertagfilter = $listmanager->filtertagfilter($table, $opt->tagfilter(), $opt->tagcompare());
+ $filtersecure = $listmanager->filtersecure($table, $opt->secure());
+
+ $filter = array_intersect($filtertagfilter, $filtersecure);
+ $table2 = [];
+ $table2invert = [];
+ foreach ($table as $art) {
+ if (in_array($art->id(), $filter)) {
+ $table2[] = $art;
+ } else {
+ $table2invert[] = $art;
+ }
+
+
+ }
+
+ if (!empty($opt->invert())) {
+ $table2 = $table2invert;
+ }
+
+ $listmanager->artlistsort($table2, $opt->sortby(), $opt->order());
+
+
+ return $table2;
+ }
+}
+
+
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/modelmassedit.php b/app/class/modelmassedit.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/class/modelmassedit.php
diff --git a/app/class/modelmedia.php b/app/class/modelmedia.php
new file mode 100644
index 0000000..14a1c4e
--- /dev/null
+++ b/app/class/modelmedia.php
@@ -0,0 +1,95 @@
+<?php
+
+class Modelmedia extends Model
+{
+
+ public function addmedia(array $file, $maxsize = 2 ** 24, $id)
+ {
+ $message = 'runing';
+ $id = strtolower(strip_tags($id));
+ $id = str_replace(' ', '_', $id);
+ if (isset($file) and $file['media']['error'] == 0 and $file['media']['size'] < $maxsize) {
+ $infosfichier = pathinfo($file['media']['name']);
+ $extension_upload = $infosfichier['extension'];
+ $extensions_autorisees = $this::MEDIA_EXTENSIONS;
+ if (in_array($extension_upload, $extensions_autorisees)) {
+ if (!file_exists($this::MEDIA_DIR . $id . '.' . $extension_upload)) {
+
+ $extension_upload = strtolower($extension_upload);
+ $uploadok = move_uploaded_file($file['media']['tmp_name'], $this::MEDIA_DIR . $id . '.' . $extension_upload);
+ if ($uploadok) {
+ $message = 'uploadok';
+ } else {
+ $message = 'uploaderror';
+ }
+ } else {
+ $message = 'filealreadyexist';
+
+ }
+ }
+ } else {
+ $message = 'filetoobig';
+
+ }
+
+ return $message;
+ }
+
+
+ public function getmedia($entry, $dir)
+ {
+ $fileinfo = pathinfo($entry);
+
+ $filepath = $fileinfo['dirname'] . '.' . $fileinfo['extension'];
+
+ $donnees = array(
+ 'id' => str_replace('.' . $fileinfo['extension'], '', $fileinfo['filename']),
+ 'path' => $dir,
+ 'extension' => $fileinfo['extension']
+ );
+
+
+
+ return new Media($donnees);
+
+ }
+
+ public function getlistermedia($dir, $type = "all")
+ {
+ if ($handle = opendir($dir)) {
+ $list = [];
+ while (false !== ($entry = readdir($handle))) {
+ if ($entry != "." && $entry != "..") {
+
+ $media = $this->getmedia($entry, $dir);
+
+
+ $media->analyse();
+
+ if (in_array($type, self::MEDIA_TYPES)) {
+ if ($media->type() == $type) {
+ $list[] = $media;
+ }
+ } else {
+ $list[] = $media;
+ }
+
+
+ }
+ }
+ return $list;
+ }
+
+ return $list;
+
+ }
+
+
+
+
+}
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/modelrender.php b/app/class/modelrender.php
new file mode 100644
index 0000000..238bc85
--- /dev/null
+++ b/app/class/modelrender.php
@@ -0,0 +1,277 @@
+<?php
+
+class Modelrender extends Modelart
+{
+ const SUMMARY = '%SUMMARY%';
+
+
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+ public function renderhead(Art2 $art)
+ {
+
+ $head = $this->gethead($art);
+ $this->write($art);
+ return $head;
+ }
+
+ public function renderbody(Art2 $art)
+ {
+ $body = $this->getbody($this->gethtml($art), $this->getelements($art));
+ $parsebody = $this->parser($art, $body);
+ return $parsebody;
+ }
+
+
+
+ public function getelements(Art2 $art)
+ {
+ $elements = [];
+ foreach (self::TEXT_ELEMENTS as $element) {
+ if (isset($art->template('array')[$element])) {
+ $templateid = $art->template('array')[$element];
+ $tempalteart = $this->get($templateid);
+ $text = $tempalteart->$element() . PHP_EOL . $art->$element();
+ } else {
+ $text = $art->$element();
+ }
+ $elements[$element] = PHP_EOL . '<' . $element . '>' . PHP_EOL . $this->markdown($text) . PHP_EOL . '</' . $element . '>' . PHP_EOL;
+
+ }
+
+ return $elements;
+ }
+
+ public function gethtml(Art2 $art)
+ {
+ if (isset($art->template('array')['html'])) {
+ $templateid = $art->template('array')['html'];
+ $tempalteart = $this->get($templateid);
+ $html = $tempalteart->html() . PHP_EOL . $art->html();
+ } else {
+ $html = $art->html();
+ }
+ return $html;
+ }
+
+ public function getbody(string $html, array $elements)
+ {
+ $html = preg_replace_callback('~\%(SECTION|ASIDE|NAV|HEADER|FOOTER)\%~', function ($match) use ($elements) {
+ return $elements[strtolower($match[1])];
+ }, $html);
+ return $html;
+ }
+
+ public function write(Art2 $art)
+ {
+ file_put_contents(Model::RENDER_DIR . $art->id() . '.css', $art->css());
+ file_put_contents(Model::RENDER_DIR . $art->id() . '.quick.css', $art->quickcss());
+ file_put_contents(Model::RENDER_DIR . $art->id() . '.js', $art->javascript());
+ }
+
+ public function writetemplates(Art2 $art)
+ {
+ if (array_key_exists('css', $art->template('array'))) {
+ $tempaltecssart = $this->get($art->template('array')['css']);
+ file_put_contents(Model::RENDER_DIR . $tempaltecssart->id() . '.css', $tempaltecssart->css());
+ }
+ if (array_key_exists('quickcss', $art->template('array'))) {
+ $tempaltequickcssart = $this->get($art->template('array')['quickcss']);
+ file_put_contents(Model::RENDER_DIR . $tempaltequickcssart->id() . '.quick.css', $tempaltequickcssart->quickcss());
+ }
+ if (array_key_exists('javascript', $art->template('array'))) {
+ $templatejsart = $this->get($art->template('array')['javascript']);
+ file_put_contents(Model::RENDER_DIR . $templatejsart->id() . '.js', $templatejsart->javascript());
+ }
+ }
+
+
+ public function gethead(Art2 $art)
+ {
+
+ $head = '';
+
+ $head .= '<meta charset="utf8" />' . PHP_EOL;
+ $head .= '<title>'.$art->title() .'</title>' . PHP_EOL;
+ $head .= '<meta name="description" content="'.$art->description() .'" />' . PHP_EOL;
+ $head .= '<meta name="viewport" content="width=device-width" />' . PHP_EOL;
+
+ if (isset($art->template('array')['quickcss'])) {
+ $tempaltequickcssart = $art->template('array')['quickcss'];
+ $head .= '<link href="' . Config::renderpath() . $tempaltequickcssart . '.quick.css" rel="stylesheet" />' . PHP_EOL;
+ }
+ $head .= '<link href="' . Config::renderpath() . $art->id() . '.quick.css" rel="stylesheet" />' . PHP_EOL;
+ if (isset($art->template('array')['css'])) {
+ $tempaltecssart = $art->template('array')['css'];
+ $head .= '<link href="' . Config::renderpath() . $tempaltecssart . '.css" rel="stylesheet" />' . PHP_EOL;
+ }
+ $head .= '<link href="' . Config::renderpath() . $art->id() . '.css" rel="stylesheet" />' . PHP_EOL;
+
+ if (isset($art->template('array')['javascript'])) {
+ $templatejsart = $art->template('array')['javascript'];
+ $head .= '<script src="' . Config::renderpath() . $templatejsart . '.js" async/></script>' . PHP_EOL;
+ }
+ $head .= '<script src="' . Config::renderpath() . $art->id() . '.js" async/></script>' . PHP_EOL;
+
+ return $head;
+}
+
+public function elementsrender(Art2 $art)
+{
+ foreach ($this->getelements($art) as $element => $text) {
+ if (in_array($element, self::TEXT_ELEMENTS)) {
+ $elements[$element] = $this->markdown($text);
+ }
+ }
+ return $elements;
+}
+
+
+
+public function parser(Art2 $art, string $text)
+{
+ $text = str_replace('%TITLE%', $art->title(), $text);
+ $text = str_replace('%DESCRIPTION%', $art->description(), $text);
+
+
+ $text = str_replace(self::SUMMARY, $this->sumparser($text), $text);
+
+ $text = str_replace('href="=', 'href="?id=', $text);
+
+ $text = $this->tooltip($art->linkfrom('array'), $text);
+
+ $text = str_replace('href="http', ' class="external" target="_blank" href="http', $text);
+ $text = str_replace('<img src="/', '<img src="./media/', $text);
+
+ $text = $this->autourl($text);
+
+ return $text;
+}
+
+
+public function autourl($text)
+{
+ $text = preg_replace('#( |\R|>)(https?:\/\/((\S+)\.([^< ]+)))#', '$1<a href="$2" class="external" target="_blank">$3</a>', $text);
+ 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 tooltip(array $linkfrom, string $text)
+{
+ $descriptions = [];
+ $artlist = $this->getlisterid($linkfrom);
+ foreach ($artlist as $art) {
+ $descriptions[$art->id()] = $art->description();
+ }
+
+ foreach ($linkfrom as $id) {
+ if (isset($descriptions[$id])) {
+ $linkfrom = 'href="?id=' . $id . '"';
+ $titlelinkfrom = ' title="' . $descriptions[$id] . '" ' . $linkfrom;
+ $text = str_replace($linkfrom, $titlelinkfrom, $text);
+ }
+ }
+ return $text;
+}
+
+
+
+function sumparser($text)
+{
+ preg_match_all('#<h([1-6]) id="(\w+)">(.+)</h[1-6]>#iU', $text, $out);
+
+
+ $sum = [];
+ foreach ($out[2] as $key => $value) {
+ $sum[$value][$out[1][$key]] = $out[3][$key];
+ }
+
+
+ $sumstring = '';
+ $last = 0;
+ foreach ($sum as $title => $list) {
+ foreach ($list as $h => $link) {
+ if ($h > $last) {
+ for ($i = 1; $i <= ($h - $last); $i++) {
+ $sumstring .= '<ul>';
+ }
+ $sumstring .= '<li><a href="#' . $title . '">' . $link . '</a></li>';
+ } elseif ($h < $last) {
+ for ($i = 1; $i <= ($last - $h); $i++) {
+ $sumstring .= '</ul>';
+ }
+ $sumstring .= '<li><a href="#' . $title . '">' . $link . '</a></li>';
+ } elseif ($h = $last) {
+ $sumstring .= '<li><a href="#' . $title . '">' . $link . '</a></li>';
+ }
+ $last = $h;
+ }
+ }
+ for ($i = 1; $i <= ($last); $i++) {
+ $sumstring .= '</ul>';
+ }
+ return $sumstring;
+}
+
+
+
+ //tag auto menu
+
+
+public function autotaglist()
+{
+ $pattern = "/%%(\w*)%%/";
+ preg_match_all($pattern, $this->md(), $out);
+ return $out[1];
+
+}
+
+public function autotaglistupdate($taglist)
+{
+ foreach ($taglist as $tag => $artlist) {
+ $replace = '<ul>';
+ foreach ($artlist as $art) {
+ $replace .= '<li><a href="?id=' . $art->id() . '" title="' . $art->description() . '">' . $art->title() . '</a></li>';
+ }
+ $replace .= '</ul>';
+ $text = str_replace('%%' . $tag . '%%', $replace, $text);
+ }
+}
+
+public function autotaglistcalc($taglist)
+{
+ foreach ($taglist as $tag => $artlist) {
+ foreach ($artlist as $art) {
+ if (!in_array($art->id(), $this->linkfrom('array')) && $art->id() != $this->id()) {
+ $this->linkfrom[] = $art->id();
+ }
+ }
+ }
+}
+
+
+
+}
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/modeluser.php b/app/class/modeluser.php
new file mode 100644
index 0000000..899d1cc
--- /dev/null
+++ b/app/class/modeluser.php
@@ -0,0 +1,61 @@
+<?php
+
+
+class Modeluser extends Model
+{
+ const ADMIN = 10;
+ const EDITOR = 3;
+ const INVITE = 2;
+ const READ = 1;
+ const FREE = 0;
+
+
+ public function writesession(User $user)
+ {
+ $_SESSION['user'] = ['level' => $user->level()];
+ }
+
+ public function readsession()
+ {
+ $userdatas = [];
+ if(array_key_exists('user', $_SESSION)) {
+ $userdatas = $_SESSION['user'];
+ }
+ $user = new User($userdatas);
+ return $user;
+ }
+
+ public function login($pass)
+ {
+ $user = new User(['level' => $this->passlevel($pass)]);
+ return $user;
+ }
+
+ public function passlevel($pass)
+ {
+ if (strip_tags($pass) == Config::admin()) {
+ return $level = self::ADMIN;
+ } elseif (strip_tags($pass) == Config::read()) {
+ return $level = self::READ;
+ } elseif (strip_tags($pass) == Config::editor()) {
+ return $level = self::EDITOR;
+ } elseif (strip_tags($pass) == Config::invite()) {
+ return $level = self::INVITE;
+ } else {
+ return $level = self::FREE;
+ }
+ }
+
+ public function logout()
+ {
+ $user = new User(['level' => self::FREE]);
+ return $user;
+ }
+}
+
+
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/opt.php b/app/class/opt.php
new file mode 100644
index 0000000..f1cb4df
--- /dev/null
+++ b/app/class/opt.php
@@ -0,0 +1,272 @@
+<?php
+class Opt
+{
+ private $sortby = 'id';
+ private $order = 1;
+ private $tagfilter = [];
+ private $tagcompare = 'OR';
+ private $secure = 4;
+ private $linkto = ['min' => '0', 'max' => '0'];
+ private $linkfrom = ['min' => '0', 'max' => '0'];
+ private $col = ['id'];
+ private $taglist = [];
+ private $invert = 0;
+
+ private $artvarlist;
+
+ public function __construct(array $donnees = [])
+ {
+ $this->hydrate($donnees);
+ }
+
+ public function hydrate(array $donnees)
+ {
+ foreach ($donnees as $key => $value) {
+ $method = 'set' . $key;
+
+ if (method_exists($this, $method)) {
+ $this->$method($value);
+ }
+ }
+ }
+
+
+ public function resetall()
+ {
+ $varlist = get_class_vars(__class__);
+
+ foreach ($varlist as $var => $default) {
+ $method = 'set' . $var;
+ $this->$method($default);
+ }
+ }
+
+ public function reset($var)
+ {
+ $varlist = get_class_vars(__class__);
+ if(in_array($var, $varlist)) {
+ $this->$var = $varlist[$var];
+ }
+ }
+
+ public function submit()
+ {
+ if(isset($_GET['submit'])) {
+ if ($_GET['submit'] == 'reset') {
+ $_SESSION['opt'] = [];
+ } elseif ($_GET['submit'] == 'filter') {
+ $this->getall();
+ }
+ } else {
+ $this->sessionall();
+ }
+ }
+
+ public function getall()
+ {
+ $optlist = ['sortby', 'order', 'secure', 'tagcompare', 'tagfilter', 'invert'];
+
+ foreach ($optlist as $method) {
+ if (method_exists($this, $method)) {
+ if(isset($_GET[$method])) {
+ $setmethod = 'set'. $method;
+ $this->$setmethod($_GET[$method]);
+ } else {
+ $this->reset($method);
+ }
+ $_SESSION['opt'][$method] = $this->$method();
+ }
+ }
+ }
+
+ public function sessionall()
+ {
+ if(isset($_SESSION['opt'])) {
+ $this->hydrate($_SESSION['opt']);
+ }
+ }
+
+
+
+ // _______________________________________________ G E T _______________________________________________
+
+ public function sortby()
+ {
+ return $this->sortby;
+ }
+
+ public function order()
+ {
+ return $this->order;
+ }
+
+ public function secure()
+ {
+ return $this->secure;
+ }
+
+ public function tagfilter($type = 'array')
+ {
+ return $this->tagfilter;
+ }
+
+ public function tagcompare()
+ {
+ return $this->tagcompare;
+ }
+
+ public function linkto($type = 'array')
+ {
+ return $this->linkto;
+ }
+
+ public function linkfrom($type = 'array')
+ {
+ return $this->linkfrom;
+ }
+
+ public function col($type = 'array')
+ {
+ if ($type == 'string') {
+ return implode(', ', $this->col);
+ } else {
+ return ($this->col);
+ }
+ }
+
+ public function taglist()
+ {
+ return $this->taglist;
+ }
+
+ public function invert()
+ {
+ return $this->invert;
+ }
+
+ public function artvarlist()
+ {
+ return $this->artvarlist;
+ }
+
+
+ // __________________________________________________ S E T _____________________________________________
+
+ public function setsortby($sortby)
+ {
+ if (is_string($sortby) && in_array($sortby, $this->artvarlist())) {
+ $this->sortby = strtolower(strip_tags($sortby));
+ }
+ }
+
+ public function setorder($order)
+ {
+ $order = intval($order);
+ if (in_array($order, [-1, 0, 1])) {
+ $this->order = $order;
+ }
+ }
+
+ public function settagfilter($tagfilter)
+ {
+ if (!empty($tagfilter) && is_array($tagfilter)) {
+ $tagfilterverif = [];
+ foreach ($tagfilter as $tag) {
+ if(array_key_exists($tag, $this->taglist)) {
+ $tagfilterverif[] = $tag;
+ }
+ }
+ $this->tagfilter = $tagfilterverif;
+ }
+ }
+
+ public function settagcompare($tagcompare)
+ {
+ if (in_array($tagcompare, ['OR', 'AND'])) {
+ $this->tagcompare = $tagcompare;
+ }
+ }
+
+ public function setsecure($secure)
+ {
+ if ($secure >= 0 && $secure <= 5) {
+ $this->secure = intval($secure);
+ }
+ }
+
+ public function setlinkto($range)
+ {
+ $this->linkto = $range;
+ }
+
+ public function setlinkfrom($range)
+ {
+ $this->linkfrom = $range;
+ }
+
+ public function setlinktomin($min)
+ {
+ $this->linkto['min'] = intval($min);
+ }
+
+ public function setlinktomax($max)
+ {
+ $this->linkto['max'] = intval($max);
+ }
+
+ public function setlinkfrommin($min)
+ {
+ $this->linkfrom['min'] = intval($min);
+ }
+
+ public function setlinkfrommax($max)
+ {
+ $this->linkfrom['max'] = intval($max);
+ }
+
+ public function setcol($col)
+ {
+ if (is_array($col)) {
+ $this->col = array_intersect($this->artvarlist(), $col);
+ }
+ }
+
+
+ public function settaglist(array $artlist)
+ {
+ $taglist = [];
+ foreach ($artlist as $art) {
+ foreach ($art->tag('array') as $tag) {
+ if (!array_key_exists($tag, $taglist)) {
+ $taglist[$tag] = 1;
+ } else {
+ $taglist[$tag]++;
+ }
+ }
+ }
+ $taglistsorted = arsort($taglist);
+ $this->taglist = $taglist;
+ }
+
+ public function setinvert(int $invert)
+ {
+ if ($invert == 0 || $invert == 1) {
+ $this->invert = $invert;
+ } else {
+ $this->invert = 0;
+ }
+ }
+
+
+ public function setartvarlist(array $artvarlist)
+ {
+ $this->artvarlist = $artvarlist;
+ }
+
+
+}
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/quickcss.php b/app/class/quickcss.php
new file mode 100644
index 0000000..dc7dbac
--- /dev/null
+++ b/app/class/quickcss.php
@@ -0,0 +1,291 @@
+<?php
+
+class Quickcss
+{
+
+
+ private $active = [];
+ private $values = [];
+ private $units = [];
+ private $new = [];
+ private $jsoncss = [];
+
+ private $quickcss = [];
+
+ const COLOR = ['color', 'background-color', 'border-color', 'text-decoration-color'];
+ const SIZE = ['width', 'height', 'margin', 'padding', 'border-radius', 'border-width', 'left', 'right', 'top', 'bottom'];
+ const UNIQUE = ['background-image', 'opacity', 'font-size'];
+
+ const OPTIONS = [
+ 'text-align' => ['left', 'right', 'center', 'justify'],
+ 'border-style' => ['solid', 'double', 'outset', 'ridge'],
+ 'font-family' => ['serif', 'sans-serif', 'monospace', 'cursive', 'fantasy'],
+ 'text-decoration-line' => ['none', 'underline', 'overline', 'line-through', 'underline overline'],
+ 'display' => ['none', ]
+ ];
+
+
+ private static function getselect()
+ {
+ return array_keys(self::OPTIONS);
+ }
+
+ private static function getparams()
+ {
+ $params = array_merge(self::COLOR, self::SIZE, self::getselect(), self::UNIQUE);
+ sort($params, SORT_STRING );
+ return $params;
+ }
+
+ public function __construct($data)
+ {
+ $this->hydrate($data); }
+
+ public function hydrate($data)
+ {
+ foreach ($data as $key => $value) {
+ $method = 'set' . $key;
+
+ if (method_exists($this, $method)) {
+ $this->$method($value);
+ }
+ }
+ }
+
+ public function calc()
+ {
+ $quickcss = $this->intersect($this->values,$this->active);
+ $quickcss = $this->merge($quickcss, $this->new);
+ $quickcss = $this->addunits($quickcss, $this->units);
+ $quickcss = $this->merge($this->jsoncss, $quickcss);
+
+ $this->quickcss = $quickcss;
+ }
+
+
+
+ // _________________________________________ P O S T __________________________________________________
+
+ public function setvalues($data)
+ {
+ if(is_array($data)) {
+ $this->values = $data;
+ }
+ }
+
+ public function setunits($data)
+ {
+ if(is_array($data)) {
+ $this->units = $data;
+ }
+ }
+
+ public function setactive($data)
+ {
+ if(is_array($data)) {
+ $this->active = $data;
+ }
+ }
+
+ public function setnew($data)
+ {
+ if (!empty($data['element']) && !empty($data['param']) && in_array($data['param'], self::getparams())) {
+ $new = array($data['element'] => array($data['param'] => ''));
+ $this->new = $new;
+ }
+ }
+
+
+ public function setjson($jsoncss)
+ {
+ if(!empty($jsoncss) && is_string($jsoncss)) {
+ $jsoncss = json_decode($jsoncss);
+ if(is_array($jsoncss)) {
+ $this->jsoncss = $jsoncss;
+ } else {
+ $this->jsoncss = [];
+ }
+ }
+ }
+
+
+ // _______________________________________ C A L C ___________________________________________________
+
+ public function intersect($values, $active)
+ {
+ $intersect = array_intersect_key($values, $active);
+
+ foreach ($intersect as $element => $css) {
+ $intersect[$element] = array_intersect_key($values[$element], $active[$element]);
+ }
+ return $intersect;
+ }
+
+ public function merge($quickcss, $new)
+ {
+ $quickcss = array_merge_recursive($quickcss, $new);
+ return $quickcss;
+ }
+
+ public function addunits($quickcss, $units)
+ {
+ foreach ($units as $element => $css) {
+ foreach ($css as $param => $unit) {
+ if (array_key_exists($element, $quickcss) && array_key_exists($param, $quickcss[$element])) {
+ $quickcss[$element][$param] = $quickcss[$element][$param] . $unit;
+ }
+ }
+ }
+ return $quickcss;
+ }
+
+
+
+ // __________________________________________ C O M _________________________________________
+
+ public function tocss()
+ {
+ $string = '';
+ foreach ($this->quickcss as $element => $css) {
+ $string .= PHP_EOL . $element . ' {';
+ foreach ($css as $param => $value) {
+ $string .= PHP_EOL . ' ' . $param . ': ' . $value . ';';
+ }
+ $string .= PHP_EOL . '}' . PHP_EOL;
+ }
+ return $string;
+ }
+
+ public function tojson()
+ {
+ return json_encode($this->quickcss);
+ }
+
+
+
+
+ // _____________________________________________ F O R M ____________________________________________
+
+ public function form($action)
+ {
+ echo '<form action="' . $action . '" method="post">';
+ echo '</br><input type="submit" value="submit">';
+ $this->inputs($this->quickcss);
+ echo '</br><input type="submit" value="submit">';
+ echo '</form>';
+
+ }
+
+ public function inputs($quickcss)
+ {
+ echo '<h1>Add element</h1>';
+
+ echo '<input type="text" name="new[element]" list="used">';
+ echo '<datalist id="used">';
+ foreach (array_keys($quickcss) as $element) {
+ echo '<option value ="'.$element.'">';
+ }
+ echo '</datalist>';
+
+ echo '<select name="new[param]">';
+ foreach (self::getparams() as $param) {
+ echo '<option value="' . $param . '">' . $param . '</option>';
+ }
+ echo '</select>';
+
+ foreach ($quickcss as $element => $css) {
+ echo '<h3>' . $element . '</h3>';
+ foreach ($css as $param => $value) {
+
+ echo '<div class="quicklabel">';
+ echo '<input type="checkbox" name="active[' . $element . '][' . $param . ']" id="active[' . $element . '][' . $param . ']" checked>';
+ echo '<label for="active[' . $element . '][' . $param . ']">' . $param . '</label>';
+ echo '</div>';
+
+ echo '<div class="quickinput">';
+
+ if (in_array($param, self::COLOR)) {
+ echo '<input type="color" name="values[' . $element . '][' . $param . ']" value="' . $quickcss[$element][$param] . '" id="values[' . $element . '][' . $param . ']">';
+ }
+
+ if (in_array($param, self::SIZE)) {
+ $this->sizeinput($element, $param, $value);
+ }
+
+ if (in_array($param, self::getselect())) {
+ $this->selectinput($element, $param, $value);
+ }
+
+ if (in_array($param, self::UNIQUE)) {
+ $method = str_replace('-', '', $param) . 'input';
+ if (method_exists($this, $method)) {
+ $this->$method($element, $param, $value);
+ }
+ }
+
+ echo '</div>';
+ }
+ }
+
+
+ }
+
+
+
+
+
+
+ // ____________________________________ I N P U T __________________________________
+
+ public function sizeinput($element, $param, $value)
+ {
+ echo '<input type="number" name="values[' . $element . '][' . $param . ']" value="' . intval($value) . '" id="values[' . $element . '][' . $param . ']">';
+
+ $unit = preg_replace('/\d/', '', $value);
+ ?>
+ <select name="units[<?= $element ?>][<?= $param ?>]" >
+ <option value="px" <?= $unit == 'px' ? 'selected' : '' ?>>px</option>
+ <option value="%" <?= $unit == '%' ? 'selected' : '' ?>>%</option>
+ </select>
+ <?php
+
+ }
+
+ public function fontsizeinput($element, $param, $value)
+ {
+ echo '<input type="number" name="values[' . $element . '][' . $param . ']" value="' . intval($value) . '" id="values[' . $element . '][' . $param . ']">';
+
+ $unit = preg_replace('/\d/', '', $value);
+ ?>
+ <select name="units[<?= $element ?>][<?= $param ?>]" >
+ <option value="px" <?= $unit == 'px' ? 'selected' : '' ?>>px</option>
+ <option value="em" <?= $unit == 'em' ? 'selected' : '' ?>>em</option>
+ </select>
+ <?php
+
+ }
+
+ public function opacityinput($element, $param, $value)
+ {
+ echo '<input type="number" name="values[' . $element . '][' . $param . ']" value="' . $value . '" id="values[' . $element . '][' . $param . ']" step="0.1" min="0" max="1">';
+ }
+
+ public function selectinput($element, $param, $value)
+ {
+ echo '<select name="values[' . $element . '][' . $param . ']">';
+ foreach (self::OPTIONS[$param] as $option) {
+ if($option == $value) {
+ echo '<option value="'.$option.'" selected>'.$option.'</option>';
+ } else {
+ echo '<option value="'.$option.'">'.$option.'</option>';
+ }
+ }
+ echo '</select>';
+ }
+
+
+}
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/record.php b/app/class/record.php
new file mode 100644
index 0000000..e488383
--- /dev/null
+++ b/app/class/record.php
@@ -0,0 +1,116 @@
+<?php
+
+class Record
+{
+ private $id;
+ private $path;
+ private $extension;
+ private $size;
+ private $datetime;
+ private $number;
+
+
+
+// _____________________________________________________ F U N ____________________________________________________
+
+ public function __construct(array $donnees)
+ {
+ $this->hydrate($donnees);
+ }
+
+ public function hydrate(array $donnees)
+ {
+ foreach ($donnees as $key => $value) {
+ $method = 'set' . $key;
+
+ if (method_exists($this, $method)) {
+ $this->$method($value);
+ }
+ }
+ }
+
+
+
+// _________________________________________________ G E T ____________________________________________________
+
+ public function id()
+ {
+ return $this->id;
+ }
+
+ public function path()
+ {
+ return $this->path;
+ }
+
+ public function extension()
+ {
+ return $this->extension;
+ }
+
+ public function size()
+ {
+ return $this->size;
+ }
+
+ public function datetime()
+ {
+ return $this->datetime;
+ }
+
+ public function number()
+ {
+ return $this->number;
+ }
+
+// ___________________________________________________ S E T __________________________________________________
+
+ public function setid($id)
+ {
+ if (strlen($id) < 100 and is_string($id)) {
+ $this->id = strip_tags(strtolower($id));
+ }
+ }
+
+ public function setpath($path)
+ {
+ if (strlen($path) < 40 and is_string($path)) {
+ $this->path = strip_tags(strtolower($path));
+ }
+ }
+
+ public function setextension($extension)
+ {
+ if (strlen($extension) < 7 and is_string($extension)) {
+ $this->extension = strip_tags(strtolower($extension));
+ }
+ }
+
+ public function setsize($size)
+ {
+ if (40 and is_int($size)) {
+ $this->size = strip_tags(strtolower($size));
+ }
+ }
+
+ public function setdatetime($datetime)
+ {
+ if (is_int($datetime)) {
+ $this->datetime = strip_tags(strtolower($datetime));
+ }
+ }
+
+ public function setnumber($number)
+ {
+ if (is_int($number)) {
+ $this->number = strip_tags(strtolower($number));
+ }
+ }
+
+
+
+
+
+}
+
+?> \ No newline at end of file
diff --git a/app/class/route.php b/app/class/route.php
new file mode 100644
index 0000000..cc2fe59
--- /dev/null
+++ b/app/class/route.php
@@ -0,0 +1,84 @@
+<?php
+
+class Route
+{
+ protected $id = null;
+ protected $aff = null;
+ protected $action = null;
+ protected $redirect = null;
+
+ const AFF = ['read', 'edit', 'admin', 'media'];
+
+ public function __construct($vars)
+ {
+ $this->hydrate($vars);
+ }
+
+ public function hydrate($vars)
+ {
+ foreach ($vars as $var => $value) {
+ $method = 'set' . $var;
+ if (method_exists($this, $method)) {
+ $this->$method($value);
+ }
+ }
+ }
+
+ public function toarray()
+ {
+ $array = [];
+ if (!empty($this->id)) {
+ $array[] = 'art';
+ }
+ if (!empty($this->aff)) {
+ $array[] = 'aff='.$this->aff;
+ }
+ if (!empty($this->action)) {
+ $array[] = 'action=' . $this->action;
+ }
+ if (!empty($this->redirect)) {
+ $array[] = $this->redirect;
+ }
+
+
+ return $array;
+ }
+
+ function tostring()
+ {
+ return implode(' ', $this->toarray());
+ }
+
+
+
+ public function setid($id)
+ {
+ $this->id = $id;
+ }
+
+ public function setaff($aff)
+ {
+ $this->aff = $aff;
+
+ }
+
+ public function setaction($action)
+ {
+ $this->action = $action;
+ }
+
+ public function setredirect($redirect)
+ {
+ $this->redirect = $redirect;
+ }
+
+ public function id()
+ {
+ return $this->id;
+ }
+}
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/routes.php b/app/class/routes.php
new file mode 100644
index 0000000..6f37b93
--- /dev/null
+++ b/app/class/routes.php
@@ -0,0 +1,34 @@
+<?php
+
+class Routes
+{
+ /**
+ * Cherche une correspondance entre l'URL et les routes, et appelle la méthode appropriée
+ */
+ public function match()
+ {
+ $router = new AltoRouter();
+ $router->addRoutes([
+ ['GET|POST', '/', 'Backrouter#run', 'backrouter'],
+ ['GET', '/[a:art]/', 'Controllerart#read', 'artread/'],
+ ['GET', '/[a:art]', 'Controllerart#read', 'artread'],
+ ['GET', '/[a:art]/edit', 'Controllerart#edit', 'artedit'],
+ ['GET', '/[a:art]/edit/', 'Controllerart#edit', 'artedit/'],
+ ]);
+
+ $match = $router->match();
+ if ($match) {
+ $callableParts = explode('#', $match['target']);
+ $controllerName = $callableParts[0];
+ $methodName = $callableParts[1];
+
+ $controller = new $controllerName();
+
+ call_user_func_array(array($controller, $methodName), $match['params']);
+ }
+ //404
+ else {
+ header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
+ }
+ }
+} \ No newline at end of file
diff --git a/app/class/sleekdbw.php b/app/class/sleekdbw.php
new file mode 100644
index 0000000..dd77752
--- /dev/null
+++ b/app/class/sleekdbw.php
@@ -0,0 +1,180 @@
+<?php
+
+use SleekDB\SleekDB;
+
+
+class SleekDBw extends SleekDB
+{
+
+ public function getStoreIdList()
+ {
+ $listPath = $this->storePath . 'data/';
+ $lengh = strlen($listPath);
+ $list = [];
+ foreach (glob($listPath . '*.json') as $filename) {
+ $list[] = substr(substr($filename, $lengh), 0, -5);
+ }
+ return $list;
+ }
+
+ public function getbyid($id)
+ {
+ return $this->getStoreDocumentById($id);
+ }
+
+ public function updatebyid($id, $data)
+ {
+ foreach ($data as $key => $value) {
+ // Do not update the _id reserved index of a store.
+ if ($key != '_id') {
+ $data[$key] = $value;
+ }
+ }
+ $storePath = $this->storePath . 'data/' . $id . '.json';
+ if (file_exists($storePath)) {
+ // Wait until it's unlocked, then update data.
+ file_put_contents($storePath, json_encode($data), LOCK_EX);
+ }
+ // Check do we need to wipe the cache for this store.
+ if ($this->deleteCacheOnCreate === true) $this->_emptyAllCache();
+ return true;
+ }
+
+
+
+
+
+
+ // Writes an object in a store.
+ protected function writeInStore($storeData)
+ {
+ // Cast to array
+ $storeData = (array)$storeData;
+ // Check if it has _id key
+ if (empty($storeData['_id'])) throw new \Exception('Lack of id in this object');
+ if (in_array($storeData['_id'], $this->getStoreIdList())) throw new \Exception('Id already used');
+ // Add the system ID with the store data array.
+ $id = $storeData['_id'];
+ // Prepare storable data
+ $storableJSON = json_encode($storeData);
+ if ($storableJSON === false) throw new \Exception('Unable to encode the data array, please provide a valid PHP associative array');
+ // Define the store path
+ $storePath = $this->storePath . 'data/' . $id . '.json';
+ if (!file_put_contents($storePath, $storableJSON)) {
+ throw new \Exception("Unable to write the object file! Please check if PHP has write permission.");
+ }
+ return $storeData;
+ }
+
+
+ // Find store objects with conditions, sorting order, skip and limits.
+ protected function findStoreDocuments()
+ {
+ $found = [];
+ $storeIdList = $this->getStoreIdList();
+ $searchRank = [];
+ // Start collecting and filtering data.
+ foreach ($storeIdList as $id) {
+ // Collect data of current iteration.
+ $data = $this->getStoreDocumentById($id);
+ if (!empty($data)) {
+ // Filter data found.
+ if (empty($this->conditions)) {
+ // Append all data of this store.
+ $found[] = $data;
+ } else {
+ // Append only passed data from this store.
+ $storePassed = true;
+ // Iterate each conditions.
+ foreach ($this->conditions as $condition) {
+ // Check for valid data from data source.
+ $validData = true;
+ $fieldValue = '';
+ try {
+ $fieldValue = $this->getNestedProperty($condition['fieldName'], $data);
+ } catch (\Exception $e) {
+ $validData = false;
+ $storePassed = false;
+ }
+ if ($validData === true) {
+ // Check the type of rule.
+ if ($condition['condition'] === '=') {
+ // Check equal.
+ if ($fieldValue != $condition['value']) $storePassed = false;
+ } else if ($condition['condition'] === '!=') {
+ // Check not equal.
+ if ($fieldValue == $condition['value']) $storePassed = false;
+ } else if ($condition['condition'] === '>') {
+ // Check greater than.
+ if ($fieldValue <= $condition['value']) $storePassed = false;
+ } else if ($condition['condition'] === '>=') {
+ // Check greater equal.
+ if ($fieldValue < $condition['value']) $storePassed = false;
+ } else if ($condition['condition'] === '<') {
+ // Check less than.
+ if ($fieldValue >= $condition['value']) $storePassed = false;
+ } else if ($condition['condition'] === '<=') {
+ // Check less equal.
+ if ($fieldValue > $condition['value']) $storePassed = false;
+ }
+ }
+ }
+ // Check if current store is updatable or not.
+ if ($storePassed === true) {
+ // Append data to the found array.
+ $found[] = $data;
+ }
+ }
+ }
+ }
+ if (count($found) > 0) {
+ // Check do we need to sort the data.
+ if ($this->orderBy['order'] !== false) {
+ // Start sorting on all data.
+ $found = $this->sortArray($this->orderBy['field'], $found, $this->orderBy['order']);
+ }
+ // If there was text search then we would also sort the result by search ranking.
+ if (!empty($this->searchKeyword)) {
+ $found = $this->performSerach($found);
+ }
+ // Skip data
+ if ($this->skip > 0) $found = array_slice($found, $this->skip);
+ // Limit data.
+ if ($this->limit > 0) $found = array_slice($found, 0, $this->limit);
+ }
+ return $found;
+ }
+
+
+
+ // Method to boot a store.
+ protected function bootStore()
+ {
+ $store = trim($this->storeName);
+ // Validate the store name.
+ if (!$store || empty($store)) throw new \Exception('Invalid store name was found');
+ // Prepare store name.
+ if (substr($store, -1) !== '/') $store = $store . '/';
+ // Store directory path.
+ $this->storePath = $this->dataDirectory . $store;
+ // Check if the store exists.
+ if (!file_exists($this->storePath)) {
+ // The directory was not found, create one with cache directory.
+ if (!mkdir($this->storePath, 0777, true)) throw new \Exception('Unable to create the store path at ' . $this->storePath);
+ // Create the cache directory.
+ if (!mkdir($this->storePath . 'cache', 0777, true)) throw new \Exception('Unable to create the store\'s cache directory at ' . $this->storePath . 'cache');
+ // Create the data directory.
+ if (!mkdir($this->storePath . 'data', 0777, true)) throw new \Exception('Unable to create the store\'s data directory at ' . $this->storePath . 'data');
+ // Check if PHP has write permission in that directory.
+ if (!is_writable($this->storePath)) throw new \Exception('Store path is not writable at "' . $this->storePath . '." Please change store path permission.');
+ // Finally check if the directory is readable by PHP.
+ if (!is_readable($this->storePath)) throw new \Exception('Store path is not readable at "' . $this->storePath . '." Please change store path permission.');
+ }
+ }
+
+
+
+
+}
+
+?> \ No newline at end of file
diff --git a/app/class/user.php b/app/class/user.php
new file mode 100644
index 0000000..77d6ba2
--- /dev/null
+++ b/app/class/user.php
@@ -0,0 +1,58 @@
+<?php
+
+class User
+{
+ protected $level = 0;
+
+ public function __construct($datas = []) {
+ if(!empty($datas)) {
+ $this->hydrate($datas);
+ }
+ }
+
+ public function hydrate(array $datas = [])
+ {
+ foreach ($datas as $key => $value) {
+ $method = 'set' . $key;
+
+ if (method_exists($this, $method)) {
+ $this->$method($value);
+ }
+ }
+ }
+
+ public function setlevel($level)
+ {
+ $this->level = $level;
+ }
+
+ public function level()
+ {
+ return $this->level;
+ }
+
+ public function isvisitor()
+ {
+ return $this->level === Modeluser::FREE;
+ }
+
+ public function canedit()
+ {
+ // a modifier en prenant compte du code invitation de l'article
+ return $this->level >= Modeluser::EDITOR;
+ }
+
+ public function cancreate()
+ {
+ return $this->level >=Modeluser::EDITOR;
+ }
+
+ public function isadmin()
+ {
+ return $this->level === Modeluser::ADMIN;
+ }
+}
+
+
+
+?> \ No newline at end of file
diff --git a/app/class/w.article.php b/app/class/w.article.php
new file mode 100644
index 0000000..2476353
--- /dev/null
+++ b/app/class/w.article.php
@@ -0,0 +1,32 @@
+<?php
+
+if ($app->exist($_GET['id'])) {
+
+ $art = $app->get($_GET['id']);
+
+ if (isset($_GET['edit']) and $_GET['edit'] == 1 and $app->session() >= $app::EDITOR) {
+ echo '<section class=edit>';
+ $aff->edit($art, $app, $app->getlister(['id', 'title']), $config->fontsize(), $app->getlistermedia($app::MEDIA_DIR, 'image'));
+ $aff->aside($app);
+ echo '</section>';
+ } else {
+ echo '<section class="lecture">';
+
+
+ $art->autotaglistupdate($app->taglist($app->getlister(['id', 'title', 'description', 'tag']), $art->autotaglist()));
+
+
+ $aff->lecture($art, $app);
+ echo '</section>';
+
+ }
+} else {
+ echo '<span class="alert">This article does not exist yet</span>';
+
+ if ($app->session() >= $app::EDITOR) {
+ echo '<form action="?id=' . $_GET['id'] . '&edit=1" method="post"><input type="hidden" name="action" value="new"><input type="submit" value="Create"></form>';
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/app/class/w.home.php b/app/class/w.home.php
new file mode 100644
index 0000000..8ba8b44
--- /dev/null
+++ b/app/class/w.home.php
@@ -0,0 +1,85 @@
+<?php
+
+
+$aff->header();
+
+echo '<section class="home">';
+
+
+if ($app->session() >= $app::EDITOR) {
+
+ $app->bddinit($config);
+
+ $opt = new Opt(Art2::classvarlist());
+ $opt->setcol(['id', 'tag', 'linkfrom', 'contenu', 'description', 'title', 'datemodif', 'datecreation', 'secure']);
+ $table = $app->getlisteropt($opt);
+ $app->listcalclinkfrom($table);
+ $opt->settaglist($table);
+ $opt->submit();
+
+
+
+
+
+
+
+
+
+
+
+ $opt->setcol(['id', 'tag', 'linkfrom', 'contenu', 'description', 'title', 'datemodif', 'datecreation', 'secure', 'linkto']);
+
+
+ $aff->option($app, $opt);
+
+ $filtertagfilter = $app->filtertagfilter($table, $opt->tagfilter(), $opt->tagcompare());
+ $filtersecure = $app->filtersecure($table, $opt->secure());
+
+ $filter = array_intersect($filtertagfilter, $filtersecure);
+ $table2 = [];
+ $table2invert = [];
+ foreach ($table as $art) {
+ if (in_array($art->id(), $filter)) {
+ $table2[] = $art;
+ } else {
+ $table2invert[] = $art;
+ }
+
+
+ }
+
+ if(!empty($opt->invert())) {
+ $table2 = $table2invert;
+ }
+
+ $app->artlistsort($table2, $opt->sortby(), $opt->order());
+
+
+ echo '<div id="flex">';
+
+
+ $aff->home2table($app, $table2, $app->getlister());
+
+
+
+
+ echo '<div id="map">';
+ $aff->mapheader();
+ if(isset($_GET['map'])) {
+ $aff->mermaid($app->map($table2));
+ }
+ echo '</div>';
+
+
+
+
+
+ echo '</div>';
+
+}
+
+
+
+echo '</section>';
+
+?> \ No newline at end of file
diff --git a/app/class/w.menu.php b/app/class/w.menu.php
new file mode 100644
index 0000000..8e89ed1
--- /dev/null
+++ b/app/class/w.menu.php
@@ -0,0 +1,56 @@
+<?php
+
+
+if ($app->session() >= $app::EDITOR) {
+
+ if ($_GET['aff'] == 'admin' && $app->session() >= $app::ADMIN) {
+ echo '<section>';
+ echo '<h1>Admin</h1>';
+
+ $aff->admincss($config, $app);
+ $aff->adminpassword($config);
+ $aff->admindb($config);
+ if ($app->setbdd($config)) {
+ $status = "OK";
+ } else {
+ $status = "Not Connected";
+ }
+ $aff->admintable($config, $status, $app->tablelist($config->dbname()));
+ $aff->admindisplay($config->color4());
+
+ echo '</section>';
+ } elseif ($_GET['aff'] == 'media') {
+ echo '<h1>Media</h1>';
+ echo '<section>';
+ echo '<article>';
+
+ $aff->addmedia($app);
+ $aff->medialist($app->getlistermedia($app::MEDIA_DIR), $app::MEDIA_DIR);
+
+ echo '</article>';
+ echo '</section>';
+
+ } elseif ($_GET['aff'] == 'record') {
+ echo '<h1>Record</h1>';
+ echo '<section>';
+
+ $aff->recordlist($app);
+
+ echo '</section>';
+
+ } elseif ($_GET['aff'] == 'info') {
+
+
+
+ } else {
+
+ echo '<h1>Private</h1><p>You dont have the permission to access this page.</p>';
+
+ }
+
+
+} else {
+ echo '<h1>Private</h1><p>You should be connected to access this page.</p>';
+}
+
+?> \ No newline at end of file
diff --git a/app/fn/fn.php b/app/fn/fn.php
new file mode 100644
index 0000000..8bfdee8
--- /dev/null
+++ b/app/fn/fn.php
@@ -0,0 +1,155 @@
+<?php
+function bddconnect($host, $bdname, $user, $password)
+{
+ try {
+ $bdd = new PDO('mysql:host=' . $host . ';dbname=' . $dbname . ';charset=utf8', $user, $password);
+ } catch (Exeption $e) {
+ die('Erreur : ' . $e->getMessage());
+ }
+ return $bdd;
+}
+
+
+function secure()
+{
+ if (!isset($_SESSION['id'])) {
+ header("location: ./");
+ }
+}
+
+function head($title)
+{
+ ?>
+ <head>
+ <meta charset="utf8" />
+ <meta name="viexport" content="width=device-width" />
+ <link href="./css/style.css" rel="stylesheet" />
+ <title><?= $title ?></title>
+ </head>
+ <?php
+
+}
+
+function search($haystack, $debut, $fin)
+{
+ $list = [];
+
+ $indexdebut = strpos($haystack, $debut);
+ if ($indexdebut !== false) {
+ $indexdebut += strlen($debut);
+ $indexfin = strpos($haystack, $fin, $indexdebut);
+ if ($indexfin !== false) {
+ array_push($list, substr($haystack, $indexdebut, $indexfin - $indexdebut));
+ $haystack = substr($haystack, $indexfin);
+ $list = array_merge($list, search($haystack, $debut, $fin));
+ }
+ }
+ return $list;
+
+}
+
+function readablesize($bytes)
+{
+
+ $num = 5;
+ $location = 'tree';
+ $format = ' %d %s';
+
+
+
+ if ($bytes < 2 ** 10) {
+ $num = $bytes;
+ $unit = 'o';
+ } elseif ($bytes < 2 ** 20) {
+ $num = round($bytes / 2 ** 10, 1);
+ $unit = 'Kio';
+ } elseif ($bytes < 2 ** 30) {
+ $num = round($bytes / 2 ** 20, 1);
+ $unit = 'Mio';
+ } elseif ($bytes < 2 ** 40) {
+ $num = round($bytes / 2 ** 30, 1);
+ $unit = 'Gio';
+ }
+
+ return sprintf($format, $num, $unit);
+}
+
+/* human readable date interval
+ * @param DateInterval $diff - l'interval de temps
+ * @return string
+ */
+function hrdi(DateInterval $diff)
+{
+ $str = "";
+ if ($diff->y > 1) return $str . $diff->y . ' years';
+ if ($diff->y == 1) return $str . ' 1 year and ' . $diff->m . ' months';
+ if ($diff->m > 1) return $str . $diff->m . ' months';
+ if ($diff->m == 1) return $str . ' 1 month and ' . $diff->d . ($diff->d > 1 ? ' days' : ' day');
+ if ($diff->d > 1) return $str . $diff->d . ' days';
+ if ($diff->d == 1) return $str . ' 1 day and ' . $diff->h . ($diff->h > 1 ? ' hours' : ' hour');
+ if ($diff->h > 1) return $str . $diff->h . ' hours';
+ if ($diff->h == 1) return $str . ' 1 hour and ' . $diff->i . ($diff->i > 1 ? ' minutes' : ' minute');
+ if ($diff->i > 1) return $str . $diff->i . ' minutes';
+ if ($diff->i == 1) return $str . ' 1 minute';
+ return $str . ' a few secondes';
+}
+
+
+
+function arrayclean($input)
+{
+ $output = [];
+ foreach ($input as $key => $value) {
+ if (is_array($value)) {
+ $output[$key] = array_filter($value);
+ } else {
+ $output[$key] = $value;
+ }
+ }
+ return $output;
+}
+
+
+
+
+function array_update($base, $new)
+{
+ foreach ($base as $key => $value) {
+ if (array_key_exists($key, $new)) {
+ if (gettype($base[$key]) == gettype($new[$key])) {
+ $base[$key] = $new[$key];
+ }
+ }
+ }
+ return $base;
+}
+
+function contains($needle, $haystack)
+{
+ return strpos($haystack, $needle) !== false;
+}
+
+
+function str_clean(string $string)
+{
+ return str_replace(' ', '_', strtolower(strip_tags($string)));
+}
+
+
+
+
+function changekey($array, $oldkey, $newkey)
+{
+ if (!array_key_exists($oldkey, $array))
+ return $array;
+
+ $keys = array_keys($array);
+ $keys[array_search($oldkey, $keys)] = $newkey;
+
+ return array_combine($keys, $array);
+}
+
+
+
+
+?> \ No newline at end of file
diff --git a/app/oldindex.php b/app/oldindex.php
new file mode 100644
index 0000000..5bc42bf
--- /dev/null
+++ b/app/oldindex.php
@@ -0,0 +1,327 @@
+<?php
+
+exit;
+
+// ________________________________________________________ I N S T A L _________________________________________________
+
+$app = new App();
+$aff = new Aff();
+
+
+$config = $app->readconfig();
+if (!$config) {
+ $message = 'config_file_error';
+ echo $message;
+ if (isset($_POST['config']) && $_POST['config'] == 'create') {
+ $config = $app->createconfig($_POST);
+ $app->savejson($config->tojson());
+ header('Location: ./');
+
+ } else {
+ $aff->configform();
+ }
+ exit;
+}
+
+
+// _________________________________________________________ S E S ___________________________________________________________
+
+
+if (!isset($_SESSION['level'])) {
+ $session = 0;
+} else {
+ $session = $_SESSION['level'];
+}
+
+$app->setsession($session);
+
+
+
+
+// _______________________________________________________ A C T I O N __________________________________________________________________
+
+
+$router = new Router;
+
+
+
+
+
+if (isset($_POST['action'])) {
+ switch ($_POST['action']) {
+
+ case 'login':
+ $_SESSION['level'] = $app->login($_POST['pass'], $config);
+ if (isset($_GET['id'])) {
+ header('Location: ?id=' . $_GET['id']);
+ } else {
+ header('Location: ./');
+ }
+ break;
+
+ case 'logout':
+ $_SESSION['level'] = $app->logout();
+ if (isset($_GET['id'])) {
+ header('Location: ?id=' . $_GET['id']);
+ } else {
+ header('Location: ./');
+ }
+ break;
+
+ case 'addmedia':
+ $message = $app->addmedia($_FILES, 2 ** 24, $_POST['id']);
+ header('Location: ./?aff=media&message=' . $message);
+ break;
+
+
+
+ case 'editcss':
+ file_put_contents($app::GLOBAL_CSS_DIR, $_POST['editcss']);
+ header('Location: ./?aff=admin');
+ break;
+
+ case 'editconfig':
+ $config->hydrate($_POST);
+ $app->savejson($config->tojson());
+ header('Location: ./?aff=admin');
+ break;
+
+
+ }
+}
+
+
+
+// _____________________________________________________ D A T A B A S E __________________________________________________________________
+
+if (isset($_POST['action'])) {
+ $app->bddinit($config);
+
+ switch ($_POST['action']) {
+
+ case 'new':
+ if (isset($_GET['id'])) {
+ $art = new Art2($_GET);
+ $art->reset();
+ $app->add($art);
+ header('Location: ?id=' . $_GET['id'] . '&edit=1');
+ }
+ break;
+
+ case 'update':
+ if ($app->exist($_GET['id'])) {
+ $art = new Art2($_POST);
+ $art->updatelinkfrom();
+ $art->autotaglistcalc($app->taglist($app->getlister(['id', 'title', 'tag']), $art->autotaglist()));
+ $app->update($art);
+ if ($config->fontsize() != $_POST['fontsize']) {
+ $config->setfontsize($_POST['fontsize']);
+ $app->savejson($config->tojson());
+ }
+ header('Location: ?id=' . $art->id() . '&edit=1&message=' . $art->id() . '_saved');
+ }
+ break;
+
+ case 'display':
+ if ($app->exist($_GET['id'])) {
+ $art = new Art2($_POST);
+ $art->updatelinkfrom();
+ $art->autotaglistcalc($app->taglist($app->getlister(['id', 'title', 'tag']), $art->autotaglist()));
+ $app->update($art);
+ if ($config->fontsize() != $_POST['fontsize']) {
+ $config->setfontsize($_POST['fontsize']);
+ $app->savejson($config->tojson());
+ }
+ header('Location: ?id=' . $art->id() . '&message=' . $art->id() . '_saved');
+ }
+ break;
+
+ case 'home':
+ if ($app->exist($_GET['id'])) {
+ $art = new Art2($_POST);
+ $art->updatelinkfrom();
+ $art->autotaglistcalc($app->taglist($app->getlister(['id', 'title', 'tag']), $art->autotaglist()));
+ $app->update($art);
+ if ($config->fontsize() != $_POST['fontsize']) {
+ $config->setfontsize($_POST['fontsize']);
+ $app->savejson($config->tojson());
+ }
+ header('Location: ./?message=' . $art->id() . '_saved');
+ }
+ break;
+
+ case 'delete':
+ if ($app->exist($_GET['id'])) {
+ $art = new Art2($_POST);
+ $app->delete($art);
+ header('Location: ?id=' . $art->id());
+ }
+ break;
+
+ case 'massedit':
+ if (isset($_POST['id'])) {
+ foreach ($_POST['id'] as $id) {
+ if ($app->exist($id)) {
+ $art = $app->get($id);
+
+ switch ($_POST['massaction']) {
+ case 'do':
+ switch ($_POST['massedit']) {
+ case 'delete':
+ $app->delete($art);
+ break;
+
+ case 'erasetag':
+ $art->settag('');
+ $app->update($art);
+ break;
+
+ case 'erasetemplate':
+ $art->settemplate('');
+ $app->update($art);
+ break;
+
+ case 'not published':
+ $art->setsecure(2);
+ $app->update($art);
+ break;
+
+ case 'private':
+ $art->setsecure(1);
+ $app->update($art);
+ break;
+
+ case 'public':
+ $art->setsecure(0);
+ $app->update($art);
+ break;
+ }
+ break;
+
+ case 'set template':
+ if (isset($_POST['masstemplate'])) {
+ $art->settemplate($_POST['masstemplate']);
+ $app->update($art);
+ }
+ break;
+
+ case 'add tag':
+ if (isset($_POST['targettag'])) {
+ $art = $app->get($id);
+ $tagstring = strip_tags(trim(strtolower($_POST['targettag'])));
+ $taglist = str_replace(' ', '', $tagstring);
+ $taglist = explode(",", $taglist);
+ foreach ($taglist as $tag) {
+ if (!in_array($tag, $art->tag('array'))) {
+ $newtaglist = $art->tag('array');
+ array_push($newtaglist, $tag);
+ $art->settag($newtaglist);
+ }
+ }
+ $app->update($art);
+ }
+ break;
+
+ }
+
+
+
+
+ }
+ header('Location: ./');
+ }
+ break;
+ }
+ }
+}
+
+
+
+
+
+if (isset($_POST['actiondb'])) {
+ $app->setbdd($config);
+
+ switch ($_POST['actiondb']) {
+
+ case 'addtable':
+ if (isset($_POST['tablename'])) {
+ $message = $app->addtable($config->dbname(), $_POST['tablename']);
+ header('Location: ./?aff=admin&message=' . $message);
+ }
+ break;
+
+ case 'duplicatetable':
+ $message = $app->tableduplicate($config->dbname(), $_POST['arttable'], $_POST['tablename']);
+ header('Location: ./?aff=admin&message=' . $message);
+ break;
+
+ }
+}
+
+
+
+
+// _______________________________________________________ H E A D _____________________________________________________________
+
+if (isset($_GET['id'])) {
+ $app->bddinit($config);
+ if ($app->exist($_GET['id'])) {
+ $art = $app->get($_GET['id']);
+ if (!isset($_GET['edit'])) {
+ $_GET['edit'] = 0;
+ }
+ $aff->arthead($art, $app::GLOBAL_CSS_DIR, $_GET['edit']);
+ } else {
+ // $aff->head($_GET['id'], '', 'white');
+ $aff->noarthead($_GET['id'], $app::GLOBAL_CSS_DIR);
+
+ }
+} elseif (isset($_GET['aff'])) {
+ $aff->head($_GET['aff'], $_GET['aff'], $config->color4());
+} else {
+ $aff->head('home', 'home', $config->color4());
+}
+
+
+
+
+
+
+
+// _____________________________________________________ A L E R T _______________________________________________________________
+
+if (isset($_GET['message'])) {
+ echo '<span class="alert">' . $_GET['message'] . '</span>';
+}
+
+
+
+
+
+
+
+
+// ______________________________________________________ B O D Y _______________________________________________________________
+
+
+$aff->nav($app);
+
+if (array_key_exists('id', $_GET)) {
+ $app->bddinit($config);
+ include(__DIR__ . '/controller/w.article.php');
+} elseif (array_key_exists('tag', $_GET)) {
+ $app->bddinit($config);
+ echo '<h4>' . $_GET['tag'] . '</h4>';
+ $aff->tag($app->getlister(['id', 'title', 'description', 'tag']), $_GET['tag'], $app);
+} elseif (array_key_exists('linkfrom', $_GET)) {
+ $app->bddinit($config);
+ echo '<h4><a href="?id=' . $_GET['linkfrom'] . '">' . $_GET['linkfrom'] . '</a></h4>';
+ $aff->linkfrom($app->getlister(['id', 'title', 'description', 'linkfrom']), $_GET['linkfrom'], $app);
+} elseif (array_key_exists('aff', $_GET)) {
+ include(__DIR__ . '/controller/w.menu.php');
+} else {
+ include(__DIR__ . '/controller/w.home.php');
+}
+
+?> \ No newline at end of file
diff --git a/app/view/templates/arthead.php b/app/view/templates/arthead.php
new file mode 100644
index 0000000..b137c7f
--- /dev/null
+++ b/app/view/templates/arthead.php
@@ -0,0 +1,6 @@
+<meta charset="utf8" />
+<meta name="viewport" content="width=device-width" />
+<link rel="shortcut icon" href="./media/logo.png" type="image/x-icon">
+<title><?= $title ?></title>
+<meta name="description" content="<?= $description ?>">
+<link rel="stylesheet" href="./css/soft.css"> \ No newline at end of file
diff --git a/app/view/templates/body.php b/app/view/templates/body.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/view/templates/body.php
diff --git a/app/view/templates/connect.php b/app/view/templates/connect.php
new file mode 100644
index 0000000..3e2aeba
--- /dev/null
+++ b/app/view/templates/connect.php
@@ -0,0 +1,30 @@
+<?php $this->layout('layout', ['title' => 'Connect', 'description' => 'connect']) ?>
+
+
+
+
+<?php $this->start('page') ?>
+
+<span>
+<?= $user->level() ?>
+</span>
+
+<?php if($user->isvisitor()) { ?>
+
+<form action="./?action=login" method="post">
+<input type="password" name="pass" id="loginpass" placeholder="password">
+<input type="submit" value="login">
+</form>
+
+
+<?php } else { ?>
+
+<form action="./?action=logout" method="post">
+<input type="submit" value="logout">
+</form>
+
+
+
+<?php } ?>
+
+<?php $this->stop() ?> \ No newline at end of file
diff --git a/app/view/templates/delete.php b/app/view/templates/delete.php
new file mode 100644
index 0000000..be54451
--- /dev/null
+++ b/app/view/templates/delete.php
@@ -0,0 +1,44 @@
+<?php $this->layout('layout', ['title' => 'delete', 'description' => 'delete']) ?>
+
+
+<?php $this->start('page') ?>
+
+
+<?php $this->insert('navart', ['user' => $user, 'art' => $art, 'artexist' => $artexist]) ?>
+
+<div>
+
+<h1>Delete</h1>
+
+<ul>
+<li>Id : <?= $art->title() ?></li>
+<li>Title : <?= $art->title() ?></li>
+<li>Article(s) linked to this one : <?= $art->linkto('sort') ?></li>
+<li>Article(s) linked from this one : <?= $art->linkfrom('sort') ?></li>
+<li>Number of edits : <?= $art->editcount() ?></li>
+</ul>
+
+<?php if (!empty($art->linkto())) { ?>
+
+<h2>Article linked to :</h2>
+
+<ul>
+<?php foreach ($art->linkto('array') as $linkto) {
+ echo '<li><a href="./?id=' . $linkto . '">' . $linkto . '</a></li>';
+} ?>
+</ul>
+
+<?php
+} ?>
+
+</div>
+
+
+<form action="./?id=<?= $art->id() ?>&action=delete" method="post">
+<input type="hidden" name="deleteconfirm" value="true">
+<input type="submit" value="confirm delete">
+</form>
+
+
+
+<?php $this->stop() ?> \ No newline at end of file
diff --git a/app/view/templates/edit.php b/app/view/templates/edit.php
new file mode 100644
index 0000000..33d42f4
--- /dev/null
+++ b/app/view/templates/edit.php
@@ -0,0 +1,35 @@
+<?php $this->layout('layout', ['title' => '✏ '.$art->title()]) ?>
+
+
+
+
+<?php $this->start('page') ?>
+
+<style>.tabs textarea{font-size: <?= Config::fontsize() ?>px}</style>
+
+<body>
+<section class="editor">
+
+ <?php $this->insert('navart', ['user' => $user, 'art' => $art, 'artexist' => $artexist]) ?>
+
+
+
+ <?php $this->insert('edittopbar', ['art' => $art]) ?>
+
+ <div id="workspace">
+
+ <?php $this->insert('editleftbar', ['art' => $art, 'tablist' => $tablist, 'artlist' => $artlist, 'showleftpanel' => $showleftpanel]) ?>
+ <?php $this->insert('edittabs', ['tablist' => $tablist, 'opentab' => $art->interface()]) ?>
+ <?php $this->insert('editrightbar', ['art' => $art, 'artlist' => $artlist, 'showrightpanel' => $showrightpanel]) ?>
+
+ </div>
+
+
+<input type="hidden" name="id" value="<?= $art->id() ?>">
+
+</form>
+
+</section>
+</body>
+
+<?php $this->stop() ?> \ No newline at end of file
diff --git a/app/view/templates/edithelp.php b/app/view/templates/edithelp.php
new file mode 100644
index 0000000..fee94c7
--- /dev/null
+++ b/app/view/templates/edithelp.php
@@ -0,0 +1,27 @@
+
+ <h2>Help !</h2>
+ <p>To save your article, press the HOME, UPDATE, or DISPLAY buttons. You can use the keyboard shortcuts as well.</p>
+ <pre><span class="i">ALT + W</span> : home</pre>
+ <pre><span class="i">ALT + X</span> : update</pre>
+ <pre><span class="i">ALT + C</span> : display</pre>
+ <h3>Markdown</h3>
+ <p>The html section use <a href="https://daringfireball.net/projects/markdown/syntax" target="_blank">Markdown encoding</a>. Actualy, W is using Michel Fortin's <a href="https://michelf.ca/projects/php-markdown/extra/" target="_blank">Markdown Extra</a>.</p>
+ <h3>Links</h3>
+ <pre>[text](=<span class="i">article_id</span>)</pre>
+ <p>where article_id is the article's id you want to point to.</p>
+ <h3>Images</h3>
+ <pre>[altimage](/<span class="i">img_id.extension</span>)</pre>
+ <p>Where img_id is the id of your image and its extension.</p>
+ <h3>Shortcuts</h3>
+ <pre>%TITLE%</pre>
+ <p>Show the title of your article.</p>
+ <pre>%DESCRIPTION%</pre>
+ <p>Show the description of your article.</p>
+ <pre>%SUMMARY%</pre>
+ <p>Generate a <strong>summary</strong>, the list of all your head titles using #, ##, ###...</p>
+ <pre>%%<span class="i">tag_name</span>%%</pre>
+ <p>Generate a <strong>menu</strong>, a list of links to all articles under this tag.</p>
+ <p>vv</p>
+ <p>vv</p>
+ <p>vv</p>
+ <p></p> \ No newline at end of file
diff --git a/app/view/templates/editleftbar.php b/app/view/templates/editleftbar.php
new file mode 100644
index 0000000..7533599
--- /dev/null
+++ b/app/view/templates/editleftbar.php
@@ -0,0 +1,70 @@
+<div id="leftbar">
+ <input id="showleftpanel" name="workspace[showleftpanel]" value="1" class="toggle" type="checkbox" <?= $showleftpanel == true ? 'checked' : '' ?>>
+ <label for="showleftpanel" class="toogle">◧</label>
+ <div id="leftbarpanel" class="panel">
+ <details id="editinfo" open>
+ <summary>Infos</summary>
+ <fieldset>
+ <label for="title">title :</label>
+ <input type="text" name="title" id="title" value="<?= $art->title(); ?>">
+ <label for="description">Description :</label>
+ <input type="text" name="description" id="description" value="<?= $art->description(); ?>">
+ <label for="tag">Tag(s) :</label>
+ <input type="text" name="tag" id="tag" value="<?= $art->tag('string'); ?>">
+ <label for="secure">Privacy level :</label>
+ <select name="secure" id="secure">
+ <option value="0" <?= $art->secure() == 0 ? 'selected' : '' ?>>0</option>
+ <option value="1" <?= $art->secure() == 1 ? 'selected' : '' ?>>1</option>
+ <option value="2" <?= $art->secure() == 2 ? 'selected' : '' ?>>2</option>
+ <option value="3" <?= $art->secure() == 3 ? 'selected' : '' ?>>3</option>
+ </select>
+ </fieldset>
+ </details>
+ <details>
+ <summary>Advanced</summary>
+ <fieldset>
+ <h3>Template options</h3>
+ <ul>
+ <?php
+ foreach ($tablist as $element => $value) {
+ if(isset($art->template()[$element])) {
+ $template = $art->template()[$element];
+ } else {
+ $template = '';
+ }
+ echo '<li>';
+ echo '<label for="'.$element.'template">'.$element.'</label>';
+ echo '<select name="template['.$element.']" id="'.$element.'template">';
+ ?>
+ <option value="" <?= $template === '' ? 'selected' : '' ?>>--no template--</option>
+ <?php
+ foreach ($artlist as $artid ) {
+
+ ?>
+ <option value="<?= $artid ?>" <?= $template === $artid ? 'selected' : '' ?>><?= $artid ?></option>
+ <?php
+ }
+ echo '</select>';
+ echo '</li>';
+ }
+
+
+ ?>
+ </ul>
+ </fieldset>
+ </details>
+ <details id="editcss" open>
+ <summary>Quick CSS</summary>
+
+ </details>
+ <details>
+ <summary>Help</summary>
+ <div id="help">
+ <?php $this->insert('edithelp') ?>
+
+ </div>
+ </details>
+
+ </div>
+
+</div> \ No newline at end of file
diff --git a/app/view/templates/editrightbar.php b/app/view/templates/editrightbar.php
new file mode 100644
index 0000000..92d5f81
--- /dev/null
+++ b/app/view/templates/editrightbar.php
@@ -0,0 +1,20 @@
+<div id="rightbar">
+ <input id="showrightpanel" name="workspace[showrightpanel]" value="1" class="toggle" type="checkbox" <?= $showrightpanel == true ? 'checked' : '' ?>>
+ <label for="showrightpanel" class="toogle">◧</label>
+ <div id="rightbarpanel" class="panel">
+ <details id="linkassist" open>
+ <summary>Links</summary>
+ <?php
+ foreach ($artlist as $item ) {
+ ?>
+ <a href="?id=<?= $item ?>&aff=edit"><?= $item ?></a>
+ <input type="text" value="[<?= $item ?>](=<?= $item ?>)">
+ <?php
+ }
+
+ ?>
+ </details>
+
+ </div>
+
+</div> \ No newline at end of file
diff --git a/app/view/templates/edittabs.php b/app/view/templates/edittabs.php
new file mode 100644
index 0000000..efb1650
--- /dev/null
+++ b/app/view/templates/edittabs.php
@@ -0,0 +1,19 @@
+<div class="tabs">
+
+<?php
+foreach ($tablist as $key => $value) {
+ echo '<div class="tab">';
+ if ($key == $opentab) {
+ echo '<input name="interface" type="radio" value="'.$key.'" id="tab' . $key . '" class="checkboxtab" checked>';
+ } else {
+ echo '<input name="interface" type="radio" value="'.$key.'" id="tab' . $key . '" class="checkboxtab">';
+ }
+ echo '<label for="tab' . $key . '">' . $key . '</label>';
+ echo '<div class="content">';
+ echo '<textarea name="' . $key . '" id="' . $key . '" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">' . $value . '</textarea>';
+ echo '</div>';
+ echo '</div>';
+}
+?>
+
+</div> \ No newline at end of file
diff --git a/app/view/templates/edittopbar.php b/app/view/templates/edittopbar.php
new file mode 100644
index 0000000..20c2d8b
--- /dev/null
+++ b/app/view/templates/edittopbar.php
@@ -0,0 +1,29 @@
+<div id="topbar">
+ <form id="delete" action="./" method="get">
+ <input type="hidden" name="id" value="<?= $art->id() ?>">
+ </form>
+
+ <form action="?id=<?= $art->id() ?>&action=update" method="post" id="update">
+
+ <span>
+ <input type="submit" name="action" value="update" accesskey="x" form="update">
+ </span>
+
+
+ <span>
+ <input type="submit" name="action" value="delete" form="delete">
+ </span>
+
+
+ <span>
+ <a href="?id=<?= $art->id() ?>" target="_blank">👁</a>
+ <a href="?id=<?= $art->id() ?>&aff=log" target="_blank">¶</a>
+ </span>
+ <span id="headid"><?= $art->id() ?></span>
+
+<span>
+
+ <label for="fontsize">Font-size</label>
+ <input type="number" name="fontsize" value="<?= Config::fontsize() ?>" id="fontsize">
+</span>
+</div> \ No newline at end of file
diff --git a/app/view/templates/home.php b/app/view/templates/home.php
new file mode 100644
index 0000000..2303f0f
--- /dev/null
+++ b/app/view/templates/home.php
@@ -0,0 +1,109 @@
+<?php $this->layout('layout', ['title' => 'home']) ?>
+
+
+
+
+<?php $this->start('page') ?>
+
+
+<body>
+
+ <?php $this->insert('navback', ['user' => $user]) ?>
+
+<?php if($user->canedit()) { ?>
+
+<section>
+
+<div>
+
+<form id="goto" action="./" method="get">
+<input type="text" name="id" placeholder="id" required>
+<input type="submit" name="aff" value="read">
+<input type="submit" name="aff" value="edit">
+<input type="submit" name="action" value="add">
+</form>
+
+
+<form action="./" method="get">
+<input type="submit" name="action" value="analyseall">
+</form>
+
+
+</div>
+
+
+<div id="flex">
+
+
+ <?php $this->insert('homeopt', ['opt' => $opt]) ?>
+
+
+
+<div id="main">
+<h2>Articles</h2>
+<form action="./" method="post">
+
+
+ <div id="massedit">
+ <h3>Mass Edit</h3>
+ <select name="massedit" required>
+ <option value="public">set as public</option>
+ <option value="private">set as private</option>
+ <option value="not published">set as not published</option>
+ <option value="erasetag">erase all tags</option>
+ <option value="erasetemplate">erase template</option>
+ <option value="delete">delete</option>
+ </select>
+
+ <input type="submit" name="massaction" value="do" onclick="confirmSubmit(event, 'Are you sure')" >
+
+ <input type="text" name="targettag" placeholder="add tag">
+ <input type="submit" name="massaction" value="add tag" onclick="confirmSubmit(event, 'Are you sure')" >
+
+ <select name="masstemplate">
+ <?php
+ foreach ($table2 as $art) {
+ echo '<option value="' . $art->id() . '">' . $art->id() . '</option>';
+ }
+ ?>
+ </select>
+
+ <input type="submit" name="massaction" value="set template" onclick="confirmSubmit(event, 'Are you sure')" >
+
+ <input type="hidden" name="action" value="massedit">
+ </div>
+
+
+ <table id="home2table">
+ <tr><th>x</th><th>id</th><th>edit</th><th>see</th><th>del</th><th>log</th><th>tag</th><th>summary</th><th>↘ to</th><th>↗ from</th><th>last modification</th><th>date of creation</th><th>privacy</th></tr>
+ <?php foreach ($table2 as $item) { ?>
+ <tr>
+ <td><input type="checkbox" name="id[]" value="<?= $item->id() ?>" id="<?= $item->id() ?>"></td>
+ <td><label title="<?= $item->title() ?>" for="<?= $item->id() ?>"><?= $item->id() ?></label></td>
+ <td><a href="?id=<?= $item->id() ?>&aff=edit">✏</a></td>
+ <td><a href="?id=<?= $item->id() ?>" target="_blank">👁</a></td>
+ <td><a href="?id=<?= $item->id() ?>&action=delete" >🗑</a></td>
+ <td><a href="?id=<?= $item->id() ?>&aff=log" target="_blank">¶</a></td>
+ <td><?= $item->tag('sort') ?></td>
+ <td><?= $item->description() ?></td>
+ <td><?= $item->linkto('sort') ?></td>
+ <td><?= $item->linkfrom('sort') ?></td>
+ <td><?= $item->datemodif('hrdi') ?></td>
+ <td><?= $item->datecreation('hrdi') ?></td>
+ <td><?= $item->secure('string') ?></td>
+ </tr>
+
+ <?php }?>
+ </table>
+</form>
+</div>
+</div>
+</section>
+
+<?php } ?>
+
+</body>
+
+
+
+<?php $this->stop() ?> \ No newline at end of file
diff --git a/app/view/templates/homeopt.php b/app/view/templates/homeopt.php
new file mode 100644
index 0000000..cecb79b
--- /dev/null
+++ b/app/view/templates/homeopt.php
@@ -0,0 +1,84 @@
+<div id="options">
+<h2>Options</h2>
+<form action="./" method="get" >
+<input type="submit" name="submit" value="filter">
+⬅<input type="submit" name="submit" value="reset">
+
+
+ <!-- $this->optionsort($opt);
+ $this->optionprivacy($opt);
+ $this->optiontag($opt); -->
+
+<fieldset><legend>Sort</legend>
+<select name="sortby" id="sortby">
+<?php
+foreach ($opt->col('array') as $key => $col) {
+ echo '<option value="' . $col . '" ' . ($opt->sortby() == $col ? "selected" : "") . '>' . $col . '</option>';
+}
+?>
+</select>
+</br>
+<input type="radio" id="asc" name="order" value="1" <?= $opt->order() == '1' ? "checked" : "" ?>/><label for="asc">ascending</label>
+</br>
+<input type="radio" id="desc" name="order" value="-1" <?= $opt->order() == '-1' ? "checked" : "" ?>/><label for="desc">descending</label>
+
+</fieldset>
+
+<fieldset><legend>Privacy</legend><ul>
+<li><input type="radio" id="4" name="secure" value="4"<?= $opt->secure() == 4 ? "checked" : "" ?>/><label for="4">all</label></li>
+<li><input type="radio" id="3" name="secure" value="3"<?= $opt->secure() == 3 ? "checked" : "" ?>/><label for="3">editor</label></li>
+<li><input type="radio" id="2" name="secure" value="2"<?= $opt->secure() == 2 ? "checked" : "" ?>/><label for="2">invite only</label></li>
+<li><input type="radio" id="1" name="secure" value="1"<?= $opt->secure() == 1 ? "checked" : "" ?>/><label for="1">private</label></li>
+<li><input type="radio" id="0" name="secure" value="0"<?= $opt->secure() == 0 ? "checked" : "" ?>/><label for="0">public</label></li>
+</ul></fieldset>
+
+ <fieldset><legend>Tag</legend><ul>
+
+
+<input type="radio" id="OR" name="tagcompare" value="OR" ' . <?= $opt->tagcompare() == "OR" ? "checked" : "" ?> ><label for="OR">OR</label>
+<input type="radio" id="AND" name="tagcompare" value="AND" <?= $opt->tagcompare() == "AND" ? "checked" : "" ?>><label for="AND">AND</label>
+
+<?php
+$in = false;
+$out = false;
+$limit = 1;
+foreach ($opt->taglist() as $tagfilter => $count) {
+
+ if ($count > $limit && $in == false) {
+ echo '<details open><summary>>' . $limit . '</summary>';
+ $in = true;
+ }
+ if ($count == $limit && $in == true && $out == false) {
+ echo '</details><details><summary>' . $limit . '</summary>';
+ $out = true;
+ }
+
+ if (in_array($tagfilter, $opt->tagfilter())) {
+
+ echo '<li><input type="checkbox" name="tagfilter[]" id="' . $tagfilter . '" value="' . $tagfilter . '" checked /><label for="' . $tagfilter . '">' . $tagfilter . ' (' . $count . ')</label></li>';
+ } else {
+ echo '<li><input type="checkbox" name="tagfilter[]" id="' . $tagfilter . '" value="' . $tagfilter . '" /><label for="' . $tagfilter . '">' . $tagfilter . ' (' . $count . ')</label></li>';
+ }
+}
+if ($in = true || $out = true) {
+ echo '</details>';
+}
+?>
+
+</ul></fieldset>
+
+ <?php
+ if ($opt->invert() == 1) {
+ echo '<input type="checkbox" name="invert" value="1" id="invert" checked>';
+ } else {
+ echo '<input type="checkbox" name="invert" value="1" id="invert">';
+ }
+ echo '<label for="invert">invert</></br>';
+ ?>
+
+
+<input type="submit" name="submit" value="filter">
+⬅<input type="submit" name="submit" value="reset">
+
+</form>
+</div>
diff --git a/app/view/templates/layout.php b/app/view/templates/layout.php
new file mode 100644
index 0000000..7439f48
--- /dev/null
+++ b/app/view/templates/layout.php
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf8" />
+
+ <meta name="viewport" content="width=device-width" />
+ <link rel="shortcut icon" href="./media/logo.png" type="image/x-icon">
+ <title><?= $title ?></title>
+ <link rel="stylesheet" href="./../public/css/soft.css">
+ <?=$this->section('customhead')?>
+ <?=$this->section('arthead')?>
+
+</head>
+
+
+
+<?=$this->section('page')?>
+
+
+</html> \ No newline at end of file
diff --git a/app/view/templates/media.php b/app/view/templates/media.php
new file mode 100644
index 0000000..8b189d5
--- /dev/null
+++ b/app/view/templates/media.php
@@ -0,0 +1,4 @@
+<?php $this->layout('base', ['title' => 'Media']) ?>
+
+<h1>Media</h1>
+<p>Hello, <?=$this->e($interface)?></p> \ No newline at end of file
diff --git a/app/view/templates/navart.php b/app/view/templates/navart.php
new file mode 100644
index 0000000..b6a7219
--- /dev/null
+++ b/app/view/templates/navart.php
@@ -0,0 +1,85 @@
+<style>
+.menu {
+ all:initial;
+ position: fixed;
+ top: 0;
+ right: 0;
+ z-index: 10;
+ background-color: var(--color1);
+}
+
+div#dropmenu {
+ display: none;
+}
+
+.menu:hover div#dropmenu {
+ display: block;
+}
+
+</style>
+
+
+<div class="menu" >
+ <?= $user->level() ?>
+ <div id="dropmenu">
+
+ <ul>
+
+ <li>
+ <a class="button" href="./">home</a>
+ </li>
+
+
+<?php if($user->isvisitor()) { ?>
+
+ <li>
+ <form action="./?action=login<?= $art->id() !== null ? '&id=' . $art->id() : '' ?>" method="post">
+ <input type="password" name="pass" id="loginpass" placeholder="password">
+ <input type="submit" value="login">
+ </form>
+ </li>
+
+<?php } else { ?>
+
+ <li>
+ <form action="./?action=logout<?= $art->id() !== null ? '&id=' . $art->id() : '' ?>" method="post">
+ <input type="submit" value="logout">
+ </form>
+ </li>
+
+<?php } ?>
+
+
+<?php if($user->canedit() && $artexist) { ?>
+
+ <li>
+ <a class="button" href="?id=<?=$art->id() ?>" target="_blank">display</a>
+ </li>
+ <li>
+ <a class="button" href="?id=<?=$art->id() ?>&aff=edit" >edit</a>
+ </li>
+
+<?php } ?>
+
+
+<?php if ($user->canedit()) { ?>
+
+ <li>
+ <a class="button" href="?aff=media" >Media</a>
+ </li>
+
+<?php } ?>
+
+<?php if($user->isadmin()) { ?>
+
+ <li>
+ <a class="button" href="?aff=admin" >Admin</a>
+ </li>
+
+<?php } ?>
+
+
+
+
+ </div>
+</div> \ No newline at end of file
diff --git a/app/view/templates/navback.php b/app/view/templates/navback.php
new file mode 100644
index 0000000..c738ae2
--- /dev/null
+++ b/app/view/templates/navback.php
@@ -0,0 +1,54 @@
+<div class="menu">
+ <?= $user->level() ?>
+ <div id="dropmenu">
+
+ <ul>
+
+ <li>
+ <a class="button" href="./">home</a>
+ </li>
+
+
+<?php if($user->isvisitor()) { ?>
+
+ <li>
+ <form action="?action=login" method="post">
+ <input type="password" name="pass" id="loginpass" placeholder="password">
+ <input type="submit" value="login">
+ </form>
+ </li>
+
+<?php } else { ?>
+
+ <li>
+ <form action="?action=logout" method="post">
+ <input type="submit" value="logout">
+ </form>
+ </li>
+
+<?php } ?>
+
+
+
+
+<?php if ($user->canedit()) { ?>
+
+ <li>
+ <a class="button" href="?aff=media" >Media</a>
+ </li>
+
+<?php } ?>
+
+<?php if($user->isadmin()) { ?>
+
+ <li>
+ <a class="button" href="?aff=admin" >Admin</a>
+ </li>
+
+<?php } ?>
+
+
+ </ul>
+
+ </div>
+</div> \ No newline at end of file
diff --git a/app/view/templates/read.php b/app/view/templates/read.php
new file mode 100644
index 0000000..35b1e7d
--- /dev/null
+++ b/app/view/templates/read.php
@@ -0,0 +1,67 @@
+<?php $this->layout('readerlayout') ?>
+
+<?php
+$this->start('head');
+
+if ($artexist) {
+ if ($canread) {
+ echo $head;
+ } else {
+ $this->insert('arthead', ['title' => $art->title(), 'description' => $art->description()]);
+ }
+} else {
+ $this->insert('arthead', ['title' => $art->id(), 'description' => $alertnotexist]);
+}
+
+
+
+$this->stop();
+?>
+
+
+
+
+
+
+
+
+
+<?php $this->start('page') ?>
+
+ <body>
+
+
+
+ <?php
+ if ($readernav) {
+ $this->insert('navart', ['user' => $user, 'art' => $art, 'artexist' => $artexist]);
+ }
+ ?>
+
+
+
+ <?php
+
+ if ($artexist) {
+
+ if ($canread) {
+ echo $body;
+ } else {
+ echo '<h1>'.$alertprivate.'</h1>';
+ }
+
+ } else {
+ echo '<h1>' . $alertnotexist . '</h1>';
+ if ($cancreate) {
+ $this->insert('readcreate', ['id' => $art->id()]);
+ }
+ }
+
+
+
+ ?>
+
+
+ </body>
+
+<?php $this->stop() ?> \ No newline at end of file
diff --git a/app/view/templates/readart.php b/app/view/templates/readart.php
new file mode 100644
index 0000000..e44877d
--- /dev/null
+++ b/app/view/templates/readart.php
@@ -0,0 +1,25 @@
+<script>
+<?=$art->javascript() ?>
+</script>
+
+<body>
+
+<header>
+<?=$art->header()?>
+</header>
+
+<nav>
+<?=$art->nav()?>
+</nav>
+
+<aside>
+<?=$art->aside()?>
+</aside>
+
+<section>
+<?=$art->section()?>
+</section>
+
+<footer>
+<?=$art->footer()?>
+</footer>
diff --git a/app/view/templates/readcreate.php b/app/view/templates/readcreate.php
new file mode 100644
index 0000000..dc36420
--- /dev/null
+++ b/app/view/templates/readcreate.php
@@ -0,0 +1,5 @@
+<form action="./" method="get">
+<input type="hidden" name="id" value="<?= $id ?>">
+<input type="hidden" name="action" value="add">
+<input type="submit" value="create">
+</form> \ No newline at end of file
diff --git a/app/view/templates/readerlayout.php b/app/view/templates/readerlayout.php
new file mode 100644
index 0000000..51ab406
--- /dev/null
+++ b/app/view/templates/readerlayout.php
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+ <?=$this->section('head')?>
+
+
+</head>
+
+
+
+<?=$this->section('page')?>
+
+
+</html> \ No newline at end of file