Location: PHPKode > projects > phpMakeUpdate > phpMakeUpdate/includes/makeupdate.class.php
<?php
/**
 * phpMakeUpdate - web tool for make the updates from Subversion repository
 * Copyright (C) 2006  Arthur Harder
 *
 * web: http://www.easyWebSolutions.biz or http://www.easyWebSolutions.de
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

class makeupdate
{
    var $errors = array();

    function __construct()
    {
        //
    }

    function makeupdate()
    {
        $this->__construct();
    }

    /**
     * Execute the 'svnlook history' command
     *
     * @param string $path Path in repository (/trunk, /branches/myproject etc)
     * @return boolean
     */
    function get_history($path)
    {
        if ( substr($path,0,1) != '/' )
        {
            $path = '/'.$path;
        }

        $command = SVNLOOK.' history '.$_SESSION['repository'].' '.$path;

        $result = $this->Execute($command);

        if ( !empty($result[ID_ERROUT]) )
        {
            $this->command = $command;
            $this->errors = $result[ID_ERROUT];
            return false;
        }

        $erg = array();
        foreach ($result[ID_STDOUT] as $line)
        {
            $line = trim($line);
            $_arr = preg_split('/[\s]+/',$line);
            if ((int) $_arr[0] > 0)
            {
                $foo = new foo;
                $foo->revision  = $_arr[0];
                $foo->path      = $_arr[1];
                $erg[] = $foo;
            }
        }

        $this->result = $erg;
        return true;
    }

    /**
     * Execute the 'svnlook info' command
     *
     * @param integer $revision Revision number in the repository
     * @return boolean
     */
    function get_info($revision)
    {
        if ( (int) $revision < 1 )
        {
            $revision = 1;
        }
        $command = SVNLOOK.sprintf(" info -r %d ".$_SESSION['repository'],$revision);

        $result = $this->Execute($command);

        if ( !empty($result[ID_ERROUT]) )
        {
            $this->errors = $result[ID_ERROUT];
            return false;
        }

        $erg = array();
        $erg[ID_AUTHOR] = $result[ID_STDOUT][0];
        $erg[ID_DATE]   = $result[ID_STDOUT][1];
        $erg[ID_MESSAGE_SIZE] = $result[ID_STDOUT][2];
        $erg[ID_MESSAGE]   = $result[ID_STDOUT][3];

        $this->result = $erg;
        return true;
    }

    /**
     * Get list with all changed files with svnlook changed -r
     *
     * All revision numbers are reading from $_SESSION['checkbox']
     *
     * @param string $path Path in repository (/trunk, /branches/myproject etc)
     * @return boolean
     */
    function get_changes($path)
    {
        $this->result = array();
        $this->deleted_files = array();

        $path = trim($path);

        if (strlen($path) < 4 )
        {
            return false;
        }

        if ( substr($path,0,1) == '/' )
        {
            $path = substr($path,1);
        }

        if ( substr($path,-1,1) == '/' )
        {
            $path = substr($path,0,strlen($path)-1);
        }

        if ( !empty($_SESSION['checkbox']) && count($_SESSION['checkbox']) > 0 )
        {
            $arg = '';
            ksort($_SESSION['checkbox']);
            reset($_SESSION['checkbox']);
            while ( $key = key($_SESSION['checkbox']) )
            {
                $arg .= ' ' . $key;
                next($_SESSION['checkbox']);
            }
            $command = 'for i in'.$arg.'; do '.SVNLOOK.' changed -r $i '.$_SESSION['repository'].'; done';
            $result = $this->Execute($command);

            if ( !empty($result[ID_ERROUT]) )
            {
                $this->errors = $result[ID_ERROUT];
                return false;
            }

            foreach ($result[ID_STDOUT] as $line)
            {
                $line = trim($line);
                $_arr = preg_split('/[\s]+/',$line);
                if ( count($_arr) > 1)
                {
                    $pos = strpos($line,$path);
                    if ($pos === false || substr($_arr[1],strlen($path)+1) == '')
                    {
                        continue;
                    }
                    $foo = new foo;
                    $foo->filename = substr($_arr[1],strlen($path)+1);
                    $foo->status   = $_arr[0];
                    if (strstr('D',$_arr[0]))
                    {
                        $this->deleted_files[$foo->filename] = $foo;
                    }
                    else
                    {
                        $this->result[$foo->filename] = $foo;
                    }
                }
            }

            sort ($this->result);
            reset($this->result);

            sort($this->deleted_files);
            reset($this->deleted_files);
        }
        return true;
    }

    /**
     * Make the tarbal and send it into browser window
     *
     * @param string $repository Real Path to repository
     * @param string $source Path in repository (/trunk, /branches/myproject etc)
     * @param string $files_array only selected files from 'available files for update' list
     * @return boolean
     */
    function makeTar($source, $files_array)
    {
        if ( isset($_SESSION['repository']) )
        {
            $repository = $_SESSION['repository'];
        }
        else
        {
        	return false;
        }

        $file = '';
        if ( count($files_array) > 0 )
        {
            $arg = '';
            foreach ($files_array as $file)
            {
                $arg .= ' '. $file;
            }

            if (strlen($source) < 4 || strlen($repository) < 4 )
            {
                return false;
            }

            if (substr($source,0,1)  == '/')
            {
                $source = substr($source,1);
            }

            if (substr($repository,-1,1)  != '/')
            {
                $repository .= '/';
            }

            chdir('tmp');
            umask(0);

            $command = 'umask 0; '.SVN.' export file://'.
            $repository.$source.' update && chmod -R a+w update; cd update; mkdir UPDATE; chmod a+w UPDATE';

            $this->Execute($command);
            chdir('update');

            $command = 'for i in'.$arg.';do cp --parents $i UPDATE; done && ';
            $command .= TAR.' cfz ../update.tar.gz UPDATE';
            $this->Execute($command);
            chdir('../');
            $command = 'rm -rf update;';
            $this->Execute($command);

            return true;
        }
        return false;
    }

    function getRepositoryList()
    {
        global $dict;
        if ( !defined('REP_LIST') || !is_readable(REP_LIST))
        {
            $this->errors[] = $dict['ERR_CANNOT_READ_REPOSLIST'];
            return false;
        }

        $this->repos_list = file(REP_LIST);
        return true;
    }

    function getRepDirArray($repository)
    {
        $command = SVNLOOK.sprintf(" tree %s ",$repository);

        $result = $this->Execute($command);

        if ( !empty($result[ID_ERROUT]) )
        {
            $this->errors = $result[ID_ERROUT];
            return false;
        }

        $path = array();
        $dirArray = array();
        $key_old = 0;
        foreach ($result[ID_STDOUT] as $line)
        {
            // if this $line is are not a directory - next line
            if (substr(trim($line),-1,1) != '/')
            {
                continue;
            }
            else
            {
                //echo substr($line,-1,1);
            }

            $key = getIndexFromLine($line);
            if ($key > DEPT_TREE )
            {
                continue;
            }
            if ($key < $key_old)
            {
                $path_new = array();

                for ($i = 0; $i <= $key; $i++)
                {
                    $path_new[$i] = $path[$i];
                }
                $path = $path_new;
                $key_old = $key;
            }
            $path[$key] = trim($line);

            $url = '';
            foreach ($path as $dir)
            {
                $url .= $dir;
            }
            $dirArray[] = $url;
        }

        $this->result = $dirArray;

        return true;
    }

    /**
    * Executes an SVN command.
    * @param string $cmd Command to execute
    * @param string $switch Switches to be applied for the given command
    * @param string $arg Arguments of the command
    * @return array Result array containing commandline (id = ID_CMDLINE),
    * standard out array (id = ID_STDOUT), error array (id = ID_ERROUT),
    * and return code of the command (id = ID_CMD_RC).
    */

    function Execute($cmd, $arg = '', $switches = '')
    {
        $descriptorspec = array (
            0 => array("pipe", "r"), // stdin is a pipe that the child will read from
            1 => array("pipe", "w"), // stdout is a pipe that the child will write to
            2 => array("pipe", "w")  // stderr is a pipe to write to
        );

        $pipes = NULL;
        $cmdline = $cmd." ".$switches." ".$arg;
        $result = array();
        $result[ID_CMDLINE] = $cmdline;
        $result[ID_STDOUT] = array();
        $result[ID_ERROUT] = array();
        $result[ID_CMD_RC] = -1;

        $process = proc_open($cmdline, $descriptorspec, $pipes, $cmd);

        if (is_resource($process))
        {
            // $pipes now looks like this:
            // 0 => writeable handle connected to child stdin
            // 1 => readable handle connected to child stdout
            // 1 => readable handle connected to child errout

            $result = array();
            $result[ID_CMDLINE] = $cmdline;
            $result[ID_STDOUT] = $this->GetLineArray($pipes[1]);
            $result[ID_ERROUT] = $this->GetLineArray($pipes[2]);


            fclose($pipes[0]);
            fclose($pipes[1]);
            fclose($pipes[2]);

            // It is important that you close any pipes before calling
            // proc_close in order to avoid a deadlock

            $result[ID_CMD_RC] = proc_close($process);

            // echo "CMD: $cmdline<br/>";
            // PrintDebugArray($result, "Result");
            $this->log_output($result);

        }
        return $result;
    }

    /**
    * Reads data from a resource (e.g. pipe) and
    * returns an array that contains each line for a
    * separate index.
    * @param resource $handle Resource handle
    * @param int $length Maximum line length used if a line is not delimited.
    * @return array Array containing a delimited line per index.
    */
    function GetLineArray($handle, $length = 4096)
    {
        $content = array();
        $line = fgets($handle, $length);

        while ($line !== false)
        {
            $content[] = $line;
            $line = fgets($handle, $length);
        }

        return $content;
    }

    /**
     * Private function for logging into tmp/log.txt
     *
     * @param array $response
     */
    function log_output($result)
    {
        global $dict;
        $fp = fopen(current_dir().'tmp/log.txt','a');
        fputs($fp,'Zeit: '.date('Y-m-d H:i')."\n");
        fputs($fp,$dict['COMMAND'].' '.$result[ID_CMDLINE]."\n");

        foreach ($result[ID_STDOUT] as $line)
        {
            fputs($fp,$dict['STD_OUTPUT'].' '.$line);
        }

        foreach ($result[ID_ERROUT] as $line)
        {
            fputs($fp,$dict['ERR_OUTPUT'].' '.$line);
        }

        fputs($fp,"=======================================\n\n");
        fclose($fp);
    }
}

/**
 * Get count of white space from start in $lang
 *
 * @param string $line
 * @return integer $key
 */
function getIndexFromLine($line)
{
    $key = 0;
    if (preg_match('/^(\s*)/',$line,$matches))
    {
        $key = strlen($matches[1]);
    }
    return $key;
}

function current_dir()
{
    $path = $_SERVER["SCRIPT_FILENAME"];
    $position = strrpos($path,'/') + 1;
    return substr($path,0,$position);
}
/**
 * Provate foo class for intern use
 *
 */
class foo
{
    //
}

?>
Return current item: phpMakeUpdate