From 1549745402270b86d2116b8f2a498fddf28ea2e8 Mon Sep 17 00:00:00 2001 From: plegall Date: Sat, 13 Aug 2005 23:09:54 +0000 Subject: - new : maintenance screen in administration. There you can update categories informations (number of images, date of the last added element), update images informations (path, average rate), purge obsolete sessions, purge history. - new : ability to have random representative for categories. This configuration parameter is set to false by default. - new : ability to set an element as representative of a category without belonging to the category. Thus, administrator can choose representative even for empty categories. - improvement : semantically superior design for category edition screen by regrouping fields in fieldsets. The improved screen contains action buttons as in category list screen. - new : ability to move a virtual category (ie change its parent category). - bug fixed : the sync_users function checks all user children tables (access, cache, group association). git-svn-id: http://piwigo.org/svn/trunk@809 68402e56-0260-453c-a942-63ccdbb3a9ee --- admin/cat_modify.php | 155 +++++++++++++++++-- admin/cat_options.php | 44 +++++- admin/include/functions.php | 366 +++++++++++++++++++++++++++++++++++++++----- admin/maintenance.php | 103 +++++++++++++ admin/picture_modify.php | 5 +- 5 files changed, 610 insertions(+), 63 deletions(-) create mode 100644 admin/maintenance.php (limited to 'admin') diff --git a/admin/cat_modify.php b/admin/cat_modify.php index 44c07ad85..700b6fe5f 100644 --- a/admin/cat_modify.php +++ b/admin/cat_modify.php @@ -41,12 +41,6 @@ $template->set_filenames( array('categories'=>'admin/cat_modify.tpl') ); //--------------------------------------------------------- form criteria check if ( isset( $_POST['submit'] ) ) { - $query = 'SELECT status'; - $query.= ' FROM '.CATEGORIES_TABLE; - $query.= ' WHERE id = '.$_GET['cat_id']; - $query.= ';'; - $row = mysql_fetch_array( pwg_query( $query ) ); - $query = 'UPDATE '.CATEGORIES_TABLE; $query.= ' SET name = '; if ( empty($_POST['name'])) @@ -81,12 +75,26 @@ if ( isset( $_POST['submit'] ) ) set_cat_visible(array($_GET['cat_id']), $_POST['visible']); set_cat_status(array($_GET['cat_id']), $_POST['status']); - array_push($infos, $lang['editcat_confirm']); + if (isset($_POST['parent'])) + { + move_category($_GET['cat_id'], $_POST['parent']); + } + + array_push($page['infos'], $lang['editcat_confirm']); } else if (isset($_POST['set_random_representant'])) { set_random_representant(array($_GET['cat_id'])); } +else if (isset($_POST['delete_representant'])) +{ + $query = ' +UPDATE '.CATEGORIES_TABLE.' + SET representative_picture_id = NULL + WHERE id = '.$_GET['cat_id'].' +;'; + pwg_query($query); +} $query = ' SELECT * @@ -95,7 +103,7 @@ SELECT * ;'; $category = mysql_fetch_array( pwg_query( $query ) ); // nullable fields -foreach (array('comment','dir','site_id') as $nullable) +foreach (array('comment','dir','site_id', 'id_uppercat') as $nullable) { if (!isset($category[$nullable])) { @@ -103,6 +111,8 @@ foreach (array('comment','dir','site_id') as $nullable) } } +$category['is_virtual'] = empty($category['dir']) ? true : false; + // Navigation path $url = PHPWG_ROOT_PATH.'admin.php?page=cat_list&parent_id='; $navigation = ''; @@ -134,6 +144,16 @@ else } //----------------------------------------------------- template initialization + +$base_url = PHPWG_ROOT_PATH.'admin.php?page='; +$cat_list_url = $base_url.'cat_list'; + +$self_url = $cat_list_url; +if (!empty($category['id_uppercat'])) +{ + $self_url.= '&parent_id='.$category['id_uppercat']; +} + $template->assign_vars(array( 'CATEGORIES_NAV'=>$navigation, 'CAT_NAME'=>$category['name'], @@ -163,27 +183,89 @@ $template->assign_vars(array( 'L_NO'=>$lang['no'], 'L_SUBMIT'=>$lang['submit'], 'L_SET_RANDOM_REPRESENTANT'=>$lang['cat_representant'], + + 'U_JUMPTO'=> + add_session_id(PHPWG_ROOT_PATH.'category.php?cat='.$category['id']), + 'U_CHILDREN'=> + add_session_id($cat_list_url.'&parent_id='.$category['id']), 'F_ACTION'=>add_session_id($form_action) )); + +if ('private' == $category['status']) +{ + $template->assign_block_vars( + 'permissions', + array( + 'URL'=>add_session_id($base_url.'cat_perm&cat='.$category['id']) + ) + ); +} + +// manage category elements link if ($category['nb_images'] > 0) { - $query = ' + $template->assign_block_vars( + 'elements', + array( + 'URL'=>add_session_id($base_url.'element_set&cat='.$category['id']) + ) + ); +} + +// representant management +if ($category['nb_images'] > 0 + or !empty($category['representative_picture_id'])) +{ + $template->assign_block_vars('representant', array()); + + // picture to display : the identified representant or the generic random + // representant ? + if (!empty($category['representative_picture_id'])) + { + $query = ' SELECT tn_ext,path FROM '.IMAGES_TABLE.' WHERE id = '.$category['representative_picture_id'].' ;'; - $row = mysql_fetch_array(pwg_query($query)); - $src = get_thumbnail_src($row['path'], @$row['tn_ext']); - $url = PHPWG_ROOT_PATH.'admin.php?page=picture_modify'; - $url.= '&image_id='.$category['representative_picture_id']; - $template->assign_block_vars('representant', - array('SRC' => $src, - 'URL' => $url)); + $row = mysql_fetch_array(pwg_query($query)); + $src = get_thumbnail_src($row['path'], @$row['tn_ext']); + $url = PHPWG_ROOT_PATH.'admin.php?page=picture_modify'; + $url.= '&image_id='.$category['representative_picture_id']; + + $template->assign_block_vars( + 'representant.picture', + array( + 'SRC' => $src, + 'URL' => $url + ) + ); + } + else // $category['nb_images'] > 0 + { + $template->assign_block_vars('representant.random', array()); + } + + // can the admin choose to set a new random representant ? + if ($category['nb_images'] > 0) + { + $template->assign_block_vars('representant.set_random', array()); + } + + // can the admin delete the current representant ? + if ( + ($category['nb_images'] > 0 + and $conf['allow_random_representative']) + or + ($category['nb_images'] == 0 + and !empty($category['representative_picture_id']))) + { + $template->assign_block_vars('representant.delete_representant', array()); + } } -if (!empty($category['dir'])) +if (!$category['is_virtual']) //!empty($category['dir'])) { $template->assign_block_vars( 'storage', @@ -192,6 +274,45 @@ if (!empty($category['dir'])) get_complete_dir($category['id'])))); $template->assign_block_vars('upload' ,array()); } +else +{ + $template->assign_block_vars( + 'delete', + array( + 'URL'=>add_session_id($self_url.'&delete='.$category['id']) + ) + ); + + $template->assign_block_vars('move', array()); + + // the category can be moved in any category but in itself, in any + // sub-category + $unmovables = get_subcat_ids(array($category['id'])); + + $blockname = 'move.parent_option'; + + $template->assign_block_vars( + $blockname, + array( + 'SELECTED' + => empty($category['id_uppercat']) ? 'selected="selected"' : '', + 'VALUE'=> 0, + 'OPTION' => '------------' + ) + ); + + $query = ' +SELECT id,name,uppercats,global_rank + FROM '.CATEGORIES_TABLE.' + WHERE id NOT IN ('.implode(',', $unmovables).') +;'; + + display_select_cat_wrapper( + $query, + empty($category['id_uppercat']) ? array() : array($category['id_uppercat']), + $blockname + ); +} if (is_numeric($category['site_id']) and $category['site_id'] != 1) { diff --git a/admin/cat_options.php b/admin/cat_options.php index d4fa2dd92..fc10cbc05 100644 --- a/admin/cat_options.php +++ b/admin/cat_options.php @@ -72,6 +72,16 @@ UPDATE '.CATEGORIES_TABLE.' set_cat_status($_POST['cat_true'], 'private'); break; } + case 'representative' : + { + $query = ' +UPDATE '.CATEGORIES_TABLE.' + SET representative_picture_id = NULL + WHERE id IN ('.implode(',', $_POST['cat_true']).') +;'; + pwg_query($query); + break; + } } } else if (isset($_POST['trueify']) @@ -110,6 +120,13 @@ UPDATE '.CATEGORIES_TABLE.' set_cat_status($_POST['cat_false'], 'public'); break; } + case 'representative' : + { + // theoretically, all categories in $_POST['cat_false'] contain at + // least one element, so PhpWebGallery can find a representant. + set_random_representant($_POST['cat_false']); + break; + } } } // +-----------------------------------------------------------------------+ @@ -178,7 +195,6 @@ SELECT id,name,uppercats,global_rank 'L_CAT_OPTIONS_INFO' => $lang['cat_upload_info'], ) ); - $template->assign_block_vars('upload', array()); break; } case 'comments' : @@ -201,7 +217,6 @@ SELECT id,name,uppercats,global_rank 'L_CAT_OPTIONS_INFO' => $lang['cat_comments_info'], ) ); - $template->assign_block_vars('comments', array()); break; } case 'visible' : @@ -224,7 +239,6 @@ SELECT id,name,uppercats,global_rank 'L_CAT_OPTIONS_INFO' => $lang['cat_lock_info'], ) ); - $template->assign_block_vars('visible', array()); break; } case 'status' : @@ -247,7 +261,29 @@ SELECT id,name,uppercats,global_rank 'L_CAT_OPTIONS_INFO' => $lang['cat_status_info'], ) ); - $template->assign_block_vars('status', array()); + break; + } + case 'representative' : + { + $query_true = ' +SELECT id,name,uppercats,global_rank + FROM '.CATEGORIES_TABLE.' + WHERE representative_picture_id IS NOT NULL +;'; + $query_false = ' +SELECT id,name,uppercats,global_rank + FROM '.CATEGORIES_TABLE.' + WHERE nb_images != 0 + AND representative_picture_id IS NULL +;'; + $template->assign_vars( + array( + 'L_CAT_TITLE' => l10n('Representative'), + 'L_CAT_OPTIONS_TRUE' => l10n('singly represented'), + 'L_CAT_OPTIONS_FALSE' => l10n('randomly represented'), + 'L_CAT_OPTIONS_INFO' => l10n('') + ) + ); break; } } diff --git a/admin/include/functions.php b/admin/include/functions.php index 2364ada41..5811da226 100644 --- a/admin/include/functions.php +++ b/admin/include/functions.php @@ -395,6 +395,8 @@ DELETE FROM '.USERS_TABLE.' */ function update_category($ids = 'all', $recursive = false) { + global $conf; + // retrieving all categories to update $cat_ids = array(); @@ -428,12 +430,7 @@ SELECT id } $query.= ' ;'; - $result = pwg_query( $query ); - while ( $row = mysql_fetch_array( $result ) ) - { - array_push($cat_ids, $row['id']); - } - $cat_ids = array_unique($cat_ids); + $cat_ids = array_unique(array_from_query($query, 'id')); if (count($cat_ids) == 0) { @@ -470,45 +467,88 @@ SELECT category_id, 'update' => array('date_last', 'nb_images')); mass_updates(CATEGORIES_TABLE, $fields, $datas); - $query = ' -UPDATE '.CATEGORIES_TABLE.' - SET representative_picture_id = NULL - WHERE nb_images = 0 -;'; - pwg_query($query); - + // representative pictures if (count($cat_ids) > 0) { - $categories = array(); - // find all categories where the setted representative is not possible + // find all categories where the setted representative is not possible : + // the picture does not exist $query = ' -SELECT id - FROM '.CATEGORIES_TABLE.' LEFT JOIN '.IMAGE_CATEGORY_TABLE.' - ON id = category_id AND representative_picture_id = image_id +SELECT c.id + FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i + ON c.representative_picture_id = i.id WHERE representative_picture_id IS NOT NULL - AND id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").') - AND category_id IS NULL + AND c.id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").') + AND i.id IS NULL ;'; - $result = pwg_query($query); - while ($row = mysql_fetch_array($result)) + $wrong_representant = array_from_query($query, 'id'); + + if ($conf['allow_random_representative']) { - array_push($categories, $row['id']); + if (count($wrong_representant) > 0) + { + $query = ' +UPDATE '.CATEGORIES_TABLE.' + SET representative_picture_id = NULL + WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 80, "\n").') +;'; + pwg_query($query); + } } - // find categories with elements and with no representant - $query = ' + else + { + $to_null = array(); + $to_rand = array(); + + if (count($wrong_representant) > 0) + { + // among the categories with an unknown representant, we dissociate + // categories containing pictures and categories containing no + // pictures. Indeed, the representant must set to NULL if no picture + // in the category and set to a random picture otherwise. + $query = ' +SELECT id + FROM '.CATEGORIES_TABLE.' + WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 80, "\n").') + AND nb_images = 0 +;'; + $to_null = array_from_query($query, 'id'); + $to_rand = array_diff($wrong_representant, $to_null); + } + + if (count($to_null) > 0) + { + $query = ' +UPDATE '.CATEGORIES_TABLE.' + SET representative_picture_id = NULL + WHERE id IN ('.wordwrap(implode(', ', $to_null), 80, "\n").') +;'; + pwg_query($query); + } + + // If the random representant is not allowed, we need to find + // categories with elements and with no representant. Those categories + // must be added to the list of categories to set to a random + // representant. + $query = ' SELECT id FROM '.CATEGORIES_TABLE.' WHERE representative_picture_id IS NULL AND nb_images != 0 + AND id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").') ;'; - $result = pwg_query($query); - while ($row = mysql_fetch_array($result)) - { - array_push($categories, $row['id']); + $to_rand = + array_unique( + array_merge( + $to_rand, + array_from_query($query, 'id') + ) + ); + + if (count($to_rand) > 0) + { + set_random_representant($to_rand); + } } - - $categories = array_unique($categories); - set_random_representant($categories); } } @@ -1186,8 +1226,14 @@ function micro_seconds() } /** - * compares and synchronizes USERS_TABLE and USER_INFOS_TABLE : each user in - * USERS_TABLE must be present in USER_INFOS_TABLE. + * synchronize base users list and related users list + * + * compares and synchronizes base users table (USERS_TABLE) with its child + * tables (USER_INFOS_TABLE, USER_ACCESS, USER_CACHE, USER_GROUP) : each + * base user must be present in child tables, users in child tables not + * present in base table must be deleted. + * + * @return void */ function sync_users() { @@ -1240,17 +1286,257 @@ SELECT user_id $inserts); } - // users present in $infos_users and not in $base_users must be deleted - $to_delete = array_diff($infos_users, $base_users); - - if (count($to_delete) > 0) + // users present in user related tables must be present in the base user + // table + $tables = + array( + USER_INFOS_TABLE, + USER_ACCESS_TABLE, + USER_CACHE_TABLE, + USER_GROUP_TABLE + ); + foreach ($tables as $table) { $query = ' +SELECT user_id + FROM '.$table.' +;'; + $to_delete = + array_diff( + array_from_query($query, 'user_id'), + $base_users + ); + + if (count($to_delete) > 0) + { + $query = ' DELETE - FROM '.USER_INFOS_TABLE.' + FROM '.$table.' WHERE user_id in ('.implode(',', $to_delete).') +;'; + pwg_query($query); + } + } +} + +/** + * updates categories.uppercats field based on categories.id + + * categories.id_uppercat + * + * @return void + */ +function update_uppercats() +{ + $uppercat_ids = array(); + + $query = ' +SELECT id, id_uppercat + FROM '.CATEGORIES_TABLE.' +;'; + $result = pwg_query($query); + while ($row = mysql_fetch_array($result)) + { + $uppercat_ids[$row['id']] = + !empty($row['id_uppercat']) ? $row['id_uppercat'] : 'NULL'; + } + + // uppercats array associates a category id to the list of uppercats id. + $uppercats = array(); + + foreach (array_keys($uppercat_ids) as $id) + { + $uppercats[$id] = array(); + + $uppercat = $id; + + while ($uppercat != 'NULL') + { + array_push($uppercats[$id], $uppercat); + $uppercat = $uppercat_ids[$uppercat]; + } + } + + $datas = array(); + + foreach ($uppercats as $id => $list) + { + array_push( + $datas, + array( + 'id' => $id, + 'uppercats' => implode(',', array_reverse($list)) + ) + ); + } + + $fields = array('primary' => array('id'), 'update' => array('uppercats')); + mass_updates(CATEGORIES_TABLE, $fields, $datas); +} + +/** + * update images.path field + * + * @return void + */ +function update_path() +{ + $query = ' +SELECT DISTINCT(storage_category_id) + FROM '.IMAGES_TABLE.' +;'; + $cat_ids = array_from_query($query, 'storage_category_id'); + $fulldirs = get_fulldirs($cat_ids); + + foreach ($cat_ids as $cat_id) + { + $query = ' +UPDATE '.IMAGES_TABLE.' + SET path = CONCAT(\''.$fulldirs[$cat_id].'\',\'/\',file) + WHERE storage_category_id = '.$cat_id.' ;'; pwg_query($query); - } + } +} + +/** + * update images.average_rate field + * + * @return void + */ +function update_average_rate() +{ + $average_rates = array(); + + $query = ' +SELECT element_id, + ROUND(AVG(rate),2) AS average_rate + FROM '.RATE_TABLE.' + GROUP BY element_id +;'; + $result = pwg_query($query); + while ($row = mysql_fetch_array($result)) + { + array_push($average_rates, $row); + } + + $datas = array(); + foreach ($average_rates as $item) + { + array_push( + $datas, + array( + 'id' => $item['element_id'], + 'average_rate' => $item['average_rate'] + ) + ); + } + $fields = array('primary' => array('id'), 'update' => array('average_rate')); + mass_updates(IMAGES_TABLE, $fields, $datas); +} + +/** + * change the parent category of the given category. The category is + * supposed virtual. + * + * @param int category identifier + * @param int parent category identifier + * @return void + */ +function move_category($category_id, $new_parent = -1) +{ + // verifies if the move is necessary + $query = ' +SELECT id_uppercat, status + FROM '.CATEGORIES_TABLE.' + WHERE id = '.$category_id.' +;'; + list($old_parent, $status) = mysql_fetch_row(pwg_query($query)); + + $old_parent = empty($old_parent) ? 'NULL' : $old_parent; + $new_parent = $new_parent < 1 ? 'NULL' : $new_parent; + + if ($new_parent == $old_parent) + { + // no need to move ! + return; + } + + $query = ' +UPDATE '.CATEGORIES_TABLE.' + SET id_uppercat = '.$new_parent.' + WHERE id = '.$category_id.' +;'; + pwg_query($query); + + update_uppercats(); + ordering(); + update_global_rank(); + + // status and related permissions management + if ('NULL' == $new_parent) + { + $parent_status = 'public'; + } + else + { + $query = ' +SELECT status + FROM '.CATEGORIES_TABLE.' + WHERE id = '.$new_parent.' +;'; + list($parent_status) = mysql_fetch_row(pwg_query($query)); + } + + if ('private' == $parent_status) + { + switch ($status) + { + case 'public' : + { + set_cat_status(array($category_id), 'private'); + break; + } + case 'private' : + { + $subcats = get_subcat_ids(array($category_id)); + + $tables = + array( + USER_ACCESS_TABLE => 'user_id', + GROUP_ACCESS_TABLE => 'group_id' + ); + + foreach ($tables as $table => $field) + { + $query = ' +SELECT '.$field.' + FROM '.$table.' + WHERE category_id = '.$category_id.' +;'; + $category_access = array_from_query($query, $field); + + $query = ' +SELECT '.$field.' + FROM '.$table.' + WHERE category_id = '.$new_parent.' +;'; + $parent_access = array_from_query($query, $field); + + $to_delete = array_diff($parent_access, $category_access); + + if (count($to_delete) > 0) + { + $query = ' +DELETE FROM '.$table.' + WHERE '.$field.' IN ('.implode(',', $to_delete).') + AND category_id IN ('.implode(',', $subcats).') +;'; + pwg_query($query); + } + } + break; + } + } + } } ?> diff --git a/admin/maintenance.php b/admin/maintenance.php new file mode 100644 index 000000000..f6dfa3297 --- /dev/null +++ b/admin/maintenance.php @@ -0,0 +1,103 @@ +set_filenames(array('maintenance'=>'admin/maintenance.tpl')); + +$start_url = PHPWG_ROOT_PATH.'admin.php?page=maintenance&action='; + +$template->assign_vars( + array( + 'U_MAINT_CATEGORIES' => add_session_id($start_url.'categories'), + 'U_MAINT_IMAGES' => add_session_id($start_url.'images'), + 'U_MAINT_HISTORY' => add_session_id($start_url.'history'), + 'U_MAINT_SESSIONS' => add_session_id($start_url.'sessions') + ) + ); + +// +-----------------------------------------------------------------------+ +// | sending html code | +// +-----------------------------------------------------------------------+ + +$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance'); +?> \ No newline at end of file diff --git a/admin/picture_modify.php b/admin/picture_modify.php index 532f5aeee..1533d9f08 100644 --- a/admin/picture_modify.php +++ b/admin/picture_modify.php @@ -234,6 +234,7 @@ SELECT id,name,uppercats,global_rank WHERE id NOT IN ('.implode(',', $associateds).') ;'; display_select_cat_wrapper($query,array(),'dissociated_option'); + // representing $query = ' SELECT id,name,uppercats,global_rank @@ -245,8 +246,8 @@ display_select_cat_wrapper($query,array(),'elected_option'); $query = ' SELECT id,name,uppercats,global_rank FROM '.CATEGORIES_TABLE.' - WHERE id IN ('.implode(',', $associateds).') - AND representative_picture_id != '.$_GET['image_id'].' + WHERE representative_picture_id != '.$_GET['image_id'].' + OR representative_picture_id IS NULL ;'; display_select_cat_wrapper($query,array(),'dismissed_option'); //----------------------------------------------------------- sending html code -- cgit v1.2.3