Completed
Pull Request — master (#406)
by
unknown
02:25
created

RemoteFileFormFactory::getRequiredContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
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\HiddenField;
18
use SilverStripe\Forms\HTMLEditor\HTMLEditorField_Embed;
19
use SilverStripe\Forms\LabelField;
20
use SilverStripe\Forms\LiteralField;
21
use SilverStripe\Forms\OptionsetField;
22
use SilverStripe\Forms\ReadonlyField;
23
use SilverStripe\Forms\RequiredFields;
24
use SilverStripe\Forms\TextField;
25
26
class RemoteFileFormFactory implements FormFactory
27
{
28
    use Extensible;
29
    use Configurable;
30
    
31
    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...
32
    
33
    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...
34
    
35
    /**
36
     * @param Controller $controller
37
     * @param string $name
38
     * @param array $context
39
     * @return Form
40
     */
41 View Code Duplication
    public function getForm(Controller $controller, $name = self::DEFAULT_NAME, $context = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
42
    {
43
        // Validate context
44
        foreach ($this->getRequiredContext() as $required) {
45
            if (!isset($context[$required])) {
46
                throw new InvalidArgumentException("Missing required context $required");
47
            }
48
        }
49
    
50
        $fields = $this->getFormFields($controller, $name, $context);
51
        $actions = $this->getFormActions($controller, $name, $context);
52
        
53
        $validator = new RequiredFields();
54
        $form = Form::create($controller, $name, $fields, $actions, $validator);
55
        $form->addExtraClass('form--fill-height');
56
        $form->addExtraClass('insert-embed-modal--'. strtolower($context['type']));
57
    
58
        // Extend form
59
        $this->invokeWithExtensions('updateForm', $form, $controller, $name, $context);
60
    
61
        return $form;
62
    }
63
    
64
    public function getRequiredContext()
65
    {
66
        return ['type'];
67
    }
68
    
69
    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...
70
    {
71
        $fields = [];
72
        $url = (isset($context['url'])) ? $context['url'] : null;
73
        
74
        if ($context['type'] === 'create') {
75
            $fields = [
76
                LabelField::create('UrlDescription', _t(
77
                    'RemoteFileForm.UrlDescription',
78
                    'Embed Youtube and Vimeo videos, images and other media directly from the web.'
79
                )),
80
                TextField::create('Url', ''),
81
            ];
82
        }
83
        
84
        if ($context['type'] === 'edit' && $url && $this->validateUrl($url)) {
85
            $embed = $this->getEmbed($url);
86
            $alignments = array(
87
                'leftAlone' => _t('AssetAdmin.AlignmentLeftAlone', 'On the left, on its own.'),
88
                'center' => _t('AssetAdmin.AlignmentCenter', 'Centered, on its own.'),
89
                'rightAlone' => _t('AssetAdmin.AlignmentRightAlone', 'On the right, on its own.'),
90
                'left' => _t('AssetAdmin.AlignmentLeft', 'On the left, with text wrapping around.'),
91
                'right' => _t('AssetAdmin.AlignmentRight', 'On the right, with text wrapping around.'),
92
            );
93
            
94
            $fields = CompositeField::create([
95
                LiteralField::create('Preview', sprintf('<img src="%s" class="%s" />',
96
                    $embed->getPreviewURL(),
97
                    'insert-embed-modal__preview'
98
                ))->addExtraClass('insert-embed-modal__preview-container'),
99
                HiddenField::create('PreviewUrl', 'PreviewUrl', $embed->getPreviewURL()),
100
                CompositeField::create([
101
                    ReadonlyField::create('Url', $embed->getName(), $url),
102
                    TextField::create('CaptionText', _t('AssetAdmin.Caption', 'Caption')),
103
                    OptionsetField::create(
104
                        'Placement',
105
                        _t('AssetAdmin.Placement', 'Placement'),
106
                        $alignments
107
                    )
108
                        ->addExtraClass('insert-embed-modal__placement'),
109
                    FieldGroup::create(
110
                        _t('AssetAdmin.ImageSpecs', 'Dimensions'),
111
                        TextField::create(
112
                            'Width',
113
                            _t('AssetAdmin.ImageWidth', 'Width'),
114
                            $embed->getWidth()
115
                        )
116
                            ->setMaxLength(5)
117
                            ->addExtraClass('flexbox-area-grow'),
118
                        TextField::create(
119
                            'Height',
120
                            _t('AssetAdmin.ImageHeight', 'Height'),
121
                            $embed->getHeight()
122
                        )
123
                            ->setMaxLength(5)
124
                            ->addExtraClass('flexbox-area-grow')
125
                    )->addExtraClass('fieldgroup--fill-width')
126
                ])->addExtraClass('flexbox-area-grow'),
127
            ])->addExtraClass('insert-embed-modal__fields--fill-width');
128
        }
129
        
130
        return FieldList::create($fields);
131
    }
132
    
133
    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...
134
    {
135
        $actions = [];
136
        
137
        if ($context['type'] === 'create') {
138
            $actions = [
139
                FormAction::create('addmedia', _t('RemoteFileForm.AddMedia', 'Add media'))
140
                    ->setSchemaData(['data' => ['buttonStyle' => 'primary']]),
141
            ];
142
        }
143
        
144
        if ($context['type'] === 'edit') {
145
            $actions = [
146
                FormAction::create('insertmedia', _t('RemoteFileForm.InsertMedia', 'Insert media'))
147
                    ->setSchemaData(['data' => ['buttonStyle' => 'primary']]),
148
                FormAction::create('cancel', _t('RemoteFileForm.Cancel', 'Cancel')),
149
            ];
150
        }
151
    
152
        return FieldList::create($actions);
153
    }
154
    
155
    /**
156
     * @param $url
157
     * @return bool
158
     * @throws InvalidUrlException
159
     */
160
    protected function validateUrl($url)
161
    {
162
        if (!Director::is_absolute_url($url)) {
163
            throw new InvalidUrlException(_t(
164
                "HTMLEditorField_Toolbar.ERROR_ABSOLUTE",
165
                "Only absolute urls can be embedded"
166
            ));
167
        }
168
        $scheme = strtolower(parse_url($url, PHP_URL_SCHEME));
169
        $allowed_schemes = self::config()->get('fileurl_scheme_whitelist');
170
        if (!$scheme || ($allowed_schemes && !in_array($scheme, $allowed_schemes))) {
171
            throw new InvalidUrlException(_t(
172
                "HTMLEditorField_Toolbar.ERROR_SCHEME",
173
                "This file scheme is not included in the whitelist"
174
            ));
175
        }
176
        $domain = strtolower(parse_url($url, PHP_URL_HOST));
177
        $allowed_domains = self::config()->get('fileurl_domain_whitelist');
178
        if (!$domain || ($allowed_domains && !in_array($domain, $allowed_domains))) {
179
            throw new InvalidUrlException(_t(
180
                "HTMLEditorField_Toolbar.ERROR_HOSTNAME",
181
                "This file hostname is not included in the whitelist"
182
            ));
183
        }
184
        return true;
185
    }
186
    
187
    protected function getEmbed($url)
188
    {
189
        $embed = new HTMLEditorField_Embed($url);
190
        
191
        return $embed;
192
    }
193
}
194