Completed
Pull Request — master (#406)
by Damian
02:19
created

RemoteFileFormFactory::getFormActions()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 21
rs 9.3142
cc 3
eloc 12
nc 4
nop 3
1
<?php
2
3
namespace SilverStripe\AssetAdmin\Forms;
4
5
use Embed\Exceptions\InvalidUrlException;
6
use InvalidArgumentException;
7
use SilverStripe\Control\Controller;
8
use SilverStripe\Control\Director;
9
use SilverStripe\Core\Config\Configurable;
10
use SilverStripe\Core\Extensible;
11
use SilverStripe\Forms\CompositeField;
12
use SilverStripe\Forms\FieldGroup;
13
use SilverStripe\Forms\FieldList;
14
use SilverStripe\Forms\Form;
15
use SilverStripe\Forms\FormAction;
16
use SilverStripe\Forms\FormFactory;
17
use SilverStripe\Forms\HeaderField;
18
use SilverStripe\Forms\HiddenField;
19
use SilverStripe\Forms\HTMLEditor\HTMLEditorField_Embed;
20
use SilverStripe\Forms\LabelField;
21
use SilverStripe\Forms\LiteralField;
22
use SilverStripe\Forms\OptionsetField;
23
use SilverStripe\Forms\ReadonlyField;
24
use SilverStripe\Forms\RequiredFields;
25
use SilverStripe\Forms\TextField;
26
27
class RemoteFileFormFactory implements FormFactory
28
{
29
    use Extensible;
30
    use Configurable;
31
    
32
    private static $fileurl_scheme_whitelist = ['http', 'https'];
0 ignored issues
show
Unused Code introduced by
The property $fileurl_scheme_whitelist 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...
33
    
34
    private static $fileurl_domain_whitelist = [];
0 ignored issues
show
Unused Code introduced by
The property $fileurl_domain_whitelist 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...
35
    
36
    /**
37
     * @param Controller $controller
38
     * @param string $name
39
     * @param array $context
40
     * @return Form
41
     */
42
    public function getForm(Controller $controller, $name = self::DEFAULT_NAME, $context = [])
43
    {
44
        // Validate context
45
        foreach ($this->getRequiredContext() as $required) {
46
            if (!isset($context[$required])) {
47
                throw new InvalidArgumentException("Missing required context $required");
48
            }
49
        }
50
    
51
        $fields = $this->getFormFields($controller, $name, $context);
52
        $actions = $this->getFormActions($controller, $name, $context);
53
        
54
        $validator = new RequiredFields();
55
        $form = Form::create($controller, $name, $fields, $actions, $validator);
56
        $form->addExtraClass('form--fill-height');
57
        $form->addExtraClass('form--no-dividers');
58
        $form->addExtraClass('insert-embed-modal--'. strtolower($context['type']));
59
    
60
        // Extend form
61
        $this->invokeWithExtensions('updateForm', $form, $controller, $name, $context);
62
    
63
        return $form;
64
    }
65
    
66
    public function getRequiredContext()
67
    {
68
        return ['type'];
69
    }
70
    
71
    protected function getFormFields($controller, $name, $context)
0 ignored issues
show
Unused Code introduced by
The parameter $controller is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
72
    {
73
        $fields = [];
74
        $url = (isset($context['url'])) ? $context['url'] : null;
75
        
76
        if ($context['type'] === 'create') {
77
            $fields = [
78
                TextField::create('Url',
79
                    _t(
80
                        'RemoteFileForm.UrlDescription',
81
                        'Embed Youtube and Vimeo videos, images and other media directly from the web.'
82
                    )
83
                )
84
                ->addExtraClass('insert-embed-modal__url-create'),
85
            ];
86
        }
87
        
88
        if ($context['type'] === 'edit' && $url && $this->validateUrl($url)) {
89
            $embed = $this->getEmbed($url);
90
            $alignments = array(
91
                'leftAlone' => _t('AssetAdmin.AlignmentLeftAlone', 'Left'),
92
                'center' => _t('AssetAdmin.AlignmentCenter', 'Center'),
93
                'rightAlone' => _t('AssetAdmin.AlignmentRightAlone', 'Right'),
94
                'left' => _t('AssetAdmin.AlignmentLeft', 'Left wrap'),
95
                'right' => _t('AssetAdmin.AlignmentRight', 'Right wrap'),
96
            );
97
            
98
            $fields = CompositeField::create([
99
                LiteralField::create(
100
                    'Preview',
101
                    sprintf(
102
                        '<img src="%s" class="%s" />',
103
                        $embed->getPreviewURL(),
104
                        'insert-embed-modal__preview'
105
                    )
106
                )->addExtraClass('insert-embed-modal__preview-container'),
107
                HiddenField::create('PreviewUrl', 'PreviewUrl', $embed->getPreviewURL()),
108
                CompositeField::create([
109
                    ReadonlyField::create('Url', $embed->getName(), $url),
110
                    TextField::create('CaptionText', _t('AssetAdmin.Caption', 'Caption')),
111
                    OptionsetField::create(
112
                        'Placement',
113
                        _t('AssetAdmin.Placement', 'Placement'),
114
                        $alignments
115
                    )
116
                        ->addExtraClass('insert-embed-modal__placement'),
117
                    FieldGroup::create(
118
                        _t('AssetAdmin.ImageSpecs', 'Dimensions'),
119
                        TextField::create('Width', '', $embed->getWidth())
120
                            ->setRightTitle(_t('AssetAdmin.ImageWidth', 'Width'))
121
                            ->setMaxLength(5)
122
                            ->addExtraClass('flexbox-area-grow'),
123
                        TextField::create('Height', '', $embed->getHeight())
124
                            ->setRightTitle(_t('AssetAdmin.ImageHeight', 'Height'))
125
                            ->setMaxLength(5)
126
                            ->addExtraClass('flexbox-area-grow')
127
                    )->addExtraClass('fieldgroup--fill-width')
128
                ])->addExtraClass('flexbox-area-grow'),
129
            ])->addExtraClass('insert-embed-modal__fields--fill-width');
130
        }
131
        
132
        return FieldList::create($fields);
133
    }
134
    
135
    protected function getFormActions($controller, $name, $context)
0 ignored issues
show
Unused Code introduced by
The parameter $controller is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
136
    {
137
        $actions = [];
138
        
139
        if ($context['type'] === 'create') {
140
            $actions = [
141
                FormAction::create('addmedia', _t('RemoteFileForm.AddMedia', 'Add media'))
142
                    ->setSchemaData(['data' => ['buttonStyle' => 'primary']]),
143
            ];
144
        }
145
        
146
        if ($context['type'] === 'edit') {
147
            $actions = [
148
                FormAction::create('insertmedia', _t('RemoteFileForm.InsertMedia', 'Insert media'))
149
                    ->setSchemaData(['data' => ['buttonStyle' => 'primary']]),
150
                FormAction::create('cancel', _t('RemoteFileForm.Cancel', 'Cancel')),
151
            ];
152
        }
153
    
154
        return FieldList::create($actions);
155
    }
156
    
157
    /**
158
     * @param $url
159
     * @return bool
160
     * @throws InvalidUrlException
161
     */
162
    protected function validateUrl($url)
163
    {
164
        if (!Director::is_absolute_url($url)) {
165
            throw new InvalidUrlException(_t(
166
                "HTMLEditorField_Toolbar.ERROR_ABSOLUTE",
167
                "Only absolute urls can be embedded"
168
            ));
169
        }
170
        $scheme = strtolower(parse_url($url, PHP_URL_SCHEME));
171
        $allowed_schemes = self::config()->get('fileurl_scheme_whitelist');
172
        if (!$scheme || ($allowed_schemes && !in_array($scheme, $allowed_schemes))) {
173
            throw new InvalidUrlException(_t(
174
                "HTMLEditorField_Toolbar.ERROR_SCHEME",
175
                "This file scheme is not included in the whitelist"
176
            ));
177
        }
178
        $domain = strtolower(parse_url($url, PHP_URL_HOST));
179
        $allowed_domains = self::config()->get('fileurl_domain_whitelist');
180
        if (!$domain || ($allowed_domains && !in_array($domain, $allowed_domains))) {
181
            throw new InvalidUrlException(_t(
182
                "HTMLEditorField_Toolbar.ERROR_HOSTNAME",
183
                "This file hostname is not included in the whitelist"
184
            ));
185
        }
186
        return true;
187
    }
188
    
189
    protected function getEmbed($url)
190
    {
191
        $embed = new HTMLEditorField_Embed($url);
192
        
193
        return $embed;
194
    }
195
}
196