Changeset 19446
- Timestamp:
- Dec 16, 2012, 3:21:10 PM (11 years ago)
- Location:
- extensions/SmartAlbums
- Files:
-
- 1 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/SmartAlbums/admin/album.php
r17677 r19446 72 72 if (isset($_POST['submitFilters'])) 73 73 { 74 if (defined('SMART_DEBUG')) 75 { 76 var_dump($_POST['filters']); 77 } 78 74 79 // test if it was a Smart Album 75 80 $query = ' … … 98 103 pwg_query('DELETE FROM '.CATEGORY_FILTERS_TABLE.' WHERE category_id = '.$cat_id.';'); 99 104 105 $inserts = array(); 100 106 foreach ($_POST['filters'] as $filter) 101 107 { 102 108 if (($filter = smart_check_filter($filter)) != false) 103 109 { 104 $query = ' 105 INSERT IGNORE INTO '.CATEGORY_FILTERS_TABLE.' 106 VALUES( 107 '.$cat_id.', 108 "'.$filter['type'].'", 109 "'.$filter['cond'].'", 110 "'.$filter['value'].'" 111 ) 112 ;'; 113 pwg_query($query); 110 $filter['category_id'] = $cat_id; 111 $inserts[] = $filter; 114 112 } 115 113 } 114 115 mass_inserts( 116 CATEGORY_FILTERS_TABLE, 117 array('category_id', 'type', 'cond', 'value'), 118 $inserts, 119 array('ignore'=>true) 120 ); 116 121 117 122 $associated_images = smart_make_associations($cat_id); … … 143 148 'name' => l10n('Date'), 144 149 'options' => array( 145 'the_post' 146 'before_post' 147 'after_post' 148 'the_taken' 149 'before_taken' 150 'after_taken' 150 'the_post' => l10n('Added on'), 151 'before_post' => l10n('Added before'), 152 'after_post' => l10n('Added after'), 153 'the_taken' => l10n('Created on'), 154 'before_taken' => l10n('Created before'), 155 'after_taken' => l10n('Created after'), 151 156 ), 152 157 ), … … 160 165 'not_begin' => l10n('Doesn\'t begin with'), 161 166 'not_end' => l10n('Doesn\'t end with'), 167 'regex' => l10n('Regular expression'), 162 168 ), 163 169 ), … … 171 177 ), 172 178 ), 179 'dimensions' => array( 180 'name' => l10n('Dimensions'), 181 'options' => array( 182 'width' => l10n('Width'), 183 'height' => l10n('Height'), 184 'ratio' => l10n('Ratio').' ('.l10n('Width').'/'.l10n('Height').')', 185 ), 186 ), 173 187 'author' => array( 174 188 'name' => l10n('Author'), … … 178 192 'not_is' => l10n('Is not'), 179 193 'not_in' => l10n('Is not in'), 194 'regex' => l10n('Regular expression'), 180 195 ), 181 196 ), … … 205 220 $template->assign('options', $options); 206 221 222 207 223 /* get filters for this album */ 208 224 $query = ' 209 225 SELECT * 210 226 FROM '.CATEGORY_FILTERS_TABLE.' 211 WHERE category_id = '.$cat_id.' 227 WHERE category_id = '.$cat_id.' 212 228 ORDER BY 213 229 type ASC, … … 216 232 $result = pwg_query($query); 217 233 234 $template->assign('filter_mode', 'and'); 235 218 236 while ($filter = pwg_db_fetch_assoc($result)) 219 237 { 220 // get tags name and id 221 if ($filter['type'] == 'tags') 238 if ($filter['type'] == 'mode') 239 { 240 $template->assign('filter_mode', $filter['value']); 241 continue; 242 } 243 else if ($filter['type'] == 'tags') 222 244 { 223 245 $query = ' 224 SELECT 225 id, 226 name 246 SELECT id, name 227 247 FROM '.TAGS_TABLE.' 228 248 WHERE id IN('.$filter['value'].') … … 230 250 $filter['value'] = get_taglist($query); 231 251 } 232 else if ($filter['type'] == 'album')233 {234 $filter['value'] = explode(',', $filter['value']);235 }236 252 237 $template->append('filters', array( 238 'TYPE' => $filter['type'], 239 'COND' => $filter['cond'], 240 'VALUE' => $filter['value'], 241 'CAPTION' => $options[ $filter['type'] ]['name'], 253 $template->append('filters', $filter); 254 } 255 256 257 /* format types */ 258 $template->assign('format_options', array( 259 'portrait' => l10n('Portrait'), 260 'square' => l10n('Square'), 261 'lanscape' => l10n('Landscape'), 262 'panorama' => l10n('Panorama'), 242 263 )); 243 }244 264 245 265 /* all tags */ 246 266 $query = ' 247 SELECT 248 id, 249 name 267 SELECT id, name 250 268 FROM '.TAGS_TABLE.' 251 269 ;'; … … 262 280 ;'; 263 281 display_select_cat_wrapper($query, array(), 'all_albums'); 282 283 // +-----------------------------------------------------------------------+ 284 // | dimensions | 285 // +-----------------------------------------------------------------------+ 286 287 $widths = array(); 288 $heights = array(); 289 $ratios = array(); 290 291 // get all width, height and ratios 292 $query = ' 293 SELECT 294 DISTINCT width, height 295 FROM '.IMAGES_TABLE.' 296 WHERE width IS NOT NULL 297 AND height IS NOT NULL 298 ;'; 299 $result = pwg_query($query); 300 301 while ($row = pwg_db_fetch_assoc($result)) 302 { 303 $widths[] = $row['width']; 304 $heights[] = $row['height']; 305 $ratios[] = floor($row['width'] * 100 / $row['height']) / 100; 306 } 307 308 $widths = array_unique($widths); 309 sort($widths); 310 311 $heights = array_unique($heights); 312 sort($heights); 313 314 $ratios = array_unique($ratios); 315 sort($ratios); 316 317 $dimensions['bounds'] = array( 318 'min_width' => $widths[0], 319 'max_width' => $widths[count($widths)-1], 320 'min_height' => $heights[0], 321 'max_height' => $heights[count($heights)-1], 322 'min_ratio' => $ratios[0], 323 'max_ratio' => $ratios[count($ratios)-1], 324 ); 325 326 // find ratio categories 327 $ratio_categories = array( 328 'portrait' => array(), 329 'square' => array(), 330 'landscape' => array(), 331 'panorama' => array(), 332 ); 333 334 foreach ($ratios as $ratio) 335 { 336 if ($ratio < 0.95) 337 { 338 $ratio_categories['portrait'][] = $ratio; 339 } 340 else if ($ratio >= 0.95 and $ratio <= 1.05) 341 { 342 $ratio_categories['square'][] = $ratio; 343 } 344 else if ($ratio > 1.05 and $ratio < 2) 345 { 346 $ratio_categories['landscape'][] = $ratio; 347 } 348 else if ($ratio >= 2) 349 { 350 $ratio_categories['panorama'][] = $ratio; 351 } 352 } 353 354 foreach (array_keys($ratio_categories) as $ratio_category) 355 { 356 if (count($ratio_categories[$ratio_category]) > 0) 357 { 358 $dimensions['ratio_'.$ratio_category] = array( 359 'min' => $ratio_categories[$ratio_category][0], 360 'max' => $ratio_categories[$ratio_category][count($ratio_categories[$ratio_category]) - 1] 361 ); 362 } 363 } 364 365 $template->assign('dimensions', $dimensions); 264 366 265 367 /* get image number */ … … 289 391 'level_options' => get_privacy_level_options(), 290 392 'F_ACTION' => $self_url, 291 'CATEGORIES_NAV' => get_cat_display_name_cache( 292 $category['uppercats'], 293 SMART_ADMIN.'-album&cat_id=' 294 ), 393 'CATEGORIES_NAV' => get_cat_display_name_cache($category['uppercats'], SMART_ADMIN.'-album&cat_id='), 295 394 )); 296 395 -
extensions/SmartAlbums/admin/cat_list.php
r16104 r19446 21 21 permalink, 22 22 dir, 23 rank, 24 status 23 smart_update 25 24 FROM '.CATEGORIES_TABLE.' AS cat 26 25 INNER JOIN '.CATEGORY_FILTERS_TABLE.' AS cf … … 124 123 // +-----------------------------------------------------------------------+ 125 124 126 // get the categories containing images directly 127 $categories_with_images = array(); 125 $categories_count_images = array(); 128 126 if ( count($categories) ) 129 127 { 130 128 $query = ' 131 SELECT DISTINCT category_id 129 SELECT 130 category_id, 131 COUNT(image_id) AS total_images 132 132 FROM '.IMAGE_CATEGORY_TABLE.' 133 WHERE category_id IN ('.implode(',', array_keys($categories)).')'; 134 $categories_with_images = array_flip( array_from_query($query, 'category_id') ); 133 WHERE category_id IN ('.implode(',', array_keys($categories)).') 134 GROUP BY category_id 135 ;'; 136 $categories_count_images = simple_hash_from_query($query, 'category_id', 'total_images'); 135 137 } 136 138 … … 141 143 $tpl_cat = 142 144 array( 143 'NAME' => get_cat_display_name_from_id($category['id'], $base_url.'album-'), 144 'ID' => $category['id'], 145 'RANK' => $category['rank']*10, 145 'NAME' => get_cat_display_name_from_id($category['id'], $base_url.'album-'), 146 'ID' => $category['id'], 147 'IMG_COUNT' => !empty($categories_count_images[ $category['id'] ]) ? $categories_count_images[ $category['id'] ] : 0, 148 'LAST_UPDATE' => format_date($category['smart_update'], true), 146 149 147 'U_JUMPTO' => make_index_url( 148 array( 149 'category' => $category 150 ) 151 ), 152 153 'U_EDIT' => $base_url.'album-'.$category['id'], 154 'U_DELETE' => $self_url.'&delete='.$category['id'].'&pwg_token='.get_pwg_token(), 155 'U_SMART' => $self_url.'&smart_generate='.$category['id'], 150 'U_JUMPTO' => make_index_url(array('category' => $category)), 151 'U_EDIT' => SMART_ADMIN.'-album&cat_id='.$category['id'], 152 'U_DELETE' => $self_url.'&delete='.$category['id'].'&pwg_token='.get_pwg_token(), 153 'U_SMART' => $self_url.'&smart_generate='.$category['id'], 156 154 ); 157 158 if ( array_key_exists($category['id'], $categories_with_images) )159 {160 $tpl_cat['U_MANAGE_ELEMENTS'] =161 $base_url.'batch_manager&cat='.$category['id'];162 }163 155 164 156 $template->append('categories', $tpl_cat); -
extensions/SmartAlbums/admin/config.php
r16939 r19446 5 5 if (isset($_POST['submit'])) 6 6 { 7 $conf['SmartAlbums']['update_on_upload'] = isset($_POST['update_on_upload']); 8 $conf['SmartAlbums']['smart_is_forbidden'] = isset($_POST['smart_is_forbidden']); 7 if ( $_POST['update_timeout'] == 0 or !preg_match('#^[0-9.]+$#', $_POST['update_timeout']) ) 8 { 9 array_push($page['errors'], l10n('Invalid number of days')); 10 $_POST['update_timeout'] = $conf['SmartAlbums']['update_timeout']; 11 } 12 13 $conf['SmartAlbums'] = array( 14 'show_list_messages' => $conf['SmartAlbums']['show_list_messages'], 15 'last_update' => $conf['SmartAlbums']['last_update'], 16 'update_on_upload' => isset($_POST['update_on_upload']), 17 'update_on_date' => isset($_POST['update_on_date']), 18 'update_timeout' => $_POST['update_timeout'], 19 'smart_is_forbidden' => isset($_POST['smart_is_forbidden']), 20 ); 9 21 10 22 conf_update_param('SmartAlbums', serialize($conf['SmartAlbums'])); -
extensions/SmartAlbums/admin/template/album.tpl
r17677 r19446 1 1 {combine_css path=$SMART_PATH|@cat:"admin/template/style.css"} 2 2 {combine_script id='sprintf' load='footer' path=$SMART_PATH|@cat:"admin/template/sprintf.js"} 3 3 {include file='include/datepicker.inc.tpl'} 4 {combine_script id='jquery.tokeninput' load='async' require='jquery' path='themes/default/js/plugins/jquery.tokeninput.js'} 5 4 {combine_script id='jquery.tokeninput' load='footer' require='jquery' path='themes/default/js/plugins/jquery.tokeninput.js'} 6 5 {combine_css path="themes/default/js/plugins/chosen.css"} 7 6 {combine_script id='jquery.chosen' load='footer' path='themes/default/js/plugins/chosen.jquery.min.js'} 8 9 {footer_script require='jquery.tokeninput,jquery.chosen'} 10 var lang = new Array(); 11 var options = new Array(); 12 13 {foreach from=$options item=details key=mode} 14 lang['{$mode}_filter'] = '{$details.name|escape:javascript}'; 15 {capture assign="option_content"}{html_options options=$details.options}{/capture} 16 options['{$mode}'] = "{$option_content|escape:javascript}"; 17 {/foreach} 18 19 lang['Select albums...'] = '{'Select albums...'|@translate}'; 20 lang['For "Is (not) in", separate each author by a comma'] = '{'For "Is (not) in", separate each author by a comma'|@translate|escape:javascript}'; 21 lang['remove this filter'] = '{'remove this filter'|@translate|escape:javascript}'; 22 {capture assign="option_content"}{html_options options=$level_options selected=0}{/capture} 23 options['level_options'] = "{$option_content|escape:javascript}"; 24 {capture assign="option_content"}{html_options options=$all_albums selected=0}{/capture} 25 options['album_options'] = "{$option_content|escape:javascript}"; 26 27 {literal} 7 {combine_css path="themes/default/js/ui/theme/jquery.ui.slider.css"} 8 {combine_script id='jquery.ui.slider' require='jquery.ui' load='footer' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'} 9 10 {footer_script}{literal} 11 var count=0; 12 var limit_count=0; 13 var level_count=0; 14 15 // MAIN EVENT HANDLERS 28 16 $('#addFilter').change(function() { 29 17 add_filter($(this).attr('value')); … … 32 20 33 21 $('#removeFilters').click(function() { 34 $('#filter List li').each(function() {22 $('#filtersList li').each(function() { 35 23 $(this).remove(); 36 24 }); 25 26 limit_level=0; 27 level_count=0; 37 28 return false; 38 29 }); … … 50 41 51 42 52 function add_filter(type) { 53 // add line 54 $('<li class="filter_'+ type +'" id="filter_'+ i +'"></li>').appendTo('#filterList'); 55 56 //set content 57 content = 58 ' <span class="filter-title">'+ 59 ' <a href="#" class="removeFilter" title="'+ lang['remove this filter'] +'"><span>[x]</span></a>'+ 60 ' <input type="hidden" name="filters['+ i +'][type]" value="'+ type +'"/> '+ lang[type +'_filter'] + 61 '</span>'+ 62 ' <span class="filter-cond">'+ 63 ' <select name="filters['+ i +'][cond]">'+ options[type] +'</select>'+ 64 '</span>'+ 65 ' <span class="filter-value">'; 66 67 if (type == 'tags') { 68 content+= ' <select name="filters['+ i +'][value]" class="tagSelect"></select>'; 69 } 70 else if (type == 'album') { 71 content+= ' <select name="filters['+ i +'][value][]" class="albumSelect" multiple="multiple" data-placeholder="'+ lang['Select albums...'] +'">'+ options['album_options'] +'</select>'; 43 // ADD FILTER FUNCTIONS 44 function add_filter(type, cond, value) { 45 count++; 46 47 content = $("#filtersRepo #filter_"+type).html().replace(/iiii/g, count); 48 $block = $(content); 49 $("#filtersList").append($block); 50 51 if (cond) { 52 select_cond($block, type, cond); 53 } 54 55 if (value) { 56 if (type == "tags") { 57 $block.find(".filter-value .tagSelect").html(value); 58 } 59 else if (type == "album") { 60 select_options($block, value); 61 } 62 else if (type == "level") { 63 select_options($block, value); 64 } 65 else if (type != "dimensions") { 66 $block.find(".filter-value input").val(value); 67 } 68 } 69 70 init_jquery_handlers($block); 71 72 if (type == "dimensions") { 73 select_dimensions($block, cond, value); 74 } 75 76 if (type == 'limit') { 77 limit_count=1; 78 $("#addFilter option[value='limit']").attr('disabled','disabled'); 72 79 } 73 80 else if (type == 'level') { 74 content+= ' <select name="filters['+ i +'][value]">'+ options['level_options'] +'</select>'; 81 level_count=1; 82 $("#addFilter option[value='level']").attr('disabled','disabled'); 83 } 84 } 85 86 function select_cond($block, type, cond) { 87 $block.find(".filter-cond option").removeAttr('selected'); 88 $block.find(".filter-cond option[value='"+cond+"']").attr('selected', 'selected'); 89 } 90 91 function select_dimensions($block, cond, value) { 92 if (!cond) cond = 'width'; 93 94 $block.find(".filter-value span:not(.filter_dimension_info)").hide(); 95 $block.find(".filter-value .dimension_"+cond).show(); 96 97 if (value) { 98 values = value.split(','); 75 99 } 76 100 else { 77 content+= ' <input type="text" name="filters['+ i +'][value]" size="30"/>'; 78 } 79 80 if (type == 'author') { 81 content+= ' <i>'+ lang['For "Is (not) in", separate each author by a comma'] +'</i>'; 82 } 83 84 content+= '</span>'; 85 86 $('#filter_'+ i).html(content); 87 88 // reinit handlers 89 init_jquery_handlers(); 90 i++; 91 } 92 93 function init_jquery_handlers() { 94 $('.removeFilter').click(function() { 101 values = $block.find(".filter_dimension_"+cond+"_slider").slider("values"); 102 } 103 $block.find(".filter_dimension_"+cond+"_slider").slider("values", values); 104 } 105 106 function select_options($block, value) { 107 values = value.split(','); 108 for (j in values) { 109 $block.find(".filter-value option[value='"+ values[j] +"']").attr('selected', 'selected'); 110 } 111 } 112 113 114 // DECLARE JQUERY PLUGINS AND VERSATILE HANDLERS 115 function init_jquery_handlers($block) { 116 // remove filter 117 $block.find(".removeFilter").click(function() { 118 type = $(this).next("input").val(); 119 if (type == 'limit') { 120 limit_count=1; 121 $("#addFilter option[value='limit']").removeAttr('disabled'); 122 } 123 else if (type == 'level') { 124 level_count=1; 125 $("#addFilter option[value='level']").removeAttr('disabled'); 126 } 127 95 128 $(this).parents('li').remove(); 96 129 return false; 97 130 }); 98 131 99 $('.filter_date input[type="text"]').each(function() { 100 $(this).datepicker({dateFormat:'yy-mm-dd', firstDay:1}); 101 }); 102 103 jQuery(".tagSelect").tokenInput( 104 {/literal} 105 [{foreach from=$all_tags item=tag name=tags}{ldelim}"name":"{$tag.name|@escape:'javascript'}","id":"{$tag.id}"{rdelim}{if !$smarty.foreach.tags.last},{/if}{/foreach}], 106 {ldelim} 107 hintText: '{'Type in a search term'|@translate}', 108 noResultsText: '{'No results'|@translate}', 109 searchingText: '{'Searching...'|@translate}', 110 animateDropdown: false, 111 preventDuplicates: true, 112 allowCreation: false 113 {literal} 114 } 115 ); 116 117 jQuery(".albumSelect").chosen(); 132 // date filter 133 if ($block.hasClass('filter_date')) { 134 $block.find("input[type='text']").each(function() { 135 $(this).datepicker({dateFormat:'yy-mm-dd', firstDay:1}); 136 }); 137 } 138 139 // tags filter 140 if ($block.hasClass('filter_tags')) { 141 $block.find(".tagSelect").tokenInput( 142 {/literal} 143 [{foreach from=$all_tags item=tag name=tags}{ldelim}"name":"{$tag.name|@escape:'javascript'}","id":"{$tag.id}"{rdelim}{if !$smarty.foreach.tags.last},{/if}{/foreach}], 144 {ldelim} 145 hintText: '{'Type in a search term'|@translate}', 146 noResultsText: '{'No results'|@translate}', 147 searchingText: '{'Searching...'|@translate}', 148 animateDropdown: false, 149 preventDuplicates: true, 150 allowCreation: false 151 {literal} 152 }); 153 } 154 155 // album filter 156 if ($block.hasClass('filter_album')) { 157 $block.find(".albumSelect").chosen(); 158 } 159 160 // dimension filter 161 if ($block.hasClass('filter_dimensions')) { 162 $block.find(".filter-cond select").change(function() { 163 select_dimensions($block, $(this).attr("value")); 164 }); 165 {/literal} 166 167 $block.find(".filter_dimension_width_slider").slider({ldelim} 168 range: true, 169 min: {$dimensions.bounds.min_width}, 170 max: {$dimensions.bounds.max_width}, 171 values: [{$dimensions.bounds.min_width}, {$dimensions.bounds.max_width}], 172 slide: function(event, ui) {ldelim} 173 change_dimension_info($block, ui.values, "{'between %d and %d pixels'|@translate}"); 174 }, 175 change: function(event, ui) {ldelim} 176 change_dimension_info($block, ui.values, "{'between %d and %d pixels'|@translate}"); 177 } 178 }); 179 180 $block.find(".filter_dimension_height_slider").slider({ldelim} 181 range: true, 182 min: {$dimensions.bounds.min_height}, 183 max: {$dimensions.bounds.max_height}, 184 values: [{$dimensions.bounds.min_height}, {$dimensions.bounds.max_height}], 185 slide: function(event, ui) {ldelim} 186 change_dimension_info($block, ui.values, "{'between %d and %d pixels'|@translate}"); 187 }, 188 change: function(event, ui) {ldelim} 189 change_dimension_info($block, ui.values, "{'between %d and %d pixels'|@translate}"); 190 } 191 }); 192 193 $block.find(".filter_dimension_ratio_slider").slider({ldelim} 194 range: true, 195 step: 0.01, 196 min: {$dimensions.bounds.min_ratio}, 197 max: {$dimensions.bounds.max_ratio}, 198 values: [{$dimensions.bounds.min_ratio}, {$dimensions.bounds.max_ratio}], 199 slide: function(event, ui) {ldelim} 200 change_dimension_info($block, ui.values, "{'between %.2f and %.2f'|@translate}"); 201 }, 202 change: function(event, ui) {ldelim} 203 change_dimension_info($block, ui.values, "{'between %.2f and %.2f'|@translate}"); 204 } 205 }); 206 {literal} 207 208 $block.find("a.dimensions-choice").click(function() { 209 $block.find(".filter_dimension_"+ $(this).data("type") +"_slider").slider("values", 210 [$(this).data("min"), $(this).data("max")] 211 ); 212 }); 213 } 214 } 215 216 217 // GENERAL FUNCTIONS 218 function change_dimension_info($block, values, text) { 219 $block.find("input[name$='[value][min]']").val(values[0]); 220 $block.find("input[name$='[value][max]']").val(values[1]); 221 $block.find(".filter_dimension_info").html(sprintf(text, values[0], values[1])); 118 222 } 119 223 … … 136 240 } 137 241 } 138 139 init_jquery_handlers();140 242 {/literal} 243 141 244 {if isset($new_smart)}doBlink('.new_smart', 0, 3);{/if} 142 245 {/footer_script} 246 143 247 144 248 <div class="titrePage"> … … 153 257 <legend>{'Filters'|@translate}</legend> 154 258 155 <ul id="filterList"> 156 {counter start=0 assign=i} 157 {foreach from=$filters item=filter} 158 <li class="filter_{$filter.TYPE}" id="filter_{$i}"> 159 <span class="filter-title"> 160 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 161 <input type="hidden" name="filters[{$i}][type]" value="{$filter.TYPE}"/> 162 {$filter.CAPTION} 163 </span> 164 165 <span class="filter-cond"> 166 <select name="filters[{$i}][cond]"> 167 {html_options options=$options[$filter.TYPE].options selected=$filter.COND} 168 </select> 169 </span> 170 171 <span class="filter-value"> 172 {if $filter.TYPE == 'tags'} 173 <select name="filters[{$i}][value]" class="tagSelect"> 174 {foreach from=$filter.VALUE item=tag} 175 <option value="{$tag.id}" class="selected">{$tag.name}</option> 176 {/foreach} 177 </select> 178 {elseif $filter.TYPE == 'album'} 179 <select name="filters[{$i}][value][]" class="albumSelect" multiple="multiple" data-placeholder="{'Select albums...'|@translate}"> 180 {html_options options=$all_albums selected=$filter.VALUE} 181 </select> 182 {elseif $filter.TYPE == 'level'} 183 <select name="filters[{$i}][value]"> 184 {html_options options=$level_options selected=$filter.VALUE} 185 </select> 186 {else} 187 <input type="text" name="filters[{$i}][value]" value="{$filter.VALUE}" size="30"/> 188 {/if} 189 {if $filter.TYPE == 'author'} 190 <i>{'For "Is (not) in", separate each author by a comma'|@translate}</i> 191 {/if} 192 </span> 193 </li> 194 {counter} 195 {/foreach} 259 <ul id="filtersList"> 260 {foreach from=$filters item=filter}{strip} 261 {if $filter.type == 'tags'} 262 {capture assign='value'}{foreach from=$filter.value item=tag}<option value="{$tag.id}" class="selected">{$tag.name}</option>{/foreach}{/capture} 263 {else} 264 {assign var='value' value=$filter.value} 265 {/if} 196 266 197 {footer_script}var i={$i};{/footer_script} 267 {if $filter.type == 'limit'} 268 {footer_script} 269 limit_count=1; 270 $("#addFilter option[value='limit']").attr('disabled','disabled'); 271 {/footer_script} 272 {elseif $filter.type == 'level'} 273 {footer_script} 274 level_count=1; 275 $("#addFilter option[value='level']").attr('disabled','disabled'); 276 {/footer_script} 277 {/if} 278 279 {footer_script}add_filter('{$filter.type}', '{$filter.cond}', '{$value|escape:javascript}');{/footer_script} 280 {/strip}{/foreach} 198 281 </ul> 199 282 283 <div> 284 <b>{'Mode'|@translate} :</b> 285 <label><input type="radio" name="filters[0][value]" value="and" {if $filter_mode=='and'}checked="checked"{/if}> AND</label> 286 <label><input type="radio" name="filters[0][value]" value="or" {if $filter_mode=='or'}checked="checked"{/if}> OR</label> 287 <input type="hidden" name="filters[0][type]" value="mode"> 288 <input type="hidden" name="filters[0][cond]" value="mode"> 289 </div> 290 200 291 <p class="actionButtons"> 201 <select id="addFilter"> 202 <option value="-1">{'Add a filter'|@translate}</option> 203 <option disabled="disabled">------------------</option> 204 <option value="tags">{'Tags'|@translate}</option> 205 <option value="date">{'Date'|@translate}</option> 206 <option value="name">{'Photo name'|@translate}</option> 207 <option value="album">{'Album'|@translate}</option> 208 <option value="author">{'Author'|@translate}</option> 209 <option value="hit">{'Hits'|@translate}</option> 210 <option value="rating_score">{'Rating score'|@translate}</option> 211 <option value="level">{'Privacy level'|@translate}</option> 212 <option value="limit">{'Max. number of photos'|@translate}</option> 213 </select> 214 <a id="removeFilters">{'Remove all filters'|@translate}</a> 215 {if isset($new_smart)}<span class="new_smart">{'Add filters here'|@translate}</span>{/if} 292 <select id="addFilter"> 293 <option value="-1">{'Add a filter'|@translate}</option> 294 <option disabled="disabled">------------------</option> 295 <option value="tags">{'Tags'|@translate}</option> 296 <option value="date">{'Date'|@translate}</option> 297 <option value="name">{'Photo name'|@translate}</option> 298 <option value="album">{'Album'|@translate}</option> 299 <option value="dimensions">{'Dimensions'|@translate}</option> 300 <option value="author">{'Author'|@translate}</option> 301 <option value="hit">{'Hits'|@translate}</option> 302 <option value="rating_score">{'Rating score'|@translate}</option> 303 <option value="level">{'Privacy level'|@translate}</option> 304 <option value="limit">{'Max. number of photos'|@translate}</option> 305 </select> 306 <a id="removeFilters">{'Remove all filters'|@translate}</a> 307 {if isset($new_smart)}<span class="new_smart">{'Add filters here'|@translate}</span>{/if} 216 308 </p> 217 309 </fieldset> 218 310 219 311 <p class="actionButtons" id="applyFilterBlock"> 220 312 <input class="submit" type="submit" value="{'Submit'|@translate}" name="submitFilters"/> … … 225 317 </form> 226 318 </div> 319 320 <div id="filtersRepo" style="display:none;"> 321 <!-- tags --> 322 <div id="filter_tags"> 323 <li id="filter_iiii" class="filter_tags"> 324 <span class="filter-title"> 325 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 326 <input type="hidden" name="filters[iiii][type]" value="tags"/> 327 {$options.tags.name} 328 </span> 329 330 <span class="filter-cond"> 331 <select name="filters[iiii][cond]"> 332 {html_options options=$options.tags.options} 333 </select> 334 </span> 335 336 <span class="filter-value"> 337 <select name="filters[iiii][value]" class="tagSelect"> 338 </select> 339 </span> 340 </li> 341 </div> 342 343 <!-- date --> 344 <div id="filter_date"> 345 <li id="filter_iiii" class="filter_date"> 346 <span class="filter-title"> 347 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 348 <input type="hidden" name="filters[iiii][type]" value="date"/> 349 {$options.date.name} 350 </span> 351 352 <span class="filter-cond"> 353 <select name="filters[iiii][cond]"> 354 {html_options options=$options.date.options} 355 </select> 356 </span> 357 358 <span class="filter-value"> 359 <input type="text" name="filters[iiii][value]" size="30"/> 360 </span> 361 </li> 362 </div> 363 364 <!-- name --> 365 <div id="filter_name"> 366 <li id="filter_iiii" class="filter_name"> 367 <span class="filter-title"> 368 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 369 <input type="hidden" name="filters[iiii][type]" value="name"/> 370 {$options.name.name} 371 </span> 372 373 <span class="filter-cond"> 374 <select name="filters[iiii][cond]"> 375 {html_options options=$options.name.options} 376 </select> 377 </span> 378 379 <span class="filter-value"> 380 <input type="text" name="filters[iiii][value]" size="30"/> 381 </span> 382 </li> 383 </div> 384 385 <!-- album --> 386 <div id="filter_album"> 387 <li id="filter_iiii" class="filter_album"> 388 <span class="filter-title"> 389 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 390 <input type="hidden" name="filters[iiii][type]" value="album"/> 391 {$options.album.name} 392 </span> 393 394 <span class="filter-cond"> 395 <select name="filters[iiii][cond]"> 396 {html_options options=$options.album.options} 397 </select> 398 </span> 399 400 <span class="filter-value"> 401 <select name="filters[iiii][value][]" class="albumSelect" multiple="multiple" data-placeholder="{'Select albums...'|@translate}"> 402 {html_options options=$all_albums} 403 </select> 404 </span> 405 </li> 406 </div> 407 408 <!-- dimensions --> 409 <div id="filter_dimensions"> 410 <li id="filter_iiii" class="filter_dimensions"> 411 <span class="filter-title"> 412 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 413 <input type="hidden" name="filters[iiii][type]" value="dimensions"/> 414 {$options.dimensions.name} 415 </span> 416 417 <span class="filter-cond"> 418 <select name="filters[iiii][cond]"> 419 {html_options options=$options.dimensions.options} 420 </select> 421 </span> 422 423 <span class="filter-value"> 424 <span class="filter_dimension_info"></span> 425 <span class="dimension_width"> 426 | <a class="dimensions-choice" data-type="width" data-min="{$dimensions.bounds.min_width}" data-max="{$dimensions.bounds.max_width}">{'Reset'|@translate}</a> 427 <div class="filter_dimension_width_slider"></div> 428 </span> 429 430 <span class="filter-value dimension_height"> 431 | <a class="dimensions-choice" data-type="height" data-min="{$dimensions.bounds.min_height}" data-max="{$dimensions.bounds.max_height}">{'Reset'|@translate}</a> 432 <div class="filter_dimension_height_slider"></div> 433 </span> 434 435 <span class="filter-value dimension_ratio"> 436 {if isset($dimensions.ratio_portrait)} 437 | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_portrait.min}" data-max="{$dimensions.ratio_portrait.max}">{'Portrait'|@translate}</a> 438 {/if} 439 {if isset($dimensions.ratio_square)} 440 | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_square.min}" data-max="{$dimensions.ratio_square.max}">{'square'|@translate}</a> 441 {/if} 442 {if isset($dimensions.ratio_landscape)} 443 | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_landscape.min}" data-max="{$dimensions.ratio_landscape.max}">{'Landscape'|@translate}</a> 444 {/if} 445 {if isset($dimensions.ratio_panorama)} 446 | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_panorama.min}" data-max="{$dimensions.ratio_panorama.max}">{'Panorama'|@translate}</a> 447 {/if} 448 | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.bounds.min_ratio}" data-max="{$dimensions.bounds.max_ratio}">{'Reset'|@translate}</a> 449 <div class="filter_dimension_ratio_slider"></div> 450 </span> 451 </span> 452 453 <input type="hidden" name="filters[iiii][value][min]" value=""> 454 <input type="hidden" name="filters[iiii][value][max]" value=""> 455 </li> 456 </div> 457 458 <!-- author --> 459 <div id="filter_author"> 460 <li id="filter_iiii" class="filter_author"> 461 <span class="filter-title"> 462 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 463 <input type="hidden" name="filters[iiii][type]" value="author"/> 464 {$options.author.name} 465 </span> 466 467 <span class="filter-cond"> 468 <select name="filters[iiii][cond]"> 469 {html_options options=$options.author.options} 470 </select> 471 </span> 472 473 <span class="filter-value"> 474 <input type="text" name="filters[iiii][value]" size="30"/> 475 <i>{'For "Is (not) in", separate each author by a comma'|@translate}</i> 476 </span> 477 </li> 478 </div> 479 480 <!-- hit --> 481 <div id="filter_hit"> 482 <li id="filter_iiii" class="filter_hit"> 483 <span class="filter-title"> 484 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 485 <input type="hidden" name="filters[iiii][type]" value="hit"/> 486 {$options.hit.name} 487 </span> 488 489 <span class="filter-cond"> 490 <select name="filters[iiii][cond]"> 491 {html_options options=$options.hit.options} 492 </select> 493 </span> 494 495 <span class="filter-value"> 496 <input type="text" name="filters[iiii][value]" size="5"/> 497 </span> 498 </li> 499 </div> 500 501 <!-- rating_score --> 502 <div id="filter_rating_score"> 503 <li id="filter_iiii" class="filter_rating_score"> 504 <span class="filter-title"> 505 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 506 <input type="hidden" name="filters[iiii][type]" value="rating_score"/> 507 {$options.rating_score.name} 508 </span> 509 510 <span class="filter-cond"> 511 <select name="filters[iiii][cond]"> 512 {html_options options=$options.rating_score.options} 513 </select> 514 </span> 515 516 <span class="filter-value"> 517 <input type="text" name="filters[iiii][value]" size="5"/> 518 </span> 519 </li> 520 </div> 521 522 <!-- level --> 523 <div id="filter_level"> 524 <li id="filter_iiii" class="filter_level"> 525 <span class="filter-title"> 526 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 527 <input type="hidden" name="filters[iiii][type]" value="level"/> 528 {$options.level.name} 529 </span> 530 531 <input type="hidden" name="filters[iiii][cond]" value="level"/> 532 533 <span class="filter-value"> 534 <select name="filters[iiii][value]"> 535 {html_options options=$level_options} 536 </select> 537 </span> 538 </li> 539 </div> 540 541 <!-- limit --> 542 <div id="filter_limit"> 543 <li id="filter_iiii" class="filter_limit"> 544 <span class="filter-title"> 545 <a href="#" class="removeFilter" title="{'remove this filter'|@translate}"><span>[x]</span></a> 546 <input type="hidden" name="filters[iiii][type]" value="limit"/> 547 {$options.limit.name} 548 </span> 549 550 <input type="hidden" name="filters[iiii][cond]" value="limit"/> 551 552 <span class="filter-value"> 553 <input type="text" name="filters[iiii][value]" size="5"/> 554 </span> 555 </li> 556 </div> 557 </div> -
extensions/SmartAlbums/admin/template/cat_list.tpl
r16104 r19446 60 60 <strong><a href="{$category.U_CHILDREN}" title="{'manage sub-albums'|@translate}">{$category.NAME}</a></strong> 61 61 <img src="{$SMART_PATH}admin/template/lightning.png"> 62 {'%d photos'|@translate|sprintf:$category.IMG_COUNT} 62 63 </p> 63 64 64 65 <p class="albumActions"> 65 66 <a href="{$category.U_EDIT}">{'Edit'|@translate}</a> 66 | <a href="{$category.U_SMART}">{'Regenerate photos list of this SmartAlbum'|@translate}</a> 67 {if isset($category.U_MANAGE_ELEMENTS) } 68 | <a href="{$category.U_MANAGE_ELEMENTS}">{'manage album photos'|@translate}</a> 69 {/if} 67 | <a href="{$category.U_SMART}" title="{$category.LAST_UPDATE}">{'Regenerate photos list of this SmartAlbum'|@translate}</a> 70 68 {if isset($category.U_DELETE) } 71 69 | <a href="{$category.U_DELETE}" onclick="return confirm('{'Are you sure?'|@translate|@escape:javascript}');">{'delete album'|@translate}</a> -
extensions/SmartAlbums/admin/template/config.tpl
r16939 r19446 23 23 24 24 <div class="titrePage"> 25 25 <h2>SmartAlbums</h2> 26 26 </div> 27 27 28 28 <form method="post" action="" class="properties"> 29 30 <ul> 31 29 <fieldset id="commentsConf"> 30 <ul> 31 <li> 32 32 <label> 33 33 <input type="checkbox" name="update_on_upload" value="true" {if $update_on_upload}checked="checked"{/if}/> … … 35 35 <a class="showInfo" title="{'can cause slowdowns'|@translate}">i</a> 36 36 </label> 37 </li> 37 </li> 38 <li> 39 <label> 40 <input type="checkbox" name="update_on_date" value="true" {if $update_on_date}checked="checked"{/if}/> 41 {assign var=input value='<input type="text" name="update_timeout" size="2" value="'|cat:$update_timeout|cat:'"/>'} 42 <b>{'Update albums every %s days'|@translate|sprintf:$input}</b> 43 </label> 44 </li> 38 45 <li> 39 46 <label> … … 42 49 <a class="showInfo" title="{'SmartAlbums are considered private for everyone, and a user can see it\'s content only if available in another album he has access to.'|@translate}">i</a> 43 50 </label> 44 45 46 47 48 51 </li> 52 </ul> 53 </fieldset> 54 55 <p class="formButtons"><input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" /></p> 49 56 </form> -
extensions/SmartAlbums/admin/template/style.css
r17677 r19446 3 3 vertical-align:bottom; 4 4 } 5 #batchManagerGlobal #filter List li.token-input-token {5 #batchManagerGlobal #filtersList li.token-input-token { 6 6 margin-bottom:0px !important; 7 7 padding-top:0; 8 8 } 9 #batchManagerGlobal #filter List li.token-input-input-token {9 #batchManagerGlobal #filtersList li.token-input-input-token { 10 10 margin-bottom:-3px !important; 11 } 12 13 #batchManagerGlobal .filter_dimensions .ui-slider-horizontal { 14 margin: 5px 0 10px; 15 width: 500px; 11 16 } 12 17 … … 19 24 } 20 25 21 #filter List li {26 #filtersList li { 22 27 padding:2px; 23 28 border-bottom:1px dotted rgba(100, 100, 100, 0.5); 29 display:block; 24 30 } 25 #filter List lispan {31 #filtersList li>span { 26 32 display:inline-block; 27 33 } 28 #filter List li span * {34 #filtersList li span * { 29 35 vertical-align:middle; 30 36 } … … 39 45 .filter-cond { 40 46 width:220px; 41 }42 43 .filter_limit .filter-cond, .filter_level .filter-cond {44 display:none !important;45 47 } 46 48 -
extensions/SmartAlbums/include/functions.inc.php
r17677 r19446 29 29 ); 30 30 } 31 mass_inserts _ignore(31 mass_inserts( 32 32 IMAGE_CATEGORY_TABLE, 33 33 array_keys($datas[0]), 34 $datas 34 $datas, 35 array('ignore'=>true) 35 36 ); 36 37 } … … 49 50 set_random_representant(array($cat_id)); 50 51 } 52 53 $query = ' 54 UPDATE '.CATEGORIES_TABLE.' 55 SET smart_update = NOW() 56 WHERE id = '.$cat_id.' 57 ;'; 58 pwg_query($query); 51 59 52 60 return $images; … … 64 72 if ( defined('SMART_NOT_UPDATE') OR !$conf['SmartAlbums']['update_on_upload'] ) return; 65 73 66 / * get categories with smart filters */74 // get categories with smart filters 67 75 $query = ' 68 76 SELECT DISTINCT id … … 72 80 ;'; 73 81 74 / * regenerate photo list */82 // regenerate photo list 75 83 $smart_cats = array_from_query($query, 'id'); 76 84 array_map('smart_make_associations', $smart_cats); … … 115 123 return array(); 116 124 } 117 125 126 $mode = 'and'; 127 118 128 /* build constrains */ 119 129 ## generate 'join', 'where' arrays and 'limit' string to create the SQL query … … 249 259 $where[] = 'name NOT LIKE "%'.$filter['value'].'"'; 250 260 break; 261 case 'regex': 262 $where[] = 'name REGEXP "'.$filter['value'].'"'; 263 break; 251 264 } 252 265 … … 327 340 } 328 341 342 // dimensions 343 case 'dimensions': 344 { 345 $filter['value'] = explode(',', $filter['value']); 346 347 switch ($filter['cond']) 348 { 349 case 'width': 350 $where[] = 'width >= '.$filter['value'][0].' AND width <= '.$filter['value'][1]; 351 break; 352 case 'height': 353 $where[] = 'height >= '.$filter['value'][0].' AND height <= '.$filter['value'][1]; 354 break; 355 case 'ratio': 356 $where[] = 'width/height >= '.$filter['value'][0].' AND width/height < '.($filter['value'][1]+0.01); 357 break; 358 } 359 } 360 329 361 // author 330 362 case 'author': … … 348 380 $where[] = 'author NOT IN('.$filter['value'].')'; 349 381 break; 382 case 'regex': 383 $where[] = 'author REGEXP "'.$filter['value'].'"'; 384 break; 350 385 } 351 386 … … 396 431 { 397 432 $limit = '0, '.$filter['value']; 433 break; 434 } 435 436 // mode 437 case 'mode': 438 { 439 $mode = $filter['value']; 398 440 break; 399 441 } … … 415 457 $MainQuery.= ' 416 458 WHERE 417 '.implode("\n AND", $where);459 '.implode("\n ".$mode." ", $where); 418 460 } 419 461 … … 424 466 ;'; 425 467 426 // file_put_contents(SMART_PATH.'query.sql', $MainQuery); 468 if (defined('SMART_DEBUG')) 469 { 470 file_put_contents(SMART_PATH.'dump_filters.txt', print_r($filters, true)); 471 file_put_contents(SMART_PATH.'dump_query.sql', $MainQuery); 472 } 473 427 474 return array_from_query($MainQuery, 'id'); 428 475 } … … 442 489 if (!isset($level_is_set)) $level_is_set = false; 443 490 444 # tags 445 if ($filter['type'] == 'tags') 446 { 447 if ($filter['value'] == null) 491 switch ($filter['type']) 492 { 493 # tags 494 case 'tags': 495 { 496 if ($filter['value'] == null) 497 { 498 $error = true; 499 array_push($page['errors'], l10n('No tag selected')); 500 } 501 else 502 { 503 $filter['value'] = implode(',', get_tag_ids($filter['value'])); 504 } 505 break; 506 } 507 # date 508 case 'date': 509 { 510 if (!preg_match('#([0-9]{4})-([0-9]{2})-([0-9]{2})#', $filter['value'])) 511 { 512 $error = true; 513 array_push($page['errors'], l10n('Date string is malformed')); 514 } 515 break; 516 } 517 # name 518 case 'name': 519 { 520 if (empty($filter['value'])) 521 { 522 $error = true; 523 array_push($page['errors'], l10n('Name is empty')); 524 } 525 else if ( $filter['cond']=='regex' and @preg_match('/'.$filter['value'].'/', null)===false ) 526 { 527 $error = true; 528 array_push($page['errors'], l10n('Regex is malformed')); 529 } 530 break; 531 } 532 # album 533 case 'album': 534 { 535 if (@$filter['value'] == null) 536 { 537 $error = true; 538 array_push($page['errors'], l10n('No album selected')); 539 } 540 else 541 { 542 $filter['value'] = implode(',', $filter['value']); 543 } 544 break; 545 } 546 # dimensions 547 case 'dimensions': 548 { 549 if ( empty($filter['value']['min']) or empty($filter['value']['max']) ) 550 { 551 $error = true; 552 } 553 else 554 { 555 $filter['value'] = $filter['value']['min'].','.$filter['value']['max']; 556 } 557 break; 558 } 559 # author 560 case 'author': 561 { 562 if (empty($filter['value'])) 563 { 564 $error = true; 565 array_push($page['errors'], l10n('Author is empty')); 566 } 567 else if ( $filter['cond']=='regex' and @preg_match('/'.$filter['value'].'/', null)===false ) 568 { 569 $error = true; 570 array_push($page['errors'], l10n('Regex is malformed')); 571 } 572 else 573 { 574 $filter['value'] = preg_replace('#([ ]?),([ ]?)#', ',', $filter['value']); 575 } 576 break; 577 } 578 # hit 579 case 'hit': 580 { 581 if (!preg_match('#([0-9]{1,})#', $filter['value'])) 582 { 583 $error = true; 584 array_push($page['errors'], l10n('Hits must be an integer')); 585 } 586 break; 587 } 588 # rating_score 589 case 'rating_score': 590 { 591 if (!preg_match('#([0-9]{1,})#', $filter['value'])) 592 { 593 $error = true; 594 array_push($page['errors'], l10n('Rating score must be an integer')); 595 } 596 break; 597 } 598 # level 599 case 'level': 600 { 601 if ($level_is_set == true) // only one level is allowed, first is saved 602 { 603 $error = true; 604 array_push($page['errors'], l10n('You can\'t use more than one level filter')); 605 } 606 else 607 { 608 $filter['cond'] = 'level'; 609 $level_is_set = true; 610 } 611 break; 612 } 613 # limit 614 case 'limit': 615 { 616 if ($limit_is_set == true) // only one limit is allowed, first is saved 617 { 618 $error = true; 619 array_push($page['errors'], l10n('You can\'t use more than one limit filter')); 620 } 621 else if (!preg_match('#([0-9]{1,})#', $filter['value'])) 622 { 623 $error = true; 624 array_push($page['errors'], l10n('Limit must be an integer')); 625 } 626 else 627 { 628 $filter['cond'] = 'level'; 629 $limit_is_set = true; 630 } 631 break; 632 } 633 # mode 634 case 'mode': 635 { 636 $filter['cond'] = 'mode'; 637 break; 638 } 639 640 default: 448 641 { 449 642 $error = true; 450 array_push($page['errors'], l10n('No tag selected')); 451 } 452 else 453 { 454 $filter['value'] = implode(',', get_tag_ids($filter['value'])); 455 } 456 } 457 # date 458 else if ($filter['type'] == 'date') 459 { 460 if (!preg_match('#([0-9]{4})-([0-9]{2})-([0-9]{2})#', $filter['value'])) 461 { 462 $error = true; 463 array_push($page['errors'], l10n('Date string is malformed')); 464 } 465 } 466 # name 467 else if ($filter['type'] == 'name') 468 { 469 if (empty($filter['value'])) 470 { 471 $error = true; 472 array_push($page['errors'], l10n('Name is empty')); 473 } 474 } 475 # album 476 else if ($filter['type'] == 'album') 477 { 478 if (@$filter['value'] == null) 479 { 480 $error = true; 481 array_push($page['errors'], l10n('No album selected')); 482 } 483 else 484 { 485 $filter['value'] = implode(',', $filter['value']); 486 } 487 } 488 # author 489 else if ($filter['type'] == 'author') 490 { 491 if (empty($filter['value'])) 492 { 493 $error = true; 494 array_push($page['errors'], l10n('Author is empty')); 495 } 496 else 497 { 498 $filter['value'] = preg_replace('#([ ]?),([ ]?)#', ',', $filter['value']); 499 } 500 } 501 # hit 502 else if ($filter['type'] == 'hit') 503 { 504 if (!preg_match('#([0-9]{1,})#', $filter['value'])) 505 { 506 $error = true; 507 array_push($page['errors'], l10n('Hits must be an integer')); 508 } 509 } 510 # rating_score 511 else if ($filter['type'] == 'rating_score') 512 { 513 if (!preg_match('#([0-9]{1,})#', $filter['value'])) 514 { 515 $error = true; 516 array_push($page['errors'], l10n('Rating score must be an integer')); 517 } 518 } 519 # level 520 else if ($filter['type'] == 'level') 521 { 522 if ($level_is_set == true) // only one level is allowed, first is saved 523 { 524 $error = true; 525 array_push($page['errors'], l10n('You can\'t use more than one level filter')); 526 } 527 else 528 { 529 $level_is_set = true; 530 } 531 } 532 # limit 533 else if ($filter['type'] == 'limit') 534 { 535 if (!preg_match('#([0-9]{1,})#', $filter['value'])) 536 { 537 $error = true; 538 array_push($page['errors'], l10n('Limit must be an integer')); 539 } 540 else if ($limit_is_set == true) // only one limit is allowed, first is saved 541 { 542 $error = true; 543 array_push($page['errors'], l10n('You can\'t use more than one limit filter')); 544 } 545 else 546 { 547 $limit_is_set = true; 548 } 549 } 550 551 # out 643 break; 644 } 645 } 646 647 552 648 if ($error == false) 553 649 { … … 560 656 } 561 657 562 563 /**564 * inserts multiple lines in a table, ignore duplicate entries565 * @param string table_name566 * @param array dbfields567 * @param array inserts568 * @return void569 */570 function mass_inserts_ignore($table_name, $dbfields, $datas)571 {572 if (count($datas) != 0)573 {574 $first = true;575 576 $query = 'SHOW VARIABLES LIKE \'max_allowed_packet\'';577 list(, $packet_size) = pwg_db_fetch_row(pwg_query($query));578 $packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/579 $query = '';580 581 foreach ($datas as $insert)582 {583 if (strlen($query) >= $packet_size)584 {585 pwg_query($query);586 $first = true;587 }588 589 if ($first)590 {591 $query = '592 INSERT IGNORE INTO '.$table_name.'593 ('.implode(',', $dbfields).')594 VALUES';595 $first = false;596 }597 else598 {599 $query .= '600 , ';601 }602 603 $query .= '(';604 foreach ($dbfields as $field_id => $dbfield)605 {606 if ($field_id > 0)607 {608 $query .= ',';609 }610 611 if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')612 {613 $query .= 'NULL';614 }615 else616 {617 $query .= "'".$insert[$dbfield]."'";618 }619 }620 $query .= ')';621 }622 pwg_query($query);623 }624 }625 658 626 659 /** … … 636 669 } 637 670 671 /** 672 * update images list periodically 673 */ 674 function smart_periodic_update() 675 { 676 global $conf; 677 678 // we only search for old albums every hour, nevermind which user is connected 679 if ($conf['SmartAlbums']['last_update'] > time() - 3600) return; 680 681 $conf['SmartAlbums']['last_update'] = time(); 682 conf_update_param('SmartAlbums', serialize($conf['SmartAlbums'])); 683 684 // get categories with smart filters 685 $query = ' 686 SELECT DISTINCT id 687 FROM '.CATEGORIES_TABLE.' AS c 688 INNER JOIN '.CATEGORY_FILTERS_TABLE.' AS cf 689 ON c.id = cf.category_id 690 WHERE smart_update < DATE_SUB(NOW(), INTERVAL '.$conf['SmartAlbums']['update_timeout'].' DAY) 691 ;'; 692 693 // regenerate photo list 694 $smart_cats = array_from_query($query, 'id'); 695 array_map('smart_make_associations', $smart_cats); 696 } 697 638 698 ?> -
extensions/SmartAlbums/include/install.inc.php
r17716 r19446 11 11 $smart_default_config = serialize(array( 12 12 'update_on_upload' => false, 13 'update_on_date' => true, 14 'update_timeout' => 3, 13 15 'show_list_messages' => true, 14 16 'smart_is_forbidden' => true, 17 'last_update' => 0, 15 18 )); 16 19 … … 25 28 { 26 29 $new_conf['smart_is_forbidden'] = true; 27 conf_update_param('SmartAlbums', serialize($new_conf));28 $conf['SmartAlbums'] = serialize($new_conf);29 30 } 31 // new params in 2.1.0 32 if (!isset($new_conf['update_on_date'])) 33 { 34 $new_conf['update_on_date'] = true; 35 $new_conf['update_timeout'] = 3; 36 $new_conf['last_update'] = 0; 37 } 38 conf_update_param('SmartAlbums', serialize($new_conf)); 39 $conf['SmartAlbums'] = serialize($new_conf); 30 40 } 31 41 … … 45 55 { 46 56 pwg_query('ALTER TABLE `' . IMAGE_CATEGORY_TABLE . '` ADD `smart` ENUM(\'true\', \'false\') NOT NULL DEFAULT \'false\';'); 57 } 58 59 // new column on category table 60 $result = pwg_query('SHOW COLUMNS FROM `' . CATEGORIES_TABLE . '` LIKE "smart_update";'); 61 if (!pwg_db_num_rows($result)) 62 { 63 pwg_query('ALTER TABLE `' . CATEGORIES_TABLE . '` ADD `smart_update` DATETIME NOT NULL;'); 47 64 } 48 65 … … 68 85 foreach ($name_changes as $old => $new) 69 86 { 70 pwg_query('UPDATE `' . $prefixeTable . 'category_filters` SET cond = "'.$new.'" WHERE cond = "'.$old.'";');87 pwg_query('UPDATE `' . $prefixeTable . 'category_filters` SET cond = "'.$new.'" WHERE type = "date" AND cond = "'.$old.'";'); 71 88 } 72 89 } -
extensions/SmartAlbums/language/en_UK/plugin.lang.php
r18622 r19446 23 23 $lang['Doesn\'t begin with'] = 'Doesn\'t begin with'; 24 24 $lang['Doesn\'t end with'] = 'Doesn\'t end with'; 25 $lang['Regular expression'] = 'Regular expression'; 25 26 $lang['Is'] = 'Is'; 26 27 $lang['Is in'] = 'Is in'; … … 44 45 $lang['Limit must be an integer'] = 'Limit must be an integer'; 45 46 $lang['Rating score must be an integer'] = 'Rating score must be an integer'; 47 $lang['Regex is malformed'] = 'Regex is malformed'; 46 48 $lang['You can\'t use more than one limit filter'] = 'You can\'t use more than one limit filter'; 47 49 $lang['You can\'t use more than one level filter'] = 'You can\'t use more than one level filter'; … … 60 62 $lang['Exclude SmartAlbums from permissions management'] = 'Exclude SmartAlbums from permissions management'; 61 63 $lang['SmartAlbums are considered private for everyone, and a user can see it\'s content only if available in another album he has access to.'] = 'SmartAlbums are considered private for everyone, and a user can see it\'s content only if available in another album he has access to.'; 64 $lang['Update albums every %s days'] = 'Update albums every %s days'; 62 65 63 66 ?> -
extensions/SmartAlbums/language/fr_FR/plugin.lang.php
r19074 r19446 23 23 $lang['Doesn\'t begin with'] = 'Ne commence pas par'; 24 24 $lang['Doesn\'t end with'] = 'Ne fini pas par'; 25 $lang['Regular expression'] = 'Expression régulière'; 25 26 $lang['Is'] = 'Est'; 26 27 $lang['Is in'] = 'Est dans'; … … 44 45 $lang['Limit must be an integer'] = 'La nombre d\'éléments doit être un entier'; 45 46 $lang['Rating score must be an integer'] = 'Le score doit être un entier'; 47 $lang['Regex is malformed'] = 'Regex malformée'; 46 48 $lang['You can\'t use more than one limit filter'] = 'Vous ne pouvez choisir qu\'une seule limite de nombre d\'éléments'; 47 49 $lang['You can\'t use more than one level filter'] = 'Vous ne pouvez choisir qu\'un seul niveau de confidentialité'; … … 60 62 $lang['Exclude SmartAlbums from permissions management'] = 'Exclure les SmartAlbums de la gestion des droits d\'accès'; 61 63 $lang['SmartAlbums are considered private for everyone, and a user can see it\'s content only if available in another album he has access to.'] = 'Les SmartAlbums sont considérés comme privés pour tout le monde, et un utilisateur ne peut voir leur contenu que si disponible dans un autre album auquel il a accès.'; 64 $lang['Update albums every %s days'] = 'Mettre à jour les albums tous les %s jours'; 62 65 63 66 ?> -
extensions/SmartAlbums/main.inc.php
r17821 r19446 12 12 global $prefixeTable; 13 13 14 define('SMART_PATH', PHPWG_PLUGINS_PATH . 'SmartAlbums/');14 define('SMART_PATH', PHPWG_PLUGINS_PATH . 'SmartAlbums/'); 15 15 define('CATEGORY_FILTERS_TABLE', $prefixeTable . 'category_filters'); 16 define('SMART_ADMIN', get_root_url() . 'admin.php?page=plugin-SmartAlbums'); 17 define('SMART_VERSION', '2.0.4'); 16 define('SMART_ADMIN', get_root_url() . 'admin.php?page=plugin-SmartAlbums'); 17 define('SMART_VERSION', 'auto'); 18 //define('SMART_DEBUG', true); 18 19 19 20 21 add_event_handler('init', 'smart_init'); 22 add_event_handler('init', 'smart_periodic_update'); 20 23 add_event_handler('invalidate_user_cache', 'smart_make_all_associations'); 21 add_event_handler('init', 'smart_init');22 24 23 25 if (defined('IN_ADMIN')) … … 41 43 42 44 if ( 45 SMART_VERSION == 'auto' or 43 46 $pwg_loaded_plugins['SmartAlbums']['version'] == 'auto' or 44 47 version_compare($pwg_loaded_plugins['SmartAlbums']['version'], SMART_VERSION, '<') … … 48 51 smart_albums_install(); 49 52 50 if ( $pwg_loaded_plugins['SmartAlbums']['version'] != 'auto')53 if ( $pwg_loaded_plugins['SmartAlbums']['version'] != 'auto' and SMART_VERSION != 'auto' ) 51 54 { 52 55 $query = ' -
extensions/SmartAlbums/maintain.inc.php
r17716 r19446 24 24 pwg_query('DROP TABLE `' . $prefixeTable . 'category_filters`;'); 25 25 pwg_query('ALTER TABLE `' . IMAGE_CATEGORY_TABLE . '` DROP `smart`;'); 26 pwg_query('ALTER TABLE `' . CATEGORIES_TABLE . '` DROP `smart_update`;'); 26 27 pwg_query('DELETE FROM `' . CONFIG_TABLE . '` WHERE param = \'SmartAlbums\' LIMIT 1;'); 27 28 }
Note: See TracChangeset
for help on using the changeset viewer.