Completed
Push — master ( 145320...5b49b5 )
by Damian
11s
created

RemoteFileFormFactory   B

Complexity

Total Complexity 25

Size/Duplication

Total Lines 187
Duplicated Lines 5.35 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
wmc 25
c 0
b 0
f 0
lcom 1
cbo 16
dl 10
loc 187
rs 8.4614

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getForm() 0 23 3
A getRequiredContext() 0 4 1
C getFormFields() 10 81 9
A getFormActions() 0 21 3
C validateUrl() 0 26 8
A getEmbed() 0 6 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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\LiteralField;
20
use SilverStripe\Forms\OptionsetField;
21
use SilverStripe\Forms\RequiredFields;
22
use SilverStripe\Forms\TextField;
23
24
class RemoteFileFormFactory implements FormFactory
25
{
26
    use Extensible;
27
    use Configurable;
28
29
    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...
30
31
    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...
32
33
    /**
34
     * @param Controller $controller
35
     * @param string $name
36
     * @param array $context
37
     * @return Form
38
     */
39
    public function getForm(Controller $controller, $name = self::DEFAULT_NAME, $context = [])
40
    {
41
        // Validate context
42
        foreach ($this->getRequiredContext() as $required) {
43
            if (!isset($context[$required])) {
44
                throw new InvalidArgumentException("Missing required context $required");
45
            }
46
        }
47
48
        $fields = $this->getFormFields($controller, $name, $context);
49
        $actions = $this->getFormActions($controller, $name, $context);
50
51
        $validator = new RequiredFields();
52
        $form = Form::create($controller, $name, $fields, $actions, $validator);
53
        $form->addExtraClass('form--fill-height');
54
        $form->addExtraClass('form--no-dividers');
55
        $form->addExtraClass('insert-embed-modal--'. strtolower($context['type']));
56
57
        // Extend form
58
        $this->invokeWithExtensions('updateForm', $form, $controller, $name, $context);
59
60
        return $form;
61
    }
62
63
    public function getRequiredContext()
64
    {
65
        return ['type'];
66
    }
67
68
    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...
69
    {
70
        $fields = [];
71
        $url = (isset($context['url'])) ? $context['url'] : null;
72
73
        if ($context['type'] === 'create') {
74
            $fields = [
75
                TextField::create(
76
                    'Url',
77
                    _t(
78
                        'SilverStripe\\AssetAdmin\\Forms\\RemoteFileFormFactory.UrlDescription',
79
                        'Embed Youtube and Vimeo videos, images and other media directly from the web.'
80
                    )
81
                )
82
                ->addExtraClass('insert-embed-modal__url-create'),
83
            ];
84
        }
85
86
        if ($context['type'] === 'edit' && $url && $this->validateUrl($url)) {
87
            $embed = $this->getEmbed($url);
88
            $alignments = array(
89
                'leftAlone' => _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.AlignmentLeftAlone', 'Left'),
90
                'center' => _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.AlignmentCenter', 'Center'),
91
                'rightAlone' => _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.AlignmentRightAlone', 'Right'),
92
                'left' => _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.AlignmentLeft', 'Left wrap'),
93
                'right' => _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.AlignmentRight', 'Right wrap'),
94
            );
95
    
96
            $width = $embed->getWidth();
97
            $height = $embed->getHeight();
98
    
99
            $fields = CompositeField::create([
100
                LiteralField::create(
101
                    'Preview',
102
                    sprintf(
103
                        '<img src="%s" class="%s" />',
104
                        $embed->getPreviewURL(),
105
                        'insert-embed-modal__preview'
106
                    )
107
                )->addExtraClass('insert-embed-modal__preview-container'),
108
                HiddenField::create('PreviewUrl', 'PreviewUrl', $embed->getPreviewURL()),
109
                CompositeField::create([
110
                    TextField::create('UrlPreview', $embed->getName(), $url)
111
                        ->setReadonly(true),
112
                    HiddenField::create('Url', false, $url),
113
                    TextField::create('CaptionText', _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.Caption', 'Caption')),
114
                    OptionsetField::create(
115
                        'Placement',
116
                        _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.Placement', 'Placement'),
117
                        $alignments
118
                    )
119
                        ->addExtraClass('insert-embed-modal__placement'),
120
                    $dimensions = FieldGroup::create(
121
                        _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.ImageSpecs', 'Dimensions'),
122
                        TextField::create('Width', '', $width)
123
                            ->setRightTitle(_t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.ImageWidth', 'Width'))
124
                            ->setMaxLength(5)
125
                            ->addExtraClass('flexbox-area-grow'),
126
                        TextField::create('Height', '', $height)
127
                            ->setRightTitle(_t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.ImageHeight', 'Height'))
128
                            ->setMaxLength(5)
129
                            ->addExtraClass('flexbox-area-grow')
130
                    )->addExtraClass('fieldgroup--fill-width')
131
                        ->setName('Dimensions')
132
                ])->addExtraClass('flexbox-area-grow'),
133
            ])->addExtraClass('insert-embed-modal__fields--fill-width');
134
    
135 View Code Duplication
            if ($dimensions && $width && $height) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
136
                $ratio = $width / $height;
137
        
138
                $dimensions->setSchemaComponent('ProportionConstraintField');
139
                $dimensions->setSchemaState([
140
                    'data' => [
141
                        'ratio' => $ratio
142
                    ]
143
                ]);
144
            }
145
        }
146
147
        return FieldList::create($fields);
148
    }
149
150
    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...
151
    {
152
        $actions = [];
153
154
        if ($context['type'] === 'create') {
155
            $actions = [
156
                FormAction::create('addmedia', _t('SilverStripe\\AssetAdmin\\Forms\\RemoteFileFormFactory.AddMedia', 'Add media'))
157
                    ->setSchemaData(['data' => ['buttonStyle' => 'primary']]),
158
            ];
159
        }
160
161
        if ($context['type'] === 'edit') {
162
            $actions = [
163
                FormAction::create('insertmedia', _t('SilverStripe\\AssetAdmin\\Forms\\RemoteFileFormFactory.InsertMedia', 'Insert media'))
164
                    ->setSchemaData(['data' => ['buttonStyle' => 'primary']]),
165
                FormAction::create('cancel', _t('SilverStripe\\AssetAdmin\\Forms\\RemoteFileFormFactory.Cancel', 'Cancel')),
166
            ];
167
        }
168
169
        return FieldList::create($actions);
170
    }
171
172
    /**
173
     * @param $url
174
     * @return bool
175
     * @throws InvalidUrlException
176
     */
177
    protected function validateUrl($url)
178
    {
179
        if (!Director::is_absolute_url($url)) {
180
            throw new InvalidUrlException(_t(
181
                "SilverStripe\\Forms\\HTMLEditor\\HTMLEditorField_Toolbar.ERROR_ABSOLUTE",
182
                "Only absolute urls can be embedded"
183
            ));
184
        }
185
        $scheme = strtolower(parse_url($url, PHP_URL_SCHEME));
186
        $allowed_schemes = self::config()->get('fileurl_scheme_whitelist');
187
        if (!$scheme || ($allowed_schemes && !in_array($scheme, $allowed_schemes))) {
188
            throw new InvalidUrlException(_t(
189
                "SilverStripe\\Forms\\HTMLEditor\\HTMLEditorField_Toolbar.ERROR_SCHEME",
190
                "This file scheme is not included in the whitelist"
191
            ));
192
        }
193
        $domain = strtolower(parse_url($url, PHP_URL_HOST));
194
        $allowed_domains = self::config()->get('fileurl_domain_whitelist');
195
        if (!$domain || ($allowed_domains && !in_array($domain, $allowed_domains))) {
196
            throw new InvalidUrlException(_t(
197
                "SilverStripe\\Forms\\HTMLEditor\\HTMLEditorField_Toolbar.ERROR_HOSTNAME",
198
                "This file hostname is not included in the whitelist"
199
            ));
200
        }
201
        return true;
202
    }
203
204
    protected function getEmbed($url)
205
    {
206
        $embed = new HTMLEditorField_Embed($url);
207
208
        return $embed;
209
    }
210
}
211