<?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'); define('CURRENT_DATE', date('Y-m-d')); $error_labels = array('PWG-UPDATE-1' => $lang['update_wrong_dirname_short'], 'PWG-UPDATE-2' => $lang['update_missing_tn_short']); $errors = array(); $infos = array(); // +-----------------------------------------------------------------------+ // | directories / categories | // +-----------------------------------------------------------------------+ if (isset($_POST['submit']) and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files')) { $counts['new_categories'] = 0; $counts['del_categories'] = 0; $counts['del_elements'] = 0; $counts['new_elements'] = 0; // shall we simulate only if (isset($_POST['simulate']) and $_POST['simulate'] == 1) { $simulate = true; } else { $simulate = false; } $start = get_moment(); // which categories to update ? $cat_ids = array(); $query = ' SELECT id, uppercats, global_rank, status, visible FROM '.CATEGORIES_TABLE.' WHERE dir IS NOT NULL AND site_id = 1'; if (isset($_POST['cat']) and is_numeric($_POST['cat'])) { if (isset($_POST['subcats-included']) and $_POST['subcats-included'] == 1) { $query.= ' AND uppercats REGEXP \'(^|,)'.$_POST['cat'].'(,|$)\' '; } else { $query.= ' AND id = '.$_POST['cat'].' '; } } $query.= ' ;'; $result = pwg_query($query); $db_categories = array(); while ($row = mysql_fetch_array($result)) { $db_categories[$row['id']] = $row; } // get categort full directories in an array for comparison with file // system directory tree $db_fulldirs = get_fulldirs(array_keys($db_categories)); // what is the base directory to search file system sub-directories ? if (isset($_POST['cat']) and is_numeric($_POST['cat'])) { $basedir = $db_fulldirs[$_POST['cat']]; } else { $query = ' SELECT galleries_url FROM '.SITES_TABLE.' WHERE id = 1 ;'; list($galleries_url) = mysql_fetch_array(pwg_query($query)); $basedir = preg_replace('#/*$#', '', $galleries_url); } // we need to have fulldirs as keys to make efficient comparison $db_fulldirs = array_flip($db_fulldirs); // finding next rank for each id_uppercat $next_rank['NULL'] = 1; $query = ' SELECT id_uppercat, MAX(rank)+1 AS next_rank FROM '.CATEGORIES_TABLE.' GROUP BY id_uppercat ;'; $result = pwg_query($query); while ($row = mysql_fetch_array($result)) { // for the id_uppercat NULL, we write 'NULL' and not the empty string if (!isset($row['id_uppercat']) or $row['id_uppercat'] == '') { $row['id_uppercat'] = 'NULL'; } $next_rank[$row['id_uppercat']] = $row['next_rank']; } // next category id available $query = ' SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_id FROM '.CATEGORIES_TABLE.' ;'; list($next_id) = mysql_fetch_array(pwg_query($query)); // retrieve file system sub-directories fulldirs $fs_fulldirs = get_fs_directories($basedir); // get_fs_directories doesn't include the base directory, so if it's a // category directory, we need to include it in our array if (isset($_POST['cat'])) { array_push($fs_fulldirs, $basedir); } $inserts = array(); // new categories are the directories not present yet in the database foreach (array_diff($fs_fulldirs, array_keys($db_fulldirs)) as $fulldir) { $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'} = 1; $insert{'commentable'} = $conf['newcat_default_commentable']; $insert{'uploadable'} = $conf['newcat_default_uploadable']; $insert{'status'} = $conf{'newcat_default_status'}; $insert{'visible'} = $conf{'newcat_default_visible'}; if (isset($db_fulldirs[dirname($fulldir)])) { $parent = $db_fulldirs[dirname($fulldir)]; $insert{'id_uppercat'} = $parent; $insert{'uppercats'} = $db_categories[$parent]['uppercats'].','.$insert{'id'}; $insert{'rank'} = $next_rank[$parent]++; $insert{'global_rank'} = $db_categories[$parent]['global_rank'].'.'.$insert{'rank'}; if ('private' == $db_categories[$parent]['status']) { $insert{'status'} = 'private'; } if ('false' == $db_categories[$parent]['visible']) { $insert{'visible'} = 'false'; } } else { $insert{'uppercats'} = $insert{'id'}; $insert{'rank'} = $next_rank['NULL']++; $insert{'global_rank'} = $insert{'rank'}; } array_push($inserts, $insert); array_push($infos, array('path' => $fulldir, 'info' => $lang['update_research_added'])); // add the new category to $db_categories and $db_fulldirs array $db_categories[$insert{'id'}] = array( 'id' => $insert{'id'}, 'status' => $insert{'status'}, 'visible' => $insert{'visible'}, 'uppercats' => $insert{'uppercats'}, 'global_rank' => $insert{'global_rank'} ); $db_fulldirs[$fulldir] = $insert{'id'}; $next_rank[$insert{'id'}] = 1; } else { array_push($errors, array('path' => $fulldir, 'type' => 'PWG-UPDATE-1')); } } if (count($inserts) > 0) { if (!$simulate) { $dbfields = array( 'id','dir','name','site_id','id_uppercat','uppercats','commentable', 'uploadable','visible','status','rank','global_rank' ); mass_inserts(CATEGORIES_TABLE, $dbfields, $inserts); } $counts['new_categories'] = count($inserts); } // to delete categories $to_delete = array(); foreach (array_diff(array_keys($db_fulldirs), $fs_fulldirs) as $fulldir) { array_push($to_delete, $db_fulldirs[$fulldir]); unset($db_fulldirs[$fulldir]); array_push($infos, array('path' => $fulldir, 'info' => $lang['update_research_deleted'])); } if (count($to_delete) > 0) { if (!$simulate) { delete_categories($to_delete); } $counts['del_categories'] = count($to_delete); } echo get_elapsed_time($start, get_moment()); echo ' for new method scanning directories<br />'; } // +-----------------------------------------------------------------------+ // | files / elements | // +-----------------------------------------------------------------------+ if (isset($_POST['submit']) and $_POST['sync'] == 'files') { $start_files = get_moment(); $start= $start_files; $fs = get_fs($basedir); echo get_elapsed_time($start, get_moment()); echo ' for get_fs<br />'; $cat_ids = array_diff(array_keys($db_categories), $to_delete); $db_elements = array(); $db_unvalidated = array(); if (count($cat_ids) > 0) { $query = ' SELECT id, path FROM '.IMAGES_TABLE.' WHERE storage_category_id IN ( '.wordwrap(implode(', ', $cat_ids), 80, "\n").') ;'; $result = pwg_query($query); while ($row = mysql_fetch_array($result)) { $db_elements[$row['id']] = $row['path']; } // searching the unvalidated waiting elements (they must not be taken into // account) $query = ' SELECT file,storage_category_id FROM '.WAITING_TABLE.' WHERE storage_category_id IN ( '.wordwrap(implode(', ', $cat_ids), 80, "\n").') AND validated = \'false\' ;'; $result = pwg_query($query); while ($row = mysql_fetch_array($result)) { array_push( $db_unvalidated, array_search($row['storage_category_id'], $db_fulldirs).'/'.$row['file'] ); } } // next element id available $query = ' SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_element_id FROM '.IMAGES_TABLE.' ;'; list($next_element_id) = mysql_fetch_array(pwg_query($query)); $start = get_moment(); // because isset is one hundred time faster than in_array $fs['thumbnails'] = array_flip($fs['thumbnails']); $fs['representatives'] = array_flip($fs['representatives']); $inserts = array(); $insert_links = array(); foreach (array_diff($fs['elements'], $db_elements, $db_unvalidated) as $path) { $insert = array(); // storage category must exist $dirname = dirname($path); if (!isset($db_fulldirs[$dirname])) { continue; } $filename = basename($path); if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $filename)) { array_push($errors, array('path' => $path, 'type' => 'PWG-UPDATE-1')); continue; } // searching the thumbnail $filename_wo_ext = get_filename_wo_extension($filename); $tn_ext = ''; $base_test = $dirname.'/thumbnail/'; $base_test.= $conf['prefix_thumbnail'].$filename_wo_ext.'.'; foreach ($conf['picture_ext'] as $ext) { $test = $base_test.$ext; if (isset($fs['thumbnails'][$test])) { $tn_ext = $ext; break; } } // 2 cases : the element is a picture or not. Indeed, for a picture // thumbnail is mandatory and for non picture element, thumbnail and // representative are optionnal if (in_array(get_extension($filename), $conf['picture_ext'])) { // if we found a thumnbnail corresponding to our picture... if ($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'} = $tn_ext; $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' => $lang['update_research_added'])); } else { array_push($errors, array('path' => $path, 'type' => 'PWG-UPDATE-2')); } } else { // searching a representative $representative_ext = ''; $base_test = $dirname.'/pwg_representative/'.$filename_wo_ext.'.'; foreach ($conf['picture_ext'] as $ext) { $test = $base_test.$ext; if (isset($fs['representatives'][$test])) { $representative_ext = $ext; break; } } $insert{'id'} = $next_element_id++; $insert{'file'} = $filename; $insert{'storage_category_id'} = $db_fulldirs[$dirname]; $insert{'date_available'} = CURRENT_DATE; $insert{'path'} = $path; if ($tn_ext != '') { $insert{'tn_ext'} = $tn_ext; } if ($representative_ext != '') { $insert{'representative_ext'} = $representative_ext; } 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' => $lang['update_research_added'])); } } if (count($inserts) > 0) { if (!$simulate) { // inserts all new elements $dbfields = array( 'id','file','storage_category_id','date_available','tn_ext' ,'representative_ext','path' ); 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); } $counts['new_elements'] = count($inserts); } // delete elements that are in database but not in the filesystem $to_delete_elements = array(); foreach (array_diff($db_elements, $fs['elements']) as $path) { array_push($to_delete_elements, array_search($path, $db_elements)); array_push($infos, array('path' => $path, 'info' => $lang['update_research_deleted'])); } if (count($to_delete_elements) > 0) { if (!$simulate) { delete_elements($to_delete_elements); } $counts['del_elements'] = count($to_delete_elements); } echo get_elapsed_time($start_files, get_moment()); echo ' for new method scanning files<br />'; } // +-----------------------------------------------------------------------+ // | template initialization | // +-----------------------------------------------------------------------+ $template->set_filenames(array('update'=>'admin/update.tpl')); $result_title = ''; if (isset($simulate) and $simulate) { $result_title.= $lang['update_simulation_title'].' '; } $result_title.= $lang['update_part_research']; $template->assign_vars( array( 'L_SUBMIT'=>$lang['submit'], 'L_UPDATE_TITLE'=>$lang['update_default_title'], 'L_UPDATE_SYNC_FILES'=>$lang['update_sync_files'], 'L_UPDATE_SYNC_DIRS'=>$lang['update_sync_dirs'], 'L_UPDATE_SYNC_ALL'=>$lang['update_sync_all'], 'L_UPDATE_SYNC_METADATA'=>$lang['update_sync_metadata'], 'L_UPDATE_SYNC_METADATA_NEW'=>$lang['update_sync_metadata_new'], 'L_UPDATE_SYNC_METADATA_ALL'=>$lang['update_sync_metadata_all'], 'L_UPDATE_CATS_SUBSET'=>$lang['update_cats_subset'], 'L_RESULT_UPDATE'=>$result_title, 'L_NB_NEW_ELEMENTS'=>$lang['update_nb_new_elements'], 'L_NB_NEW_CATEGORIES'=>$lang['update_nb_new_categories'], 'L_NB_DEL_ELEMENTS'=>$lang['update_nb_del_elements'], 'L_NB_DEL_CATEGORIES'=>$lang['update_nb_del_categories'], 'L_UPDATE_NB_ERRORS'=>$lang['update_nb_errors'], 'L_SEARCH_SUBCATS_INCLUDED'=>$lang['search_subcats_included'], 'L_UPDATE_WRONG_DIRNAME_INFO'=>$lang['update_wrong_dirname_info'], 'L_UPDATE_MISSING_TN_INFO'=>$lang['update_missing_tn_info'], 'PICTURE_EXT_LIST'=>implode(',', $conf['picture_ext']), 'L_UPDATE_ERROR_LIST_TITLE'=>$lang['update_error_list_title'], 'L_UPDATE_ERRORS_CAPTION'=>$lang['update_errors_caption'], 'L_UPDATE_DISPLAY_INFO'=>$lang['update_display_info'], 'L_UPDATE_SIMULATE'=>$lang['update_simulate'], 'L_UPDATE_INFOS_TITLE'=>$lang['update_infos_title'] )); // +-----------------------------------------------------------------------+ // | introduction : choices | // +-----------------------------------------------------------------------+ if (!isset($_POST['submit'])) { $template->assign_block_vars('introduction', array()); $query = ' SELECT id,name,uppercats,global_rank FROM '.CATEGORIES_TABLE.' WHERE site_id = 1 ;'; display_select_cat_wrapper($query, array(), 'introduction.category_option', false); } // +-----------------------------------------------------------------------+ // | synchronize files | // +-----------------------------------------------------------------------+ else if (isset($_POST['submit']) and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files')) { $template->assign_block_vars( 'update', array( 'NB_NEW_CATEGORIES'=>$counts['new_categories'], 'NB_DEL_CATEGORIES'=>$counts['del_categories'], 'NB_NEW_ELEMENTS'=>$counts['new_elements'], 'NB_DEL_ELEMENTS'=>$counts['del_elements'], 'NB_ERRORS'=>count($errors), )); if (count($errors) > 0) { $template->assign_block_vars('update.errors', array()); foreach ($errors as $error) { $template->assign_block_vars( 'update.errors.error', array( 'ELEMENT' => $error['path'], 'LABEL' => $error['type'].' ('.$error_labels[$error['type']].')' )); } } if (count($infos) > 0 and isset($_POST['display_info']) and $_POST['display_info'] == 1) { $template->assign_block_vars('update.infos', array()); foreach ($infos as $info) { $template->assign_block_vars( 'update.infos.info', array( 'ELEMENT' => $info['path'], 'LABEL' => $info['info'] )); } } if (!$simulate) { $start = get_moment(); update_category('all'); echo get_elapsed_time($start,get_moment()); echo ' for update_category(all)<br />'; $start = get_moment(); ordering(); update_global_rank(); echo get_elapsed_time($start, get_moment()); echo ' for ordering categories<br />'; } } // +-----------------------------------------------------------------------+ // | synchronize metadata | // +-----------------------------------------------------------------------+ else if (isset($_POST['submit']) and preg_match('/^metadata/', $_POST['sync'])) { // sync only never synchronized files ? if ($_POST['sync'] == 'metadata_new') { $opts['only_new'] = true; } else { $opts['only_new'] = false; } $opts['category_id'] = ''; $opts['recursive'] = true; if (isset($_POST['cat'])) { $opts['category_id'] = $_POST['cat']; // recursive ? if (!isset($_POST['subcats-included']) or $_POST['subcats-included'] != 1) { $opts['recursive'] = false; } } $start = get_moment(); $files = get_filelist($opts['category_id'], $opts['recursive'], $opts['only_new']); echo get_elapsed_time($start, get_moment()).' for get_filelist<br />'; $start = get_moment(); update_metadata($files); echo get_elapsed_time($start, get_moment()).' for metadata update<br />'; } // +-----------------------------------------------------------------------+ // | sending html code | // +-----------------------------------------------------------------------+ $template->assign_var_from_handle('ADMIN_CONTENT', 'update'); ?>