Completed
Push — master ( a5b59b...9caa2c )
by
unknown
02:29
created

code/Forms/UploadField.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SilverStripe\AssetAdmin\Forms;
4
5
use SilverStripe\AssetAdmin\Controller\AssetAdmin;
6
use SilverStripe\Assets\Folder;
7
use SilverStripe\Forms\FileHandleField;
8
use SilverStripe\Forms\FileUploadReceiver;
9
use SilverStripe\Forms\FormField;
10
use SilverStripe\ORM\DataObject;
11
use SilverStripe\ORM\SS_List;
12
13
/**
14
 * Represents a file upload field with ReactJS based frontend.
15
 *
16
 * Allows writing to a parent record with the following relation types:
17
 *   - has_one
18
 *   - has_many
19
 *   - many_many
20
 *
21
 * Additionally supports writing directly to the File table not attached
22
 * to any parent record.
23
 */
24
class UploadField extends FormField implements FileHandleField
25
{
26
    use FileUploadReceiver;
27
28
    /**
29
     * @config
30
     * @var int
31
     */
32
    private static $thumbnail_width = 60;
33
34
    /**
35
     * @config
36
     * @var int
37
     */
38
    private static $thumbnail_height = 60;
39
40
    protected $inputType = 'file';
41
42
    protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_CUSTOM;
43
44
    protected $schemaComponent = 'UploadField';
45
46
    /**
47
     * @var bool|null
48
     */
49
    protected $multiUpload = null;
50
51
    /**
52
     * Create a new file field.
53
     *
54
     * @param string $name The internal field name, passed to forms.
55
     * @param string $title The field label.
56
     * @param SS_List $items Items assigned to this field
57
     */
58
    public function __construct($name, $title = null, SS_List $items = null)
59
    {
60
        $this->constructFileUploadReceiver();
61
        parent::__construct($name, $title);
62
        if ($items) {
63
            $this->setItems($items);
64
        }
65
    }
66
67
    public function getSchemaDataDefaults()
68
    {
69
        $defaults = parent::getSchemaDataDefaults();
70
        $uploadLink = AssetAdmin::singleton()->Link('api/createFile');
71
        $defaults['data']['createFileEndpoint'] = [
72
            'url' => $uploadLink,
73
            'method' => 'post',
74
            'payloadFormat' => 'urlencoded',
75
        ];
76
        $defaults['data']['multi'] = $this->getIsMultiUpload();
77
        $defaults['data']['parentid'] = $this->getFolderID();
78
        return $defaults;
79
    }
80
81
    /**
82
     * Get ID of target parent folder
83
     *
84
     * @return int
85
     */
86
    protected function getFolderID()
87
    {
88
        $folderName = $this->getFolderName();
89
        if (!$folderName) {
90
            return 0;
91
        }
92
        $folder = Folder::find_or_make($folderName);
93
        return $folder ? $folder->ID : 0;
94
    }
95
96
    public function getSchemaStateDefaults()
97
    {
98
        $state = parent::getSchemaStateDefaults();
99
        $state['data']['files'] = $this->getEncodedItems();
100
        $state['value'] = $this->Value() ?: [ 'Files' => []];
101
        return $state;
102
    }
103
104
    /**
105
     * Encode selected values for react
106
     *
107
     * @return array
108
     */
109
    protected function getEncodedItems()
110
    {
111
        $assetAdmin = AssetAdmin::singleton();
112
        $fileData = [];
113
        foreach ($this->getItems() as $file) {
114
            $fileData[] = $assetAdmin->getObjectFromData($file);
115
        }
116
        return $fileData;
117
    }
118
119
    /**
120
     * Check if allowed to upload more than one file
121
     *
122
     * @return bool
123
     */
124
    public function getIsMultiUpload()
125
    {
126
        if (isset($this->multiUpload)) {
127
            return $this->multiUpload;
128
        }
129
        // Guess from record
130
        $record = $this->getRecord();
131
        $name = $this->getName();
132
133
        // Disabled for has_one components
134
        if ($record && DataObject::getSchema()->hasOneComponent(get_class($record), $name)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression \SilverStripe\ORM\DataOb..._class($record), $name) of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
135
            return false;
136
        }
137
        return true;
138
    }
139
140
    /**
141
     * Set upload type to multi / single
142
     *
143
     * @param $multi
144
     * @return $this
145
     */
146
    public function setIsMultiUpload($multi)
147
    {
148
        $this->multiUpload = $multi;
149
        return $this;
150
    }
151
152
    public function getAttributes()
153
    {
154
        $attributes = array(
155
            'class' => $this->extraClass(),
156
            'type' => 'file',
157
            'multiple' => $this->getIsMultiUpload(),
158
            'id' => $this->ID(),
159
            'data-schema' => json_encode($this->getSchemaData()),
160
            'data-state' => json_encode($this->getSchemaState()),
161
        );
162
163
        $attributes = array_merge($attributes, $this->attributes);
164
165
        $this->extend('updateAttributes', $attributes);
166
167
        return $attributes;
168
    }
169
170
    public function Type()
171
    {
172
        return 'entwine-uploadfield uploadfield';
173
    }
174
}
175