Adding a Formats Tab on Edit photo page

* Add 3 new files for the tab creation (php, tpl and js)
* Creation of a new API method : pwg.images.formats.remove
* Adding translation in en_GB and fr_FR for the formats
* Minor change on the head-button css class
This commit is contained in:
Zacharie Guet
2022-07-29 15:56:53 +02:00
parent 4b8c033247
commit 5781810348
13 changed files with 371 additions and 3 deletions
+5 -1
View File
@@ -118,9 +118,13 @@ function add_core_tabs($sheets, $tab_id)
break; break;
case 'photo': case 'photo':
global $admin_photo_base_url; global $admin_photo_base_url, $conf;
$sheets['properties'] = array('caption' => '<span class="icon-file-image"></span>'.l10n('Properties'), 'url' => $admin_photo_base_url.'-properties'); $sheets['properties'] = array('caption' => '<span class="icon-file-image"></span>'.l10n('Properties'), 'url' => $admin_photo_base_url.'-properties');
$sheets['coi'] = array('caption' => '<span class="icon-crop"></span>'.l10n('Center of interest'), 'url' => $admin_photo_base_url.'-coi'); $sheets['coi'] = array('caption' => '<span class="icon-crop"></span>'.l10n('Center of interest'), 'url' => $admin_photo_base_url.'-coi');
if ($conf['enable_formats'])
{
$sheets['formats'] = array('caption' => '<span class="icon-docs"></span>'.l10n('Formats'), 'url' => $admin_photo_base_url.'-formats');
}
break; break;
case 'photos_add': case 'photos_add':
+4
View File
@@ -71,6 +71,10 @@ elseif ('coi' == $page['tab'])
{ {
include(PHPWG_ROOT_PATH.'admin/picture_coi.php'); include(PHPWG_ROOT_PATH.'admin/picture_coi.php');
} }
elseif ('formats' == $page['tab'] && $conf['enable_formats'])
{
include(PHPWG_ROOT_PATH.'admin/picture_formats.php');
}
else else
{ {
include(PHPWG_ROOT_PATH.'admin/photo_'.$page['tab'].'.php'); include(PHPWG_ROOT_PATH.'admin/photo_'.$page['tab'].'.php');
+63
View File
@@ -0,0 +1,63 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
if(!defined("PHPWG_ROOT_PATH"))
{
die('Hacking attempt!');
}
// +-----------------------------------------------------------------------+
// | Check Access and exit when user status is not ok |
// +-----------------------------------------------------------------------+
check_status(ACCESS_ADMINISTRATOR);
check_input_parameter('image_id', $_GET, false, PATTERN_ID);
$query='
SELECT *
FROM '.IMAGES_TABLE.'
WHERE id = '. $_GET['image_id'] .'
;';
$images = query2array($query);
$image = $images[0];
$query = '
SELECT
*
FROM '.IMAGE_FORMAT_TABLE.'
WHERE image_id = '.$_GET['image_id'].'
;';
$formats = query2array($query);
foreach ($formats as &$format)
{
$format['download_url'] = 'action.php?format='.$format['format_id'].'&amp;download';
$format['label'] = strtoupper($format['ext']);
$lang_key = 'format '.strtoupper($format['ext']);
if (isset($lang[$lang_key]))
{
$format['label'] = $lang[$lang_key];
}
$format['filesize'] = sprintf('%.1fMB', $format['filesize']/1024);
}
$template->assign(array(
'ADD_FORMATS_URL' => get_root_url().'admin.php?page=photos_add&formats='.$_GET['image_id'],
'IMG_SQUARE_SRC' => DerivativeImage::url(ImageStdParams::get_by_type(IMG_SQUARE), $image),
'FORMATS' => $formats,
'PWG_TOKEN' => get_pwg_token(),
));
$template->set_filename('picture_formats', 'picture_formats.tpl');
$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_formats');
?>
@@ -39,6 +39,8 @@ or
.head-button-1:hover { .head-button-1:hover {
background: #ff7700; background: #ff7700;
text-decoration: none !important;
color: white;
} }
.head-button-2 { .head-button-2 {
@@ -48,6 +50,8 @@ or
.head-button-2:hover { .head-button-2:hover {
background: #eee; background: #eee;
text-decoration: none !important;
color: inherit !important;
} }
/* ------------- /* -------------
@@ -0,0 +1,35 @@
function fitExtensions() {
$(".format-card-ext span").each((i, node) => {
let size = Math.min(180 * 1/node.innerHTML.length, 45)
node.setAttribute('style', `font-size:${size}px`)
})
}
fitExtensions()
$('.format-card').each((i, node) => {
let card = $(node)
let button = card.find(".format-delete")
button.click(() => {
console.log(card.data('id'));
button.find('i').attr("class", "icon-spin6 animate-spin")
$.ajax({
url: "ws.php?format=json&method=pwg.images.formats.delete",
type: "POST",
data: {
pwg_token : pwg_token,
format_id: card.data('id'),
},
success: function (raw_data) {
card.fadeOut("slow", () => {
card.remove();
if ($('.format-card').length == 0)
$('.no-formats').show()
})
},
error: function(message) {
console.log(message);
}
})
})
})
@@ -81,7 +81,7 @@ var batch_Label = "{'Manage this set of %d photos'|translate}";
var albumSummary_label = "{'Album "%s" now contains %d photos'|translate|escape}"; var albumSummary_label = "{'Album "%s" now contains %d photos'|translate|escape}";
var str_format_warning = "{'Error when trying to detect formats'|translate}"; var str_format_warning = "{'Error when trying to detect formats'|translate}";
var str_ok = "{'Ok'|translate}"; var str_ok = "{'Ok'|translate}";
var str_format_warning_multiple = "{'There is multiple image in the database with the following names : %s. Try to rename them with the Edit Filename plugin.'|translate}"; var str_format_warning_multiple = "{'There is multiple image in the database with the following names : %s.'|translate}";
var str_format_warning_notFound = "{'No picture found with the following name : %s.'|translate}"; var str_format_warning_notFound = "{'No picture found with the following name : %s.'|translate}";
var str_and_X_others = "{'and %d more'|translate}"; var str_and_X_others = "{'and %d more'|translate}";
var file_ext = "{$file_exts}"; var file_ext = "{$file_exts}";
@@ -508,7 +508,7 @@ jQuery(document).ready(function(){
<fieldset class="selectFiles"> <fieldset class="selectFiles">
<legend><span class="icon-file-image icon-yellow"></span>{'Select files'|@translate}</legend> <legend><span class="icon-file-image icon-yellow"></span>{'Select files'|@translate}</legend>
<div class="selectFilesButtonBlock"> <div class="selectFilesButtonBlock">
<button id="addFiles" class="buttonGradient">{if not $DISPLAY_FORMATS}{'Add Photos'|translate}{else}{'Add Formats'|translate}{/if}<i class="icon-plus-circled"></i></button> <button id="addFiles" class="buttonGradient">{if not $DISPLAY_FORMATS}{'Add Photos'|translate}{else}{'Add formats'|@translate}{/if}<i class="icon-plus-circled"></i></button>
<div class="selectFilesinfo"> <div class="selectFilesinfo">
{if isset($original_resize_maxheight)} {if isset($original_resize_maxheight)}
<p class="uploadInfo">{'The picture dimensions will be reduced to %dx%d pixels.'|@translate:$original_resize_maxwidth:$original_resize_maxheight}</p> <p class="uploadInfo">{'The picture dimensions will be reduced to %dx%d pixels.'|@translate:$original_resize_maxwidth:$original_resize_maxheight}</p>
@@ -0,0 +1,29 @@
{combine_css path="admin/themes/default/fontello/css/animation.css" order=10} {* order 10 is required, see issue 1080 *}
{combine_script id='picture_formats' load='footer' path='admin/themes/default/js/picture_formats.js'}
<script>
const nbFormats = {count($FORMATS)}
const pwg_token = "{$PWG_TOKEN}"
</script>
<div class="formats-header">
<a class="head-button-1 icon-plus-circled" href="{$ADD_FORMATS_URL}">{"Add formats"|@translate}</a>
</div>
<div class="formats-content">
<div class="no-formats" {if (count($FORMATS) != 0)}style="display:none"{/if}>
{"No format for this picture"|@translate}
</div>
<div class="formats-list" {if (count($FORMATS) == 0)}style="display:none"{/if}>
{foreach from=$FORMATS item=$format}
<div class="format-card" data-id="{$format["format_id"]}" style="background-image: url('{$IMG_SQUARE_SRC}')">
<span class="format-card-size">{$format["filesize"]}</span>
<div class="format-card-ext"><span>{$format["label"]}</span></div>
<div class="format-card-actions">
<a href="{$format["download_url"]}" rel="nofollow"> <i class="icon-download"></i> </a>
<a class="format-delete"> <i class="icon-trash-1"></i> </a>
</div>
</div>
{/foreach}
</div>
</div>
+72
View File
@@ -4008,6 +4008,78 @@ a#showPermissions:hover {text-decoration: none;}
grid-template-columns: 50% 50%; grid-template-columns: 50% 50%;
} }
/* Format tab on picture edit */
.formats-header {
display: flex;
flex-wrap: nowrap;
align-items: center;
margin-left: 20px;
max-width: calc(100% - 20px);
overflow: hidden;
padding: 10px;
}
.formats-content {
margin: 10px 30px;
}
.formats-list {
display: flex;
}
.format-card {
width: 150px;
height: 150px;
background-size: cover;
margin-right: 20px;
margin-bottom: 20px;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
flex-wrap: wrap;
}
.format-card::before {
content: "";
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.format-card-ext {
color: white;
font-weight: bolder;
font-size: 50px;
z-index: 2;
height: 40%;
display: flex;
justify-content: center;
align-items: center;
}
.format-card-actions {
display: flex;
justify-content: center;
z-index: 2;
}
.format-card-actions a {
color: white;
font-size: 24px;
margin: 0 10px;
}
.format-card-size {
color: white;
margin-top: 5px;
z-index: 2;
font-size: 20px;
}
/* Album Manager */ /* Album Manager */
#addAlbumForm { #addAlbumForm {
text-align:left; text-align:left;
+4
View File
@@ -1454,6 +1454,10 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important;
color: #444 !important; color: #444 !important;
} }
.head-button-1:hover {
color: #444 !important;
}
.head-button-2 { .head-button-2 {
background-color: #333 !important; background-color: #333 !important;
} }
+119
View File
@@ -1927,6 +1927,125 @@ SELECT
return $result; return $result;
} }
/**
* API method
* Remove a formats from the database and the file system
*
* @since 13
* @param mixed[] $params
* @option int format_id
* @option string pwg_token
*/
function ws_images_formats_delete($params, $service) {
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
if (!is_array($params['format_id']))
{
$params['format_id'] = preg_split(
'/[\s,;\|]/',
$params['format_id'],
-1,
PREG_SPLIT_NO_EMPTY
);
}
$params['format_id'] = array_map('intval', $params['format_id']);
$format_ids = array();
foreach ($params['format_id'] as $format_id)
{
if ($format_id >= 0)
{
$format_ids[] = $format_id;
}
}
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
$image_ids = array();
$formats_of = array();
//Delete physical file
$ok = true;
$query = '
SELECT
image_id,
ext
FROM '.IMAGE_FORMAT_TABLE.'
WHERE format_id IN ('.implode(',', $format_ids).')
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
if (!isset($formats_of[ $row['image_id'] ]))
{
$image_ids[] = $row['image_id'];
$formats_of[ $row['image_id'] ] = array();
}
$formats_of[ $row['image_id'] ][] = $row['ext'];
}
if (count($image_ids) == 0)
{
return new PwgError(404, 'No format found for the id(s) given');
}
$query = '
SELECT
id,
path,
representative_ext
FROM '.IMAGES_TABLE.'
WHERE id IN ('.implode(',', $image_ids).')
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
if (url_is_remote($row['path']))
{
continue;
}
$files = array();
$image_path = get_element_path($row);
if (isset($formats_of[ $row['id'] ]))
{
foreach ($formats_of[ $row['id'] ] as $format_ext)
{
$files[] = original_to_format($image_path, $format_ext);
}
}
foreach ($files as $path)
{
if (is_file($path) and !unlink($path))
{
$ok = false;
trigger_error('"'.$path.'" cannot be removed', E_USER_WARNING);
break;
}
}
}
//Delete format in the database
$query = '
DELETE FROM '.IMAGE_FORMAT_TABLE.'
WHERE format_id IN ('.implode(',', $format_ids).')
;';
pwg_query($query);
invalidate_user_cache();
return $ok;
}
/** /**
* API method * API method
* Check is file has been update * Check is file has been update
+11
View File
@@ -233,3 +233,14 @@ $lang['%d users deleted'] = '%d users deleted';
$lang['%d users were not updated.'] = '%d users not updated.'; $lang['%d users were not updated.'] = '%d users not updated.';
$lang['%d users were updated.'] = '%d users updated.'; $lang['%d users were updated.'] = '%d users updated.';
$lang['%d waiting for validation'] = '%d waiting for validation'; $lang['%d waiting for validation'] = '%d waiting for validation';
$lang['Upload Formats'] = 'Upload Formats';
$lang['Add formats'] = 'Add formats';
$lang['No format for this picture'] = 'No format for this picture';
$lang['Add another set of formats'] = 'Add another set of formats';
$lang['%d formats uploaded for %d photos'] = '%d formats uploaded for %d photos';
$lang['Error when trying to detect formats'] = 'Error when trying to detect formats';
$lang['There is multiple image in the database with the following names : %s.'] = 'There is multiple image in the database with the following names : %s.';
$lang['No picture found with the following name : %s.'] = 'No picture found with the following name : %s.';
$lang['and %d more'] = 'and %d more';
$lang['Picture to associate formats with'] = 'Picture to associate formats with';
$lang['The original picture will be detected with the filename (without extension).'] = 'The original picture will be detected with the filename (without extension).';
+11
View File
@@ -1301,4 +1301,15 @@ $lang['Discover'] = 'Découvrir';
$lang['Latest Piwigo news'] = 'Dernière nouvelle de Piwigo'; $lang['Latest Piwigo news'] = 'Dernière nouvelle de Piwigo';
$lang['Understood, do not show again'] = 'Compris, ne plus afficher'; $lang['Understood, do not show again'] = 'Compris, ne plus afficher';
$lang['%s pixels, %.2f MB'] = '%s pixels, %.2f Mo'; $lang['%s pixels, %.2f MB'] = '%s pixels, %.2f Mo';
$lang['Upload Formats'] = 'Télécharger des formats';
$lang['Add formats'] = 'Ajouter des formats';
$lang['No format for this picture'] = 'Il n\'y a pas de format pour cette photo';
$lang['Add another set of formats'] = 'Ajouter un autre lot de formats';
$lang['%d formats uploaded for %d photos'] = '%d format(s) téléchargé(s) pour %d photo(s)';
$lang['Error when trying to detect formats'] = 'Une erreur est survenue lors de la détection des formats';
$lang['There is multiple image in the database with the following names : %s.'] = 'Plusieurs images trouvée avec le nom : %s.';
$lang['No picture found with the following name : %s.'] = 'Pas de photos trouvée pour le nom : %s.';
$lang['and %d more'] = 'et %d autre(s)';
$lang['Picture to associate formats with'] = 'Photo à associer avec les formats';
$lang['The original picture will be detected with the filename (without extension).'] = 'La photo originale sera détectée en comparant les noms des fichiers (sans extension).';
// Leave this line empty // Leave this line empty
+12
View File
@@ -264,6 +264,18 @@ function ws_addDefaultMethods( $arr )
$ws_functions_root . 'pwg.images.php', $ws_functions_root . 'pwg.images.php',
array('admin_only'=>true, 'post_only'=>true) array('admin_only'=>true, 'post_only'=>true)
); );
$service->addMethod(
'pwg.images.formats.delete',
'ws_images_formats_delete',
array(
'format_id' => array('type'=>WS_TYPE_ID, 'default'=>null, 'flags'=>WS_PARAM_ACCEPT_ARRAY),
'pwg_token' => array(),
),
'Remove a format',
$ws_functions_root . 'pwg.images.php',
array('admin_only'=>true, 'post_only'=>true)
);
$service->addMethod( $service->addMethod(
'pwg.images.setRank', 'pwg.images.setRank',