-
Notifications
You must be signed in to change notification settings - Fork 8
/
FileField.php
92 lines (74 loc) · 2.72 KB
/
FileField.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
declare(strict_types=1);
namespace Atk4\Filestore\Field;
use Atk4\Core\InitializerTrait;
use Atk4\Data\Field;
use Atk4\Data\Model;
use Atk4\Data\Reference\HasOneSql;
use Atk4\Filestore\Form\Control\Upload;
use Atk4\Filestore\Model\File;
use League\Flysystem\Filesystem;
class FileField extends Field
{
use InitializerTrait {
init as private _init;
}
public array $ui = ['form' => [Upload::class]];
/** @var File|null */
public $fileModel;
/** @var Filesystem for fileModel init */
public $flysystem;
/** @var string */
protected $fieldNameBase;
/** @var HasOneSql */
public $reference;
/** @var Field */
public $fieldFilename;
protected function init(): void
{
$this->_init();
if ($this->fileModel === null) {
$this->fileModel = new File($this->getOwner()->getPersistence());
$this->fileModel->flysystem = $this->flysystem;
}
$this->reference = HasOneSql::assertInstanceOf($this->getOwner()->hasOne($this->shortName, [
'model' => $this->fileModel,
'theirField' => 'token',
]));
// TODO https://github.com/atk4/ui/pull/1805
$this->onHookToOwnerEntity(Model::HOOK_BEFORE_SAVE, function (Model $m) {
if ($m->get($this->shortName) === '') {
$m->set($this->shortName, null);
}
});
$this->fieldNameBase = preg_replace('~_id$~', '', $this->shortName);
$this->importFields();
// on insert/update delete old file and mark new one as linked
$fx = function (Model $m) {
if ($m->isDirty($this->shortName)) {
$old = $m->getDirtyRef()[$this->shortName];
$new = $m->get($this->shortName);
// remove old file, we don't need it
if ($old) {
$m->refModel($this->shortName)->loadBy('token', $old)->delete();
}
// mark new file as linked
if ($new) {
$m->refModel($this->shortName)->loadBy('token', $new)->save(['status' => File::STATUS_LINKED]);
}
}
};
$this->onHookToOwnerEntity(Model::HOOK_AFTER_INSERT, $fx);
$this->onHookToOwnerEntity(Model::HOOK_AFTER_UPDATE, $fx);
$this->onHookToOwnerEntity(Model::HOOK_AFTER_DELETE, function (Model $m) {
$token = $m->get($this->shortName);
if ($token) {
$m->refModel($this->shortName)->loadBy('token', $token)->delete();
}
});
}
protected function importFields(): void
{
$this->fieldFilename = $this->reference->addField($this->fieldNameBase . '_filename', 'meta_filename');
}
}