diff options
-rw-r--r-- | admin.php | 23 | ||||
-rw-r--r-- | admin/cat_modify.php | 155 | ||||
-rw-r--r-- | admin/cat_options.php | 44 | ||||
-rw-r--r-- | admin/include/functions.php | 366 | ||||
-rw-r--r-- | admin/maintenance.php | 103 | ||||
-rw-r--r-- | admin/picture_modify.php | 5 | ||||
-rw-r--r-- | doc/ChangeLog | 24 | ||||
-rw-r--r-- | include/category_subcats.inc.php | 163 | ||||
-rw-r--r-- | include/config_default.inc.php | 13 | ||||
-rw-r--r-- | template/default/admin.tpl | 9 | ||||
-rw-r--r-- | template/default/admin/cat_modify.tpl | 146 | ||||
-rw-r--r-- | template/default/admin/maintenance.tpl | 9 | ||||
-rw-r--r-- | template/default/default.css | 31 | ||||
-rw-r--r-- | template/default/theme/category_representant_random.png | bin | 0 -> 3170 bytes |
14 files changed, 912 insertions, 179 deletions
@@ -168,6 +168,18 @@ switch ( $_GET['page'] ) $page_valide = true; break; } + case 'maintenance' : + { + $title = l10n('Maintenance'); + $page_valide = true; + break; + } + case 'representative' : + { + $title = l10n('Representative'); + $page_valide = true; + break; + } // case 'element_set_unit' : // { // $title = 'batch management'; @@ -244,6 +256,7 @@ $template->assign_vars(array( 'U_FAQ'=>add_session_id($link_start.'help' ), 'U_SITES'=>add_session_id($link_start.'remote_site'), 'U_PHPINFO'=>add_session_id($link_start.'admin_phpinfo' ), + 'U_MAINTENANCE'=>add_session_id($link_start.'maintenance'), 'U_CONFIG_GENERAL'=>add_session_id($conf_link.'general' ), 'U_CONFIG_COMMENTS'=>add_session_id($conf_link.'comments' ), 'U_CONFIG_DISPLAY'=>add_session_id($conf_link.'default' ), @@ -269,6 +282,16 @@ $template->assign_vars(array( 'U_RETURN'=>add_session_id(PHPWG_ROOT_PATH.'category.php') )); +if ($conf['allow_random_representative']) +{ + $template->assign_block_vars( + 'representative', + array( + 'URL' => add_session_id($opt_link.'representative') + ) + ); +} + //--------------------------------------------------------------------- summary $link_start = PHPWG_ROOT_PATH.'admin.php?page='; //------------------------------------------------------------- content display 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 = '<a class="" href="'.add_session_id(PHPWG_ROOT_PATH.'admin.php?page=cat_list').'">'; @@ -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 @@ +<?php +// +-----------------------------------------------------------------------+ +// | PhpWebGallery - a PHP based picture gallery | +// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net | +// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net | +// +-----------------------------------------------------------------------+ +// | branch : BSF (Best So Far) +// | file : $RCSfile$ +// | last update : $Date$ +// | last modifier : $Author$ +// | revision : $Revision$ +// +-----------------------------------------------------------------------+ +// | This program is free software; you can redistribute it and/or modify | +// | it under the terms of the GNU General Public License as published by | +// | the Free Software Foundation | +// | | +// | This program is distributed in the hope that it will be useful, but | +// | WITHOUT ANY WARRANTY; without even the implied warranty of | +// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | +// | General Public License for more details. | +// | | +// | You should have received a copy of the GNU General Public License | +// | along with this program; if not, write to the Free Software | +// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | +// | USA. | +// +-----------------------------------------------------------------------+ + +if (!defined('PHPWG_ROOT_PATH')) +{ + die ("Hacking attempt!"); +} +include_once(PHPWG_ROOT_PATH.'admin/include/isadmin.inc.php'); + +// +-----------------------------------------------------------------------+ +// | actions | +// +-----------------------------------------------------------------------+ + +$action = isset($_GET['action']) ? $_GET['action'] : ''; + +switch ($action) +{ + case 'categories' : + { + update_uppercats(); + update_category('all'); + ordering(); + update_global_rank(); + break; + } + case 'images' : + { + update_path(); + update_average_rate(); + break; + } + case 'history' : + { + $query = ' +DELETE + FROM '.HISTORY_TABLE.' +;'; + pwg_query($query); + break; + } + case 'sessions' : + { + $query = ' +DELETE + FROM '.SESSIONS_TABLE.' + WHERE expiration < NOW() +;'; + pwg_query($query); + break; + } + default : + { + break; + } +} + +// +-----------------------------------------------------------------------+ +// | template init | +// +-----------------------------------------------------------------------+ + +$template->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 diff --git a/doc/ChangeLog b/doc/ChangeLog index eca7006ff..a611ab41e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,27 @@ +2005-09-13 Pierrick LE GALL + + * 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). + 2005-08-08 Pierrick LE GALL * new : external authentication in another users table. Previous diff --git a/include/category_subcats.inc.php b/include/category_subcats.inc.php index 5132172b9..8e40d8498 100644 --- a/include/category_subcats.inc.php +++ b/include/category_subcats.inc.php @@ -32,7 +32,7 @@ */ $query = ' -SELECT id, name, date_last +SELECT id, name, date_last, representative_picture_id FROM '.CATEGORIES_TABLE.' WHERE id_uppercat '; if (!isset($page['cat']) or !is_numeric($page['cat'])) @@ -43,81 +43,132 @@ else { $query.= '= '.$page['cat']; } -// we must not show pictures of a forbidden category -if ($user['forbidden_categories'] != '') -{ - $query.= ' AND id NOT IN ('.$user['forbidden_categories'].')'; -} -$query.= ' + $query.= ' + AND id NOT IN ('.$user['forbidden_categories'].') ORDER BY rank ;'; $result = pwg_query($query); -// template thumbnail initialization -if (mysql_num_rows($result) > 0) -{ - $template->assign_block_vars('thumbnails', array()); - // first line - $template->assign_block_vars('thumbnails.line', array()); - // current row displayed - $row_number = 0; -} +// $conf['allow_random_representative'] + +$cat_thumbnails = array(); while ($row = mysql_fetch_array($result)) { - $query = ' -SELECT path, tn_ext - FROM '.CATEGORIES_TABLE.' AS c INNER JOIN '.IMAGES_TABLE.' AS i - ON i.id = c.representative_picture_id - WHERE uppercats REGEXP \'(^|,)'.$row['id'].'(,|$)\''; - // we must not show pictures of a forbidden category - if ($user['forbidden_categories'] != '') + if (isset($row['representative_picture_id']) + and is_numeric($row['representative_picture_id'])) { - $query.= ' - AND c.id NOT IN ('.$user['forbidden_categories'].')'; + // if a representative picture is set, it has priority + $image_id = $row['representative_picture_id']; } - $query.= ' + else if ($conf['allow_random_representative']) + { + // searching a random representant among elements in sub-categories + $query = ' +SELECT image_id + FROM '.CATEGORIES_TABLE.' AS c INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic + ON ic.category_id = c.id + WHERE uppercats REGEXP \'(^|,)'.$row['id'].'(,|$)\' + AND c.id NOT IN ('.$user['forbidden_categories'].') ORDER BY RAND() LIMIT 0,1 ;'; - $element_result = pwg_query($query); - if (mysql_num_rows($element_result) == 0) + $subresult = pwg_query($query); + if (mysql_num_rows($result) > 0) + { + list($image_id) = mysql_fetch_row($subresult); + } + } + else { - continue; + // searching a random representant among representant of sub-categories + $query = ' +SELECT representative_picture_id + FROM '.CATEGORIES_TABLE.' + WHERE uppercats REGEXP \'(^|,)'.$row['id'].'(,|$)\' + AND id NOT IN ('.$user['forbidden_categories'].') + AND representative_picture_id IS NOT NULL + ORDER BY RAND() + LIMIT 0,1 +;'; + $subresult = pwg_query($query); + if (mysql_num_rows($subresult) > 0) + { + list($image_id) = mysql_fetch_row($subresult); + } } - $element_row = mysql_fetch_array($element_result); - - $thumbnail_link = get_thumbnail_src($element_row['path'], - @$element_row['tn_ext']); - $thumbnail_title = $lang['hint_category']; + if (isset($image_id)) + { + array_push( + $cat_thumbnails, + array( + 'category' => $row['id'], + 'picture' => $image_id, + 'name' => $row['name'], + 'date_last' => @$row['date_last'] + ) + ); + } - $url_link = PHPWG_ROOT_PATH.'category.php?cat='.$row['id']; + unset($image_id); +} - $template->assign_block_vars( - 'thumbnails.line.thumbnail', - array( - 'IMAGE' => $thumbnail_link, - 'IMAGE_ALT' => $row['name'], - 'IMAGE_TITLE' => $thumbnail_title, - 'IMAGE_TS' => get_icon(@$row['date_last']), - - 'U_IMG_LINK' => add_session_id($url_link) - ) - ); +if (count($cat_thumbnails) > 0) +{ + $images = array(); + + foreach ($cat_thumbnails as $item) + { + $images[$item['picture']] = ''; + } - $template->assign_block_vars( - 'thumbnails.line.thumbnail.category_name', - array( - 'NAME' => $row['name'] - ) - ); + $query = ' +SELECT id, path, tn_ext + FROM '.IMAGES_TABLE.' + WHERE id IN ('.implode(',', array_keys($images)).') +;'; + $result = pwg_query($query); + while ($row = mysql_fetch_array($result)) + { + $images[$row['id']] = get_thumbnail_src($row['path'], @$row['tn_ext']); + } - // create a new line ? - if (++$row_number == $user['nb_image_line']) + $template->assign_block_vars('thumbnails', array()); + // first line + $template->assign_block_vars('thumbnails.line', array()); + // current row displayed + $row_number = 0; + + foreach ($cat_thumbnails as $item) { - $template->assign_block_vars('thumbnails.line', array()); - $row_number = 0; + $url_link = PHPWG_ROOT_PATH.'category.php?cat='.$row['id']; + + $template->assign_block_vars( + 'thumbnails.line.thumbnail', + array( + 'IMAGE' => $images[$item['picture']], + 'IMAGE_ALT' => $item['name'], + 'IMAGE_TITLE' => $lang['hint_category'], + 'IMAGE_TS' => get_icon(@$item['date_last']), + 'U_IMG_LINK' => + add_session_id(PHPWG_ROOT_PATH.'category.php?cat='.$item['category']) + ) + ); + + $template->assign_block_vars( + 'thumbnails.line.thumbnail.category_name', + array( + 'NAME' => $item['name'] + ) + ); + + // create a new line ? + if (++$row_number == $user['nb_image_line']) + { + $template->assign_block_vars('thumbnails.line', array()); + $row_number = 0; + } } } ?>
\ No newline at end of file diff --git a/include/config_default.inc.php b/include/config_default.inc.php index d641223da..99efedd0d 100644 --- a/include/config_default.inc.php +++ b/include/config_default.inc.php @@ -252,4 +252,17 @@ $conf['pass_convert'] = create_function('$s', 'return md5($s);'); // guest_id : id of the anonymous user $conf['guest_id'] = 2; + +// allow_random_representative : do you wish PhpWebGallery to search among +// categories elements a new representative at each reload ? +// +// If false, an element is randomly or manually chosen to represent its +// category and remains the representative as long as an admin does not +// change it. +// +// Warning : setting this parameter to true is CPU consuming. Each time you +// change the value of this parameter from false to true, an administrator +// must update categories informations in screen [Admin > General > +// Maintenance]. +$conf['allow_random_representative'] = false; ?> diff --git a/template/default/admin.tpl b/template/default/admin.tpl index db93f7ca9..8c72195d2 100644 --- a/template/default/admin.tpl +++ b/template/default/admin.tpl @@ -20,6 +20,7 @@ <li><a class="adminMenu" href="{U_PHPINFO}">{L_PHPINFO}</a></li> <li><a class="adminMenu" href="{U_HISTORY}">{L_HISTORY}</a></li> <li><a class="adminMenu" href="{U_CAT_UPDATE}">{L_UPDATE}</a></li> + <li><a class="adminMenu" href="{U_MAINTENANCE}">{lang:Maintenance}</a></li> </ul> </div> <div class="titreMenu">{L_CONFIGURATION}</div> @@ -41,6 +42,9 @@ <li><a class="adminMenu" href="{U_CAT_COMMENTS}">{L_CAT_COMMENTS}</a></li> <li><a class="adminMenu" href="{U_CAT_VISIBLE}">{L_CAT_VISIBLE}</a></li> <li><a class="adminMenu" href="{U_CAT_STATUS}">{L_CAT_STATUS}</a></li> + <!-- BEGIN representative --> + <li><a class="adminMenu" href="{representative.URL}">{lang:Representatve}</a></li> + <!-- END representative --> </ul> </div> <div class="titreMenu">{L_IMAGES}</div> @@ -91,8 +95,9 @@ </ul> </div> <!-- END infos --> - - <div align="center">{ADMIN_CONTENT}{ADMIN_CONTENT_2}</div> + <div id="adminMain"> + {ADMIN_CONTENT}{ADMIN_CONTENT_2} + </div> </div> </td> </tr> diff --git a/template/default/admin/cat_modify.tpl b/template/default/admin/cat_modify.tpl index e83f587d4..c2ddfc7ee 100644 --- a/template/default/admin/cat_modify.tpl +++ b/template/default/admin/cat_modify.tpl @@ -1,82 +1,130 @@ -<div class="admin">{CATEGORIES_NAV}</div> +<h2>{CATEGORIES_NAV}</h2> + +<ul class="categoryActions"> + <li><a href="{U_JUMPTO}" title="{lang:jump to category}"><img src="./template/default/theme/category_jump-to.png" alt="{lang:jump to}" /></a></li> + <!-- BEGIN elements --> + <li><a href="{elements.URL}" title="{lang:manage category elements}"><img src="./template/default/theme/category_elements.png" alt="{lang:elements}" /></a></li> + <!-- END elements --> + <li><a href="{U_CHILDREN}" title="{lang:manage sub-categories}"><img src="./template/default/theme/category_children.png" alt="{lang:sub-categories}" /></a></li> + <!-- BEGIN permissions --> + <li><a href="{permissions.URL}" title="{lang:edit category permissions}" ><img src="./template/default/theme/category_permissions.png" alt="{lang:permissions}" /></a></li> + <!-- END permissions --> + <!-- BEGIN delete --> + <li><a href="{delete.URL}" title="{lang:delete category}"><img src="./template/default/theme/category_delete.png" alt="{lang:delete}" /></a></li> + <!-- END delete --> +</ul> + <form action="{F_ACTION}" method="POST"> -<table style="width:100%;"> - <!-- BEGIN representant --> - <tr> - <td style="width:50%;" align="center"> - <a href="{representant.URL}"><img src="{representant.SRC}" alt="" class="miniature" /></a> - </td> - <td class="row1"><input type="submit" name="set_random_representant" value="{L_SET_RANDOM_REPRESENTANT}" class="bouton" /></td> - </tr> - <!-- END representant --> - </table> -</form> -<form action="{F_ACTION}" method="POST"> -<table style="width:100%;"> + +<fieldset> + <legend>{lang:Informations}</legend> + <table> <!-- BEGIN server --> <tr> - <td style="width:50%;"><strong>{L_REMOTE_SITE}</strong></td> - <td class="row1">{server.SITE_URL}</td> + <td><strong>{L_REMOTE_SITE}</strong></td> + <td>{server.SITE_URL}</td> </tr> <!-- END server --> + <!-- BEGIN storage --> <tr> - <td style="width:50%;"><strong>{L_EDIT_NAME}</strong></td> - <td class="row1"> - <input type="text" name="name" value="{CAT_NAME}" maxlength="60"/> - </td> - </tr> - <!-- BEGIN storage --> - <tr> <td><strong>{L_STORAGE}</strong></td> <td class="row1">{storage.CATEGORY_DIR}</td> </tr> - <!-- END storage --> + <!-- END storage --> + <tr> + <td><strong>{L_EDIT_NAME}</strong></td> + <td> + <input type="text" name="name" value="{CAT_NAME}" maxlength="60"/> + </td> + </tr> <tr> <td><strong>{L_EDIT_COMMENT}</strong></td> - <td class="row1"> + <td> <textarea name="comment" rows="3" cols="50" >{CAT_COMMENT}</textarea> </td> </tr> - <tr class="admin"> - <th colspan="2">{L_EDIT_CAT_OPTIONS}</th> - </tr> + </table> +</fieldset> + +<!-- BEGIN move --> +<fieldset> + <legend>{lang:Move}</legend> + {lang:Parent category} + <select name="parent"> + <!-- BEGIN parent_option --> + <option class="{move.parent_option.CLASS}" {move.parent_option.SELECTED} value="{move.parent_option.VALUE}">{move.parent_option.OPTION}</option> + <!-- END parent_option --> + </select> +</fieldset> +<!-- END move --> + +<fieldset> + <legend>{lang:Options}</legend> + <table> <tr> - <td><strong>{L_EDIT_STATUS} :</strong><br /><span class="small">{L_EDIT_STATUS_INFO}</span></td> - <td class="row1"> - <input type="radio" class="radio" name="status" value="public" {STATUS_PUBLIC} />{L_STATUS_PUBLIC} - <input type="radio" class="radio" name="status" value="private" {STATUS_PRIVATE} />{L_STATUS_PRIVATE} + <td><strong>{L_EDIT_STATUS}</strong><br /><span class="small">{L_EDIT_STATUS_INFO}</span></td> + <td> + <input type="radio" name="status" value="public" {STATUS_PUBLIC} />{L_STATUS_PUBLIC} + <input type="radio" name="status" value="private" {STATUS_PRIVATE} />{L_STATUS_PRIVATE} </td> </tr> <tr> - <td><strong>{L_EDIT_LOCK} :</strong><br /><span class="small">{L_EDIT_LOCK_INFO}</span></td> - <td class="row1"> - <input type="radio" class="radio" name="visible" value="false" {LOCKED} />{L_YES} - <input type="radio" class="radio" name="visible" value="true" {UNLOCKED} />{L_NO} + <td><strong>{L_EDIT_LOCK}</strong><br /><span class="small">{L_EDIT_LOCK_INFO}</span></td> + <td> + <input type="radio" name="visible" value="false" {LOCKED} />{L_YES} + <input type="radio" name="visible" value="true" {UNLOCKED} />{L_NO} </td> </tr> <tr> - <td><strong>{L_EDIT_COMMENTABLE} :</strong><br /><span class="small">{L_EDIT_COMMENTABLE_INFO}</span></td> - <td class="row1"> - <input type="radio" class="radio" name="commentable" value="true" {COMMENTABLE_TRUE} />{L_YES} - <input type="radio" class="radio" name="commentable" value="false" {COMMENTABLE_FALSE} />{L_NO} + <td><strong>{L_EDIT_COMMENTABLE}</strong><br /><span class="small">{L_EDIT_COMMENTABLE_INFO}</span></td> + <td> + <input type="radio" name="commentable" value="true" {COMMENTABLE_TRUE} />{L_YES} + <input type="radio" name="commentable" value="false" {COMMENTABLE_FALSE} />{L_NO} </td> </tr> <!-- BEGIN upload --> <tr> - <td><strong>{L_EDIT_UPLOADABLE} :</strong><br /><span class="small">{L_EDIT_UPLOADABLE_INFO}</span></td> - <td class="row1"> - <input type="radio" class="radio" name="uploadable" value="true" {UPLOADABLE_TRUE} />{L_YES} - <input type="radio" class="radio" name="uploadable" value="false" {UPLOADABLE_FALSE} />{L_NO} + <td><strong>{L_EDIT_UPLOADABLE}</strong><br /><span class="small">{L_EDIT_UPLOADABLE_INFO}</span></td> + <td> + <input type="radio" name="uploadable" value="true" {UPLOADABLE_TRUE} />{L_YES} + <input type="radio" name="uploadable" value="false" {UPLOADABLE_FALSE} />{L_NO} </td> </tr> <!-- END upload --> + </table> +</fieldset> + +<p style="text-align:center;"> + <input type="submit" value="{L_SUBMIT}" name="submit" /> + <input type="reset" value="{lang:Reset}" name="reset" /> +</p> + +<!-- BEGIN representant --> +<fieldset> + <legend>{lang:Representant}</legend> + <table> <tr> - <td colspan="2"> </td> - </tr> - <tr> - <td colspan="2" align="center"> - <input type="submit" name="submit" value="{L_SUBMIT}" class="bouton" /> + <td align="center"> + <!-- BEGIN picture --> + <a href="{representant.picture.URL}"><img src="{representant.picture.SRC}" alt="" class="miniature" /></a> + <!-- END picture --> + + <!-- BEGIN random --> + <img src="./template/default/theme/category_representant_random.png" alt="{lang:Random picture}" class="miniature" /> + <!-- END random --> + </td> + <td> + <!-- BEGIN set_random --> + <p><input type="submit" name="set_random_representant" value="{L_SET_RANDOM_REPRESENTANT}" /></p> + <!-- END set_random --> + + <!-- BEGIN delete_representant --> + <p><input type="submit" name="delete_representant" value="{lang:Delete Representant}" /></p> + <!-- END delete_representant --> </td> </tr> </table> +</fieldset> +<!-- END representant --> + </form> diff --git a/template/default/admin/maintenance.tpl b/template/default/admin/maintenance.tpl new file mode 100644 index 000000000..cb8f506ff --- /dev/null +++ b/template/default/admin/maintenance.tpl @@ -0,0 +1,9 @@ +<ul> + <li><a href="{U_MAINT_CATEGORIES}">{lang:update categories informations}</a></li> + <li><a href="{U_MAINT_IMAGES}">{lang:update images informations}</a></li> + <li><a href="{U_MAINT_HISTORY}">{lang:purge history}</a></li> + <li><a href="{U_MAINT_SESSIONS}">{lang:purge sessions}</a></li> +<!-- + <li><a href="{U_FEEDS}">{lang:purge obsolete notification feed}</a></li> +--> +</ul> diff --git a/template/default/default.css b/template/default/default.css index 3169c6a64..5091b7431 100644 --- a/template/default/default.css +++ b/template/default/default.css @@ -50,15 +50,6 @@ h1 /* H1 tag style (admin side only) */ font-weight: bold; } -h2 /* H2 tag style (admin side only) */ -{ - font-family: Arial, Helvetica, sans-serif; - text-decoration:none; - line-height: 120%; - font-size:12px; - font-weight: bold; -} - .titreMenu /* Menu titles */ { font-size:12px; @@ -365,6 +356,16 @@ input,select,textarea font-size:12px; } +div#adminMain { + text-align: left; +} + +div#adminMain h2 { + background-color: #3f3f3f; + text-align: center; + font-size: 120%; +} + div.adminMenu{ margin:10px 50px 10px 50px; } .admin @@ -413,6 +414,10 @@ form#categoryOrdering ul.categoryActions { margin-top: 5px; } +div#adminMain>ul.categoryActions { + text-align: center; +} + ul.categoryActions>li { display: inline; } @@ -490,3 +495,11 @@ FORM#categoryPermissions LI { display:inline; white-space: nowrap; } + +fieldset { + border: 1px solid gray; +} + +fieldset>legend { + margin: 5px; +} diff --git a/template/default/theme/category_representant_random.png b/template/default/theme/category_representant_random.png Binary files differnew file mode 100644 index 000000000..df0151535 --- /dev/null +++ b/template/default/theme/category_representant_random.png |