Break tmpdir handling out into its own class
Break tmpdir handling out into its own class

--- a/include/git/Blob.class.php
+++ b/include/git/Blob.class.php
@@ -119,25 +119,6 @@
 			return explode("\n", $this->data);
 		else
 			return $this->data;
-	}
-
-	/**
-	 * PipeData
-	 *
-	 * Pipes the blob data to a file
-	 *
-	 * @access public
-	 * @param string $file file to pipe to
-	 */
-	public function PipeData($file)
-	{
-		if (empty($file))
-			return;
-
-		if (!$this->dataRead)
-			$this->ReadData();
-
-		file_put_contents($file, $this->data);
 	}
 
 	/**

--- a/include/git/FileDiff.class.php
+++ b/include/git/FileDiff.class.php
@@ -11,6 +11,7 @@
  */
 
 require_once(GITPHP_GITOBJECTDIR . 'Blob.class.php');
+require_once(GITPHP_GITOBJECTDIR . 'TmpDir.class.php');
 
 /**
  * Commit class
@@ -521,10 +522,7 @@
 			return;
 		}
 
-		if (!GitPHP_Config::GetInstance()->GetValue('tmpdirprepared'))
-			GitPHP_FileDiff::PrepareTempDir();
-
-		$tmpdir = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('gittmp', '/tmp/gitphp/'));
+		$tmpdir = GitPHP_TmpDir::GetInstance();
 
 		$pid = 0;
 		if (function_exists('posix_getpid'))
@@ -532,19 +530,16 @@
 		else
 			$pid = rand();
 
-		$fromFile = '/dev/null';
-		$hasFrom = false;
-		$toFile = '/dev/null';
-		$hasTo = false;
+		$fromTmpFile = '';
+		$toTmpFile = '';
 
 		$fromName = '/dev/null';
 		$toName = '/dev/null';
 
 		if ((empty($this->status)) || ($this->status == 'D') || ($this->status == 'M')) {
 			$fromBlob = $this->project->GetBlob($this->fromHash);
-			$fromFile = $tmpdir . 'gitphp_' . $pid . '_from';
-			$fromBlob->PipeData($fromFile);
-			$hasFrom = true;
+			$fromTmpFile = 'gitphp_' . $pid . '_from';
+			$tmpdir->AddFile($fromTmpFile, $fromBlob->GetData());
 
 			$fromName = 'a/';
 			if (!empty($file)) {
@@ -558,9 +553,8 @@
 
 		if ((empty($this->status)) || ($this->status == 'A') || ($this->status == 'M')) {
 			$toBlob = $this->project->GetBlob($this->toHash);
-			$toFile = $tmpdir . 'gitphp_' . $pid . '_to';
-			$toBlob->PipeData($toFile);
-			$hasTo = true;
+			$toTmpFile = 'gitphp_' . $pid . '_to';
+			$tmpdir->AddFile($toTmpFile, $toBlob->GetData());
 
 			$toName = 'b/';
 			if (!empty($file)) {
@@ -581,14 +575,14 @@
 			}
 		}
 
-		$this->diffData = shell_exec($diffExe . ' -u -p -L "' . $fromName . '" -L "' . $toName . '" ' . $fromFile . ' ' . $toFile);
-
-		if ($hasFrom) {
-			unlink($fromFile);
-		}
-
-		if ($hasTo) {
-			unlink($toFile);
+		$this->diffData = shell_exec($diffExe . ' -u -p -L "' . $fromName . '" -L "' . $toName . '" ' . (empty($fromTmpFile) ? '/dev/null' : ($tmpdir->GetDir() . $fromTmpFile)) . ' ' . (empty($toTmpFile) ? '/dev/null' : ($tmpdir->GetDir() . $toTmpFile)));
+
+		if (!empty($fromTmpFile)) {
+			$tmpdir->RemoveFile($fromTmpFile);
+		}
+
+		if (!empty($toTmpFile)) {
+			$tmpdir->RemoveFile($toTmpFile);
 		}
 
 		if ($explode)
@@ -598,38 +592,6 @@
 	}
 
 	/**
-	 * PrepareTempDir
-	 *
-	 * Prepares the temporary directory
-	 *
-	 * @access private
-	 * @static
-	 * @throws Exception exception on error
-	 */
-	private static function PrepareTempDir()
-	{
-		GitPHP_Config::GetInstance()->SetValue('tmpdirprepared', true);
-
-		$tmpdir = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('gittmp', '/tmp/gitphp/'));
-
-		if (empty($tmpdir)) {
-			throw new Exception(__('No tmpdir defined'));
-		}
-
-		if (file_exists($tmpdir)) {
-			if (is_dir($tmpdir)) {
-				if (!is_writeable($tmpdir)) {
-					throw new Exception(sprintf(__('Specified tmpdir %1$s is not writable'), $tmpdir));
-				}
-			} else {
-				throw new Exception(sprintf(__('Specified tmpdir %1$s is not a directory'), $tmpdir));
-			}
-		} else if (!mkdir($tmpdir, 0700)) {
-			throw new Exception(sprintf(__('Could not create tmpdir %1$s'), $tmpdir));
-		}
-	}
-
-	/**
 	 * GetCommit
 	 *
 	 * Gets the commit for this filediff

--- /dev/null
+++ b/include/git/TmpDir.class.php
@@ -1,1 +1,192 @@
+<?php
+/**
+ * GitPHP Tmp Dir
+ *
+ * Temporary directory class
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
 
+/**
+ * TmpDir class
+ *
+ * Class to handle managing files in a temporary directory
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_TmpDir
+{
+	
+	/**
+	 * instance
+	 *
+	 * Stores the singleton instance
+	 *
+	 * @access protected
+	 * @static
+	 */
+	protected static $instance;
+
+	/**
+	 * dir
+	 *
+	 * Stores the directory
+	 *
+	 * @access protected
+	 */
+	protected $dir = null;
+
+	/**
+	 * files
+	 *
+	 * Stores a list of files in this tmpdir
+	 *
+	 * @access protected
+	 */
+	protected $files = array();
+
+	/**
+	 * GetInstance
+	 *
+	 * Returns the singleton instance
+	 *
+	 * @access public
+	 * @static
+	 * @return mixed instance of tmpdir class
+	 */
+	public static function GetInstance()
+	{
+		if (!self::$instance) {
+			self::$instance = new GitPHP_TmpDir();
+		}
+		return self::$instance;
+	}
+
+	/**
+	 * __construct
+	 *
+	 * Constructor
+	 *
+	 * @access public
+	 */
+	public function __construct()
+	{
+		$this->dir = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('gittmp', '/tmp/gitphp/'));
+
+		if (empty($this->dir)) {
+			throw new Exception(__('No tmpdir defined'));
+		}
+
+		if (file_exists($this->dir)) {
+			if (is_dir($this->dir)) {
+				if (!is_writeable($this->dir)) {
+					throw new Exception(sprintf(__('Specified tmpdir %1$s is not writable'), $this->dir));
+				}
+			} else {
+				throw new Exception(sprintf(__('Specified tmpdir %1$s is not a directory'), $this->dir));
+			}
+		} else if (!mkdir($this->dir, 0700)) {
+			throw new Exception(sprintf(__('Could not create tmpdir %1$s'), $this->dir));
+		}
+	}
+
+	/**
+	 * __destruct
+	 *
+	 * Destructor
+	 *
+	 * @access public
+	 */
+	public function __destruct()
+	{
+		$this->Cleanup();
+	}
+
+	/**
+	 * GetDir
+	 *
+	 * Gets the temp dir
+	 *
+	 * @return string temp dir
+	 */
+	public function GetDir()
+	{
+		return $this->dir;
+	}
+
+	/**
+	 * SetDir
+	 *
+	 * Sets the temp dir
+	 *
+	 * @param string $dir new temp dir
+	 */
+	public function SetDir($dir)
+	{
+		$this->Cleanup();
+		$this->dir = $dir;
+	}
+
+	/**
+	 * AddFile
+	 *
+	 * Adds a file to the temp dir
+	 *
+	 * @param string $filename file name
+	 * @param string $content file content
+	 */
+	public function AddFile($filename, $content)
+	{
+		if (empty($filename)) {
+			return;
+		}
+
+		file_put_contents($this->dir . $filename, $content);
+
+		if (!in_array($filename, $this->files)) {
+			$this->files[] = $filename;
+		}
+	}
+
+	/**
+	 * RemoveFile
+	 *
+	 * Removes a file from the temp dir
+	 *
+	 * @param string $filename file name
+	 */
+	public function RemoveFile($filename)
+	{
+		if (empty($filename)) {
+			return;
+		}
+
+		unlink($this->dir . $filename);
+
+		$idx = array_search($filename, $this->files);
+		if ($idx !== false) {
+			unset($this->files[$idx]);
+		}
+	}
+
+	/**
+	 * Cleanup
+	 *
+	 * Cleans up any temporary files
+	 */
+	public function Cleanup()
+	{
+		if (!empty($this->dir) && (count($this->files) > 0)) {
+			foreach ($this->files as $file) {
+				$this->RemoveFile($file);
+			}
+		}
+	}
+}
+

comments