PHP Labware source code viewer / Internal utilities | 25 Apr, 2024
Root | Help
./LabWiki/backups.php
<?php

/*
LabWiki 1.2.1, 22 August 2012, by Santosh Patnaik, MD, PhD. Based on QwikiWiki 1.5 of David Barrett
*/

////// BACKUP MAINTAINANCE 
//////// Requires edit.php be such that backups are made in
//////// document specific subdirectories
//////// inside backups folders
//////////// Also requires appropriate Javascript in
//////////// template files and show_backup.php and show_source.php files.
////// See - https://sourceforge.net/tracker/?func=browse&group_id=80406&atid=625194

include( "_global.php" );
QWDisableCaching( );

// set extra javascript so buttomn pressing and not 'enter' key works
$extra_javascript = 
'function checkCR(evt) 
{
var evt  = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if ((evt.keyCode == 13) && (node.type=="text")) {return false;}
}
document.onkeypress = checkCR;';

// checks
if(!$QW['requestPage'])
  {QWRedirect( "index.php" );exit;}
if(!$QW['userIsAuthenticated'])
  {QWRedirect("login.php?page=".htlmspecialchars($QW['page']).$QW['URLSuffix']);exit;}
if(!is_file($QW['pagePath']))
  {QWRedirect( "index.php" );exit;}

// Update the list of recently viewed pages
$recentlyViewedPages[] = $QW['page'];
if( isset( $QW['cookieRecentPageList'] ) ) 
{$QW['cookieRecentPageList'] = array_merge( array( $QW['page'] ), $QW['cookieRecentPageList'] );}
else                                      
{$QW['cookieRecentPageList'] = array( $QW['page'] );}
$QW['cookieRecentPageList'] = QWUnduplicateArray( $QW['cookieRecentPageList'] );
QWTruncateArrayInPlace( $QW['cookieRecentPageList'], 20 ); // only keep a history of 20 pages
setcookie( "recentpages", serialize( $QW['cookieRecentPageList'] ), time()+60*60*24*30 );
// QWTBackupFormatTitle
$titlePrefix = "Backup maintainance | Document: ";
$QW_TEMPLATE['getTitle'] = "QWTBackupFormatTitle";
function QWTBackupFormatTitle( )
{global $titlePrefix, $QW;
return $titlePrefix . QWCleanQwikiPageName( $QW['page'] );
}

//////////////////// Delete specific backup file if requested
if (isset($_GET['delete_page']) && strcasecmp(substr($_GET['delete_page'], -6), '.qwiki') == 0)
{
$pagename =  $QW['page'];
$file_to_delete = 'backups/'.$pagename.'/'.$_GET['delete_page'];
if (is_file($file_to_delete)) 
 {
 unlink ($file_to_delete);
 }
$message = 'The specified file was deleted.';
}

//////////////////// Restore current document with backup file if requested
if (isset($_GET['restore_page']) && strcasecmp(substr($_GET['restore_page'], -6), '.qwiki') == 0)
{
// don't do if lock exists
if (!QWLockExists($QW['lockPath']))
 {
 // Make backup of current version
 $pagename =  $QW['page'];
 $backupDir = 'backups/'.$pagename;
 $c = 0;
 do
  {
  // Increment the version number
  $backupPath = sprintf( "$backupDir/$QW[page].%04d.qwiki", $c++ );
  }
 while( is_file( $backupPath ) );
 if( is_file( $QW['pagePath'] ) ) 
  {copy( $QW['pagePath'], $backupPath );
  }
 // Delete the current version
 unlink ( $QW['pagePath'] );
 // Restore with designated backup file and then delete it
 $backup_to_copy = $backupDir.'/'.$_GET['restore_page'];
 copy( $backup_to_copy , $QW['pagePath'] );
 unlink ($backup_to_copy);
 // Notify
 $message = '<p>The wiki document has been restored with data from <em>' . htmlspecialchars($_GET['restore_page']) . '</em>. You can log out now.</p>';
 }
else 
 {
 $message = '<p>Restoration cannot be performed as the wiki document is being edited by someone. Please try later. You can log out now.</p>';
 }
}

/////////////////////////////// Directory removal function
function remove_dir($dir)
{
global $total_count;
if(!is_dir($dir)){return false;}
$handle = opendir($dir);
while (false!==($item = readdir($handle)))
 {
 if($item != '.' && $item != '..')
   {if(is_dir($dir.'/'.$item)) 
     {remove_dir($dir.'/'.$item);}
    else
     {unlink($dir.'/'.$item); $total_count++;}
   }
 }
closedir($handle);
$success=false;
if(rmdir($dir))
 {$success = true;}
return $success;
}

////////////////////////////// Delete all backups for this document
if (isset($_POST['this_all']))
{
$total_count = 0;
$pagename =  $QW['page'];
$dir_to_delete = 'backups/'.$pagename;
remove_dir($dir_to_delete);
$message = '<p>All backup files - a total of ' . $total_count . ' - for this document have been deleted. You may log out now.</p>';
}

///////////////////////////// Delete all backups for entire wiki
if (isset($_POST['all_all']))
{
$total_count = 0;
$dir_to_delete = 'backups';
remove_dir($dir_to_delete);
$backup_dir = $dir_to_delete;
// recreate backups directory as it was deleted
QWVerifyDirectory( $backup_dir );
chmod ($backup_dir, 0755);
$message = '<p>All backup files - a total of ' . $total_count . ' - for the entire wiki have been deleted. You may log out now.</p>';
}

///////////////// Delete certain number of backups for this document by age
if (isset($_POST['this_days']) && isset($_POST['this_days_number']))
{
$n = $_POST['this_days_number'];
if (!preg_match("/^([0-9]+)$/",$n))
 {
 $message = '<p>Please input a positive number, such as 2, 5, etc.</p>';
 }
else
 {
 // convert no. of days to seconds
 $n = 86400 * $n;
 // sort the files
 $number_deleted = 0;
 $pagename =  $QW['page'];
 $dir_to_use = 'backups/'.$pagename;
 $handle = opendir($dir_to_use); 
 while (false!==($itemname = readdir($handle)))
  { 
  if(!is_dir($dir_to_use.'/'.$itemname) && strcasecmp(substr($itemname, -6), '.qwiki') == 0)
    {
    $the_path = $dir_to_use.'/'.$itemname;
    $age = time() - filemtime($the_path);
    if ($age > $n)
     {
     unlink ($the_path);
     $number_deleted++;
     }
    } 
  }
 closedir($handle);
 if ($number_deleted == 0)
  {
  $message = '<p>No backup files had to be deleted. You may log out now.</p>';
  }
 else
  {
  if ($number_deleted == 1)
   {
   $message = '<p>One backup file was deleted. You may log out now.</p>';
   }
  else
   {
   $message = '<p>'.$number_deleted.' backup files were deleted. You may log out now.</p>';
   }
  }
 } 
}

/////////////// Delete certain number of backups for all of wiki by age
if (isset($_POST['all_days']) && isset($_POST['all_days_number']))
{
$n = $_POST['all_days_number'];
if (!preg_match("/^([0-9]+)$/",$n))
 {
 $message = '<p>Please input a positive number, such as 2, 5, etc.</p>';
 }
else
 {
 // convert no. of days to seconds
 $n = 86400 * $n;
 // get all directories
 $handle = opendir(backups); 
 while (false!==($item_name = readdir($handle)))
  {
  if($item_name != '.' && $item_name != '..')
   {
   if(is_dir('backups/'.$item_name))
    {
    $dir_list[] = 'backups/'.$item_name;
    }
   }
  }
 closedir($handle);
 $number_deleted = 0;
 $total_count = 0;
 // start deleting if aged
 foreach ($dir_list as $key=>$value)
 {
 $handle = opendir($value); 
 while (false!==($itemname = readdir($handle)))
  { 
  if(!is_dir($value.'/'.$itemname) && strcasecmp(substr($itemname, -6), '.qwiki') == 0)
    {
    $total_count++;
    $the_path = $value.'/'.$itemname;
    $age = time() - filemtime($the_path);
    if ($age > $n)
     {
     unlink ($the_path);
     $number_deleted++;
     // to show what was deleted
     $list_item = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$itemname . '<br />';
     $list_deleted .= $list_item;
     }
    } 
  }
 closedir($handle);
 }
 if ($number_deleted == 0)
  {
  $message = '<p>No backup file from a total of ' . $total_count . ' had to be deleted. You may log out now.</p>';
  }
 else
  {
  if ($number_deleted == 1)
   {
   $message = '<p>One backup file from a total of ' . $total_count .' was deleted:<br /><br />'.$list_deleted.' <br />You may log out now.</p>';
   }
  else
   {
   $message = '<p>These '. $number_deleted.' backup files from a total of ' . $total_count . ' were deleted:<br /><br />'.$list_deleted.' <br />You may log out now.</p>';
   }
  }
 } 
}

//////////////////// Delete certain number of backups for this document by version
if (isset($_POST['this_versions']) && isset($_POST['this_versions_number']))
{
$n = $_POST['this_versions_number'];
if (!preg_match("/^([0-9]+)$/",$n))
 {
 $message = '<p>Please input a positive number, such as 2, 5, etc.</p>';
 }
else
 {
 // get the files
 $number_deleted = 0;
 $pagename =  $QW['page'];
 $dir_to_use = 'backups/'.$pagename;
 $handle = opendir($dir_to_use); 
 while (false!==($itemname = readdir($handle)))
  { 
  if(!is_dir($dir_to_use.'/'.$itemname) && strcasecmp(substr($itemname, -6), '.qwiki') == 0)
    {
    $file_list['path'][] = $dir_to_use.'/'.$itemname;
    $file_list['age'][] = filemtime($dir_to_use.'/'.$itemname);
    } 
  }
 closedir($handle);
 // sort the files by age - youngest first
 arsort($file_list['age']); 
 $i=0; 
 while (list ($key, $val) = each ($file_list['age'])) 
  { 
  $sorted_list[$i]['path'] = $file_list['path'][$key]; 
  $sorted_list[$i]['age'] = $file_list['age'][$key]; 
  $i++; 
  }
 // get age of latest file that will be deleted
 $age_limit = $sorted_list[$n]['age'];
 // delete files with age equalling or more than age_limit
 foreach ($sorted_list as $key => $value)
 {
 if (!($sorted_list[$key]['age'] > $age_limit))
  {
  unlink ($sorted_list[$key]['path']);
  $number_deleted++;
  }
 }
 if ($number_deleted == 0)
  {
  $message = '<p>No backup files had to be deleted. You may log out now.</p>';
  }
 else
  {
  if ($number_deleted == 1)
   {
   $message = '<p>One backup file was deleted. You may log out now.</p>';
   }
  else
   {
   $message = '<p>'.$number_deleted.' backup files were deleted. You may log out now.</p>';
   }
  }
 } 
}

//////////////////// Delete certain number of backups for entire wiki by version
if (isset($_POST['all_versions']) && isset($_POST['all_versions_number']))

{

$n = $_POST['all_versions_number'];

if (!preg_match("/^([0-9]+)$/",$n))
 {
 $message = '<p>Please input a positive number, such as 2, 5, etc.</p>';
 }

else
 {
 $number_deleted = 0;
 $total_count = 0;
 // get all directories
 $handle = opendir(backups); 
 while (false!==($item_name = readdir($handle)))
  {
  if($item_name != '.' && $item_name != '..')
   {
   if(is_dir('backups/'.$item_name))
    {
    $dir_list[] = 'backups/'.$item_name;
    }
   }
  }
 closedir($handle);
 // get files from all directories
 foreach ($dir_list as $key=>$value)
 {
 
 $handle2 = opendir($value);
 
 while (false!==($itemname = readdir($handle2)))
  { 
  if(!is_dir($value.'/'.$itemname) && strcasecmp(substr($itemname, -6), '.qwiki') == 0)
    {
    $total_count++;
    $file_list['path'][] = $value.'/'.$itemname;
    $file_list['age'][] = filemtime($value.'/'.$itemname);
    // sort the files by age - youngest first
    arsort($file_list['age']); 
    $i=0; 
    while (list ($key2, $value2) = each ($file_list['age'])) 
     { 
     $sorted_list[$i]['path'] = $file_list['path'][$key2]; 
     $sorted_list[$i]['age'] = $file_list['age'][$key2]; 
     $i++; 
     }
    }
  }
 
 // further proceed if targeted backups present 
 
 if (count($sorted_list) > $n)
 {
 // get age of latest file that will be deleted
 // e.g., if n=3, this will be 4th youngest file, 1st to 3rd being younger 
 $age_limit = $sorted_list[$n]['age'];
 // make list of files with age equalling or more than age_limit
 foreach ($sorted_list as $key3 => $value3)
  {
  if (!($sorted_list[$key3]['age'] > $age_limit))
   {
   $to_delete_list[] = $sorted_list[$key3]['path'];
   }
  }
 }
 
 // reset the arrays except to_delete_list
 $file_list = array();
 $sorted_list = array();
 closedir($handle2); 
 
 }
 
// start deleting
$to_delete_list = array_unique($to_delete_list);

foreach ($to_delete_list as $key4 => $value4)
 {
 if (file_exists($value4))
  {
  unlink ($value4); 
  $number_deleted++;
  // to show what was deleted
  $list_item = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$value4. '<br />';
  $list_deleted .= $list_item;
  }
 }
 
 if ($number_deleted == 0)
  {
  $message = '<p>No backup file from a total of ' . $total_count . ' had to be deleted. You may log out now.</p>';
  }
 else
  {
  if ($number_deleted == 1)
   {
   $message = '<p>One backup file from a total of ' . $total_count .' was deleted:<br /><br />'.$list_deleted.' <br />You may log out now.</p>';
   }
  else
   {
   $message = '<p>These '. $number_deleted.' backup files from a total of ' . $total_count . ' were deleted:<br /><br />'.$list_deleted.' <br />You may log out now.</p>';
   }
  }
 } 
}

//////////////////////////////////////// QWTBackupInjectBody
$QW_TEMPLATE['injectBody'] = "QWTBackupInjectBody";
function QWTBackupInjectBody( )
{
global $QW, $QW_CONFIG, $errorHTML, $message, $total_count;
if( $errorHTML ) {echo QWFormatMessage( $errorHTML );}
$pagename =  $QW['page'];
$backup_dir = 'backups/'.$pagename.'/';
// output result of actions
echo ('<table summary="none" width="790" ><tr align="center"><td align="center">');
echo ("<p><i>" . $message . "</i></p>");
// output title of document
echo "<p><b>Wiki document</b> - " . htmlspecialchars(QWCleanQwikiPageName( $QW['page'] )) . "</b></p>";
// checks if backup directory exists or not 
if (!is_dir($backup_dir))
{ echo "<p>Backups of previous versions of this document do not exist.</p>"; }
// get list of files if it exists
else 
{
$handle = opendir($backup_dir);
$list= array();
while (false!==($item = readdir($handle)))
 {
 // See if it's a qwiki file
 if(!is_dir( $item) && strcasecmp(substr($item, -6), '.qwiki') == 0)
  {$list[] = $item;} 
 } 
closedir($handle);
// if list empty
$number = count ($list);
if ($number == 0)
 { 
 echo "<p>Backups of previous versions of this document do not exist.</p>";
 }
else 
 { 
 if ($number ==1)
 {
 echo "<p>One previous version of this document is available as backup.</p>";
 }
 else
 {
 echo "<p>" . $number ." previous versions of this document are available as backups.</p>";
 }
 echo '<table class="QWInnerSection" summary="list" cellpadding="2">
 <tr class="QWInnerSectionTitle">
 <td align="left">Filename</td>
 <td align="left">Generated - date &amp; time</td>
 <td align="left">Size - bytes</td>
 <td align="left">Action</td>
 </tr>';
 foreach ($list as $item)
  {
  $path = $backup_dir.'/'.$item;
  $size = filesize ($path);
  $creation_time = filemtime ($path);
  $time = date ("F d, Y: Hi", $creation_time);
 echo '
<tr>
	<td align="left">
		' . htmlspecialchars($item) . '
	</td>
	<td align="left">
		' . $time . ' h
	</td>
	<td align="left">
		' . $size . '
	</td>
	<td align="left">
		<a href="show_backup.php?page='.htmlspecialchars($item).'" onclick="window.open(this.href); return false;" onkeypress="window.open(this.href); return false;">
			View
		</a>
		| 
		<a href="show_source.php?page='.htmlspecialchars($item).'" onclick="window.open(this.href); return false;" onkeypress="window.open(this.href); return false;">
			Code
		</a>
		| 
		<a href="javascript:confirmdelete(\'backups.php?page='.htmlspecialchars($QW['page']).'&amp;delete_page='.htmlspecialchars($item).'\')">
			Delete
		</a>
		| 
		<a href="javascript:confirmdelete(\'backups.php?page='.htmlspecialchars($QW['page']).'&amp;restore_page='.htmlspecialchars($item).'\')">
			Restore
		</a>
	</td>
</tr>
';
  }
 echo "</table>"; 
 }

}
// code form for various options
echo ('<form class="QWForm" method="post" action="backups.php?page='.htmlspecialchars($QW['page']).'">
<input type="hidden" name="debug" value="'.htmlspecialchars($QW['requestDebug']).'" />
<input type="hidden" name="help" value="'.htmlspecialchars($QW['requestHelp']).'" />');
// show document-specific options if backups present
if (!empty($number))
{echo ('
<p>Delete all backups for this document - 
<input type="submit" name="this_all" action="backups.php?page='.htmlspecialchars($QW['page']).'" value="Delete" onclick="return confirmsubmit()" />
<br />
Delete backups older than these many days - 
<input type="text" name="this_days_number" maxlength="3" size="3" value="30">
<input type="submit" name="this_days" action="backups.php?page='.htmlspecialchars($QW['page']).'" value="Delete" onclick="return confirmsubmit()" />
<br />
Delete backups older than these many versions - 
<input type="text" name="this_versions_number" maxlength="3" size="3" value="3">
<input type="submit" name="this_versions" action="backups.php?page='.htmlspecialchars($QW['page']).'" value="Delete" onclick="return confirmsubmit()" />
</p>');
}
// show options for entire wiki
echo ('
<p><strong>Entire wiki</strong></p>
<p>Delete all backups for entire wiki - 
<input type="submit" name="all_all" action="backups.php?page='.htmlspecialchars($QW['page']).'" value="Delete" onclick="return confirmsubmit()" />
<br />
Delete backups older than these many days for entire wiki - 
<input type="text" name="all_days_number" maxlength="3" size="3" value="30">
<input type="submit" name="all_days" action="backups.php?page='.htmlspecialchars($QW['page']).'" value="Delete" onclick="return confirmsubmit()" />
<br />
Delete backups older than these many versions for entire wiki -
<input type="text" name="all_versions_number" maxlength="3" size="3" value="3">
<input type="submit" name="all_versions" action="backups.php?page='.htmlspecialchars($QW['page']).'" value="Delete" onclick="return confirmsubmit()" />
</p>
</form>');
// help
QWFormatHelp( "Everytime a wiki document is edited, a backup of the older version is generated. These backups can accummulate to a large number over time. To trim them, a number of options are provided here. Before deleting a backup, its contents can be viewed as formatted (view) or without formatting (code). The latter allows easy copying and pasting. The current wiki file may be restored with a specific backup file (restore). Note that backups contain only the text and not any attached image files, etc. Restoring with a backup will therefore not restore any attached files that were deleted. Similarly, when viewing a backup file, attached files will not be displayed.", "backups.php?page=".htmlspecialchars($QW['page']) );
	echo ('</td></tr></table>');
}

//////////////////////////////////////////// QWTBackupFormatCommandList
$QW_TEMPLATE['commandList'] = "QWTBackupFormatCommandList";
function QWTBackupFormatCommandList( )
{global $QW, $QW_CONFIG;	
 if($QW['userIsAuthenticated']){$commandList[]='<a href="logout.php?page='.htmlspecialchars($QW['page']).$QW['URLSuffix'].'">Admin logout</a>';}
   else{$commandList[]='<a href="login.php?page='.htmlspecialchars($QW['page']).$QW['URLSuffix'].'">Admin login</a>';}
 $commandList[] = '<a href="index.php?page='.htmlspecialchars($QW['page']).$QW['URLSuffix'].'">Back to '.htmlspecialchars(QWCleanQwikiPageName( $QW['page'] )) .'</a>';
 if($QW['requestFrom']){$fromSuffix="&amp;from=".htmlspecialchars($QW['requestFrom']);}
   else{$fromSuffix="";}
 return $commandList;
}

/////////////////////////////////////////// Include the template
include( $QW_CONFIG['templateFilename'] );
// Output debugging, if requested
if( $QW_CONFIG['enableDebugging'] && $QW['requestDebug'] ) echo QWFormatDebug( );
Presented with Sourceer
PHP Labware home | visitors since Sept 2017