#!/usr/bin/php
<?php
/**
 * horde-update.php
 * Upgrades and existing horde installation by running the following steps
 * 1 - Get updated files from CVS
 * 2 - Run framework/install-packages.php
 * 3 - Regenerate any out of date config files using defaults
 */

/* Root of the horde installation to be upgraded. */
//define('HORDE_BASE', '/var/www/horde/');
define('HORDE_BASE', dirname(__FILE__) . '/..');

/* CVS Command to run */
$HORDE_CVS_COMMAND = 'cvs -q update -P';

/* Set to true to part of this update */
$DO_CVS_UPDATE = true;	// Get new versions from CVS
$DO_FRAMEWORK  = true;  // Install framework packages
$DO_CONFIG     = true;  // Regenerate out of date config files

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

// Write the content string to the file
function _writeConf($content, $file) {
    $fp = fopen($file, 'w');
    if ($fp) {
        fwrite($fp, $content);
        fclose($fp);
        return true;
    }
    return false;
}
// Parse raw config file and return array with same data
function _getConf($HordeConf) {
    $conf = array();
    @eval($HordeConf->getPHPConfig());
    if (isset($conf)) {
        return $conf;
    }
}
// Regenerate a modules configuration file
function _refreshConf($module, $appPath) {
    $ret = true;
    echo $module . ' configuration ';
    $appConf = new Horde_Config($module);
    $appCurrentConf = _getConf($appConf);
    $rawOut = $appConf->generatePHPConfig(new Variables(), $appCurrentConf);
    $confPath = $appPath . '/config/conf.php';
    if (file_exists($confPath)) {
        copy($confPath, $confPath . '.bak');
    }
    if (_writeConf($rawOut, $confPath)) {
        echo 'successfully';
    } else {
        $ret = false;
        echo 'could not be';
    }
    echo " generated.\n";
    return $ret;
}
// Returns the CVS version for a given file.
function _getVersion($file) {
     $data = @file_get_contents($file);
     if (preg_match('/\$.*?conf\.xml,v (.*?) .*\$/', $data, $match)) {
         return $match[1];
     } else {
         return false;
     }
}
// Checks if the config file is out of date
function _outOfDate($appPath) {
    $appPath = $appPath . '/config/';
    $xmlFile = $appPath . 'conf.xml';
    $phpFile = $appPath . 'conf.php';
    if (file_exists($phpFile) && is_writeable($phpFile)) {
        return _getVersion($xmlFile) != _getVersion($phpFile);
    } else return false;
}

// Make sure no one runs this from the web.
if (php_sapi_name() != 'cli') {
    exit("Must be run from the command line\n");
}
// No auth.
@define('AUTH_HANDLER', true);

include_once 'Horde.php';
include_once 'Horde/NLS.php';
include_once 'Horde/Auth.php';
include_once 'Horde/Perms.php';
include_once 'Horde/Config.php';
include_once 'Horde/Browser.php';
include_once 'Horde/Registry.php';
include_once 'Horde/Variables.php';
include_once 'Horde/Notification.php';
$registry = new Registry();
$browser = new Browser();

$_appCount = 0;
$_upgradeCount = 0;

echo 'Upgrade of Horde installation started in '.HORDE_BASE."\n\n";
if ($DO_CVS_UPDATE) {
    echo "Running CVS update. Command: $HORDE_CVS_COMMAND (This may take a while)\n";
    if (chdir(HORDE_BASE)) {
        if (passthru($HORDE_CVS_COMMAND, $res)) {
            echo "Error running CVS command. See above for details.\n";
        }
    } else {
        echo 'Unable to change to '.HORDE_BASE."\n";
        exit("Script failed.");
    }
    echo "\n";
}
if ($DO_FRAMEWORK) {
    echo 'Installing framework. (This will take a few minutes)';
    $ins = HORDE_BASE.'/framework/install-packages.php';
    if (file_exists($ins)) {
        $descriptorspec = array(
            0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "r")
        );
        $prc = proc_open($ins, $descriptorspec, $pipes);
        if (is_resource($prc)) {
            echo ".\n";
            while (!feof($pipes[1])) {
                $line = fgets($pipes[1]);
                if (strstr($line,'Installing') == $line) { echo '.';}
            }
            proc_close($prc);
            echo ' Done';
        } else {
            echo ' - unable to run install-packages.php';
        }
    } else {
        echo ' - failed (cannot find install-packages.php)';
    }
    echo "\n";
}
if ($DO_CONFIG) {
    echo "Refreshing any out of date configuration files.\n";

    foreach ($registry->listApps(array('inactive', 'hidden', 'notoolbar', 'active', 'admin')) as $a) {
        $appPath = $registry->get('fileroot', $a);
        // If there is no conf.xml there is no app so skip it
        if (!file_exists($appPath.'/config/conf.xml')) continue;
        $_appCount++;
        if (_outOfDate($appPath)) {
            if (_refreshConf($a, $appPath)) {$_upgradeCount++;}
        }
    }
    echo "Refreshed $_upgradeCount of $_appCount modules.\n";
}
echo "\nUpgrade Complete!\n";
?>
