New approach when the page is created, remove UUID, remove symlinks for upload images, modal for filemanager, and more

This commit is contained in:
dignajar 2021-01-01 23:13:01 +01:00
parent 39de732f3b
commit ff2a51fae8
16 changed files with 712 additions and 519 deletions

View file

@ -14,26 +14,5 @@ checkRole(array('admin', 'editor', 'author'));
// Main
// ============================================================================
// UUID of the page is need it for autosave and media manager
$uuid = $pages->generateUUID();
// Images prefix directory
define('PAGE_IMAGES_KEY', $uuid);
// Images and thubmnails directories
if (IMAGE_RESTRICT) {
define('PAGE_IMAGES_DIRECTORY', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : HTML_PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/'));
define('PAGE_IMAGES_URL', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : DOMAIN_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/'));
define('PAGE_THUMBNAILS_DIRECTORY', PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.DS.'thumbnails'.DS);
define('PAGE_THUMBNAILS_HTML', HTML_PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/thumbnails/');
define('PAGE_THUMBNAILS_URL', DOMAIN_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/thumbnails/');
} else {
define('PAGE_IMAGES_DIRECTORY', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : HTML_PATH_UPLOADS));
define('PAGE_IMAGES_URL', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : DOMAIN_UPLOADS));
define('PAGE_THUMBNAILS_DIRECTORY', PATH_UPLOADS_THUMBNAILS);
define('PAGE_THUMBNAILS_HTML', HTML_PATH_UPLOADS_THUMBNAILS);
define('PAGE_THUMBNAILS_URL', DOMAIN_UPLOADS_THUMBNAILS);
}
// View HTML <title>
$layout['title'] = $L->g('New content') . ' - ' . $layout['title'];

View file

@ -5,7 +5,13 @@ a {
/* Remove Focus glow */
.btn:focus,
.form-control:focus {
.form-control:focus,
.form-select:focus {
outline: none;
box-shadow: none;
}
/* Icons */
.bi {
margin-right: .5rem!important;
}

View file

@ -0,0 +1,19 @@
<div aria-live="polite" aria-atomic="true" class="position-relative">
<div class="toast-container position-absolute top-0 end-0 p-3">
<div id="alert" class="toast d-flex align-items-center text-white bg-primary border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-body">Hello, I'm a Bludit alert!</div>
<button type="button" class="btn-close btn-close-white ms-auto me-2" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
<script>
function showAlert(text) {
$('#alert').children('.toast-body').html(text);
$('#alert').toast('show');
}
function hideAlert(text) {
$('#alert').toast('hide');
}
</script>

View file

@ -0,0 +1,156 @@
<div class="modal" id="modal-fileManager" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col">
<div class="d-flex align-items-center mb-2">
<h3 class="me-auto m-0 p-0"><i class="bi bi-image"></i><?php $L->p('File Manager'); ?></h3>
<label class="btn btn-primary"><i class="bi bi-upload"></i><?php $L->p('Upload file'); ?><input type="file" id="filesToUpload" name="filesToUpload[]" multiple hidden></label>
<div class="progress d-none">
<div class="progress-bar" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">Preview</th>
<th scope="col">Filename</th>
<th scope="col">Type</th>
<th scope="col">Size</th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="fmFiles">
<tr>
<td class="align-middle">
<img style="width: 32px" src="<?php echo HTML_PATH_CORE_IMG ?>default.svg" />
</td>
<td class="align-middle">photo.jpg</td>
<td class="align-middle">image/jpeg</td>
<td class="align-middle">300Kb</td>
<td class="align-middle">
<i class="bi bi-trash"></i><span><?php $L->p('Delete') ?></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// Open File Manager modal
function fmOpen() {
$('#modal-fileManager').modal('show');
}
// Get files for the current page and show them
function fmGetFiles() {
logs('File Manager. Get files for page: ' + _pageKey);
api.getPageFiles({
'pageKey': _pageKey
}).then(function(files) {
fmDisplayFiles(files);
});
}
// Show the files in the table
function fmDisplayFiles(files) {
$('#fmFiles').empty();
if (files.length == 0) {
logs('File Manager. File list empty.');
return false;
}
$.each(files, function(key, file) {
var row = '<tr>' +
' <td class="align-middle">' +
' <img style="width: 32px" src="<?php echo HTML_PATH_CORE_IMG ?>default.svg" />' +
' </td>' +
' <td class="align-middle">' + file.filename + '</td>' +
' <td class="align-middle">' + file.mime + '</td>' +
' <td class="align-middle">' + formatBytes(file.size) + '</td>' +
' <td class="align-middle">' +
' <i class="bi bi-trash"></i><span><?php $L->p('Delete') ?></span>' +
' </td>' +
' </tr>';
$('#fmFiles').append(row);
});
return true;
}
// Upload a file for the current page
function fmUploadFile(file) {
logs('File Manager. Uploading file.');
// Check file type/extension
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml'];
if (!validImageTypes.includes(file.type)) {
logs("File Manager. File type is not supported.");
showAlert("<?php echo $L->g('File type is not supported. Allowed types:') . ' ' . implode(', ', $GLOBALS['ALLOWED_IMG_EXTENSION']) ?>");
return false;
}
// Check file size and compare with PHP upload_max_filesize
if (file.size > UPLOAD_MAX_FILESIZE) {
logs("File Manager. File size to big for PHP configuration.");
showAlert("<?php echo $L->g('Maximum load file size allowed:') . ' ' . ini_get('upload_max_filesize') ?>");
return false;
}
// Data to send via AJAX
var formData = new FormData();
formData.append("file", file);
formData.append("token", api.body.token);
formData.append("authentication", api.body.authentication);
$.ajax({
url: api.apiURL + 'files/' + _pageKey,
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false,
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
logs("File Manager. Uploading file, percent complete: " + percentComplete + "%");
}
}, false);
}
return xhr;
}
}).done(function(data) {
logs("File Manager. File uploaded.")
logs(data);
fmGetFiles();
});
}
$(document).ready(function() {
// Input file change event
$("#filesToUpload").on("change", function(e) {
var filesToUpload = $("#filesToUpload")[0].files;
for (var i = 0; i < filesToUpload.length; i++) {
fmUploadFile(filesToUpload[i]);
}
});
});
</script>

View file

@ -1,5 +1,6 @@
<!DOCTYPE html>
<html class="h-100">
<head>
<title><?php echo $layout['title'] ?></title>
<meta charset="<?php echo CHARSET ?>">
@ -12,34 +13,34 @@
<!-- CSS -->
<?php
echo HTML::cssBootstrap();
echo HTML::cssBootstrapIcons();
echo HTML::css(array(
'bludit-bootstrap.css',
'bludit.css'
), DOMAIN_ADMIN_THEME_CSS);
echo HTML::css(array(
'jquery.datetimepicker.min.css',
'jquery-ui.min.css',
'select2.min.css',
'select2-bootstrap4.min.css',
'tagsinput-revisited.min.css'
), DOMAIN_CORE_CSS);
echo HTML::cssBootstrap();
echo HTML::cssBootstrapIcons();
echo HTML::css(array(
'bludit-bootstrap.css',
'bludit.css'
), DOMAIN_ADMIN_THEME_CSS);
echo HTML::css(array(
'jquery.datetimepicker.min.css',
'jquery-ui.min.css',
'select2.min.css',
'select2-bootstrap4.min.css',
'tagsinput-revisited.min.css'
), DOMAIN_CORE_CSS);
?>
<!-- Javascript -->
<?php
echo HTML::jquery();
echo HTML::jsBootstrap();
echo HTML::jsSortable();
echo HTML::js(array(
'jquery.datetimepicker.full.min.js',
'jquery-ui.min.js',
'select2.full.min.js',
'tagsinput-revisited.min.js',
'functions.js',
'api.js'
), DOMAIN_CORE_JS);
echo HTML::jquery();
echo HTML::jsBootstrap();
echo HTML::jsSortable();
echo HTML::js(array(
'jquery.datetimepicker.full.min.js',
'jquery-ui.min.js',
'select2.full.min.js',
'tagsinput-revisited.min.js',
'functions.js',
'api.js'
), DOMAIN_CORE_JS);
?>
<!-- Execute plugins for the admin area inside the HTML <head> tag -->
@ -54,11 +55,12 @@
<!-- Javascript global variable generated by PHP -->
<?php include(PATH_CORE_JS . 'variables.php') ?>
<!-- Navbar, only for small devices -->
<?php include('html/navbar.php'); ?>
<div class="container-fluid p-0 m-0 d-flex flex-column h-100">
<!-- Alerts -->
<?php include('html/alerts.php') ?>
<!-- End Alerts -->
<!-- Top Navbar -->
<div class="container-fluid p-0 bg-dark">
<div class="container">
@ -72,19 +74,19 @@
</div>
</div>
</div>
<!-- END Top Navbar -->
<!-- End Top Navbar -->
<!-- Main -->
<div class="container mt-3 h-100 flex-grow-1">
<div class="container h-100 flex-grow-1">
<div class="row h-100 flex-grow-1">
<!-- LEFT Main, display only on large devices -->
<div class="sidebar col-lg-2 d-none d-lg-block">
<div class="sidebar col-lg-2 d-none d-lg-block mt-4">
<?php include('html/sidebar.php'); ?>
</div>
<!-- RIGHT Main -->
<div class="main col-lg-10">
<div class="main col-lg-10 mt-2">
<?php
if (Sanitize::pathFile(PATH_ADMIN_VIEWS . $layout['view'] . '.php')) {
include(PATH_ADMIN_VIEWS . $layout['view'] . '.php');
@ -98,7 +100,7 @@
</div>
</div>
</div>
<!-- END Main -->
<!-- End Main -->
</div>
@ -106,4 +108,5 @@
<?php execPluginsByHook('adminBodyEnd') ?>
</body>
</html>

View file

@ -1,6 +1,6 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
echo '<h1 class="text-center font-weight-normal mb-5">'.$site->title().'</h1>';
echo '<h1 class="text-center fw-normal mb-5">'.$site->title().'</h1>';
echo Bootstrap::formOpen(array());
@ -42,4 +42,4 @@ echo '</form>';
echo '<p class="mt-5 text-end">Powered by <a href="https://www.bludit.com">Bludit</a></p>'
?>
?>

View file

@ -1,253 +1,256 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ----------------------------------------------------------------------------
// Variables for the view
// ----------------------------------------------------------------------------
var _pageKey = null; // The page key is generated the first time the user click on the button "Save"
var _uuid = '<?php echo $uuid ?>'; // The UUID is generated at the begining if the user uploaded files to the page
// ----------------------------------------------------------------------------
// Variables for the view
// ----------------------------------------------------------------------------
var _pageKey = null; // The page key is generated the first time the user click on the button "Save"
// ----------------------------------------------------------------------------
// Functions for the view
// ----------------------------------------------------------------------------
// Default function for the editor area (textarea)
// This helps if the user doesn't activate any plugin as editor
if (typeof editorGetContent != 'function') {
window.editorGetContent = function(){
return $('#editor').val();
};
}
if (typeof editorInsertContent != 'function') {
window.editorInsertContent = function(html){
$('#editor').val($('#editor').val()+html);
};
}
// ----------------------------------------------------------------------------
// Functions for the view
// ----------------------------------------------------------------------------
// Creates or save the page
// This function set the global variable "_pageKey"
function save(args) {
args['uuid'] = _uuid;
// If the "page key" doesn't exists means the page not was created
// Create the page to generate a "page key"
if (_pageKey == null) {
// Default function for the editor
// These functions work if the user does not activate any plugin
if (typeof editorGetContent != 'function') {
window.editorGetContent = function() {
return $('#editor').val();
};
}
if (typeof editorInsertContent != 'function') {
window.editorInsertContent = function(html) {
$('#editor').val($('#editor').val() + html);
};
}
// Create the a page
// This function set the global variable "_pageKey"
function createPage() {
logs('Creating page');
api.createPage(args).then(function(key) {
logs('Page created. Key: '+key);
api.createPage().then(function(key) {
logs('Page created. Key: ' + key);
// Set the global variable with the page key
_pageKey = key;
// Disable the button save and change text
//$("#btnSave").attr("disabled", true).html("Saved");
});
} else {
return true;
}
// Save the current page
// This function set the global variable "_pageKey"
function save(args) {
logs('Saving page');
if (_pageKey == null) {
showAlert("Error, page not created.");
return false;
}
args['pageKey'] = _pageKey;
api.savePage(args).then(function(key) {
logs('Page saved. Old key: '+_pageKey+' / New key: '+key);
logs('Page saved. Old key: ' + _pageKey + ' / New key: ' + key);
// Set the global variable with the page key
// The page key can change after save the page so you need to set again the variable
_pageKey = key;
// Disable the button save and change text
//$("#btnSave").attr("disabled", true).html("Saved");
});
return true;
}
// Close all modals
$('.modal').modal('hide');
return true;
}
// Open the modal and store the current value
// The current value is store to recover it if the user click on the button "Cancel"
function openModal(fieldName) {
var value = $('#'+fieldName).val();
localStorage.setItem(fieldName, value);
$('#modal-'+fieldName).modal('show');
}
// Close the modal when the user click in the button "Cancel"
// The function also recover the old value
function closeModal(fieldName) {
var value = localStorage.getItem(fieldName);
$('#'+fieldName).val(value);
$('#modal-'+fieldName).modal('hide');
}
// This function is to catch all key press
// Provides Shortcuts
// The editor plugin need to call this function for the event "keydown"
function keypress(event) {
logs(event);
// Shortcuts
// ------------------------------------------------------------------------
// Ctrl+S or Command+S
if ((event.ctrlKey || event.metaKey) && event.which == 83) {
var args = {
title: $('#title').val(),
content: editorGetContent(),
category: $('#category option:selected').val(),
tags: $('#tags').val()
}
save(args);
$('#btnSave').addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>');
event.preventDefault();
return false;
// Open the modal and store the current value
// The current value is store to recover it if the user click on the button "Cancel"
function openModal(fieldName) {
var value = $('#' + fieldName).val();
localStorage.setItem(fieldName, value);
$('#modal-' + fieldName).modal('show');
}
$('#btnSave').removeClass('btn-primary-disabled').html('<?php $L->p('Save') ?>');
}
// Close the modal when the user click in the button "Cancel"
// The function also recover the old value
function closeModal(fieldName) {
var value = localStorage.getItem(fieldName);
$('#' + fieldName).val(value);
$('#modal-' + fieldName).modal('hide');
}
// ----------------------------------------------------------------------------
// Events for the view
// ----------------------------------------------------------------------------
$(document).ready(function() {
// This function is to catch all key press and provides shortcuts
// The editor plugin need to call this function for the event "keydown"
function keypress(event) {
logs(event);
// Main interface events
// ------------------------------------------------------------------------
$(this).keydown(function(event){
keypress(event);
});
$('#btnSave').on('click', function() {
var args = {
title: $('#title').val(),
content: editorGetContent(),
category: $('#category option:selected').val(),
tags: $('#tags').val()
// Shortcuts
// ------------------------------------------------------------------------
// Ctrl+S or Command+S
if ((event.ctrlKey || event.metaKey) && event.which == 83) {
var args = {
title: $('#title').val(),
content: editorGetContent(),
category: $('#category option:selected').val(),
tags: $('#tags').val()
}
save(args);
$('#btnSave').addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>');
event.preventDefault();
return false;
}
save(args);
$(this).addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>');
});
$("#btnPreview").on("click", function() {
var title = $("#jstitle").val();
var content = editorGetContent();
bluditAjax.saveAsDraft(uuid, title, content).then(function(data) {
var preview = window.open("<?php echo DOMAIN_PAGES.'autosave-'.$uuid.'?preview='.md5('autosave-'.$uuid) ?>", "bludit-preview");
preview.focus();
$('#btnSave').removeClass('btn-primary-disabled').html('<?php $L->p('Save') ?>');
}
// ----------------------------------------------------------------------------
// Events for the view
// ----------------------------------------------------------------------------
$(document).ready(function() {
// Main interface events
// ------------------------------------------------------------------------
$(this).keydown(function(event) {
keypress(event);
});
});
$('#btnCurrenStatus').on('click', function() {
openModal('status');
});
$('#category').on("change", function() {
$('#btnSave').html('<?php $L->p('Save') ?>');
});
// Modal description events
// ------------------------------------------------------------------------
$('#btnSaveDescription').on('click', function() {
var args = {
description: $('#description').val()
};
save(args);
});
$('#btnCancelDescription').on('click', function() {
closeModal('description');
});
// Modal date events
// ------------------------------------------------------------------------
$('#btnSaveDate').on('click', function() {
var args = {
date: $('#date').val()
};
save(args);
});
$('#btnCancelDate').on('click', function() {
closeModal('date');
});
// Modal friendly-url events
// ------------------------------------------------------------------------
$('#btnSaveFriendlyURL').on('click', function() {
var args = {
slug: $('#friendlyURL').val()
};
save(args);
});
$('#btnCancelFriendlyURL').on('click', function() {
closeModal('friendlyURL');
});
$('#btnGenURLFromTitle').on('click', function() {
var args = {
text: $('#title').val(),
parentKey: $('#parent').val(),
pageKey: _pageKey
}
api.friendlyURL(args).then(function(slug) {
$('#friendlyURL').val(slug);
$('#btnSave').on('click', function() {
var args = {
title: $('#title').val(),
content: editorGetContent(),
category: $('#category option:selected').val(),
tags: $('#tags').val()
}
save(args);
$(this).addClass('btn-primary-disabled').html('<?php $L->p('Saved') ?>');
});
$("#btnPreview").on("click", function() {
var title = $("#jstitle").val();
var content = editorGetContent();
bluditAjax.saveAsDraft(uuid, title, content).then(function(data) {
var preview = window.open("<?php echo DOMAIN_PAGES . 'autosave-' . $uuid . '?preview=' . md5('autosave-' . $uuid) ?>", "bludit-preview");
preview.focus();
});
});
$('#btnCurrenStatus').on('click', function() {
openModal('status');
});
$('#category').on("change", function() {
$('#btnSave').html('<?php $L->p('Save') ?>');
});
// Modal description events
// ------------------------------------------------------------------------
$('#btnSaveDescription').on('click', function() {
var args = {
description: $('#description').val()
};
save(args);
});
$('#btnCancelDescription').on('click', function() {
closeModal('description');
});
// Modal date events
// ------------------------------------------------------------------------
$('#btnSaveDate').on('click', function() {
var args = {
date: $('#date').val()
};
save(args);
});
$('#btnCancelDate').on('click', function() {
closeModal('date');
});
// Modal friendly-url events
// ------------------------------------------------------------------------
$('#btnSaveFriendlyURL').on('click', function() {
var args = {
slug: $('#friendlyURL').val()
};
save(args);
});
$('#btnCancelFriendlyURL').on('click', function() {
closeModal('friendlyURL');
});
$('#btnGenURLFromTitle').on('click', function() {
var args = {
text: $('#title').val(),
parentKey: $('#parent').val(),
pageKey: _pageKey
}
api.friendlyURL(args).then(function(slug) {
$('#friendlyURL').val(slug);
});
});
// Modal status events
// ------------------------------------------------------------------------
$('#btnSaveStatus').on('click', function() {
var args = {
type: $('input[name="status"]:checked').val()
};
save(args);
if (args['type'] == 'draft') {
$('#btnCurrenStatus').html('<i class="bi-square-fill"></i> <?php $L->p('Draft') ?>');
} else if (args['type'] == 'published') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Published') ?>');
} else if (args['type'] == 'unlisted') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Unlisted') ?>');
} else if (args['type'] == 'sticky') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Sticky') ?>');
} else if (args['type'] == 'static') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Static') ?>');
}
});
$('#btnCancelStatus').on('click', function() {
closeModal('status');
});
// Modal SEO events
// ------------------------------------------------------------------------
$('#btnSaveSeo').on('click', function() {
var args = {
parent: $('#parent').val()
};
save(args);
});
$('#btnCancelSeo').on('click', function() {
closeModal('seo');
});
// Modal parent events
// ------------------------------------------------------------------------
$('#btnSaveParent').on('click', function() {
var args = {
parent: $('#parent').val()
};
save(args);
});
$('#btnCancelParent').on('click', function() {
closeModal('parent');
});
});
// Modal status events
// ------------------------------------------------------------------------
$('#btnSaveStatus').on('click', function() {
var args = {
type: $('input[name="status"]:checked').val()
};
save(args);
if (args['type']=='draft') {
$('#btnCurrenStatus').html('<i class="bi-square-fill"></i> <?php $L->p('Draft') ?>');
} else if (args['type']=='published') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Published') ?>');
} else if (args['type']=='unlisted') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Unlisted') ?>');
} else if (args['type']=='sticky') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Sticky') ?>');
} else if (args['type']=='static') {
$('#btnCurrenStatus').html('<i class="bi-check-square-fill"></i> <?php $L->p('Static') ?>');
}
// ----------------------------------------------------------------------------
// Initlization for the view
// ----------------------------------------------------------------------------
$(document).ready(function() {
// Create the page at the beggining
// How do you hang your toilet paper ? over or under ?
createPage();
});
$('#btnCancelStatus').on('click', function() {
closeModal('status');
});
// Modal SEO events
// ------------------------------------------------------------------------
$('#btnSaveSeo').on('click', function() {
var args = {
parent: $('#parent').val()
};
save(args);
});
$('#btnCancelSeo').on('click', function() {
closeModal('seo');
});
// Modal parent events
// ------------------------------------------------------------------------
$('#btnSaveParent').on('click', function() {
var args = {
parent: $('#parent').val()
};
save(args);
});
$('#btnCancelParent').on('click', function() {
closeModal('parent');
});
});
// ----------------------------------------------------------------------------
// Initlization for the view
// ----------------------------------------------------------------------------
$(document).ready(function() {
// nothing here yet
// how do you hang your toilet paper ? over or under ?
});
</script>
<!-- File manager -->
<?php include(PATH_ADMIN_THEMES . 'booty/html/file-manager.php'); ?>
<!-- End File manager -->
<!-- Modal Description -->
<div class="modal" id="modal-description" tabindex="-1">
<div class="modal-dialog">
@ -287,9 +290,11 @@ $(document).ready(function() {
</div>
</div>
<script>
$(document).ready(function() {
$("#date").datetimepicker({format:DB_DATE_FORMAT});
});
$(document).ready(function() {
$("#date").datetimepicker({
format: DB_DATE_FORMAT
});
});
</script>
<!-- End Modal Date -->
@ -412,198 +417,169 @@ $(document).ready(function() {
</div>
</div>
<script>
$(document).ready(function() {
var parent = $("#parent").select2({
placeholder: "",
allowClear: true,
theme: "bootstrap4",
minimumInputLength: 2,
ajax: {
url: HTML_PATH_ADMIN_ROOT+"ajax/get-published",
data: function (params) {
var query = {
checkIsParent: true,
query: params.term
}
return query;
},
processResults: function (data) {
return data;
}
},
escapeMarkup: function(markup) {
return markup;
},
templateResult: function(data) {
var html = data.text;
if (data.type=="static") {
html += '<span class="badge badge-pill badge-light">'+data.type+'</span>';
}
return html;
}
});
});
</script>
<!-- End Modal Parent -->
<!-- Modal Files / Images -->
<div class="modal" id="modal-files" tabindex="-1" aria-labelledby="modal-files" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<label class="fw-bold">Files</label>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelSeo" type="button" class="btn btn-cancel fw-bold me-auto"><i class="bi-x-square me-2"></i>Cancel</button>
<button id="btnSaveSeo" type="button" class="btn btn-save fw-bold text-success"><i class="bi-check-square me-2"></i>Save</button>
</div>
</div>
</div>
</div>
<!-- End Modal SEO -->
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-9 d-flex flex-column h-100">
<!-- Toolbar > Save, Preview, Status and Options -->
<div id="editorToolbar">
<div id="editorToolbarRight" class="btn-group btn-group-sm float-end" role="group" aria-label="Toolbar right">
<div class="dropdown">
<button type="button" class="btn dropdown-toggle" type="button" id="dropdownMenuOptions" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi-gear me-2"></i></span><?php $L->p('Options') ?>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuOptions">
<a onclick="openModal('description')" class="dropdown-item" href="#"><i class="bi-info-square me-2"></i>Description</a>
<a onclick="openModal('date')" class="dropdown-item" href="#"><i class="bi-calendar me-2"></i>Publish date</a>
<a onclick="openModal('friendlyURL')" class="dropdown-item" href="#"><i class="bi-link me-2"></i>Change URL</a>
<a onclick="openModal('status')" class="dropdown-item" href="#"><i class="bi-eye me-2"></i>Status</a>
<a onclick="openModal('seo')" class="dropdown-item" href="#"><i class="bi-compass me-2"></i>SEO features</a>
<a onclick="openModal('parent')" class="dropdown-item" href="#"><i class="bi-diagram-2 me-2"></i>Parent page</a>
</div>
</div>
</div>
<div id="editorToolbarLeft">
<button id="btnSave" type="button" class="btn btn-sm btn-primary" ><?php $L->p('Save') ?></button>
<button id="btnPreview" type="button" class="btn btn-sm btn-secondary"><?php $L->p('Preview') ?></button>
<span id="btnCurrenStatus"><i class="bi-square-fill ms-1 me-1"></i><span><?php $L->p('Draft') ?></span></span>
</div>
</div>
<!-- End Toolbar > Save, Preview, Status and Options -->
<!-- Title -->
<div class="mb-1">
<input id="title" name="title" type="text" class="form-control form-control-lg" value="" placeholder="<?php $L->p('Enter title') ?>">
</div>
<!-- End Title -->
<!-- Editor -->
<textarea class="form-control flex-grow-1" placeholder="" id="editor"></textarea>
<!-- End Editor -->
</div> <!-- End <div class="col-sm-9 h-100"> -->
<div class="col-sm-3 h-100">
<!-- Cover Image -->
<h6 class="mt-1 mb-2 pb-2 text-uppercase"><?php $L->p('Cover Image') ?></h6>
<div>
<img id="jscoverImagePreview" class="mx-auto d-block w-100" alt="Cover image preview" src="<?php echo HTML_PATH_CORE_IMG ?>default.svg" />
</div>
<!-- End Cover Image -->
<!-- Images -->
<h6 class="mt-4 mb-2 pb-2 text-uppercase"><?php $L->p('Images') ?></h6>
<div class="media text-muted pt-3">
<svg class="align-self-center me-3 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32"><title>Placeholder</title><rect width="100%" height="100%" fill="#007bff"></rect><text x="50%" y="50%" fill="#007bff" dy=".3em">32x32</text></svg>
<div class="media-body">
<div class="mt-0">
photo1.jpg
</div>
</div>
</div>
<div class="media text-muted pt-3">
<svg class="align-self-center me-3 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32"><title>Placeholder</title><rect width="100%" height="100%" fill="#007bff"></rect><text x="50%" y="50%" fill="#007bff" dy=".3em">32x32</text></svg>
<div class="media-body">
<div class="mt-0">
photo2.jpg
</div>
</div>
</div>
<div class="d-block text-end mt-3">
<a href="#">All images</a>
</div>
<!-- End Images -->
<!-- Category -->
<div class="m-0">
<h6 class="mt-4 mb-2 pb-2 text-uppercase">Category</h6>
<select id="category" name="category" class="custom-select">
<option value="">- Uncategorized -</option>
<?php foreach ($categories->db as $key=>$fields): ?>
<option value="<?php echo $key ?>"><?php echo $fields['name']?></option>
<?php endforeach; ?>
</select>
</div>
<!-- End Category -->
<!-- Tags -->
<h6 class="mt-4 mb-2 pb-2 text-uppercase">Tags</h6>
<input id="tags" name="tags" type="text" value="">
<script>
$(document).ready(function() {
$('#tags').tagsInput({
placeholder:'Add a tag',
delimiter:',',
removeWithBackspace:true,
'autocomplete': {
source: [
<?php
foreach ($tags->db as $key=>$fields) {
echo '"'.$fields['name'].'",';
var parent = $("#parent").select2({
placeholder: "",
allowClear: true,
theme: "bootstrap4",
minimumInputLength: 2,
ajax: {
url: HTML_PATH_ADMIN_ROOT + "ajax/get-published",
data: function(params) {
var query = {
checkIsParent: true,
query: params.term
}
?>
]
return query;
},
processResults: function(data) {
return data;
}
},
escapeMarkup: function(markup) {
return markup;
},
templateResult: function(data) {
var html = data.text;
if (data.type == "static") {
html += '<span class="badge badge-pill badge-light">' + data.type + '</span>';
}
return html;
}
});
});
</script>
<!-- End Tags -->
</script>
<!-- End Modal Parent -->
</div> <!-- End <div class="col-sm-3 h-100"> -->
</div> <!-- End <div class="row h-100"> -->
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-9 d-flex flex-column h-100">
<!-- Toolbar > Save, Preview, Status and Options -->
<div id="editorToolbar" class="d-flex align-items-center mb-2">
<div id="editorToolbarLeft">
<button id="btnSave" type="button" class="btn btn-sm btn-primary"><?php $L->p('Save') ?></button>
<button id="btnPreview" type="button" class="btn btn-sm btn-secondary"><?php $L->p('Preview') ?></button>
<span id="btnCurrenStatus"><i class="bi-square-fill ms-1 me-1"></i><span><?php $L->p('Draft') ?></span></span>
</div>
<div id="editorToolbarRight" class="ms-auto">
<div class="dropdown">
<button type="button" class="btn dropdown-toggle" type="button" id="dropdownMenuOptions" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi-gear me-2"></i></span><?php $L->p('Options') ?>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuOptions">
<a onclick="openModal('description')" class="dropdown-item" href="#"><i class="bi-info-square me-2"></i>Description</a>
<a onclick="openModal('date')" class="dropdown-item" href="#"><i class="bi-calendar me-2"></i>Publish date</a>
<a onclick="openModal('friendlyURL')" class="dropdown-item" href="#"><i class="bi-link me-2"></i>Change URL</a>
<a onclick="openModal('status')" class="dropdown-item" href="#"><i class="bi-eye me-2"></i>Status</a>
<a onclick="openModal('seo')" class="dropdown-item" href="#"><i class="bi-compass me-2"></i>SEO features</a>
<a onclick="openModal('parent')" class="dropdown-item" href="#"><i class="bi-diagram-2 me-2"></i>Parent page</a>
</div>
</div>
</div>
</div>
<!-- End Toolbar > Save, Preview, Status and Options -->
<!-- Title -->
<div class="mb-2">
<input id="title" name="title" type="text" class="form-control form-control-lg" value="" placeholder="<?php $L->p('Enter title') ?>">
</div>
<!-- End Title -->
<!-- Editor -->
<textarea class="form-control flex-grow-1" placeholder="" id="editor"></textarea>
<!-- End Editor -->
</div> <!-- End <div class="col-sm-9 h-100"> -->
<div class="col-sm-3 h-100 mt-2">
<!-- Cover Image -->
<h6 class="text-uppercase"><?php $L->p('Cover Image') ?></h6>
<div>
<img id="jscoverImagePreview" class="mx-auto d-block w-100" alt="Cover image preview" src="<?php echo HTML_PATH_CORE_IMG ?>default.svg" />
</div>
<!-- End Cover Image -->
<!-- Category -->
<h6 class="text-uppercase mt-4">Category</h6>
<?php
echo Bootstrap::formSelect(array(
'id' => 'category',
'name' => 'category',
'options' => array_merge(array('' => $L->g('Uncategorized')), $categories->getKeyNameArray())
));
?>
<!-- End Category -->
<!-- Tags -->
<h6 class="mt-4 mb-2 pb-2 text-uppercase">Tags</h6>
<input id="tags" name="tags" type="text" value="">
<script>
$(document).ready(function() {
$('#tags').tagsInput({
placeholder: 'Add a tag',
delimiter: ',',
removeWithBackspace: true,
'autocomplete': {
source: [
<?php
foreach ($tags->db as $key => $fields) {
echo '"' . $fields['name'] . '",';
}
?>
]
}
});
});
</script>
<!-- End Tags -->
<!-- Quick files -->
<h6 class="text-uppercase mt-4"><?php $L->p('Images') ?></h6>
<div id="quickFiles">
<div class="d-flex align-items-center mb-1">
<i class="bi bi-image me-2" style="font-size: 1.6rem;"></i>
<span>photo1.jpg</span>
</div>
<div class="d-flex align-items-center mb-1">
<i class="bi bi-image me-2" style="font-size: 1.6rem;"></i>
<span>test.txt</span>
</div>
<div class="d-flex align-items-center mb-1">
<i class="bi bi-image me-2" style="font-size: 1.6rem;"></i>
<span>test.txt</span>
</div>
</div>
<!-- End Quick files -->
</div> <!-- End <div class="col-sm-3 h-100"> -->
</div> <!-- End <div class="row h-100"> -->
</div> <!-- End <div class="container-fluid h-100"> -->
<script>
$(document).ready(function() {
$(document).ready(function() {
// Autosave
var currentContent = editorGetContent();
setInterval(function() {
// Autosave
var currentContent = editorGetContent();
setInterval(function() {
var uuid = $("#jsuuid").val();
var title = $("#jstitle").val() + "[<?php $L->p('Autosave') ?>]";
var content = editorGetContent();
// Autosave when content has at least 100 characters
if (content.length<100) {
if (content.length < 100) {
return false;
}
// Autosave only when the user change the content
if (currentContent!=content) {
if (currentContent != content) {
currentContent = content;
bluditAjax.saveAsDraft(uuid, title, content).then(function(data) {
if (data.status==0) {
if (data.status == 0) {
showAlert("<?php $L->p('Autosave') ?>");
}
});
}
},1000*60*AUTOSAVE_INTERVAL);
}, 1000 * 60 * AUTOSAVE_INTERVAL);
});
</script>
});
</script>

View file

@ -304,25 +304,14 @@ function execPluginsByHook($hook, $args = array()) {
}
}
/*
Create a new page
/* Create a new page
The array $args support all the keys from variable $dbFields of the class pages.class.php
If you don't pass all the keys, the default values are used, the default values are from $dbFields in the class pages.class.php
@args array The array $args supports all the keys from the variable $dbFields of the class pages.class.php. If you don't pass all the keys, the default values are used.
@returns string/boolean Returns the page key if the page is successfully created, FALSE otherwise
*/
function createPage($args) {
global $pages;
global $syslog;
global $L;
// Check if the autosave page exists for this new page and delete it
if (isset($args['uuid'])) {
$autosaveKey = $pages->getByUUID('autosave-'.$args['uuid']);
if (!empty($autosaveKey)) {
Log::set('Function createPage()'.LOG_SEP.'Autosave deleted for '.$args['title'], LOG_TYPE_INFO);
deletePage($autosaveKey);
}
}
// The user is always the one logged
$args['username'] = Session::get('username');
@ -334,8 +323,9 @@ function createPage($args) {
$key = $pages->add($args);
if ($key) {
// Call the plugins after page created
Theme::plugins('afterPageCreate', array($key));
execPluginsByHook('afterPageCreate', array($key));
// Reindex categories and tags
reindexCategories();
reindexTags();
@ -345,47 +335,43 @@ function createPage($args) {
'notes'=>(empty($args['title'])?$key:$args['title'])
));
Log::set('Function createPage()'.LOG_SEP.'Page created successfully.', LOG_TYPE_INFO);
return $key;
}
Log::set('Function createNewPage()'.LOG_SEP.'Error occurred when trying to create the page', LOG_TYPE_ERROR);
Log::set('Function createNewPage()'.LOG_SEP.'Cleaning database...', LOG_TYPE_ERROR);
Log::set('Function createPage()'.LOG_SEP.'Something happened when you tried to create the page.', LOG_TYPE_ERROR);
deletePage($key);
Log::set('Function createNewPage()'.LOG_SEP.'Cleaning finished...', LOG_TYPE_ERROR);
return false;
}
/* Edit a page
@args array The array $args supports all the keys from the variable $dbFields of the class pages.class.php. If you don't pass all the keys, the default values are used.
@args['key'] string The key of the page to be edited
@returns string/boolean Returns the page key if the page is successfully edited, FALSE otherwise
*/
function editPage($args) {
global $pages;
global $syslog;
// Check if the autosave/preview page exists for this new page and delete it
if (isset($args['uuid'])) {
$autosaveKey = $pages->getByUUID('autosave-'.$args['uuid']);
if ($autosaveKey) {
Log::set('Function editPage()'.LOG_SEP.'Autosave/Preview deleted for '.$autosaveKey, LOG_TYPE_INFO);
deletePage($autosaveKey);
}
}
// Check if the key is not empty
if (empty($args['key'])) {
Log::set('Function editPage()'.LOG_SEP.'Empty key.', LOG_TYPE_ERROR);
Log::set('Function editPage()'.LOG_SEP.'Empty page key.', LOG_TYPE_ERROR);
return false;
}
// Check if the page key exist
if (!$pages->exists($args['key'])) {
Log::set('Function editPage()'.LOG_SEP.'Page key does not exist, '.$args['key'], LOG_TYPE_ERROR);
Log::set('Function editPage()'.LOG_SEP.'Page key doesn\'t exist: '.$args['key'], LOG_TYPE_ERROR);
return false;
}
$key = $pages->edit($args);
if ($key) {
// Call the plugins after page modified
Theme::plugins('afterPageModify', array($key));
execPluginsByHook('afterPageModify', array($key));
// Reindex categories and tags
reindexCategories();
reindexTags();
@ -395,21 +381,28 @@ function editPage($args) {
'notes'=>empty($args['title'])?$key:$args['title']
));
Log::set('Function editPage()'.LOG_SEP.'Page edited successfully.', LOG_TYPE_INFO);
return $key;
}
Log::set('Function editPage()'.LOG_SEP.'Something happen when try to edit the page.', LOG_TYPE_ERROR);
Log::set('Function editPage()'.LOG_SEP.'Something happened when you tried to edit the page.', LOG_TYPE_ERROR);
return false;
}
/* Delete a page
@key string The key of the page to be deleted
@returns string/boolean Returns TRUE if the page is successfully deleted, FALSE otherwise
*/
function deletePage($key) {
global $pages;
global $syslog;
if ($pages->delete($key)) {
// Call the plugins after page deleted
Theme::plugins('afterPageDelete', array($key));
execPluginsByHook('afterPageDelete', array($key));
// Reindex categories and tags
reindexCategories();
reindexTags();
@ -419,9 +412,11 @@ function deletePage($key) {
'notes'=>$key
));
Log::set('Function deletePage()'.LOG_SEP.'Page deleted successfully.', LOG_TYPE_INFO);
return true;
}
Log::set('Function deletePage()'.LOG_SEP.'Something happened when you tried to delete the page.', LOG_TYPE_ERROR);
return false;
}

View file

@ -8,11 +8,10 @@ class Bootstrap {
{
$name = $args['name'];
$id = isset($args['id'])?$args['id']:$name;
$disabled = empty($args['disabled'])?'':'disabled';
$readonly = empty($args['readonly'])?'':'readonly';
$placeholder = isset($args['placeholder'])?$args['placeholder']:'';
$value = isset($args['value'])?$args['value']:'';
$type = isset($args['type'])?$args['type']:'text';
$placeholder = isset($args['placeholder'])?$args['placeholder']:'';
$label = isset($args['label'])?$args['label']:$placeholder;
$class = 'form-control';
@ -22,12 +21,36 @@ class Bootstrap {
return <<<EOF
<div class="form-floating mb-3">
<input type="$type" class="$class" id="$id" name="$name" placeholder="$placeholder">
<input type="$type" class="$class" id="$id" name="$name" value="$value" placeholder="$placeholder">
<label for="$id">$label</label>
</div>
EOF;
}
public static function formSelect($args)
{
$name = $args['name'];
$id = isset($args['id'])?$args['id']:$name;
$class = 'form-select';
if (isset($args['class'])) {
$class = $class.' '.$args['class'];
}
$html = '<div>';
if (isset($args['label'])) {
$html .= '<label for="'.$id.'">'.$args['label'].'</label>';
}
$html .= '<select id="'.$id.'" name="'.$name.'" class="'.$class.'">';
foreach ($args['options'] as $key=>$value) {
$html .= '<option '.(($key==$args['selected'])?'selected':'').' value="'.$key.'">'.$value.'</option>';
}
$html .= '</select>';
$html .= '</div>';
return $html;
}
public static function formInputText($args)
{
$name = $args['name'];
@ -64,7 +87,7 @@ return <<<EOF
EOF;
}
public static function formSelect($args)
public static function formSelectOld($args)
{
$name = $args['name'];
$id = isset($args['id'])?$args['id']:$name;

View file

@ -12,7 +12,7 @@ class API {
}
}
async createPage(args) {
async createPage(args={}) {
var url = this.apiURL + "pages";
var body = Object.assign({}, this.body, args);
try {
@ -32,12 +32,10 @@ class API {
}
}
/*
Save page fields
/* Save page fields
@args['pageKey'] string Page key from the page to edit
@args array Arguments can be any of the fields from a page
@returns string New page key
*/
async savePage(args) {
@ -60,13 +58,11 @@ class API {
}
}
/*
Generates unique slug text for the a page
/* Generates unique slug text for the a page
@args['pageKey'] string Page key for the page to generate the slug url
@args['text'] string Text that you want to generate the slug url
@args['parentKey'] string Parent page key if the page has one, if not empty string
@returns string Slug text
*/
async friendlyURL(args) {
@ -87,11 +83,9 @@ class API {
}
}
/*
Get all files uploaded for the page
/* Get all files uploaded for the page
@args['pageKey'] string
@returns array
*/
async getPageFiles(args) {
@ -109,11 +103,35 @@ class API {
}
}
/*
Save settings
/* Upload files
@args['pageKey'] string
@returns array
*/
async uploadPageFiles(args) {
var url = this.apiURL + "files/" + args['pageKey'];
var body = Object.assign({}, this.body, args);
try {
var response = await fetch(url, {
credentials: "same-origin",
method: "POST",
body: JSON.stringify(body),
headers: new Headers({
"Content-Type": "application/json"
})
});
var json = await response.json();
return json.data.key;
} catch (err) {
console.log(err);
return true;
}
}
/* Save settings
@args array Arguments can be any of the fields from settings
@returns array
*/
async saveSettings(args) {

View file

@ -43,4 +43,16 @@ function logs(message) {
if (DEBUG_MODE) {
console.log(message);
}
}
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

View file

@ -50,8 +50,11 @@ class Pages extends dbJSON {
return isset( $this->db[$key] );
}
// Create a new page
// This function returns the key of the new page
/* Create a new page
@args array The array $args supports all the keys from the variable $dbFields. If you don't pass all the keys, the default values are used.
@returns string/boolean Returns the page key if the page is successfully created, FALSE otherwise
*/
public function add($args)
{
$row = array();
@ -134,20 +137,26 @@ class Pages extends dbJSON {
// Create the directory
if (Filesystem::mkdir(PATH_PAGES.$key, true) === false) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory ['.PATH_PAGES.$key.']',LOG_TYPE_ERROR);
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to create the directory: '.PATH_PAGES.$key, LOG_TYPE_ERROR);
return false;
}
// Create the upload directory for the page
if (Filesystem::mkdir(PATH_UPLOADS_PAGES.$key, true) === false) {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to create the directory: '.PATH_UPLOADS_PAGES.$key, LOG_TYPE_ERROR);
return false;
}
// Create the index.txt and save the file
if (file_put_contents(PATH_PAGES.$key.DS.FILENAME, $contentRaw) === false) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the content in the file ['.FILENAME.']',LOG_TYPE_ERROR);
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to create the file: '.FILENAME, LOG_TYPE_ERROR);
return false;
}
// Checksum MD5
$row['md5file'] = md5_file(PATH_PAGES.$key.DS.FILENAME);
// Insert in database
// Insert into database
$this->db[$key] = $row;
// Sort database
@ -156,18 +165,14 @@ class Pages extends dbJSON {
// Save database
$this->save();
// Create symlink for images directory
if (Filesystem::mkdir(PATH_UPLOADS_PAGES.$row['uuid'])) {
symlink(PATH_UPLOADS_PAGES.$row['uuid'], PATH_UPLOADS_PAGES.$key);
}
return $key;
}
// Edit a page
// This function do not edit the current row from the table -
// - instead of that the function creates a new row and is completed by the current -
// - values of the page and then the old row is deleted and the new row is inserted.
/* Edit a page
@args array The array $args supports all the keys from the variable $dbFields. If you don't pass all the keys, the default values are used.
@returns string/boolean Returns the page key if the page is successfully edited, FALSE otherwise
*/
public function edit($args)
{
// This is the new row for the table and is going to replace the old row
@ -248,13 +253,14 @@ class Pages extends dbJSON {
// Move the directory from old key to new key only if the keys are different
if ($newKey!==$key) {
if (Filesystem::mv(PATH_PAGES.$key, PATH_PAGES.$newKey) === false) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to move the directory to '.PATH_PAGES.$newKey);
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to move the directory '.PATH_PAGES.$newKey);
return false;
}
// Regenerate the symlink to a proper directory
unlink(PATH_UPLOADS_PAGES.$key);
symlink(PATH_UPLOADS_PAGES.$row['uuid'], PATH_UPLOADS_PAGES.$newKey);
if (Filesystem::mv(PATH_UPLOADS_PAGES.$key, PATH_UPLOADS_PAGES.$newKey) === false) {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to move the directory '.PATH_UPLOADS_PAGES.$newKey);
return false;
}
}
// If the content was passed via arguments replace the content

View file

@ -142,7 +142,7 @@ class pluginBackup extends Plugin {
}
$html .= '<div>';
$html .= '<h4 class="font-weight-normal">'.$name.($count > 0? " ($count)": "").'</h4>';
$html .= '<h4 class="fw-normal">'.$name.($count > 0? " ($count)": "").'</h4>';
// Allow download if a zip file
if ($this->zip) {
$html .= '<a class="btn btn-outline-secondary btn-sm me-1 mt-1" href="'.DOMAIN_BASE.'plugin-backup-download?file='.$filename.'.zip"><span class="bi-download"></span> '.$L->get('download').'</a>';

View file

@ -597,7 +597,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
<div class="container">
<div class="row justify-content-md-center pt-5">
<div class="col-md-4 pt-5">
<h1 class="text-center mb-5 mt-5 font-weight-normal text-uppercase" style="color: #555;"><?php echo $L->get('Bludit Installer') ?></h1>
<h1 class="text-center mb-5 mt-5 fw-normal text-uppercase" style="color: #555;"><?php echo $L->get('Bludit Installer') ?></h1>
<?php
$system = checkSystem();
if (!empty($system)) {