PHP Classes

File: tools/updater.php

Recommend this page to a friend!
  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: removed references to waveframework.com
Date: 14 days ago
Size: 14,889 bytes
 

Contents

Class file image Download
<?php /** * Wave Framework <http://github.com/kristovaher/Wave-Framework> * 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.7.1 */ // 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; // Comparing Wave Framework version numbers if(!isset($updateVersions['www']) || version_compare($updateVersions['www'],$softwareVersions['www'])==-1){ $versionValid=false; } // Comparing system version numbers if(!isset($updateVersions['system']) || version_compare($updateVersions['system'],$softwareVersions['system'])==-1){ $versionValid=false; } // Note that API version numbers are never compared due to technically being API specifications // This means that system version numbers apply to API as well. // 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>