aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--admin/batch_manager_global.php24
-rw-r--r--admin/picture_modify.php15
-rw-r--r--admin/themes/default/js/LocalStorageCache.js121
-rw-r--r--admin/themes/default/template/batch_manager_global.tpl59
-rw-r--r--admin/themes/default/template/cat_modify.tpl59
-rw-r--r--admin/themes/default/template/photos_add_direct.tpl47
-rw-r--r--admin/themes/default/template/picture_modify.tpl39
-rw-r--r--include/ws_functions/pwg.categories.php2
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);