diff --git a/e107_admin/banlist.php b/e107_admin/banlist.php index 07c5a2ccf..01a8b953f 100644 --- a/e107_admin/banlist.php +++ b/e107_admin/banlist.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_admin/banlist.php,v $ -| $Revision: 1.3 $ -| $Date: 2007-12-09 16:42:22 $ +| $Revision: 1.4 $ +| $Date: 2007-12-11 22:48:36 $ | $Author: e107steved $ +----------------------------------------------------------------------------+ */ @@ -20,6 +20,9 @@ define('BAN_TIME_FORMAT',"%d-%m-%Y %H:%M"); define('BAN_REASON_COUNT',7); // Update as more ban reasons added (max 10 supported) +define('BAN_TYPE_IMPORTED',5); // Imported bans +define('BAN_TYPE_TEMPORARY',9); // Used during CSV import + require_once("../class2.php"); if (!getperms("4")) { @@ -173,6 +176,24 @@ function ban_time_dropdown($click_js = '', $zero_text=BANLAN_21, $curval=-1,$dro } +// Character options for import & export +$separator_char = array(1 => ',', 2 => '|'); +$quote_char = array(1 => '', 2 => "'", 3 => '"'); + + +function select_box($name, $data, $curval = FALSE) +{ + $ret = "\n"; + return $ret; +} + $text = ""; @@ -298,6 +319,74 @@ switch ($action) $ns->tablerender(BANLAN_9, $text); break; // End of 'Add' and 'Edit' + + case 'transfer' : + $message = ''; + if (isset($_POST['ban_import'])) + { // Got a file to import + require_once(e_HANDLER.'upload_handler.php'); + if (($files = process_uploaded_files(e_FILE."public/",FALSE,array('overwrite'=>TRUE, 'max_file_count' => 1, 'file_mask'=> 'csv'))) === FALSE) + { // Invalid file + $message = BANLAN_47; + } + if (!$message && $files[0]['error']) $message = $files[0]['message']; + if (!$message) + { // Got a file of some sort + $message = process_csv(e_FILE."public/".$files[0]['name'], + intval(varset($_POST['ban_over_import'],0)), + intval(varset($_POST['ban_over_expiry'],0)), + $separator_char[intval(varset($_POST['ban_separator'],1))], + $quote_char[intval(varset($_POST['ban_quote'],3))]); + } + + } + if ($message) $ns->tablerender(BANLAN_48, "
{$message}
"); + + $text = "
+
+
+ + + + + "; + $text .= ""; + $text .= "
".BANLAN_36."".BANLAN_15."
\n"; + $spacer = ''; + for ($i = 0; $i < BAN_REASON_COUNT; $i++) + { + $text .= $spacer." ".constant('BANLAN_10'.$i)." - ".constant('BANLAN_11'.$i); + $spacer = "
\n"; + } + $text .= "
".select_box('ban_separator',$separator_char).' '.BANLAN_37; + $text .= "
".select_box('ban_quote',$quote_char).' '.BANLAN_38."
"; + $text .= " +


"; + $ns->tablerender(BANLAN_40, $text); + + // Now do the import options + $text = "
+
+
+ + + + + "; + $text .= " + + "; + $text .= "
".BANLAN_42."".BANLAN_15."
\n"; + $text .= " ".BANLAN_43.'
'; + $text .= " ".BANLAN_44; + + $text .= "
".select_box('ban_separator',$separator_char).' '.BANLAN_37; + $text .= "
".select_box('ban_quote',$quote_char).' '.BANLAN_38."
"; + $text .= " +


"; + $ns->tablerender(BANLAN_41, $text); + break; + case 'list' : default : $text = $rs->form_open("post", e_SELF, "ban_form")."
".$rs->form_hidden("ban_secure", "1"); @@ -361,11 +450,15 @@ function banlist_adminmenu() $var['list']['text'] = BANLAN_14; // List existing bans $var['list']['link'] = e_SELF."?list"; - $var['list']['perm'] = "W"; + $var['list']['perm'] = "4"; $var['add']['text'] = BANLAN_25; // Add a new ban $var['add']['link'] = e_SELF."?add"; - $var['add']['perm'] = "W"; + $var['add']['perm'] = "4"; + + $var['transfer']['text'] = BANLAN_35; + $var['transfer']['link'] = e_SELF."?transfer"; + $var['transfer']['perm'] = "4"; if(getperms("0")) { @@ -377,4 +470,91 @@ function banlist_adminmenu() } + +// Parse the date string used by the import/export - YYYYMMDD_HHMMSS +function parse_date($instr) +{ + if (strlen($instr) != 15) return 0; + return mktime(substr($instr,9,2),substr($instr,11,2),substr($instr,13,2),substr($instr,4,2),substr($instr,6,2),substr($instr,0,4)); +} + + +// Process the imported CSV file, update the database, delete the file. +// Return a message +function process_csv($filename, $override_imports, $override_expiry, $separator = ',', $quote = '"') +{ + global $sql, $pref; +// echo "Read CSV: {$filename} separator: {$separator}, quote: {$quote} override imports: {$override_imports} override expiry: {$override_expiry}
"; + // Renumber imported bans + if ($override_imports) $sql->db_Update('banlist', "`banlist_bantype`=".BAN_TYPE_TEMPORARY." WHERE `banlist_bantype` = ".BAN_TYPE_IMPORTED); + $temp = file($filename); + $line_num = 0; + foreach ($temp as $line) + { // Process one entry + $line = trim($line); + $line_num++; + if ($line) + { + $fields = explode($separator,$line); + $field_num = 0; + $field_list = array('banlist_bantype' => BAN_TYPE_IMPORTED); + foreach ($fields as $f) + { + $f = trim($f); + if (substr($f,0,1) == $quote) + { + if (substr($f,-1,1) == $quote) + { // Strip quotes + $f = substr($f,1,-1); // Strip off the quotes + } + else + { + return BANLAN_49.$line_num; + } + } + // Now handle the field + $field_num++; + switch ($field_num) + { + case 1 : // IP address + $field_list['banlist_ip'] = $f; + break; + case 2 : // Original date of ban + $field_list['banlist_datestamp'] = parse_date($f); + break; + case 3 : // Expiry of ban - depends on $override_expiry + if ($override_expiry) + { + $field_list['banlist_banexpires'] = parse_date($f); + } + else + { // Use default ban time from now + $field_list['banlist_banexpires'] = $pref['ban_durations'][BAN_TYPE_IMPORTED] ? time() + (60*60*$pref['ban_durations'][BAN_TYPE_IMPORTED]) : 0; + } + break; + case 4 : // Original ban type - we always ignore this and force to 'imported' + break; + case 5 : // Ban reason originally generated by E107 + $field_list['banlist_reason'] = $f; + break; + case 6 : // Any user notes added + $field_list['banlist_notes'] = $f; + break; + default : // Just ignore any others + } + } + $qry = "REPLACE INTO `#banlist` (".implode(',',array_keys($field_list)).") values ('".implode("', '",$field_list)."')"; +// echo count($field_list)." elements, query: ".$qry."
"; + if (!$sql->db_Select_gen($qry)) + { + return BANLAN_50.$line_num; + } + } + } + // Success here - may need to delete old imported bans + if ($override_imports) $sql->db_Delete('banlist', "`banlist_bantype` = ".BAN_TYPE_TEMPORARY); + @unlink($filename); // Delete file once done + return str_replace('--NUM--',$line_num, BANLAN_51).$filename; +} + ?> diff --git a/e107_admin/banlist_export.php b/e107_admin/banlist_export.php new file mode 100644 index 000000000..1ebcf758f --- /dev/null +++ b/e107_admin/banlist_export.php @@ -0,0 +1,136 @@ + ',', 2 => '|'); +$quote_char = array(1 => '', 2 => "'", 3 => '"'); + + +$format_array = array( + 'banlist_ip' => 1, + 'banlist_datestamp' => "%Y%m%d_%H%M%S", + 'banlist_banexpires' => "%Y%m%d_%H%M%S", + 'banlist_bantype' => 1, + 'banlist_reason' => 1, + 'banlist_notes' => 1 +); + +$use_separator = varset($separator_char[intval($_POST['ban_separator'])],$separator_char[1]); +$use_quote = varset($quote_char[intval($_POST['ban_quote'])],$quote_char[2]); + + +$type_list = ''; +if (is_array($_POST['ban_types'])) +{ + $spacer = ''; + foreach($_POST['ban_types'] as $b) + { + $b = trim($b); + if (is_numeric($b) && ($b >= 0) && ($b <= 10)) + { + $type_list .= $spacer.($b); + $spacer = ','; + } + } +} + +$filename = 'banlist_'.strftime("%Y%m%d_%H%M%S").'.csv'; + +if ($error_string = do_export($filename, $type_list, $format_array, $use_separator, $use_quote)) +{ +// Need to report an error here + echo "Error report: {$error_string}
"; +} + +function do_export($filename, $type_list='',$format_array, $sep = ',', $quot = '"') +{ + global $sql; + $export_text = ''; + $qry = "SELECT * FROM `#banlist` "; + if ($type_list != '') $qry .= " WHERE`banlist_bantype` IN ({$type_list})"; + if (!$sql->db_Select_gen($qry)) return "No data: ".$qry; + while ($row = $sql->db_Fetch()) + { + $line = ''; + $spacer = ''; + foreach ($format_array as $f => $v) + { + switch ($f) + { + case 'banlist_ip' : + case 'banlist_bantype' : + case 'banlist_reason' : + case 'banlist_notes' : + $line .= $spacer.$quot.$row[$f].$quot; + break; + case 'banlist_datestamp' : + case 'banlist_banexpires' : + if ($row[$f]) $line .= $spacer.$quot.strftime($v,$row[$f]).$quot; else $line .= $spacer.$quot.'0'.$quot; + break; + } + $spacer = $sep; + } + $export_text .= $line."\n"; + } + + if (defined('CSV_DEBUG')) + { + $export_text .= "Summary data:
"; + $export_text .= 'File: '.$filename.'
'; + $export_text .= 'Types: '.$type_list.'
'; + $export_text .= 'Query: '.$qry.'
'; + echo str_replace("\n","
",$export_text); + } + else + { + if(headers_sent()) + { + return "Cannot output file - some data already sent

"; + } + + //Secure https check + if (isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype') header('Pragma: public'); + if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) + header('Content-Type: application/force-download'); + else + header('Content-Type: application/octet-stream'); + header('Content-Length: '.strlen($export_text)); + header('Content-disposition: attachment; filename="'.$filename.'"'); + echo $export_text; + } + +} + +?> \ No newline at end of file diff --git a/e107_languages/English/admin/help/banlist.php b/e107_languages/English/admin/help/banlist.php index e68ac4f84..adee7ba85 100644 --- a/e107_languages/English/admin/help/banlist.php +++ b/e107_languages/English/admin/help/banlist.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_languages/English/admin/help/banlist.php,v $ -| $Revision: 1.3 $ -| $Date: 2007-12-09 16:42:23 $ +| $Revision: 1.4 $ +| $Date: 2007-12-11 22:48:42 $ | $Author: e107steved $ +----------------------------------------------------------------------------+ */ @@ -24,6 +24,19 @@ if (e_QUERY) list($action,$junk) = explode('.',e_QUERY); else $action = 'list'; switch ($action) { +case 'transfer' : + $text = "This page allows you to transfer banlist data to and from this site as CSV (Comma Separated Variable) files.

"; + $text .= "Data Export
+ Select the types of ban to export. The fields will be delimited by the chosen separator, and optionally included within the selected quotation marks.

"; + $text .= "Data Import
+ You can choose whether the imported bans replace existing imported bans, or whether they add to the list. If the imported data includes an expiry date/time, you + can select whether this is used, or whether the value for this site is used.

"; + $text .= "CSV Format
+ The format of each line in the file is: IP/email, date, expiry, type, reason, notes.
+ Date and expiry are in the format YYYYMMDD_HHMMDD, except that a zero value indicates 'unknown' or 'indefinite'
+ Only the IP or email address is essential; the other fields are imported if present.

+ Note: You will need to add the 'CSV' file type to admin_filetypes.php"; + break; case 'options' : $text = "This page sets the default behaviour for various types of ban.
If a message is specified, this will be shown to the user (where appropriate); otherwise they will most likely get a blank screen
diff --git a/e107_languages/English/admin/lan_banlist.php b/e107_languages/English/admin/lan_banlist.php index 38f5d2010..38294fa43 100644 --- a/e107_languages/English/admin/lan_banlist.php +++ b/e107_languages/English/admin/lan_banlist.php @@ -4,8 +4,8 @@ | e107 website system - Language File. | | $Source: /cvs_backup/e107_0.8/e107_languages/English/admin/lan_banlist.php,v $ -| $Revision: 1.3 $ -| $Date: 2007-12-09 16:42:23 $ +| $Revision: 1.4 $ +| $Date: 2007-12-11 22:48:42 $ | $Author: e107steved $ +----------------------------------------------------------------------------+ */ @@ -42,12 +42,32 @@ define('BANLAN_31','(Use an empty message if you wish the user to get a blank sc define('BANLAN_32','Indefinite'); define('BANLAN_33','Settings Updated'); define('BANLAN_34','Expired'); -define('BANLAN_35',''); -define('BANLAN_36',''); -define('BANLAN_37',''); -define('BANLAN_38',''); -define('BANLAN_39',''); -define('BANLAN_40',''); +define('BANLAN_35','Import/Export'); +define('BANLAN_36','Export Types'); +define('BANLAN_37','Field Separator'); +define('BANLAN_38','Quote (round each value)'); +define('BANLAN_39','Export'); +define('BANLAN_40','Banlist Export'); +define('BANLAN_41','Banlist Import'); +define('BANLAN_42','Import Choices'); +define('BANLAN_43','Replace all existing imported bans'); +define('BANLAN_44','Use expiry date/time from import'); +define('BANLAN_45','Import'); +define('BANLAN_46','Import File'); +define('BANLAN_47','File upload error'); +define('BANLAN_48','Error importing file'); +define('BANLAN_49','CSV import: Unbalanced quotes in line '); +define('BANLAN_50','CSV import: Error writing banlist record at line '); +define('BANLAN_51','CSV import: Success, --NUM-- lines imported from file '); +define('BANLAN_52',''); +define('BANLAN_53',''); +define('BANLAN_54',''); +define('BANLAN_55',''); +define('BANLAN_56',''); +define('BANLAN_57',''); +define('BANLAN_58',''); +define('BANLAN_59',''); +define('BANLAN_60',''); // Ban types - block reserved 100-109 define('BANLAN_100', 'Unknown'); @@ -59,7 +79,7 @@ define('BANLAN_105', 'Imported'); define('BANLAN_106', 'User'); define('BANLAN_107', 'Unknown'); define('BANLAN_108', 'Unknown'); -define('BANLAN_109', 'Unknown'); +define('BANLAN_109', 'Old'); // Detailed explanations for ban types - block reserved 110-119 define('BANLAN_110', 'Most likely a ban that was imposed before E107 was upgraded to 0.8'); @@ -71,7 +91,7 @@ define('BANLAN_115', 'Added from an external list'); define('BANLAN_116', 'IP address banned on account of user ban'); define('BANLAN_117', 'Spare reason'); define('BANLAN_118', 'Spare reason'); -define('BANLAN_119', 'Spare reason'); +define('BANLAN_119', 'Indicates an import error - previously imported bans'); define('BANLAN_120', 'Unknown');