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