Completed
Pull Request — master (#331)
by
unknown
01:55
created

UploadField::getAttributes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 1
eloc 11
nc 1
nop 0
1
<?php
2
3
namespace SilverStripe\AssetAdmin\Forms;
4
5
use SilverStripe\AssetAdmin\Controller\AssetAdmin;
6
use SilverStripe\Assets\Folder;
7
use SilverStripe\Forms\FileUploadReceiver;
8
use SilverStripe\Forms\FormField;
9
use SilverStripe\ORM\DataObject;
10
use SilverStripe\ORM\SS_List;
11
12
/**
13
 * Represents a file upload field with ReactJS based frontend.
14
 *
15
 * Allows writing to a parent record with the following relation types:
16
 *   - has_one
17
 *   - has_many
18
 *   - many_many
19
 *
20
 * Additionally supports writing directly to the File table not attached
21
 * to any parent record.
22
 */
23
class UploadField extends FormField
24
{
25
    use FileUploadReceiver;
26
27
    /**
28
     * @config
29
     * @var int
30
     */
31
    private static $thumbnail_width = 60;
0 ignored issues
show
Unused Code introduced by
The property $thumbnail_width is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
32
33
    /**
34
     * @config
35
     * @var int
36
     */
37
    private static $thumbnail_height = 60;
0 ignored issues
show
Unused Code introduced by
The property $thumbnail_height is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
38
39
    protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_CUSTOM;
40
41
    protected $schemaComponent = 'UploadField';
42
43
    /**
44
     * @var bool|null
45
     */
46
    protected $multiUpload = null;
47
48
    /**
49
     * Create a new file field.
50
     *
51
     * @param string $name The internal field name, passed to forms.
52
     * @param string $title The field label.
53
     * @param SS_List $items Items assigned to this field
54
     */
55
    public function __construct($name, $title = null, SS_List $items = null)
56
    {
57
        $this->constructFileUploadReceiver();
58
        parent::__construct($name, $title);
59
        if ($items) {
60
            $this->setItems($items);
61
        }
62
    }
63
64
    public function getSchemaDataDefaults()
65
    {
66
        $defaults = parent::getSchemaDataDefaults();
67
        $uploadLink = AssetAdmin::singleton()->Link('api/createFile');
68
        $defaults['data']['createFileEndpoint'] = [
69
            'url' => $uploadLink,
70
            'method' => 'post',
71
            'payloadFormat' => 'urlencoded',
72
        ];
73
        $defaults['data']['multi'] = $this->getIsMultiUpload();
74
        $defaults['data']['parentid'] = $this->getFolderID();
75
        return $defaults;
76
    }
77
78
    /**
79
     * Get ID of target parent folder
80
     *
81
     * @return int
82
     */
83
    protected function getFolderID()
84
    {
85
        $folderName = $this->getFolderName();
86
        if (!$folderName) {
87
            return 0;
88
        }
89
        $folder = Folder::find_or_make($folderName);
90
        return $folder ? $folder->ID : 0;
91
    }
92
93
    public function getSchemaStateDefaults()
94
    {
95
        $state = parent::getSchemaStateDefaults();
96
        $state['data']['files'] = $this->getEncodedItems();
97
        $state['value'] = $this->Value() ?: [ 'Files' => []];
98
        return $state;
99
    }
100
101
    /**
102
     * Encode selected values for react
103
     *
104
     * @return array
105
     */
106
    protected function getEncodedItems()
107
    {
108
        $assetAdmin = AssetAdmin::singleton();
109
        $fileData = [];
110
        foreach ($this->getItems() as $file) {
111
            $fileData[] = $assetAdmin->getObjectFromData($file);
112
        }
113
        return $fileData;
114
    }
115
116
    /**
117
     * Check if allowed to upload more than one file
118
     *
119
     * @return bool
120
     */
121
    public function getIsMultiUpload()
122
    {
123
        if (isset($this->multiUpload)) {
124
            return $this->multiUpload;
125
        }
126
        // Guess from record
127
        $record = $this->getRecord();
128
        $name = $this->getName();
129
130
        // Disabled for has_one components
131
        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...
132
            return false;
133
        }
134
        return true;
135
    }
136
137
    /**
138
     * Set upload type to multi / single
139
     *
140
     * @param $multi
141
     * @return $this
142
     */
143
    public function setIsMultiUpload($multi)
144
    {
145
        $this->multiUpload = $multi;
146
        return $this;
147
    }
148
149
    public function getAttributes()
150
    {
151
        $attributes = array(
152
            'class' => $this->extraClass(),
153
            'type' => 'file',
154
            'multiple' => $this->getIsMultiUpload(),
155
            'id' => $this->ID(),
156
            'data-schema' => json_encode($this->getSchemaData()),
157
            'data-state' => json_encode($this->getSchemaState()),
158
        );
159
160
        $attributes = array_merge($attributes, $this->attributes);
161
162
        $this->extend('updateAttributes', $attributes);
163
164
        return $attributes;
165
    }
166
167
    public function Type()
168
    {
169
        return 'entwine-uploadfield uploadfield';
170
    }
171
}
172