From ae1c99c813516729beff07de7aab321008e9d760 Mon Sep 17 00:00:00 2001 From: Diego Najar Date: Fri, 19 Mar 2021 16:42:17 -0300 Subject: [PATCH] refactor and delete old files --- bl-kernel/admin/controllers/dashboard.php | 64 +-- .../admin/controllers/plugins-settings.php | 9 - bl-kernel/admin/controllers/settings.php | 2 +- bl-kernel/admin/themes/booty/index.php | 2 +- bl-kernel/admin/themes/gris | 1 - bl-kernel/ajax/delete-image.php | 43 -- bl-kernel/ajax/list-images.php | 62 --- bl-kernel/ajax/logo-remove.php | 22 -- bl-kernel/ajax/logo-upload.php | 70 ---- bl-kernel/ajax/profile-picture-upload.php | 74 ---- bl-kernel/ajax/upload-images.php | 97 ----- bl-kernel/boot/init.php | 4 +- bl-kernel/helpers/html.class.php | 6 + bl-kernel/helpers/theme.class.php | 280 ------------- bl-kernel/js/bludit-ajax.php | 148 ------- bl-kernel/js/token-autocomplete.js | 371 ------------------ bl-kernel/{pagex.class.php => page.class.php} | 0 .../bootbox}/bootbox.all.min.js | 0 18 files changed, 16 insertions(+), 1239 deletions(-) delete mode 160000 bl-kernel/admin/themes/gris delete mode 100644 bl-kernel/ajax/delete-image.php delete mode 100644 bl-kernel/ajax/list-images.php delete mode 100644 bl-kernel/ajax/logo-remove.php delete mode 100644 bl-kernel/ajax/logo-upload.php delete mode 100644 bl-kernel/ajax/profile-picture-upload.php delete mode 100644 bl-kernel/ajax/upload-images.php delete mode 100644 bl-kernel/helpers/theme.class.php delete mode 100644 bl-kernel/js/bludit-ajax.php delete mode 100644 bl-kernel/js/token-autocomplete.js rename bl-kernel/{pagex.class.php => page.class.php} (100%) rename bl-kernel/{js => vendors/bootbox}/bootbox.all.min.js (100%) diff --git a/bl-kernel/admin/controllers/dashboard.php b/bl-kernel/admin/controllers/dashboard.php index 46f5448f..63846b87 100644 --- a/bl-kernel/admin/controllers/dashboard.php +++ b/bl-kernel/admin/controllers/dashboard.php @@ -1,66 +1,16 @@ currentBuild()==0) { - $site->set(array('currentBuild'=>BLUDIT_BUILD)); - } - - // Check if Bludit need to be update - if ( ($site->currentBuild() < BLUDIT_BUILD) || isset($_GET['update']) ) { - Log::set('UPDATE SYSTEM - Starting.'); - - // Updates only for version less than Bludit v3.0 rc-3 - if ($site->currentBuild()<='20180910') { - @mkdir(PATH_WORKSPACES, DIR_PERMISSIONS, true); - $plugins = array('simple-stats', 'pluginRSS', 'pluginSitemap', 'pluginTimeMachineX', 'pluginBackup'); - foreach ($plugins as $plugin) { - if (pluginActivated($plugin)) { - Log::set('UPDATE SYSTEM - Re-enable plugin: '.$plugin); - deactivatePlugin($plugin); - activatePlugin($plugin); - } - } - } - - // Updates only for version less than Bludit v3.1 - if ($site->currentBuild()<='20180921') { - @mkdir(PATH_UPLOADS_PAGES, DIR_PERMISSIONS, true); - $site->set(array('imageRelativeToAbsolute'=>true, 'imageRestrict'=>false)); - } - - // Set the current build number - $site->set(array('currentBuild'=>BLUDIT_BUILD)); - Log::set('UPDATE SYSTEM - Finished.'); - - // Add to syslog - $syslog->add(array( - 'dictionaryKey'=>'system-updated', - 'notes'=>'Bludit v'.BLUDIT_VERSION - )); - } -} // ============================================================================ -// Main before POST +// Main // ============================================================================ -// ============================================================================ -// POST Method -// ============================================================================ - -// ============================================================================ -// Main after POST -// ============================================================================ - -// Try update Bludit -updateBludit(); - -// Title of the page -$layout['title'] .= ' - '.$L->g('Dashboard'); \ No newline at end of file +// HTML +$layout['title'] = $L->g('Dashboard') . ' - ' . $layout['title']; \ No newline at end of file diff --git a/bl-kernel/admin/controllers/plugins-settings.php b/bl-kernel/admin/controllers/plugins-settings.php index 1d0d7981..97931461 100644 --- a/bl-kernel/admin/controllers/plugins-settings.php +++ b/bl-kernel/admin/controllers/plugins-settings.php @@ -29,14 +29,5 @@ if (!method_exists($plugin, 'form')) { Redirect::page('plugins'); } -// Save the settings -if ($_SERVER['REQUEST_METHOD'] == 'POST') { - $plugin->post(); - $syslog->add(array( - 'dictionaryKey'=>'plugin-configured', - 'notes'=>$plugin->name() - )); -} - // HTML <title> $layout['title'] = $L->g('Plugin'). ' [ ' .$plugin->name(). ' ] ' . ' - ' . $layout['title']; \ No newline at end of file diff --git a/bl-kernel/admin/controllers/settings.php b/bl-kernel/admin/controllers/settings.php index 27e7dff1..010715f3 100644 --- a/bl-kernel/admin/controllers/settings.php +++ b/bl-kernel/admin/controllers/settings.php @@ -14,5 +14,5 @@ checkRole(array('admin')); // Main // ============================================================================ -// View HTML <title> +// HTML <title> $layout['title'] = $L->g('Settings') . ' - ' . $layout['title']; \ No newline at end of file diff --git a/bl-kernel/admin/themes/booty/index.php b/bl-kernel/admin/themes/booty/index.php index 79ca88a0..086fd993 100644 --- a/bl-kernel/admin/themes/booty/index.php +++ b/bl-kernel/admin/themes/booty/index.php @@ -33,13 +33,13 @@ echo HTML::jquery(); echo HTML::jsBootstrap(); echo HTML::jsSortable(); + echo HTML::bootbox(); echo HTML::js(array( 'jquery.datetimepicker.full.min.js', 'jquery-ui.min.js', 'select2.full.min.js', 'tagsinput-revisited.min.js', 'functions.js', - 'bootbox.all.min.js', 'api.js' ), DOMAIN_CORE_JS); ?> diff --git a/bl-kernel/admin/themes/gris b/bl-kernel/admin/themes/gris deleted file mode 160000 index c97e1681..00000000 --- a/bl-kernel/admin/themes/gris +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c97e1681dda9576128298d299e42973646df2475 diff --git a/bl-kernel/ajax/delete-image.php b/bl-kernel/ajax/delete-image.php deleted file mode 100644 index 0135a6ad..00000000 --- a/bl-kernel/ajax/delete-image.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php defined('BLUDIT') or die('Bludit CMS.'); -header('Content-Type: application/json'); - -/* -| Delete an image from a particular page -| -| @_POST['filename'] string Name of the file to delete -| @_POST['uuid'] string Page UUID -| -| @return array -*/ - -// $_POST -// ---------------------------------------------------------------------------- -$filename = isset($_POST['filename']) ? $_POST['filename'] : false; -$uuid = empty($_POST['uuid']) ? false : $_POST['uuid']; -// ---------------------------------------------------------------------------- - -if ($filename===false) { - ajaxResponse(1, 'The filename is empty.'); -} - -if ($uuid && IMAGE_RESTRICT) { - $imagePath = PATH_UPLOADS_PAGES.$uuid.DS; - $thumbnailPath = PATH_UPLOADS_PAGES.$uuid.DS.'thumbnails'.DS; -} else { - $imagePath = PATH_UPLOADS; - $thumbnailPath = PATH_UPLOADS_THUMBNAILS; -} - -// Delete image -if (Sanitize::pathFile($imagePath.$filename)) { - Filesystem::rmfile($imagePath.$filename); -} - -// Delete thumbnail -if (Sanitize::pathFile($thumbnailPath.$filename)) { - Filesystem::rmfile($thumbnailPath.$filename); -} - -ajaxResponse(0, 'Image deleted.'); - -?> \ No newline at end of file diff --git a/bl-kernel/ajax/list-images.php b/bl-kernel/ajax/list-images.php deleted file mode 100644 index 7f608ff8..00000000 --- a/bl-kernel/ajax/list-images.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php defined('BLUDIT') or die('Bludit CMS.'); -header('Content-Type: application/json'); - -/* -| Returns a list of images from a particular page -| -| @_POST['pageNumber'] int Page number for the paginator -| @_POST['path'] string Pre-defined name for the directory to read, its pre-defined to avoid security issues -| @_POST['uuid'] string Page UUID -| -| @return array -*/ - -// $_POST -// ---------------------------------------------------------------------------- -// $_POST['pageNumber'] > 0 -$pageNumber = empty($_POST['pageNumber']) ? 1 : (int)$_POST['pageNumber']; -$pageNumber = $pageNumber - 1; - -$path = empty($_POST['path']) ? false : $_POST['path']; -$uuid = empty($_POST['uuid']) ? false : $_POST['uuid']; -// ---------------------------------------------------------------------------- - -// Set the path to get the file list -if ($path=='thumbnails') { - if ($uuid && IMAGE_RESTRICT) { - $path = PATH_UPLOADS_PAGES.$uuid.DS.'thumbnails'.DS; - } else { - $path = PATH_UPLOADS_THUMBNAILS; - } -} else { - ajaxResponse(1, 'Invalid path.'); -} - -// Get all files from the directory $path, also split the array by numberOfItems -// The function listFiles split in chunks -$listOfFilesByPage = Filesystem::listFiles($path, '*', '*', MEDIA_MANAGER_SORT_BY_DATE, MEDIA_MANAGER_NUMBER_OF_FILES); - -// Check if the page number exists in the chunks -if (isset($listOfFilesByPage[$pageNumber])) { - - // Get only the filename from the chunk - $files = array(); - foreach ($listOfFilesByPage[$pageNumber] as $file) { - $filename = basename($file); - array_push($files, $filename); - } - - // Returns the number of chunks for the paginator - // Returns the files inside the chunk - ajaxResponse(0, 'List of files and number of chunks.', array( - 'numberOfPages'=>count($listOfFilesByPage), - 'files'=>$files - )); -} - -ajaxResponse(0, 'List of files and number of chunks.', array( - 'numberOfPages'=>0, - 'files'=>array() -)); - -?> \ No newline at end of file diff --git a/bl-kernel/ajax/logo-remove.php b/bl-kernel/ajax/logo-remove.php deleted file mode 100644 index 55f2b699..00000000 --- a/bl-kernel/ajax/logo-remove.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php defined('BLUDIT') or die('Bludit CMS.'); -header('Content-Type: application/json'); - -/* -| Delete the site logo -| This script delete the file and set and empty string in the database -| -| @return array -*/ - -// Delete the file -$logoFilename = $site->logo(false); -if ($logoFilename) { - Filesystem::rmfile(PATH_UPLOADS.$logoFilename); -} - -// Remove the logo from the database -$site->set(array('logo'=>'')); - -ajaxResponse(0, 'Logo removed.'); - -?> \ No newline at end of file diff --git a/bl-kernel/ajax/logo-upload.php b/bl-kernel/ajax/logo-upload.php deleted file mode 100644 index 6f1ad4e2..00000000 --- a/bl-kernel/ajax/logo-upload.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php defined('BLUDIT') or die('Bludit CMS.'); -header('Content-Type: application/json'); - -/* -| Upload site logo -| The final filename is the site's name and the extension is the same as the file uploaded -| -| @_FILES['inputFile'] multipart/form-data File from form -| -| @return array -*/ - -if (!isset($_FILES['inputFile'])) { - ajaxResponse(1, 'Error trying to upload the site logo.'); -} - -// Check path traversal on $filename -if (Text::stringContains($_FILES['inputFile']['name'], DS, false)) { - $message = 'Path traversal detected.'; - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); -} - -// File extension -$fileExtension = Filesystem::extension($_FILES['inputFile']['name']); -$fileExtension = Text::lowercase($fileExtension); -if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS'])) { - $message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSIONS']); - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); -} - -// File MIME Type -$fileMimeType = Filesystem::mimeType($_FILES['inputFile']['tmp_name']); -if ($fileMimeType!==false) { - if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { - $message = $L->g('File mime type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_MIMETYPES']); - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } -} - -// Final filename -$filename = 'logo.'.$fileExtension; -if (Text::isNotEmpty( $site->title() )) { - $filename = $site->title().'.'.$fileExtension; -} - -// Delete old image -$oldFilename = $site->logo(false); -if ($oldFilename) { - Filesystem::rmfile(PATH_UPLOADS.$oldFilename); -} - -// Move from temporary directory to uploads -Filesystem::mv($_FILES['inputFile']['tmp_name'], PATH_UPLOADS.$filename); - -// Permissions -chmod(PATH_UPLOADS.$filename, 0644); - -// Store the filename in the database -$site->set(array('logo'=>$filename)); - -ajaxResponse(0, 'Image uploaded.', array( - 'filename'=>$filename, - 'absoluteURL'=>DOMAIN_UPLOADS.$filename, - 'absolutePath'=>PATH_UPLOADS.$filename -)); - -?> diff --git a/bl-kernel/ajax/profile-picture-upload.php b/bl-kernel/ajax/profile-picture-upload.php deleted file mode 100644 index 2160be55..00000000 --- a/bl-kernel/ajax/profile-picture-upload.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php defined('BLUDIT') or die('Bludit CMS.'); -header('Content-Type: application/json'); - -// $_POST -// ---------------------------------------------------------------------------- -// (string) $_POST['username'] -$username = empty($_POST['username']) ? false : $_POST['username']; -// ---------------------------------------------------------------------------- - -if ($username===false) { - ajaxResponse(1, 'Error in username.'); -} - -if ( ($login->role()!='admin') && ($login->username()!=$username) ) { - ajaxResponse(1, 'Error in username.'); -} - -if (!isset($_FILES['profilePictureInputFile'])) { - ajaxResponse(1, 'Error trying to upload the profile picture.'); -} - -// Check path traversal -if (Text::stringContains($username, DS, false)) { - $message = 'Path traversal detected.'; - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); -} - -// Check file extension -$fileExtension = Filesystem::extension($_FILES['profilePictureInputFile']['name']); -$fileExtension = Text::lowercase($fileExtension); -if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ) { - $message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSIONS']); - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); -} - -// Check file MIME Type -$fileMimeType = Filesystem::mimeType($_FILES['profilePictureInputFile']['tmp_name']); -if ($fileMimeType!==false) { - if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { - $message = $L->g('File mime type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_MIMETYPES']); - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } -} - -// Tmp filename -$tmpFilename = $username.'.'.$fileExtension; - -// Final filename -$filename = $username.'.png'; - -// Move from temporary directory to uploads folder -rename($_FILES['profilePictureInputFile']['tmp_name'], PATH_TMP.$tmpFilename); - -// Resize and convert to png -$image = new Image(); -$image->setImage(PATH_TMP.$tmpFilename, PROFILE_IMG_WIDTH, PROFILE_IMG_HEIGHT, 'crop'); -$image->saveImage(PATH_UPLOADS_PROFILES.$filename, PROFILE_IMG_QUALITY, false, true); - -// Delete temporary file -Filesystem::rmfile(PATH_TMP.$tmpFilename); - -// Permissions -chmod(PATH_UPLOADS_PROFILES.$filename, 0644); - -ajaxResponse(0, 'Image uploaded.', array( - 'filename'=>$filename, - 'absoluteURL'=>DOMAIN_UPLOADS_PROFILES.$filename, - 'absolutePath'=>PATH_UPLOADS_PROFILES.$filename -)); - -?> diff --git a/bl-kernel/ajax/upload-images.php b/bl-kernel/ajax/upload-images.php deleted file mode 100644 index c2fb4e9c..00000000 --- a/bl-kernel/ajax/upload-images.php +++ /dev/null @@ -1,97 +0,0 @@ -<?php defined('BLUDIT') or die('Bludit CMS.'); -header('Content-Type: application/json'); - -/* -| Upload an image to a particular page -| -| @_POST['uuid'] string Page uuid -| -| @return array -*/ - -// $_POST -// ---------------------------------------------------------------------------- -$uuid = empty($_POST['uuid']) ? false : $_POST['uuid']; -// ---------------------------------------------------------------------------- - -// Check path traversal on $uuid -if ($uuid) { - if (Text::stringContains($uuid, DS, false)) { - $message = 'Path traversal detected.'; - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } -} - -// Set upload directory -if ($uuid && IMAGE_RESTRICT) { - $imageDirectory = PATH_UPLOADS_PAGES.$uuid.DS; - $thumbnailDirectory = $imageDirectory.'thumbnails'.DS; - if (!Filesystem::directoryExists($thumbnailDirectory)) { - Filesystem::mkdir($thumbnailDirectory, true); - } -} else { - $imageDirectory = PATH_UPLOADS; - $thumbnailDirectory = PATH_UPLOADS_THUMBNAILS; -} - -$images = array(); -foreach ($_FILES['images']['name'] as $uuid=>$filename) { - // Check for errors - if ($_FILES['images']['error'][$uuid] != 0) { - $message = $L->g('Maximum load file size allowed:').' '.ini_get('upload_max_filesize'); - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } - - // Convert URL characters such as spaces or quotes to characters - $filename = urldecode($filename); - - // Check path traversal on $filename - if (Text::stringContains($filename, DS, false)) { - $message = 'Path traversal detected.'; - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } - - // Check file extension - $fileExtension = Filesystem::extension($filename); - $fileExtension = Text::lowercase($fileExtension); - if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ) { - $message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSIONS']); - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } - - // Check file MIME Type - $fileMimeType = Filesystem::mimeType($_FILES['images']['tmp_name'][$uuid]); - if ($fileMimeType!==false) { - if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { - $message = $L->g('File mime type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_MIMETYPES']); - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } - } - - // Move from PHP tmp file to Bludit tmp directory - Filesystem::mv($_FILES['images']['tmp_name'][$uuid], PATH_TMP.$filename); - - // Transform the image and generate the thumbnail - $image = transformImage(PATH_TMP.$filename, $imageDirectory, $thumbnailDirectory); - - if ($image) { - chmod($image, 0644); - $filename = Filesystem::filename($image); - array_push($images, $filename); - } else { - $message = 'Error after transformImage() function.'; - Log::set($message, LOG_TYPE_ERROR); - ajaxResponse(1, $message); - } -} - -ajaxResponse(0, 'Images uploaded.', array( - 'images'=>$images -)); - -?> diff --git a/bl-kernel/boot/init.php b/bl-kernel/boot/init.php index 6c941bd7..ac4ef92e 100644 --- a/bl-kernel/boot/init.php +++ b/bl-kernel/boot/init.php @@ -83,7 +83,7 @@ include(PATH_KERNEL.'language.class.php'); include(PATH_KERNEL.'site.class.php'); include(PATH_KERNEL.'categories.class.php'); include(PATH_KERNEL.'syslog.class.php'); -include(PATH_KERNEL.'pagex.class.php'); +include(PATH_KERNEL.'page.class.php'); include(PATH_KERNEL.'category.class.php'); include(PATH_KERNEL.'tag.class.php'); include(PATH_KERNEL.'user.class.php'); @@ -99,7 +99,6 @@ include(PATH_KERNEL.'functions.php'); include(PATH_HELPERS.'text.class.php'); include(PATH_HELPERS.'log.class.php'); include(PATH_HELPERS.'date.class.php'); -include(PATH_HELPERS.'theme.class.php'); include(PATH_HELPERS.'session.class.php'); include(PATH_HELPERS.'redirect.class.php'); include(PATH_HELPERS.'sanitize.class.php'); @@ -113,7 +112,6 @@ include(PATH_HELPERS.'tcp.class.php'); include(PATH_HELPERS.'dom.class.php'); include(PATH_HELPERS.'cookie.class.php'); include(PATH_HELPERS.'bootstrap.class.php'); - include(PATH_HELPERS.'html.class.php'); if (file_exists(PATH_KERNEL.'bludit.pro.php')) { diff --git a/bl-kernel/helpers/html.class.php b/bl-kernel/helpers/html.class.php index 4d6cd376..c51190f1 100644 --- a/bl-kernel/helpers/html.class.php +++ b/bl-kernel/helpers/html.class.php @@ -52,6 +52,12 @@ class HTML { return '<script src="'.DOMAIN_CORE_VENDORS.'jquery/jquery.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; } + public static function bootbox($attributes='') + { + // https://bootbox.com/ + return '<script '.$attributes.' src="'.DOMAIN_CORE_VENDORS.'bootbox/bootbox.all.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; + } + public static function jsBootstrap($attributes='') { // https://getbootstrap.com/ diff --git a/bl-kernel/helpers/theme.class.php b/bl-kernel/helpers/theme.class.php deleted file mode 100644 index 6446eea2..00000000 --- a/bl-kernel/helpers/theme.class.php +++ /dev/null @@ -1,280 +0,0 @@ -<?php - -// DEPRECATED CLASS -// WILL BE REMOVED IN BLUDIT V4 -class Theme { - - public static function socialNetworks() - { - global $site; - $socialNetworks = array( - 'github'=>'Github', - 'gitlab'=>'GitLab', - 'twitter'=>'Twitter', - 'facebook'=>'Facebook', - 'instagram'=>'Instagram', - 'codepen'=>'Codepen', - 'linkedin'=>'Linkedin', - 'xing'=>'Xing', - 'mastodon'=>'Mastodon', - 'vk'=>'VK' - ); - - foreach ($socialNetworks as $key=>$label) { - if (!$site->{$key}()) { - unset($socialNetworks[$key]); - } - } - return $socialNetworks; - } - - public static function title() - { - global $site; - return $site->title(); - } - - public static function description() - { - global $site; - return $site->description(); - } - - public static function slogan() - { - global $site; - return $site->slogan(); - } - - public static function footer() - { - global $site; - return $site->footer(); - } - - public static function lang() - { - global $language; - return $language->currentLanguageShortVersion(); - } - - public static function rssUrl() - { - if (pluginActivated('pluginRSS')) { - return DOMAIN_BASE.'rss.xml'; - } - return false; - } - - public static function sitemapUrl() - { - if (pluginActivated('pluginSitemap')) { - return DOMAIN_BASE.'sitemap.xml'; - } - return false; - } - - // Returns the absolute URL of the site - // Ex. https://example.com the method returns https://example.com/ - // Ex. https://example.com/bludit/ the method returns https://example.com/bludit/ - public static function siteUrl() - { - return DOMAIN_BASE; - } - - // Returns the absolute URL of admin panel - // Ex. https://example.com/admin/ the method returns https://example.com/admin/ - // Ex. https://example.com/bludit/admin/ the method returns https://example.com/bludit/admin/ - public static function adminUrl() - { - return DOMAIN_ADMIN; - } - - public static function metaTags($tag) - { - if ($tag=='title') { - return self::metaTagTitle(); - } elseif ($tag=='description') { - return self::metaTagDescription(); - } - } - - public static function metaTagTitle() - { - global $url; - global $site; - global $tags; - global $categories; - global $WHERE_AM_I; - global $page; - - if ($WHERE_AM_I=='page') { - $format = $site->titleFormatPages(); - $format = Text::replace('{{page-title}}', $page->title(), $format); - $format = Text::replace('{{page-description}}', $page->description(), $format); - } elseif ($WHERE_AM_I=='tag') { - try { - $tagKey = $url->slug(); - $tag = new Tag($tagKey); - $format = $site->titleFormatTag(); - $format = Text::replace('{{tag-name}}', $tag->name(), $format); - } catch (Exception $e) { - // Tag doesn't exist - } - - } elseif ($WHERE_AM_I=='category') { - try { - $categoryKey = $url->slug(); - $category = new Category($categoryKey); - $format = $site->titleFormatCategory(); - $format = Text::replace('{{category-name}}', $category->name(), $format); - } catch (Exception $e) { - // Category doesn't exist - } - } else { - $format = $site->titleFormatHomepage(); - } - - $format = Text::replace('{{site-title}}', $site->title(), $format); - $format = Text::replace('{{site-slogan}}', $site->slogan(), $format); - $format = Text::replace('{{site-description}}', $site->description(), $format); - - return '<title>'.$format.''.PHP_EOL; - } - - public static function metaTagDescription() - { - global $site; - global $WHERE_AM_I; - global $page; - global $url; - - $description = $site->description(); - - if ($WHERE_AM_I=='page') { - $description = $page->description(); - } elseif ($WHERE_AM_I=='category') { - try { - $categoryKey = $url->slug(); - $category = new Category($categoryKey); - $description = $category->description(); - } catch (Exception $e) { - // description from the site - } - } - - return ''.PHP_EOL; - } - - // DEPRECATED v3.0.0 - // Return the metatag with a predefine structure - public static function headTitle() - { - return self::metaTagTitle(); - } - - // DEPRECATED v3.0.0 - // Return the metatag <decription> with a predefine structure - public static function headDescription() - { - return self::metaTagDescription(); - } - - public static function charset($charset) - { - return '<meta charset="'.$charset.'">'.PHP_EOL; - } - - public static function viewport($content) - { - return '<meta name="viewport" content="'.$content.'">'.PHP_EOL; - } - - public static function src($file, $base=DOMAIN_THEME) - { - return $base.$file; - } - - public static function css($files, $base=DOMAIN_THEME) - { - if( !is_array($files) ) { - $files = array($files); - } - - $links = ''; - foreach($files as $file) { - $links .= '<link rel="stylesheet" type="text/css" href="'.$base.$file.'?version='.BLUDIT_VERSION.'">'.PHP_EOL; - } - - return $links; - } - - public static function javascript($files, $base=DOMAIN_THEME, $attributes='') - { - if( !is_array($files) ) { - $files = array($files); - } - - $scripts = ''; - foreach($files as $file) { - $scripts .= '<script '.$attributes.' src="'.$base.$file.'?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; - } - - return $scripts; - } - - public static function js($files, $base=DOMAIN_THEME, $attributes='') - { - return self::javascript($files, $base, $attributes); - } - - public static function plugins($type, $args = array()) - { - global $plugins; - foreach ($plugins[$type] as $plugin) { - echo call_user_func_array(array($plugin, $type), $args); - } - } - - public static function favicon($file='favicon.png', $typeIcon='image/png') - { - return '<link rel="icon" href="'.DOMAIN_THEME.$file.'" type="'.$typeIcon.'">'.PHP_EOL; - } - - public static function keywords($keywords) - { - if (is_array($keywords)) { - $keywords = implode(',', $keywords); - } - return '<meta name="keywords" content="'.$keywords.'">'.PHP_EOL; - } - - public static function jquery() - { - return '<script src="'.DOMAIN_CORE_JS.'jquery.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; - } - - public static function jsBootstrap($attributes='') - { - return '<script '.$attributes.' src="'.DOMAIN_CORE_JS.'bootstrap.bundle.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; - } - - public static function cssBootstrap() - { - return '<link rel="stylesheet" type="text/css" href="'.DOMAIN_CORE_CSS.'bootstrap.min.css?version='.BLUDIT_VERSION.'">'.PHP_EOL; - } - - public static function cssBootstrapIcons() - { - return '<link rel="stylesheet" type="text/css" href="'.DOMAIN_CORE_CSS.'/bootstrap-icons/bootstrap-icons.css?version='.BLUDIT_VERSION.'">'.PHP_EOL; - } - - public static function jsSortable($attributes='') - { - // https://github.com/psfpro/bootstrap-html5sortable - return '<script '.$attributes.' src="'.DOMAIN_CORE_JS.'jquery.sortable.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; - } - -} - -?> diff --git a/bl-kernel/js/bludit-ajax.php b/bl-kernel/js/bludit-ajax.php deleted file mode 100644 index e15fef05..00000000 --- a/bl-kernel/js/bludit-ajax.php +++ /dev/null @@ -1,148 +0,0 @@ -/* - DEPRECATED CLASS - WILL BE REMOVED IN BLUDIT V4 -*/ - -class bluditAjax { - - constructor(apiURL, apiToken, apiAuth, tokenCSRF) { - this.apiURL = "http://localhost:9000/api/"; - this.apiToken = '45643a4071fad6a12261bb0763550feb'; - this.apiAuth = '18a8410f0043d004c2e87f404170e112'; - this.tokenCSRF = tokenCSRF; - } - - static async savePage(uuid, title, content) { - let url = this.apiURL+"pages"; - try { - const response = await fetch(url, { - credentials: "same-origin", - method: "POST", - body: JSON.stringify({ - tokenCSRF: this.tokenCSRF, - token: this.apiToken, - authentication: this.apiAuth, - uuid: uuid, - title: title, - content: content - }), - headers: new Headers({ - "Content-Type": "application/json" - }), - }); - const json = await response.json(); - return json.data.key; - } - catch (err) { - console.log(err); - return true; - } - } - - static async saveAsDraft(uuid, title, content) { - let url = HTML_PATH_ADMIN_ROOT+"ajax/save-as-draft" - try { - const response = await fetch(url, { - credentials: 'same-origin', - method: "POST", - headers: new Headers({ - 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' - }), - body: new URLSearchParams({ - 'tokenCSRF': tokenCSRF, - 'uuid': "autosave-" + uuid, - 'title': title, - 'content': content, - 'type': 'autosave' - }), - }); - const json = await response.json(); - return json; - } - catch (err) { - console.log(err); - return true; - } - } - - static async removeLogo() { - let url = HTML_PATH_ADMIN_ROOT+"ajax/logo-remove" - try { - const response = await fetch(url, { - credentials: 'same-origin', - method: "POST", - headers: new Headers({ - 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' - }), - body: new URLSearchParams({ - 'tokenCSRF': tokenCSRF - }), - }); - const json = await response.json(); - return json; - } - catch (err) { - console.log(err); - return true; - } - } - - // Alert the user when the user is not logged - userLogged(callBack) { - var ajaxRequest; - if (ajaxRequest) { - ajaxRequest.abort(); - } - - console.log("[INFO] [BLUDIT AJAX] [userLogged()] Checking if the user is logged."); - - ajaxRequest = $.ajax({ - type: "GET", - url: HTML_PATH_ADMIN_ROOT+"ajax/user-logged" - }); - - ajaxRequest.done(function (response, textStatus, jqXHR) { - console.log("[INFO] [BLUDIT AJAX] [userLogged()] The user is logged."); - }); - - ajaxRequest.fail(function (jqXHR, textStatus, errorThrown) { - // The fail is produced by admin.php when the user is not logged the ajax request is not possible and returns 401 - console.log("[INFO] [BLUDIT AJAX] [userLogged()] The user is NOT logged."); - if (jqXHR.status==401) { - callBack("You are not logged in anymore, so Bludit can't save your settings and content."); - } - }); - } - - generateSlug(text, parentKey, currentKey, callBack) { - var ajaxRequest; - if (ajaxRequest) { - ajaxRequest.abort(); - } - - ajaxRequest = $.ajax({ - type: "POST", - data: { - tokenCSRF: tokenCSRF, - text: text, - parentKey: parentKey, - currentKey: currentKey - }, - url: HTML_PATH_ADMIN_ROOT+"ajax/generate-slug" - }); - - ajaxRequest.done(function (response, textStatus, jqXHR) { - console.log("Bludit AJAX: generateSlug(): done handler"); - callBack.val(response["slug"]); - }); - - ajaxRequest.fail(function (jqXHR, textStatus, errorThrown) { - console.log("Bludit AJAX: generateSlug(): fail handler"); - }); - - ajaxRequest.always(function () { - console.log("Bludit AJAX: generateSlug(): always handler"); - }); - } - -} diff --git a/bl-kernel/js/token-autocomplete.js b/bl-kernel/js/token-autocomplete.js deleted file mode 100644 index 58c4f365..00000000 --- a/bl-kernel/js/token-autocomplete.js +++ /dev/null @@ -1,371 +0,0 @@ -var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); -}; -var TokenAutocomplete = /** @class */ (function () { - function TokenAutocomplete(options) { - this.KEY_BACKSPACE = 8; - this.KEY_ENTER = 13; - this.KEY_UP = 38; - this.KEY_DOWN = 40; - this.defaults = { - name: '', - selector: '', - noMatchesText: null, - initialTokens: null, - initialSuggestions: null, - suggestionsUri: '', - suggestionRenderer: TokenAutocomplete.Autocomplete.defaultRenderer, - minCharactersForSuggestion: 1 - }; - this.options = __assign(__assign({}, this.defaults), options); - var passedContainer = document.querySelector(this.options.selector); - if (!passedContainer) { - throw new Error('passed selector does not point to a DOM element.'); - } - this.container = passedContainer; - this.container.classList.add('token-autocomplete-container'); - if (!Array.isArray(this.options.initialTokens) && !Array.isArray(this.options.initialSuggestions)) { - this.parseTokensAndSuggestions(); - } - this.hiddenSelect = document.createElement('select'); - this.hiddenSelect.id = this.container.id + '-select'; - this.hiddenSelect.name = this.options.name; - this.hiddenSelect.setAttribute('multiple', 'true'); - this.hiddenSelect.style.display = 'none'; - this.textInput = document.createElement('span'); - this.textInput.id = this.container.id + '-input'; - this.textInput.classList.add('token-autocomplete-input'); - this.textInput.setAttribute('data-placeholder', 'enter some text'); - this.textInput.contentEditable = 'true'; - this.container.appendChild(this.textInput); - this.container.appendChild(this.hiddenSelect); - this.select = new TokenAutocomplete.MultiSelect(this); - this.autocomplete = new TokenAutocomplete.Autocomplete(this); - this.debug(false); - var me = this; - if (Array.isArray(this.options.initialTokens)) { - this.options.initialTokens.forEach(function (token) { - if (typeof token === 'object') { - me.select.addToken(token.value, token.text); - } - }); - } - this.textInput.addEventListener('keydown', function (event) { - if (event.which == me.KEY_ENTER || event.keyCode == me.KEY_ENTER) { - event.preventDefault(); - var highlightedSuggestion = me.autocomplete.suggestions.querySelector('.token-autocomplete-suggestion-highlighted'); - if (highlightedSuggestion !== null) { - if (highlightedSuggestion.classList.contains('token-autocomplete-suggestion-active')) { - me.select.removeTokenWithText(highlightedSuggestion.textContent); - } - else { - me.select.addToken(highlightedSuggestion.getAttribute('data-value'), highlightedSuggestion.textContent); - } - } - else { - me.select.addToken(me.textInput.textContent, me.textInput.textContent); - } - me.clearCurrentInput(); - } - else if (me.textInput.textContent === '' && (event.which == me.KEY_BACKSPACE || event.keyCode == me.KEY_BACKSPACE)) { - event.preventDefault(); - me.select.removeLastToken(); - } - }); - this.textInput.addEventListener('keyup', function (event) { - var _a, _b; - if ((event.which == me.KEY_UP || event.keyCode == me.KEY_UP) && me.autocomplete.suggestions.childNodes.length > 0) { - var highlightedSuggestion = me.autocomplete.suggestions.querySelector('.token-autocomplete-suggestion-highlighted'); - var aboveSuggestion = (_a = highlightedSuggestion) === null || _a === void 0 ? void 0 : _a.previousSibling; - if (aboveSuggestion != null) { - me.autocomplete.highlightSuggestion(aboveSuggestion); - } - return; - } - if ((event.which == me.KEY_DOWN || event.keyCode == me.KEY_DOWN) && me.autocomplete.suggestions.childNodes.length > 0) { - var highlightedSuggestion = me.autocomplete.suggestions.querySelector('.token-autocomplete-suggestion-highlighted'); - var belowSuggestion = (_b = highlightedSuggestion) === null || _b === void 0 ? void 0 : _b.nextSibling; - if (belowSuggestion != null) { - me.autocomplete.highlightSuggestion(belowSuggestion); - } - return; - } - me.autocomplete.hideSuggestions(); - me.autocomplete.clearSuggestions(); - var value = me.textInput.textContent || ''; - if (value.length >= me.options.minCharactersForSuggestion) { - if (Array.isArray(me.options.initialSuggestions)) { - me.options.initialSuggestions.forEach(function (suggestion) { - if (typeof suggestion !== 'object') { - // the suggestion is of wrong type and therefore ignored - return; - } - if (value.localeCompare(suggestion.text.slice(0, value.length), undefined, { sensitivity: 'base' }) === 0) { - // The suggestion starts with the query text the user entered and will be displayed - me.autocomplete.addSuggestion(suggestion); - } - }); - if (me.autocomplete.suggestions.childNodes.length > 0) { - me.autocomplete.highlightSuggestionAtPosition(0); - } - else if (me.options.noMatchesText) { - me.autocomplete.addSuggestion({ value: '_no_match_', text: me.options.noMatchesText, description: null }); - } - } - else if (me.options.suggestionsUri.length > 0) { - me.autocomplete.requestSuggestions(value); - } - } - }); - this.container.tokenAutocomplete = this; - } - /** - * Searches the element given as a container for option elements and creates active tokens (when the option is marked selected) - * and suggestions (all options found) from these. During this all found options are removed from the DOM. - */ - TokenAutocomplete.prototype.parseTokensAndSuggestions = function () { - var initialTokens = []; - var initialSuggestions = []; - var options = this.container.querySelectorAll('option'); - var me = this; - options.forEach(function (option) { - if (option.text != null) { - if (option.hasAttribute('selected')) { - initialTokens.push({ value: option.value, text: option.text }); - } - initialSuggestions.push({ value: option.value, text: option.text, description: null }); - } - me.container.removeChild(option); - }); - if (initialTokens.length > 0) { - this.options.initialTokens = initialTokens; - } - if (initialSuggestions.length > 0) { - this.options.initialSuggestions = initialSuggestions; - } - }; - /** - * Clears the currently present tokens and creates new ones from the given input value. - * - * @param {(Array\|string)} value - either the name of a single token or a list of tokens to create - */ - TokenAutocomplete.prototype.val = function (value) { - this.select.clear(); - if (Array.isArray(value)) { - var me_1 = this; - value.forEach(function (token) { - if (typeof token === 'object') { - me_1.select.addToken(token.value, token.text); - } - }); - } - else { - this.select.addToken(value.value, value.text); - } - }; - TokenAutocomplete.prototype.clearCurrentInput = function () { - this.textInput.textContent = ''; - }; - TokenAutocomplete.prototype.debug = function (state) { - if (state) { - this.log = console.log.bind(window.console); - } - else { - this.log = function () { }; - } - }; - var _a; - TokenAutocomplete.MultiSelect = /** @class */ (function () { - function class_1(parent) { - this.parent = parent; - this.container = parent.container; - this.options = parent.options; - } - /** - * Adds a token with the specified name to the list of currently prensent tokens displayed to the user and the hidden select. - * - * @param {string} tokenText - the name of the token to create - */ - class_1.prototype.addToken = function (tokenValue, tokenText) { - if (tokenValue === null || tokenText === null) { - return; - } - var option = document.createElement('option'); - option.text = tokenText; - option.value = tokenValue; - option.setAttribute('selected', 'true'); - option.setAttribute('data-text', tokenText); - option.setAttribute('data-value', tokenValue); - this.parent.hiddenSelect.add(option); - var token = document.createElement('span'); - token.classList.add('token-autocomplete-token'); - token.setAttribute('data-text', tokenText); - option.setAttribute('data-value', tokenValue); - token.textContent = tokenText; - var deleteToken = document.createElement('span'); - deleteToken.classList.add('token-autocomplete-token-delete'); - deleteToken.textContent = '\u00D7'; - token.appendChild(deleteToken); - var me = this; - deleteToken.addEventListener('click', function (event) { - me.removeToken(token); - }); - this.container.insertBefore(token, this.parent.textInput.nextSibling); - this.parent.log('added token', token); - }; - /** - * Completely clears the currently present tokens from the field. - */ - class_1.prototype.clear = function () { - var tokens = this.container.querySelectorAll('.token-autocomplete-token'); - var me = this; - tokens.forEach(function (token) { me.removeToken(token); }); - }; - /** - * Removes the last token in the list of currently present token. This is the last added token next to the input field. - */ - class_1.prototype.removeLastToken = function () { - var tokens = this.container.querySelectorAll('.token-autocomplete-token'); - var token = tokens[tokens.length - 1]; - this.removeToken(token); - }; - /** - * Removes the specified token from the list of currently present tokens. - * - * @param {Element} token - the token to remove - */ - class_1.prototype.removeToken = function (token) { - var _a, _b; - this.container.removeChild(token); - var tokenText = token.getAttribute('data-text'); - var hiddenOption = this.parent.hiddenSelect.querySelector('option[data-text="' + tokenText + '"]'); - (_b = (_a = hiddenOption) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(hiddenOption); - this.parent.log('removed token', token.textContent); - }; - class_1.prototype.removeTokenWithText = function (tokenText) { - if (tokenText === null) { - return; - } - var token = this.container.querySelector('.token-autocomplete-token[data-text="' + tokenText + '"]'); - if (token !== null) { - this.removeToken(token); - } - }; - return class_1; - }()); - TokenAutocomplete.Autocomplete = (_a = /** @class */ (function () { - function class_2(parent) { - this.parent = parent; - this.container = parent.container; - this.options = parent.options; - this.renderer = parent.options.suggestionRenderer; - this.suggestions = document.createElement('ul'); - this.suggestions.id = this.container.id + '-suggestions'; - this.suggestions.classList.add('token-autocomplete-suggestions'); - this.container.appendChild(this.suggestions); - } - /** - * Hides the suggestions dropdown from the user. - */ - class_2.prototype.hideSuggestions = function () { - this.suggestions.style.display = ''; - }; - /** - * Shows the suggestions dropdown to the user. - */ - class_2.prototype.showSuggestions = function () { - this.suggestions.style.display = 'block'; - }; - class_2.prototype.highlightSuggestionAtPosition = function (index) { - var suggestions = this.suggestions.querySelectorAll('li'); - suggestions.forEach(function (suggestion) { - suggestion.classList.remove('token-autocomplete-suggestion-highlighted'); - }); - suggestions[index].classList.add('token-autocomplete-suggestion-highlighted'); - }; - class_2.prototype.highlightSuggestion = function (suggestion) { - this.suggestions.querySelectorAll('li').forEach(function (suggestion) { - suggestion.classList.remove('token-autocomplete-suggestion-highlighted'); - }); - suggestion.classList.add('token-autocomplete-suggestion-highlighted'); - }; - /** - * Removes all previous suggestions from the dropdown. - */ - class_2.prototype.clearSuggestions = function () { - this.suggestions.innerHTML = ''; - }; - /** - * Loads suggestions matching the given query from the rest service behind the URI given as an option while initializing the field. - * - * @param query the query to search suggestions for - */ - class_2.prototype.requestSuggestions = function (query) { - var me = this; - var request = new XMLHttpRequest(); - request.onload = function () { - if (Array.isArray(request.response)) { - request.response.forEach(function (suggestion) { - me.addSuggestion(suggestion); - }); - } - }; - request.open('GET', me.options.suggestionsUri + '?query=' + query, true); - request.responseType = 'json'; - request.setRequestHeader('Content-type', 'application/json'); - request.send(); - }; - /** - * Adds a suggestion with the given text matching the users input to the dropdown. - * - * @param {string} suggestionText - the text that should be displayed for the added suggestion - */ - class_2.prototype.addSuggestion = function (suggestion) { - var element = this.renderer(suggestion); - element.setAttribute('data-value', suggestion.value); - var me = this; - element.addEventListener('click', function (_event) { - if (suggestion.text == me.options.noMatchesText) { - return true; - } - if (element.classList.contains('token-autocomplete-suggestion-active')) { - me.parent.select.removeTokenWithText(suggestion.text); - } - else { - me.parent.select.addToken(suggestion.value, suggestion.text); - } - me.clearSuggestions(); - me.hideSuggestions(); - me.parent.clearCurrentInput(); - }); - if (this.container.querySelector('.token-autocomplete-token[data-text="' + suggestion.text + '"]') !== null) { - element.classList.add('token-autocomplete-suggestion-active'); - } - this.suggestions.appendChild(element); - this.showSuggestions(); - me.parent.log('added suggestion', suggestion); - }; - return class_2; - }()), - _a.defaultRenderer = function (suggestion) { - var option = document.createElement('li'); - option.textContent = suggestion.text; - if (suggestion.description) { - var description = document.createElement('small'); - description.textContent = suggestion.description; - description.classList.add('token-autocomplete-suggestion-description'); - option.appendChild(description); - } - return option; - }, - _a); - return TokenAutocomplete; -}()); diff --git a/bl-kernel/pagex.class.php b/bl-kernel/page.class.php similarity index 100% rename from bl-kernel/pagex.class.php rename to bl-kernel/page.class.php diff --git a/bl-kernel/js/bootbox.all.min.js b/bl-kernel/vendors/bootbox/bootbox.all.min.js similarity index 100% rename from bl-kernel/js/bootbox.all.min.js rename to bl-kernel/vendors/bootbox/bootbox.all.min.js