Comment: | Remove modified from web pages, use file data instead, add ability to create page and category |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dev |
Files: | files | file ages | folders |
SHA3-256: |
1e99259f11164421f20181a463cde0e3 |
User & Date: | bohwaz on 2021-01-22 01:01:45 |
Other Links: | branch diff | manifest | tags |
2021-01-22
| ||
18:08 | Add page creation form check-in: 0a13ed8eac user: bohwaz tags: dev | |
01:01 | Remove modified from web pages, use file data instead, add ability to create page and category check-in: 1e99259f11 user: bohwaz tags: dev | |
2021-01-20
| ||
18:24 | Make web pages work again check-in: fac4232482 user: bohwaz tags: dev | |
Modified src/include/data/1.1.0_migration.sql from [3a241dc4a5] to [6ec9e829cb].
︙ | ︙ | |||
114 115 116 117 118 119 120 | INSERT INTO files_search (id, content) SELECT new_id, content FROM wiki_as_files WHERE encrypted = 0; UPDATE wiki_as_files SET new_id = (SELECT id FROM files WHERE hash = wiki_as_files.hash); UPDATE wiki_as_files SET new_parent = (SELECT w.new_id FROM wiki_as_files w WHERE w.old_id = wiki_as_files.old_parent); INSERT INTO web_pages | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | INSERT INTO files_search (id, content) SELECT new_id, content FROM wiki_as_files WHERE encrypted = 0; UPDATE wiki_as_files SET new_id = (SELECT id FROM files WHERE hash = wiki_as_files.hash); UPDATE wiki_as_files SET new_parent = (SELECT w.new_id FROM wiki_as_files w WHERE w.old_id = wiki_as_files.old_parent); INSERT INTO web_pages SELECT new_id, new_parent, type, 1, uri, title FROM wiki_as_files WHERE public = 1; -- Link transactions to files UPDATE files SET context = 2, context_ref = (SELECT id FROM fichiers_acc_transactions WHERE fichier = files.id) WHERE id IN (SELECT id FROM fichiers_acc_transactions WHERE fichier = files.id); -- Link background image file to config UPDATE files SET context = 3, context_ref = 'image_fond' WHERE id = (SELECT valeur FROM config WHERE cle = 'image_fond' AND valeur > 0); |
︙ | ︙ |
Modified src/include/data/1.1.0_schema.sql from [5689773e37] to [2d50efb549].
︙ | ︙ | |||
310 311 312 313 314 315 316 | CREATE TABLE IF NOT EXISTS web_pages ( id INTEGER NOT NULL PRIMARY KEY REFERENCES files(id), parent_id INTEGER NULL REFERENCES web_pages(id) ON DELETE SET NULL, type INTEGER NOT NULL, -- 1 = Category, 2 = Page status INTEGER NOT NULL DEFAULT 0, -- 0 = draft, 1 = online uri TEXT NOT NULL, | | < | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | CREATE TABLE IF NOT EXISTS web_pages ( id INTEGER NOT NULL PRIMARY KEY REFERENCES files(id), parent_id INTEGER NULL REFERENCES web_pages(id) ON DELETE SET NULL, type INTEGER NOT NULL, -- 1 = Category, 2 = Page status INTEGER NOT NULL DEFAULT 0, -- 0 = draft, 1 = online uri TEXT NOT NULL, title TEXT NOT NULL ); CREATE UNIQUE INDEX web_pages_uri ON web_pages (uri); CREATE TRIGGER IF NOT EXISTS web_page_insert AFTER INSERT ON web_pages BEGIN UPDATE files SET public = CASE WHEN NEW.status = 1 THEN 1 ELSE 0 END WHERE id = NEW.id; |
︙ | ︙ |
Modified src/include/lib/Garradin/Entities/Web/Page.php from [39d9abbabf] to [4ee1a90ae5].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php namespace Garradin\Entities\Web; use Garradin\DB; use Garradin\Entity; use Garradin\UserException; use Garradin\Entities\Files\File; use KD2\DB\EntityManager as EM; use const Garradin\WWW_URL; class Page extends Entity { const TABLE = 'web_pages'; protected $id; protected $parent_id; protected $type; protected $status; protected $title; protected $uri; | > < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <?php namespace Garradin\Entities\Web; use Garradin\DB; use Garradin\Entity; use Garradin\UserException; use Garradin\Utils; use Garradin\Entities\Files\File; use KD2\DB\EntityManager as EM; use const Garradin\WWW_URL; class Page extends Entity { const TABLE = 'web_pages'; protected $id; protected $parent_id; protected $type; protected $status; protected $title; protected $uri; protected $_types = [ 'id' => 'int', 'parent_id' => '?int', 'type' => 'int', 'status' => 'int', 'uri' => 'string', 'title' => 'string', ]; protected $_file; const STATUS_ONLINE = 1; const STATUS_DRAFT = 0; |
︙ | ︙ | |||
63 64 65 66 67 68 69 | { return $this->file()->created; } public function file(): File { if (null === $this->_file) { | > | > > > > > > > > > | > > > > > > > | > | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | { return $this->file()->created; } public function file(): File { if (null === $this->_file) { if ($this->exists()) { $this->_file = EM::findOneById(File::class, $this->id()); } else { $file = $this->_file = new File; $file->type = File::FILE_TYPE_SKRIV; $file->context = File::CONTEXT_WEB; $file->public = 1; $file->image = 0; } } return $this->_file; } public function setFile(File $file) { $this->_file = $file; } public function save(): bool { $file = $this->file(); $this->set('uri', Utils::transformTitleToURI($this->uri)); if ($this->type == self::TYPE_CATEGORY) { $file->set('name', 'index.skriv'); } else { $file->set('name', $this->uri . '.skriv'); } $file->set('modified', new \DateTime); $file->save(); $this->id($file->id()); return parent::save(); } |
︙ | ︙ | |||
129 130 131 132 133 134 135 | else { $file->set('type', File::FILE_TYPE_SKRIV); } return $this->import($source); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | else { $file->set('type', File::FILE_TYPE_SKRIV); } return $this->import($source); } public function render(array $options = []): string { return $this->file()->render(); } public function getBreadcrumbs() { |
︙ | ︙ |
Modified src/include/lib/Garradin/Web.php from [b23a9486c6] to [e30325c51a].
︙ | ︙ | |||
39 40 41 42 43 44 45 | $where = $parent ? sprintf('parent_id = %d', $parent) : 'parent_id IS NULL'; $sql = sprintf('SELECT * FROM @TABLE WHERE %s AND type = %d ORDER BY title COLLATE NOCASE;', $where, Page::TYPE_CATEGORY); return EM::getInstance(Page::class)->all($sql); } static public function listPages(?int $parent, bool $order_by_date = true): array { | | | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | $where = $parent ? sprintf('parent_id = %d', $parent) : 'parent_id IS NULL'; $sql = sprintf('SELECT * FROM @TABLE WHERE %s AND type = %d ORDER BY title COLLATE NOCASE;', $where, Page::TYPE_CATEGORY); return EM::getInstance(Page::class)->all($sql); } static public function listPages(?int $parent, bool $order_by_date = true): array { $where = $parent ? sprintf('w.parent_id = %d', $parent) : 'w.parent_id IS NULL'; $order = $order_by_date ? 'f.modified DESC' : 'w.title COLLATE NOCASE'; $sql = sprintf('SELECT w.* FROM @TABLE w INNER JOIN files f USING (id) WHERE %s AND w.type = %d ORDER BY %s;', $where, Page::TYPE_PAGE, $order); return EM::getInstance(Page::class)->all($sql); } static public function listCategoriesTree(?int $current = null): array { $db = DB::getInstance(); $flat = $db->get('SELECT id, parent_id, title FROM web_pages ORDER BY title COLLATE NOCASE;'); |
︙ | ︙ |
Modified src/include/lib/Garradin/Web/Skeleton.php from [e458f7bdb8] to [fa6cbff46b].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php namespace Garradin\Web; use Garradin\Files\Files; use Garradin\Entities\Files\File; use Garradin\UserException; use Garradin\UserTemplate; use KD2\Brindille_Exception; use const Garradin\ROOT; class Skeleton { const TEMPLATE_TYPES = '!^(?:text/(?:html|plain)|\w+/(?:\w+\+)?xml)$!'; | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php namespace Garradin\Web; use Garradin\Files\Files; use Garradin\Entities\Files\File; use Garradin\UserException; use Garradin\UserTemplate; use KD2\Brindille_Exception; use KD2\DB\EntityManager as EM; use const Garradin\ROOT; class Skeleton { const TEMPLATE_TYPES = '!^(?:text/(?:html|plain)|\w+/(?:\w+\+)?xml)$!'; |
︙ | ︙ | |||
120 121 122 123 124 125 126 | { if (!$this->file) { $this->file = new File; $this->file->import([ 'type' => $this->type(), 'name' => $this->name, 'image' => 0, | | < | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | { if (!$this->file) { $this->file = new File; $this->file->import([ 'type' => $this->type(), 'name' => $this->name, 'image' => 0, 'public' => 0, 'context' => File::CONTEXT_SKELETON, ]); } $this->file->store(null, $content); $this->file->save(); } |
︙ | ︙ | |||
185 186 187 188 189 190 191 | continue; $defaults[$file] = null; } $dir->close(); | | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | continue; $defaults[$file] = null; } $dir->close(); $modified_skeletons = EM::getInstance(File::class)->DB()->getGrouped('SELECT name, id, modified FROM files WHERE context = ? ORDER BY name;', File::CONTEXT_SKELETON); $sources = array_merge($defaults, $modified_skeletons); ksort($sources); return $sources; } } |
Modified src/templates/web/config.tpl from [31bee0260a] to [8a16e77e75].
︙ | ︙ | |||
91 92 93 94 95 96 97 | <td>Dernière modification</td> <td></td> </tr> </thead> <tbody> {foreach from=$sources key="source" item="local"} <tr> | | | | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | <td>Dernière modification</td> <td></td> </tr> </thead> <tbody> {foreach from=$sources key="source" item="local"} <tr> <td>{if $local.modified}<input type="checkbox" name="select[]" value="{$source}" id="f_source_{$iteration}" /><label for="f_source_{$iteration}"></label>{/if}</td> <th><a href="?edit={$source|escape:'url'}" title="Éditer">{$source}</a></th> <td>{if $local.modified}{$local.modified|date_fr:'d/m/Y à H:i:s'}{else}<em>(fichier non modifié)</em>{/if}</td> <td class="actions"> {linkbutton shape="edit" label="Éditer" href="?edit=%s"|args:$source} </td> </tr> {/foreach} </tbody> </table> |
︙ | ︙ |
Modified src/templates/web/edit.tpl from [08595d53aa] to [beb9c1a589].
︙ | ︙ | |||
9 10 11 12 13 14 15 | <form method="post" action="{$self_url}" class="web-edit"> <fieldset class="wikiMain"> <legend>Informations générales</legend> <dl> {input type="text" name="title" source=$page required=true label="Titre"} | > | > | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <form method="post" action="{$self_url}" class="web-edit"> <fieldset class="wikiMain"> <legend>Informations générales</legend> <dl> {input type="text" name="title" source=$page required=true label="Titre"} {if $page->exists()} {input type="text" name="uri" source=$page required=true label="Adresse unique URI" help="Utilisée pour désigner l'adresse de la page sur le site. Ne peut comporter que des lettres, des chiffres, des tirets et des tirets bas." pattern="[A-Za-z0-9_-]+"} {/if} {input type="list" name="parent_id" label="Catégorie" default=$parent target="web/_selector.php?parent=%d"|args:$page.parent_id required=true} {input type="datetime" name="date" label="Date" required=true default=$created} <dt>Statut</dt> {input type="radio" name="status" value=$page::STATUS_ONLINE label="En ligne" source=$page} {input type="radio" name="status" value=$page::STATUS_DRAFT label="Brouillon" source=$page help="ne sera pas visible sur le site"} </dl> </fieldset> <fieldset class="wikiEncrypt"> |
︙ | ︙ | |||
36 37 38 39 40 41 42 | il n'est pas possible de retrouver le contenu si vous l'oubliez.</dd> </dl> </fieldset> <fieldset class="wikiText"> <div class="textEditor"> | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | il n'est pas possible de retrouver le contenu si vous l'oubliez.</dd> </dl> </fieldset> <fieldset class="wikiText"> <div class="textEditor"> {input type="textarea" name="content" cols="70" rows="35" default=$new_content required=true} </div> </fieldset> <p class="submit"> {csrf_field key=$csrf_key} <input type="hidden" name="editing_started" value="{$editing_started}" /> {button type="submit" name="save" label="Enregistrer" shape="upload" class="main"} |
︙ | ︙ |
Modified src/templates/web/index.tpl from [28b776b678] to [655b65039b].
1 2 3 4 | {include file="admin/_head.tpl" title=$title current="web"} <nav class="tabs"> <aside> | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title=$title current="web"} <nav class="tabs"> <aside> {linkbutton shape="plus" label="Nouvelle page" href="edit.php?type=%d&parent=%d"|args:$type_page,$parent} {linkbutton shape="plus" label="Nouvelle catégorie" href="edit.php?type=%d&parent=%d"|args:$type_category,$parent} </aside> <ul> <li class="current"><a href="./">Gestion du site web</a></li> {if $session->canAccess($session::SECTION_WEB, Membres::DROIT_ADMIN)} {*<li><a href="theme.php">Thèmes</a></li>*} <li><a href="config.php">Configuration</a></li> {/if} |
︙ | ︙ | |||
33 34 35 36 37 38 39 | </td> </tr> {/foreach} </tbody> </table> {else} <p class="submit"> | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | </td> </tr> {/foreach} </tbody> </table> {else} <p class="submit"> {linkbutton class="main" shape="plus" label="Nouvelle catégorie" href="edit.php?type=%d&parent=%d"|args:$type_category,$parent} </p> {/if} {if count($pages)} <h2 class="ruler">Pages</h2> <p> {if !$order_date} |
︙ | ︙ | |||
68 69 70 71 72 73 74 | </td> </tr> {/foreach} </tbody> </table> {else} <p class="submit"> | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 | </td> </tr> {/foreach} </tbody> </table> {else} <p class="submit"> {linkbutton shape="plus" class="main" label="Nouvelle page" href="edit.php?type=%d&parent=%d"|args:$type_page,$parent} </p> {/if} {include file="admin/_foot.tpl"} |
Modified src/www/admin/web/config.php from [0eeba662a7] to [88ef818b0b].
1 2 3 | <?php namespace Garradin; | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?php namespace Garradin; use Garradin\Web\Skeleton; require_once __DIR__ . '/_inc.php'; $config = Config::getInstance(); if (f('desactiver_site') && $form->check('config_site')) { $config->set('desactiver_site', true); $config->save(); Utils::redirect(Utils::getSelfURI()); } elseif (f('activer_site') && $form->check('config_site')) { $config->set('desactiver_site', false); $config->save(); Utils::redirect(Utils::getSelfURI()); } $form->runIf('reset', function () { Skeleton::resetSelected(f('select')); }, 'squelettes', Utils::getSelfURI('reset_ok')); if (qg('edit')) { $source = trim(qg('edit')); $csrf_key = 'edit_skel_' . md5($source); $form->runIf('save', function () use ($source) { $tpl = new Skeleton($source); $tpl->edit(f('content')); $fullscreen = null !== qg('fullscreen') ? '#fullscreen' : ''; Utils::redirect(Utils::getSelfURI(sprintf('edit=%s&ok%s', rawurlencode($source), $fullscreen))); }, $csrf_key); $tpl->assign('edit', ['file' => $source, 'content' => (new Skeleton($source))->raw()]); $tpl->assign('csrf_key', $csrf_key); } $tpl->assign('sources', Skeleton::list()); $tpl->assign('reset_ok', qg('reset_ok') !== null); $tpl->assign('ok', qg('ok') !== null); $tpl->display('web/config.tpl'); |
Modified src/www/admin/web/edit.php from [aaebf502fe] to [41d79274e7].
1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; use Garradin\Web; use Garradin\Entities\Web\Page; use Garradin\Entities\Files\File; use KD2\SimpleDiff; require_once __DIR__ . '/_inc.php'; $id = (int) qg('id'); | > > | | | | > > > > > > > > > | > > | > > > > > | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | <?php namespace Garradin; use Garradin\Web; use Garradin\Entities\Web\Page; use Garradin\Entities\Files\File; use KD2\SimpleDiff; require_once __DIR__ . '/_inc.php'; $id = (int) qg('id'); if ($id) { $page = Web::get($id); if (!$page) { throw new UserException('Page inconnue'); } $csrf_key = 'web_edit_' . $page->id(); } else { $page = new Page; $page->set('parent_id', (int) qg('parent') ?: null); $page->set('type', (int) qg('type')); $page->set('status', Page::STATUS_ONLINE); $page->set('title', $page->type == Page::TYPE_CATEGORY ? 'Nouvelle catégorie' : 'Nouvel article'); $csrf_key = 'web_new'; } $editing_started = f('editing_started') ?: date('Y-m-d H:i:s'); if (f('cancel')) { Utils::redirect(ADMIN_URL . 'web/?parent=' . $page->parent_id); } $show_diff = false; $form->runIf('save', function () use ($page, $editing_started, &$show_diff) { $editing_started = new \DateTime($editing_started); if ($page->exists() && $editing_started < $page->modified) { $show_diff = true; throw new UserException('La page a été modifiée par quelqu\'un d\'autre pendant que vous éditiez le contenu.'); } $page->importForm(); if (!$page->exists()) { $page->set('uri', Utils::transformTitleToURI($page->title)); } $page->save(); }, $csrf_key, Utils::getSelfURI() . '#saved'); $parent = $page->parent_id ? [$page->parent_id => Web::get($page->parent_id)->title] : null; $encrypted = f('encrypted') || ($page->exists() && $page->file()->type == File::FILE_TYPE_ENCRYPTED); $old_content = f('content'); $new_content = $page->exists() ? $page->raw() : ''; $created = $page->exists() ? $page->file()->created : new \DateTime; $tpl->assign(compact('created', 'page', 'parent', 'editing_started', 'encrypted', 'csrf_key', 'old_content', 'new_content', 'show_diff')); $tpl->assign('custom_js', ['wiki_editor.js', 'wiki-encryption.js']); $tpl->assign('custom_css', ['wiki.css', 'scripts/wiki_editor.css']); $tpl->display('web/edit.tpl'); |