From 8cd0fe80b86b8f0b3cd3f99e8f500feb80dda928 Mon Sep 17 00:00:00 2001 From: grandeljay Date: Thu, 24 Nov 2022 16:09:33 +0100 Subject: [PATCH] Refactor API --- .htaccess | 7 ++ src/api/wishlists.php | 18 ++-- src/assets/js/default.js | 9 +- src/assets/js/home.js | 20 +--- src/assets/js/html2canvas.js | 2 +- src/assets/js/inline.js.php | 28 ++++++ src/assets/js/install.js | 2 +- src/assets/js/parts/wishlists.js | 152 +++++++++++++++---------------- src/assets/js/wishlist.js | 13 +-- src/classes/url.php | 6 +- 10 files changed, 133 insertions(+), 124 deletions(-) diff --git a/.htaccess b/.htaccess index 6c895b2e..06f25a68 100644 --- a/.htaccess +++ b/.htaccess @@ -18,6 +18,13 @@ # Blog Post RewriteRule ^blog/([a-z\-0-9]+)$ /?page=post&slug=$1 [QSA,L] + + # API + RewriteRule ^api/([a-zA-Z\-0-9=]+)$ /?page=api&module=$1 [QSA,L] + + RewriteRule ^api/statistics/([a-zA-Z0-9=]+)$ /?page=api&module=statistics&table=$1 [QSA,L] + RewriteRule ^api/url/([a-zA-Z0-9=]+)$ /?page=api&module=url&url=$1 [QSA,L] + RewriteRule ^api/wishlists/([0-9]+)$ /?page=api&module=wishlists&wishlist_id=$1 [QSA,L] ##-- When caching of gzipped JS and CSS files is used, enable this setting diff --git a/src/api/wishlists.php b/src/api/wishlists.php index a4f3227b..ec3819fc 100644 --- a/src/api/wishlists.php +++ b/src/api/wishlists.php @@ -10,11 +10,6 @@ namespace wishthis; global $page, $database; -if (!isset($page)) { - http_response_code(403); - die('Direct access to this location is not allowed.'); -} - switch ($_SERVER['REQUEST_METHOD']) { case 'POST': if (isset($_POST['wishlist-name'], $_SESSION['user']->id)) { @@ -124,7 +119,16 @@ switch ($_SERVER['REQUEST_METHOD']) { */ $wishlist = new Wishlist($_GET['wishlist_id']); - $response['results'] = $wishlist; + if ($wishlist->exists) { + /** Determine if user is allowed to access wishlist */ + if ($_SESSION['user']->isLoggedIn() && $_SESSION['user']->id === $wishlist->user) { + $response['results'] = $wishlist; + } else { + http_response_code(403); + } + } else { + http_response_code(404); + } } elseif (isset($_GET['userid']) || isset($_SESSION['user']->id)) { /** * Get user wishlists @@ -165,7 +169,7 @@ switch ($_SERVER['REQUEST_METHOD']) { $database->query( 'DELETE FROM `wishlists` - WHERE `id` = ' . Sanitiser::getNumber($_DELETE['wishlistID']) . ';' + WHERE `id` = ' . Sanitiser::getNumber($_DELETE['wishlist_id']) . ';' ); $response['success'] = true; diff --git a/src/assets/js/default.js b/src/assets/js/default.js index ded7f358..0d0dc20f 100644 --- a/src/assets/js/default.js +++ b/src/assets/js/default.js @@ -16,14 +16,6 @@ $(function() { /** * Fomantic UI */ - /** API */ - $.fn.api.settings.api = { - 'get wishlists' : '/?page=api&module=wishlists', - 'get wishlists by priority' : '/?page=api&module=wishlists&style={style}&wishlist_id={wishlistid}&priority={priority}', - 'delete wishlist' : '/?page=api&module=wishlists', - 'update wish status' : '/?page=api&module=wishes', - 'delete wish' : '/?page=api&module=wishes', - }; /** Default callbacks */ $.fn.api.settings.onResponse = function(response) { @@ -210,6 +202,7 @@ function handleFetchError(response) { console.log(response); showError(response.statusText); + throw Error(response.statusText); } diff --git a/src/assets/js/home.js b/src/assets/js/home.js index f966b5aa..2cbc9679 100644 --- a/src/assets/js/home.js +++ b/src/assets/js/home.js @@ -2,16 +2,7 @@ $(function() { /** * Statistics */ - const params_statistics = new URLSearchParams( - { - 'module' : 'statistics', - 'page' : 'api', - - 'table' : 'all', - } - ); - - fetch('/?' + params_statistics, { + fetch('/api/statistics/all', { method: 'GET' }) .then(handleFetchError) @@ -65,14 +56,7 @@ $(function() { /** * News */ - const params_news = new URLSearchParams( - { - 'module' : 'blog', - 'page' : 'api', - } - ); - - fetch('/?' + params_news, { + fetch('/api/blog', { method: 'GET' }) .then(handleFetchError) diff --git a/src/assets/js/html2canvas.js b/src/assets/js/html2canvas.js index ec763341..3af996ce 100644 --- a/src/assets/js/html2canvas.js +++ b/src/assets/js/html2canvas.js @@ -20,7 +20,7 @@ window.addEventListener("load", (event) => { data.append('page', wishthis.$_GET.page); /** Save page preview */ - fetch('/?page=api&module=save-preview', { + fetch('/api/save-preview', { method : 'POST', body : data }) diff --git a/src/assets/js/inline.js.php b/src/assets/js/inline.js.php index fea90e8d..c36f45e2 100644 --- a/src/assets/js/inline.js.php +++ b/src/assets/js/inline.js.php @@ -148,4 +148,32 @@ global $options; } }, } + + /** + * Fomantic UI + */ + '/?page=api&module=wishlists', + 'get wishlists by priority' => '/?page=api&module=wishlists&style={style}&wishlist_id={wishlistid}&priority={priority}', + 'delete wishlist' => '/?page=api&module=wishlists', + 'update wish status' => '/?page=api&module=wishes', + 'delete wish' => '/?page=api&module=wishes', + ); + ?> + + document.addEventListener('DOMContentLoaded', function() { + /** API */ + $.fn.api.settings.api = { + $url) { + $url = new URL($url); + $pretty = $url->getPretty(); + + echo '\'' . $action . '\' : \'' . $pretty . '\',' . PHP_EOL; + } + ?> + }; + }); + diff --git a/src/assets/js/install.js b/src/assets/js/install.js index 5709b763..ba18fb66 100644 --- a/src/assets/js/install.js +++ b/src/assets/js/install.js @@ -9,7 +9,7 @@ $(function() { form.addClass('loading'); - fetch('/?page=api&module=database-test', { + fetch('/api/database-test', { method : 'POST', body : formDatabase }) diff --git a/src/assets/js/parts/wishlists.js b/src/assets/js/parts/wishlists.js index 9fc4fe18..f9174258 100644 --- a/src/assets/js/parts/wishlists.js +++ b/src/assets/js/parts/wishlists.js @@ -28,17 +28,7 @@ $(function () { dropdown_wishlists.dropdown('setup menu', dropdown_values); /** Select a dropdown item */ - if (!dropdown_wishlists.dropdown('get value')) { - if (wishthis.$_GET.id) { - dropdown_wishlists.dropdown('set selected', wishthis.$_GET.id); - } else { - if (Object.keys(wishlists).length >= 1) { - var first_wishlist_id = Object.keys(wishlists)[0]; - - dropdown_wishlists.dropdown('set selected', first_wishlist_id); - } - } - } + setDropdownWishlistsSelection(); /** Open add wish modal */ if (wishthis.$_GET.wish_add) { @@ -63,15 +53,7 @@ $(function () { if (wishlist_id) { /** Get wishlist */ - const get_wishlist = new URLSearchParams( - { - 'module' : 'wishlists', - 'page' : 'api', - - 'wishlist_id' : wishlist_id, - } - ); - fetch('/?' + get_wishlist, { method: 'GET' }) + fetch('/api/wishlists/' + wishlist_id, { method: 'GET' }) .then(handleFetchError) .then(handleFetchResponse) .then(function(response) { @@ -81,7 +63,7 @@ $(function () { wishlist = response.results; /** Set share link */ - $('.wishlist-share').attr('href', '/?page=wishlist&hash=' + wishlist.hash); + $('.wishlist-share').attr('href', '/wishlist/' + wishlist.hash); /** Enable wishlist options buttons */ $('.button.wishlist-wish-add').removeClass('disabled'); @@ -93,22 +75,7 @@ $(function () { /** Update URL */ urlParams.set('id', wishlist_id); - const params_url = new URLSearchParams( - { - 'module' : 'url', - 'page' : 'api', - - 'url' : window.btoa(urlParams.toString()), - } - ); - fetch('/?' + params_url, { - method: 'GET' - }) - .then(handleFetchError) - .then(handleFetchResponse) - .then(function(response) { - window.history.pushState(null, document.title, response.data.url_pretty); - }); + updateURL(); /** Get wishlist cards/wishes */ @@ -308,7 +275,7 @@ $(function () { var formData = new URLSearchParams(new FormData(formRename[0])); formData.append('wishlist_id', wishthis.$_GET.id); - fetch('/?page=api&module=wishlists', { + fetch('/api/wishlists', { method : 'PUT', body : formData, }) @@ -360,61 +327,61 @@ $(function () { /** * Delete Wishlist */ - $(document).on('click', '.options .wishlist-delete', function () { - var wishlist_id = $('.ui.dropdown.wishlists').dropdown('get value'); + $(document).on('click', '.wishlist-options .wishlist-delete', function () { + var wishlist_id = wishthis.$_GET.id; if (wishlist_id) { var modalDefault = $('.ui.modal.default'); modalDefault .modal({ - title : wishthis.strings.wishlist.delete.title, - class : 'tiny', - content : wishthis.strings.wishlist.delete.content.replace('WISHLIST_NAME', $('.ui.dropdown.wishlists').dropdown('get text')), - actions : [ + 'title' : wishthis.strings.modal.wishlist.delete.title, + 'class' : 'tiny', + 'content' : wishthis.strings.modal.wishlist.delete.content.replace('WISHLIST_NAME', $('.ui.dropdown.wishlists').dropdown('get text')), + 'actions' : [ { - text : wishthis.strings.wishlist.delete.approve, + text : wishthis.strings.modal.wishlist.delete.approve, class: 'approve red' }, { - text : wishthis.strings.wishlist.delete.deny, + text : wishthis.strings.modal.wishlist.delete.deny, class: 'deny' }, ], - autoShow : true, - onApprove: function (buttonApprove) { + 'autoShow' : true, + 'onApprove': function (buttonApprove) { buttonApprove.addClass('loading'); - $('.ui.dropdown.wishlists').api({ - action: 'delete wishlist', - method: 'DELETE', - data: { - 'wishlistID' : wishlist_id - }, - on: 'now', - onSuccess: function (response, wishlists) { - $('.wishlist-cards .column').fadeOut(800); - - wishlists.dropdown('clear'); - - urlParams.delete('id'); - - $('body').toast({ message : wishthis.strings.toast.wishlist.delete }); - - modalDefault.modal('hide'); - - setTimeout(() => { - $('.ui.dropdown.wishlists').api('query'); - }, 200); + var delete_wishlist = new URLSearchParams( + { + 'wishlist_id' : wishlist_id, } + ); + fetch('/api/wishlists', { + 'method' : 'DELETE', + 'body' : delete_wishlist, + }) + .then(handleFetchError) + .then(handleFetchResponse) + .then(function(response) { + $('.wishlist-cards .column').fadeOut(800); + + urlParams.delete('id'); + wishthis.$_GET.id = null; + updateURL(); + setDropdownWishlistsSelection(); + + $('.ui.dropdown.wishlists').api('query'); + + modalDefault.modal('hide'); + + $('body').toast({ message : wishthis.strings.toast.wishlist.delete }); + }) + .catch(handleFetchCatch) + .finally(function() { + buttonApprove.removeClass('loading'); }); - /** - * Return false is currently not working. - * - * @version 2.8.8 - * @see https://github.com/fomantic/Fomantic-UI/issues/2105 - */ return false; } }); @@ -664,7 +631,7 @@ $(function () { var formData = new URLSearchParams(new FormData(formWishlistCreate[0])); - fetch('/?page=api&module=wishlists', { + fetch('/api/wishlists', { method : 'POST', body : formData }) @@ -677,7 +644,9 @@ $(function () { $('body').toast({ message: wishthis.strings.toast.wish.create }); - $('.ui.dropdown.wishlists').api('query'); + $('.ui.dropdown.wishlists') + .api('query') + .dropdown('set value', response.data.lastInsertId); }) .finally(() => { formWishlistCreate.removeClass('loading'); @@ -846,5 +815,34 @@ $(function () { } } + /** + * Update URL + */ + function updateURL() { + fetch('/api/url/' + window.btoa('/?' + urlParams.toString()), { method: 'GET' }) + .then(handleFetchError) + .then(handleFetchResponse) + .then(function(response) { + window.history.pushState(null, document.title, response.data.url_pretty); + }); + } + /** + * Set dropdown wishlists seelction + */ + function setDropdownWishlistsSelection() { + var dropdown_wishlists = $('.ui.dropdown.wishlists'); + + if (!dropdown_wishlists.dropdown('get value')) { + if (wishthis.$_GET.id) { + dropdown_wishlists.dropdown('set selected', wishthis.$_GET.id); + } else { + if (Object.keys(wishlists).length >= 1) { + var first_wishlist_id = Object.keys(wishlists)[0]; + + dropdown_wishlists.dropdown('set selected', first_wishlist_id); + } + } + } + } }); diff --git a/src/assets/js/wishlist.js b/src/assets/js/wishlist.js index 793dcf5c..75b4bf03 100644 --- a/src/assets/js/wishlist.js +++ b/src/assets/js/wishlist.js @@ -90,7 +90,7 @@ $(function() { } ); - fetch('/?page=api&module=wishlists-saved', { + fetch('/api/wishlists-saved', { method : 'POST', body : formData }) @@ -113,14 +113,7 @@ $(function() { }); /** Determine if list is saved */ - const params_ws_saved = new URLSearchParams( - { - 'module' : 'wishlists-saved', - 'page' : 'api', - } - ); - - fetch('/?' + params_ws_saved, { + fetch('/api/wishlists-saved', { method : 'GET', }) .then(handleFetchError) @@ -168,7 +161,7 @@ $(function() { buttonRequest.addClass('disabled loading'); - fetch('/?page=api&module=wishlists', { + fetch('/api/wishlists', { method : 'POST', body : formData }) diff --git a/src/classes/url.php b/src/classes/url.php index e7074146..53da7345 100644 --- a/src/classes/url.php +++ b/src/classes/url.php @@ -72,9 +72,11 @@ class URL */ public function isPretty(): bool { - $isPretty = 1 === preg_match('/^\/[a-z0-9\/\-]+$/', $this->url); + if ('/?' === substr($this->url, 0, 2)) { + return false; + } - return $isPretty; + return true; } /**