Refactor for Site logo

This commit is contained in:
Diego Najar 2021-03-09 11:55:08 -03:00
parent 3570734110
commit a55ab5d2ec
8 changed files with 252 additions and 50 deletions

View file

@ -68,6 +68,77 @@
save();
});
$('#inputSiteLogo').on("change", function(e) {
var inputSiteLogo = $('#inputSiteLogo')[0].files;
var formData = new FormData();
formData.append("file", inputSiteLogo[0]);
formData.append("token", api.body.token);
formData.append("authentication", api.body.authentication);
$.ajax({
url: api.apiURL + 'settings/logo',
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 site logo: ' + percentComplete + '%');
}
}, false);
}
return xhr;
}
}).done(function(response) {
logs(response);
if (response.status == 0) {
logs("Site logo uploaded.");
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#siteLogoPreview').attr('src', response.data.absoluteURL);
} else {
logs("An error occurred while trying to upload the site logo.");
showAlertError(response.message);
}
});
return true;
});
$('#btnRemoveSiteLogo').on('click', function() {
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete the site logo') ?>',
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) {
api.deleteSiteLogo().then(function(response) {
if (response.status == 0) {
logs('Site logo deleted.');
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#siteLogoPreview').attr('src', '<?php echo HTML_PATH_CORE_IMG . 'default.svg' ?>');
} else {
logs("An error occurred while trying to delete the site logo.");
showAlertError(response.message);
}
});
return true;
}
}
});
});
});
// ============================================================================
@ -509,50 +580,17 @@
<!-- Site logo tab -->
<div class="tab-pane" id="logo" role="tabpanel" aria-labelledby="logo-tab">
<?php
echo Bootstrap::formTitle(array('title' => $L->g('Site logo')));
?>
<div class="container">
<div class="row">
<div class="col-lg-4 col-sm-12 p-0 pe-2">
<div class="custom-file">
<input id="jssiteLogoInputFile" class="custom-file-input" type="file" name="inputFile">
<label for="jssiteLogoInputFile" class="custom-file-label"><?php $L->p('Upload image'); ?></label>
</div>
<button id="jsbuttonRemoveLogo" type="button" class="btn btn-primary w-100 mt-4 mb-4"><i class="bi-trash"></i><?php $L->p('Remove logo') ?></button>
<div class="col-8">
<img id="siteLogoPreview" class="img-fluid img-thumbnail" alt="Site logo preview" src="<?php echo ($site->logo()?$site->logo():HTML_PATH_CORE_IMG . 'default.svg') ?>" />
</div>
<div class="col-lg-8 col-sm-12 p-0 text-center">
<img id="jssiteLogoPreview" class="img-fluid img-thumbnail" alt="Site logo preview" src="<?php echo ($site->logo() ? DOMAIN_UPLOADS . $site->logo(false) . '?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="inputSiteLogo" name="inputSiteLogo" hidden></label>
<button id="btnRemoveSiteLogo" type="button" class="btn btn-secondary"><i class="bi bi-trash"></i><?php $L->p('Remove image'); ?></button>
</div>
</div>
</div>
<script>
$("#jsbuttonRemoveLogo").on("click", function() {
bluditAjax.removeLogo();
$("#jssiteLogoPreview").attr("src", "<?php echo HTML_PATH_CORE_IMG . 'default.svg' ?>");
});
$("#jssiteLogoInputFile").on("change", function() {
var formData = new FormData();
formData.append('tokenCSRF', tokenCSRF);
formData.append('inputFile', $(this)[0].files[0]);
$.ajax({
url: HTML_PATH_ADMIN_ROOT + "ajax/logo-upload",
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false
}).done(function(data) {
if (data.status == 0) {
$("#jssiteLogoPreview").attr('src', data.absoluteURL + "?time=" + Math.random());
} else {
showAlert(data.message);
}
});
});
</script>
</div>
</div>

View file

@ -331,7 +331,6 @@ function editUser($args) {
@username string Username
@_FILE array https://www.php.net/manual/en/reserved.variables.files.php
@return array
*/
function uploadProfilePicture($username) {
@ -401,7 +400,6 @@ function uploadProfilePicture($username) {
/* Delete a profile picture === Bludit v4
@username string Username
@return bool Returns TRUE on successful delete, FALSE otherwise
*/
function deleteProfilePicture($username) {
@ -424,6 +422,103 @@ function deleteProfilePicture($username) {
return false;
}
/* Upload the site logo === Bludit v4
The site logo is store in PATH_UPLOADS/<site title>.<extension>
@_FILE array https://www.php.net/manual/en/reserved.variables.files.php
@return array
*/
function uploadSiteLogo() {
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($_FILES['file']['name'], 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;
}
}
// Final filename
$filename = 'logo.'.$fileExtension;
$siteTitle = Text::cleanUrl($site->title(), '-', $allowExtremeFriendlyURL=false);
if (Text::isNotEmpty($siteTitle)) {
$filename = $siteTitle.'.'.$fileExtension;
}
// Move the image from PHP tmp folder to Bludit tmp folder
Filesystem::mv($_FILES['file']['tmp_name'], PATH_TMP.$filename);
$absolutePath = PATH_UPLOADS.$filename;
$absoluteURL = DOMAIN_UPLOADS.$filename;
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;
}
$site->set(array('logo'=>$filename));
Log::set(__FUNCTION__.LOG_SEP.'Site logo uploaded and cropped.', LOG_TYPE_INFO);
return array(
'filename'=>$filename,
'absolutePath'=>$absolutePath,
'absoluteURL'=>$absoluteURL,
'mime'=>Filesystem::mimeType($absolutePath),
'size'=>Filesystem::getSize($absolutePath)
);
}
/* Delete the site logo === Bludit v4
@return bool Returns TRUE on successful delete, FALSE otherwise
*/
function deleteSiteLogo() {
global $site;
if ($site->logo()) {
Filesystem::rmfile(PATH_UPLOADS.$site->logo(false));
$site->set(array('logo'=>''));
Log::set(__FUNCTION__.LOG_SEP.'Site logo deleted.', LOG_TYPE_INFO);
return true;
}
Log::set(__FUNCTION__.LOG_SEP.'Error when try to delete the site logo, the file doesn\'t exists.', LOG_TYPE_ERROR);
return false;
}
/* Upload a file to a page === Bludit v4
The files is saved in

View file

@ -152,11 +152,11 @@ class Text {
// Convert unicode characters to utf-8 characters
// Characters that cannot be converted will be removed from the string
// This function can return an empty string
public static function cleanUrl($string, $separator='-')
public static function cleanUrl($string, $separator='-', $allowExtremeFriendlyURL=true)
{
global $L;
if (EXTREME_FRIENDLY_URL) {
if (EXTREME_FRIENDLY_URL && $allowExtremeFriendlyURL) {
$string = self::lowercase($string);
$string = trim($string, $separator);
$string = self::removeSpecialCharacters($string, $separator);

View file

@ -243,6 +243,28 @@ class API {
}
}
/* Delete the site logo
*/
async deleteSiteLogo() {
var url = this.apiURL + "settings/logo"
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;
}
}
/* Create a new user
@args array Arguments can be any of the fields from a user

View file

@ -393,6 +393,7 @@
"current-password": "Current password",
"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-the-site-logo": "Are you sure you want to delete the site logo?",
"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

@ -205,6 +205,14 @@ class pluginAPI extends Plugin {
elseif ( ($method==='PUT') && ($parmA==='settings') && empty($parmB) && $writePermissions ) {
$data = $this->editSettings($inputs);
}
// (POST) /api/settings/logo
elseif ( ($method==='POST') && ($parmA==='settings') && ($parmB==='logo') && $writePermissions ) {
$data = $this->uploadSiteLogo($inputs);
}
// (DELETE) /api/settings/logo
elseif ( ($method==='DELETE') && ($parmA==='settings') && ($parmB==='logo') && $writePermissions ) {
$data = $this->deleteSiteLogo();
}
// (GET) /api/tags
elseif ( ($method==='GET') && ($parmA==='tags') && empty($parmB) ) {
$data = $this->getTags();
@ -833,6 +841,44 @@ class pluginAPI extends Plugin {
);
}
/* Upload the site logo === Bludit v4
Referer to the function uploadSiteLogo() from functions.php
*/
private function uploadSiteLogo($username)
{
$data = uploadSiteLogo($username);
if ($data===false) {
return array(
'status'=>'1',
'message'=>'An error occurred while trying to upload the site logo.'
);
}
return array(
'status'=>'0',
'message'=>'Site logo uploaded.',
'data'=>$data
);
}
/* Delete the site logo === Bludit v4
Referer to the function deleteSiteLogo() from functions.php
*/
private function deleteSiteLogo()
{
if (deleteSiteLogo()) {
return array(
'status'=>'0',
'message'=>'Site logo deleted.'
);
}
return array(
'status'=>'1',
'message'=>'An error occurred while trying to delete the site logo.'
);
}
/* Upload a file to a particular page === Bludit v4
Referer to the function uploadPageFile() from functions.php
*/

View file

@ -2,8 +2,8 @@
class pluginTinymce extends Plugin {
private $loadOnController = array(
'editor' // Load this plugin only in the Dashboard
private $loadOnViews = array(
'editor' // Load this plugin only in the Editor view
);
public function init()
@ -39,8 +39,8 @@ class pluginTinymce extends Plugin {
public function adminHead()
{
// Load the plugin only in the controllers setted in $this->loadOnController
if (!in_array($GLOBALS['ADMIN_CONTROLLER'], $this->loadOnController)) {
// Load the plugin only in the controllers setted in $this->loadOnViews
if (!in_array($GLOBALS['ADMIN_VIEW'], $this->loadOnViews)) {
return false;
}
@ -53,8 +53,8 @@ class pluginTinymce extends Plugin {
{
global $L;
// Load the plugin only in the controllers setted in $this->loadOnController
if (!in_array($GLOBALS['ADMIN_CONTROLLER'], $this->loadOnController)) {
// Load the plugin only in the controllers setted in $this->loadOnViews
if (!in_array($GLOBALS['ADMIN_VIEW'], $this->loadOnViews)) {
return false;
}

View file

@ -2,7 +2,7 @@
class pluginVisitsStats extends Plugin {
private $loadOnController = array(
private $loadOnViews = array(
'dashboard' // Load this plugin only in the Dashboard
);
@ -17,7 +17,7 @@ class pluginVisitsStats extends Plugin {
public function adminHead()
{
if (!in_array($GLOBALS['ADMIN_CONTROLLER'], $this->loadOnController)) {
if (!in_array($GLOBALS['ADMIN_VIEW'], $this->loadOnViews)) {
return false;
}