Issues (8)

src/IFramePage.php (6 issues)

1
<?php
2
3
namespace SilverStripe\IFrame;
4
5
use Page;
0 ignored issues
show
The type Page was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Forms\TextField;
7
use SilverStripe\Forms\DropdownField;
8
use SilverStripe\Forms\CheckboxField;
9
use SilverStripe\Forms\NumericField;
10
use SilverStripe\Forms\HTMLEditor\HtmlEditorField;
11
use SilverStripe\ORM\FieldType\DBField;
12
use SilverStripe\ORM\ValidationException;
13
use SilverStripe\ORM\ValidationResult;
14
15
/**
16
 * Iframe page type embeds an iframe of URL of choice into the page.
17
 * CMS editor can choose width, height, or set it to attempt automatic size configuration.
18
 */
19
20
class IFramePage extends Page
21
{
22
    private static $db = array(
0 ignored issues
show
The private property $db is not used, and could be removed.
Loading history...
23
        'IFrameURL' => 'Text',
24
        'IFrameTitle' => 'Varchar',
25
        'AutoHeight' => 'Boolean(1)',
26
        'AutoWidth' => 'Boolean(1)',
27
        'FixedHeight' => 'Int(500)',
28
        'FixedWidth' => 'Int(0)',
29
        'AlternateContent' => 'HTMLText',
30
        'BottomContent' => 'HTMLText',
31
        'ForceProtocol' => 'Varchar',
32
    );
33
34
    private static $defaults = array(
0 ignored issues
show
The private property $defaults is not used, and could be removed.
Loading history...
35
        'AutoHeight' => '1',
36
        'AutoWidth' => '1',
37
        'FixedHeight' => '500',
38
        'FixedWidth' => '0'
39
    );
40
41
    private static $table_name = 'IFramePage';
0 ignored issues
show
The private property $table_name is not used, and could be removed.
Loading history...
42
43
    private static $description = 'Embeds an iframe into the body of the page.';
0 ignored issues
show
The private property $description is not used, and could be removed.
Loading history...
44
45
    private static $singular_name = 'IFrame Page';
0 ignored issues
show
The private property $singular_name is not used, and could be removed.
Loading history...
46
47
    public function getCMSFields()
48
    {
49
        $fields = parent::getCMSFields();
50
51
        $fields->removeFieldFromTab('Root.Main', 'Content');
52
        $fields->addFieldsToTab('Root.Main', [
53
            $url = TextField::create('IFrameURL', 'Iframe URL'),
54
            TextField::create('IFrameTitle', 'Description of contents (title)')
55
                ->setDescription(_t(__CLASS__ . '.TITLE_DESCRIPTION', 'Used by screen readers')),
56
        ]);
57
        $url->setRightTitle(
58
            DBField::create_field(
59
                'HTMLText',
60
                'Can be absolute (<em>http://silverstripe.com</em>) or relative to this site (<em>about-us</em>).'
61
            )
62
        );
63
        $fields->addFieldToTab(
64
            'Root.Main',
65
            DropdownField::create('ForceProtocol', 'Force protocol?')
66
                ->setSource(array('http://' => 'http://', 'https://' => 'https://'))
67
                ->setEmptyString('')
68
                ->setDescription(
69
                    'Avoids mixed content warnings when iframe content is just available under a specific protocol'
70
                ),
71
            'Metadata'
72
        );
73
        $fields->addFieldsToTab('Root.Main', [
74
            CheckboxField::create('AutoHeight', 'Auto height (only works with same domain URLs)'),
75
            CheckboxField::create('AutoWidth', 'Auto width (100% of the available space)'),
76
            NumericField::create('FixedHeight', 'Fixed height (in pixels)'),
77
            NumericField::create('FixedWidth', 'Fixed width (in pixels)'),
78
            HtmlEditorField::create('Content', 'Content (appears above iframe)'),
79
            HtmlEditorField::create('BottomContent', 'Content (appears below iframe)'),
80
            HtmlEditorField::create('AlternateContent', 'Alternate Content (appears when user has iframes disabled)')
81
        ]);
82
83
        // Move the Metadata field to last position, but make a check for it's
84
        // existence first.
85
        //
86
        // See https://github.com/silverstripe-labs/silverstripe-iframe/issues/18
87
        $mainTab = $fields->findOrMakeTab('Root.Main');
88
        $mainTabFields = $mainTab->FieldList();
89
        $metaDataField = $mainTabFields->fieldByName('Metadata');
90
        if ($metaDataField) {
91
            $mainTabFields->removeByName('Metadata');
92
            $mainTabFields->push($metaDataField);
93
        }
94
        return $fields;
95
    }
96
97
    /**
98
     * Compute class from the size parameters.
99
     */
100
    public function getClass()
101
    {
102
        $class = '';
103
        if ($this->AutoHeight) {
104
            $class .= 'iframepage-height-auto';
105
        }
106
107
        return $class;
108
    }
109
110
    /**
111
     * Compute style from the size parameters.
112
     */
113
    public function getStyle()
114
    {
115
        $style = '';
116
117
        // Always add fixed height as a fallback if autosetting or JS fails.
118
        $height = $this->FixedHeight;
119
        if (!$height) {
120
            $height = 800;
121
        }
122
        $style .= "height: {$height}px; ";
123
124
        if ($this->AutoWidth) {
125
            $style .= "width: 100%; ";
126
        } elseif ($this->FixedWidth) {
127
            $style .= "width: {$this->FixedWidth}px; ";
128
        }
129
130
        return $style;
131
    }
132
133
    /**
134
     * Ensure that the IFrameURL is a valid url and prevents XSS
135
     *
136
     * @throws ValidationException
137
     * @return ValidationResult
138
     */
139
    public function validate()
140
    {
141
        $result = parent::validate();
142
143
        //whitelist allowed URL schemes
144
        $allowed_schemes = array('http', 'https');
145
        if ($matches = parse_url($this->IFrameURL)) {
146
            if (isset($matches['scheme']) && !in_array($matches['scheme'], $allowed_schemes)) {
147
                $result->addError(_t(__CLASS__ . '.VALIDATION_BANNEDURLSCHEME', "This URL scheme is not allowed."));
148
            }
149
        }
150
151
        return $result;
152
    }
153
}
154