====Expanded Administration and Backup Tool==== This tool was designed to meet some local needs but has features useful to most admin (the backup of an image directory won't be useful until I upload the tools that are to generate indivdual user directories). This tool allows deleting or "hiding"/restoring individual revisions, hiding/restoring pages, resetting passwords, "reserving" user names, inactivating users, deleting users, backing up database tables (to both an external ftp server and locally), backing up image uploads (I have an upload tool that uploads to a user directory, not to a page directory, and it will back up these to an external ftp server), and, other than the graphic and exports directory, allows backing up the files in the wikka directory (both to an external ftp server and locally as a compressed file) thereby allowing backups of php code development easily. The other "needs" for this script are listed in the file header (note that page.inc.php is available at the WikkaBlog2 page). Install the script below in actions (I call it wikkamanagement.php). It will work without an ftp server (although you should put the variable references into the wikka.config.php, just leave the variable names blank) and local backups can be downloaded. [note that you have to replace "percentpercent" in the code with two percent signs] %%(php) "000.000.000.000", //no http: or slashes (e.g. "put.the.file.here") "db_backup_ftp_user" => "username", "db_backup_ftp_pass" => "password", "graphic_backup_ftp_host" => "000.000.000.000", //no http: or slashes (e.g. "put.the.file.here") "graphic_backup_ftp_user" => "username", "graphic_backup_ftp_pass" => "password", "graphic_directory" => "graphicdirectory", //directory in wikka root, permissions set to allow upload @note: graphic directory is for individual user upload directory (requires modified upload & insertimage code) @note: a directory in wikka root called "exports" is needed (and should be writeable). It needs two writeable subdirectories called "codebackup" and "dbbackup". An htaccess file with the content Options -Indexes order allow,deny allow from all is necessary in the "exports" directory to stop browsing of those files (the SQL files can contain sensitive user info). */ # Include functions for doing pagination include_once("scripts/page.inc.php"); define ('RECORDS_PER_PAGE','20'); $t_pages = $this->config["table_prefix"]."pages"; $t_users = $this->config["table_prefix"]."users"; $t_resetpasswords = $this->config["table_prefix"]."resetpasswords"; $link = $this->Href(); $can_use = $this->IsAdmin(); if (!$can_use) { echo "Only the designated admin can use Wiki Management."; } else { $menu1 = $_REQUEST['menu1']?$_REQUEST['menu1']:''; echo "

Wiki Management

"; $pre_link = $link; $this_link = $pre_link.'&menu1=pages'; $page_name = 'Pages'; echo ($menu1 != 'pages')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu1=users'; $page_name = 'Users'; echo ($menu1 != 'users')?''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu1=backup'; $page_name = 'Backup'; echo ($menu1 != 'backup')?''.$page_name.'' :''.$page_name.''; ################################################################ ################################################################ # Pages ################################################################ ################################################################ if ($menu1 == 'pages') { $menu2 = $_REQUEST['menu2']?$_REQUEST['menu2']:''; $pre_link = $link.'&menu1='.$menu1; echo '
'; $this_link = $pre_link.'&menu2=manage'; $page_name = 'Manage Pages'; echo ($menu2 != 'manage')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=hidden'; $page_name = 'Hidden Pages'; echo ($menu2 != 'hidden')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=revisions'; $page_name = 'Manage Revisions'; echo ($menu2 != 'revisions')?''.$page_name.'' :''.$page_name.''; /* echo ' | '; $this_link = $pre_link.'&menu2=info'; $page_name = 'Page Info'; echo ($menu2 != 'info')?''.$page_name.'' :''.$page_name.''; */ $this_link = $link.'&menu1='.$menu1.'&menu2='.$menu2; ################################################################ # Manage Pages ################################################################ if ($menu2 == 'manage') { if ($_REQUEST['set']) { $tag = $_REQUEST['tag']; $action = $_REQUEST['action']; $n = count($tag); for ($i = 0; $i < $n; $i++) { $this_tag = $tag[$i]; $this_action = $action[$i]; if ($this_action == 'delete_page_history') { # Erase all records concerning page name. $this->Query("DELETE FROM `$t_pages` WHERE `tag`='".mysql_real_escape_string($this_tag)."'"); } else if ($this_action == 'delete_history') { # Remove all records from DB concerning that page where mostrecent is N. $this->Query("DELETE FROM `$t_pages` WHERE `tag`='".mysql_real_escape_string($this_tag)."' AND `latest`='N'"); } else if ($this_action == 'hide_page') { # Set most-recent to H on the current record $this->Query("UPDATE `$t_pages` SET `latest`='H' WHERE `tag`='".mysql_real_escape_string($this_tag)."' AND `latest`='Y'"); } } } $cur_page = $_REQUEST['page']; $sort = $_REQUEST['sort']; $sort_order = $_REQUEST['sortorder']; $t_temp_pages = $this->config["table_prefix"]."pages".rand(1,10000); $this->Query("CREATE TEMPORARY TABLE `$t_temp_pages` (`tag` varchar(75),`num_revisions` int) TYPE=MyISAM;"); $pages = $this->LoadAll("SELECT `tag` FROM `$t_pages` WHERE `latest`='Y'"); foreach ($pages as $page) { $tag = &$page['tag']; $num_revisions = $this->LoadSingle("SELECT count(*) as `num_revisions` FROM `$t_pages` WHERE `tag`='$tag'"); $num_revisions = $num_revisions ['num_revisions']; $this->Query("INSERT INTO `$t_temp_pages` (`tag`,`num_revisions`) VALUES ('$tag','$num_revisions');"); } if ($sort == 'tag') $order = 'ORDER BY `tag`'; else if ($sort == 'num_revisions') $order = 'ORDER BY `num_revisions`'; else $order = 'ORDER BY `tag`'; if ($sort_order == 'DESC') { $order .= ' DESC'; $sort_order = 'ASC' ; $sort_order2 = 'DESC'; } else { $order .= ' ASC' ; $sort_order = 'DESC'; $sort_order2 = 'ASC' ; } $query = "SELECT * FROM `$t_temp_pages` $order"; $page = new Page(); $total_records = count($this->LoadAll($query)); $page->set_page_data($this_link.'&sort='.$sort.'&sortorder='.$sort_order2,$total_records,RECORDS_PER_PAGE,5,true,true,true); ob_start(); $page->get_page_nav(); $page_nav = ob_get_contents(); ob_end_clean(); $pages = $this->LoadAll($page->get_limit_query($query)); $this->Query("DROP TABLE `$t_temp_pages`;"); $this_link2 = $this_link.'&sort='.$sort.'&sortorder='.$sort_order2.'&page='.$cur_page; echo '

Page Management And Deletion

'; echo '
'. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''; $i = 0; foreach ($pages as $page) { $tag = &$page['tag']; $num_revisions = &$page['num_revisions']; $color = ($i%2)?"#ffffff":"#f5f6f7"; echo ''. ''. ''. ''. ''. ''. ''; $i++; } echo '
'. '
'.$page_nav.'
'. '
 Page Name:  Do Nothing  Hide Page:  Erase History:  Erase Page and History: 
 '.$this->Link($tag).' '. ''. ''. ''. ''. '  '. ''. '['.$num_revisions.' Rev'.(($num_revisions > 1)?'\'s':'').']'. ''. ''. '
'. ''. ''. '
'; } ################################################################ # Hidden ################################################################ else if ($menu2 == 'hidden') { $unhide = $_REQUEST['unhide']; if ($unhide) { $unhidename = $_REQUEST['unhidename']; $this->query("UPDATE ".$this->config['table_prefix']."pages SET `latest`='Y' WHERE tag='".mysql_real_escape_string($unhidename)."' AND latest = 'H' "); } $count = 0; $query = "SELECT tag,owner,latest,time FROM `$t_pages` WHERE `latest`='H' ORDER BY id asc"; $result = mysql_query($query); echo '

Hidden Pages

'; echo ""; ?> ". "". "". "". "". "". ""; } echo "
 #   Page Name   Page Owner   Time Hidden   Un-Hide 
 ".$count."  ".$row['tag']."  ".$row['owner']."  ".$row['time']."   Restore
"; } ################################################################ # Manage Revisions ################################################################ else if ($menu2 == 'revisions') { $cur_page = $_REQUEST['page']; $sort = $_REQUEST['sort']; $sort_order = $_REQUEST['sortorder']; $show_owner = $_REQUEST['show_owner']; $show_page = $_REQUEST['show_page']; if ($sort == 'tag') $order = 'ORDER BY `tag`'; else if ($sort == 'time') $order = 'ORDER BY `time`'; else if ($sort == 'owner') $order = 'ORDER BY `owner`'; else if ($sort == 'num_revisions') $order = 'ORDER BY `num_revisions`'; else if ($sort == 'num_editors') $order = 'ORDER BY `num_editors`'; else $order = 'ORDER BY `tag`'; if ($sort_order == 'DESC') { $order .= ' DESC'; $sort_order = 'ASC' ; $sort_order2 = 'DESC'; } else { $order .= ' ASC' ; $sort_order = 'DESC'; $sort_order2 = 'ASC' ; } $show_owner = $this->LoadUser($show_owner); $show_owner = $show_owner['name']; $this_link2 = $this_link.'&sort='.$sort.'&sortorder='.$sort_order2.'&page='.$cur_page; if (!$show_page) { $t_temp_pages = $this->config["table_prefix"]."pages".rand(1,10000); $this->Query("CREATE TEMPORARY TABLE `$t_temp_pages` (`tag` varchar(75),`time` datetime,`user` varchar(75),`owner` varchar(75),`num_revisions` int,`num_editors` int) TYPE=MyISAM;"); $pages = $this->LoadAll("SELECT `tag`,`time`,`user`,`owner` FROM `$t_pages` WHERE ".($show_owner?"`owner`='$show_owner' AND ":'')."`latest`='Y'"); foreach ($pages as $page) { $tag = &$page['tag']; $time = &$page['time']; $user = &$page['user']; $owner = &$page['owner']; $num_revisions = $this->LoadSingle("SELECT count(*) as `num_revisions` FROM `$t_pages` WHERE `tag`='$tag'"); $num_revisions = $num_revisions ['num_revisions']; $num_editors = $this->LoadSingle("SELECT count(DISTINCT `user`) as `num_editors` FROM `$t_pages` WHERE `tag`='$tag'"); $num_editors = $num_editors['num_editors']; $this->Query("INSERT INTO `$t_temp_pages` (`tag`,`time`,`user`,`owner`,`num_revisions`,`num_editors`) VALUES ('$tag','$time','$user','$owner','$num_revisions','$num_editors');"); } $this_link3 = $this_link.'&show_owner='.$show_owner; $this_link4 = $this_link2.'&show_owner='.$show_owner; $query = "SELECT * FROM `$t_temp_pages` $order"; $page = new Page(); $total_records = count($this->LoadAll($query)); $page->set_page_data($this_link3.'&sort='.$sort.'&sortorder='.$sort_order2,$total_records,RECORDS_PER_PAGE,5,true,true,true); ob_start(); $page->get_page_nav(); $page_nav = ob_get_contents(); ob_end_clean(); $pages = $this->LoadAll($page->get_limit_query($query)); $this->Query("DROP TABLE `$t_temp_pages`;"); echo ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''; $i = 0; foreach ($pages as $page) { $tag = &$page['tag']; $time = &$page['time']; $owner = &$page['owner']; $last_editor = &$page['user']; $num_revisions = &$page['num_revisions']; $num_editors = &$page['num_editors']; $color = ($i%2)?"#ffffff":"#f5f6f7"; echo ''. ''. ''. ''. ''. ''. ''. ''; $i++; } echo '
'. '

Page Info

'. '
'. '
'. 'Owner: '. ''. ''. '
'. '
'. 'Click on the page name to manage revisions.'. '
'. '
'.$page_nav.'
'. '
 Page Name:  # Edits:  # Editors:  Page Owner:  Last Editor:  Last Edited: 
 '.$tag.'  '.$num_revisions.'  '.$num_editors.'  '.$owner.'  '.$last_editor.'  '.$time.' 
'; } # Show Page else { if ($_REQUEST['set']) { $id = $_REQUEST['id']; $action = $_REQUEST['action']; $n = count($id); for ($i = 0; $i < $n; $i++) { $this_id = $id[$i]; $this_action = $action[$i]; if ($this_action == 'delete_revision') { $this->Query("DELETE FROM `$t_pages` WHERE `id`='".mysql_real_escape_string($this_id)."'"); } else if ($this_action == 'hide_revision') { $this->Query("UPDATE `$t_pages` SET `latest`='V' WHERE `id`='".mysql_real_escape_string($this_id)."' AND `latest`='N'"); } else if ($this_action == 'restore_revision') { $this->Query("UPDATE `$t_pages` SET `latest`='N' WHERE `id`='".mysql_real_escape_string($this_id)."' AND `latest`='V'"); } } } $show_page = $this->LoadPage($show_page); $show_page = $show_page['tag']; $this_link3 = $this_link2.'&show_page='.$show_page.'&show_owner='.$show_owner; $this_link4 = $this_link2.'&show_page=&show_owner='.$show_owner; $revisions = $this->LoadAll("SELECT `id`,`tag`,`time`,`user`,`latest` FROM `$t_pages` WHERE `tag`='$show_page' ORDER BY `time` DESC"); echo '

Manage Revisions: '.$show_page.'

'. '<=Back'. '
'. ''. ''. ''. ''. ''. ''. ''. ''; $i = 0; foreach ($revisions as $revision) { $id = &$revision['id']; $tag = &$revision['tag']; $time = &$revision['time']; $user = &$revision['user']; $latest = &$revision['latest']; $current_rev = ($latest == 'Y'); $hidden_rev = ($latest == 'V'); $color = ($i%2)?"#ffffff":"#f5f6f7"; echo ''; if ($current_rev) { echo ''. ''; } else if ($hidden_rev) { echo ''. ''; } else { echo ''. ''; } echo ''. ''. ''. ''; $i++; } echo '
 Time:  User:    Delete:  Hide: 
 '.$time.'  '.$user.'  '.$time.'  '.$user.'  '.$time.'  '.$user.' '. ''. ''. ''. ''. ''. ''. '
'. ''. ''. '
'; } } } ################################################################ ################################################################ # Users ################################################################ ################################################################ else if ($menu1 == 'users') { $menu2 = $_REQUEST['menu2']?$_REQUEST['menu2']:''; $pre_link = $link.'&menu1='.$menu1; echo '
'; $this_link = $pre_link.'&menu2=delete'; $page_name = 'Delete User'; echo ($menu2 != 'delete')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=reset_password'; $page_name = 'Reset Password'; echo ($menu2 != 'reset_password')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=reset_wikiname'; $page_name = 'Reset Wikiname'; echo ($menu2 != 'reset_wikiname')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=inactivate'; $page_name = 'Inactivate User'; echo ($menu2 != 'inactivate')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=reserve'; $page_name = 'Reserve Account'; echo ($menu2 != 'reserve')?''.$page_name.'' :''.$page_name.''; $this_link = $link.'&menu1='.$menu1.'&menu2='.$menu2; ################################################################ # Delete Users ################################################################ if ($menu2 == 'delete') { if ($_REQUEST['set']) { $delete = $_REQUEST['delete']; $n = count($delete); for ($i = 0; $i < $n; $i++) { if ($this_delete = $delete[$i]) { $this->Query("DELETE FROM `$t_users` WHERE `name`='".mysql_real_escape_string($this_delete)."'"); } } } $sort = stripslashes($_REQUEST['sort']); $sort_order = stripslashes($_REQUEST['sortorder']); $cur_page = stripslashes($_REQUEST['page']); if ($sort == 'name') $order = 'ORDER BY `name`'; else $order = 'ORDER BY `signuptime`'; if ($sort_order == 'ASC') { $order .= ' ASC' ; $sort_order = 'DESC'; $sort_order2 = 'ASC'; } else { $order .= ' DESC'; $sort_order = 'ASC'; $sort_order2 = 'DESC'; } $query = "SELECT `name`,`signuptime`,`login_count`,`email` FROM `$t_users` WHERE `password`!='Reserved Account' $order "; $page = new Page(); $total_records = count($this->LoadAll($query)); $page->set_page_data($this_link.'&sort='.$sort.'&sortorder='.$sort_order2,$total_records,RECORDS_PER_PAGE,5,true,true,true); ob_start(); $page->get_page_nav(); $page_nav = ob_get_contents(); ob_end_clean(); $users = $this->LoadAll($page->get_limit_query($query)); $this_link2 = $this_link.'&sort='.$sort.'&sortorder='.$sort_order2.'&page='.$cur_page; echo '
'. '

Wiki User Delete

'. ''. ''. ''. ''. ''. "". ''. "". "". "". ''. ""; $i = 0; foreach($users as $user) { if ($stat!=="0") $num = $this->LoadSingle("SELECT count(*) as n from ".$this->config["table_prefix"]."pages where owner='".$user["name"]."' AND latest = 'Y'"); echo ''. ''. "". "". "". "". "". ''; $i ++; } echo '
'. '
'.$page_nav.'
'. '
 Del.  Name  # logins  Owned Pages  Email  Signup Date/Time 
'. ''. ''. '".$this->Link($user["name"])."".$user["login_count"]."".($stat!=="0"?"".$num["n"]."":"")."".$user["email"]."(".$user["signuptime"].")
'. ''. ''. '
'; } ################################################################ # Reset Passwords ################################################################ else if ($menu2 == 'reset_password') { $user_action = $_REQUEST['user_action']; if ($user_action == 'set_password') { $username = strtolower($_REQUEST['username']); $password1 = $_REQUEST['password1']; $password2 = $_REQUEST['password2']; if ($password1 != $password2) { echo 'Passwords entered do not match.'; } else { $password = md5($password1); $wikiname = $this->LoadUser(mysql_real_escape_string($username)); $wikiname = $wikiname['name']; if ($wikiname) { $this->Query("UPDATE `$t_users` SET `password`='$password' WHERE `name`='$wikiname'"); } } } echo '
'. '
'. '

Reset Password

'. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. '
'. 'Username: '. ''. ' '. '
'. 'New Password: '. ''. ' '. '
'. 'Confirm Password: '. ''. ' '. '
'. ''. ''. '
'; } ################################################################ # Reset Wikiname ################################################################ else if ($menu2 == 'reset_wikiname') { $old_username = preg_replace("/[^A-Za-z0-9]/i","",$_REQUEST['old_username']); $old_username = $this->LoadUser($old_username); $old_username = $old_username['name']; $new_username = preg_replace("/[^A-Za-z0-9]/i","",$_REQUEST['new_username']); if ($new_username) { if (strtolower($old_username) != strtolower($new_username)) { echo '
'. 'The new username you have specified is incompatable with your old username. The new username must be the same as the old name in all ways but case.'. '
'; } else { if (!$this->isWikiName($new_username)) { echo '
'. "The entered username is not an acceptable wiki name. Wiki names are \"humped\" like this: PageName, PageName2, HumpedName.". '
'; } else { $this->Query("UPDATE `$t_users` SET `name`='$new_username' WHERE `name`='$old_username'"); $this->SetUser($this->LoadUser($new_username)); header("Location: $this_link"); } } } echo "

Reset Upper/Lower Case In Wikiname

". '
'. ''. ''. ''. ''. ''. ''. ''. ''. ''. '
Old Username:   '. '
New Username:   '. '
'. '
'. '
'; } ################################################################ # Inactivate account ################################################################ else if ($menu2 == 'inactivate') { $reset_action = $_REQUEST['reset_action']; if ($reset_action == 'reset_password') { $username = $_REQUEST['username']; if (!$user = $this->LoadUser($username)) { echo 'No such user.
'; } else { if (strtolower($username) == strtolower($this->GetUserName())) { echo 'Cannot reset password for your own account.
'; } else { $username = $user['name']; $password = $user['password']; if ($this->LoadSingle("SELECT username FROM $t_resetpasswords WHERE `username`='$username'")) { echo 'Password for that account has already been reset.
'; } else { $this->Query("INSERT INTO $t_resetpasswords (`username`,`password`) VALUES ('$username','$password')"); $this->Query("UPDATE `$t_users` SET `password`='Inactive Password' WHERE `name`='$username'"); } } } } else if ($reset_action == 'restore_passwords') { $usernames = $_REQUEST['usernames']; $n = count($usernames); for ($i = 0; $i < $n; $i++) { if ($username = $usernames[$i]) { $r_account = $this->LoadSingle("SELECT password FROM $t_resetpasswords WHERE `username`='$username'"); $password = $r_account['password']; $this->Query("UPDATE `$t_users` SET `password`='$password' WHERE `name`='$username'"); $this->Query("DELETE FROM $t_resetpasswords WHERE `username`='$username'"); unset($r_account); } } } echo '

Inactivate Wiki User

'. '
'. 'Username: '. ' '. ''. ''. '
'; $reset_passwords = $this->LoadAll("SELECT username FROM $t_resetpasswords"); echo '
'. '
'. '

Reactivate User:

'; $i = 0; foreach ($reset_passwords as $this_username) { echo ''. ''. ''. '
'; $i++; } if (!$i) { echo 'No inactive users.
'; } echo ''. ''. '
'; } ################################################################ # Reserve Account ################################################################ else if ($menu2 == 'reserve') { $reset_action = $_REQUEST['reset_action']; if ($reset_action == 'reserve_account') { $username = $_REQUEST['username']; if ($user = $this->LoadUser($username)) { echo 'User/account name is in use or already reserved. Only unused usernames/accounts can be reserved.
'; } else { $this->Query("INSERT INTO `$t_users` (`name`,`password`) VALUES ('".mysql_real_escape_string($username)."','Reserved Account')"); } } else if ($reset_action == 'release_accounts') { $usernames = $_REQUEST['usernames']; $n = count($usernames); for ($i = 0; $i < $n; $i++) { if ($username = $usernames[$i]) { $this->Query("DELETE FROM `$t_users` WHERE `name`='$username'"); } } } echo '
'. '

Reserve User Name

'. 'Username: '. ' '. ''. ''. '
'; $reserved_accounts = $this->LoadAll("SELECT name FROM $t_users WHERE `password`='Reserved Account'"); echo '
'. '
'. '

Release Username for Use:

'; $i = 0; foreach ($reserved_accounts as $this_username) { echo ''. ''. ''. '
'; $i++; } if (!$i) { echo 'No reserved user names.
'; } echo ''. ''. '
'; } } ################################################################ ################################################################ # Backup ################################################################ ################################################################ else if ($menu1 == 'backup') { $menu2 = $_REQUEST['menu2']?$_REQUEST['menu2']:''; $pre_link = $link.'&menu1='.$menu1; echo '
'; $this_link = $pre_link.'&menu2=database'; $page_name = 'Database'; echo ($menu2 != 'database')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=images'; $page_name = 'Images'; echo ($menu2 != 'images')?''.$page_name.'' :''.$page_name.''; echo ' | '; $this_link = $pre_link.'&menu2=other'; $page_name = 'Other Files'; echo ($menu2 != 'other')?''.$page_name.'' :''.$page_name.''; echo '
'; $this_link = $link.'&menu1='.$menu1.'&menu2='.$menu2; ################################################################ # Database ################################################################ if ($menu2 == 'database') { $ftp_host = $this->config['db_backup_ftp_host']; $ftp_user = $this->config['db_backup_ftp_user']; $ftp_pass = $this->config['db_backup_ftp_pass']; $ftp_available = ($ftp_host && $ftp_user && $ftp_pass); $path = "exports/"; is_dir($path) || mkdir($path, 0766); $path = $path."dbbackup/"; is_dir($path) || mkdir($path, 0766); $dl_pre_link = $path; function backup_timestamptotime($timestamp) { if (ereg ("([0-9]{4})([0-9]{2})([0-9]{2})_([0-9]{2})([0-9]{2})([0-9]{2})", $timestamp, $date)) { return $time = mktime($date[4], $date[5], $date[6], $date[2], $date[3], $date[1]); } else { return 0; } } if ($_REQUEST['backup'] == 'backup_tables') { $compress = $_REQUEST['compress']; $backup_tables = $_REQUEST['backup_tables']; $timestamp = date("Ymd_His"); $filename = $timestamp." - backup"; $filename .= ($backup_tables == 'all')?'.full':'.part'; $filename .= '.sql'; $filename .= $compress?'.gz':''; $ok = 1; function get_def($table) { $def = ""; $def .= "DROP TABLE IF EXISTS `$table`;#percentpercent\n"; $def .= "CREATE TABLE `$table` (\n"; $result = mysql_query("SHOW FIELDS FROM `$table`") or die("Table $table not existing in database"); while($row = mysql_fetch_array($result)) { $def .= " `$row[Field]` $row[Type]"; if ($row["Default"] != "" ) $def .= " DEFAULT '$row[Default]'"; if ($row["Null"] != "YES") $def .= " NOT NULL"; if ($row["Extra"] != "" ) $def .= " $row[Extra]"; $def .= ",\n"; } $def = ereg_replace(",\n$","", $def); $result = mysql_query("SHOW KEYS FROM `$table`"); while($row = mysql_fetch_array($result)) { $kname = $row['Key_name']; if(($kname != "PRIMARY") && ($row["Non_unique"] == 0)) $kname="UNIQUE|$kname"; if(!isset($index[$kname])) $index[$kname] = array(); $index[$kname][] = '`'.$row["Column_name"].'`'; } while(list($x, $columns) = @each($index)) { $def .= ",\n"; if($x == "PRIMARY") $def .= " PRIMARY KEY (" . implode($columns, ", ") . ")"; else if (substr($x,0,6) == "UNIQUE") $def .= " UNIQUE ".substr($x,7)." (" . implode($columns, ", ") . ")"; else $def .= " KEY $x (" . implode($columns, ", ") . ")"; } $def .= "\n);#percentpercent"; return (stripslashes($def)); } function get_content($table) { $content=""; $result = mysql_query("SELECT * FROM `$table`"); while($row = mysql_fetch_row($result)) { $insert = "INSERT INTO `$table` VALUES ("; for($j=0; $jLoadAll("SHOW TABLE STATUS LIKE '%' "); foreach ($tables as $table) { $table = $table['Name']; $newfile .= get_def($table); $newfile .= "\n\n"; $newfile .= get_content($table); $newfile .= "\n\n"; $count++; } } # ##################################### ##################################### # Save locally if ($compress) { if ($fp = gzopen ($path.$filename,"w9")) { gzwrite ($fp,$newfile); gzclose ($fp); $ok++; } } else { if ($fp = fopen ($path.$filename,"w")) { fwrite ($fp,$newfile); fclose ($fp); $ok++; } } ################################################## ########################################## # Andrew: Upload the backup to FTP server # if option set and delete local file on success. if ($_REQUEST['destination'] == 'ftp' && $ftp_available) { if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; $ok--; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; $ok--; } else { if (!@ftp_put($conn_id, $filename, $path.$filename, FTP_BINARY)) { echo "Could not upload backup to $ftp_host...backup left on localhost."; $ok--; } else { @unlink ($path.$filename); } } ftp_close($conn_id); } } ##################################### if ($ok >= 2) { echo 'Backup was successful! '.$count.' tables dumped.
'; } else { echo 'Backup failed.
'; } } else if ($_REQUEST['delete_ftp'] && $ftp_available) { $filenames = $_REQUEST['filenames']; $n = count($filenames); if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; } else { for ($i = 0; $i < $n; $i++) { if ($file = $filenames [$i]) { if (!@ftp_delete($conn_id, $file)) { echo "Could not delete $file from ftp server $ftp_host"; } } } } ftp_close($conn_id); } } else if ($_REQUEST['delete_localhost']) { $filenames = $_REQUEST['filenames']; $n = count($filenames); for ($i = 0; $i < $n; $i++) { if ($file = $filenames [$i]) { @unlink($path.$file); } } } ?> Database Backup". '
'. ''. ''. ''. ''. ''. ''. ''; if ($ftp_available) { echo ''. ''. ''; } echo ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. '
'. 'Select destination.'. '
'. ''. ''. '
'. ''. ''. '
'. ''. ''. '
'. 'Select which tables you would like to back up.'. '
'. ''. ''. '
'. ''. ''. '
'. ''. ''. '
'; $tables = $this->LoadAll("SHOW TABLE STATUS LIKE '%' "); echo ''. ''. ''. ''. ''. ''. ""; $i = 0; foreach ($tables as $table) { $bgcolor = ($i % 2) ? "#F6F6F6" : "#FFFFFF"; echo ''. ''. "". "". "". ""; $i++; } echo "
 Name:  # Records:  Size: 
'. ''. ''. ' ". $table['Name']. "  ". $table['Rows']. "  ". round($table['Data_length']/1024, 2). " kB 
". '
'. '
'; if ($ftp_available) { echo "

Backups on ftp server: $ftp_host

". '
'. ''. ''. ''. ''. ''. ''. ''. ""; if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; } else { if ($files = @ftp_nlist($conn_id,'.')) { sort($files); $i = 0; foreach ($files as $file) { $bgcolor = ($i % 2) ? "#F6F6F6" : "#FFFFFF"; if (ereg("([0-9]{8}_[0-9]{6}) - backup.(full|part).(sql|sql\.gz)", $file, $regs)) { $type = ($regs[2]=='full')?'Yes':'No'; $compressed = ($regs[3]=='sql.gz')?'Yes':'No'; $date = date("m/d/Y - h:i:s", backup_timestamptotime($regs[1])); $size = round((ftp_size($conn_id, $file))/1024, 2); echo ''. ''. ''. ''. ''. ''. ''; $i++; } } } } ftp_close($conn_id); } echo ''. ''. ''. '
 Del.  Date:  Full:  Compressed:  Size 
'. ''. ''. ' '.$date.'  '.$type.'  '.$compressed.'  '.$size.' kB 
'. ''. ''. '
'. '
'. '
'; } echo "

Backups on localhost in $path

". '
'. ''. ''. ''. ''. ''. ''. ''. ""; if (is_dir($path)) { if ($dh = opendir($path)) { $files = Array(); while (($file = readdir($dh)) !== false) { Array_push($files,$file); } closedir($dh); sort($files); $i = 0; foreach ($files as $file) { $bgcolor = ($i % 2) ? "#F6F6F6" : "#FFFFFF"; if (ereg("([0-9]{8}_[0-9]{6}) - backup.(full|part).(sql|sql\.gz)", $file, $regs)) { $type = ($regs[2]=='full')?'Yes':'No'; $compressed = ($regs[3]=='sql.gz')?'Yes':'No'; $date = date("m/d/Y - h:i:s", backup_timestamptotime($regs[1])); $size = round((filesize($path.$file))/1024, 2); echo ''. ''. ''. ''. ''. ''. ''; $i++; } } } } echo ''. ''. ''. '
 Del.  Date:  Full:  Compressed:  Size 
'. ''. ''. ' '.$date.'  '.$type.'  '.$compressed.'  '.$size.' kB 
'. ''. ''. ' To download backup, right-click and save as.'. '
'. '
'; } ################################################################ # Images ################################################################ else if ($menu2 == 'images') { $ftp_host = $this->config['graphic_backup_ftp_host']; $ftp_user = $this->config['graphic_backup_ftp_user']; $ftp_pass = $this->config['graphic_backup_ftp_pass']; $ftp_available = ($ftp_host && $ftp_user && $ftp_pass); $local_dir = $this->config['graphic_directory']; $timestamp = date("Ymd_His"); function ftp_parseline($line) { $file = Array(); if (ereg ("([-d][rwxst-]+).* ([0-9]) ([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*) ([a-zA-Z]+[0-9: ]*[0-9]) ([0-9]{2}:[0-9]{2}) (.+)", $line, $regs)) { $file['isdir'] = (substr ($regs[1],0,1) == "d"); $file['links'] = $regs[2]; $file['user'] = $regs[3]; $file['group'] = $regs[4]; $file['size'] = $regs[5]; $file['date'] = $regs[6]; $file['time'] = $regs[7]; $file['filename'] = $regs[8]; return $file; } else { return 0; } } function ftp_assoclist($conn_id,$dir='/',$recursive=false) { $files = Array(); if ($lines = ftp_rawlist ($conn_id, $dir, $recursive)) { $i = 0; foreach ($lines as $line) { if ($file = ftp_parseline($line)) { $files[$i] = $file; $i++; } } } return $files; } function backup_timestamptotime($timestamp) { if (ereg ("([0-9]{4})([0-9]{2})([0-9]{2})_([0-9]{2})([0-9]{2})([0-9]{2})", $timestamp, $date)) { return $time = mktime($date[4], $date[5], $date[6], $date[2], $date[3], $date[1]); } else { return 0; } } function backup_parseimagedirname($dirname) { $attribs = Array(); if (ereg("([0-9]{8}_[0-9]{6}) - images.(upd|full)", $dirname, $regs)) { $attribs['time'] = backup_timestamptotime($regs[1]); $attribs['timestamp'] = $regs[1]; $attribs['type'] = $regs[2]; return $attribs; } else { return 0; } } function latest_image_backup_time($conn_id) { $latest = 0; $files = ftp_assoclist($conn_id,'/'); foreach ($files as $file) { if ($file['isdir']) { if ($attribs = backup_parseimagedirname($file['filename'])) { if ($attribs['time'] > $latest) { $latest = $attribs['time']; } } } } return $latest; } function list_image_backupsassoc($conn_id) { $backups = Array(); $files = ftp_assoclist($conn_id,'/'); sort($files); $i = 0; foreach ($files as $file) { if ($file['isdir']) { if ($attribs = backup_parseimagedirname($file['filename'])) { $backups[$i]['filename'] = $file['filename']; $backups[$i]['time'] = $attribs['time']; $backups[$i]['type'] = $attribs['type']; $i++; } } } return $backups; } function ftp_mirrordirectorystructure($conn_id, $dir, $remote_dir) { $local_prefix = $dir; $stack[] = $dir; while ($stack) { $current_dir = array_pop($stack); if ($dh = opendir($current_dir)) { while (($file = readdir($dh)) !== false) { if ($file !== '.' && $file !== '..') { $current_file = "{$current_dir}/{$file}"; if (is_dir($current_file)) { @ftp_mkdir($conn_id, $remote_dir.'/'.substr($current_file,strlen($local_prefix)+1)); $stack[] = $current_file; } } } } } } function ftp_rmdirr($conn_id, $path) { $files = ftp_assoclist($conn_id, $path); foreach ($files as $file) { if ($file['filename'] !== '.' && $file['filename'] !== '..') { if ($file['isdir']) { ftp_rmdirr($conn_id, "$path/".$file['filename']); } else { ftp_delete($conn_id, "$path/".$file['filename']); } } } ftp_rmdir($conn_id, $path); } function list_directory($dir) { $file_list = ''; $stack[] = $dir; while ($stack) { $current_dir = array_pop($stack); if ($dh = opendir($current_dir)) { while (($file = readdir($dh)) !== false) { if ($file !== '.' && $file !== '..') { $current_file = "{$current_dir}/{$file}"; if (is_file($current_file)) { $file_list[] = "{$current_dir}/{$file}"; } elseif (is_dir($current_file)) { $stack[] = $current_file; } } } } } return $file_list; } if ($_REQUEST['image_backup'] && $ftp_available) { if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; } else { $count = 0; if ($_REQUEST['incremental']) { $latest_backup = latest_image_backup_time($conn_id); $backup_dir = $timestamp." - images.upd"; @ftp_mkdir($conn_id, $backup_dir); ftp_mirrordirectorystructure($conn_id, $local_dir, $backup_dir); $files = list_directory($local_dir); foreach ($files as $file) { $remote_filename = $backup_dir.'/'.substr($file,strlen($local_dir)+1); if (filemtime($file) >= $latest_backup) { if (!@ftp_put($conn_id, $remote_filename, $file, FTP_BINARY)) { echo 'Error in file '.$file.'.
'; } else { $count++; } } } } else { $backup_dir = $timestamp." - images.full"; @ftp_mkdir($conn_id, $backup_dir); ftp_mirrordirectorystructure($conn_id, $local_dir, $backup_dir); $files = list_directory($local_dir); foreach ($files as $file) { $remote_filename = $backup_dir.'/'.substr($file,strlen($local_dir)+1); if (!@ftp_put($conn_id, $remote_filename, $file, FTP_BINARY)) { echo 'Error in file '.$file.'.
'; } else { $count++; } } } echo 'Backup Complete. '.$count.' files transferred. '; } ftp_close($conn_id); } } else if ($_REQUEST['delete_image_backup'] && $ftp_available) { $filenames = $_REQUEST['filenames']; $n = count($filenames); if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; } else { for ($i = 0; $i < $n; $i++) { if ($file = $filenames[$i]) { @ftp_rmdirr($conn_id, $file); } } } ftp_close($conn_id); } } echo '

Backup Image Bay (Set in wikka.config.php)

'; if (!$ftp_available) { echo '
This feature requires an FTP file server. Please specify "graphic_backup_ftp_host", "graphic_backup_ftp_user", and "graphic_backup_ftp_pass" in wikka.config.php.'; } else { echo '
'. ''. ''. ''. ''. ''. ''. ''. ''. ''. ''. '
'. ''. ''. '
'. ''. ''. '
'. ''. ''. '
'. '
'; echo "

Backups on ftp server: $ftp_host

". '
'. ''. ''. ''. ''. ''. ''. ""; if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; } else { $backups = list_image_backupsassoc($conn_id); $i = 0; foreach ($backups as $backup) { $bgcolor = ($i % 2) ? "#F6F6F6" : "#FFFFFF"; echo ''. ''. ''. ''. ''. ''; $i++; } } ftp_close($conn_id); } echo ''. ''. ''. '
 Del.  BackupName:  Date:  Type: 
'. ''. ''. ' '.$backup['filename'].'  '.date("m/d/Y H:i.s", $backup['time']).'  '.(($backup['type']=='full')?'Full':'Incremental').' 
'. ''. ''. '
'. '
'; } } ################################################################ # Other Files ################################################################ else if ($menu2 == 'other') { $ftp_host = $this->config['db_backup_ftp_host']; $ftp_user = $this->config['db_backup_ftp_user']; $ftp_pass = $this->config['db_backup_ftp_pass']; $ftp_available = ($ftp_host && $ftp_user && $ftp_pass); $path = "exports/"; is_dir($path) || mkdir($path, 0766); $path = $path."codebackup/"; is_dir($path) || mkdir($path, 0766); $dl_pre_link = $path; $exclude = Array('exports','graphic'); if ($_REQUEST['backup'] == 'backup_code') { $compress = $_REQUEST['compress']; $timestamp = date("Ymd_His"); $filename = $timestamp." - code.tar"; ##################################### if ($compress) { $filename = $timestamp." - code.tar.gz"; } else { $filename = $timestamp." - code.tar"; } ##################################### # Save locally $exclude_string = " "; foreach ($exclude as $this_item) { $exclude_string .= " --exclude=".escapeshellarg($this_item)." "; } #echo "tar --create $exclude_string --file=".escapeshellarg($path.$filename)." ."; if ($compress) { system ("tar --gzip --create $exclude_string --file=".escapeshellarg($path.$filename)." .",$ret); } else { system ("tar --create $exclude_string --file=".escapeshellarg($path.$filename)." .",$ret); } $ok++; ################################################## ########################################## # Andrew: Upload the backup to FTP server # if option set and delete local file on success. if ($_REQUEST['destination'] == 'ftp' && $ftp_available) { if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; $ok--; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; $ok--; } else { if (!@ftp_put($conn_id, $filename, $path.$filename, FTP_BINARY)) { echo "Could not upload backup to $ftp_host...backup left on localhost."; $ok--; } else { @unlink ($path.$filename); } } ftp_close($conn_id); } } ##################################### if ($ok >= 1) { echo 'Backup was successful!
'; } else { echo "Backup failed. "; } } else if ($_REQUEST['delete_ftp'] && $ftp_available) { $filenames = $_REQUEST['filenames']; $n = count($filenames); if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; } else { for ($i = 0; $i < $n; $i++) { if ($file = $filenames [$i]) { if (!@ftp_delete($conn_id, $file)) { echo "Could not delete $file from ftp server $ftp_host"; } } } } ftp_close($conn_id); } } else if ($_REQUEST['delete_localhost']) { $filenames = $_REQUEST['filenames']; $n = count($filenames); for ($i = 0; $i < $n; $i++) { if ($file = $filenames [$i]) { unlink($path.$file); } } } echo "

Other Files (Code and Folders in Wiki Root)

". '
'. ''. ''. ''. ''; if ($ftp_available) { echo ''. ''. ''; } echo ''. ''. ''. ''. ''. ''. '
'. ''. ''. '
'. ''. ''. '
'. ''. ''. '
'. ''. ''. '
'. '
'. '
'; if ($ftp_available) { echo "

Backups on ftp server: $ftp_host

". '
'. ''. ''. ''. ''. ''. ""; if (!($conn_id = @ftp_connect($ftp_host))) { echo "Could not connect to ftp server."; } else { if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) { echo "Could not log in to ftp server."; } else { if ($files = @ftp_nlist($conn_id,'.')) { sort($files); $i = 0; foreach ($files as $file) { $bgcolor = ($i % 2) ? "#F6F6F6" : "#FFFFFF"; if (ereg("([0-9]{8}_[0-9]{6}) - code.(tar|tar\.gz)", $file, $regs)) { $size = round((ftp_size($conn_id, $file))/1024, 2); echo ''. ''. ''. ''. ''; $i++; } } } } ftp_close($conn_id); } echo ''. ''. ''. '
 Del.  Name:  Size 
'. ''. ''. ' '.$file.'  '.$size.' kB 
'. ''. ''. '
'. '
'. '
'; } echo "

Backups on localhost in $path

". '
'. ''. ''. ''. ''. ''. ""; if (is_dir($path)) { if ($dh = opendir($path)) { $files = Array(); while (($file = readdir($dh)) !== false) { Array_push($files,$file); } closedir($dh); sort($files); $i = 0; foreach ($files as $file) { $bgcolor = ($i % 2) ? "#F6F6F6" : "#FFFFFF"; if (ereg("([0-9]{8}_[0-9]{6}) - code.(tar|tar\.gz)", $file, $regs)) { $size = round((filesize($path.$file))/1024, 2); echo ''. ''. ''. ''. ''; $i++; } } } } echo ''. ''. ''. '
 Del.  Name:  Size 
'. ''. ''. ' '.$file.'  '.$size.' kB 
'. ''. ''. ' To download backup, right-click and save as.'. '
'. '
'; } # End other files ####################### } } ?> %% In the interest of fairness, I want to briefly describe the development of this tool. I conceptualized most of the tools to support my project and Andrew wrote most (but not all of) the 'code' here. If people have problems I'll address them the best I can, but will probably have to ask Andrew's indulgence for providing feedback. WazoO Adds - Until Mike gets back and updates this page, this is what I did to make this functional. Code fix; %%(php) Line 64 echo ($menu1 != 'users')?''.$page_name.'' %% New Table needed, based on my best guess by looking at what the code was looking for; %%(mysql) mysql> CREATE TABLE `wikka_resetpasswords` ( -> `username` varchar(75) NOT NULL default '', -> `password` varchar(32) NOT NULL default '', -> PRIMARY KEY (`username`) -> ) TYPE=MyISAM; Query OK, 0 rows affected (0.00 sec) %% As the field "login_count" and the code needed to stuff this filed isn't provided (and I've not found it described anywhere in this Wiki) I commented out some lines, modified another to drop the field from a Query ... the "Delete User" section is provided here to make it a cut/past/replace operation; %%(php) # Delete Users ################################################################ if ($menu2 == 'delete') { if ($_REQUEST['set']) { $delete = $_REQUEST['delete']; $n = count($delete); for ($i = 0; $i < $n; $i++) { if ($this_delete = $delete[$i]) { $this->Query("DELETE FROM `$t_users` WHERE `name`='".mysql_real_escape_string($this_delete)."'"); } } } $sort = stripslashes($_REQUEST['sort']); $sort_order = stripslashes($_REQUEST['sortorder']); $cur_page = stripslashes($_REQUEST['page']); if ($sort == 'name') $order = 'ORDER BY `name`'; else $order = 'ORDER BY `signuptime`'; if ($sort_order == 'ASC') { $order .= ' ASC' ; $sort_order = 'DESC'; $sort_order2 = 'ASC'; } else { $order .= ' DESC'; $sort_order = 'ASC'; $sort_order2 = 'DESC'; } // need database field $query = "SELECT `name`,`signuptime`,`login_count`,`email` FROM `$t_users` WHERE `password`!='Reserved Account' $order "; $query = "SELECT `name`,`signuptime`,`email` FROM `$t_users` WHERE `password`!='Reserved Account' $order "; $page = new Page(); $total_records = count($this->LoadAll($query)); $page->set_page_data($this_link.'&sort='.$sort.'&sortorder='.$sort_order2,$total_records,RECORDS_PER_PAGE,5,true,true,true); ob_start(); $page->get_page_nav(); $page_nav = ob_get_contents(); ob_end_clean(); $users = $this->LoadAll($page->get_limit_query($query)); $this_link2 = $this_link.'&sort='.$sort.'&sortorder='.$sort_order2.'&page='.$cur_page; echo '
'. '

Wiki User Delete

'. ''. ''. ''. ''. ''. "". ''. // need database field "". "". "". ''. ""; $i = 0; foreach($users as $user) { if ($stat!=="0") $num = $this->LoadSingle("SELECT count(*) as n from ".$this->config["table_prefix"]."pages where owner='".$user["name"]."' AND latest = 'Y'"); echo ''. ''. "". // need database field "". "". "". "". ''; $i ++; } echo '
'. '
'.$page_nav.'
'. '
 Del.  Name  # logins  Owned Pages  Email  Signup Date/Time 
'. ''. ''. '".$this->Link($user["name"])."".$user["login_count"]."".($stat!=="0"?"".$num["n"]."":"")."".$user["email"]."(".$user["signuptime"].")
'. ''. ''. '
'; } ################################################################ %% WazoO - 9 Feb 2006