Login   Register  
PHP Classes
elePHPant
Icontem

File: tools/updater.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Kristo Vaher  >  Wave Framework  >  tools/updater.php  >  Download  
File: tools/updater.php
Role: Auxiliary script
Content type: text/plain
Description: Updater Tool
Class: Wave Framework
MVC framework for building Web sites and APIs
Author: By
Last change: Made session starting configurations possible to be changed at runtime.
Updated documentation with indexes and anchors.
Added jQuery 2.0 as an alternative - to use the new version of jQuery that ignores Internet Explorer up to and including 8, then change jquery.js file to jquery2.js in the View Controller.
Developer tools Debugger and Log Reader for internal log messages are now browser IP and session-based, allowing to separate messages from one another based on client that makes the request.
Added a warning to developer tools when using the default password.
Fixed bug with tester script that did not properly autoload certain PHP scripts.
Implemented an improved getState() method that allows to return data better from nested arrays.
Implemented an improved setState() that allows to set nested array values in State more easily.
PNG images will also now get a background, if RGB setting is set in the dynamic image loading.
Date: 2013-05-21 01:44
Size: 14,475 bytes
 

Contents

Class file image Download
<?php

/**
 * Wave Framework <http://www.waveframework.com>
 * Updater
 *
 * This script is used to update Wave Framework application. It downloads an archive from specific 
 * URL and unpacks it in the temporary folder where it will be used by FTP to update all files in 
 * root folder of the system.
 *
 * @package    Tools
 * @author     Kristo Vaher <kristo@waher.net>
 * @copyright  Copyright (c) 2012, Kristo Vaher
 * @license    GNU Lesser General Public License Version 3
 * @tutorial   /doc/pages/guide_tools.htm
 * @since      1.8.9
 * @version    3.6.0
 */

// This initializes tools and authentication
require('.'.DIRECTORY_SEPARATOR.'tools_autoload.php');

// Log is printed out in plain text format
header('Content-Type: text/html;charset=utf-8');

?>
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>Updater</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width"/> 
		<link type="text/css" href="style.css" rel="stylesheet" media="all"/>
		<link rel="icon" href="../favicon.ico" type="image/x-icon"/>
		<link rel="icon" href="../favicon.ico" type="image/vnd.microsoft.icon"/>
		<meta content="noindex,nocache,nofollow,noarchive,noimageindex,nosnippet" name="robots"/>
		<meta http-equiv="cache-control" content="no-cache"/>
		<meta http-equiv="pragma" content="no-cache"/>
		<meta http-equiv="expires" content="0"/>
	</head>
	<body>
		<?php
		
		// Pops up an alert about default password
		passwordNotification($config['http-authentication-password']);
		
		// Header
		echo '<h1>System update</h1>';
		echo '<h4 class="highlight">';
		foreach($softwareVersions as $software=>$version){
			// Adding version numbers
			echo '<b>'.$software.'</b> ('.$version.') ';
		}
		echo '</h4>';

		// Nothing has been submitted yet
		if(empty($_POST) && empty($_GET)){
		
			echo '<h2>Apply Update</h2>';
			
			// This script only works if Zip and FTP functions are supported
			if(extension_loaded('Zip') && extension_loaded('ftp')){
				?>
					<form method="post" action="" enctype="multipart/form-data">
						<p class="bold">Update archive URL:</p>
						<input type="text" name="archive_url" value=""/>
						<p class="bold">Update archive file upload:</p>
						<input type="file" name="archive_file"/>
						<p class="bold">FTP directory (this is the directory your system is installed in)</p>
						<input type="text" name="ftp_directory" value="/"/>
						<p class="bold">FTP username</p>
						<input type="text" name="ftp_username" value=""/>
						<p class="bold">FTP password</p>
						<input type="password" name="ftp_password" value=""/>
						<p><input type="submit" value="APPLY UPDATE"/></p>
					</form>
				<?php
			} else {
				// required extensions don't seem to be used
				echo '<p class="bold">Updater requires Zip and FTP PHP extensions</p>';
			}

		} elseif(trim($_REQUEST['ftp_username'])!='' && trim($_REQUEST['ftp_password'])!='' && trim($_REQUEST['ftp_directory'])!=''){
		
			// Error encounter flag
			$error='';

			// This script only works if Zip and FTP functions are supported
			if(extension_loaded('Zip') && extension_loaded('ftp')){

				// If file has been uploaded then this is used instead of archive URL
				if(isset($_FILES['archive_file']) && !empty($_FILES['archive_file']) && $_FILES['archive_file']['error']==0){
				
					// Update archive is moved to temporary directory
					if(!move_uploaded_file($_FILES['archive_file']['tmp_name'],'..'.DIRECTORY_SEPARATOR.'filesystem'.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'update.zip')){
						// Error is archive file creation failed
						$error='Cannot store update archive to temporary files';
					}
					
				} elseif(isset($_REQUEST['archive_url']) && trim($_REQUEST['archive_url'])!=''){
				
					// Since archive URL was set, then system downloads the file
					$file=file_get_contents($_REQUEST['archive_url']);
					if($file){
						// Downloaded file contents are placed in update.zip file in temporary directory
						if(!file_put_contents('..'.DIRECTORY_SEPARATOR.'filesystem'.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'update.zip',$file)){
							// Error is archive file creation failed
							$error='<p class="bold red">Cannot store update archive to temporary files';
						}
					} else {
						// Error is thrown if downloading failed
						$error='Cannot download update archive from '.$_REQUEST['archive_url'];
					}
					
				} else {
					// Since archive file was not set with URL or uploaded file, system throws an error
					$error='Update archive was not uploaded or found';
				}
				
				// Only continues if no error has been encountered
				if($error==''){
				
					// Zip is used to unpack the update archive
					$zip=new ZipArchive;
					
					// Opening the previously created archive
					if($zip->open('..'.DIRECTORY_SEPARATOR.'filesystem'.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'update.zip')){
					
						// This is the directory where update archive contents will be unpacked
						$updateArchiveDirectory='..'.DIRECTORY_SEPARATOR.'filesystem'.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'update-'.date('Y-m-d-H-i-s').DIRECTORY_SEPARATOR;
						// If cache folder does not exist, it is created
						if(!is_dir($updateArchiveDirectory)){
							if(!mkdir($updateArchiveDirectory,0755)){
								$error='Cannot create update folder';
							}
						}
						
						// Only continues if no error has been encountered
						if($error==''){
					
							// Archive is unpacked
							if($zip->extractTo($updateArchiveDirectory)){
							
								// Testing if the update archive version is new or not
								if(file_exists($updateArchiveDirectory.'.version')){
									// Default version numbers
									$updateVersions=array();
									// Loading data from version file to array
									$versionsRaw=explode("\n",str_replace("\r",'',file_get_contents($updateArchiveDirectory.'.version')));
									foreach($versionsRaw as $ver){
										// Versions are separated by colon in the version file
										$thisVersion=explode(':',$ver);
										$updateVersions[$thisVersion[0]]=$thisVersion[1];
									}
									
									// This tests if new version numbers are good for this update
									$versionValid=true;
									foreach($softwareVersions as $software=>$version){
										if(!isset($updateVersions[$software]) || version_compare($updateVersions[$software],$version)==-1){
											$versionValid=false;
										}
									}
									
									// Making sure that update archive version numbers are at least equal to current installations version numbers
									if($versionValid){
									
										// Connecting to localhost FTP
										$ftpConnection=ftp_connect('localhost');
										
										// If connection is a success
										if($ftpConnection){
										
											// If log-in with provided authentication is a success
											if(ftp_login($ftpConnection,$_REQUEST['ftp_username'],$_REQUEST['ftp_password'])){
											
												// This attempts to change current FTP connection to installation directory
												if(ftp_chdir($ftpConnection,$_REQUEST['ftp_directory'])){
												
													// Assigning current FTP directory
													$ftpDirectory=$_REQUEST['ftp_directory'];
													// Making sure that FTP directory ends in slash
													$lastCharacter=strrev($ftpDirectory);
													if($lastCharacter[0]!=DIRECTORY_SEPARATOR){
														$ftpDirectory.=DIRECTORY_SEPARATOR;
													}
													// This is the directory where files are
													$ftpUpdateDirectory=$ftpDirectory.'filesystem/tmp/update/';
													// Installation directory contents
													$directoryContents=ftp_nlist($ftpConnection,'.');
													
													// This checks if .version file exists in this directory and is the same size as the current installation and has been modified at the same time
													if(in_array('.version',$directoryContents) && ftp_size($ftpConnection,'.version')==filesize('..'.DIRECTORY_SEPARATOR.'.version') && ftp_mdtm($ftpConnection,'.version')==filemtime('..'.DIRECTORY_SEPARATOR.'.version')){

														// Target archive of the backup
														$backupFilename='system-backup-'.date('Y-m-d-H-i-s').'.zip.tmp';
														// This creates a backup of all core files, if this fails then updater will not continue
														if(systemBackup('../','..'.DIRECTORY_SEPARATOR.'filesystem'.DIRECTORY_SEPARATOR.'backups'.DIRECTORY_SEPARATOR.$backupFilename)){
															
															// This stores log messages
															$log=array();
															// Since backup was successful
															$log[]='SYSTEM BACKUP SAVED TO /filesystem/backups/'.$backupFilename;

															// Scanning the unpacked archive directory
															$files=scandir($updateArchiveDirectory);
															// Notice that files were updated
															$log[]='INSTALLING UPDATE FILES';
															
															// This will loop over all the files if files were found in this directory
															if(!empty($files)){
																$log=array_merge($log,ftpFileMover($ftpConnection,$ftpUpdateDirectory,$ftpDirectory));
															}
															// Notice that files were updated
															$log[]='INSTALLATION COMPLETE';
															
															// If uploader also uploaded an updater script then this is executed and then removed
															if(file_exists('../www-updater.php')){
																// Log message for updater script
																$log[]='EXECUTING UPDATER SCRIPT';
																// Building software version string
																$softwareVersionString=array();
																foreach($softwareVersions as $software=>$version){
																	$softwareVersionString[]=$software.'-version='.$version;
																}
																// This is the URL that needs to be executed for update to complete
																$updateScriptAddress=((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']==1 || $_SERVER['HTTPS']=='on'))?'https':'http').'://'.$_SERVER['SERVER_NAME'].'/www-updater.php?'.implode('&',$softwareVersionString);
																// Request is made with file get contents, so allow_url_fopen must be enabled
																if(function_exists('ini_get') && ini_get('allow_url_fopen')==1){
																	// Script is executed over HTTP
																	$updaterScript=file_get_contents($updateScriptAddress);
																	// If updater script was a success
																	if($updaterScript){
																		// Adding log messages from updater script
																		$log=array_merge($log,explode("\n",$updaterScript));
																		// Successful log message for updater script
																		$log[]='UPDATER SCRIPT COMPLETE';
																		// Removing updater script
																		ftp_delete($ftpConnection,$ftpDirectory.'www-updater.php');
																	} else {
																		// Failed log message for updater script
																		$log[]='UPDATER SCRIPT FAILED, PLEASE RUN '.$updateScriptAddress.' MANUALLY AND THEN DELETE THE FILE';
																	}
																} else {
																	// Failed log message for updater script
																	$log[]='CANNOT MAKE URL REQUESTS, PLEASE RUN '.$updateScriptAddress.' MANUALLY AND THEN DELETE THE FILE';
																}
															}
															
															// Printing out plain-text log
															echo '<p>';
															echo implode('</p><p>',$log);
															echo '</p>';
															
															// Notice that files were updated
															echo '<p class="bold">UPDATE COMPLETE</p>';
														
														} else {
															// Backup creation failed
															echo '<p class="bold red">Cannot create backup, update halted</p>';
														}
													
													} else {
														// This is shown when the installation directory given is different based on .version file information
														echo '<p class="bold red">Incorrect installation directory</p>';
													}
													
												} else {
													// This is thrown when FTP cannot move its directory
													echo '<p class="bold red">Cannot move to installation directory</p>';
												}
												
											} else {
												// This is thrown when FTP authentication fails
												echo '<p class="bold red">Cannot log-in to FTP</p>';
											}
											
											// Closing FTP connection
											ftp_close($ftpConnection);
											
										} else {
											// This is thrown when localhost FTP connection does not work
											echo '<p class="bold red">Cannot connect to localhost with FTP</p>';
										}
									} else {
										// Error message
										echo '<p class="bold red">Update archive version numbers are too old for current installation</p>';
									}
								} else {
									// Error message
									echo '<p class="bold red">Update archive version number information is missing</p>';
								}
								
								// Cleaning the update directory and removing the directory
								dirCleaner($updateArchiveDirectory,time());
								rmdir($updateArchiveDirectory);
								
							} else {
							
								// This is thrown when it was not possible to unpack the archive
								echo '<p class="bold red">Cannot unpack archive</p>';
								
							}
							
							// Zip class is closed as the file is not used anymore
							$zip->close();
							// Archive file is removed
							unlink('..'.DIRECTORY_SEPARATOR.'filesystem'.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'update.zip');
							
						} else {
							echo '<p class="bold red">'.$error.'</p>';
						}
						
					} else {
						// Since opening archive fails, the file is removed and error is thrown
						unlink('..'.DIRECTORY_SEPARATOR.'filesystem'.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'update.zip');
						echo '<p class="bold red">Cannot open archive</p>';
					}
					
				} else {
					echo '<p class="bold red">'.$error.'</p>';
				}
			
			} else {
				// required extensions don't seem to be used
				echo '<p class="bold red">Updater requires Zip and FTP PHP extensions</p>';
			}

		} else {
			// Error is thrown if downloading failed
			echo '<p class="bold red">FTP authentication is required</p>';
		}
		
		// Footer
		echo '<p class="footer small bold">Generated at '.date('d.m.Y h:i').' GMT '.date('P').' for '.$_SERVER['HTTP_HOST'].'</p>';
	
		?>
	</body>
</html>