diff options
-rw-r--r-- | admin/batch_manager_global.php | 24 | ||||
-rw-r--r-- | admin/picture_modify.php | 15 | ||||
-rw-r--r-- | admin/themes/default/js/LocalStorageCache.js | 121 | ||||
-rw-r--r-- | admin/themes/default/template/batch_manager_global.tpl | 59 | ||||
-rw-r--r-- | admin/themes/default/template/cat_modify.tpl | 59 | ||||
-rw-r--r-- | admin/themes/default/template/photos_add_direct.tpl | 47 | ||||
-rw-r--r-- | admin/themes/default/template/picture_modify.tpl | 39 | ||||
-rw-r--r-- | include/ws_functions/pwg.categories.php | 2 |
8 files changed, 186 insertions, 180 deletions
diff --git a/admin/batch_manager_global.php b/admin/batch_manager_global.php index 6e65c462d..26e0e7660 100644 --- a/admin/batch_manager_global.php +++ b/admin/batch_manager_global.php @@ -519,30 +519,8 @@ SELECT } } -$template->assign( 'filter_category_selected', $selected_category); +$template->assign('filter_category_selected', $selected_category); -// Dissociate from a category : categories listed for dissociation can only -// represent virtual links. We can't create orphans. Links to physical -// categories can't be broken. -if (count($page['cat_elements_id']) > 0) -{ - $query = ' -SELECT - DISTINCT(category_id) AS id, - c.name, - c.uppercats, - c.global_rank - FROM '.IMAGE_CATEGORY_TABLE.' AS ic - JOIN '.CATEGORIES_TABLE.' AS c ON c.id = ic.category_id - JOIN '.IMAGES_TABLE.' AS i ON i.id = ic.image_id - WHERE ic.image_id IN ('.implode(',', $page['cat_elements_id']).') - AND ( - ic.category_id != i.storage_category_id - OR i.storage_category_id IS NULL - ) -;'; - display_select_cat_wrapper($query, array(), 'dissociate_options', true); -} if (count($page['cat_elements_id']) > 0) { diff --git a/admin/picture_modify.php b/admin/picture_modify.php index 370d64caf..134859ca4 100644 --- a/admin/picture_modify.php +++ b/admin/picture_modify.php @@ -42,7 +42,7 @@ SELECT id FROM '.CATEGORIES_TABLE.' WHERE representative_picture_id = '.$_GET['image_id'].' ;'; -$represent_options_selected = query2array($query, null, 'id'); +$represented_albums = query2array($query, null, 'id'); // +-----------------------------------------------------------------------+ // | delete photo | @@ -165,13 +165,13 @@ if (isset($_POST['submit'])) $_POST['represent'] = array(); } - $no_longer_thumbnail_for = array_diff($represent_options_selected, $_POST['represent']); + $no_longer_thumbnail_for = array_diff($represented_albums, $_POST['represent']); if (count($no_longer_thumbnail_for) > 0) { set_random_representant($no_longer_thumbnail_for); } - $new_thumbnail_for = array_diff($_POST['represent'], $represent_options_selected); + $new_thumbnail_for = array_diff($_POST['represent'], $represented_albums); if (count($new_thumbnail_for) > 0) { $query = ' @@ -182,7 +182,7 @@ UPDATE '.CATEGORIES_TABLE.' pwg_query($query); } - $represent_options_selected = $_POST['represent']; + $represented_albums = $_POST['represent']; $page['infos'][] = l10n('Photo informations updated'); } @@ -406,11 +406,12 @@ SELECT id INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = category_id WHERE image_id = '.$_GET['image_id'].' ;'; -$associate_options_selected = query2array($query, null, 'id'); +$associated_albums = query2array($query, null, 'id'); $template->assign(array( - 'associate_options_selected' => $associate_options_selected, - 'represent_options_selected' => $represent_options_selected, + 'associated_albums' => $associated_albums, + 'represented_albums' => $represented_albums, + 'STORAGE_ALBUM' => $storage_category_id, 'CACHE_KEYS' => get_admin_client_cache_keys(array('tags', 'categories')), )); diff --git a/admin/themes/default/js/LocalStorageCache.js b/admin/themes/default/js/LocalStorageCache.js index b720851be..747254349 100644 --- a/admin/themes/default/js/LocalStorageCache.js +++ b/admin/themes/default/js/LocalStorageCache.js @@ -1,4 +1,22 @@ +/** + * Base LocalStorage cache + * + * @param options {object} + * - key (required) identifier of the collection + * - serverId (recommended) identifier of the Piwigo instance + * - serverKey (required) state of collection server-side + * - lifetime (optional) cache lifetime in seconds + * - loader (required) function called to fetch data, takes a callback as first argument + * which must be called with the loaded date + */ var LocalStorageCache = function(options) { + this._init(options); +}; + +/* + * Constructor (deported for easy inheritance) + */ +LocalStorageCache.prototype._init = function(options) { this.key = options.key + '_' + options.serverId; this.serverKey = options.serverKey; this.lifetime = options.lifetime ? options.lifetime*1000 : 3600*1000; @@ -8,6 +26,10 @@ var LocalStorageCache = function(options) { this.ready = !!this.storage; }; +/* + * Get the cache content + * @param callback {function} called with the data as first parameter + */ LocalStorageCache.prototype.get = function(callback) { var now = new Date().getTime(), that = this; @@ -27,6 +49,10 @@ LocalStorageCache.prototype.get = function(callback) { }); }; +/* + * Manually set the cache content + * @param data {mixed} + */ LocalStorageCache.prototype.set = function(data) { if (this.ready) { this.storage[this.key] = JSON.stringify({ @@ -37,8 +63,103 @@ LocalStorageCache.prototype.set = function(data) { } }; +/* + * Manually clear the cache + */ LocalStorageCache.prototype.clear = function() { if (this.ready) { this.storage.removeItem(this.key); } +}; + + +/** + * Special LocalStorage for admin categories list + * + * @param options {object} + * - serverId (recommended) identifier of the Piwigo instance + * - serverKey (required) state of collection server-side + * - rootUrl (required) used for WS call + */ +var CategoriesCache = function(options) { + options.key = 'categoriesAdminList'; + + options.loader = function(callback) { + jQuery.getJSON(options.rootUrl + 'ws.php?format=json&method=pwg.categories.getAdminList', function(data) { + callback(data.result.categories); + }); + }; + + this._init(options); +}; + +CategoriesCache.prototype = new LocalStorageCache({}); + +/* + * Init Selectize with cache content + * @param $target {jQuery} + * @param options {object} + * - default (optional) default value which will be forced if the select is emptyed + * - filter (optional) function called for each select before applying the data + * takes two parameters: cache data, options + * must return new data + */ +CategoriesCache.prototype.selectize = function($target, options) { + options = options || {}; + + $target.selectize({ + valueField: 'id', + labelField: 'fullname', + sortField: 'global_rank', + searchField: ['fullname'], + plugins: ['remove_button'] + }); + + this.get(function(categories) { + $target.each(function() { + var data; + if (options.filter != undefined) { + data = options.filter.call(this, categories, options); + } + else { + data = categories; + } + + this.selectize.load(function(callback) { + callback(data); + }); + + if (jQuery(this).data('value')) { + jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, id) { + this.selectize.addItem(id); + }, this)); + } + + if (options.default != undefined) { + if (this.selectize.getValue() == '') { + this.selectize.addItem(options.default); + } + + // if multiple: prevent item deletion + if (this.multiple) { + this.selectize.getItem(options.default).find('.remove').hide(); + + this.selectize.on('item_remove', function(id) { + if (id == options.default) { + this.addItem(id); + this.getItem(id).find('.remove').hide(); + } + }); + } + // if single: restore default on blur + else { + this.selectize.on('dropdown_close', function() { + if (this.getValue() == '') { + this.addItem(options.default); + } + }); + } + } + }); + }); };
\ No newline at end of file diff --git a/admin/themes/default/template/batch_manager_global.tpl b/admin/themes/default/template/batch_manager_global.tpl index 4a45cab41..a5a48e8de 100644 --- a/admin/themes/default/template/batch_manager_global.tpl +++ b/admin/themes/default/template/batch_manager_global.tpl @@ -119,46 +119,31 @@ jQuery(document).ready(function() {ldelim} }); {* <!-- CATEGORIES --> *} - var categoriesCache = new LocalStorageCache({ - key: 'categoriesAdminList', + var categoriesCache = new CategoriesCache({ serverKey: '{$CACHE_KEYS.categories}', serverId: '{$CACHE_KEYS._hash}', - - loader: function(callback) { - jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.categories.getAdminList', function(data) { - callback(data.result.categories); - }); - } + rootUrl: '{$ROOT_URL}' }); - jQuery('[data-selectize=categories]').selectize({ - valueField: 'id', - labelField: 'fullname', - sortField: 'global_rank', - searchField: ['fullname'], - plugins: ['remove_button'] - }); - - categoriesCache.get(function(categories) { - jQuery('[data-selectize=categories]').each(function() { - this.selectize.load(function(callback) { - callback(categories); - }); - - if (jQuery(this).data('value')) { - this.selectize.setValue(jQuery(this).data('value')[0]); + categoriesCache.selectize(jQuery('[data-selectize=categories]'), { + filter: function(categories, options) { + if (this.name == 'dissociate') { + var filtered = jQuery.grep(categories, function(cat) { + return !cat.dir; + }); + + if (filtered.length > 0) { + jQuery('.albumDissociate').show(); + options.default = filtered[0].id; + } + + return filtered; } - - // prevent empty value - if (this.selectize.getValue() == '') { - this.selectize.setValue(categories[0].id); + else { + options.default = categories[0].id; + return categories; } - this.selectize.on('dropdown_close', function() { - if (this.getValue() == '') { - this.setValue(categories[0].id); - } - }); - }); + } }); jQuery('[data-add-album]').pwgAddAlbum({ cache: categoriesCache }); @@ -837,9 +822,7 @@ UL.thumbnails SPAN.wrap2 {ldelim} <option value="delete" class="icon-trash">{'Delete selected photos'|@translate}</option> <option value="associate">{'Associate to album'|@translate}</option> <option value="move">{'Move to album'|@translate}</option> - {if !empty($dissociate_options)} - <option value="dissociate">{'Dissociate from album'|@translate}</option> - {/if} + <option value="dissociate" class="albumDissociate" style="display:none">{'Dissociate from album'|@translate}</option> <option value="add_tags">{'Add tags'|@translate}</option> {if !empty($associated_tags)} <option value="del_tags">{'remove tags'|@translate}</option> @@ -884,7 +867,7 @@ UL.thumbnails SPAN.wrap2 {ldelim} <!-- dissociate --> - <div id="action_dissociate" class="bulkAction"> + <div id="action_dissociate" class="bulkAction albumDissociate" style="display:none"> <select data-selectize="categories" name="dissociate" style="width:400px"></select> </div> diff --git a/admin/themes/default/template/cat_modify.tpl b/admin/themes/default/template/cat_modify.tpl index 4bb06c03b..b1b9a5e06 100644 --- a/admin/themes/default/template/cat_modify.tpl +++ b/admin/themes/default/template/cat_modify.tpl @@ -5,57 +5,28 @@ {footer_script} {* <!-- CATEGORIES --> *} -var categoriesCache = new LocalStorageCache({ - key: 'categoriesAdminList', +var categoriesCache = new CategoriesCache({ serverKey: '{$CACHE_KEYS.categories}', serverId: '{$CACHE_KEYS._hash}', - - loader: function(callback) { - jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.categories.getAdminList', function(data) { - callback(data.result.categories); - }); - } -}); - -jQuery('[data-selectize=categories]').selectize({ - valueField: 'id', - labelField: 'fullname', - sortField: 'global_rank', - searchField: ['fullname'], - plugins: ['remove_button'] + rootUrl: '{$ROOT_URL}' }); -categoriesCache.get(function(categories) { - categories.push({ - id: 0, - fullname: '------------', - global_rank: 0 - }); - - // remove itself and children - categories = jQuery.grep(categories, function(cat) { - return !(/\b{$CAT_ID}\b/.test(cat.uppercats)); - }); - - jQuery('[data-selectize=categories]').each(function() { - this.selectize.load(function(callback) { - callback(categories); +categoriesCache.selectize(jQuery('[data-selectize=categories]'), { + default: 0, + filter: function(categories, options) { + // remove itself and children + var filtered = jQuery.grep(categories, function(cat) { + return !(/\b{$CAT_ID}\b/.test(cat.uppercats)); }); - - if (jQuery(this).data('value')) { - this.selectize.setValue(jQuery(this).data('value')[0]); - } - // prevent empty value - if (this.selectize.getValue() == '') { - this.selectize.setValue(0); - } - this.selectize.on('dropdown_close', function() { - if (this.getValue() == '') { - this.setValue(0); - } + filtered.push({ + id: 0, + fullname: '------------', + global_rank: 0 }); - }); + + return filtered; + } }); {/footer_script} diff --git a/admin/themes/default/template/photos_add_direct.tpl b/admin/themes/default/template/photos_add_direct.tpl index fdf80c481..df87e4d87 100644 --- a/admin/themes/default/template/photos_add_direct.tpl +++ b/admin/themes/default/template/photos_add_direct.tpl @@ -16,50 +16,21 @@ {footer_script} {* <!-- CATEGORIES --> *} -var categoriesCache = new LocalStorageCache({ - key: 'categoriesAdminList', +var categoriesCache = new CategoriesCache({ serverKey: '{$CACHE_KEYS.categories}', serverId: '{$CACHE_KEYS._hash}', - - loader: function(callback) { - jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.categories.getAdminList', function(data) { - callback(data.result.categories); - }); - } + rootUrl: '{$ROOT_URL}' }); -jQuery('[data-selectize=categories]').selectize({ - valueField: 'id', - labelField: 'fullname', - sortField: 'global_rank', - searchField: ['fullname'], - plugins: ['remove_button'] -}); - -categoriesCache.get(function(categories) { - if (categories.length > 0) { - jQuery("#albumSelection").show(); - } - - jQuery('[data-selectize=categories]').each(function() { - this.selectize.load(function(callback) { - callback(categories); - }); - - if (jQuery(this).data('value')) { - this.selectize.setValue(jQuery(this).data('value')[0]); +categoriesCache.selectize(jQuery('[data-selectize=categories]'), { + filter: function(categories, options) { + if (categories.length > 0) { + jQuery("#albumSelection").show(); + options.default = categories[0].id; } - // prevent empty value - if (this.selectize.getValue() == '') { - this.selectize.setValue(categories[0].id); - } - this.selectize.on('dropdown_close', function() { - if (this.getValue() == '') { - this.setValue(categories[0].id); - } - }); - }); + return categories; + } }); jQuery('[data-add-album]').pwgAddAlbum({ cache: categoriesCache }); diff --git a/admin/themes/default/template/picture_modify.tpl b/admin/themes/default/template/picture_modify.tpl index 3688d92ff..454a06428 100644 --- a/admin/themes/default/template/picture_modify.tpl +++ b/admin/themes/default/template/picture_modify.tpl @@ -10,37 +10,18 @@ {footer_script} (function(){ {* <!-- CATEGORIES --> *} -var categoriesCache = new LocalStorageCache({ - key: 'categoriesAdminList', +var categoriesCache = new CategoriesCache({ serverKey: '{$CACHE_KEYS.categories}', serverId: '{$CACHE_KEYS._hash}', - - loader: function(callback) { - jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.categories.getAdminList', function(data) { - callback(data.result.categories); - }); - } -}); - -jQuery('[data-selectize=categories]').selectize({ - valueField: 'id', - labelField: 'fullname', - sortField: 'global_rank', - searchField: ['fullname'], - plugins: ['remove_button'] + rootUrl: '{$ROOT_URL}' }); -categoriesCache.get(function(categories) { - jQuery('[data-selectize=categories]').each(function() { - this.selectize.load(function(callback) { - callback(categories); - }); - - jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, id) { - this.selectize.addItem(id); - }, this)); - }); -}); +categoriesCache.selectize(jQuery('[data-selectize=categories]'), { {if $STORAGE_ALBUM} + filter: function(categories, options) { + options.default = (this.name == 'associate[]') ? {$STORAGE_ALBUM} : undefined; + return categories; + } +{/if} }); {* <!-- TAGS --> *} var tagsCache = new LocalStorageCache({ @@ -157,14 +138,14 @@ jQuery(function(){ {* <!-- onLoad needed to wait localization loads --> *} <p> <strong>{'Linked albums'|@translate}</strong> <br> - <select data-selectize="categories" data-value="{$associate_options_selected|@json_encode|escape:html}" + <select data-selectize="categories" data-value="{$associated_albums|@json_encode|escape:html}" name="associate[]" multiple style="width:600px;" ></select> </p> <p> <strong>{'Representation of albums'|@translate}</strong> <br> - <select data-selectize="categories" data-value="{$represent_options_selected|@json_encode|escape:html}" + <select data-selectize="categories" data-value="{$represented_albums|@json_encode|escape:html}" name="represent[]" multiple style="width:600px;" ></select> </p> diff --git a/include/ws_functions/pwg.categories.php b/include/ws_functions/pwg.categories.php index da2706ab2..5ed387e70 100644 --- a/include/ws_functions/pwg.categories.php +++ b/include/ws_functions/pwg.categories.php @@ -489,7 +489,7 @@ SELECT category_id, COUNT(*) AS counter $nb_images_of = query2array($query, 'category_id', 'counter'); $query = ' -SELECT id, name, comment, uppercats, global_rank +SELECT id, name, comment, uppercats, global_rank, dir FROM '. CATEGORIES_TABLE .' ;'; $result = pwg_query($query); |