1 | <?php |
||||||
2 | |||||||
3 | namespace Epesi\FileStorage\Models; |
||||||
4 | |||||||
5 | use Illuminate\Support\Facades\Auth; |
||||||
6 | use atk4\data\Model; |
||||||
7 | use Epesi\Core\Data\HasEpesiConnection; |
||||||
0 ignored issues
–
show
|
|||||||
8 | use Epesi\Core\System\User\Database\Models\atk4\User; |
||||||
9 | |||||||
10 | class LinkNotFound extends \Exception {} |
||||||
11 | class LinkDuplicate extends \Exception {} |
||||||
12 | class FileNotFound extends \Exception {} |
||||||
13 | |||||||
14 | class File extends Model |
||||||
15 | { |
||||||
16 | use HasEpesiConnection; |
||||||
17 | |||||||
18 | public $table = 'filestorage_files'; |
||||||
19 | |||||||
20 | function init() { |
||||||
21 | parent::init(); |
||||||
22 | |||||||
23 | $this->addFields([ |
||||||
24 | 'created_at' => ['caption' => __('Stored At')], |
||||||
25 | 'name' => ['caption' => __('File Name')], |
||||||
26 | 'link' => ['caption' => __('Link')], |
||||||
27 | 'backref' |
||||||
28 | ]); |
||||||
29 | |||||||
30 | $this->hasOne('created_by', [User::class, 'our_field' => 'created_by'])->addTitle(['field' => 'created_by_user', 'caption' => __('Stored By')]); |
||||||
0 ignored issues
–
show
The method
addTitle() does not exist on atk4\data\Reference . It seems like you code against a sub-type of atk4\data\Reference such as atk4\data\Reference\HasOne_SQL .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
31 | |||||||
32 | $this->hasOne('content', [FileContent::class, 'our_field' => 'content_id']); |
||||||
33 | |||||||
34 | $this->hasMany('links', [FileRemoteAccess::class, 'their_field' => 'file_id']); |
||||||
35 | |||||||
36 | $this->addCalculatedField('thumbnail', [[__CLASS__, 'getThumbnailField']]); |
||||||
37 | } |
||||||
38 | |||||||
39 | public function userActiveLinks() |
||||||
40 | { |
||||||
41 | return $this->ref('links')->addCrits([ |
||||||
42 | ['created_by', Auth::id()], |
||||||
43 | ['expires_at', '>', date('Y-m-d H:i:s')] |
||||||
44 | ]); |
||||||
45 | } |
||||||
46 | |||||||
47 | /** |
||||||
48 | * Retrieve the file |
||||||
49 | * |
||||||
50 | * @param int|string $idOrLink Filestorage ID or unique link string |
||||||
51 | * @param bool $useCache Use cache or not |
||||||
52 | * |
||||||
53 | * @return static |
||||||
54 | * |
||||||
55 | * @throws FileNotFound |
||||||
56 | */ |
||||||
57 | public static function retrieve($idOrLink) |
||||||
58 | { |
||||||
59 | $id = self::getIdByLink($idOrLink, true, true); |
||||||
60 | |||||||
61 | $file = self::create()->tryLoad($id); |
||||||
62 | |||||||
63 | if (! $file->ref('content')['hash']) { |
||||||
64 | throw new FileNotFound('File object does not have corresponding content'); |
||||||
65 | } |
||||||
66 | |||||||
67 | return $file; |
||||||
68 | } |
||||||
69 | |||||||
70 | /** |
||||||
71 | * Get Filestorage ID by link |
||||||
72 | * |
||||||
73 | * @param string $link Unique link |
||||||
74 | * @param bool $useCache Use cache or not |
||||||
75 | * @param bool $throwException Throw exception if link is not found |
||||||
76 | * |
||||||
77 | * @return int Filestorage ID |
||||||
78 | * @throws LinkNotFound |
||||||
79 | */ |
||||||
80 | public static function getIdByLink($link, $useCache = true, $throwException = false) |
||||||
81 | { |
||||||
82 | static $cache = []; |
||||||
83 | |||||||
84 | if (is_numeric($link) || is_null($link)) return $link; |
||||||
0 ignored issues
–
show
|
|||||||
85 | |||||||
86 | if (is_object($link)) return $link['id']; |
||||||
0 ignored issues
–
show
|
|||||||
87 | |||||||
88 | if (!$useCache || !isset($cache[$link])) { |
||||||
89 | $file = self::create()->tryLoadBy('link', $link); |
||||||
90 | |||||||
91 | $cache[$link] = $file? $file->get('id'): null; |
||||||
92 | |||||||
93 | if (!$cache[$link] && $throwException) { |
||||||
94 | throw new LinkNotFound($link); |
||||||
95 | } |
||||||
96 | } |
||||||
97 | |||||||
98 | return $cache[$link]; |
||||||
99 | } |
||||||
100 | |||||||
101 | /** |
||||||
102 | * Mark file as deleted. Does not remove any content! |
||||||
103 | * |
||||||
104 | * @param int|string $idOrLink Filestorage ID or unique link |
||||||
105 | */ |
||||||
106 | public static function unlink($idOrLink) |
||||||
107 | { |
||||||
108 | if ($id = self::getIdByLink($idOrLink, false)) { |
||||||
109 | self::create()->delete($id); |
||||||
110 | } |
||||||
111 | } |
||||||
112 | |||||||
113 | /** |
||||||
114 | * Check if file exists |
||||||
115 | * |
||||||
116 | * @param int|static $idOrMeta Filestorage ID or file object |
||||||
117 | * @param bool $throwException Throw exception on missing file or return false |
||||||
118 | * |
||||||
119 | * @return bool True if file exists, false otherwise |
||||||
120 | * @throws FileNotFound May be thrown if $throwException set to true |
||||||
121 | */ |
||||||
122 | public static function exists($idOrMeta, $throwException = false) |
||||||
123 | { |
||||||
124 | try { |
||||||
125 | $file = is_numeric($idOrMeta) ? self::retrieve($idOrMeta) : $idOrMeta; |
||||||
126 | |||||||
127 | if (! file_exists($file->ref('content')['path'])) { |
||||||
128 | throw new FileNotFound('Exception - file not found: ' . $file->ref('content')['path']); |
||||||
129 | } |
||||||
130 | } catch (\Exception $exception) { |
||||||
131 | if ($throwException) |
||||||
132 | throw $exception; |
||||||
133 | else |
||||||
134 | return false; |
||||||
135 | } |
||||||
136 | |||||||
137 | return true; |
||||||
138 | } |
||||||
139 | |||||||
140 | /** |
||||||
141 | * Add multiple files, clone file if file id is provided. |
||||||
142 | * May be used to update backref for all files. |
||||||
143 | * |
||||||
144 | * @param array $files array of existing filestorage ids or array with values for the new file |
||||||
145 | * @param string|null $backref Backref for all files |
||||||
146 | * @return array Newly created Meta Ids sorted in ascending order |
||||||
147 | */ |
||||||
148 | public static function storeMany($files, $backref = null) |
||||||
149 | { |
||||||
150 | $ids = []; |
||||||
151 | foreach ((array) $files as $filePath) { |
||||||
152 | if (! is_numeric($filePath)) { |
||||||
153 | $ids[] = self::store($filePath); |
||||||
154 | |||||||
155 | continue; |
||||||
156 | } |
||||||
157 | |||||||
158 | $file = self::retrieve($filePath, false); |
||||||
0 ignored issues
–
show
The call to
Epesi\FileStorage\Models\File::retrieve() has too many arguments starting with false .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
159 | |||||||
160 | if ($backref && $file['backref'] != $backref) { |
||||||
161 | $file->save(compact('backref')); |
||||||
162 | } |
||||||
163 | |||||||
164 | $ids[] = $file['id']; |
||||||
165 | } |
||||||
166 | |||||||
167 | sort($ids); |
||||||
168 | |||||||
169 | return $ids; |
||||||
170 | } |
||||||
171 | |||||||
172 | /** |
||||||
173 | * @param string|array $fileOrPath |
||||||
174 | * @param string $content Content of the file |
||||||
175 | * |
||||||
176 | * @return int Filestorage ID |
||||||
177 | * @throws LinkDuplicate |
||||||
178 | */ |
||||||
179 | public static function store($fileOrPath, $content = null) |
||||||
180 | { |
||||||
181 | $file = $fileOrPath; |
||||||
182 | |||||||
183 | if (is_object($file)) { |
||||||
0 ignored issues
–
show
|
|||||||
184 | $file->action('update', [ |
||||||
185 | 'content_id' => FileContent::store($content) |
||||||
186 | ]); |
||||||
187 | |||||||
188 | return $file['id']; |
||||||
189 | } |
||||||
190 | |||||||
191 | if (! $content && is_string($fileOrPath)) { |
||||||
192 | $content = file_get_contents($fileOrPath); |
||||||
193 | |||||||
194 | $file = [ |
||||||
195 | 'name' => basename($fileOrPath) |
||||||
196 | ]; |
||||||
197 | } |
||||||
198 | |||||||
199 | if (! empty($file['link']) && self::getIdByLink($file['link'], false)) { |
||||||
200 | throw new LinkDuplicate($file['link']); |
||||||
201 | } |
||||||
202 | |||||||
203 | $content = $file['content']?? $content; |
||||||
204 | |||||||
205 | if (is_array($content)) { |
||||||
206 | $path = $content['path']; |
||||||
207 | |||||||
208 | $file['name'] = $file['name']?? basename($path); |
||||||
209 | |||||||
210 | $content = file_get_contents($path); |
||||||
211 | } |
||||||
212 | |||||||
213 | unset($file['content']); |
||||||
214 | |||||||
215 | return self::create()->insert(array_merge([ |
||||||
216 | 'created_at' => date('Y-m-d H:i:s'), |
||||||
217 | 'created_by' => Auth::id(), |
||||||
218 | 'content_id' => FileContent::store($content) |
||||||
219 | ], $file)); |
||||||
220 | } |
||||||
221 | |||||||
222 | public static function getThumbnailField($model) |
||||||
223 | { |
||||||
224 | if (! $model->thumbnailPossible()) return false; |
||||||
225 | |||||||
226 | $image = new \Imagick($model->ref('content')['path'] . '[0]'); |
||||||
227 | |||||||
228 | $image->setImageFormat('jpg'); |
||||||
229 | |||||||
230 | return collect([ |
||||||
231 | 'mime' => 'image/jpeg', |
||||||
232 | 'name' => 'preview.jpeg', |
||||||
233 | 'contents' => $image . '' |
||||||
234 | ]); |
||||||
235 | } |
||||||
236 | |||||||
237 | public function thumbnailPossible() { |
||||||
238 | return $this->ref('content')['type'] == 'application/pdf' && class_exists('Imagick'); |
||||||
239 | } |
||||||
240 | } |
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:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths