♻️ Rework logo support

This commit is contained in:
Kazhnuz 2025-07-15 16:41:34 +02:00
parent 072728b5c7
commit bba63a533d
13 changed files with 91 additions and 183 deletions

View file

@ -367,6 +367,43 @@ EOF;
return $html;
}
public static function formSelectGallery($args)
{
global $medias;
global $L;
$id = 'js' . $args['name'];
if (isset($args['id'])) {
$id = $args['id'];
}
$class = 'form-select custom-select';
if (isset($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$html = '<div class="form-group row mb-2">';
if (isset($args['label'])) {
$html .= '<label for="' . $id . '" class="col-sm-2 col-form-label">' . $args['label'] . '</label>';
}
$html .= '<div class="col-sm-10">';
$html .= '<select id="' . $id . '" name="' . $args['name'] . '" class="' . $class . '">';
$html .= '<option value="" ' . (('' == $args['selected']) ? 'selected' : '') . '>' . $L->get('None') . '</option>';
foreach ($medias->content() as $key=>$media) {
$html .= '<option value="'.$key.'" ' . (($key == $args['selected']) ? 'selected' : '') . '>' . $media->name() . '</option>';
}
$html .= '</select>';
if (isset($args['tip'])) {
$html .= '<small class="form-text text-muted">' . $args['tip'] . '</small>';
}
$html .= '</div>';
$html .= '</div>';
return $html;
}
public static function formSelectBlock($args)
{
$id = 'js' . $args['name'];

View file

@ -49,10 +49,9 @@
));
?>
<div class="form-group row mb-2">
<label class="col-sm-2 col-form-label" for="jssiteLogoInputFile"><?php $L->p('Upload image'); ?></label>
<label class="col-sm-2 col-form-label" for="jssiteInputFile"><?php $L->p('Upload image'); ?></label>
<div class="col-sm-10">
<input id="jssiteLogoInputFile" class="form-control custom-file-input" type="file" name="inputFile">
<small class="form-text text-muted">Prout</small>
<input id="jssiteInputFile" class="form-control custom-file-input" type="file" name="inputFile">
</div>
</div>
</div>

View file

@ -23,7 +23,6 @@
<a class="nav-item nav-link" id="nav-images-tab" data-bs-toggle="tab" data-bs-target="#images" role="tab" aria-controls="nav-images" aria-selected="false"><?php $L->p('Images') ?></a>
<a class="nav-item nav-link" id="nav-language-tab" data-bs-toggle="tab" data-bs-target="#language" role="tab" aria-controls="nav-language" aria-selected="false"><?php $L->p('Language') ?></a>
<a class="nav-item nav-link" id="nav-custom-fields-tab" data-bs-toggle="tab" data-bs-target="#custom-fields" role="tab" aria-controls="nav-custom-fields" aria-selected="false"><?php $L->p('Custom fields') ?></a>
<a class="nav-item nav-link" id="nav-logo-tab" data-bs-toggle="tab" data-bs-target="#logo" role="tab" aria-controls="nav-logo" aria-selected="false"><?php $L->p('Logo') ?></a>
</div>
</nav>
@ -436,6 +435,19 @@ echo Bootstrap::formInputHidden(array(
<!-- Images tab -->
<div class="tab-pane fade" id="images" role="tabpanel" aria-labelledby="images-tab">
<?php
echo Bootstrap::cardBegin($L->g('Images'));
echo Bootstrap::formSelectGallery(array(
'name' => 'logo',
'label' => $L->g('Site logo'),
'selected' => $site->logo(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::cardEnd();
echo Bootstrap::cardBegin($L->g('Thumbnails'));
echo Bootstrap::formInputText(array(
@ -565,56 +577,6 @@ echo Bootstrap::formInputHidden(array(
echo Bootstrap::cardEnd();
?>
</div>
<!-- Site logo tab -->
<div class="tab-pane fade" id="logo" role="tabpanel" aria-labelledby="logo-tab">
<?php
echo Bootstrap::cardBegin($L->g('Site logo'));
?>
<div class="container">
<div class="row">
<div class="col-lg-4 col-sm-12 p-0 pr-2">
<div class="custom-file">
<input id="jssiteLogoInputFile" class="form-control 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-danger w-100 mt-4 mb-4"><i class="fa fa-trash"></i><?php $L->p('Remove logo') ?></button>
</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>
</div>
</div>
<script>
$("#jsbuttonRemoveLogo").on("click", function() {
koblogAjax.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>
<?php echo Bootstrap::cardEnd(); ?>
</div>
<?php echo Bootstrap::formClose(); ?>

View file

@ -1,22 +0,0 @@
<?php defined('KOBLOG') or die('Koblog CMS.');
header('Content-Type: application/json');
/*
| Delete the site logo
| This script delete the file and set and empty string in the database
|
| @return array
*/
// Delete the file
$logoFilename = $site->logo(false);
if ($logoFilename) {
Filesystem::rmfile(PATH_UPLOADS.$logoFilename);
}
// Remove the logo from the database
$site->set(array('logo'=>''));
ajaxResponse(0, 'Logo removed.');
?>

View file

@ -1,70 +0,0 @@
<?php defined('KOBLOG') or die('Koblog CMS.');
header('Content-Type: application/json');
/*
| Upload site logo
| The final filename is the site's name and the extension is the same as the file uploaded
|
| @_FILES['inputFile'] multipart/form-data File from form
|
| @return array
*/
if (!isset($_FILES['inputFile'])) {
ajaxResponse(1, 'Error trying to upload the site logo.');
}
// Check path traversal on $filename
if (Text::stringContains($_FILES['inputFile']['name'], DS, false)) {
$message = 'Path traversal detected.';
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// File extension
$fileExtension = Filesystem::extension($_FILES['inputFile']['name']);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION'])) {
$message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// File MIME Type
$fileMimeType = Filesystem::mimeType($_FILES['inputFile']['tmp_name']);
if ($fileMimeType!==false) {
if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) {
$message = $L->g('File mime type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_MIMETYPES']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
}
// Final filename
$filename = 'logo.'.$fileExtension;
if (Text::isNotEmpty( $site->title() )) {
$filename = $site->title().'.'.$fileExtension;
}
// Delete old image
$oldFilename = $site->logo(false);
if ($oldFilename) {
Filesystem::rmfile(PATH_UPLOADS.$oldFilename);
}
// Move from temporary directory to uploads
Filesystem::mv($_FILES['inputFile']['tmp_name'], PATH_UPLOADS.$filename);
// Permissions
chmod(PATH_UPLOADS.$filename, 0644);
// Store the filename in the database
$site->set(array('logo'=>$filename));
ajaxResponse(0, 'Image uploaded.', array(
'filename'=>$filename,
'absoluteURL'=>DOMAIN_UPLOADS.$filename,
'absolutePath'=>PATH_UPLOADS.$filename
));
?>

View file

@ -130,6 +130,7 @@ 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 . 'media.class.php');
include(PATH_HELPERS . 'tcp.class.php');
include(PATH_HELPERS . 'dom.class.php');
include(PATH_HELPERS . 'cookie.class.php');

View file

@ -418,12 +418,6 @@ function createMedia($args, $files)
// Final filename
$filename = $key.'.'.$fileExtension;
// Delete old image
// $oldFilename = $site->logo(false);
// if ($oldFilename) {
// Filesystem::rmfile(PATH_UPLOADS.$oldFilename);
// }
if (!Filesystem::directoryExists(PATH_UPLOADS_MEDIAS)) {
Filesystem::mkdir(PATH_UPLOADS_MEDIAS, true);
}

View file

@ -0,0 +1,20 @@
<?php defined('KOBLOG') or die('Koblog CMS.');
class MediaHelper {
public static function getImage($slug)
{
global $medias;
if ($slug == '' || !$medias->exists($slug)) {
return null;
}
return new Media($slug);
}
public static function getLogo()
{
global $site;
return MediaHelper::getImage($site->logo());
}
}

View file

@ -26,28 +26,6 @@ class koblogAjax {
}
}
static async removeLogo() {
let url = HTML_PATH_ADMIN_ROOT+"ajax/logo-remove"
try {
const response = await fetch(url, {
credentials: 'same-origin',
method: "POST",
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}),
body: new URLSearchParams({
'tokenCSRF': tokenCSRF
}),
});
const json = await response.json();
return json;
}
catch (err) {
console.log(err);
return true;
}
}
// Alert the user when the user is not logged
userLogged(callBack) {
var ajaxRequest;

View file

@ -41,4 +41,8 @@ class Media {
function permalink() {
return HTML_PATH_UPLOADS_MEDIAS.$this->filename();
}
function toHTML($classes) {
return "<img src='" . $this->permalink() . "' alt='" . $this->alt() . "' " . ($classes ? "class='" . $classes . "'" : "" ) . " >";
}
}

View file

@ -345,13 +345,9 @@ class Site extends dbJSON
// Returns the absolute URL of the site logo
// If you set $absolute=false returns only the filename
public function logo($absolute = true)
public function logo()
{
$logo = $this->getField('logo');
if ($absolute && $logo) {
return DOMAIN_UPLOADS . $logo;
}
return $logo;
return $this->getField('logo');
}
// Returns the full domain and base url

View file

@ -40,7 +40,6 @@ header#main-header {
grid-area: header;
nav {
background-color: var(--navbar-color);
padding:4px;
@ -67,6 +66,11 @@ header#main-header {
}
}
img.logo {
max-height: 200px;
width: auto;
}
footer {
text-align: center;
font-style: italic;

View file

@ -10,8 +10,13 @@
</ul>
</nav>
<hgroup id="title-container">
<h1><?php echo $site->title() ?></h1>
<p><?php echo $site->description() ?></p>
<?php $logo = MediaHelper::getLogo(); ?>
<?php if ($logo) : ?>
<h1><?php echo $logo->toHTML('logo') ?></h1>
<?php else : ?>
<h1><?php echo $site->title() ?></h1>
<p><?php echo $site->description() ?></p>
<?php endif ?>
</hgroup>
<nav>
<ul>