From c08fa6f67ef5b149fdeb3bcc57045e629df8fff4 Mon Sep 17 00:00:00 2001 From: plegall Date: Sat, 4 Mar 2006 23:31:46 +0000 Subject: new feature: source/destination links between categories. Will we keep this feature? Code is complicated and very few people will understand how it works... modification: #images.storage_category_id replaced by #image_category.is_storage improvement: many code refactoring to improve readibility improvement: virtual category creation code was moved to a dedicated function in order to be called from admin/cat_list.php and admin/cat_modify.php (create a new destination category) git-svn-id: http://piwigo.org/svn/trunk@1064 68402e56-0260-453c-a942-63ccdbb3a9ee --- admin/cat_list.php | 111 +------ admin/cat_modify.php | 181 +++++++++++ admin/include/functions.php | 590 +++++++++++++++++++++++++++++++++-- admin/include/functions_metadata.php | 4 +- admin/maintenance.php | 1 + admin/picture_modify.php | 6 +- admin/rating.php | 42 ++- admin/site_reader_local.php | 41 ++- admin/site_reader_remote.php | 68 ++-- admin/site_update.php | 282 ++++++++++------- include/constants.php | 2 +- install/db/10-database.php | 56 ++++ install/db/9-database.php | 90 ++++++ install/phpwebgallery_structure.sql | 46 ++- template/yoga/admin/cat_list.tpl | 1 - template/yoga/admin/cat_modify.tpl | 84 +++++ 16 files changed, 1317 insertions(+), 288 deletions(-) create mode 100644 install/db/10-database.php create mode 100644 install/db/9-database.php diff --git a/admin/cat_list.php b/admin/cat_list.php index 3acbbad5e..0c350ea00 100644 --- a/admin/cat_list.php +++ b/admin/cat_list.php @@ -83,92 +83,18 @@ if (isset($_GET['delete']) and is_numeric($_GET['delete'])) // request to add a virtual category else if (isset($_POST['submitAdd'])) { - // is the given category name only containing blank spaces ? - if (preg_match('/^\s*$/', $_POST['virtual_name'])) + $output_create = create_virtual_category( + $_POST['virtual_name'], + @$_GET['parent_id'] + ); + + if (isset($output_create['error'])) { - array_push($page['errors'], $lang['cat_error_name']); + array_push($page['errors'], $output_create['error']); } - - if (!count($page['errors'])) + else { - $parent_id = !empty($_GET['parent_id'])?$_GET['parent_id']:'NULL'; - - if ($parent_id != 'NULL') - { - $query = ' -SELECT id,uppercats,global_rank,visible,status - FROM '.CATEGORIES_TABLE.' - WHERE id = '.$parent_id.' -;'; - $row = mysql_fetch_array(pwg_query($query)); - $parent = array('id' => $row['id'], - 'uppercats' => $row['uppercats'], - 'visible' => $row['visible'], - 'status' => $row['status'], - 'global_rank' => $row['global_rank']); - } - - // what will be the inserted id ? - $query = ' -SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) - FROM '.CATEGORIES_TABLE.' -;'; - list($next_id) = mysql_fetch_array(pwg_query($query)); - - $insert = array(); - $insert{'id'} = $next_id++; - $insert{'name'} = $_POST['virtual_name']; - $insert{'rank'} = $_POST['rank']; - $insert{'commentable'} = $conf['newcat_default_commentable']; - - // a virtual category can't be uploadable - $insert{'uploadable'} = 'false'; - - if (isset($parent)) - { - $insert{'id_uppercat'} = $parent{'id'}; - $insert{'uppercats'} = $parent{'uppercats'}.','.$insert{'id'}; - $insert{'global_rank'} = $parent{'global_rank'}.'.'.$insert{'rank'}; - // at creation, must a category be visible or not ? Warning : if - // the parent category is invisible, the category is automatically - // create invisible. (invisible = locked) - if ('false' == $parent['visible']) - { - $insert{'visible'} = 'false'; - } - else - { - $insert{'visible'} = $conf['newcat_default_visible']; - } - // at creation, must a category be public or private ? Warning : - // if the parent category is private, the category is - // automatically create private. - if ('private' == $parent['status']) - { - $insert{'status'} = 'private'; - } - else - { - $insert{'status'} = $conf['newcat_default_status']; - } - } - else - { - $insert{'visible'} = $conf['newcat_default_visible']; - $insert{'status'} = $conf['newcat_default_status']; - $insert{'uppercats'} = $insert{'id'}; - $insert{'global_rank'} = $insert{'rank'}; - } - - $inserts = array($insert); - - // we have then to add the virtual category - $dbfields = array('id','site_id','name','id_uppercat','rank', - 'commentable','uploadable','visible','status', - 'uppercats','global_rank'); - mass_inserts(CATEGORIES_TABLE, $dbfields, $inserts); - - array_push($page['infos'], $lang['cat_virtual_added']); + array_push($page['infos'], $output_create['info']); } } else if (isset($_POST['submitOrder'])) @@ -211,9 +137,12 @@ if (isset($_GET['parent_id'])) $navigation.= $conf['level_separator']; $current_category = get_cat_info($_GET['parent_id']); - $navigation.= get_cat_display_name($current_category['name'], - $base_url.'&parent_id=', - false); + + $navigation.= get_cat_display_name( + $current_category['name'], + $base_url.'&parent_id=', + false + ); } // +-----------------------------------------------------------------------+ // | template initialization | @@ -226,18 +155,8 @@ if (isset($_GET['parent_id'])) $form_action.= '&parent_id='.$_GET['parent_id']; } -if (count($categories) > 0) -{ - $next_rank = max(array_keys($categories)) + 1; -} -else -{ - $next_rank = 1; -} - $template->assign_vars(array( 'CATEGORIES_NAV'=>$navigation, - 'NEXT_RANK'=>$next_rank, 'F_ACTION'=>$form_action, 'L_ADD_VIRTUAL'=>$lang['cat_add'], diff --git a/admin/cat_modify.php b/admin/cat_modify.php index 309425c91..e06e1a8cb 100644 --- a/admin/cat_modify.php +++ b/admin/cat_modify.php @@ -88,6 +88,122 @@ UPDATE '.CATEGORIES_TABLE.' ;'; pwg_query($query); } +else if (isset($_POST['submitAdd'])) +{ + $output_create = create_virtual_category( + $_POST['virtual_name'], + (0 == $_POST['parent'] ? null : $_POST['parent']) + ); + + if (isset($output_create['error'])) + { + array_push($page['errors'], $output_create['error']); + } + else + { + // Virtual category creation succeeded + // + // Add the information in the information list + array_push($page['infos'], $output_create['info']); + + // Link the new category to the current category + $query = ' +INSERT + INTO '.CATEGORIES_LINK_TABLE.' + (source, destination) + VALUES + ('.$_GET['cat_id'].', '.$output_create['id'].') +;'; + pwg_query($query); + + check_links(array($output_create['id'])); + update_category(array($output_create['id'])); + } +} +else if (isset($_POST['destination_trueify']) + and isset($_POST['destination_false']) + and count($_POST['destination_false'])) +{ + $datas = array(); + + foreach ($_POST['destination_false'] as $category_id) + { + array_push( + $datas, + array( + 'source' => $_GET['cat_id'], + 'destination' => $category_id, + ) + ); + } + + mass_inserts( + CATEGORIES_LINK_TABLE, + array('source', 'destination'), + $datas + ); + + check_links($_POST['destination_false']); + update_category( + $_POST['destination_false'], + true // recursive update + ); +} +else if (isset($_POST['destination_falsify']) + and isset($_POST['destination_true']) + and count($_POST['destination_true'])) +{ + foreach ($_POST['destination_true'] as $destination) + { + delete_sources($destination, array($_GET['cat_id'])); + } + + update_category( + $_POST['destination_true'], + true // recursive update + ); +} +else if (isset($_POST['source_trueify']) + and isset($_POST['source_false']) + and count($_POST['source_false'])) +{ + $datas = array(); + + foreach ($_POST['source_false'] as $category_id) + { + array_push( + $datas, + array( + 'source' => $category_id, + 'destination' => $_GET['cat_id'], + ) + ); + } + + mass_inserts( + CATEGORIES_LINK_TABLE, + array('source', 'destination'), + $datas + ); + + check_links(array($_GET['cat_id'])); + update_category( + array($_GET['cat_id']), + true // recursive update + ); +} +else if (isset($_POST['source_falsify']) + and isset($_POST['source_true']) + and count($_POST['source_true'])) +{ + delete_sources($_GET['cat_id'], $_POST['source_true']); + + update_category( + array($_GET['cat_id']), + true // recursive update + ); +} + $query = ' SELECT * @@ -316,6 +432,71 @@ if (!$category['is_virtual'] and !url_is_remote($category['cat_dir']) ) $template->assign_block_vars('upload' ,array()); } +$blockname = 'category_option_parent'; + +$template->assign_block_vars( + $blockname, + array( + 'VALUE'=> 0, + 'OPTION' => '------------' + ) + ); + +$query = ' +SELECT id,name,uppercats,global_rank + FROM '.CATEGORIES_TABLE.' +;'; + +display_select_cat_wrapper( + $query, + array(), + $blockname + ); + +// destination categories +$query = ' +SELECT DISTINCT id, name, uppercats, global_rank + FROM '.CATEGORIES_TABLE.' + INNER JOIN '.CATEGORIES_LINK_TABLE.' ON destination = id + WHERE source = '.$_GET['cat_id'].' +;'; +display_select_cat_wrapper($query, array(), 'destination_option_true'); + +// non destination categories +$destinations = array_merge( + array($_GET['cat_id']), + array_from_query($query, 'id') + ); + +$query = ' +SELECT DISTINCT id, name, uppercats, global_rank + FROM '.CATEGORIES_TABLE.' + WHERE id NOT IN ('.implode(',', $destinations).') +;'; +display_select_cat_wrapper($query, array(), 'destination_option_false'); + +// source categories +$query = ' +SELECT DISTINCT id, name, uppercats, global_rank + FROM '.CATEGORIES_TABLE.' + INNER JOIN '.CATEGORIES_LINK_TABLE.' ON source = id + WHERE destination = '.$_GET['cat_id'].' +;'; +display_select_cat_wrapper($query, array(), 'source_option_true'); + +// non source categories +$sources = array_merge( + array($_GET['cat_id']), + array_from_query($query, 'id') + ); + +$query = ' +SELECT DISTINCT id, name, uppercats, global_rank + FROM '.CATEGORIES_TABLE.' + WHERE id NOT IN ('.implode(',', $sources).') +;'; +display_select_cat_wrapper($query, array(), 'source_option_false'); + //----------------------------------------------------------- sending html code $template->assign_var_from_handle('ADMIN_CONTENT', 'categories'); ?> diff --git a/admin/include/functions.php b/admin/include/functions.php index 9c385092e..a1c13cd05 100644 --- a/admin/include/functions.php +++ b/admin/include/functions.php @@ -1,3 +1,4 @@ + $sources) + { + delete_sources($destination, $sources); + } + + update_category(); + // destruction of the category $query = ' DELETE FROM '.CATEGORIES_TABLE.' @@ -395,30 +434,48 @@ SELECT id SELECT category_id, COUNT(image_id) AS nb_images, MAX(date_available) AS date_last - FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id + FROM '.IMAGES_TABLE.' + INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id WHERE category_id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").') GROUP BY category_id ;'; $result = pwg_query($query); $datas = array(); $query_ids = array(); - while ( $row = mysql_fetch_array( $result ) ) + while ($row = mysql_fetch_array($result)) { array_push($query_ids, $row['category_id']); - array_push($datas, array('id' => $row['category_id'], - 'date_last' => $row['date_last'], - 'nb_images' => $row['nb_images'])); + + array_push( + $datas, + array( + 'id' => $row['category_id'], + 'date_last' => $row['date_last'], + 'nb_images' => $row['nb_images'] + ) + ); } // if all links between a category and elements have disappeared, no line // is returned but the update must be done ! foreach (array_diff($cat_ids, $query_ids) as $id) { - array_push($datas, array('id' => $id, 'nb_images' => 0)); + array_push( + $datas, + array( + 'id' => $id, + 'nb_images' => 0, + ) + ); } - $fields = array('primary' => array('id'), - 'update' => array('date_last', 'nb_images')); - mass_updates(CATEGORIES_TABLE, $fields, $datas); + mass_updates( + CATEGORIES_TABLE, + array( + 'primary' => array('id'), + 'update' => array('date_last', 'nb_images') + ), + $datas + ); // representative pictures if (count($cat_ids) > 0) @@ -1291,19 +1348,42 @@ SELECT id, id_uppercat */ function update_path() { + $images_of = array(); + $query = ' -SELECT DISTINCT(storage_category_id) - FROM '.IMAGES_TABLE.' +SELECT category_id, image_id + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE is_storage = \'true\' ;'; - $cat_ids = array_from_query($query, 'storage_category_id'); - $fulldirs = get_fulldirs($cat_ids); + $result = pwg_query($query); + while ($row = mysql_fetch_array($result)) + { + if (!isset($images_of[ $row['category_id'] ])) + { + $images_of[ $row['category_id'] ] = array(); + } - foreach ($cat_ids as $cat_id) + array_push( + $images_of[ $row['category_id'] ], + $row['image_id'] + ); + } + + $fulldirs = get_fulldirs( + array_keys($images_of) + ); + + foreach ($images_of as $cat_id => $image_ids) { $query = ' UPDATE '.IMAGES_TABLE.' SET path = CONCAT(\''.$fulldirs[$cat_id].'\',\'/\',file) - WHERE storage_category_id = '.$cat_id.' + WHERE id IN ('. + wordwrap( + implode(', ', $image_ids), + 80, + "\n"). + ') ;'; pwg_query($query); } @@ -1522,4 +1602,474 @@ DELETE FROM '.$table.' ) ); } + +/** + * Returns all destinations of a list of source categories. This function + * solves transitivity. + * + * @param mixed array of category ids, empty for all categories + */ +function get_destinations($categories = 'all') +{ + $query = ' +SELECT source, destination + FROM '.CATEGORIES_LINK_TABLE.' +'; + $result = pwg_query($query); + + $destinations_of = array(); + + while ($row = mysql_fetch_array($result)) + { + if (!isset($destinations_of[ $row['source'] ])) + { + $destinations_of[ $row['source'] ] = array(); + } + + array_push( + $destinations_of[ $row['source'] ], + $row['destination'] + ); + } + + // transitivity resolution: if " => " means "source of", if A=>B=>C + // implies A=>B and A=>C. So A has 2 destinations: B and C. + do + { + // let's suppose we only need a single turn + $need_new_turn = false; + + foreach ($destinations_of as $source => $destinations) + { + foreach ($destinations as $destination) + { + // does the current destination has destinations itself? + if (isset($destinations_of[$destination])) + { + // are there destinations of current destination not already among + // destinations of the current source? (advise: take a piece of + // paper and draw a schema). The source itself must not be counted + // as a destination, thus avoiding cyclic links. + $missing_destinations = array_diff( + $destinations_of[$destination], + $destinations, + array($source) // no cyclic link + ); + + if (count($missing_destinations) > 0) + { + $destinations_of[$source] = array_unique( + array_merge( + $destinations, + $missing_destinations + ) + ); + + // a category has a least one new destination, we have to check + // one more time that it doesn't generate more destinations + $need_new_turn = true; + } + } + } + } + } while ($need_new_turn); + + if (is_array($categories)) + { + $filtered_destinations_of = array(); + + // Even if there is no destinations for the requested categories, we + // return empty arrays + foreach ($categories as $category) + { + $filtered_destinations_of[$category] = array(); + } + + foreach ($destinations_of as $source => $destinations) + { + if (in_array($source, $categories)) + { + $filtered_destinations_of[$source] = $destinations; + } + } + + return $filtered_destinations_of; + } + else + { + return $destinations_of; + } +} + +/** + * Returns all sources of a list of destination categories. This function + * solves transitivity. + * + * @param mixed array of category ids, empty for all categories + */ +function get_sources($categories = 'all') +{ + $destinations_of = get_destinations(); + + $sources_of = array(); + + foreach ($destinations_of as $source => $destinations) + { + foreach ($destinations as $destination) + { + if (!isset($sources_of[$destination])) + { + $sources_of[$destination] = array(); + } + + array_push($sources_of[$destination], $source); + } + } + + // eventually, filter + if (is_array($categories)) + { + $filtered_sources_of = array(); + + // Even if there is no sources for the requested categories, we return + // empty arrays + foreach ($categories as $category) + { + $filtered_sources_of[$category] = array(); + } + + foreach ($sources_of as $destination => $sources) + { + if (in_array($destination, $categories)) + { + $filtered_sources_of[$destination] = $sources; + } + } + + return $filtered_sources_of; + } + else + { + return $sources_of; + } +} + +/** + * Checks categories links are respected for a given list of destinations. + * + * Checking categories links means that each destination must be associated + * to the images of its sources. + * + * @param mixed source category ids + */ +function check_links($destinations = 'all') +{ + $sources_of = get_sources($destinations); + + if (empty($sources_of)) + { + return true; + } + + // we need to search images of all sources and destinations + $images_of = array(); + + foreach ($sources_of as $destination => $sources) + { + $images_of[$destination] = array(); + + foreach ($sources as $source) + { + $images_of[$source] = array(); + } + } + + $query = ' +SELECT image_id, category_id + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE category_id IN ('. + implode(',', array_keys($images_of)). + ') +;'; + $result = pwg_query($query); + + while ($row = mysql_fetch_array($result)) + { + array_push( + $images_of[ $row['category_id'] ], + $row['image_id'] + ); + } + + $inserts = array(); + + foreach ($sources_of as $destination => $sources) + { + // merge all images from the sources of this destination + $sources_images = array(); + + foreach ($sources as $source) + { + $sources_images = array_merge( + $sources_images, + $images_of[$source] + ); + } + + $sources_images = array_unique($sources_images); + + // are there images among the sources that are not linked to the + // destination? + $missing_images = array_diff( + $sources_images, + $images_of[$destination] + ); + + // if we find missing images (missing links in reality), we prepare the + // final mass_inserts + if (count($missing_images) > 0) + { + foreach ($missing_images as $missing_image) + { + array_push( + $inserts, + array( + 'category_id' => $destination, + 'image_id' => $missing_image, + ) + ); + } + } + } + + if (count($inserts) > 0) + { + mass_inserts( + IMAGE_CATEGORY_TABLE, + array_keys($inserts[0]), + $inserts + ); + } +} + +/** + * Based on categories links, delete image_category links on destinations. + * + * The rule is the following: if an image belong to the category and to the + * source, we suppose it comes from the source. If the source/destination + * link is broken, we delete the image/category link if the only origin of + * the link was the broken categories link. + * + * Example: "=>" means "source of". Between brackets the associated images. + * + * A (1,2,9) => \ + * |=> C (1,2,3,4,5,9) => D (1,2,3,4,5,6,9) + * B (3,4,9) => / + * + * In category C, we suppose (1,2) come from A, (3,4) from B, 9 from A or B + * and 5 was manually added. In category D, 6 was added manually. + * + * If we break A=>C, C and D loose (1,2) but not 9 because it can come from + * B. If we break C=>D, D loose (3,4,5,9) but not 6 because it was + * associated manually to 9. + * + * Warning: only virtual links can be removed, physical links are protected. + * + * @param int destination + * @param array sources + */ +function delete_sources($destination, $sources) +{ + // if no sources to unlink, we stop with OK status + if (count($sources) == 0) + { + return true; + } + + $query = ' +DELETE + FROM '.CATEGORIES_LINK_TABLE.' + WHERE destination = '.$destination.' + AND source IN ('.implode(',', $sources).') +;'; + pwg_query($query); + + // The strategy is the following: + // + // * first we brutally delete the image/category associations on + // destinations categories for all images belonging to sources. + // + // * then we check_links on destinations to rebuild missing image/category + // associations. + + // what are the images associated to the sources to unlink + $query = ' +SELECT image_id + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE category_id IN ('. + implode(',', $sources). + ') +;'; + $sources_images = array_unique( + array_from_query($query, 'image_id') + ); + + if (count($sources_images) == 0) + { + return true; + } + + // retrieve all direct and indirect destinations of the current + // destination + $destinations_of = get_destinations(array($destination)); + + $destinations = array_merge( + array($destination), + $destinations_of[$destination] + ); + + // unlink sources images from destinations + $query = ' +DELETE + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE category_id IN ('.implode(',', $destinations).') + AND image_id IN ('.implode(',', $sources_images).') + AND is_storage = \'false\' +;'; + pwg_query($query); + + // if the representative thumbnail of destinations was a picture from + // $sources_images, we request a new random representant + $query = ' +SELECT id, representative_picture_id + FROM '.CATEGORIES_TABLE.' + WHERE id IN ('.implode(',', $destinations).') +;'; + $result = pwg_query($query); + + $request_random = array(); + + while ($row = mysql_fetch_array($result)) + { + if (isset($row['representative_picture_id'])) + { + if (in_array($row['representative_picture_id'], $sources_images)) + { + array_push($request_random, $row['id']); + } + } + } + + set_random_representant($request_random); + + // eventually, we check_links to rebuild missing associations + check_links($destinations); + + return true; +} + +/** + * create a virtual category + * + * @param string category name + * @param int parent category id + * @return array with ('info' and 'id') or ('error') key + */ +function create_virtual_category($category_name, $parent_id=null) +{ + global $conf; + + // is the given category name only containing blank spaces ? + if (preg_match('/^\s*$/', $category_name)) + { + return array('error' => l10n('cat_error_name')); + } + + $parent_id = !empty($parent_id) ? $parent_id : 'NULL'; + + $query = ' +SELECT MAX(rank) + FROM '.CATEGORIES_TABLE.' + WHERE id_uppercat '.(is_numeric($parent_id) ? '= '.$parent_id : 'IS NULL').' +;'; + list($current_rank) = mysql_fetch_array(pwg_query($query)); + + $insert = array( + 'name' => $category_name, + 'rank' => ++$current_rank, + 'commentable' => $conf['newcat_default_commentable'], + 'uploadable' => 'false', + ); + + if ($parent_id != 'NULL') + { + $query = ' +SELECT id, uppercats, global_rank, visible, status + FROM '.CATEGORIES_TABLE.' + WHERE id = '.$parent_id.' +;'; + $parent = mysql_fetch_array(pwg_query($query)); + + $insert{'id_uppercat'} = $parent{'id'}; + $insert{'global_rank'} = $parent{'global_rank'}.'.'.$insert{'rank'}; + + // at creation, must a category be visible or not ? Warning : if the + // parent category is invisible, the category is automatically create + // invisible. (invisible = locked) + if ('false' == $parent['visible']) + { + $insert{'visible'} = 'false'; + } + else + { + $insert{'visible'} = $conf['newcat_default_visible']; + } + + // at creation, must a category be public or private ? Warning : if the + // parent category is private, the category is automatically create + // private. + if ('private' == $parent['status']) + { + $insert{'status'} = 'private'; + } + else + { + $insert{'status'} = $conf['newcat_default_status']; + } + } + else + { + $insert{'visible'} = $conf['newcat_default_visible']; + $insert{'status'} = $conf['newcat_default_status']; + $insert{'global_rank'} = $insert{'rank'}; + } + + // we have then to add the virtual category + mass_inserts( + CATEGORIES_TABLE, + array( + 'site_id', 'name', 'id_uppercat', 'rank', 'commentable', + 'uploadable', 'visible', 'status', 'global_rank', + ), + array($insert) + ); + + $inserted_id = mysql_insert_id(); + + $query = ' +UPDATE + '.CATEGORIES_TABLE.' + SET uppercats = \''. + (isset($parent) ? $parent{'uppercats'}.',' : ''). + $inserted_id. + '\' + WHERE id = '.$inserted_id.' +;'; + pwg_query($query); + + return array( + 'info' => l10n('cat_virtual_added'), + 'id' => $inserted_id, + ); +} ?> diff --git a/admin/include/functions_metadata.php b/admin/include/functions_metadata.php index 23dca79a9..337019b2e 100644 --- a/admin/include/functions_metadata.php +++ b/admin/include/functions_metadata.php @@ -224,7 +224,9 @@ SELECT id $query = ' SELECT id, path FROM '.IMAGES_TABLE.' - WHERE storage_category_id IN ('.implode(',', $cat_ids).')'; + INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id + WHERE is_storage = \'true\' + AND category_id IN ('.implode(',', $cat_ids).')'; if ($only_new) { $query.= ' diff --git a/admin/maintenance.php b/admin/maintenance.php index 067f1ff82..5653ed4cd 100644 --- a/admin/maintenance.php +++ b/admin/maintenance.php @@ -41,6 +41,7 @@ switch ($action) { case 'categories' : { + check_links(); update_uppercats(); update_category('all'); ordering(); diff --git a/admin/picture_modify.php b/admin/picture_modify.php index 097857ec5..a4d5d8ac5 100644 --- a/admin/picture_modify.php +++ b/admin/picture_modify.php @@ -171,11 +171,13 @@ if (isset($_POST['dismiss']) $query = ' SELECT * FROM '.IMAGES_TABLE.' + INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id WHERE id = '.$_GET['image_id'].' + AND is_storage = \'true\' ;'; $row = mysql_fetch_array(pwg_query($query)); -$storage_category_id = $row['storage_category_id']; +$storage_category_id = $row['category_id']; // Navigation path @@ -341,7 +343,7 @@ SELECT id,name,uppercats,global_rank FROM '.CATEGORIES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = category_id WHERE image_id = '.$_GET['image_id'].' - AND id != '.$storage_category_id.' + AND is_storage = \'false\' ;'; display_select_cat_wrapper($query, array(), 'associated_option'); diff --git a/admin/rating.php b/admin/rating.php index 6be2dd8ca..38f58f3ff 100644 --- a/admin/rating.php +++ b/admin/rating.php @@ -168,16 +168,26 @@ for ($i=0; $isite_url)) { - array_push($errors, array('path' => $this->site_url, 'type' => 'PWG-ERROR-NO-FS')); + array_push( + $errors, + array( + 'path' => $this->site_url, + 'type' => 'PWG-ERROR-NO-FS' + ) + ); + return false; } + return true; } @@ -135,8 +144,11 @@ function get_elements($path) function get_update_attributes() { global $conf; - $update_fields = array( 'has_high', 'representative_ext', - 'filesize', 'width', 'height' ); + + $update_fields = array( + 'has_high', 'representative_ext', 'filesize', 'width', 'height' + ); + if ($conf['use_exif']) { $update_fields = @@ -154,6 +166,7 @@ function get_update_attributes() array_keys($conf['use_iptc_mapping']) ); } + return $update_fields; } @@ -169,9 +182,13 @@ function get_element_update_attributes($file) $data = array(); $filename = basename($file); - $data['has_high'] = $this->get_has_high( dirname($file), $filename ); - $data['representative_ext'] = $this->get_representative_ext( dirname($file), - get_filename_wo_extension($filename) ); + + $data['has_high'] = $this->get_has_high(dirname($file), $filename); + + $data['representative_ext'] = $this->get_representative_ext( + dirname($file), + get_filename_wo_extension($filename) + ); $data['filesize'] = floor(filesize($file)/1024); if ($image_size = @getimagesize($file)) @@ -204,6 +221,7 @@ function get_element_update_attributes($file) } } } + return $data; } @@ -212,8 +230,7 @@ function get_element_update_attributes($file) function get_representative_ext($path, $filename_wo_ext) { global $conf; - $base_test = $path.'/pwg_representative/'; - $base_test.= $filename_wo_ext.'.'; + $base_test = $path.'/pwg_representative/'.$filename_wo_ext.'.'; foreach ($conf['picture_ext'] as $ext) { $test = $base_test.$ext; @@ -228,8 +245,10 @@ function get_representative_ext($path, $filename_wo_ext) function get_tn_ext($path, $filename_wo_ext) { global $conf; - $base_test = $path.'/thumbnail/'; - $base_test.= $conf['prefix_thumbnail'].$filename_wo_ext.'.'; + + $base_test = + $path.'/thumbnail/'.$conf['prefix_thumbnail'].$filename_wo_ext.'.'; + foreach ($conf['picture_ext'] as $ext) { $test = $base_test.$ext; @@ -238,6 +257,7 @@ function get_tn_ext($path, $filename_wo_ext) return $ext; } } + return null; } @@ -247,6 +267,7 @@ function get_has_high($path, $filename) { return 'true'; } + return null; } diff --git a/admin/site_reader_remote.php b/admin/site_reader_remote.php index 3bcd367d3..1810b955b 100644 --- a/admin/site_reader_remote.php +++ b/admin/site_reader_remote.php @@ -39,8 +39,12 @@ var $update_attributes; function RemoteSiteReader($url) { $this->site_url = $url; - $this->insert_attributes = array('tn_ext', 'representative_ext', 'has_high'); - $this->update_attributes = array( 'representative_ext', 'has_high', 'filesize', 'width', 'height' ); + $this->insert_attributes = array( + 'tn_ext', 'representative_ext', 'has_high' + ); + $this->update_attributes = array( + 'representative_ext', 'has_high', 'filesize', 'width', 'height' + ); } /** @@ -51,6 +55,7 @@ function RemoteSiteReader($url) function open() { global $errors; + $listing_file = $this->site_url.'/listing.xml'; if (@fopen($listing_file, 'r')) { @@ -58,20 +63,38 @@ function open() $this->site_files = array(); $xml_content = getXmlCode($listing_file); $info_xml_element = getChild($xml_content, 'informations'); - if ( getAttribute($info_xml_element , 'phpwg_version') != PHPWG_VERSION ) + if (getAttribute($info_xml_element , 'phpwg_version') != PHPWG_VERSION) { - array_push($errors, array('path' => $listing_file, 'type' => 'PWG-ERROR-VERSION')); + array_push( + $errors, + array( + 'path' => $listing_file, + 'type' => 'PWG-ERROR-VERSION' + ) + ); + return false; } - $meta_attributes = explode ( ',', - getAttribute($info_xml_element , 'metadata') ); - $this->update_attributes = array_merge( $this->update_attributes, $meta_attributes ); + + $this->update_attributes = array_merge( + $this->update_attributes, + explode(',', getAttribute($info_xml_element, 'metadata')) + ); + $this->build_structure($xml_content, '', 0); + return true; } else { - array_push($errors, array('path' => $listing_file, 'type' => 'PWG-ERROR-NOLISTING')); + array_push( + $errors, + array( + 'path' => $listing_file, + 'type' => 'PWG-ERROR-NOLISTING' + ) + ); + return false; } } @@ -83,8 +106,8 @@ function get_full_directories($basedir) foreach ( array_keys($this->site_dirs) as $dir) { $full_dir = $this->site_url . $dir; - if ( $full_dir!=$basedir - and strpos($full_dir, $basedir)===0 + if ($full_dir != $basedir + and strpos($full_dir, $basedir) === 0 ) { array_push($dirs, $full_dir); @@ -105,12 +128,14 @@ function get_elements($path) foreach ( $this->site_dirs as $dir=>$files) { $full_dir = $this->site_url . $dir; - if ( strpos($full_dir, $path)===0 ) + if (strpos($full_dir, $path) === 0) { - foreach ( $files as $file) + foreach ($files as $file) { - $data = $this->get_element_attributes($file, - $this->insert_attributes); + $data = $this->get_element_attributes( + $file, + $this->insert_attributes + ); $elements[$file] = $data; } } @@ -129,8 +154,10 @@ function get_update_attributes() // returns a hash of attributes (metadata+filesize+width,...) for file function get_element_update_attributes($file) { - return $this->get_element_attributes($file, - $this->update_attributes); + return $this->get_element_attributes( + $file, + $this->update_attributes + ); } //-------------------------------------------------- private functions -------- @@ -143,7 +170,7 @@ function get_element_update_attributes($file) function get_element_attributes($file, $attributes) { $xml_element = $this->site_files[$file]; - if ( ! isset($xml_element) ) + if (!isset($xml_element)) { return null; } @@ -177,12 +204,15 @@ function build_structure($xml_content, $basedir, $level) if ($basedir != '') { - $xml_elements = getChildren( getChild($xml_content, 'root'), 'element' ); + $xml_elements = getChildren( + getChild($xml_content, 'root'), + 'element' + ); foreach ($xml_elements as $xml_element) { $path = getAttribute($xml_element, 'path'); $this->site_files[$path] = $xml_element; - array_push( $this->site_dirs[$basedir], $path); + array_push($this->site_dirs[$basedir], $path); } } } diff --git a/admin/site_update.php b/admin/site_update.php index 04f395190..8c5ecf54c 100644 --- a/admin/site_update.php +++ b/admin/site_update.php @@ -27,22 +27,25 @@ if (!defined('PHPWG_ROOT_PATH')) { - die ('Hacking attempt!'); + die('Hacking attempt!'); } include_once( PHPWG_ROOT_PATH.'admin/include/isadmin.inc.php'); -if (! is_numeric($_GET['site']) ) +if (!is_numeric($_GET['site'])) { die ('site param missing or invalid'); } $site_id = $_GET['site']; -$query='SELECT galleries_url FROM '.SITES_TABLE.' -WHERE id='.$site_id.' + +$query=' +SELECT galleries_url + FROM '.SITES_TABLE.' + WHERE id = '.$site_id.' ;'; -list($site_url)=mysql_fetch_row(pwg_query($query)); -if (! isset($site_url) ) +list($site_url) = mysql_fetch_row(pwg_query($query)); +if (!isset($site_url)) { - die ("site $site_id does not exist"); + die('site '.$site_id.' does not exist'); } $site_is_remote = url_is_remote($site_url); @@ -50,24 +53,33 @@ list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();')); define('CURRENT_DATE', $dbnow); $error_labels = array( - 'PWG-UPDATE-1' => array( l10n('update_wrong_dirname_short'), - l10n('update_wrong_dirname_info') ), - 'PWG-UPDATE-2' => array( l10n('update_missing_tn_short'), - l10n('update_missing_tn_info') - . implode(',', $conf['picture_ext']) ), - 'PWG-ERROR-NO-FS' => array( l10n('update_missing_file_or_dir'), - l10n('update_missing_file_or_dir_info')), - 'PWG-ERROR-VERSION' => array( l10n('update_err_pwg_version_differs'), - l10n('update_err_pwg_version_differs_info')), - 'PWG-ERROR-NOLISTING' => array( l10n('update_err_remote_listing_not_found'), - l10n('update_err_remote_listing_not_found_info')) - ); + 'PWG-UPDATE-1' => array( + l10n('update_wrong_dirname_short'), + l10n('update_wrong_dirname_info') + ), + 'PWG-UPDATE-2' => array( + l10n('update_missing_tn_short'), + l10n('update_missing_tn_info').implode(',', $conf['picture_ext']) + ), + 'PWG-ERROR-NO-FS' => array( + l10n('update_missing_file_or_dir'), + l10n('update_missing_file_or_dir_info') + ), + 'PWG-ERROR-VERSION' => array( + l10n('update_err_pwg_version_differs'), + l10n('update_err_pwg_version_differs_info') + ), + 'PWG-ERROR-NOLISTING' => array( + l10n('update_err_remote_listing_not_found'), + l10n('update_err_remote_listing_not_found_info') + ) + ); $errors = array(); $infos = array(); if ($site_is_remote) { - include_once( PHPWG_ROOT_PATH.'admin/site_reader_remote.php'); + include_once(PHPWG_ROOT_PATH.'admin/site_reader_remote.php'); $site_reader = new RemoteSiteReader($site_url); } else @@ -76,7 +88,7 @@ else $site_reader = new LocalSiteReader($site_url); } -$general_failure=true; +$general_failure = true; if (isset($_POST['submit'])) { if ($site_reader->open()) @@ -213,23 +225,18 @@ SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_id $dir = basename($fulldir); if (preg_match('/^[a-zA-Z0-9-_.]+$/', $dir)) { - $insert = array(); - - $insert{'id'} = $next_id++; - $insert{'dir'} = $dir; - $insert{'name'} = str_replace('_', ' ', $dir); - $insert{'site_id'} = $site_id; - $insert{'commentable'} = $conf['newcat_default_commentable']; - if (! $site_is_remote) - { - $insert{'uploadable'} = $conf['newcat_default_uploadable']; - } - else - { - $insert{'uploadable'} = 'false'; - } - $insert{'status'} = $conf{'newcat_default_status'}; - $insert{'visible'} = $conf{'newcat_default_visible'}; + $insert = array( + 'id' => $next_id++, + 'dir' => $dir, + 'name' => str_replace('_', ' ', $dir), + 'site_id' => $site_id, + 'commentable' => $conf['newcat_default_commentable'], + 'uploadable' => $site_is_remote + ? false + : $conf['newcat_default_uploadable'], + 'status' => $conf{'newcat_default_status'}, + 'visible' => $conf{'newcat_default_visible'}, + ); if (isset($db_fulldirs[dirname($fulldir)])) { @@ -258,8 +265,13 @@ SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_id } array_push($inserts, $insert); - array_push($infos, array('path' => $fulldir, - 'info' => l10n('update_research_added'))); + array_push( + $infos, + array( + 'path' => $fulldir, + 'info' => l10n('update_research_added') + ) + ); // add the new category to $db_categories and $db_fulldirs array $db_categories[$insert{'id'}] = @@ -275,7 +287,13 @@ SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_id } else { - array_push($errors, array('path' => $fulldir, 'type' => 'PWG-UPDATE-1')); + array_push( + $errors, + array( + 'path' => $fulldir, + 'type' => 'PWG-UPDATE-1' + ) + ); } } @@ -338,8 +356,15 @@ if (isset($_POST['submit']) and $_POST['sync'] == 'files' $query = ' SELECT id, path FROM '.IMAGES_TABLE.' - WHERE storage_category_id IN ( -'.wordwrap(implode(', ', $cat_ids), 80, "\n").') + INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id + WHERE is_storage = \'true\' + AND category_id IN ('. + wordwrap( + implode(', ', $cat_ids), + 80, + "\n" + ). + ') ;'; $result = pwg_query($query); while ($row = mysql_fetch_array($result)) @@ -361,8 +386,10 @@ SELECT file,storage_category_id { array_push( $db_unvalidated, - array_search($row['storage_category_id'], - $db_fulldirs).'/'.$row['file'] + array_search( + $row['storage_category_id'], + $db_fulldirs) + .'/'.$row['file'] ); } } @@ -391,7 +418,14 @@ SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_element_id $filename = basename($path); if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $filename)) { - array_push($errors, array('path' => $path, 'type' => 'PWG-UPDATE-1')); + array_push( + $errors, + array( + 'path' => $path, + 'type' => 'PWG-UPDATE-1' + ) + ); + continue; } @@ -401,67 +435,90 @@ SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_element_id if (in_array(get_extension($filename), $conf['picture_ext'])) { // if we found a thumnbnail corresponding to our picture... - if ( isset($fs[$path]['tn_ext']) ) + if (isset($fs[$path]['tn_ext'])) { - $insert{'id'} = $next_element_id++; - $insert{'file'} = $filename; - $insert{'storage_category_id'} = $db_fulldirs[$dirname]; - $insert{'date_available'} = CURRENT_DATE; - $insert{'tn_ext'} = $fs[$path]['tn_ext']; - if ( isset($fs[$path]['has_high']) ) - { - $insert{'has_high'} = $fs[$path]['has_high']; - } - else - { - $insert{'has_high'} = null; - } - $insert{'path'} = $path; - - array_push($inserts, $insert); - array_push($insert_links, - array('image_id' => $insert{'id'}, - 'category_id' => $insert{'storage_category_id'})); - array_push($infos, array('path' => $insert{'path'}, - 'info' => l10n('update_research_added'))); + $insert = array( + 'id' => $next_element_id++, + 'file' => $filename, + 'date_available' => CURRENT_DATE, + 'tn_ext' => $fs[$path]['tn_ext'], + 'has_high' => isset($fs[$path]['has_high']) + ? $fs[$path]['has_high'] + : null, + 'path' => $path, + ); + + array_push( + $inserts, + $insert + ); + + array_push( + $insert_links, + array( + 'image_id' => $insert{'id'}, + 'category_id' => $db_fulldirs[$dirname], + 'is_storage' => 'true', + ) + ); + array_push( + $infos, + array( + 'path' => $insert{'path'}, + 'info' => l10n('update_research_added') + ) + ); } else { - array_push($errors, array('path' => $path, 'type' => 'PWG-UPDATE-2')); + array_push( + $errors, + array( + 'path' => $path, + 'type' => 'PWG-UPDATE-2' + ) + ); } } else { - $insert{'id'} = $next_element_id++; - $insert{'file'} = $filename; - $insert{'storage_category_id'} = $db_fulldirs[$dirname]; - $insert{'date_available'} = CURRENT_DATE; - $insert{'has_high'} = $fs[$path]['has_high']; - if ( isset($fs[$path]['has_high']) ) - { - $insert{'has_high'} = $fs[$path]['has_high']; - } - else - { - $insert{'has_high'} = null; - } - $insert{'path'} = $path; + $insert = array( + 'id' => $next_element_id++, + 'file' => $filename, + 'date_available' => CURRENT_DATE, + 'path' => $path, + 'has_high' => isset($fs[$path]['has_high']) + ? $fs[$path]['has_high'] + : null, + 'tn_ext' => isset($fs[$path]['tn_ext']) + ? $fs[$path]['tn_ext'] + : null, + 'representative_ext' => isset($fs[$path]['representative_ext']) + ? $fs[$path]['representative_ext'] + : null, + ); - if ( isset($fs[$path]['tn_ext']) ) - { - $insert{'tn_ext'} = $fs[$path]['tn_ext']; - } - if (isset($fs[$path]['representative_ext'])) - { - $insert{'representative_ext'} = $fs[$path]['representative_ext']; - } + array_push( + $inserts, + $insert + ); - array_push($inserts, $insert); - array_push($insert_links, - array('image_id' => $insert{'id'}, - 'category_id' => $insert{'storage_category_id'})); - array_push($infos, array('path' => $insert{'path'}, - 'info' => l10n('update_research_added'))); + array_push( + $insert_links, + array( + 'image_id' => $insert{'id'}, + 'category_id' => $db_fulldirs[$dirname], + 'is_storage' => 'true', + ) + ); + + array_push( + $infos, + array( + 'path' => $insert{'path'}, + 'info' => l10n('update_research_added') + ) + ); } } @@ -470,15 +527,23 @@ SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_element_id if (!$simulate) { // inserts all new elements - $dbfields = array( - 'id','file','storage_category_id','date_available','tn_ext' - ,'representative_ext', 'has_high', 'path' + mass_inserts( + IMAGES_TABLE, + array( + 'id', 'file', 'date_available', 'tn_ext', 'representative_ext', + 'has_high', 'path', + ), + $inserts ); - mass_inserts(IMAGES_TABLE, $dbfields, $inserts); - // insert all links between new elements and their storage category - $dbfields = array('image_id','category_id'); - mass_inserts(IMAGE_CATEGORY_TABLE, $dbfields, $insert_links); + // inserts all links between new elements and their storage category + mass_inserts( + IMAGE_CATEGORY_TABLE, + array( + 'image_id','category_id', 'is_storage', + ), + $insert_links + ); } $counts['new_elements'] = count($inserts); } @@ -532,7 +597,9 @@ SELECT id,file,storage_category_id,infos $query = ' SELECT id FROM '.IMAGES_TABLE.' - WHERE storage_category_id = \''.$row['storage_category_id'].'\' + INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id + WHERE is_storage = \'true\' + AND category_id = '.$row['storage_category_id'].' AND file = \''.$row['file'].'\' ;'; list($data['id']) = mysql_fetch_array(pwg_query($query)); @@ -579,6 +646,11 @@ if (isset($_POST['submit']) if (!$simulate) { + $start = get_moment(); + check_links('all'); + echo ''."\n"; $start = get_moment(); update_category('all'); echo ' + + -- cgit v1.2.3