Refactor main clasess, add new library for manage images

This commit is contained in:
dignajar 2021-01-23 22:19:47 +01:00
parent 993a4f92d6
commit 3b37cb2905
30 changed files with 3116 additions and 876 deletions

View file

@ -63,7 +63,7 @@ class dbJSON {
/* Save the JSON file
@returns boolean Returns TRUE if the file was saved successfully, FALSE otherwise
@return boolean Returns TRUE if the file was saved successfully, FALSE otherwise
*/
public function save()
{

View file

@ -78,7 +78,7 @@ class dbList extends dbJSON
/* Add a new item to the dblist === Bludit v4
@args array The array $args supports the following keys 'name', 'template', 'description', list'
@returns string/boolean Returns the item's key if the item was successfully added, FALSE otherwise
@return string/boolean Returns the item's key if the item was successfully added, FALSE otherwise
*/
public function add($args)
{
@ -102,7 +102,7 @@ class dbList extends dbJSON
/* Delete an item from the dblist === Bludit v4
@key string Key of the item to be deleted
@returns boolean Returns TRUE if the database was successfully saved, FALSE otherwise
@return boolean Returns TRUE if the database was successfully saved, FALSE otherwise
*/
public function remove($key)
{
@ -192,7 +192,7 @@ class dbList extends dbJSON
/* Returns an array with a portion of the database filtered by key === Bludit v4
@key string The item key
@returns array/bool Returns the following structure array('key'=>'', 'name'=>'', 'template'=>'', 'description'=>'', list'=>array()), FALSE if the key doesn't exist
@return array/bool Returns the following structure array('key'=>'', 'name'=>'', 'template'=>'', 'description'=>'', list'=>array()), FALSE if the key doesn't exist
*/
public function getMap($key)
{

View file

@ -181,7 +181,7 @@ function uploadImages() {
// Check file type/extension
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml'];
if (!validImageTypes.includes(images[i].type)) {
showMediaAlert("<?php echo $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']) ?>");
showMediaAlert("<?php echo $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSIONS']) ?>");
return false;
}

View file

@ -39,6 +39,7 @@
'select2.full.min.js',
'tagsinput-revisited.min.js',
'functions.js',
'bootbox.all.min.js',
'api.js'
), DOMAIN_CORE_JS);
?>

View file

@ -39,9 +39,14 @@ echo Bootstrap::formTextarea(array(
name: name,
description: $('#description').val()
};
api.createCategory(args).then(function(key) {
logs('Category created. Key: ' + key);
window.location.replace('<?php echo HTML_PATH_ADMIN_ROOT . 'categories' ?>');
api.createCategory(args).then(function(response) {
if (response.status == 0) {
logs('Category created. Key: ' + response.data.key);
window.location.replace('<?php echo HTML_PATH_ADMIN_ROOT . 'categories' ?>');
} else {
logs("An error occurred while trying to create the category.");
showAlertError(response.message);
}
});
return true;
});

View file

@ -77,9 +77,14 @@ echo Bootstrap::formInputText(array(
role: $('#role').val(),
email: $('#email').val()
};
api.createUser(args).then(function(username) {
logs('User created. Username: ' + username);
window.location.replace(HTML_PATH_ADMIN_ROOT + 'users');
api.createUser(args).then(function(response) {
if (response.status == 0) {
logs('User created. Username: ' + response.data.username);
window.location.replace(HTML_PATH_ADMIN_ROOT + 'users');
} else {
logs('An error occurred while trying to create the user.');
showAlertError(response.message);
}
});
return true;
});

View file

@ -108,7 +108,7 @@ function table($type)
<a href="' . HTML_PATH_ADMIN_ROOT . 'editor/' . $child->key() . '">' . ($child->title() ? $child->title() : '<span class="text-muted">' . $L->g('Empty title') . '</span> ') . '</a>
</div>
<div>
<span class="m-0 text-uppercase text-muted" style="font-size: 0.8rem">'.( ((ORDER_BY=='position') || ($type!='published'))?$L->g('Position').': '.$child->position():$child->date(MANAGE_CONTENT_DATE_FORMAT) ).'</span>
<span class="m-0 text-uppercase text-muted" style="font-size: 0.8rem">' . (((ORDER_BY == 'position') || ($type != 'published')) ? $L->g('Position') . ': ' . $child->position() : $child->date(MANAGE_CONTENT_DATE_FORMAT)) . '</span>
</div>
</td>';
@ -267,29 +267,32 @@ function table($type)
</div>
<!-- End Content -->
<!-- Modal Delete page -->
<div class="modal" id="modalDeletePage" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p class="fw-bold text-danger"><?php $L->p('Are you sure you want to delete this page') ?></p>
<p class="fw-bold" id="deletePageTip"></p>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancel" type="button" class="btn fw-bold me-auto"><i class="bi bi-x-square"></i>Cancel</button>
<button id="btnConfirm" type="button" class="btn fw-bold text-success"><i class="bi bi-check-square"></i>Confirm</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Button for delete a page
$(".btnDeletePage").on("click", function() {
var key = $(this).data('key');
$('#deletePageTip').html(key);
$('#modalDeletePage').modal('show');
logs('Deleting page. Key: ' + key);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete this page') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
// delete page
}
}
});
});
});
</script>
<!-- End Modal Delete page -->
</script>

View file

@ -62,9 +62,15 @@ echo Bootstrap::formInputText(array(
friendlyURL: $('#friendlyURL').val(),
template: $('#template').val()
};
api.editCategory(args).then(function(key) {
logs('Category edited. Key: ' + key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
api.editCategory(args).then(function(response) {
if (response.status == 0) {
logs('Category edited. Key: ' + response.data.key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#key').val(response.data.key);
} else {
logs('An error occurred while trying to edit the category.');
showAlertError(response.message);
}
});
return true;
});
@ -72,14 +78,37 @@ echo Bootstrap::formInputText(array(
$('#btnDelete').on('click', function() {
var key = $('#key').val();
logs('Deleting category. Key: ' + key);
var args = {
key: key
};
api.deleteCategory(args).then(function(key) {
logs('Category deleted. Key: ' + key);
window.location.replace(HTML_PATH_ADMIN_ROOT + 'categories');
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete this category') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
var args = {
key: key
};
api.deleteCategory(args).then(function(response) {
if (response.status == 0) {
logs('Category deleted. Key: ' + response.data.key);
window.location.replace(HTML_PATH_ADMIN_ROOT + 'categories');
} else {
logs('An error occurred while trying to delete the category.');
showAlertError(response.message);
}
});
return true;
}
}
});
return true;
});
});
</script>

View file

@ -1,180 +1,116 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?>
<div class="align-middle">
<div class="float-end mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>" role="button"><?php $L->p('Cancel') ?></a>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-person"></i><?php $L->p('Edit user') ?></h2>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm"><?php $L->p('Save') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'users' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Edit user'), 'icon'=>'user')); ?>
</div>
<!-- TABS -->
<nav class="mb-3">
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<a class="nav-item nav-link active" id="nav-profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="nav-profile" aria-selected="false"><?php $L->p('Profile') ?></a>
<a class="nav-item nav-link" id="nav-picture-tab" data-toggle="tab" href="#picture" role="tab" aria-controls="nav-picture" aria-selected="false"><?php $L->p('Profile picture') ?></a>
<a class="nav-item nav-link" id="nav-security-tab" data-toggle="tab" href="#security" role="tab" aria-controls="nav-security" aria-selected="false"><?php $L->p('Security') ?></a>
<a class="nav-item nav-link" id="nav-social-tab" data-toggle="tab" href="#social" role="tab" aria-controls="nav-social" aria-selected="false"><?php $L->p('Social Networks') ?></a>
</div>
</nav>
<!-- Tabs -->
<ul class="nav nav-tabs ps-3 mb-3" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="profile-tab" data-bs-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="true"><?php $L->p('Profile') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="picture-tab" data-bs-toggle="tab" href="#picture" role="tab" aria-controls="picture" aria-selected="false"><?php $L->p('Profile picture') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="security-tab" data-bs-toggle="tab" href="#security" role="tab" aria-controls="security" aria-selected="false"><?php $L->p('Security') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="social-tab" data-bs-toggle="tab" href="#social" role="tab" aria-controls="social" aria-selected="false"><?php $L->p('Social Networks') ?></a>
</li>
</ul>
<!-- End Tabs -->
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
<!-- Content -->
<div class="tab-content" id="tabContent">
// Username
echo Bootstrap::formInputHidden(array(
'name'=>'username',
'value'=>$user->username()
));
?>
<div class="tab-content" id="nav-tabContent">
<!-- Profile tab -->
<div class="tab-pane fade show active" id="profile" role="tabpanel" aria-labelledby="nav-profile-tab">
<?php
// Display username but disable the field
<!-- Tab profile -->
<div class="tab-pane show active" id="profile" role="tabpanel">
<?php
echo Bootstrap::formInputText(array(
'name'=>'usernameDisabled',
'label'=>$L->g('Username'),
'value'=>$user->username(),
'class'=>'',
'placeholder'=>'',
'disabled'=>true,
'tip'=>''
'name' => 'username',
'label' => $L->g('Username'),
'value' => $user->username(),
'disabled' => true
));
if ($login->role()==='admin') {
if ($login->role() === 'admin') {
echo Bootstrap::formSelect(array(
'name'=>'role',
'label'=>$L->g('Role'),
'options'=>array('author'=>$L->g('Author'), 'editor'=>$L->g('Editor'), 'admin'=>$L->g('Administrator')),
'selected'=>$user->role(),
'class'=>'',
'tip'=>$L->g('author-can-write-and-edit-their-own-content')
'name' => 'role',
'label' => $L->g('Role'),
'options' => array('author' => $L->g('Author'), 'editor' => $L->g('Editor'), 'admin' => $L->g('Administrator')),
'selected' => $user->role(),
'tip' => $L->g('author-can-write-and-edit-their-own-content')
));
}
echo Bootstrap::formInputText(array(
'name'=>'email',
'label'=>$L->g('Email'),
'value'=>$user->email(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'email',
'label' => $L->g('Email'),
'value' => $user->email()
));
echo Bootstrap::formInputText(array(
'name'=>'nickname',
'label'=>$L->g('Nickname'),
'value'=>$user->nickname(),
'class'=>'',
'placeholder'=>'',
'tip'=>$L->g('The nickname is almost used in the themes to display the author of the content')
'name' => 'nickname',
'label' => $L->g('Nickname'),
'value' => $user->nickname(),
'tip' => $L->g('The nickname is almost used in the themes to display the author of the content')
));
echo Bootstrap::formInputText(array(
'name'=>'firstName',
'label'=>$L->g('First Name'),
'value'=>$user->firstName(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'firstName',
'label' => $L->g('First Name'),
'value' => $user->firstName()
));
echo Bootstrap::formInputText(array(
'name'=>'lastName',
'label'=>$L->g('Last Name'),
'value'=>$user->lastName(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'lastName',
'label' => $L->g('Last Name'),
'value' => $user->lastName()
));
?>
?>
</div>
<!-- End Tab profile -->
<!-- Profile picture tab -->
<div class="tab-pane fade" id="picture" role="tabpanel" aria-labelledby="nav-picture-tab">
<!-- Tab profile picture -->
<div class="tab-pane" id="picture" role="tabpanel">
<div class="container">
<div class="row">
<div class="col-lg-4 col-sm-12 p-0 pe-2">
<div class="custom-file">
<input type="file" class="custom-file-input" id="jsprofilePictureInputFile" name="profilePictureInputFile">
<label class="custom-file-label" for="jsprofilePictureInputFile"><?php $L->p('Upload image'); ?></label>
</div>
<!-- <button id="jsbuttonRemovePicture" type="button" class="btn btn-primary w-100 mt-4 mb-4"><i class="bi-trash"></i> Remove picture</button> -->
<div class="col-8">
<img id="profilePicturePreview" class="img-fluid img-thumbnail" alt="Profile picture preview" src="<?php echo ($user->profilePicture() ? $user->profilePicture() . '?version=' . time() : HTML_PATH_CORE_IMG . 'default.svg') ?>" />
</div>
<div class="col-lg-8 col-sm-12 p-0 text-center">
<img id="jsprofilePicturePreview" class="img-fluid img-thumbnail" alt="Profile picture preview" src="<?php echo (Sanitize::pathFile(PATH_UPLOADS_PROFILES.$user->username().'.png')?DOMAIN_UPLOADS_PROFILES.$user->username().'.png?version='.time():HTML_PATH_CORE_IMG.'default.svg') ?>" />
<div class="col-4">
<label id="btnUploadProfilePicture" class="btn btn-primary"><i class="bi bi-upload"></i><?php $L->p('Upload image'); ?><input type="file" id="inputProfilePicture" name="inputProfilePicture" hidden></label>
<button id="btnRemoveProfilePicture" type="button" class="btn btn-secondary"><i class="bi bi-trash"></i><?php $L->p('Remove image'); ?></button>
</div>
</div>
</div>
<script>
// $("#jsbuttonRemovePicture").on("click", function() {
// var username = $("#jsusername").val();
// bluditAjax.removeProfilePicture(username);
// $("#jsprofilePicturePreview").attr("src", "<?php echo HTML_PATH_CORE_IMG.'default.svg' ?>");
// });
$("#jsprofilePictureInputFile").on("change", function() {
var formData = new FormData();
formData.append('tokenCSRF', tokenCSRF);
formData.append('profilePictureInputFile', $(this)[0].files[0]);
formData.append('username', $("#jsusername").val());
$.ajax({
url: HTML_PATH_ADMIN_ROOT+"ajax/profile-picture-upload",
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false
}).done(function(data) {
if (data.status==0) {
$("#jsprofilePicturePreview").attr('src',data.absoluteURL+"?time="+Math.random());
} else {
showAlert(data.message);
}
});
});
</script>
</div>
<!-- End Tab profile picture -->
<!-- Security tab -->
<div class="tab-pane fade" id="security" role="tabpanel" aria-labelledby="nav-security-tab">
<?php
echo Bootstrap::formTitle(array('title'=>$L->g('Password')));
echo '
<div class="form-group">
<a href="'.HTML_PATH_ADMIN_ROOT.'user-password/'.$user->username().'" class="btn btn-primary me-2">'.$L->g('Change password').'</a>
</div>
';
echo Bootstrap::formTitle(array('title'=>$L->g('Authentication Token')));
echo Bootstrap::formInputText(array(
'name'=>'tokenAuth',
'label'=>$L->g('Token'),
'value'=>$user->tokenAuth(),
'class'=>'',
'tip'=>$L->g('this-token-is-similar-to-a-password-it-should-not-be-shared')
));
if (checkRole(array('admin'),false)) {
echo Bootstrap::formTitle(array('title'=>$L->g('Status')));
<!-- Tab security -->
<div class="tab-pane" id="security" role="tabpanel">
<?php
if (checkRole(array('admin'), false)) {
echo Bootstrap::formTitle(array('title' => $L->g('Status')));
echo Bootstrap::formInputText(array(
'name'=>'status',
'label'=>$L->g('Current status'),
'value'=>$user->enabled()?$L->g('Enabled'):$L->g('Disabled'),
'class'=>'',
'disabled'=>true,
'tip'=>$user->enabled()?'':$L->g('To enable the user you must set a new password')
'name' => 'status',
'label' => $L->g('Current status'),
'value' => $user->enabled() ? $L->g('Enabled') : $L->g('Disabled'),
'disabled' => true,
'tip' => $user->enabled() ? '' : $L->g('To enable the user you must set a new password')
));
echo Bootstrap::formInputText(array(
'name' => 'registered',
'label' => $L->g('Registered'),
'value' => Date::format($user->registered(), DB_DATE_FORMAT, ADMIN_PANEL_DATE_FORMAT),
'disabled' => true
));
if ($user->enabled()) {
@ -182,126 +118,248 @@
<div class="form-group row">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<button type="submit" class="btn btn-warning me-2" id="jsdisableUser" name="disableUser">'.$L->g('Disable user').'</button>
<button type="submit" class="btn btn-danger me-2" id="jsdeleteUserAndKeepContent" name="deleteUserAndKeepContent">'.$L->g('Delete user and keep content').'</button>
<button type="submit" class="btn btn-danger me-2" id="jsdeleteUserAndDeleteContent" name="deleteUserAndDeleteContent">'.$L->g('Delete user and delete content').'</button>
<button type="button" class="btn btn-warning me-2" id="btnDisableUser"><i class="bi bi-slash-circle"></i>' . $L->g('Disable user') . '</button>
<button type="button" class="btn btn-danger me-2" id="btnDeleteUserAndKeepContent"><i class="bi bi-trash"></i>' . $L->g('Delete user and keep content') . '</button>
<button type="button" class="btn btn-danger" id="btnDeleteUserAndContent"><i class="bi bi-trash"></i>' . $L->g('Delete user and delete content') . '</button>
</div>
</div>
';
}
}
?>
echo Bootstrap::formTitle(array('title' => $L->g('Authentication Token')));
echo Bootstrap::formInputText(array(
'name' => 'tokenAuth',
'label' => $L->g('Token'),
'value' => $user->tokenAuth(),
'class' => '',
'tip' => $L->g('this-token-is-similar-to-a-password-it-should-not-be-shared')
));
echo Bootstrap::formTitle(array('title' => $L->g('Password')));
echo '
<div class="form-group">
<a href="' . HTML_PATH_ADMIN_ROOT . 'user-password/' . $user->username() . '" class="btn btn-primary me-2">' . $L->g('Change password') . '</a>
</div>
';
?>
</div>
<!-- End Tab security -->
<!-- Social Networks tab -->
<div class="tab-pane fade" id="social" role="tabpanel" aria-labelledby="nav-social-tab">
<?php
<div class="tab-pane" id="social" role="tabpanel">
<?php
echo Bootstrap::formInputText(array(
'name'=>'twitter',
'label'=>'Twitter',
'value'=>$user->twitter(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'twitter',
'label' => 'Twitter',
'value' => $user->twitter(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'facebook',
'label'=>'Facebook',
'value'=>$user->facebook(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'facebook',
'label' => 'Facebook',
'value' => $user->facebook(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'codepen',
'label'=>'CodePen',
'value'=>$user->codepen(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'codepen',
'label' => 'CodePen',
'value' => $user->codepen(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'instagram',
'label'=>'Instagram',
'value'=>$user->instagram(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'instagram',
'label' => 'Instagram',
'value' => $user->instagram(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'gitlab',
'label'=>'GitLab',
'value'=>$user->gitlab(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'gitlab',
'label' => 'GitLab',
'value' => $user->gitlab(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'github',
'label'=>'GitHub',
'value'=>$user->github(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'github',
'label' => 'GitHub',
'value' => $user->github(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'linkedin',
'label'=>'LinkedIn',
'value'=>$user->linkedin(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'linkedin',
'label' => 'LinkedIn',
'value' => $user->linkedin(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'xing',
'label'=>'Xing',
'value'=>$user->xing(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'xing',
'label' => 'Xing',
'value' => $user->xing(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'mastodon',
'label'=>'Mastodon',
'value'=>$user->mastodon(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'mastodon',
'label' => 'Mastodon',
'value' => $user->mastodon(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name'=>'vk',
'label'=>'VK',
'value'=>$user->vk(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
'name' => 'vk',
'label' => 'VK',
'value' => $user->vk(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
?>
?>
</div>
</div>
<?php echo Bootstrap::formClose(); ?>
<script>
// Open current tab after refresh page
$(function() {
$('a[data-toggle="tab"]').on('click', function(e) {
window.localStorage.setItem('activeTab', $(e.target).attr('href'));
console.log($(e.target).attr('href'));
$(document).ready(function() {
$('#inputProfilePicture').on("change", function(e) {
var inputProfilePicture = $('#inputProfilePicture')[0].files;
var username = $('#username').val();
var formData = new FormData();
formData.append("file", inputProfilePicture[0]);
formData.append("token", api.body.token);
formData.append("authentication", api.body.authentication);
$.ajax({
url: api.apiURL + 'users/picture/' + username,
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('Uploading profile image: ' + percentComplete + '%');
}
}, false);
}
return xhr;
}
}).done(function(response) {
logs(response);
if (response.status == 0) {
logs("Profile picture uploaded.");
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#profilePicturePreview').attr('src', response.data.absoluteURL);
} else {
logs("An error occurred while trying to upload the profile picture.");
showAlertError(response.message);
}
});
return true;
});
var activeTab = window.localStorage.getItem('activeTab');
if (activeTab) {
$('#nav-tab a[href="' + activeTab + '"]').tab('show');
//window.localStorage.removeItem("activeTab");
}
$('#btnRemoveProfilePicture').on('click', function() {
var username = $('#username').val();
logs('Deleting profile picture. Username: ' + username);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete the profile picture') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
var args = {
username: username
};
api.deleteProfilePicture(args).then(function(response) {
if (response.status == 0) {
logs('Profile picture deleted. Username: ' + response.data.username);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#profilePicturePreview').attr('src', '<?php echo HTML_PATH_CORE_IMG . 'default.svg' ?>');
} else {
logs("An error occurred while trying to delete the profile picture.");
showAlertError(response.message);
}
});
return true;
}
}
});
});
$('#btnDisableUser').on('click', function() {
var username = $('#username').val();
logs('Disabling user. Username: ' + username);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to disable this user') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
var args = {
username: $('#username').val(),
disable: true
};
api.disableUser(args).then(function(response) {
if (response.status == 0) {
logs('User disabled. Username: ' + response.data.username);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
} else {
logs("An error occurred while trying to disable the user.");
showAlertError(response.message);
}
});
}
}
});
});
});
</script>

View file

@ -31,15 +31,20 @@
// Create the a page
// This function set the global variable "_pageKey"
function createPage() {
logs('Creating page');
api.createPage().then(function(key) {
logs('Page created. Key: ' + key);
// Set the global variable with the page key
_pageKey = key;
// Set Friendly URL
$('#friendlyURL').val(key);
// Get current files
fmGetFiles();
logs('Creating page.');
api.createPage().then(function(response) {
if (response.status == 0) {
logs('Page created. Key: ' + response.data.key);
// Set the global variable with the page key
_pageKey = response.data.key;
// Set Friendly URL
$('#friendlyURL').val(response.data.key);
// Get current files
fmGetFiles();
} else {
logs("An error occurred while trying to create the page.");
showAlertError(response.message);
}
});
return true;
}
@ -55,19 +60,27 @@
// Save the current page
// This function set the global variable "_pageKey"
function savePage(args) {
logs('Saving page');
logs('Saving page.');
if (_pageKey == null) {
logs('Error, page not created.');
showAlertError("Error, page not created.");
return false;
}
args['pageKey'] = _pageKey;
api.savePage(args).then(function(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;
api.savePage(args).then(function(response) {
if (response.status == 0) {
logs('Page saved. Old key: ' + _pageKey + ' / New key: ' + response.data.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 = response.data.key;
// Set friendly URL with the key
$('#friendlyURL').val(response.data.key);
} else {
logs('An error occurred while trying to save the current page.');
showAlertError(response.message);
}
});
return true;
}
@ -141,7 +154,7 @@
// Warn the user to save the changes before leave
$(window).bind('beforeunload', function(e) {
if ($('#btnSave').attr('data-current')=='unsaved') {
if ($('#btnSave').attr('data-current') == 'unsaved') {
(e || window.event).returnValue = '';
return '';
}
@ -153,7 +166,9 @@
title: $('#title').val(),
content: editorGetContent(),
category: $('#category option:selected').val(),
tags: $("#tags option:selected").map(function(){ return this.value }).get().join(",")
tags: $("#tags option:selected").map(function() {
return this.value
}).get().join(",")
}
savePage(args);
disableBtnSave();
@ -218,8 +233,14 @@
parentKey: $('#parent').val(),
pageKey: _pageKey
}
api.friendlyURL(args).then(function(slug) {
$('#friendlyURL').val(slug);
api.friendlyURL(args).then(function(response) {
if (response.status == 0) {
logs('Friendly URL created: ' + response.data.slug);
$('#friendlyURL').val(response.data.slug);
} else {
logs('An error occurred while trying to generate a friendly URL for the page.');
showAlertError(response.message);
}
});
});
@ -555,7 +576,9 @@
<a onclick="openModal('type')" class="dropdown-item" href="#"><i class="bi bi-eye"></i>Type</a>
<a onclick="openModal('seo')" class="dropdown-item" href="#"><i class="bi bi-compass"></i>SEO features</a>
<a onclick="openModal('parent')" class="dropdown-item" href="#"><i class="bi bi-diagram-2"></i>Parent page</a>
<a><hr class="dropdown-divider"></a>
<a>
<hr class="dropdown-divider">
</a>
<a onclick="fmOpen()" class="dropdown-item" href="#"><i class="bi bi-files"></i>Files & images</a>
</div>
</div>
@ -604,7 +627,7 @@
<select id="tags" size="5" class="form-select" multiple aria-label="multiple select">
<?php
foreach ($tags->db as $key => $fields) {
echo '<option value="'.$key.'" '.($pageKey && in_array($key, $page->tags(true))?'selected':'').'>'.$fields['name'].'</option>';
echo '<option value="' . $key . '" ' . ($pageKey && in_array($key, $page->tags(true)) ? 'selected' : '') . '>' . $fields['name'] . '</option>';
}
?>
</select>

View file

@ -84,13 +84,12 @@
logs('File Manager. Getting files for the current page: ' + _pageKey);
api.getPageFiles({
'pageKey': _pageKey
}).then(function(data) {
if (data.status == 0) {
fmDisplayFiles(data.data);
}).then(function(response) {
if (response.status == 0) {
fmDisplayFiles(response.data);
} else {
logs("File Manager. An error occurred while trying to get the files for the current page.");
// Alert the user about the error
showAlertError('File Manager. ' + data.message);
showAlertError(response.message);
}
});
}
@ -138,7 +137,7 @@
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', 'application/pdf'];
if (!validImageTypes.includes(file.type)) {
logs("File Manager. File type is not supported.");
showAlertError("<?php echo $L->g('File type is not supported. Allowed types:') . ' ' . implode(', ', $GLOBALS['ALLOWED_IMG_EXTENSION']) ?>");
showAlertError("<?php echo $L->g('File type is not supported. Allowed types:') . ' ' . implode(', ', $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ?>");
return false;
}
@ -161,7 +160,7 @@
formData.append("authentication", api.body.authentication);
$.ajax({
url: api.apiURL + 'files/' + _pageKey,
url: api.apiURL + 'pages/files/' + _pageKey,
type: "POST",
data: formData,
cache: false,
@ -179,8 +178,8 @@
}
return xhr;
}
}).done(function(data) {
if (data.status == 0) {
}).done(function(response) {
if (response.status == 0) {
logs("File Manager. File uploaded.");
// Progress bar
$('#progressUploadFile').addClass('d-none');
@ -192,7 +191,7 @@
// Progress bar
$('#progressUploadFile').children('.progress-bar').addClass('bg-danger');
// Alert the user about the error
showAlertError('File Manager. ' + data.message);
showAlertError('File Manager. ' + response.message);
}
});
}

View file

@ -46,7 +46,7 @@ function save() {
});
logs('Saving settings');
api.saveSettings(args).then(function() {
api.saveSettings(args).then(function(response) {
logs('Settings saved');
});

View file

@ -24,8 +24,8 @@ if (Text::stringContains($_FILES['inputFile']['name'], DS, false)) {
// File extension
$fileExtension = Filesystem::extension($_FILES['inputFile']['name']);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION'])) {
$message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']);
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);
}

View file

@ -29,8 +29,8 @@ if (Text::stringContains($username, DS, false)) {
// Check file extension
$fileExtension = Filesystem::extension($_FILES['profilePictureInputFile']['name']);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION']) ) {
$message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']);
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);
}

View file

@ -57,8 +57,8 @@ foreach ($_FILES['images']['name'] as $uuid=>$filename) {
// Check file extension
$fileExtension = Filesystem::extension($filename);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION']) ) {
$message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']);
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);
}

View file

@ -108,7 +108,7 @@ include(PATH_HELPERS.'email.class.php');
include(PATH_HELPERS.'filesystem.class.php');
include(PATH_HELPERS.'alert.class.php');
include(PATH_HELPERS.'paginator.class.php');
include(PATH_HELPERS.'image.class.php');
include(PATH_HELPERS.'simple-image.class.php');
include(PATH_HELPERS.'tcp.class.php');
include(PATH_HELPERS.'dom.class.php');
include(PATH_HELPERS.'cookie.class.php');

View file

@ -107,7 +107,13 @@ define('MEDIA_MANAGER_SORT_BY_DATE', true);
$GLOBALS['DB_TAGS_TYPES'] = array('published','static','sticky');
// Allowed image extensions
$GLOBALS['ALLOWED_IMG_EXTENSION'] = array('gif', 'png', 'jpg', 'jpeg', 'svg');
$GLOBALS['ALLOWED_IMG_EXTENSIONS'] = array('gif', 'png', 'jpg', 'jpeg', 'svg');
// Allowed image mime types
$GLOBALS['ALLOWED_IMG_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf');
$GLOBALS['ALLOWED_IMG_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml');
// Allowed files extensions
$GLOBALS['ALLOWED_FILE_EXTENSIONS'] = array('gif', 'png', 'jpg', 'jpeg', 'svg');
// Allowed files mime types
$GLOBALS['ALLOWED_FILE_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf');

View file

@ -14,7 +14,7 @@
/* Create a new page === Bludit v4
@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
@return string/bool Returns the page key if the page is successfully created, FALSE otherwise
*/
function createPage($args) {
global $pages;
@ -55,7 +55,7 @@ function createPage($args) {
@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
@return string/bool Returns the page key if the page is successfully edited, FALSE otherwise
*/
function editPage($args) {
global $pages;
@ -99,7 +99,7 @@ function editPage($args) {
/* Delete a page === Bludit v4
@key string The key of the page to be deleted
@returns string/boolean Returns TRUE if the page is successfully deleted, FALSE otherwise
@return string/bool Returns TRUE if the page is successfully deleted, FALSE otherwise
*/
function deletePage($key) {
global $pages;
@ -130,7 +130,7 @@ function deletePage($key) {
/* Create a new category === Bludit v4
@args array Array => (name: string, template: string, description: string)
@returns string/boolean Returns the category key if the category is successfully created, FALSE otherwise
@return string/bool Returns the category key if the category is successfully created, FALSE otherwise
*/
function createCategory($args) {
global $categories;
@ -159,7 +159,7 @@ function createCategory($args) {
/* Edit a category === Bludit v4
@args array Array => (key: string, name: string, friendlyURL: string, template: string, description: string)
@returns string/boolean Returns the category key if the category is successfully edited, FALSE otherwise
@return string/bool Returns the category key if the category is successfully edited, FALSE otherwise
*/
function editCategory($args) {
global $pages;
@ -207,7 +207,7 @@ function editCategory($args) {
/* Delete a category === Bludit v4
@args array Array => (key: string)
@returns boolean Returns TRUE if the category was deleted, FALSE otherwise
@return bool Returns TRUE if the category was deleted, FALSE otherwise
*/
function deleteCategory($args) {
global $categories;
@ -236,7 +236,7 @@ function deleteCategory($args) {
This function should check everthing, such as empty username, emtpy password, password lenght, etc
@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
@return string/bool Returns the page key if the page is successfully created, FALSE otherwise
*/
function createUser($args) {
global $users;
@ -269,6 +269,232 @@ function createUser($args) {
return false;
}
/* Edit an user === Bludit v4
@args array The array $args supports all the keys from the variable $dbFields of the class users.class.php. If you don't pass all the keys, the default values are used.
@args['disable'] bool If you set this variable the user will be disabled
@return string/bool Returns the username if the user was successfully disabled, FALSE otherwise
*/
function editUser($args) {
global $users;
global $syslog;
if (Text::isEmpty($args['username'])) {
Log::set(__FUNCTION__.LOG_SEP.'Empty username.', LOG_TYPE_ERROR);
return false;
}
if (!$users->exists($args['username'])) {
Log::set(__FUNCTION__.LOG_SEP.'Username doesn\'t exist.', LOG_TYPE_ERROR);
return false;
}
if (isset($args['disable'])) {
$login = new Login();
if ($login->role()!=='admin') {
Log::set(__FUNCTION__.LOG_SEP.'Only the administrator can disable users.', LOG_TYPE_ERROR);
return false;
}
$key = $users->disableUser($args['username']);
if ($key) {
Log::set(__FUNCTION__.LOG_SEP.'User disabled.', LOG_TYPE_INFO);
return $key;
}
}
$key = $users->edit($args);
if ($key) {
$syslog->add(array(
'dictionaryKey'=>'user-edited',
'notes'=>$args['username']
));
Log::set(__FUNCTION__.LOG_SEP.'User edited.', LOG_TYPE_INFO);
return $key;
}
Log::set(__FUNCTION__.LOG_SEP.'An error occurred while trying to edit the user.', LOG_TYPE_ERROR);
return false;
}
/* Upload a profile picture === Bludit v4
The profile picture is saved in PATH_UPLOADS_PROFILES.$username.png
@username string Username
@_FILE array https://www.php.net/manual/en/reserved.variables.files.php
@return array
*/
function uploadProfilePicture($username) {
if (!isset($_FILES['file'])) {
Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR);
return false;
}
if ($_FILES['file']['error'] != 0) {
Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR);
return false;
}
// Check path traversal
if (Text::stringContains($username, DS, false)) {
Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR);
return false;
}
// Check file extension
$fileExtension = Filesystem::extension($_FILES['file']['name']);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ) {
Log::set(__FUNCTION__.LOG_SEP.'Image type is not supported.', LOG_TYPE_ERROR);
return false;
}
// Check file MIME Type
$fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']);
if ($fileMimeType!==false) {
if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) {
Log::set(__FUNCTION__.LOG_SEP.'Image mime type is not supported.', LOG_TYPE_ERROR);
return false;
}
}
// Move the image from PHP tmp folder to Bludit tmp folder
$filename = $username.'.'.$fileExtension;
Filesystem::mv($_FILES['file']['tmp_name'], PATH_TMP.$filename);
$finalFilename = $username.'.png';
$absolutePath = PATH_UPLOADS_PROFILES.$finalFilename;
$absoluteURL = DOMAIN_UPLOADS_PROFILES.$finalFilename;
try {
$image = new \claviska\SimpleImage();
$image
->fromFile(PATH_TMP.$filename)
->autoOrient()
->thumbnail(PROFILE_IMG_WIDTH, PROFILE_IMG_HEIGHT, 'center')
->toFile($absolutePath, 'image/png');
} catch(Exception $e) {
Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR);
return false;
}
Log::set(__FUNCTION__.LOG_SEP.'Image profile uploaded to the user.', LOG_TYPE_INFO);
return array(
'filename'=>$filename,
'absolutePath'=>$absolutePath,
'absoluteURL'=>$absoluteURL,
'mime'=>Filesystem::mimeType($absolutePath),
'size'=>Filesystem::getSize($absolutePath)
);
}
/* Delete a profile picture === Bludit v4
@username string Username
@return bool Returns TRUE if the profile pictures is deleted succesfully, FALSE otherwise
*/
function deleteProfilePicture($username) {
// Check path traversal
if (Text::stringContains($username, DS, false)) {
Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR);
return false;
}
$finalFilename = $username.'.png';
$absolutePath = PATH_UPLOADS_PROFILES.$finalFilename;
if (Sanitize::pathFile($absolutePath)) {
Filesystem::rmfile($absolutePath);
Log::set(__FUNCTION__.LOG_SEP.'Profile picture deleted.', LOG_TYPE_INFO);
return true;
}
Log::set(__FUNCTION__.LOG_SEP.'Error when try to delete the profile picture, the file doesn\'t exists.', LOG_TYPE_ERROR);
return false;
}
/* Upload a file to a page === Bludit v4
The files is saved in
@pageKey string Page key
@_FILE array https://www.php.net/manual/en/reserved.variables.files.php
@return array
*/
function uploadPageFile($pageKey) {
global $site;
if (!isset($_FILES['file'])) {
Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR);
return false;
}
if ($_FILES['file']['error'] != 0) {
Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR);
return false;
}
// Check path traversal
if (Text::stringContains($pageKey, DS, false)) {
Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR);
return false;
}
// Check file extension
$fileExtension = Filesystem::extension($_FILES['file']['name']);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_FILE_EXTENSIONS']) ) {
Log::set(__FUNCTION__.LOG_SEP.'File type is not supported.', LOG_TYPE_ERROR);
return false;
}
// Check file MIME Type
$fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']);
if ($fileMimeType!==false) {
if (!in_array($fileMimeType, $GLOBALS['ALLOWED_FILE_MIMETYPES'])) {
Log::set(__FUNCTION__.LOG_SEP.'File mime type is not supported.', LOG_TYPE_ERROR);
return false;
}
}
$filename = $_FILES['file']['name'];
$absoluteURL = DOMAIN_UPLOADS_PAGES.$pageKey.DS.$filename;
$absolutePath = PATH_UPLOADS_PAGES.$pageKey.DS.$filename;
if (Filesystem::mv($_FILES['file']['tmp_name'], $absolutePath)) {
// Create thumbnail if the files is an image
$thumbnail = '';
if (in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) {
try {
$thumbnail = PATH_UPLOADS_THUMBNAILS.$pageKey.DS.$filename;
$image = new \claviska\SimpleImage();
$image
->fromFile($absolutePath)
->thumbnail($site->thumbnailWidth(), $site->thumbnailHeight(), 'center')
->toFile($thumbnail, 'image/jpeg');
} catch(Exception $e) {
Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR);
return false;
}
}
Log::set(__FUNCTION__.LOG_SEP.'File uploaded to the page.', LOG_TYPE_INFO);
return array(
'filename'=>$filename,
'absolutePath'=>$absolutePath,
'absoluteURL'=>$absoluteURL,
'mime'=>Filesystem::mimeType($absolutePath),
'size'=>Filesystem::getSize($absolutePath),
'thumbnail'=>$thumbnail
);
}
Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR);
return false;
}
// Re-index database of categories
// If you create/edit/remove a page is necessary regenerate the database of categories
function reindexCategories() {
@ -575,54 +801,7 @@ function execPluginsByHook($hook, $args = array()) {
function editUser($args) {
global $users;
global $syslog;
if ($users->set($args)) {
// Add to syslog
$syslog->add(array(
'dictionaryKey'=>'user-edited',
'notes'=>$args['username']
));
return true;
}
return false;
}
function disableUser($args) {
global $users;
global $login;
global $syslog;
// Arguments
$username = $args['username'];
// Only administrators can disable users
if ($login->role()!=='admin') {
return false;
}
// Check if the username exists
if (!$users->exists($username)) {
return false;
}
// Disable the user
if ($users->disableUser($username)) {
// Add to syslog
$syslog->add(array(
'dictionaryKey'=>'user-disabled',
'notes'=>$username
));
return true;
}
return false;
}
function deleteUser($args) {
global $users, $pages;
@ -894,50 +1073,7 @@ function ajaxResponse($status=0, $message="", $data=array()) {
exit (json_encode($output));
}
/*
| This function checks the image extension,
| generate a new filename to not overwrite the exists,
| generate the thumbnail,
| and move the image to a proper place
|
| @file string Path and filename of the image
| @imageDir string Path where the image is going to be stored
| @thumbnailDir string Path where the thumbnail is going to be stored, if you don't set the variable is not going to create the thumbnail
|
| @return string/boolean Path and filename of the new image or FALSE if there were some error
*/
function transformImage($file, $imageDir, $thumbnailDir=false) {
global $site;
// Check image extension
$fileExtension = Filesystem::extension($file);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION']) ) {
return false;
}
// Generate a filename to not overwrite current image if exists
$filename = Filesystem::filename($file);
$nextFilename = Filesystem::nextFilename($imageDir, $filename);
// Move the image to a proper place and rename
$image = $imageDir.$nextFilename;
Filesystem::mv($file, $image);
chmod($image, 0644);
// Generate Thumbnail
if (!empty($thumbnailDir)) {
if ($fileExtension == 'svg') {
symlink($image, $thumbnailDir.$nextFilename);
} else {
$Image = new Image();
$Image->setImage($image, $site->thumbnailWidth(), $site->thumbnailHeight(), 'crop');
$Image->saveImage($thumbnailDir.$nextFilename, $site->thumbnailQuality(), true);
}
}
return $image;
}
function downloadRestrictedFile($file) {
if (is_file($file)) {

View file

@ -56,6 +56,9 @@ EOF;
$html .= '<option '.(($key==$args['selected'])?'selected':'').' value="'.$key.'">'.$value.'</option>';
}
$html .= '</select>';
if (!empty($args['tip'])) {
$html .= '<div class="form-text">'.$args['tip'].'</div>';
}
$html .= '</div>';
$html .= '</div>';
@ -197,6 +200,14 @@ return <<<EOF
EOF;
}
public static function formTitle($args)
{
$title = $args['title'];
return <<<EOF
<h6 class="mt-4 mb-2 pb-2 border-bottom text-uppercase">$title</h6>
EOF;
}
// -- OLD --------
public static function modal($args) {
@ -255,13 +266,7 @@ return <<<EOF
EOF;
}
public static function formTitle($args)
{
$title = $args['title'];
return <<<EOF
<h6 class="mt-4 mb-2 pb-2 border-bottom text-uppercase">$title</h6>
EOF;
}
public static function formInputTextBlock($args)
{

View file

@ -297,16 +297,12 @@ class Filesystem {
return sprintf("%.{$decimals}f ", $bytes / pow(1024, $factor)) . @$size[$factor];
}
/*
| Returns the mime type of the file
| Example:
| @file /home/diego/dog.jpg
| @return image/jpeg
|
| @file [string] Full path of the file
|
| @return [string|bool] Mime type as string or FALSE if not possible to get the mime type
*/
/* Returns the mime type of the file === Bludit v4
@file string Full path of the file. Example: /home/diego/dog.jpg
@return string|bool Mime type or FALSE if not possible to get the mime type. Example: image/jpeg
*/
public static function mimeType($file) {
if (function_exists('mime_content_type')) {
return mime_content_type($file);

View file

@ -1,237 +0,0 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class Image {
private $image;
private $width;
private $height;
private $imageResized;
public function setImage($fileName, $newWidth, $newHeight, $option="auto")
{
// *** Open up the file
$this->image = $this->openImage($fileName);
// *** Get width and height
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
$this->resizeImage($newWidth, $newHeight, $option);
}
public function saveImage($savePath, $imageQuality="100", $forceJPG=false, $forcePNG=false)
{
$extension = strtolower(pathinfo($savePath, PATHINFO_EXTENSION));
// Remove the extension
$filename = substr($savePath, 0,strrpos($savePath,'.'));
$path_complete = $filename.'.'.$extension;
if ($forcePNG) {
$extension = 'png';
} elseif ($forceJPG) {
$extension = 'jpg';
}
switch ($extension) {
case 'jpg':
case 'jpeg':
// Checking for JPG support
if (imagetypes() & IMG_JPG) {
imagejpeg($this->imageResized, $path_complete, $imageQuality);
}
break;
case 'gif':
// Checking for GIF support
if (imagetypes() & IMG_GIF) {
imagegif($this->imageResized, $path_complete);
}
break;
case 'png':
// *** Scale quality from 0-100 to 0-9
$scaleQuality = round(($imageQuality/100) * 9);
// *** Invert quality setting as 0 is best, not 9
$invertScaleQuality = 9 - $scaleQuality;
// Checking for PNG support
if (imagetypes() & IMG_PNG) {
imagepng($this->imageResized, $path_complete, $invertScaleQuality);
}
break;
default:
// Fail extension detection
break;
}
imagedestroy($this->imageResized);
}
private function openImage($file)
{
// *** Get extension
$extension = strtolower(strrchr($file, '.'));
switch($extension)
{
case '.jpg':
case '.jpeg':
$img = imagecreatefromjpeg($file);
break;
case '.gif':
$img = imagecreatefromgif($file);
break;
case '.png':
$img = imagecreatefrompng($file);
break;
default:
$img = false;
break;
}
return $img;
}
private function resizeImage($newWidth, $newHeight, $option)
{
// *** Get optimal width and height - based on $option
$optionArray = $this->getDimensions($newWidth, $newHeight, $option);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
// *** Resample - create image canvas of x, y size
$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
imagealphablending($this->imageResized, false);
imagesavealpha($this->imageResized, true);
imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
// *** if option is 'crop', then crop too
if ($option == 'crop') {
$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
}
}
private function getDimensions($newWidth, $newHeight, $option)
{
if( ($this->width < $newWidth) and ($this->height < $newHeight) )
{
return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height);
}
switch ($option)
{
case 'exact':
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
break;
case 'portrait':
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
break;
case 'landscape':
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
break;
case 'auto':
$optionArray = $this->getSizeByAuto($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
case 'crop':
$optionArray = $this->getOptimalCrop($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
}
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
private function getSizeByFixedHeight($newHeight)
{
$ratio = $this->width / $this->height;
$newWidth = $newHeight * $ratio;
return $newWidth;
}
private function getSizeByFixedWidth($newWidth)
{
$ratio = $this->height / $this->width;
$newHeight = $newWidth * $ratio;
return $newHeight;
}
private function getSizeByAuto($newWidth, $newHeight)
{
if ($this->height < $this->width)
// *** Image to be resized is wider (landscape)
{
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
}
elseif ($this->height > $this->width)
// *** Image to be resized is taller (portrait)
{
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
}
else
// *** Image to be resizerd is a square
{
if ($newHeight < $newWidth) {
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
} else if ($newHeight > $newWidth) {
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
} else {
// *** Sqaure being resized to a square
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
}
}
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
private function getOptimalCrop($newWidth, $newHeight)
{
$heightRatio = $this->height / $newHeight;
$widthRatio = $this->width / $newWidth;
if ($heightRatio < $widthRatio) {
$optimalRatio = $heightRatio;
} else {
$optimalRatio = $widthRatio;
}
$optimalHeight = $this->height / $optimalRatio;
$optimalWidth = $this->width / $optimalRatio;
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
{
// *** Find center - this will be used for the crop
$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
$crop = $this->imageResized;
//imagedestroy($this->imageResized);
// *** Now crop from center to exact requested size
$this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
imagealphablending($this->imageResized, false);
imagesavealpha($this->imageResized, true);
imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
}
}

View file

@ -35,7 +35,7 @@ class Sanitize {
@path string The path to check, could be a path with a file
@returns boolean Returns TRUE if the path exists and is not path traversal, FALSE otherwise
@return boolean Returns TRUE if the path exists and is not path traversal, FALSE otherwise
*/
public static function pathFile($path)
{

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,7 @@ class API {
})
});
var json = await response.json();
return json.data.key;
return json;
} catch (err) {
console.log(err);
return true;
@ -51,7 +51,7 @@ class API {
@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
@return string New page key
*/
async savePage(args) {
var url = this.apiURL + "pages/" + args['pageKey'];
@ -66,7 +66,7 @@ class API {
})
});
var json = await response.json();
return json.data.key;
return json;
} catch (err) {
console.log(err);
return true;
@ -78,7 +78,7 @@ class API {
@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
@return string Slug text
*/
async friendlyURL(args) {
var url = this.apiURL + "helper/friendly-url/";
@ -91,7 +91,7 @@ class API {
method: "GET"
});
var json = await response.json();
return json.data;
return json;
} catch (err) {
console.log(err);
return true;
@ -100,11 +100,11 @@ class API {
/* Get all files uploaded for the page
@args['pageKey'] string
@returns array
@args string
@return array
*/
async getPageFiles(args) {
var url = this.apiURL + "files/" + args['pageKey'];
var url = this.apiURL + "pages/files/" + args['pageKey'];
var parameters = "?token=" + this.body.token + "&authentication=" + this.body.authentication;
try {
const response = await fetch(url + parameters, {
@ -118,36 +118,10 @@ class API {
}
}
/* 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
@args array Arguments can be any of the fields from settings
@return array
*/
async saveSettings(args) {
var url = this.apiURL + "settings";
@ -162,7 +136,7 @@ class API {
})
});
var json = await response.json();
return json.data;
return json;
} catch (err) {
console.log(err);
return true;
@ -171,8 +145,8 @@ class API {
/* Create a new category
@args array Arguments can be any of the fields from a category
@returns string New category key
@args array Arguments can be any of the fields from a category
@return string New category key
*/
async createCategory(args) {
var url = this.apiURL + "categories";
@ -187,7 +161,7 @@ class API {
})
});
var json = await response.json();
return json.data.key;
return json;
} catch (err) {
console.log(err);
return true;
@ -196,8 +170,8 @@ class API {
/* Edit a category
@args array Arguments can be any of the fields from a category
@returns string The category key
@args array Arguments can be any of the fields from a category
@return string The category key
*/
async editCategory(args) {
var url = this.apiURL + "categories/" + args['key'];
@ -212,7 +186,7 @@ class API {
})
});
var json = await response.json();
return json.data.key;
return json;
} catch (err) {
console.log(err);
return true;
@ -221,8 +195,8 @@ class API {
/* Delete a category
@args array Array => (key: string)
@returns string The category key deleted
@args array Array => (key: string)
@return string The category key deleted
*/
async deleteCategory(args) {
var url = this.apiURL + "categories/" + args['key'];
@ -237,7 +211,32 @@ class API {
})
});
var json = await response.json();
return json.data.key;
return json;
} catch (err) {
console.log(err);
return true;
}
}
/* Delete the profile picture from a user
@args array Array => (username: string)
@return string The username
*/
async deleteProfilePicture(args) {
var url = this.apiURL + "users/picture/" + args['username'];
var body = this.body;
try {
var response = await fetch(url, {
credentials: "same-origin",
method: "DELETE",
body: JSON.stringify(body),
headers: new Headers({
"Content-Type": "application/json"
})
});
var json = await response.json();
return json;
} catch (err) {
console.log(err);
return true;
@ -246,8 +245,8 @@ class API {
/* Create a new user
@args array Arguments can be any of the fields from a user
@returns string Returns the username created
@args array Arguments can be any of the fields from a user
@return string Returns the username created
*/
async createUser(args) {
var url = this.apiURL + "users";
@ -262,7 +261,32 @@ class API {
})
});
var json = await response.json();
return json.data.key;
return json;
} catch (err) {
console.log(err);
return true;
}
}
/* Disable an user
@args array Array => (username: string, enabled: bool)
@return string The username
*/
async disableUser(args) {
var url = this.apiURL + 'users/' + args['username'];
var body = Object.assign({}, this.body, args);
try {
var response = await fetch(url, {
credentials: "same-origin",
method: "PUT",
body: JSON.stringify(body),
headers: new Headers({
"Content-Type": "application/json"
})
});
var json = await response.json();
return json;
} catch (err) {
console.log(err);
return true;

6
bl-kernel/js/bootbox.all.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -37,7 +37,7 @@ class Pages extends dbJSON {
/* Get the database row associated to a page
@key string The key of the page to be fetch
@returns array/boolean Return an array with the database for a page, FALSE otherwise
@return array/boolean Return an array with the database for a page, FALSE otherwise
*/
public function getPageDB($key)
{
@ -50,7 +50,7 @@ class Pages extends dbJSON {
/* Check if a page key exists in the database
@returns boolean Return TRUE if the page exists, FALSE otherwise
@return boolean Return TRUE if the page exists, FALSE otherwise
*/
public function exists($key)
{
@ -60,7 +60,7 @@ class Pages extends dbJSON {
/* Create a new page === Bludit v4
@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
@return string/boolean Returns the page key if the page is successfully created, FALSE otherwise
*/
public function add($args)
{
@ -154,6 +154,12 @@ class Pages extends dbJSON {
return false;
}
// Create the thumbnails directory for the page
if (Filesystem::mkdir(PATH_UPLOADS_THUMBNAILS.$key, true) === false) {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to create the directory: '.PATH_UPLOADS_THUMBNAILS.$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.'An error occurred while trying to create the file: '.FILENAME, LOG_TYPE_ERROR);
@ -178,7 +184,7 @@ class Pages extends dbJSON {
/* Edit a page === Bludit v4
@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
@return string/boolean Returns the page key if the page is successfully edited, FALSE otherwise
*/
public function edit($args)
{
@ -268,6 +274,11 @@ class Pages extends dbJSON {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to move the directory: '.PATH_UPLOADS_PAGES.$newKey, LOG_TYPE_ERROR);
return false;
}
if (Filesystem::mv(PATH_UPLOADS_THUMBNAILS.$key, PATH_UPLOADS_THUMBNAILS.$newKey) === false) {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to move the directory: '.PATH_UPLOADS_THUMBNAILS.$newKey, LOG_TYPE_ERROR);
return false;
}
}
// If the content was passed via arguments replace the content
@ -303,7 +314,7 @@ class Pages extends dbJSON {
/* Delete a page === Bludit v4
@key string The key of the page to be deleted
@returns boolean Returns TRUE if the page was deleted successfully, FALSE otherwise
@return boolean Returns TRUE if the page was deleted successfully, FALSE otherwise
*/
public function delete($key)
{
@ -329,6 +340,11 @@ class Pages extends dbJSON {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to delete the directory: '.PATH_UPLOADS_PAGES.$key, LOG_TYPE_ERROR);
}
// Delete thumbnail directory
if (Filesystem::deleteRecursive(PATH_UPLOADS_THUMBNAILS.$key) === false) {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to delete the directory: '.PATH_UPLOADS_THUMBNAILS.$key, LOG_TYPE_ERROR);
}
// Remove from database
unset($this->db[$key]);
@ -789,7 +805,7 @@ class Pages extends dbJSON {
@oldCategoryKey string The old category key
@newCategoryKey string The new category key
@returns boolean Returns TRUE if the database was saved, FALSE otherwise
@return boolean Returns TRUE if the database was saved, FALSE otherwise
*/
public function changeCategory($oldCategoryKey, $newCategoryKey)
{

View file

@ -236,7 +236,7 @@ class Page {
/* Returns the template for the page === Bludit v4
@returns string/boolean Returns the template for the page or FALSE if the page haven't a template assigned
@return string/boolean Returns the template for the page or FALSE if the page haven't a template assigned
*/
public function template()
{

View file

@ -51,17 +51,22 @@ class Users extends dbJSON {
return isset($this->db[$username]);
}
// Disable the user
/* Disable an user === Bludit v4
@username string The username to be disabled
@return string Returns the username
*/
public function disableUser($username)
{
$this->db[$username]['password'] = '!';
return $this->save();
$this->save();
return $username;
}
/* Create a new user === Bludit v4
@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 username if the user is successfully created, FALSE otherwise
@return string/bool Returns the username if the user is successfully created, FALSE otherwise
*/
public function add($args)
{
@ -103,12 +108,21 @@ class Users extends dbJSON {
return $username;
}
// Edit an user
public function set($args)
/* Edit an user === Bludit v4
@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.
@return string/bool Returns the username if the user is successfully created, FALSE otherwise
*/
public function edit($args)
{
// The username is store as key and not as field
$username = $args['username'];
// The following fields can not be changed via edit the user
unset($args['salt']);
unset($args['tokenAuth']);
unset($args['registered']);
// Current database of the user
$row = $this->db[$username];
foreach ($this->dbFields as $field=>$value) {
@ -137,7 +151,8 @@ class Users extends dbJSON {
// Save the database
$this->db[$username] = $row;
return $this->save();
$this->save();
return $username;
}
// Delete an user

View file

@ -178,7 +178,6 @@
"edit-or-delete-your-categories": "Edit or delete your categories",
"create-a-new-category-to-organize-your-content": "Create a new category to organize your content",
"confirm-delete-this-action-cannot-be-undone": "Confirm delete, this action cannot be undone.",
"do-you-want-to-disable-the-user": "Do you want to disable the user ?",
"new-password": "New password",
"you-can-change-this-field-when-save-the-current-changes": "You can change this field when you save the current changes.",
"items-per-page": "Items per page",
@ -306,7 +305,6 @@
"extreme-friendly-url": "Extreme friendly URL",
"title-formats": "Title formats",
"delete-content": "Delete content",
"are-you-sure-you-want-to-delete-this-page": "Are you sure you want to delete this page?",
"sticky": "Sticky",
"actions": "Actions",
"edit": "Edit",
@ -329,7 +327,6 @@
"uncategorized": "Uncategorized",
"done": "Done",
"delete-category": "Delete category",
"are-you-sure-you-want-to-delete-this-category?": "Are you sure you want to delete this category?",
"confirm-new-password": "Confirm new password",
"the-nickname-is-almost-used-in-the-themes-to-display-the-author-of-the-content": "The nickname is almost used in the themes to display the author of the content",
"allow-unicode": "Allow Unicode",
@ -391,5 +388,11 @@
"custom-fields": "Custom fields",
"define-custom-fields-for-the-content": "Define custom fields for the content. Learn more about custom fields in the <a href='https:\/\/docs.bludit.com\/en\/content\/custom-fields'>documentation<\/a>.",
"start-typing-to-see-a-list-of-suggestions": "Start typing to see a list of suggestions.",
"view": "View"
"view": "View",
"confirm": "Confirm",
"are-you-sure-you-want-to-disable-this-user": "Are you sure you want to disable this user?",
"are-you-sure-you-want-to-delete-the-profile-picture": "Are you sure you want to delete the profile picture?",
"are-you-sure-you-want-to-delete-this-user": "Are you sure you want to delete this user?",
"are-you-sure-you-want-to-delete-this-page": "Are you sure you want to delete this page?",
"are-you-sure-you-want-to-delete-this-category?": "Are you sure you want to delete this category?"
}

View file

@ -83,6 +83,11 @@ class pluginAPI extends Plugin {
$this->response(400, 'Bad Request', array('message'=>'Missing endpoint parameters.'));
}
$parmA = isset($parameters[0])?$parameters[0]:'';
$parmB = isset($parameters[1])?$parameters[1]:'';
$parmC = isset($parameters[2])?$parameters[2]:'';
$parmD = isset($parameters[3])?$parameters[3]:'';
// API TOKEN
// ------------------------------------------------------------
// Token from the plugin, the user can change it on the settings of the plugin
@ -129,103 +134,141 @@ class pluginAPI extends Plugin {
// ENDPOINTS
// ------------------------------------------------------------
// /api/pages
// /api/pages/files
// /api/pages/files/:key
// /api/pages/files/:parent/:key
// /api/pages/:key
// /api/pages/:parent/:key
// (GET) /api/pages
if ( ($method==='GET') && ($parameters[0]==='pages') && empty($parameters[1]) ) {
if ( ($method==='GET') && ($parmA==='pages') && empty($parmB) ) {
$data = $this->getPages($inputs);
}
// (GET) /api/pages/<key>
elseif ( ($method==='GET') && ($parameters[0]==='pages') && !empty($parameters[1]) ) {
$pageKey = $parameters[1];
if (isset($parameters[2])) {
$pageKey = $parameters[1].'/'.$parameters[2];
}
$data = $this->getPage($pageKey);
}
// (PUT) /api/pages/<key>
elseif ( ($method==='PUT') && ($parameters[0]==='pages') && !empty($parameters[1]) && $writePermissions ) {
$inputs['key'] = $parameters[1];
$data = $this->editPage($inputs);
}
// (DELETE) /api/pages/<key>
elseif ( ($method==='DELETE') && ($parameters[0]==='pages') && !empty($parameters[1]) && $writePermissions ) {
$pageKey = $parameters[1];
$data = $this->deletePage($pageKey);
}
// (POST) /api/pages
elseif ( ($method==='POST') && ($parameters[0]==='pages') && empty($parameters[1]) && $writePermissions ) {
elseif ( ($method==='POST') && ($parmA==='pages') && empty($parmB) && $writePermissions ) {
$data = $this->createPage($inputs);
}
// (GET) /api/pages/files/:key
elseif ( ($method==='GET') && ($parmA==='pages') && ($parmB==='files') && !empty($parmC) ) {
$key = $parmC;
if (!empty($parmD)) {
$key = $parmC.'/'.$parmD;
}
$data = $this->getFiles($key);
}
// (POST) /api/pages/files/:key
elseif ( ($method==='POST') && ($parmA==='pages') && ($parmB==='files') && !empty($parmC) && $writePermissions ) {
$key = $parmC;
if (!empty($parmD)) {
$key = $parmC.'/'.$parmD;
}
$data = $this->uploadPageFile($key);
}
// (DELETE) /api/pages/files/:key
elseif ( ($method==='DELETE') && ($parmA==='pages') && ($parmB==='files') && !empty($parmC) && $writePermissions ) {
$key = $parmC;
if (!empty($parmD)) {
$key = $parmC.'/'.$parmD;
}
// Delete file function
}
// (GET) /api/pages/:key
elseif ( ($method==='GET') && ($parmA==='pages') && !empty($parmB) ) {
$key = $parmB;
if (!empty($parmC)) {
$key = $parmB.'/'.$parmC;
}
$data = $this->getPage($key);
}
// (PUT) /api/pages/:key
elseif ( ($method==='PUT') && ($parmA==='pages') && !empty($parmB) && $writePermissions ) {
$inputs['key'] = $parmB;
if (!empty($parmC)) {
$inputs['key'] = $parmB.'/'.$parmC;
}
$data = $this->editPage($inputs);
}
// (DELETE) /api/pages/:key
elseif ( ($method==='DELETE') && ($parmA==='pages') && !empty($parmB) && $writePermissions ) {
$key = $parmB;
if (!empty($parmC)) {
$key = $parmB.'/'.$parmC;
}
$data = $this->deletePage($key);
}
// (GET) /api/settings
elseif ( ($method==='GET') && ($parameters[0]==='settings') && empty($parameters[1]) && $writePermissions ) {
elseif ( ($method==='GET') && ($parmA==='settings') && empty($parmB) && $writePermissions ) {
$data = $this->getSettings();
}
// (PUT) /api/settings
elseif ( ($method==='PUT') && ($parameters[0]==='settings') && empty($parameters[1]) && $writePermissions ) {
elseif ( ($method==='PUT') && ($parmA==='settings') && empty($parmB) && $writePermissions ) {
$data = $this->editSettings($inputs);
}
// (POST) /api/images
elseif ( ($method==='POST') && ($parameters[0]==='images') && $writePermissions ) {
$data = $this->uploadImage($inputs);
}
// (GET) /api/tags
elseif ( ($method==='GET') && ($parameters[0]==='tags') && empty($parameters[1]) ) {
elseif ( ($method==='GET') && ($parmA==='tags') && empty($parmB) ) {
$data = $this->getTags();
}
// (GET) /api/tags/<key>
elseif ( ($method==='GET') && ($parameters[0]==='tags') && !empty($parameters[1]) ) {
$tagKey = $parameters[1];
$data = $this->getTag($tagKey);
// (GET) /api/tags/:key
elseif ( ($method==='GET') && ($parmA==='tags') && !empty($parmB) ) {
$key = $parmB;
$data = $this->getTag($key);
}
// (GET) /api/categories
elseif ( ($method==='GET') && ($parameters[0]==='categories') && empty($parameters[1]) ) {
elseif ( ($method==='GET') && ($parmA==='categories') && empty($parmB) ) {
$data = $this->getCategories();
}
// (GET) /api/categories/<key>
elseif ( ($method==='GET') && ($parameters[0]==='categories') && !empty($parameters[1]) ) {
$categoryKey = $parameters[1];
$data = $this->getCategory($categoryKey);
// (GET) /api/categories/:key
elseif ( ($method==='GET') && ($parmA==='categories') && !empty($parmB) ) {
$key = $parmB;
$data = $this->getCategory($key);
}
// (POST) /api/categories
elseif ( ($method==='POST') && ($parameters[0]==='categories') && empty($parameters[1]) && $writePermissions ) {
elseif ( ($method==='POST') && ($parmA==='categories') && empty($parmB) && $writePermissions ) {
$data = $this->createCategory($inputs);
}
// (PUT) /api/categories/<key>
elseif ( ($method==='PUT') && ($parameters[0]==='categories') && !empty($parameters[1]) && $writePermissions ) {
$inputs['key'] = $parameters[1];
// (PUT) /api/categories/:key
elseif ( ($method==='PUT') && ($parmA==='categories') && !empty($parmB) && $writePermissions ) {
$inputs['key'] = $parmB;
$data = $this->editCategory($inputs);
}
// (DELETE) /api/categories/<key>
elseif ( ($method==='DELETE') && ($parameters[0]==='categories') && !empty($parameters[1]) && $writePermissions ) {
$inputs['key'] = $parameters[1];
// (DELETE) /api/categories/:key
elseif ( ($method==='DELETE') && ($parmA==='categories') && !empty($parmB) && $writePermissions ) {
$inputs['key'] = $parmB;
$data = $this->deleteCategory($inputs);
}
// (GET) /api/users
elseif ( ($method==='GET') && ($parameters[0]==='users') && empty($parameters[1]) ) {
elseif ( ($method==='GET') && ($parmA==='users') && empty($parmB) ) {
$data = $this->getUsers();
}
// (GET) /api/users/<username>
elseif ( ($method==='GET') && ($parameters[0]==='users') && !empty($parameters[1]) ) {
$username = $parameters[1];
$data = $this->getUser($username);
}
// (GET) /api/users
elseif ( ($method==='POST') && ($parameters[0]==='users') && empty($parameters[1]) && $writePermissions ) {
// (POST) /api/users
elseif ( ($method==='POST') && ($parmA==='users') && empty($parmB) && $writePermissions ) {
$data = $this->createUser($inputs);
}
// (GET) /api/files/<page-key>
elseif ( ($method==='GET') && ($parameters[0]==='files') && !empty($parameters[1]) ) {
$pageKey = $parameters[1];
$data = $this->getFiles($pageKey);
// (POST) /api/users/picture/:username
elseif ( ($method==='POST') && ($parmA==='users') && ($parmB==='picture') && !empty($parmC) && $writePermissions ) {
$username = $parmC;
$data = $this->uploadProfilePicture($username);
}
// (POST) /api/files/<page-key>
elseif ( ($method==='POST') && ($parameters[0]==='files') && !empty($parameters[1]) ) {
$pageKey = $parameters[1];
$data = $this->uploadFile($pageKey);
// (DELETE) /api/users/picture/:username
elseif ( ($method==='DELETE') && ($parmA==='users') && ($parmB==='picture') && !empty($parmC) && $writePermissions ) {
$username = $parmC;
$data = $this->deleteProfilePicture($username);
}
// (GET) /api/helper/<helper-name>
elseif ( ($method==='GET') && ($parameters[0]==='helper') && !empty($parameters[1]) ) {
$helperName = $parameters[1];
if ($helperName=='friendly-url') {
// (GET) /api/users/:username
elseif ( ($method==='GET') && ($parmA==='users') && !empty($parmB) ) {
$username = $parmB;
$data = $this->getUser($username);
}
// (PUT) /api/users/:username
elseif ( ($method==='PUT') && ($parmA==='users') && !empty($parmB) ) {
$inputs['username'] = $parmB;
$data = $this->editUser($inputs);
}
// (GET) /api/helper/:name
elseif ( ($method==='GET') && ($parmA==='helper') && !empty($parmB) ) {
$name = $parmB;
if ($name=='friendly-url') {
$data = $this->getFriendlyURL($inputs);
}
}
@ -492,69 +535,6 @@ class pluginAPI extends Plugin {
);
}
/*
| Upload an image and generate the thumbnails
| Returns the image and thumbnail URL
|
| @inputs array
| @inputs['uuid'] string Page UUID
| @_FILE array https://www.php.net/manual/en/reserved.variables.files.php
|
| @return array
*/
private function uploadImage($inputs)
{
// Set upload directory
if (isset($inputs['uuid']) && IMAGE_RESTRICT) {
$imageDirectory = PATH_UPLOADS_PAGES.$inputs['uuid'].DS;
$thumbnailDirectory = $imageDirectory.'thumbnails'.DS;
$imageEndpoint = DOMAIN_UPLOADS_PAGES.$inputs['uuid'].'/';
$thumbnailEndpoint = $imageEndpoint.'thumbnails'.'/';
if (!Filesystem::directoryExists($thumbnailDirectory)) {
Filesystem::mkdir($thumbnailDirectory, true);
}
} else {
$imageDirectory = PATH_UPLOADS;
$thumbnailDirectory = PATH_UPLOADS_THUMBNAILS;
$imageEndpoint = DOMAIN_UPLOADS;
$thumbnailEndpoint = DOMAIN_UPLOADS_THUMBNAILS;
}
if (!isset($_FILES['image'])) {
return array(
'status'=>'1',
'message'=>'No image sent.'
);
}
if ($_FILES['image']['error'] != 0) {
return array(
'status'=>'1',
'message'=>'Error uploading the image, maximum load file size allowed: '.ini_get('upload_max_filesize')
);
}
// Move from PHP tmp file to Bludit tmp directory
Filesystem::mv($_FILES['image']['tmp_name'], PATH_TMP.$_FILES['image']['name']);
// Transform image and create thumbnails
$image = transformImage(PATH_TMP.$_FILES['image']['name'], $imageDirectory, $thumbnailDirectory);
if ($image) {
$filename = Filesystem::filename($image);
return array(
'status'=>'0',
'message'=>'Image uploaded.',
'image'=>$imageEndpoint.$filename,
'thumbnail'=>$thumbnailEndpoint.$filename
);
}
return array(
'status'=>'1',
'message'=>'Image extension not allowed.'
);
}
/*
| Get the settings
|
@ -764,9 +744,11 @@ class pluginAPI extends Plugin {
);
}
/* Create a new user === Bludit v4
Referer to the function createUser() from functions.php
*/
private function createUser($args)
{
// This function is defined on functions.php
$key = createUser($args);
if ($key===false) {
return array(
@ -782,51 +764,82 @@ class pluginAPI extends Plugin {
);
}
/*
| Upload a file to a particular page
| Returns the file URL
|
| @inputs array
| @inputs['uuid'] string Page UUID
| @_FILE array https://www.php.net/manual/en/reserved.variables.files.php
|
| @return array
/* Edit an user === Bludit v4
Referer to the function editUser() from functions.php
*/
private function uploadFile($pageKey)
private function editUser($args)
{
if (!isset($_FILES['file'])) {
$key = editUser($args);
if ($key===false) {
return array(
'status'=>'1',
'message'=>'File not sent.'
'message'=>'An error occurred while trying to edit the user.'
);
}
if ($_FILES['file']['error'] != 0) {
return array(
'status'=>'0',
'message'=>'User edited.',
'data'=>array('key'=>$key)
);
}
/* Upload a profile picture === Bludit v4
Referer to the function uploadProfilePicture() from functions.php
*/
private function uploadProfilePicture($username)
{
$data = uploadProfilePicture($username);
if ($data===false) {
return array(
'status'=>'1',
'message'=>'Error uploading the file.'
'message'=>'An error occurred while trying to upload the profile picture.'
);
}
$filename = $_FILES['file']['name'];
$absoluteURL = DOMAIN_UPLOADS_PAGES.$pageKey.DS.$filename;
$absolutePath = PATH_UPLOADS_PAGES.$pageKey.DS.$filename;
if (Filesystem::mv($_FILES['file']['tmp_name'], $absolutePath)) {
return array(
'status'=>'0',
'message'=>'Profile picture uploaded.',
'data'=>$data
);
}
/* Delete a profile picture === Bludit v4
Referer to the function deleteProfilePicture() from functions.php
*/
private function deleteProfilePicture($username)
{
if (deleteProfilePicture($username)) {
return array(
'status'=>'0',
'message'=>'File uploaded.',
'filename'=>$filename,
'absolutePath'=>$absolutePath,
'absoluteURL'=>$absoluteURL,
'mime'=>Filesystem::mimeType($absolutePath),
'size'=>Filesystem::getSize($absolutePath),
'thumbnail'=>''
'message'=>'Profile picture deleted.',
'data'=>array('username'=>$username)
);
}
return array(
'status'=>'1',
'message'=>'Error moving the file to the final path.'
'message'=>'An error occurred while trying to delete the profile picture.'
);
}
/* Upload a file to a particular page === Bludit v4
Referer to the function uploadPageFile() from functions.php
*/
private function uploadPageFile($pageKey)
{
$data = uploadPageFile($pageKey);
if ($data===false) {
return array(
'status'=>'1',
'message'=>'An error occurred while trying to upload the file.'
);
}
return array(
'status'=>'0',
'message'=>'File uploaded to the page.',
'data'=>$data
);
}
@ -837,7 +850,7 @@ class pluginAPI extends Plugin {
@args['parentKey'] string
@args['pageKey'] string
@returns['data'] string The slug string
@return['data'] string The slug string
*/
private function getFriendlyURL($args)
{
@ -847,7 +860,7 @@ class pluginAPI extends Plugin {
return array(
'status'=>'0',
'message'=>'Friendly URL generated.',
'data'=>$slug
'data'=>array('slug'=>$slug)
);
}
@ -857,7 +870,7 @@ class pluginAPI extends Plugin {
@pageKey string The page's key
@returns['data'] array The list of files
@return['data'] array The list of files
*/
private function getFiles($pageKey)
{