mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-03-28 17:42:57 +01:00
feature 3077 : factorize code for categories cache (TODO for other collections) + fix incorrect categories list for dissociation
git-svn-id: http://piwigo.org/svn/trunk@28542 68402e56-0260-453c-a942-63ccdbb3a9ee
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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')),
|
||||
));
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
else {
|
||||
options.default = categories[0].id;
|
||||
return categories;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
rootUrl: '{$ROOT_URL}'
|
||||
});
|
||||
|
||||
jQuery('[data-selectize=categories]').selectize({
|
||||
valueField: 'id',
|
||||
labelField: 'fullname',
|
||||
sortField: 'global_rank',
|
||||
searchField: ['fullname'],
|
||||
plugins: ['remove_button']
|
||||
});
|
||||
|
||||
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}
|
||||
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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}',
|
||||
rootUrl: '{$ROOT_URL}'
|
||||
});
|
||||
|
||||
loader: function(callback) {
|
||||
jQuery.getJSON('{$ROOT_URL}ws.php?format=json&method=pwg.categories.getAdminList', function(data) {
|
||||
callback(data.result.categories);
|
||||
});
|
||||
categoriesCache.selectize(jQuery('[data-selectize=categories]'), { {if $STORAGE_ALBUM}
|
||||
filter: function(categories, options) {
|
||||
options.default = (this.name == 'associate[]') ? {$STORAGE_ALBUM} : undefined;
|
||||
return categories;
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
jQuery.each(jQuery(this).data('value'), jQuery.proxy(function(i, id) {
|
||||
this.selectize.addItem(id);
|
||||
}, this));
|
||||
});
|
||||
});
|
||||
{/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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user