163 lines
4.5 KiB
PHP
163 lines
4.5 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Blob - provides a Git blob object
|
||
|
*
|
||
|
* PHP version 5.3
|
||
|
*
|
||
|
* @category Git
|
||
|
* @package Granite
|
||
|
* @author Craig Roberts <craig0990@googlemail.com>
|
||
|
* @license http://www.opensource.org/licenses/mit-license.php MIT Expat License
|
||
|
* @link http://craig0990.github.com/Granite/
|
||
|
*/
|
||
|
|
||
|
namespace Granite\Git;
|
||
|
use \Granite\Git\Object\Raw as Raw;
|
||
|
use \InvalidArgumentException as InvalidArgumentException;
|
||
|
use \finfo as finfo;
|
||
|
/**
|
||
|
* **Granite\Git\Blob** represents the raw content of an object in a Git repository,
|
||
|
* typically a **file**. This class provides methods related to the handling of
|
||
|
* blob content, mimetypes, sizes and write support.
|
||
|
*
|
||
|
* @category Git
|
||
|
* @package Granite
|
||
|
* @author Craig Roberts <craig0990@googlemail.com>
|
||
|
* @license http://www.opensource.org/licenses/mit-license.php MIT Expat License
|
||
|
* @link http://craig0990.github.com/Granite/
|
||
|
*/
|
||
|
class Blob
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* Stores the SHA-1 id of the object requested; accessed through the `sha()`
|
||
|
* method where it is recalculated based on the blob content.
|
||
|
*/
|
||
|
private $sha = null;
|
||
|
/**
|
||
|
* The raw binary string of the file contents.
|
||
|
*/
|
||
|
private $content = "";
|
||
|
/**
|
||
|
* The path to the repository location.
|
||
|
*/
|
||
|
private $path;
|
||
|
|
||
|
/**
|
||
|
* Fetches a raw Git object and parses the result. Throws an
|
||
|
* InvalidArgumentException if the object is not of the correct type,
|
||
|
* or cannot be found.
|
||
|
*
|
||
|
* @param string $path The path to the repository root.
|
||
|
* @param string $sha The SHA-1 id of the requested object, or `null` if
|
||
|
* creating a new blob object.
|
||
|
*
|
||
|
* @throws InvalidArgumentException If the SHA-1 id provided is not a blob.
|
||
|
*/
|
||
|
public function __construct($path, $sha = NULL)
|
||
|
{
|
||
|
$this->path = $path;
|
||
|
if ($sha !== NULL) {
|
||
|
$this->sha = $sha;
|
||
|
$object = Raw::factory($path, $sha);
|
||
|
|
||
|
if ($object->type() !== Raw::OBJ_BLOB) {
|
||
|
throw new InvalidArgumentException(
|
||
|
"The object $sha is not a blob, type is {$object->type()}"
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$this->content = $object->content();
|
||
|
unset($object);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets or returns the raw file content, depending whether the parameter is
|
||
|
* provided.
|
||
|
*
|
||
|
* @param string $content The object content to set, or `null` if requesting the
|
||
|
* current content.
|
||
|
*
|
||
|
* @return string The raw binary string of the file contents.
|
||
|
*/
|
||
|
public function content($content = NULL)
|
||
|
{
|
||
|
if ($content == NULL) {
|
||
|
return $this->content;
|
||
|
}
|
||
|
$this->content = $content;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the size of the file content in bytes, equivalent to
|
||
|
* `strlen($blob->content())`.
|
||
|
*
|
||
|
* @return int The size of the object in bytes.
|
||
|
*/
|
||
|
public function size()
|
||
|
{
|
||
|
return strlen($this->content);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Updates and returns the SHA-1 id of the object, based on it's contents.
|
||
|
*
|
||
|
* @return int The SHA-1 id of the object.
|
||
|
*/
|
||
|
public function sha()
|
||
|
{
|
||
|
$sha = hash_init('sha1');
|
||
|
$header = 'blob ' . strlen($this->content) . "\0";
|
||
|
hash_update($sha, $header);
|
||
|
hash_update($sha, $this->content);
|
||
|
$this->sha = hash_final($sha);
|
||
|
return $this->sha;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the mimetype of the object, using `finfo()` to determine the mimetype
|
||
|
* of the string.
|
||
|
*
|
||
|
* @return string The object mimetype.
|
||
|
* @see http://php.net/manual/en/function.finfo-open.php
|
||
|
*/
|
||
|
public function mimetype()
|
||
|
{
|
||
|
$finfo = new finfo(FILEINFO_MIME);
|
||
|
return $finfo->buffer($this->content);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Encode and compress the object content, saving it to a 'loose' file.
|
||
|
*
|
||
|
* @return boolean True on success, false on failure.
|
||
|
*/
|
||
|
public function write()
|
||
|
{
|
||
|
$sha = $this->sha(TRUE);
|
||
|
$path = $this->path
|
||
|
. 'objects'
|
||
|
. DIRECTORY_SEPARATOR
|
||
|
. substr($sha, 0, 2)
|
||
|
. DIRECTORY_SEPARATOR
|
||
|
. substr($sha, 2);
|
||
|
// FIXME: currently writes loose objects only
|
||
|
if (file_exists($path)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (!is_dir(dirname($path))) {
|
||
|
mkdir(dirname($path), 0777, TRUE);
|
||
|
}
|
||
|
|
||
|
$loose = fopen($path, 'wb');
|
||
|
$data = 'blob ' . strlen($this->content) . "\0" . $this->content;
|
||
|
$write = fwrite($loose, gzcompress($data));
|
||
|
fclose($loose);
|
||
|
|
||
|
return ($write !== FALSE);
|
||
|
}
|
||
|
|
||
|
}
|