diff --git a/README.md b/README.md index 0cbade0..6be0d4c 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ luxtools provides DokuWiki syntax that: - Provides "open this folder/path" links for local workflows - Embeds file-backed scratchpads with a minimal inline editor (no wiki revisions) - Links a page to a media folder via a UUID (.pagelink), enabling a `blobs/` alias +- Adds a Page ID download link in the page info area to fetch a `.pagelink` file It also ships a small file-serving endpoint (`lib/plugins/luxtools/file.php`) used to deliver files and generate cached thumbnails. diff --git a/js/page-link.js b/js/page-link.js index 009b4f6..be75498 100644 --- a/js/page-link.js +++ b/js/page-link.js @@ -127,6 +127,45 @@ }); } + function attachDocInfoLink() { + var container = document.querySelector('.docInfo'); + if (!container || !container.getAttribute) return; + if (container.getAttribute('data-luxtools-pagelink-docinfo') === '1') return; + container.setAttribute('data-luxtools-pagelink-docinfo', '1'); + + var pageId = getPageId(); + if (!pageId) return; + + var endpoint = getBaseUrl() + 'lib/plugins/luxtools/pagelink.php'; + var query = endpoint + '?cmd=info&id=' + encodeURIComponent(pageId); + + window.fetch(query, { + method: 'GET', + credentials: 'same-origin' + }).then(function (res) { + return res.json().catch(function () { return null; }).then(function (body) { + if (!res.ok || !body || body.ok !== true) { + throw new Error('request failed'); + } + return body; + }); + }).then(function (info) { + if (!info || !info.uuid) return; + + var link = document.createElement('a'); + link.href = endpoint + '?cmd=download&id=' + encodeURIComponent(pageId); + link.textContent = 'Page ID: ' + String(info.uuid); + + var first = container.firstChild; + container.insertBefore(link, first); + if (first) { + container.insertBefore(document.createTextNode(' ยท '), first); + } + }).catch(function () { + // ignore failures + }); + } + window.addBtnActionLuxtoolsPageLink = function ($btn, props, edid) { $btn.on('click', function () { var pageId = getPageId(); @@ -165,5 +204,8 @@ return 'luxtools-pagelink'; }; - document.addEventListener('DOMContentLoaded', attachCopyTargets, false); + document.addEventListener('DOMContentLoaded', function () { + attachCopyTargets(); + attachDocInfoLink(); + }, false); })(); diff --git a/pagelink.php b/pagelink.php index 8eec4b1..52b0c97 100644 --- a/pagelink.php +++ b/pagelink.php @@ -46,12 +46,19 @@ if ($cmd === '' || $pageId === '') { luxtools_pagelink_json(400, ['ok' => false, 'error' => 'missing parameters']); } -if (!function_exists('auth_quickaclcheck') || !defined('AUTH_EDIT')) { +if (!function_exists('auth_quickaclcheck')) { luxtools_pagelink_json(403, ['ok' => false, 'error' => 'forbidden']); } -if (auth_quickaclcheck($pageId) < AUTH_EDIT) { - luxtools_pagelink_json(403, ['ok' => false, 'error' => 'forbidden']); +$acl = auth_quickaclcheck($pageId); +if ($cmd === 'info' || $cmd === 'download') { + if (!defined('AUTH_READ') || $acl < AUTH_READ) { + luxtools_pagelink_json(403, ['ok' => false, 'error' => 'forbidden']); + } +} else { + if (!defined('AUTH_EDIT') || $acl < AUTH_EDIT) { + luxtools_pagelink_json(403, ['ok' => false, 'error' => 'forbidden']); + } } if ($cmd === 'info') { @@ -83,6 +90,30 @@ if ($cmd === 'info') { ]); } +if ($cmd === 'download') { + $depth = (int)$syntax->getConf('pagelink_search_depth'); + if ($depth < 0) $depth = 0; + + $pageLink = new PageLink((string)$syntax->getConf('paths'), $depth); + $uuid = $pageLink->getPageUuid($pageId); + if ($uuid === null || $uuid === '') { + http_status(404); + header('Content-Type: text/plain; charset=utf-8'); + header('Cache-Control: no-store, no-cache, must-revalidate'); + header('Pragma: no-cache'); + echo 'not linked'; + exit; + } + + http_status(200); + header('Content-Type: text/plain; charset=utf-8'); + header('Content-Disposition: attachment; filename=".pagelink"'); + header('Cache-Control: no-store, no-cache, must-revalidate'); + header('Pragma: no-cache'); + echo $uuid; + exit; +} + if ($cmd === 'ensure') { if (strtoupper($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') { luxtools_pagelink_json(405, ['ok' => false, 'error' => 'method not allowed']);