Files
rspade_system/app/Models/File_Hash.php
root f6fac6c4bc Fix bin/publish: copy docs.dist from project root
Fix bin/publish: use correct .env path for rspade_system
Fix bin/publish script: prevent grep exit code 1 from terminating script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 02:08:33 +00:00

174 lines
3.9 KiB
PHP
Executable File

<?php
namespace App\Models;
/**
* File_Hash model representing unique physical files
*
* This model enables deduplication of file storage - multiple logical files
* can reference the same physical file if they have the same content hash.
*/
use App\RSpade\Core\Database\Models\Rsx_Model_Abstract;
use Rsx\Models\File_Model;
/**
* _AUTO_GENERATED_ Database type hints - do not edit manually
* Generated on: 2025-09-28 10:36:08
* Table: file_hashes
*
* @property int $id
* @property mixed $hash
* @property mixed $mime_type
* @property int $size
* @property string $created_at
* @property string $updated_at
* @property int $created_by
* @property int $updated_by
*
* @mixin \Eloquent
*/
class File_Hash extends Rsx_Model_Abstract
{
// Required static properties from parent abstract class
public static $enums = [];
public static $rel = [];
/**
* _AUTO_GENERATED_ Date columns for Carbon casting
*/
protected $dates = [
'created_at',
'updated_at',
];
/**
* The table associated with the model
*
* @var string
*/
protected $table = 'file_hashes';
/**
* Column metadata for special handling
*
* @var array
*/
protected $columnMeta = [
// No special metadata needed for file_hashes table columns yet
];
/**
* Get all logical files that reference this physical file
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function files()
{
return $this->hasMany(File_Model::class, 'file_hash_id');
}
/**
* Get the storage path for this file
* Based on the hash for efficient file system distribution
*
* @return string
*/
public function get_storage_path()
{
// Split hash into subdirectories for better file system performance
// e.g., hash "abc123..." becomes "storage/files/ab/c1/abc123..."
$hash = $this->hash;
$dir1 = substr($hash, 0, 2);
$dir2 = substr($hash, 2, 2);
return "storage/files/{$dir1}/{$dir2}/{$hash}";
}
/**
* Get the full file system path
*
* @return string
*/
public function get_full_path()
{
return storage_path($this->get_storage_path());
}
/**
* Check if the physical file exists on disk
*
* @return bool
*/
public function file_exists()
{
return file_exists($this->get_full_path());
}
/**
* Get human-readable file size
*
* @return string
*/
public function get_human_size()
{
$bytes = $this->size;
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, 2) . ' ' . $units[$i];
}
/**
* Find or create a file hash record
*
* @param string $hash
* @param string $mime_type
* @param int $size
* @return static
*/
public static function find_or_create($hash, $mime_type, $size)
{
$file_hash = static::where('hash', $hash)->first();
if (!$file_hash) {
$file_hash = new static();
$file_hash->hash = $hash;
$file_hash->mime_type = $mime_type;
$file_hash->size = $size;
$file_hash->save();
}
return $file_hash;
}
/**
* Calculate hash for file content
*
* @param string $content
* @return string
*/
public static function calculate_hash($content)
{
return hash('sha256', $content);
}
/**
* Calculate hash for a file path
*
* @param string $file_path
* @return string|false
*/
public static function calculate_file_hash($file_path)
{
if (!file_exists($file_path)) {
return false;
}
return hash_file('sha256', $file_path);
}
}