<?php
/**
* @version $Id: admin.installer.php 4621 2006-08-21 16:40:39Z stingrey $
* @package Joomla
* @subpackage Installer
* @copyright Copyright (C) 2005 Open Source Matters. All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/

// no direct access
defined('_VALID_MOS') or die('Restricted access');

if (!function_exists("deldir")) {
    function deldir( $dir ) {
    	$current_dir = opendir( $dir );
    	$old_umask = umask(0);
    	while ($entryname = readdir( $current_dir )) {
    		if ($entryname != '.' and $entryname != '..') {
    			if (is_dir( $dir . $entryname )) {
    				deldir( mosPathName( $dir . $entryname ) );
    			} else {
                    @chmod($dir . $entryname, 0777);
    				unlink( $dir . $entryname );
    			}
    		}
    	}
    	umask($old_umask);
    	closedir( $current_dir );
    	return rmdir( $dir );
    }
}

upgrade();

function upgrade()
{
    global $sefConfig, $database;

    $fromServer = mosGetParam($_REQUEST, 'fromServer', null);

    $uploaddir = $GLOBALS['mosConfig_absolute_path'].'/media/';
    $uploadfile = $uploaddir.'upgradePack.zip';

    if (is_null($fromServer)) {
        echo "<p class='error'>"._COM_SEF_UPGRADE_BADSOURCE."</p>";
        return;
    }

    if ($fromServer == 1) {
        // Download ZIP from server
        $upgradeFile = @file_get_contents($sefConfig->serverUpgradeURL);
        if ($upgradeFile == false) {
            echo "<p class='error'>"._COM_SEF_UPGRADE_CONNECTIONFAILED."</p>";
            return;
        }
        if (@!file_put_contents($uploadfile, $upgradeFile)) {
            echo "<p class='error'>"._COM_SEF_WRITE_FAILED."</p>";
            return;
        }
    }
    else {
        // Use the uploaded ZIP
        $userfile = mosGetParam($_FILES, 'userfile', null);
        if (!$userfile) {
            echo "<p class='error'>ERROR UPLOADING FILE</p>";
            return;
        }

        if (!@move_uploaded_file($userfile['tmp_name'], $uploadfile)) {
            echo "<p class='error'>"._COM_SEF_WRITE_FAILED."</p>";
            return;
        }
    }

    // Extract ZIP to temp folder
    global $extractdir;   // global so we can use it in AddFileOp to ensure that file exists
    $extractdir = mosPathName( $uploaddir.uniqid('upgrade_') );

    if (!extractZIP($uploadfile, $extractdir))
    return;

    // Create an array of upgrade files
    $curVersion = SEFTools::getSEFVersion();
    $upgradeDir = mosPathName( $extractdir.'upgrade' );
    $upgradeFiles = @scandir($upgradeDir);

    if ($upgradeFiles == FALSE) {
        echo "<p class='error'>"._COM_SEF_UPGRADE_BADPACKAGE."</p>";
        unlink($uploadfile);
        deldir($extractdir);
        return;
    }

    // Check if current version is upgradeable with downloaded package
    if (!in_array($curVersion.".php", $upgradeFiles)) {
        echo "<p class='message'>"._COM_SEF_CANT_UPGRADE."</p>";
        unlink($uploadfile);
        deldir($extractdir);
        return;
    }

    natcasesort($upgradeFiles);

    // Prepare arrays of upgrade operations and functions to manipulate them
    global $fileList, $sqlList, $fileError;
    $fileError = false;
    $fileList = array();
    $sqlList = array();

    if (!function_exists("AddFileOp")) {
        // Adds a file operation to $fileList
        // $joomlaPath - destination file path (e.g. '/administrator/components/com_sef/admin.sef.php')
        // $operation - can be 'delete' or 'upgrade'
        // $packagePath - source file path in upgrade package if $operation is 'upgrade' (e.g. '/admin.sef.php')
        function AddFileOp($joomlaPath, $operation, $packagePath = '')
        {
            global $fileList, $fileError, $extractdir;
            if ($operation != 'upgrade' && $operation != 'delete') {
                $fileError = true;
                echo "<p class='error'>"._COM_SEF_UPGRADE_INVALIDOPERATION.$operation."</p>";
                return;
            }
            if ($operation == 'upgrade' && ($packagePath == '' || !file_exists(mosPathName($extractdir.$packagePath, false)))) {
                $fileError = true;
                echo "<p class='error'>"._COM_SEF_UPGRADE_INVALIDFILE.mosPathName($extractdir.$packagePath, false)."</p>";
                return;
            }

            $fileList[$joomlaPath] = new SEFUpgradeFile($operation, $packagePath);
        }
    }

    if (!function_exists("AddSQL")) {
        // Adds an SQL query to $sqlList
        function AddSQL($sql) {
            global $sqlList;
            $sqlList[] = $sql;
        }
    }

    // Load each upgrade file starting with current version in ascending order
    foreach($upgradeFiles as $uFile) {
        if (!eregi("^[0-9]+\.[0-9]+\.[0-9]+\.php$", $uFile))
        continue;
        if (strnatcasecmp($uFile, $curVersion.".php") >= 0)
        require_once ($upgradeDir.$uFile);
    }

    if ($fileError == false) {
        // Execute SQL queries
        foreach($sqlList as $sql) {
            $database->setQuery($sql);
            if (!$database->query())
            echo "<p class='error'>"._COM_SEF_UPGRADE_SQLERROR."$sql</p>";
        }

        // Perform file operations
        foreach($fileList as $dest => $op) {
            if ($op->operation == 'delete') {
                @unlink( mosPathName($GLOBALS['mosConfig_absolute_path'].$dest, false) );
            }
            elseif ($op->operation == 'upgrade') {
                $from = mosPathName($extractdir.$op->packagePath, false);
                $to = mosPathName($GLOBALS['mosConfig_absolute_path'].$dest, false);
                @copy ($from, $to);
            }
        }

        echo "<p class='message'>JoomSEF successfuly upgraded.</p>";
        echo "<font class=\"small\" align=\"left\"><a href=\"index2.php?option=com_sef\">"._COM_SEF_BACK."</a></font>";
    }

    // Cleanup
    unlink($uploadfile);
    deldir($extractdir);
}

function extractZIP($archive, $extractTo)
{
    global $mosConfig_absolute_path;

    if (!extension_loaded('zlib')) {
        echo "<p class='error'>Upgrade cannot continue before zlib is installed.</p>";
        return false;
    }

    $isWin = (substr(PHP_OS, 0, 3) == 'WIN');

    // Extract functions
    require_once($mosConfig_absolute_path.'/administrator/includes/pcl/pclzip.lib.php');
    require_once($mosConfig_absolute_path.'/administrator/includes/pcl/pclerror.lib.php');

    $zipfile = new PclZip($archive);

    if ($isWin) define('OS_WINDOWS', 1);
    else define('OS_WINDOWS', 0);

    $ret = $zipfile->extract(PCLZIP_OPT_PATH, $extractTo);
    if ($ret == 0) {
        echo "<p class='error'>Unrecoverable error ".$zipfile->errorName(true).".</p>";
        return false;
    }

    return true;
}
?>
