diff --git a/bl-kernel/admin/views/settings.php b/bl-kernel/admin/views/settings.php
index 60ba69d3..d60044f7 100644
--- a/bl-kernel/admin/views/settings.php
+++ b/bl-kernel/admin/views/settings.php
@@ -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("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: 'p('Are you sure you want to delete the site logo') ?>',
+ buttons: {
+ cancel: {
+ label: 'p('Cancel') ?>',
+ className: 'btn-sm btn-secondary'
+ },
+ confirm: {
+ label: '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("p('The changes have been saved') ?>");
+ $('#siteLogoPreview').attr('src', '');
+ } else {
+ logs("An error occurred while trying to delete the site logo.");
+ showAlertError(response.message);
+ }
+ });
+ return true;
+ }
+ }
+ });
+ });
+
});
// ============================================================================
@@ -509,50 +580,17 @@
- $L->g('Site logo')));
- ?>
-
-
-
-
-
-
-
+
+
-
-
 ? DOMAIN_UPLOADS . $site->logo(false) . '?version=' . time() : HTML_PATH_CORE_IMG . 'default.svg') ?>)
+
+
+
-
diff --git a/bl-kernel/functions.php b/bl-kernel/functions.php
index 69b6291b..e553cf5b 100644
--- a/bl-kernel/functions.php
+++ b/bl-kernel/functions.php
@@ -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/
.
+
+ @_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
diff --git a/bl-kernel/helpers/text.class.php b/bl-kernel/helpers/text.class.php
index 9ab93bef..1e5520b3 100644
--- a/bl-kernel/helpers/text.class.php
+++ b/bl-kernel/helpers/text.class.php
@@ -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);
diff --git a/bl-kernel/js/api.js b/bl-kernel/js/api.js
index 3e37e982..fd9c6c60 100644
--- a/bl-kernel/js/api.js
+++ b/bl-kernel/js/api.js
@@ -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
diff --git a/bl-languages/en.json b/bl-languages/en.json
index e10d2cc7..6f2f21b5 100644
--- a/bl-languages/en.json
+++ b/bl-languages/en.json
@@ -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?",
diff --git a/bl-plugins/api/plugin.php b/bl-plugins/api/plugin.php
index a60c6ddd..b6b33e7e 100644
--- a/bl-plugins/api/plugin.php
+++ b/bl-plugins/api/plugin.php
@@ -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
*/
diff --git a/bl-plugins/tinymce/plugin.php b/bl-plugins/tinymce/plugin.php
index 4cce0bc0..95e8e07c 100644
--- a/bl-plugins/tinymce/plugin.php
+++ b/bl-plugins/tinymce/plugin.php
@@ -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;
}
diff --git a/bl-plugins/visits-stats/plugin.php b/bl-plugins/visits-stats/plugin.php
index f75cea6f..69f1740b 100644
--- a/bl-plugins/visits-stats/plugin.php
+++ b/bl-plugins/visits-stats/plugin.php
@@ -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;
}