Merge pull request #9 from helpfulrobot/convert-to-psr-2

Converted to PSR-2
This commit is contained in:
Damian Mooyman 2015-11-20 12:47:25 +13:00
commit 7c541975a8
2 changed files with 221 additions and 207 deletions

View File

@ -4,120 +4,128 @@
* CMS editor can choose width, height, or set it to attempt automatic size configuration. * CMS editor can choose width, height, or set it to attempt automatic size configuration.
*/ */
class IFramePage extends Page { class IFramePage extends Page
static $db = array( {
'IFrameURL' => 'Text', public static $db = array(
'AutoHeight' => 'Boolean(1)', 'IFrameURL' => 'Text',
'AutoWidth' => 'Boolean(1)', 'AutoHeight' => 'Boolean(1)',
'FixedHeight' => 'Int(500)', 'AutoWidth' => 'Boolean(1)',
'FixedWidth' => 'Int(0)', 'FixedHeight' => 'Int(500)',
'AlternateContent' => 'HTMLText', 'FixedWidth' => 'Int(0)',
'BottomContent' => 'HTMLText', 'AlternateContent' => 'HTMLText',
'ForceProtocol' => 'Varchar', 'BottomContent' => 'HTMLText',
); 'ForceProtocol' => 'Varchar',
);
static $defaults = array( public static $defaults = array(
'AutoHeight' => '1', 'AutoHeight' => '1',
'AutoWidth' => '1', 'AutoWidth' => '1',
'FixedHeight' => '500', 'FixedHeight' => '500',
'FixedWidth' => '0' 'FixedWidth' => '0'
); );
static $description = 'Embeds an iframe into the body of the page.'; public static $description = 'Embeds an iframe into the body of the page.';
function getCMSFields() { public function getCMSFields()
$fields = parent::getCMSFields(); {
$fields = parent::getCMSFields();
$fields->removeFieldFromTab('Root.Main', 'Content'); $fields->removeFieldFromTab('Root.Main', 'Content');
$fields->addFieldToTab('Root.Main', $url = new TextField('IFrameURL', 'Iframe URL'), 'Metadata'); $fields->addFieldToTab('Root.Main', $url = new TextField('IFrameURL', 'Iframe URL'), 'Metadata');
$url->setRightTitle('Can be absolute (<em>http://silverstripe.com</em>) or relative to this site (<em>about-us</em>).'); $url->setRightTitle('Can be absolute (<em>http://silverstripe.com</em>) or relative to this site (<em>about-us</em>).');
$fields->addFieldToTab( $fields->addFieldToTab(
'Root.Main', 'Root.Main',
DropdownField::create('ForceProtocol', 'Force protocol?') DropdownField::create('ForceProtocol', 'Force protocol?')
->setSource(array('http://' => 'http://', 'https://' => 'https://')) ->setSource(array('http://' => 'http://', 'https://' => 'https://'))
->setEmptyString('') ->setEmptyString('')
->setDescription('Avoids mixed content warnings when iframe content is just available under a specific protocol'), ->setDescription('Avoids mixed content warnings when iframe content is just available under a specific protocol'),
'Metadata' 'Metadata'
); );
$fields->addFieldToTab('Root.Main', new CheckboxField('AutoHeight', 'Auto height (only works with same domain URLs)'), 'Metadata'); $fields->addFieldToTab('Root.Main', new CheckboxField('AutoHeight', 'Auto height (only works with same domain URLs)'), 'Metadata');
$fields->addFieldToTab('Root.Main', new CheckboxField('AutoWidth', 'Auto width (100% of the available space)'), 'Metadata'); $fields->addFieldToTab('Root.Main', new CheckboxField('AutoWidth', 'Auto width (100% of the available space)'), 'Metadata');
$fields->addFieldToTab('Root.Main', new NumericField('FixedHeight', 'Fixed height (in pixels)'), 'Metadata'); $fields->addFieldToTab('Root.Main', new NumericField('FixedHeight', 'Fixed height (in pixels)'), 'Metadata');
$fields->addFieldToTab('Root.Main', new NumericField('FixedWidth', 'Fixed width (in pixels)'), 'Metadata'); $fields->addFieldToTab('Root.Main', new NumericField('FixedWidth', 'Fixed width (in pixels)'), 'Metadata');
$fields->addFieldToTab('Root.Main', new HtmlEditorField('Content', 'Content (appears above iframe)'), 'Metadata'); $fields->addFieldToTab('Root.Main', new HtmlEditorField('Content', 'Content (appears above iframe)'), 'Metadata');
$fields->addFieldToTab('Root.Main', new HtmlEditorField('BottomContent', 'Content (appears below iframe)'), 'Metadata'); $fields->addFieldToTab('Root.Main', new HtmlEditorField('BottomContent', 'Content (appears below iframe)'), 'Metadata');
$fields->addFieldToTab('Root.Main', new HtmlEditorField('AlternateContent', 'Alternate Content (appears when user has iframes disabled)'), 'Metadata'); $fields->addFieldToTab('Root.Main', new HtmlEditorField('AlternateContent', 'Alternate Content (appears when user has iframes disabled)'), 'Metadata');
return $fields; return $fields;
} }
/** /**
* Compute class from the size parameters. * Compute class from the size parameters.
*/ */
function getClass() { public function getClass()
$class = ''; {
if ($this->AutoHeight) { $class = '';
$class .= 'iframepage-height-auto'; if ($this->AutoHeight) {
} $class .= 'iframepage-height-auto';
}
return $class; return $class;
} }
/** /**
* Compute style from the size parameters. * Compute style from the size parameters.
*/ */
function getStyle() { public function getStyle()
$style = ''; {
$style = '';
// Always add fixed height as a fallback if autosetting or JS fails. // Always add fixed height as a fallback if autosetting or JS fails.
$height = $this->FixedHeight; $height = $this->FixedHeight;
if (!$height) $height = 800; if (!$height) {
$style .= "height: {$height}px; "; $height = 800;
}
$style .= "height: {$height}px; ";
if ($this->AutoWidth) { if ($this->AutoWidth) {
$style .= "width: 100%; "; $style .= "width: 100%; ";
} } elseif ($this->FixedWidth) {
else if ($this->FixedWidth) { $style .= "width: {$this->FixedWidth}px; ";
$style .= "width: {$this->FixedWidth}px; "; }
}
return $style; return $style;
} }
/** /**
* Ensure that the IFrameURL is a valid url and prevents XSS * Ensure that the IFrameURL is a valid url and prevents XSS
* *
* @throws ValidationException * @throws ValidationException
* @return ValidationResult * @return ValidationResult
*/ */
public function validate() { public function validate()
$result = parent::validate(); {
$result = parent::validate();
//whitelist allowed URL schemes //whitelist allowed URL schemes
$allowed_schemes = array('http', 'https'); $allowed_schemes = array('http', 'https');
if($matches = parse_url($this->IFrameURL)) { if ($matches = parse_url($this->IFrameURL)) {
if(isset($matches['scheme']) && !in_array($matches['scheme'], $allowed_schemes)) { if (isset($matches['scheme']) && !in_array($matches['scheme'], $allowed_schemes)) {
$result->error(_t('IFramePage.VALIDATION.BANNEDURLSCHEME', "This URL scheme is not allowed.")); $result->error(_t('IFramePage.VALIDATION.BANNEDURLSCHEME', "This URL scheme is not allowed."));
} }
} }
return $result; return $result;
} }
} }
class IFramePage_Controller extends Page_Controller { class IFramePage_Controller extends Page_Controller
function init() { {
parent::init(); public function init()
{
parent::init();
if($this->ForceProtocol) { if ($this->ForceProtocol) {
if($this->ForceProtocol == 'http://' && Director::protocol() != 'http://') { if ($this->ForceProtocol == 'http://' && Director::protocol() != 'http://') {
return $this->redirect(preg_replace('#https://#', 'http://', $this->AbsoluteLink())); return $this->redirect(preg_replace('#https://#', 'http://', $this->AbsoluteLink()));
} else if($this->ForceProtocol == 'https://' && Director::protocol() != 'https://') { } elseif ($this->ForceProtocol == 'https://' && Director::protocol() != 'https://') {
return $this->redirect(preg_replace('#http://#', 'https://', $this->AbsoluteLink())); return $this->redirect(preg_replace('#http://#', 'https://', $this->AbsoluteLink()));
} }
} }
if ($this->IFrameURL) { if ($this->IFrameURL) {
Requirements::javascript('iframe/javascript/iframe_page.js'); Requirements::javascript('iframe/javascript/iframe_page.js');
} }
} }
} }

View File

@ -1,133 +1,139 @@
<?php <?php
class IFramePageTest extends SapphireTest { class IFramePageTest extends SapphireTest
{
public function setUp()
{
parent::setUp();
Config::nest();
}
public function setUp() { public function tearDown()
parent::setUp(); {
Config::nest(); Config::unnest();
} parent::tearDown();
}
public function tearDown() { public function testGetClass()
Config::unnest(); {
parent::tearDown(); $iframe = new IFramePage();
} $iframe->AutoHeight = 1;
$iframe->getClass();
function testGetClass() { $this->assertContains('iframepage-height-auto', $iframe->getClass());
$iframe = new IFramePage();
$iframe->AutoHeight = 1;
$iframe->getClass();
$this->assertContains('iframepage-height-auto', $iframe->getClass()); $iframe->AutoHeight = 0;
$iframe->getClass();
$iframe->AutoHeight = 0; $this->assertNotContains('iframepage-height-auto', $iframe->getClass());
$iframe->getClass(); }
$this->assertNotContains('iframepage-height-auto', $iframe->getClass()); public function testGetStyle()
} {
$iframe = new IFramePage();
function testGetStyle() { $iframe->FixedHeight = 0;
$iframe = new IFramePage(); $iframe->getStyle();
$this->assertContains('height: 800px', $iframe->getStyle(), 'Height defaults to 800 if not set.');
$iframe->FixedHeight = 0; $iframe->FixedHeight = 100;
$iframe->getStyle(); $iframe->getStyle();
$this->assertContains('height: 800px', $iframe->getStyle(), 'Height defaults to 800 if not set.'); $this->assertContains('height: 100px', $iframe->getStyle(), 'Fixed height is settable');
$iframe->FixedHeight = 100; $iframe->AutoWidth = 1;
$iframe->getStyle(); $iframe->FixedWidth = '200';
$this->assertContains('height: 100px', $iframe->getStyle(), 'Fixed height is settable'); $this->assertContains('width: 100%', $iframe->getStyle(), 'Auto width overrides fixed width');
$iframe->AutoWidth = 1; $iframe->AutoWidth = 0;
$iframe->FixedWidth = '200'; $iframe->FixedWidth = '200';
$this->assertContains('width: 100%', $iframe->getStyle(), 'Auto width overrides fixed width'); $this->assertContains('width: 200px', $iframe->getStyle(), 'Fixed width is settable');
}
$iframe->AutoWidth = 0; public function testAllowedUrls()
$iframe->FixedWidth = '200'; {
$this->assertContains('width: 200px', $iframe->getStyle(), 'Fixed width is settable'); $iframe = new IFramePage();
}
function testAllowedUrls() { $tests = array(
$iframe = new IFramePage(); 'allowed' => array(
'http://anything',
'https://anything',
'page',
'sub-page/link',
'page/link',
'page.html',
'page.htm',
'page.phpissoawesomewhywouldiuseanythingelse',
'//url.com/page',
'/root/page/link',
'http://intranet:8888',
'http://javascript:8080',
'http://username:password@hostname/path?arg=value#anchor'
),
'banned' => array(
'javascript:alert',
'tel:0210001234',
'ftp://url',
'ssh://1.2.3.4',
'ssh://url.com/page'
)
);
$tests = array( foreach ($tests['allowed'] as $url) {
'allowed' => array( $iframe->IFrameURL = $url;
'http://anything', $iframe->write();
'https://anything', $this->assertContains($iframe->IFrameURL, $url);
'page', }
'sub-page/link',
'page/link',
'page.html',
'page.htm',
'page.phpissoawesomewhywouldiuseanythingelse',
'//url.com/page',
'/root/page/link',
'http://intranet:8888',
'http://javascript:8080',
'http://username:password@hostname/path?arg=value#anchor'
),
'banned' => array(
'javascript:alert',
'tel:0210001234',
'ftp://url',
'ssh://1.2.3.4',
'ssh://url.com/page'
)
);
foreach($tests['allowed'] as $url) { foreach ($tests['banned'] as $url) {
$iframe->IFrameURL = $url; $iframe->IFrameURL = $url;
$iframe->write(); $this->setExpectedException('ValidationException');
$this->assertContains($iframe->IFrameURL, $url); $iframe->write();
} }
}
foreach($tests['banned'] as $url) { public function testForceProtocol()
$iframe->IFrameURL = $url; {
$this->setExpectedException('ValidationException'); $origServer = $_SERVER;
$iframe->write();
}
}
public function testForceProtocol() { $page = new IFramePage();
$origServer = $_SERVER; $page->URLSegment = 'iframe';
$page->IFrameURL = 'http://target.com';
$page = new IFramePage(); Config::inst()->update('Director', 'alternate_protocol', 'http');
$page->URLSegment = 'iframe'; Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
$page->IFrameURL = 'http://target.com'; $page->ForceProtocol = '';
$controller = new IFramePage_Controller($page);
$response = $controller->init();
$this->assertNull($response);
Config::inst()->update('Director', 'alternate_protocol', 'http'); Config::inst()->update('Director', 'alternate_protocol', 'https');
Config::inst()->update('Director', 'alternate_base_url', 'http://host.com'); Config::inst()->update('Director', 'alternate_base_url', 'https://host.com');
$page->ForceProtocol = ''; $page->ForceProtocol = '';
$controller = new IFramePage_Controller($page); $controller = new IFramePage_Controller($page);
$response = $controller->init(); $response = $controller->init();
$this->assertNull($response); $this->assertNull($response);
Config::inst()->update('Director', 'alternate_protocol', 'https'); Config::inst()->update('Director', 'alternate_protocol', 'http');
Config::inst()->update('Director', 'alternate_base_url', 'https://host.com'); Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
$page->ForceProtocol = ''; $page->ForceProtocol = 'http://';
$controller = new IFramePage_Controller($page); $controller = new IFramePage_Controller($page);
$response = $controller->init(); $response = $controller->init();
$this->assertNull($response); $this->assertNull($response);
Config::inst()->update('Director', 'alternate_protocol', 'http'); Config::inst()->update('Director', 'alternate_protocol', 'http');
Config::inst()->update('Director', 'alternate_base_url', 'http://host.com'); Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
$page->ForceProtocol = 'http://'; $page->ForceProtocol = 'https://';
$controller = new IFramePage_Controller($page); $controller = new IFramePage_Controller($page);
$response = $controller->init(); $response = $controller->init();
$this->assertNull($response); $this->assertEquals($response->getHeader('Location'), 'https://host.com/iframe/');
Config::inst()->update('Director', 'alternate_protocol', 'http'); Config::inst()->update('Director', 'alternate_protocol', 'https');
Config::inst()->update('Director', 'alternate_base_url', 'http://host.com'); Config::inst()->update('Director', 'alternate_base_url', 'https://host.com');
$page->ForceProtocol = 'https://'; $page->ForceProtocol = 'http://';
$controller = new IFramePage_Controller($page); $controller = new IFramePage_Controller($page);
$response = $controller->init(); $response = $controller->init();
$this->assertEquals($response->getHeader('Location'), 'https://host.com/iframe/'); $this->assertEquals($response->getHeader('Location'), 'http://host.com/iframe/');
Config::inst()->update('Director', 'alternate_protocol', 'https'); $_SERVER = $origServer;
Config::inst()->update('Director', 'alternate_base_url', 'https://host.com'); }
$page->ForceProtocol = 'http://';
$controller = new IFramePage_Controller($page);
$response = $controller->init();
$this->assertEquals($response->getHeader('Location'), 'http://host.com/iframe/');
$_SERVER = $origServer;
}
} }