--- a/include/git/GitExe.class.php +++ b/include/git/GitExe.class.php @@ -54,11 +54,6 @@ * git for-each-ref constant */ define('GIT_FOR_EACH_REF','for-each-ref'); - -/** - * git config constant - */ -define('GIT_CONFIG','config'); /** * Class to wrap git executable @@ -68,15 +63,8 @@ * @package GitPHP * @subpackage Git */ -class GitPHP_GitExe +class GitPHP_GitExe implements GitPHP_Observable_Interface { - - /** - * The singleton instance - * - * @var GitPHP_GitExe - */ - protected static $instance; /** * The binary path @@ -100,32 +88,39 @@ protected $versionRead = false; /** - * Returns the singleton instance - * - * @return GitPHP_GitExe instance of git exe classe - */ - public static function GetInstance() - { - if (!self::$instance) { - self::$instance = new GitPHP_GitExe(GitPHP_Config::GetInstance()->GetValue('gitbin')); - } - return self::$instance; - } - - /** - * Releases the singleton instance - */ - public static function DestroyInstance() - { - self::$instance = null; - } + * Observers + * + * @var GitPHP_Observer_Interface[] + */ + protected $observers = array(); + + /** + * Whether the exec function is allowed by the install + * + * @var null|boolean + */ + protected $execAllowed = null; + + /** + * Whether the shell_exec function is allowed by the install + * + * @var null|boolean + */ + protected $shellExecAllowed = null; + + /** + * Whether the popen function is allowed by the install + * + * @var null|boolean + */ + protected $popenAllowed = null; /** * Constructor * * @param string $binary path to git binary */ - protected function __construct($binary) + public function __construct($binary = '') { if (empty($binary)) { $binary = GitPHP_GitExe::DefaultBinary(); @@ -143,13 +138,20 @@ */ public function Execute($projectPath, $command, $args) { + if ($this->shellExecAllowed === null) { + $this->shellExecAllowed = GitPHP_Util::FunctionAllowed('shell_exec'); + if (!$this->shellExecAllowed) { + throw new GitPHP_DisabledFunctionException('shell_exec'); + } + } + $fullCommand = $this->CreateCommand($projectPath, $command, $args); - GitPHP_DebugLog::GetInstance()->Log('Begin executing "' . $fullCommand . '"'); + $this->Log('Begin executing "' . $fullCommand . '"'); $ret = shell_exec($fullCommand); - GitPHP_DebugLog::GetInstance()->Log('Finish executing "' . $fullCommand . '"' . + $this->Log('Finish executing "' . $fullCommand . '"' . "\nwith result: " . $ret); return $ret; @@ -166,6 +168,13 @@ */ public function Open($projectPath, $command, $args, $mode = 'r') { + if ($this->popenAllowed === null) { + $this->popenAllowed = GitPHP_Util::FunctionAllowed('popen'); + if (!$this->popenAllowed) { + throw new GitPHP_DisabledFunctionException('popen'); + } + } + $fullCommand = $this->CreateCommand($projectPath, $command, $args); return popen($fullCommand, $mode); @@ -183,7 +192,7 @@ { $gitDir = ''; if (!empty($projectPath)) { - $gitDir = '--git-dir=' . $projectPath; + $gitDir = '--git-dir=' . escapeshellarg($projectPath); } return $this->binary . ' ' . $gitDir . ' ' . $command . ' ' . implode(' ', $args); @@ -217,6 +226,13 @@ */ protected function ReadVersion() { + if ($this->shellExecAllowed === null) { + $this->shellExecAllowed = GitPHP_Util::FunctionAllowed('shell_exec'); + if (!$this->shellExecAllowed) { + throw new GitPHP_DisabledFunctionException('shell_exec'); + } + } + $this->versionRead = true; $this->version = ''; @@ -301,6 +317,13 @@ */ public function Valid() { + if ($this->execAllowed === null) { + $this->execAllowed = GitPHP_Util::FunctionAllowed('exec'); + if (!$this->execAllowed) { + throw new GitPHP_DisabledFunctionException('exec'); + } + } + if (empty($this->binary)) return false; @@ -308,6 +331,55 @@ $out = exec($this->binary . ' --version', $tmp, $code); return $code == 0; + } + + /** + * Add a new observer + * + * @param GitPHP_Observer_Interface $observer observer + */ + public function AddObserver($observer) + { + if (!$observer) + return; + + if (array_search($observer, $this->observers) !== false) + return; + + $this->observers[] = $observer; + } + + /** + * Remove an observer + * + * @param GitPHP_Observer_Interface $observer observer + */ + public function RemoveObserver($observer) + { + if (!$observer) + return; + + $key = array_search($observer, $this->observers); + + if ($key === false) + return; + + unset($this->observers[$key]); + } + + /** + * Log an execution + * + * @param string $message message + */ + private function Log($message) + { + if (empty($message)) + return; + + foreach ($this->observers as $observer) { + $observer->ObjectChanged($this, GitPHP_Observer_Interface::LoggableChange, array($message)); + } } /**