diff --git a/admin/include/add_core_tabs.inc.php b/admin/include/add_core_tabs.inc.php index 92a90c71f8..0fab911df4 100644 --- a/admin/include/add_core_tabs.inc.php +++ b/admin/include/add_core_tabs.inc.php @@ -118,9 +118,13 @@ function add_core_tabs($sheets, $tab_id) break; case 'photo': - global $admin_photo_base_url; + global $admin_photo_base_url, $conf; $sheets['properties'] = array('caption' => ''.l10n('Properties'), 'url' => $admin_photo_base_url.'-properties'); $sheets['coi'] = array('caption' => ''.l10n('Center of interest'), 'url' => $admin_photo_base_url.'-coi'); + if ($conf['enable_formats']) + { + $sheets['formats'] = array('caption' => ''.l10n('Formats'), 'url' => $admin_photo_base_url.'-formats'); + } break; case 'photos_add': diff --git a/admin/photo.php b/admin/photo.php index efabca7253..897e942af9 100644 --- a/admin/photo.php +++ b/admin/photo.php @@ -71,6 +71,10 @@ { include(PHPWG_ROOT_PATH.'admin/picture_coi.php'); } +elseif ('formats' == $page['tab'] && $conf['enable_formats']) +{ + include(PHPWG_ROOT_PATH.'admin/picture_formats.php'); +} else { include(PHPWG_ROOT_PATH.'admin/photo_'.$page['tab'].'.php'); diff --git a/admin/picture_formats.php b/admin/picture_formats.php new file mode 100644 index 0000000000..ba9c6403a2 --- /dev/null +++ b/admin/picture_formats.php @@ -0,0 +1,63 @@ +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'); +?> diff --git a/admin/themes/default/css/components/general.css b/admin/themes/default/css/components/general.css index 11cd823a2a..e5aa693fbd 100644 --- a/admin/themes/default/css/components/general.css +++ b/admin/themes/default/css/components/general.css @@ -39,6 +39,8 @@ or .head-button-1:hover { background: #ff7700; + text-decoration: none !important; + color: white; } .head-button-2 { @@ -48,6 +50,8 @@ or .head-button-2:hover { background: #eee; + text-decoration: none !important; + color: inherit !important; } /* ------------- diff --git a/admin/themes/default/js/picture_formats.js b/admin/themes/default/js/picture_formats.js new file mode 100644 index 0000000000..774dfeb57f --- /dev/null +++ b/admin/themes/default/js/picture_formats.js @@ -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); + } + }) + }) +}) \ No newline at end of file diff --git a/admin/themes/default/template/photos_add_direct.tpl b/admin/themes/default/template/photos_add_direct.tpl index 201e097ec6..c7109e0ce1 100644 --- a/admin/themes/default/template/photos_add_direct.tpl +++ b/admin/themes/default/template/photos_add_direct.tpl @@ -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 str_format_warning = "{'Error when trying to detect formats'|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_and_X_others = "{'and %d more'|translate}"; var file_ext = "{$file_exts}"; @@ -508,7 +508,7 @@ jQuery(document).ready(function(){
{'Select files'|@translate}
- +
{if isset($original_resize_maxheight)}

{'The picture dimensions will be reduced to %dx%d pixels.'|@translate:$original_resize_maxwidth:$original_resize_maxheight}

diff --git a/admin/themes/default/template/picture_formats.tpl b/admin/themes/default/template/picture_formats.tpl new file mode 100644 index 0000000000..573f343dec --- /dev/null +++ b/admin/themes/default/template/picture_formats.tpl @@ -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'} + + + + +
+
+ {"No format for this picture"|@translate} +
+ +
+ {foreach from=$FORMATS item=$format} +
+ {$format["filesize"]} +
{$format["label"]}
+
+ + +
+
+ {/foreach} +
+
\ No newline at end of file diff --git a/admin/themes/default/theme.css b/admin/themes/default/theme.css index 97e89b3e90..45de10db24 100644 --- a/admin/themes/default/theme.css +++ b/admin/themes/default/theme.css @@ -4008,6 +4008,78 @@ a#showPermissions:hover {text-decoration: none;} 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 */ #addAlbumForm { text-align:left; diff --git a/admin/themes/roma/theme.css b/admin/themes/roma/theme.css index 5d7614bfa9..8f9eb4f435 100644 --- a/admin/themes/roma/theme.css +++ b/admin/themes/roma/theme.css @@ -1454,6 +1454,10 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; color: #444 !important; } +.head-button-1:hover { + color: #444 !important; +} + .head-button-2 { background-color: #333 !important; } diff --git a/include/ws_functions/pwg.images.php b/include/ws_functions/pwg.images.php index be5dc7677e..e79d3d5683 100644 --- a/include/ws_functions/pwg.images.php +++ b/include/ws_functions/pwg.images.php @@ -1927,6 +1927,125 @@ function ws_images_formats_searchImage($params, $service) 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 * Check is file has been update diff --git a/language/en_GB/admin.lang.php b/language/en_GB/admin.lang.php index 11358076e1..716e4f86fc 100644 --- a/language/en_GB/admin.lang.php +++ b/language/en_GB/admin.lang.php @@ -233,3 +233,14 @@ $lang['%d users were not updated.'] = '%d users not updated.'; $lang['%d users were updated.'] = '%d users updated.'; $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).'; diff --git a/language/fr_FR/admin.lang.php b/language/fr_FR/admin.lang.php index 9b4cf9d067..13c19e933b 100644 --- a/language/fr_FR/admin.lang.php +++ b/language/fr_FR/admin.lang.php @@ -1301,4 +1301,15 @@ $lang['Latest Piwigo news'] = 'Dernière nouvelle de Piwigo'; $lang['Understood, do not show again'] = 'Compris, ne plus afficher'; $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 diff --git a/ws.php b/ws.php index 785df02828..b3d9d507e1 100644 --- a/ws.php +++ b/ws.php @@ -264,6 +264,18 @@ function ws_addDefaultMethods( $arr ) $ws_functions_root . 'pwg.images.php', 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( 'pwg.images.setRank',