From 34014e496e3a4b39f91ce234fd177b6c146ef907 Mon Sep 17 00:00:00 2001 From: plegall Date: Mon, 7 Dec 2009 22:28:40 +0000 Subject: feature 1312 added: pwg.images.setInfo can replace multiple values propreties (tags/categories). The primary condition is to provide "tag_ids" and/or "categories" input parameters, ie pwg.images.set won't create emptiness. You can reduce the set of tags/categories but not remove all tags/categories. bug 1277 fixed: with a stronger algorithm for adding/replacing categories, we now avoid to recreate an existing image_category association. When a remote client calls pwg.images.setInfo, Piwigo returns an error 500 if: 1. the "categories" parameter is malformed (no numeric id inside) 2. one of the input categories does not exist at database level. git-svn-id: http://piwigo.org/svn/branches/2.0@4444 68402e56-0260-453c-a942-63ccdbb3a9ee --- include/ws_functions.inc.php | 168 +++++++++++++++++++++++++++++++------------ ws.php | 1 + 2 files changed, 123 insertions(+), 46 deletions(-) diff --git a/include/ws_functions.inc.php b/include/ws_functions.inc.php index 47747b7e1..d41a4129d 100644 --- a/include/ws_functions.inc.php +++ b/include/ws_functions.inc.php @@ -1730,7 +1730,8 @@ SELECT * { ws_add_image_category_relations( $params['image_id'], - $params['categories'] + $params['categories'], + $params['replace_mode'] ); } @@ -1738,16 +1739,29 @@ SELECT * if (isset($params['tag_ids'])) { include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); - add_tags( - explode(',', $params['tag_ids']), - array($params['image_id']) - ); + + $tag_ids = explode(',', $params['tag_ids']); + + if ($params['replace_mode']) + { + set_tags( + $tag_ids, + $params['image_id'] + ); + } + else + { + add_tags( + $tag_ids, + array($params['image_id']) + ); + } } invalidate_user_cache(); } -function ws_add_image_category_relations($image_id, $categories_string) +function ws_add_image_category_relations($image_id, $categories_string, $replace_mode=false) { // let's add links between the image and the categories // @@ -1765,6 +1779,11 @@ function ws_add_image_category_relations($image_id, $categories_string) { @list($cat_id, $rank) = explode(',', $token); + if (!preg_match('/^\d+$/', $cat_id)) + { + continue; + } + array_push($cat_ids, $cat_id); if (!isset($rank)) @@ -1781,62 +1800,119 @@ function ws_add_image_category_relations($image_id, $categories_string) $cat_ids = array_unique($cat_ids); - if (count($cat_ids) > 0) + if (count($cat_ids) == 0) + { + new PwgError( + 500, + '[ws_add_image_category_relations] there is no category defined in "'.$categories_string.'"' + ); + exit(); + } + + $query = ' +SELECT + id + FROM '.CATEGORIES_TABLE.' + WHERE id IN ('.implode(',', $cat_ids).') +;'; + $db_cat_ids = array_from_query($query, 'id'); + + $unknown_cat_ids = array_diff($cat_ids, $db_cat_ids); + if (count($unknown_cat_ids) != 0) + { + new PwgError( + 500, + '[ws_add_image_category_relations] the following categories are unknown: '.implode(', ', $unknown_cat_ids) + ); + exit(); + } + + $to_update_cat_ids = array(); + + // in case of replace mode, we first check the existing associations + $query = ' +SELECT + category_id + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE image_id = '.$image_id.' +;'; + $existing_cat_ids = array_from_query($query, 'category_id'); + + if ($replace_mode) { - if ($search_current_ranks) + $to_remove_cat_ids = array_diff($existing_cat_ids, $cat_ids); + if (count($to_remove_cat_ids) > 0) { $query = ' +DELETE + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE image_id = '.$image_id.' + AND category_id IN ('.implode(', ', $to_remove_cat_ids).') +;'; + pwg_query($query); + update_category($to_remove_cat_ids); + } + } + + $new_cat_ids = array_diff($cat_ids, $existing_cat_ids); + if (count($new_cat_ids) == 0) + { + return true; + } + + if ($search_current_ranks) + { + $query = ' SELECT category_id, MAX(rank) AS max_rank FROM '.IMAGE_CATEGORY_TABLE.' WHERE rank IS NOT NULL - AND category_id IN ('.implode(',', $cat_ids).') + AND category_id IN ('.implode(',', $new_cat_ids).') GROUP BY category_id ;'; - $current_rank_of = simple_hash_from_query( - $query, - 'category_id', - 'max_rank' - ); + $current_rank_of = simple_hash_from_query( + $query, + 'category_id', + 'max_rank' + ); - foreach ($cat_ids as $cat_id) + foreach ($new_cat_ids as $cat_id) + { + if (!isset($current_rank_of[$cat_id])) { - if (!isset($current_rank_of[$cat_id])) - { - $current_rank_of[$cat_id] = 0; - } - - if ('auto' == $rank_on_category[$cat_id]) - { - $rank_on_category[$cat_id] = $current_rank_of[$cat_id] + 1; - } + $current_rank_of[$cat_id] = 0; + } + + if ('auto' == $rank_on_category[$cat_id]) + { + $rank_on_category[$cat_id] = $current_rank_of[$cat_id] + 1; } } - - $inserts = array(); - - foreach ($cat_ids as $cat_id) - { - array_push( - $inserts, - array( - 'image_id' => $image_id, - 'category_id' => $cat_id, - 'rank' => $rank_on_category[$cat_id], - ) - ); - } - - include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); - mass_inserts( - IMAGE_CATEGORY_TABLE, - array_keys($inserts[0]), - $inserts + } + + $inserts = array(); + + foreach ($new_cat_ids as $cat_id) + { + array_push( + $inserts, + array( + 'image_id' => $image_id, + 'category_id' => $cat_id, + 'rank' => $rank_on_category[$cat_id], + ) ); - - update_category($cat_ids); } + + include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); + mass_inserts( + IMAGE_CATEGORY_TABLE, + array_keys($inserts[0]), + $inserts + ); + + update_category($new_cat_ids); } function ws_categories_setInfo($params, &$service) diff --git a/ws.php b/ws.php index 2e2b8f6f9..003ead80e 100644 --- a/ws.php +++ b/ws.php @@ -289,6 +289,7 @@ function ws_addDefaultMethods( $arr ) 'default' => 0, 'maxValue' => $conf['available_permission_levels'] ), + 'replace_mode' => array('default' => false), ), 'POST method only. Admin only
categories is a string list "category_id[,rank];category_id[,rank]" The rank is optional and is equivalent to "auto" if not given.' -- cgit v1.2.3