FileContent::init()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 13
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace Epesi\FileStorage\Models;
4
5
use Illuminate\Support\Facades\Storage;
6
use atk4\data\Model;
7
use Epesi\Core\Data\HasEpesiConnection;
0 ignored issues
show
Bug introduced by
The type Epesi\Core\Data\HasEpesiConnection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
9
class WriteError extends \Exception {}
10
11
class FileContent extends Model
12
{
13
    use HasEpesiConnection;
14
    
15
	const HASH_METHOD = 'sha512';
16
17
	public $table = 'filestorage_contents';
18
19
    protected $appends = ['path'];
20
    
21
    function init(){
22
    	parent::init();
23
    	
24
    	$this->addFields([
25
    			'hash',
26
    			'size',
27
    			'type'
28
    	]);
29
    	
30
    	$this->hasMany('files', [File::class, 'their_field' => 'content_id']);
31
    	$this->addCalculatedField('storage_path', [[__CLASS__, 'getStoragePathField']]);
32
    	$this->addCalculatedField('path', [[__CLASS__, 'getPathField']]);
33
    	$this->addCalculatedField('data', [[__CLASS__, 'getDataField']]);    	
34
    }
35
    
36
    /**
37
     * One content can have many files associated with
38
     * The actual content is stored only once based on the content hash
39
     * 
40
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
41
     */
42
    public function files()
43
    {
44
    	return $this->ref('files');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->ref('files') returns the type atk4\data\Model which is incompatible with the documented return type Illuminate\Database\Eloquent\Relations\HasMany.
Loading history...
45
    }
46
    
47
    /**
48
     * Accessor method for retrieving of file content path when using the model
49
     * Having the $appends property in the File model listing the 'path' makes sure the value is also exported to arrays
50
     * 
51
     * @return string
52
     */
53
    public static function getPathField($model)
54
    {
55
    	return self::storage()->path($model->getStoragePath($model->get('hash')));
56
    }
57
    
58
    /**
59
     * Accessor method for retrieving of file contents
60
     * 
61
     * @return string
62
     */
63
    public static function getDataField($model)
64
    {
65
    	return self::storage()->get($model->get('storage_path'));
66
    }
67
    
68
    /**
69
     * Accessor method for file relative storage path
70
     * 
71
     * @return string
72
     */
73
    public static function getStoragePathField($model)
74
    {
75
    	return $model->getStoragePath($model->get('hash'));
76
    }
77
    
78
    protected static function getStoragePath($hash)
79
    {
80
    	return implode(DIRECTORY_SEPARATOR, array_merge(str_split(substr($hash, 0, 5)), [substr($hash, 5)]));
81
    }
82
    
83
    /**
84
     * Returns the storage where file contents are saved based on config settings
85
     * 
86
     * @return \Illuminate\Contracts\Filesystem\Filesystem
87
     */
88
    public static function storage()
89
    {
90
    	return Storage::disk(config('epesi.filestorage', 'local'));
91
    }
92
        
93
    /**
94
     * Add file to the filestorage
95
     *
96
     * @param string $file File path to save
97
     *
98
     * @return int File id in the database
99
     */
100
    public static function storeFromFile($file)
101
    {
102
    	return self::store(file_get_contents($file));
103
    }
104
    
105
    /**
106
     * Add content to the filestorage
107
     *
108
     * @param string $content Content to save
109
     *
110
     * @return int File id in the database
111
     */
112
    public static function store($content)
113
    {
114
    	$hash = self::hash($content);
115
    	
116
    	$path = self::getStoragePath($hash);
117
    	
118
    	if (! self::storage()->exists($path)) {
119
    		self::storage()->put($path, $content);
120
    	}
121
    	
122
    	$content = self::create()->addCondition('hash', $hash);
123
124
    	if (! $content->action('count')->getOne()) {  
125
    		return $content->insert([
126
    				'size' => self::storage()->size($path),
127
    				'type' => self::storage()->mimeType($path)
128
    		]);
129
    	}
130
    	
131
    	return $content->loadAny()->get('id');
132
    }
133
    
134
    /**
135
     * Get the hash of the content using hash method defined as constant to the class
136
     * 
137
     * @param string $content
138
     * @return string
139
     */
140
    public static function hash($content)
141
    {
142
    	return hash(self::HASH_METHOD, $content);
143
    }
144
}