fixes #2193 [search] add 5 new widgets

add ratings, ratios, filesize, width and height widgets
- in functions_search add clauses according to each new filter
- in ws_functions add new api parameters
- in index.php add queries to get data for filters
- in admin.lang add missing translations for filters
- in css add basic style to work for modus newspaper
- in js add script for new filters
- in tpl combine script + CSS for double slider & jquery Ui. Add slider conf, template for new widgets

TODO
- adapt css to different themes and skins
This commit is contained in:
HWFord 2024-07-25 16:11:07 +02:00
parent 08357f59eb
commit 6fe1d7db65
11 changed files with 1253 additions and 19 deletions

View file

@ -375,6 +375,60 @@ SELECT
$clauses[] = $local_clause;
}
if (!empty($search['fields']['ratios']))
{
foreach ($search['fields']['ratios'] as $r)
{
switch($r)
{
case 'portrait':
$clauses[] = '(FLOOR(width / height * 100) / 100) < 0.96';
break;
case'square':
$clauses[] = '(FLOOR(width / height * 100) / 100) BETWEEN 0.95 AND 1.06';
break;
case'landscape':
$clauses[] = '(FLOOR(width / height * 100) / 100) BETWEEN 1.05 AND 2.01';
break;
case'panorama':
$clauses[] = '(FLOOR(width / height * 100) / 100) > 2.01';
break;
}
}
}
if(!empty($search['fields']['ratings']))
{
foreach ($search['fields']['ratings'] as $r)
{
if (0 == $r)
{
$clauses[] = 'rating_score IS NULL';
}
else{
$clauses[] = 'rating_score BETWEEN '.(intval($r)-1).' AND '.$r;
}
}
}
if (!empty($search['fields']['filesize_min']) && !empty($search['fields']['filesize_max']))
{
$clauses[] = 'filesize BETWEEN '.$search['fields']['filesize_min'].' AND '.$search['fields']['filesize_max'];
}
if (!empty($search['fields']['height_min']) && !empty($search['fields']['height_max']))
{
$clauses[] = 'height BETWEEN '.$search['fields']['height_min'].' AND '.$search['fields']['height_max'];
}
if (!empty($search['fields']['width_min']) && !empty($search['fields']['width_max']))
{
$clauses[] = 'width BETWEEN '.$search['fields']['width_min'].' AND '.$search['fields']['width_max'];
}
// adds brackets around where clauses
$clauses = prepend_append_array_items($clauses, '(', ')');

View file

@ -841,6 +841,54 @@ function ws_images_filteredSearch_create($params, $service)
$search['fields']['date_posted'] = $params['date_posted'];
}
if (isset($params['ratios']))
{
foreach ($params['ratios'] as $ext)
{
if (!preg_match('/^[a-z0-9]+$/i', $ext))
{
return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid parameter ratios');
}
}
$search['fields']['ratios'] = $params['ratios'];
}
if (isset($params['ratings']))
{
$search['fields']['ratings'] = $params['ratings'];
}
if (isset($params['filesize_min']))
{
$search['fields']['filesize_min'] = $params['filesize_min'];
}
if (isset($params['filesize_max']))
{
$search['fields']['filesize_max'] = $params['filesize_max'];
}
if (isset($params['width_min']))
{
$search['fields']['width_min'] = $params['width_min'];
}
if (isset($params['width_max']))
{
$search['fields']['width_max'] = $params['width_max'];
}
if (isset($params['height_min']))
{
$search['fields']['height_min'] = $params['height_min'];
}
if (isset($params['height_max']))
{
$search['fields']['height_max'] = $params['height_max'];
}
list($search_uuid, $search_url) = save_search($search, $search_info['id'] ?? null);
return array(

228
index.php
View file

@ -458,6 +458,234 @@ SELECT
$template->assign('FILETYPES', query2array($query, 'ext', 'counter'));
}
// For rating
if (isset($my_search['fields']['ratings']))
{
$ratings = array();
for ($i = 0; $i <= 5; $i++)
{
$query = '
SELECT
count(*) as count
FROM '.IMAGES_TABLE.' AS i
JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.image_id = i.id
WHERE '.$search_items_clause.'
'.get_sql_condition_FandF(
array(
'forbidden_categories' => 'category_id',
'visible_categories' => 'category_id',
'visible_images' => 'id'
),
' AND '
);
if (0 == $i)
{
$query .='AND rating_score IS NULL';
}
else
{
$query .= ' AND rating_score BETWEEN '.($i-1).' AND '.$i;
}
$query .=';';
$result = pwg_db_fetch_assoc(pwg_query($query));
$ratings[$i] = $result['count'];
}
$template->assign('RATING', $ratings);
}
// For filesize
if (isset($my_search['fields']['filesize_min']) && isset($my_search['fields']['filesize_max']))
{
$filesizes = array();
$filesize = array();
$query = '
SELECT
filesize
FROM '.IMAGES_TABLE.' AS i
JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.image_id = i.id
WHERE '.$search_items_clause.'
'.get_sql_condition_FandF(
array(
'forbidden_categories' => 'category_id',
'visible_categories' => 'category_id',
'visible_images' => 'id'
),
' AND '
).'
GROUP BY filesize
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
$filesizes[] = sprintf('%.2f', $row['filesize']/1024);
}
if (empty($filesizes))
{ // arbitrary values, only used when no photos on the gallery
$filesizes = array(0, 1, 2, 5, 8, 15);
}
$filesizes = array_unique($filesizes);
sort($filesizes);
// add 0.1MB to the last value, to make sure the heaviest photo will be in
// the result
$filesizes[count($filesizes)-1]+= 0.1;
$filesize['list'] = implode(',', $filesizes);
$filesize['bounds'] = array(
'min' => sprintf('%.2f',$filesizes[0]),
'max' => sprintf('%.2f',end($filesizes)),
);
$filesize['selected'] = array(
'min' => !empty($my_search['fields']['filesize_min']) ? sprintf('%.2f', $my_search['fields']['filesize_min']/1024) : sprintf('%.2f',$filesizes[0]),
'max' => !empty($my_search['fields']['filesize_max']) ? sprintf('%.2f', $my_search['fields']['filesize_max']/1024) : sprintf('%.2f',end($filesizes)),
);
$template->assign('FILESIZE', $filesize );
}
// For ratio, height, width
//The queries need are the similar so they have been grouped together
if (isset($my_search['fields']['ratios']) || isset($my_search['fields']['height_min']) || isset($my_search['fields']['width_min']))
{
$widths = array();
$width = array();
$heights = array();
$height = array();
$ratios = array();
$ratio = array();
// $dimensions = array();
// get all width, height and ratios
$query = '
SELECT
width,
height,
(FLOOR(width / height * 100) / 100) as ratio
FROM '.IMAGES_TABLE.' as i
JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.image_id = i.id
WHERE '.$search_items_clause.'
'.get_sql_condition_FandF(
array(
'forbidden_categories' => 'category_id',
'visible_categories' => 'category_id',
'visible_images' => 'id'
),
' AND '
).'
AND width IS NOT NULL
AND height IS NOT NULL
;';
$result = pwg_query($query);
if (pwg_db_num_rows($result))
{
while ($row = pwg_db_fetch_assoc($result))
{
if ($row['width']>0 && $row['height']>0)
{
$widths[] = $row['width'];
$heights[] = $row['height'];
$ratios[] = $row['ratio'] ;
}
}
}
if (empty($widths))
{ // arbitrary values, only used when no photos on the gallery
$widths = array(600, 1920, 3500);
$heights = array(480, 1080, 2300);
$ratios = array(1.25, 1.52, 1.78);
}
$widths = array_unique($widths);
sort($widths);
$width['list'] = implode(',', $widths);
$width['bounds']= array(
'min' => $widths[0],
'max' => end($widths)+1, //Make sure the biggest is included
);
$width['selected'] = array(
'min' => !empty($my_search['fields']['width_min']) ? $my_search['fields']['width_min'] : $widths[0],
'max' => !empty($my_search['fields']['width_max']) ? $my_search['fields']['width_max'] : end($widths),
);
$heights = array_unique($heights);
sort($heights);
$height['list'] = implode(',', $heights);
$height['bounds']= array(
'min' => $heights[0],
'max' => end($heights)+1, //Make sure the biggest is included
);
$height['selected'] = array(
'min' => !empty($my_search['fields']['height_min']) ? $my_search['fields']['height_min'] : $heights[0],
'max' => !empty($my_search['fields']['height_max']) ? $my_search['fields']['height_max'] : end($heights),
);
if(isset($my_search['fields']['ratios']))
{
// find ratio categories
$ratio_categories = array(
'Portrait' => array(),
'square' => array(),
'Landscape' => array(),
'Panorama' => array(),
);
foreach ($ratios as $r)
{
if ($r < 0.95)
{
$ratio_categories['Portrait'][] = $r;
}
else if ($r >= 0.95 and $ratio <= 1.05)
{
$ratio_categories['square'][] = $r;
}
else if ($r > 1.05 and $r < 2)
{
$ratio_categories['Landscape'][] = $r;
}
else if ($r >= 2)
{
$ratio_categories['Panorama'][] = $r;
}
}
foreach (array_keys($ratio_categories) as $type)
{
$ratio[$type] = count($ratio_categories[$type]);
}
$template->assign('RATIOS', $ratio);
}
if (isset($my_search['fields']['height_min']) && isset($my_search['fields']['height_max']))
{
$template->assign('HEIGHT', $height);
}
if (isset($my_search['fields']['width_min']) && isset($my_search['fields']['width_max']))
{
$template->assign('WIDTH', $width);
}
}
$template->assign(
array(
'GP' => json_encode($my_search),

View file

@ -196,6 +196,7 @@ $lang['Basic settings'] = 'Basic settings';
$lang['Batch Manager'] = 'Batch Manager';
$lang['between'] = "between";
$lang['between %d and %d pixels'] = 'between %d and %d pixels';
$lang['between %d and %d'] = 'between %d and %d';
$lang['between %.2f and %.2f'] = 'between %.2f and %.2f';
$lang['bottom left corner'] = 'bottom left corner';
$lang['bottom right corner'] = 'bottom right corner';

View file

@ -913,6 +913,7 @@ $lang['View in gallery'] = 'Voir dans la galerie';
$lang['Number of albums per page'] = 'Nombre d\'albums par page';
$lang['Ratio'] = 'Ratio';
$lang['between %d and %d pixels'] = 'entre %d et %d pixels';
$lang['between %d and %d'] = 'entre %d et %d';
$lang['between %.2f and %.2f'] = 'entre %.2f et %.2f';
$lang['Manage the members'] = 'Gérer les membres';
$lang['Type here the name of the new group'] = 'Inscrivez ici le nom du nouveau groupe';

View file

@ -112,24 +112,42 @@
.filetypes-option:nth-child(odd),
.added_by-option:nth-child(odd),
.date_posted-option:nth-child(odd) label {
.date_posted-option:nth-child(odd) label,
.ratios-option:nth-child(odd),
.ratings-option:nth-child(odd){
background: #f3f3f3;
}
.filetypes-option label .checked-icon,
.added_by-option label .checked-icon,
.date_posted-option label .checked-icon{
.date_posted-option label .checked-icon,
.ratios-option label .checked-icon,
.ratings-option label .checked-icon{
color: #ff7700;
}
.filetypes-option label .ext-badge,
.added_by-option label .added_by-badge,
.date_posted-option label .date_posted-badge {
.date_posted-option label .date_posted-badge,
.ratios-option label .ratio-badge,
.ratings-option label .ratings-badge {
background: #ff7700;
color: white;
}
.filetypes-option input:checked + label {
.ratios-option.disabled label .ratio-badge,
.ratings-option.disabled label .ratings-badge{
background-color: #888;
}
.ratios-option.disabled label .ratio-name,
.ratings-option.disabled label .ratings-name{
color:#888
}
.filetypes-option input:checked + label,
.ratios-option input:checked + label,
.ratings-option input:checked + label {
background: #fff5e8;
}

View file

@ -112,26 +112,44 @@
.filetypes-option:nth-child(odd),
.added_by-option:nth-child(odd),
.date_posted-option:nth-child(odd) label {
.date_posted-option:nth-child(odd) label,
.ratios-option:nth-child(odd),
.ratings-option:nth-child(odd) {
background: #444;
}
.filetypes-option label .checked-icon,
.added_by-option label .checked-icon,
.date_posted-option label .checked-icon{
.date_posted-option label .checked-icon,
.ratios-option label .checked-icon,
.ratings-option label .checked-icon{
color: white;
}
.filetypes-option label .ext-badge,
.added_by-option label .added_by-badge,
.date_posted-option label .date_posted-badge {
.date_posted-option label .date_posted-badge,
.ratios-option label .ratio-badge,
.ratings-option label .ratings-badge {
background: #ff7700bb;
color: white;
}
.ratios-option.disabled label .ratio-badge,
.ratings-option.disabled label .ratings-badge{
background-color: #888;
}
.ratios-option.disabled label .ratio-name,
.ratings-option.disabled label .ratings-name{
color:#888
}
.added_by-option input:checked + label,
.filetypes-option input:checked + label,
.date_posted-option input:checked + label {
.date_posted-option input:checked + label,
.ratios-option input:checked + label,
.ratings-option input:checked + label{
background: rgba(244, 171, 79, 0.17);
}

View file

@ -45,6 +45,10 @@
cursor: pointer;
}
.filter-manager-controller-container .mcs-icon:before{
margin-right:5px;
}
.filter-manager .mcs-icon::before {
margin: 0 5px 0 -2px;
transform: rotate(90deg);
@ -229,7 +233,9 @@
}
.filter-filetypes-form .filter-actions,
.filter-date_posted-form .filter-actions {
.filter-date_posted-form .filter-actions,
.filter-ratios-form .filter-actions,
.filter-ratings-form .filter-actions{
gap: 5px;
}
@ -248,6 +254,7 @@
.word-search-options,
.filter-tag-form .search-params,
.filter-authors .search-params,
.filter-album-form .search-params {
display: flex;
flex-direction: row;
@ -290,17 +297,21 @@
margin-top: 15px;
}
.filter-filetypes-form {
.filter-filetypes-form,
.filter-ratios-form{
width: 200px;
}
.filter-date_posted-form {
.filter-date_posted-form,
.filter-ratings-form{
width: 250px;
}
.filetypes-option-container,
.added_by-option-container,
.date_posted-option-container {
.date_posted-option-container,
.ratios-option-container
.ratings-option-container {
display: flex;
flex-direction: column;
margin: 20px 0 20px 0;
@ -308,19 +319,29 @@
max-height:250px;
}
.date_posted-option-container {
margin: 10px 0 10px 0;
}
.height-option-container,
.width-option-container{
margin-bottom:30px;
}
.filetypes-option input,
.added_by-option input,
.date_posted-option input {
.date_posted-option input,
.ratios-option input,
.ratings-option input {
display: none;
}
.filetypes-option label,
.added_by-option label,
.date_posted-option label {
.date_posted-option label,
.ratios-option label,
.ratings-option label{
display: flex;
flex-direction: row;
align-items: baseline;
@ -330,7 +351,9 @@
.filetypes-option label .checked-icon,
.added_by-option label .checked-icon,
.date_posted-option label .checked-icon{
.date_posted-option label .checked-icon,
.ratios-option label .checked-icon,
.ratings-option label .checked-icon{
display: none;
position: absolute;
left: 0;
@ -344,7 +367,9 @@
.filetypes-option label .ext-name,
.added_by-option label .added_by-name,
.date_posted-option label .date-period {
.date_posted-option label .date-period,
.ratios-option label .ratio-name,
.ratings-option label .ratings-name {
margin-left: 30px;
}
@ -359,7 +384,9 @@
.filetypes-option label .ext-badge,
.added_by-option label .added_by-badge,
.date_posted-option label .date_posted-badge {
.date_posted-option label .date_posted-badge,
.ratios-option label .ratio-badge,
.ratings-option label .ratings-badge {
margin-left: auto;
border-radius: 10px;
padding: 0 5px;
@ -368,7 +395,9 @@
.filetypes-option input:checked + label .checked-icon,
.added_by-option input:checked + label .checked-icon,
.date_posted-option input:checked + label .checked-icon{
.date_posted-option input:checked + label .checked-icon,
.ratios-option input:checked + label .checked-icon,
.ratings-option input:checked + label .checked-icon{
display: flex;
}
@ -380,6 +409,21 @@
margin-top: 10px;
}
.filter-filesize-form,
.filter-height-form,
.filter-width-form{
width:400px;
}
.filesize-option-container,
.ratios-option-container,
.ratings-option-container,
.height-option-container,
.width-option-container{
margin-bottom:25px;
}
/*_____________________________*/
.head-button-2 {
position: relative;
padding: 5px 12px 5px 8px;
@ -706,7 +750,9 @@
}
.filetypes-option,
.added_by-option{
.added_by-option,
.ratios-option,
.ratings-option{
min-width:150px!important;
}
@ -855,3 +901,98 @@
box-sizing: border-box;
}
}
/* Slider css */
.slider-info
{
color: #ff7700;
font-weight: bold;
}
.slider-choice
{
color: #777;
border-radius: 4px;
padding: 2px 8px;
margin: 0 3px;
}
.slider-choice:hover
{
text-decoration: none;
color: initial;
cursor:pointer
}
.ui-slider-horizontal
{
width: 280px;
margin: 10px 0 10px 9px;
height: 2px;
}
.ui-widget-content
{
border: 1px solid #EEE;
background: #DDD;
}
.ui-slider .ui-slider-range
{
background: rgba(255, 166, 70, 0.9);
margin-top: -1px;
border: 1px solid #ffaf58;
}
.ui-slider-range.ui-widget-header.ui-corner-all
{
border: 1px solid #ffaf58;
padding:1px 0;
}
.ui-slider-handle.ui-state-default.ui-corner-all
{
margin-top:-3px;
border-radius: 10px;
}
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default
{
border: 1px solid #ffaf58;
background: #ffaf58;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover
{
background: #ffaf58
}
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus
{
border: 1px solid #ffaf58;
background: #ffaf58
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active
{
background: #ffaf58
}
.disableSlider{
pointer-events: none;
border:1px solid #ccc!important;
background-color:#ccc!important;
}
.ui-slider-horizontal .ui-slider-handle:hover{
cursor:pointer;
}

View file

@ -269,6 +269,183 @@ $(document).ready(function () {
empty_filters_list.push(PS_params.filetypes);
}
// Setup Ratio filter
if (global_params.fields.ratios) {
$(".filter-ratios").css("display", "flex");
$(".filter-manager-controller.ratios").prop("checked", true);
ratios_search_str = "";
global_params.fields.ratios.forEach(ft => {
ratios_search_str += str_ratios_label[ft] + ", ";
});
if (global_params.fields.ratios && global_params.fields.ratios.length > 0) {
$(".filter-ratios").addClass("filter-filled");
$(".filter.filter-ratios .search-words").text(ratios_search_str.slice(0, -2));
$(".ratios-option input").each(function () {
if (global_params.fields.ratios.includes($(this).attr('name'))) {
$(this).prop('checked', true);
}
});
} else {
$(".filter.filter-ratios .search-words").text(str_ratio_widget_label);
}
$(".filter-ratios .filter-actions .clear").on('click', function () {
$(".filter-ratios .ratios-option input").prop("checked", false);
});
PS_params.ratios = global_params.fields.ratios.length > 0 ? global_params.fields.ratios : '';
empty_filters_list.push(PS_params.ratios);
}
// Setup rating filter
if (global_params.fields.ratings) {
$(".filter-ratings").css("display", "flex");
$(".filter-manager-controller.ratings").prop("checked", true);
ratings_search_str = "";
global_params.fields.ratings.forEach(function(ft){
if(0 == ft )
{
ratings_search_str = str_no_rating + ", ";
}
else
{
ratings_search_str = str_between_rating.split("%d");
ratings_search_str = ratings_search_str[0] + (ft-1) + ratings_search_str[1] + ft + ratings_search_str[2];
}
});
if (global_params.fields.ratings && global_params.fields.ratings.length > 0) {
$(".filter-ratings").addClass("filter-filled");
$(".filter.filter-ratings .search-words").text(ratings_search_str);
$(".ratings-option input").each(function () {
if (global_params.fields.ratings.includes($(this).attr('name'))) {
$(this).prop('checked', true);
}
});
} else {
$(".filter.filter-ratings .search-words").text(str_rating_widget_label);
}
$(".filter-ratings .filter-actions .clear").on('click', function () {
$(".filter-ratings .ratings-option input").prop("checked", false);
});
PS_params.ratings = global_params.fields.ratings.length > 0 ? global_params.fields.ratings : '';
empty_filters_list.push(PS_params.ratings);
}
// Setup filesize filter
if (global_params.fields.filesize_min != null && global_params.fields.filesize_max != null) {
$(".filter-filesize").css("display", "flex");
$(".filter-manager-controller.filesize").prop("checked", true);
$(".filter.filter-filesize .slider-info").html(sprintf(sliders.filesizes.text,sliders.filesizes.selected.min,sliders.filesizes.selected.max,));
$('[data-slider=filesizes]').pwgDoubleSlider(sliders.filesizes);
if( global_params.fields.filesize_min != null && global_params.fields.filesize_max > 0) {
$(".filter-filesize").addClass("filter-filled");
$(".filter.filter-filesize .search-words").html(sprintf(sliders.filesizes.text,sliders.filesizes.selected.min,sliders.filesizes.selected.max,));
}
else
{
$(".filter.filter-filesize .search-words").text(str_filesize_widget_label);
}
$(".filter-filesize .filter-actions .clear").on('click', function () {
updateFilters('filesize', 'add');
$(".filter-filesize").trigger("click");
$('[data-slider=filesizes]').pwgDoubleSlider(sliders.filesizes);
if ($(".filter-filesize").hasClass("filter-filled")) {
$(".filter-filesize").removeClass("filter-filled")
$(".filter.filter-filesize .search-words").text(str_filesize_widget_label);
}
});
PS_params.filesize_min = global_params.fields.filesize_min != null ? global_params.fields.filesize_min : '';
PS_params.filesize_max = global_params.fields.filesize_max != null ? global_params.fields.filesize_max : '';
empty_filters_list.push(PS_params.filesize_min);
empty_filters_list.push(PS_params.filesize_max);
}
// Setup Height filter
if (global_params.fields.height_min != null && global_params.fields.height_max != null) {
$(".filter-height").css("display", "flex");
$(".filter-manager-controller.height").prop("checked", true);
$(".filter.filter-height .slider-info").html(sprintf(sliders.heights.text,sliders.heights.selected.min,sliders.heights.selected.max,));
$('[data-slider=heights]').pwgDoubleSlider(sliders.heights);
if( global_params.fields.height_min > 0 && global_params.fields.height_max > 0) {
$(".filter-height").addClass("filter-filled");
$(".filter.filter-height .search-words").html(sprintf(sliders.heights.text,sliders.heights.selected.min,sliders.heights.selected.max,));
}
else
{
$(".filter.filter-height .search-words").text(str_height_widget_label);
}
$(".filter-height .filter-actions .clear").on('click', function () {
updateFilters('height', 'add');
$(".filter-height").trigger("click");
$('[data-slider=heights]').pwgDoubleSlider(sliders.heights);
if ($(".filter-height").hasClass("filter-filled")) {
$(".filter-height").removeClass("filter-filled")
$(".filter.filter-height .search-words").text(str_height_widget_label);
}
});
PS_params.height_min = global_params.fields.height_min != null ? global_params.fields.height_min : '';
PS_params.height_max = global_params.fields.height_max != null ? global_params.fields.height_max : '';
empty_filters_list.push(PS_params.height_min);
empty_filters_list.push(PS_params.height_max);
}
// Setup Width filter
if (global_params.fields.width_min != null && global_params.fields.width_max != null) {
$(".filter-width").css("display", "flex");
$(".filter-manager-controller.width").prop("checked", true);
$(".filter.filter-width .slider-info").html(sprintf(sliders.widths.text,sliders.widths.selected.min,sliders.widths.selected.max,));
$('[data-slider=widths]').pwgDoubleSlider(sliders.widths);
if( global_params.fields.width_min > 0 && global_params.fields.width_max > 0) {
$(".filter-width").addClass("filter-filled");
$(".filter.filter-width .search-words").html(sprintf(sliders.widths.text,sliders.widths.selected.min,sliders.widths.selected.max,));
}
else
{
$(".filter.filter-width .search-words").text(str_width_widget_label);
}
$(".filter-width .filter-actions .clear").on('click', function () {
updateFilters('width', 'add');
$(".filter-width").trigger("click");
$('[data-slider=widths]').pwgDoubleSlider(sliders.widths);
if ($(".filter-width").hasClass("filter-filled")) {
$(".filter-width").removeClass("filter-filled")
$(".filter.filter-width .search-words").text(str_width_widget_label);
}
});
PS_params.width_min = global_params.fields.width_min != null ? global_params.fields.width_min : '';
PS_params.width_max = global_params.fields.width_max != null ? global_params.fields.width_max : '';
empty_filters_list.push(PS_params.width_min);
empty_filters_list.push(PS_params.width_max);
}
// Adapt no result message
if ($(".filter-filled").length === 0) {
$(".mcs-no-result .text .top").html(str_empty_search_top_alt);
@ -691,6 +868,210 @@ $(document).ready(function () {
}
});
/**
* Ratios widget
*/
$(".filter-ratios").on('click', function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove")) {
return;
}
$(".filter-ratios-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-ratios").addClass("show-filter-dropdown");
} else {
$(".filter-ratios").removeClass("show-filter-dropdown");
ratios_array = []
$(".ratios-option input:checked").each(function () {
ratios_array.push($(this).attr('name'));
});
global_params.fields.ratios = ratios_array;
PS_params.ratios = ratios_array.length > 0 ? ratios_array : '';
}
});
});
$(".filter-ratios .filter-validate").on("click", function () {
$(".filter-ratios").trigger("click");
performSearch(PS_params, true);
});
$(".filter-ratios .filter-actions .delete").on("click", function () {
updateFilters('ratios', 'del');
performSearch(PS_params, true);
if (!$(".filter-ratios").hasClass("filter-filled")) {
$(".filter-ratios").hide();
$(".filter-manager-controller.ratios").prop("checked", false);
}
});
/**
* Rating widget
*/
$(".filter-ratings").on('click', function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove")) {
return;
}
$(".filter-ratings-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-ratings").addClass("show-filter-dropdown");
} else {
$(".filter-ratings").removeClass("show-filter-dropdown");
ratings_array = []
$(".ratings-option input:checked").each(function () {
ratings_array.push($(this).attr('name'));
});
global_params.fields.ratings = ratings_array;
PS_params.ratings = ratings_array.length > 0 ? ratings_array : '';
}
});
});
$(".filter-ratings .filter-validate").on("click", function () {
$(".filter-ratings").trigger("click");
performSearch(PS_params, true);
});
$(".filter-ratings .filter-actions .delete").on("click", function () {
updateFilters('ratings', 'del');
performSearch(PS_params, true);
if (!$(".filter-ratings").hasClass("filter-filled")) {
$(".filter-ratings").hide();
$(".filter-manager-controller.ratings").prop("checked", false);
}
});
/**
* Filesize widget
*/
$(".filter-filesize").on('click', function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove")) {
return;
}
$(".filter-filesize-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-filesize").addClass("show-filter-dropdown");
} else {
$(".filter-filesize").removeClass("show-filter-dropdown");
}
});
});
$(".filter-filesize .filter-validate").on("click", function () {
filesize_min = Math.floor(($('input[name=filter_filesize_min]').val())*1024)
filesize_max = Math.ceil(($('input[name=filter_filesize_max]').val())*1024)
global_params.fields.filesize_min = filesize_min;
global_params.fields.filesize_max = filesize_max;
PS_params.filesize_min = filesize_min;
PS_params.filesize_max = filesize_max;
$(".filter-filesize").trigger("click");
performSearch(PS_params, true);
});
$(".filter-filesize .filter-actions .delete").on("click", function () {
updateFilters('filesize', 'del');
performSearch(PS_params, true);
if (!$(".filter-filesize").hasClass("filter-filled")) {
$(".filter-filesize").hide();
$(".filter-manager-controller.filesize").prop("checked", false);
}
});
/**
* Height widget
*/
$(".filter-height").on('click', function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove")) {
return;
}
$(".filter-height-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-height").addClass("show-filter-dropdown");
} else {
$(".filter-height").removeClass("show-filter-dropdown");
}
});
});
$(".filter-height .filter-validate").on("click", function () {
height_min = $('input[name=filter_height_min]').val()
height_max = $('input[name=filter_height_max]').val()
global_params.fields.height_min = height_min;
global_params.fields.height_max = height_max;
PS_params.height_min = height_min;
PS_params.height_max = height_max;
$(".filter-height").trigger("click");
performSearch(PS_params, true);
});
$(".filter-height .filter-actions .delete").on("click", function () {
updateFilters('height', 'del');
performSearch(PS_params, true);
if (!$(".filter-height").hasClass("filter-filled")) {
$(".filter-height").hide();
$(".filter-manager-controller.height").prop("checked", false);
}
});
/**
* Width widget
*/
$(".filter-width").on('click', function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove")) {
return;
}
$(".filter-width-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-width").addClass("show-filter-dropdown");
} else {
$(".filter-width").removeClass("show-filter-dropdown");
}
});
});
$(".filter-width .filter-validate").on("click", function () {
width_min = $('input[name=filter_width_min]').val()
width_max = $('input[name=filter_width_max]').val()
global_params.fields.width_min = width_min;
global_params.fields.width_max = width_max;
PS_params.width_min = width_min;
PS_params.width_max = width_max;
$(".filter-width").trigger("click");
performSearch(PS_params, true);
});
$(".filter-width .filter-actions .delete").on("click", function () {
updateFilters('width', 'del');
performSearch(PS_params, true);
if (!$(".filter-width").hasClass("filter-filled")) {
$(".filter-width").hide();
$(".filter-manager-controller.width").prop("checked", false);
}
});
/* Close dropdowns if you click on the screen */
// $(document).mouseup(function (e) {
// e.stopPropagation();
@ -926,6 +1307,57 @@ function updateFilters(filterName, mode) {
}
break;
case 'filesize':
if (mode == 'add') {
global_params.fields.filesize_min = '';
global_params.fields.filesize_max = '';
PS_params.filesize_min = '';
PS_params.filesize_max = '';
} else if (mode == 'del') {
delete global_params.fields.filesize_min;
delete global_params.fields.filesize_max;
delete PS_params.filesize_min;
delete PS_params.filesize_max;
}
break;
case 'height':
if (mode == 'add') {
global_params.fields.height_min = '';
global_params.fields.height_max = '';
PS_params.height_min = '';
PS_params.height_max = '';
} else if (mode == 'del') {
delete global_params.fields.height_min;
delete global_params.fields.height_max;
delete PS_params.height_min;
delete PS_params.height_max;
}
break;
case 'width':
if (mode == 'add') {
global_params.fields.width_min = '';
global_params.fields.width_max = '';
PS_params.width_min = '';
PS_params.width_max = '';
} else if (mode == 'del') {
delete global_params.fields.width_min;
delete global_params.fields.width_max;
delete PS_params.width_min;
delete PS_params.width_max;
}
break;
default:
if (mode == 'add') {
global_params.fields[filterName] = {};

View file

@ -1,3 +1,8 @@
{combine_script id='jquery.ui' load='async' path='themes/default/js/ui/minified/jquery.ui.core.min.js'}
{combine_script id='jquery.ui.slider' require='jquery.ui' load='async' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'}
{combine_css path="themes/default/js/ui/theme/jquery.ui.slider.css" order=-999}
{combine_script id='doubleSlider' load='footer' require='jquery.ui.slider' path='admin/themes/default/js/doubleSlider.js'}
{combine_script id='jquery.selectize' load='footer' path='themes/default/js/plugins/selectize.min.js'}
{combine_css path="admin/themes/default/fontello/css/animation.css" order=10} {* order 10 is required, see issue 1080 *}
{combine_script id='jquery.tipTip' load='header' path='themes/default/js/plugins/jquery.tipTip.minified.js'}
@ -25,10 +30,62 @@ str_author_widget_label = "{'Author'|@translate|escape:javascript}";
str_added_by_widget_label = "{'Added by'|@translate|escape:javascript}";
str_filetypes_widget_label = "{'File type'|@translate|escape:javascript}";
str_rating_widget_label = "{'Rating'|@translate|escape:javascript}";
str_no_rating = "{'no rate'|@translate|escape:javascript}";
str_between_rating= "{'between %d and %d'|@translate}";
str_filesize_widget_label = "{'Filesize'|@translate|escape:javascript}";
str_width_widget_label = "{'Width'|@translate|escape:javascript}";
str_height_widget_label = "{'Height'|@translate|escape:javascript}";
str_ratio_widget_label = "{'Ratio'|@translate|escape:javascript}";
str_ratios_label = [];
str_ratios_label['Portrait'] ="{'Portrait'|@translate|escape:javascript}";
str_ratios_label['square'] = "{'square'|@translate|escape:javascript}";
str_ratios_label['Landscape'] = "{'Landscape'|@translate|escape:javascript}";
str_ratios_label['Panorama'] = "{'Panorama'|@translate|escape:javascript}";
str_empty_search_top_alt = "{'Fill in the filters to start a search'|@translate|escape:javascript}";
str_empty_search_bot_alt = "{'Pre-established filters are proposed, but you can add or remove them using the "Choose filters" button.'|@translate|escape:javascript}";
const prefix_icon = 'gallery-icon-';
{*<!-- sliders config -->*}
var sliders = {
{if isset($FILESIZE)}
filesizes: {
values: [{$FILESIZE.list}],
selected: {
min: {$FILESIZE.selected.min},
max: {$FILESIZE.selected.max},
},
text: '{'between %s and %s MB'|translate|escape:'javascript'}',
},
{/if}
{if isset($HEIGHT)}
heights: {
values: [{$HEIGHT.list}],
selected: {
min: {$HEIGHT.selected.min},
max: {$HEIGHT.selected.max},
},
text: '{'between %d and %d pixels'|translate|escape:'javascript'}',
},
{/if}
{if isset($WIDTH)}
widths: {
values: [{$WIDTH.list}],
selected: {
min: {$WIDTH.selected.min},
max: {$WIDTH.selected.max},
},
text: '{'between %d and %d pixels'|translate|escape:'javascript'}',
},
{/if}
};
{/footer_script}
{combine_script id='mcs' load='async' require='jquery' path='themes/default/js/mcs.js'}
@ -68,6 +125,26 @@ const prefix_icon = 'gallery-icon-';
<input data-wid='filetypes' class="filter-manager-controller filetypes" type="checkbox"/>
<span class="mcs-icon gallery-icon-file-image">{'File type'|@translate}</span>
</label>
<label>
<input data-wid='ratios' class="filter-manager-controller ratios" type="checkbox"/>
<span class="mcs-icon gallery-icon-crop">{'Ratio'|@translate}</span>
</label>
<label>
<input data-wid='ratings' class="filter-manager-controller ratings" type="checkbox"/>
<span class="mcs-icon gallery-icon-star-1">{'Rating'|@translate}</span>
</label>
<label>
<input data-wid='filesize' class="filter-manager-controller filesize" type="checkbox"/>
<span class="mcs-icon gallery-icon-hdd">{'Filesize'|@translate}</span>
</label>
<label>
<input data-wid='height' class="filter-manager-controller height" type="checkbox"/>
<span class="mcs-icon gallery-icon-height">{'Height'|@translate}</span>
</label>
<label>
<input data-wid='width' class="filter-manager-controller width" type="checkbox"/>
<span class="mcs-icon gallery-icon-width">{'Width'|@translate}</span>
</label>
</div>
<div class="filter-manager-actions">
@ -343,6 +420,192 @@ const prefix_icon = 'gallery-icon-';
</div>
</div>
{/if}
{if isset($RATIOS)}
<div class="filter filter-ratios">
<span class="mcs-icon gallery-icon-crop filter-icon"></span>
</span><span class="search-words"></span>
<span class="filter-arrow gallery-icon-up-open"></span>
<div class="filter-form filter-ratios-form">
<div class="filter-form-title gallery-icon-crop">{'Ratio'|@translate}</div>
<div class="filter-actions">
<span class="delete mcs-icon gallery-icon-trash tiptip" title="{'Delete'|@translate}"></span>
<span class="clear mcs-icon gallery-icon-arrow-rotate-left tiptip" title="{'Clear'|@translate}"></span>
</div>
<div class="form-container">
<div class="ratios-option-container">
{foreach from=$RATIOS item=ratio key=k}
<div class="ratios-option {if 0 == $ratio}disabled{/if}">
<input type="checkbox" id="ratio-{$k}" name="{$k}" {if 0 == $ratio}disabled{/if}>
<label for="ratio-{$k}">
<span class="mcs-icon gallery-icon-checkmark checked-icon"></span>
<span class="ratio-name">{$k|translate}</span>
{if 0 != $ratio}<span class="ratio-badge">{$ratio}</span>{/if}
</label>
</div>
{/foreach}
</div>
</div>
<div class="filter-validate">
<i class="loading gallery-icon-spin6 animate-spin"></i>
<span class="validate-text">{'Validate'|@translate}</span>
</div>
</div>
</div>
{/if}
{* Add filter for rating *}
{if isset($RATING)}
<div class="filter filter-ratings">
<span class="mcs-icon mcs-icon gallery-icon-star-1 filter-icon"></span>
</span><span class="search-words"></span>
<span class="filter-arrow gallery-icon-up-open"></span>
<div class="filter-form filter-ratings-form">
<div class="filter-form-title gallery-icon-star-1">{'Rating'|@translate}</div>
<div class="filter-actions">
<span class="delete mcs-icon gallery-icon-trash tiptip" title="{'Delete'|@translate}"></span>
<span class="clear mcs-icon gallery-icon-arrow-rotate-left tiptip" title="{'Clear'|@translate}"></span>
</div>
<div class="form-container">
<div class="ratings-option-container">
<form>
{foreach from=$RATING item=rating key=k}
<div class="ratings-option {if 0 == $rating}disabled{/if}">
<input type="checkbox" id="rating-{$k}" name="{if 0 == $k}0{else}{$k}{/if}" {if 0 == $rating}disabled{/if}>
<label for="rating-{$k}">
<span class="mcs-icon gallery-icon-checkmark checked-icon"></span>
<span class="ratings-name">{if 0 == $k}{'no rate'|translate}{else}{'between %d and %d'|@translate:(intval($k)-1):$k|escape:'javascript'}{/if}</span>
{if 0 != $rating}<span class="ratings-badge">{$rating}</span>{/if}
</label>
</div>
{/foreach}
</form>
</div>
</div>
<div class="filter-validate">
<i class="loading gallery-icon-spin6 animate-spin"></i>
<span class="validate-text">{'Validate'|@translate}</span>
</div>
</div>
</div>
{/if}
{* Add filter for filesize *}
{if isset($FILESIZE)}
<div class="filter filter-filesize">
<span class="mcs-icon mcs-icon gallery-icon-hdd filter-icon"></span>
</span><span class="search-words"></span>
<span class="filter-arrow gallery-icon-up-open"></span>
<div class="filter-form filter-filesize-form">
<div class="filter-form-title mcs-icon gallery-icon-hdd">{'Filesize'|translate}</div>
<div class="filter-actions">
<span class="delete mcs-icon gallery-icon-trash tiptip" title="{'Delete'|@translate}"></span>
<span class="clear mcs-icon gallery-icon-arrow-rotate-left tiptip" data-min="{$FILESIZE.bounds.min}" data-max="{$FILESIZE.bounds.max}" title="{'Clear'|@translate}"></span>
</div>
<div class="form-container">
<div class="filesize-option-container">
<div data-slider="filesizes">
<span class="slider-info"></span>
<div class="slider-slider"></div>
<input type="hidden" data-input="min" name="filter_filesize_min" value="{$FILESIZE.selected.min}">
<input type="hidden" data-input="max" name="filter_filesize_max" value="{$FILESIZE.selected.max}">
</div>
</div>
</div>
<div class="filter-validate">
<i class="loading gallery-icon-spin6 animate-spin"></i>
<span class="validate-text">{'Validate'|@translate}</span>
</div>
</div>
</div>
{/if}
{* Add filter for Height *}
{if isset($HEIGHT)}
<div class="filter filter-height">
<span class="mcs-icon mcs-icon gallery-icon-height"></span>
<span class="search-words"></span>
<span class="filter-arrow gallery-icon-up-open"></span>
<div class="filter-form filter-height-form">
<div class="filter-form-title mcs-icon gallery-icon-heigh">
{'height'|translate}
</div>
<div class="filter-actions">
<span class="delete mcs-icon gallery-icon-trash tiptip" title="{'Delete'|@translate}"></span>
<span class="clear mcs-icon gallery-icon-arrow-rotate-left tiptip" data-min="{$HEIGHT.bounds.min}" data-max="{$HEIGHT.bounds.max}" title="{'Reset'|@translate}"></span>
</div>
<div class="form-container">
<div class="height-option-container">
<div data-slider="heights">
<span class="slider-info"></span>
<div class="slider-slider"></div>
<input type="hidden" data-input="min" name="filter_height_min" value="{$HEIGHT.selected.min}">
<input type="hidden" data-input="max" name="filter_height_max" value="{$HEIGHT.selected.max}">
</div>
</div>
</div>
<div class="filter-validate">
<i class="loading gallery-icon-spin6 animate-spin"></i>
<span class="validate-text">{'Validate'|@translate}</span>
</div>
</div>
</div>
{/if}
{* Add filter for Width *}
{if isset($WIDTH)}
<div class="filter filter-width">
<span class="mcs-icon mcs-icon gallery-icon-width"></span>
<span class="search-words"></span>
<span class="filter-arrow gallery-icon-up-open"></span>
<div class="filter-form filter-width-form">
<div class="filter-form-title mcs-icon gallery-icon-width">
{'width'|translate}
</div>
<div class="filter-actions">
<span class="delete mcs-icon gallery-icon-trash tiptip" title="{'Delete'|@translate}"></span>
<span class="clear mcs-icon gallery-icon-arrow-rotate-left tiptip" title="{'Clear'|@translate}"></span>
</div>
<div class="form-container">
<div class="width-option-container">
<div data-slider="widths">
<span class="slider-info"></span>
<div class="slider-slider"></div>
<input type="hidden" data-input="min" name="filter_width_min" value="{$WIDTH.selected.min}">
<input type="hidden" data-input="max" name="filter_width_max" value="{$WIDTH.selected.max}">
</div>
</div>
</div>
<div class="filter-validate">
<i class="loading gallery-icon-spin6 animate-spin"></i>
<span class="validate-text">{'Validate'|@translate}</span>
</div>
</div>
</div>
{/if}
<div>
<span class="mcs-icon gallery-icon-arrow-rotate-left clear-all">{'Empty filters'|@translate}</span>
</div>

30
ws.php
View file

@ -1452,6 +1452,36 @@ enabled_high, registration_date, registration_date_string, registration_date_sin
'flags' => WS_PARAM_OPTIONAL,
'info' => 'files posted within 24 hours, 7 days or 30 days or 3 months or 6 months or year NNNN. Value among 24h|7d|30d|3m|6m|yNNNN',
),
'ratios' => array(
'flags' => WS_PARAM_OPTIONAL|WS_PARAM_FORCE_ARRAY,
),
'ratings' => array(
'flags' => WS_PARAM_OPTIONAL|WS_PARAM_FORCE_ARRAY,
),
'filesize_min' => array(
'flags' => WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE,
),
'filesize_max' => array(
'flags' => WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE,
),
'height_min' => array(
'flags' => WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE,
),
'height_max' => array(
'flags' => WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE,
),
'width_min' => array(
'flags' => WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE,
),
'width_max' => array(
'flags' => WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE,
),
),
'',
$ws_functions_root . 'pwg.images.php'