Merge remote-tracking branch 'origin/4.1' into 4

# Conflicts:
#	src/Forms/HTMLEditor/HTMLEditorSanitiser.php
#	src/ORM/DataObjectSchema.php
#	src/ORM/Queries/SQLSelect.php
#	src/View/Parsers/ShortcodeParser.php
This commit is contained in:
Damian Mooyman 2018-06-11 10:19:04 +12:00
commit 77a45c0dbc
No known key found for this signature in database
GPG Key ID: 78B823A10DE27D1A
15 changed files with 111 additions and 120 deletions

View File

@ -236,7 +236,7 @@ class InstallConfig
'lv_LV' => 'Latvian (Latvia)', 'lv_LV' => 'Latvian (Latvia)',
'lt_LT' => 'Lithuanian (Lithuania)', 'lt_LT' => 'Lithuanian (Lithuania)',
'ms_MY' => 'Malay (Malaysia)', 'ms_MY' => 'Malay (Malaysia)',
'mi_NZ' => 'Maori (New Zealand)', 'mi_NZ' => 'Māori (New Zealand)',
'ne_NP' => 'Nepali (Nepal)', 'ne_NP' => 'Nepali (Nepal)',
'nb_NO' => 'Norwegian', 'nb_NO' => 'Norwegian',
'fa_IR' => 'Persian (Iran)', 'fa_IR' => 'Persian (Iran)',

View File

@ -22,7 +22,7 @@ class CurrencyField_Disabled extends CurrencyField
{ {
if ($this->value) { if ($this->value) {
$val = Convert::raw2xml($this->value); $val = Convert::raw2xml($this->value);
$val = _t('SilverStripe\\Forms\\CurrencyField.CURRENCYSYMBOL', '$') . number_format(preg_replace('/[^0-9.]/', "", $val), 2); $val = _t('SilverStripe\\Forms\\CurrencyField.CURRENCYSYMBOL', '$') . number_format(preg_replace('/[^0-9.-]/', "", $val), 2);
$valforInput = Convert::raw2att($val); $valforInput = Convert::raw2att($val);
} else { } else {
$valforInput = ''; $valforInput = '';

View File

@ -20,7 +20,7 @@ class CurrencyField_Readonly extends ReadonlyField
{ {
if ($this->value) { if ($this->value) {
$val = Convert::raw2xml($this->value); $val = Convert::raw2xml($this->value);
$val = _t('SilverStripe\\Forms\\CurrencyField.CURRENCYSYMBOL', '$') . number_format(preg_replace('/[^0-9.]/', "", $val), 2); $val = _t('SilverStripe\\Forms\\CurrencyField.CURRENCYSYMBOL', '$') . number_format(preg_replace('/[^0-9.-]/', "", $val), 2);
$valforInput = Convert::raw2att($val); $valforInput = Convert::raw2att($val);
} else { } else {
$val = '<i>' . _t('SilverStripe\\Forms\\CurrencyField.CURRENCYSYMBOL', '$') . '0.00</i>'; $val = '<i>' . _t('SilverStripe\\Forms\\CurrencyField.CURRENCYSYMBOL', '$') . '0.00</i>';

View File

@ -4,7 +4,6 @@ namespace SilverStripe\Forms\HTMLEditor;
use DOMAttr; use DOMAttr;
use DOMElement; use DOMElement;
use DOMNode;
use SilverStripe\Core\Injector\Injectable; use SilverStripe\Core\Injector\Injectable;
use SilverStripe\View\Parsers\HTMLValue; use SilverStripe\View\Parsers\HTMLValue;
use stdClass; use stdClass;
@ -122,8 +121,7 @@ class HTMLEditorSanitiser
// Default value // Default value
if ($prefix) { if ($prefix) {
// Default value if ($prefix === '=') { // Default value
if ($prefix === '=') {
$element->attributesDefault[$attrName] = $value; $element->attributesDefault[$attrName] = $value;
$attr->defaultValue = $value; $attr->defaultValue = $value;
} elseif ($prefix === ':') { } elseif ($prefix === ':') {

View File

@ -176,9 +176,11 @@ class PDOConnector extends DBConnector
if (!isset($charset)) { if (!isset($charset)) {
$charset = $connCharset; $charset = $connCharset;
} }
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $charset . ' COLLATE ' . $connCollation $options = [];
); if ($parameters['driver'] === 'mysql') {
$options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset . ' COLLATE ' . $connCollation;
}
// Set SSL options if they are defined // Set SSL options if they are defined
if (array_key_exists('ssl_key', $parameters) && if (array_key_exists('ssl_key', $parameters) &&

View File

@ -992,10 +992,10 @@ class DataObjectSchema
if (is_array($manyManySpec)) { if (is_array($manyManySpec)) {
$toClass = $this->hasOneComponent($manyManySpec['through'], $manyManySpec['to']); $toClass = $this->hasOneComponent($manyManySpec['through'], $manyManySpec['to']);
if ($toClass === $parentClass) { if ($toClass === $parentClass) {
return $inverseComponentName; return $inverseComponentName;
}
} }
} }
}
return null; return null;
} }

View File

@ -638,7 +638,6 @@ class ShortcodeParser
*/ */
public function parse($content) public function parse($content)
{ {
$this->extend('onBeforeParse', $content); $this->extend('onBeforeParse', $content);
$continue = true; $continue = true;

View File

@ -30,8 +30,11 @@ class DirectorTest extends SapphireTest
parent::setUp(); parent::setUp();
Director::config()->set('alternate_base_url', 'http://www.mysite.com:9090/'); Director::config()->set('alternate_base_url', 'http://www.mysite.com:9090/');
// Ensure redirects enabled on all environments // Ensure redirects enabled on all environments and global state doesn't affect the tests
CanonicalURLMiddleware::singleton()->setEnabledEnvs(true); CanonicalURLMiddleware::singleton()
->setForceSSLDomain(null)
->setForceSSLPatterns([])
->setEnabledEnvs(true);
$this->expectedRedirect = null; $this->expectedRedirect = null;
} }
@ -593,6 +596,7 @@ class DirectorTest extends SapphireTest
}, 'http://www.mysite.com:9090/some-url'); }, 'http://www.mysite.com:9090/some-url');
// Middleware returns non-exception redirect // Middleware returns non-exception redirect
$this->assertInstanceOf(HTTPResponse::class, $response);
$this->assertEquals('https://www.mysite.com:9090/some-url', $response->getHeader('Location')); $this->assertEquals('https://www.mysite.com:9090/some-url', $response->getHeader('Location'));
$this->assertEquals(301, $response->getStatusCode()); $this->assertEquals(301, $response->getStatusCode());
} }

View File

@ -67,23 +67,16 @@ class EmailFieldTest extends FunctionalTest
* *
* @see SimpleTagBuilder::_createInputTag() * @see SimpleTagBuilder::_createInputTag()
*/ */
function testEmailFieldPopulation() public function testEmailFieldPopulation()
{ {
$this->get('EmailFieldTest_Controller'); $this->get('EmailFieldTest_Controller');
$this->submitForm(
$response = $this->submitForm(
'Form_Form', 'Form_Form',
null, null,
array( ['Email' => 'test@test.com']
'Email' => 'test@test.com'
)
); );
$this->assertPartialMatchBySelector( $this->assertContains('Test save was successful', $response->getBody());
'p.good',
array(
'Test save was successful'
)
);
} }
} }

View File

@ -2,33 +2,31 @@
namespace SilverStripe\Forms\Tests; namespace SilverStripe\Forms\Tests;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\Session; use SilverStripe\Control\Session;
use SilverStripe\Core\Config\Config; use SilverStripe\Dev\CSSContentParser;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Forms\DateField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FileField;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\HeaderField;
use SilverStripe\Forms\LookupField;
use SilverStripe\Forms\NumericField;
use SilverStripe\Forms\PasswordField; use SilverStripe\Forms\PasswordField;
use SilverStripe\Forms\Tests\FormTest\TestController;
use SilverStripe\Forms\Tests\FormTest\ControllerWithSecurityToken; use SilverStripe\Forms\Tests\FormTest\ControllerWithSecurityToken;
use SilverStripe\Forms\Tests\FormTest\ControllerWithStrictPostCheck; use SilverStripe\Forms\Tests\FormTest\ControllerWithStrictPostCheck;
use SilverStripe\Forms\Tests\FormTest\Player; use SilverStripe\Forms\Tests\FormTest\Player;
use SilverStripe\Forms\Tests\FormTest\Team; use SilverStripe\Forms\Tests\FormTest\Team;
use SilverStripe\Forms\Tests\FormTest\TestController;
use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\ValidationResult; use SilverStripe\ORM\ValidationResult;
use SilverStripe\Security\NullSecurityToken; use SilverStripe\Security\NullSecurityToken;
use SilverStripe\Security\Security;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Security\RandomGenerator; use SilverStripe\Security\RandomGenerator;
use SilverStripe\Dev\CSSContentParser; use SilverStripe\Security\SecurityToken;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\HeaderField;
use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\DateField;
use SilverStripe\Forms\NumericField;
use SilverStripe\Forms\LookupField;
use SilverStripe\Forms\FileField;
use SilverStripe\Forms\FormAction;
use SilverStripe\View\SSViewer; use SilverStripe\View\SSViewer;
/** /**
@ -50,6 +48,8 @@ class FormTest extends FunctionalTest
ControllerWithStrictPostCheck::class, ControllerWithStrictPostCheck::class,
]; ];
protected static $disable_themes = true;
protected function setUp() protected function setUp()
{ {
parent::setUp(); parent::setUp();

View File

@ -2,20 +2,19 @@
namespace SilverStripe\Forms\Tests\GridField; namespace SilverStripe\Forms\Tests\GridField;
use SilverStripe\Dev\CSSContentParser;
use SilverStripe\Dev\Debug;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Control\Controller; use SilverStripe\Control\Controller;
use SilverStripe\Forms\HiddenField; use SilverStripe\Dev\CSSContentParser;
use SilverStripe\Forms\GridField\GridFieldDetailForm; use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldDetailForm;
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest; use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
use SilverStripe\Forms\HiddenField;
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Category; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Category;
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\CategoryController; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\CategoryController;
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController;
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\GroupController; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\GroupController;
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PeopleGroup; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PeopleGroup;
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person; use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person;
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController;
/** /**
* @skipUpgrade * @skipUpgrade
@ -36,6 +35,8 @@ class GridFieldDetailFormTest extends FunctionalTest
GroupController::class, GroupController::class,
]; ];
protected static $disable_themes = true;
public function testValidator() public function testValidator()
{ {
$this->logInWithPermission('ADMIN'); $this->logInWithPermission('ADMIN');

View File

@ -5,90 +5,85 @@ namespace SilverStripe\Forms\Tests;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\LookupField; use SilverStripe\Forms\LookupField;
use SilverStripe\Security\Member;
class LookupFieldTest extends SapphireTest class LookupFieldTest extends SapphireTest
{ {
protected static $fixture_file = 'LookupFieldTest.yml'; protected static $fixture_file = 'LookupFieldTest.yml';
public function testNullValueWithNumericArraySource() public function testNullValueWithNumericArraySource()
{ {
$source = array(1 => 'one', 2 => 'two', 3 => 'three'); $source = array(1 => 'one', 2 => 'two', 3 => 'three');
$f = new LookupField('test', 'test', $source); $field = new LookupField('test', 'test', $source);
$f->setValue(null); $field->setValue(null);
$result = trim($field->Field()->getValue());
$this->assertEquals( $this->assertContains('<span class="readonly" id="test"><i>(none)</i></span>', $result);
'<span class="readonly" id="test"><i>(none)</i></span><input type="hidden" name="test" value="" />', $this->assertContains('<input type="hidden" name="test" value="" />', $result);
trim($f->Field()->getValue())
);
} }
public function testStringValueWithNumericArraySource() public function testStringValueWithNumericArraySource()
{ {
$source = array(1 => 'one', 2 => 'two', 3 => 'three'); $source = array(1 => 'one', 2 => 'two', 3 => 'three');
$f = new LookupField('test', 'test', $source); $field = new LookupField('test', 'test', $source);
$f->setValue(1); $field->setValue(1);
$this->assertEquals( $result = trim($field->Field()->getValue());
'<span class="readonly" id="test">one</span><input type="hidden" name="test" value="1" />', $this->assertContains('<span class="readonly" id="test">one</span>', $result);
trim($f->Field()->getValue()) $this->assertContains('<input type="hidden" name="test" value="1" />', $result);
);
} }
public function testUnknownStringValueWithNumericArraySource() public function testUnknownStringValueWithNumericArraySource()
{ {
$source = array(1 => 'one', 2 => 'two', 3 => 'three'); $source = array(1 => 'one', 2 => 'two', 3 => 'three');
$f = new LookupField('test', 'test', $source); $field = new LookupField('test', 'test', $source);
$f->setValue('w00t'); $field->setValue('w00t');
$this->assertEquals( $result = trim($field->Field()->getValue());
'<span class="readonly" id="test">w00t</span><input type="hidden" name="test" value="" />',
trim($f->Field()->getValue()) $this->assertContains('<span class="readonly" id="test">w00t</span>', $result);
); $this->assertContains('<input type="hidden" name="test" value="" />', $result);
} }
public function testArrayValueWithAssociativeArraySource() public function testArrayValueWithAssociativeArraySource()
{ {
// Array values (= multiple selections) might be set e.g. from ListboxField // Array values (= multiple selections) might be set e.g. from ListboxField
$source = array('one' => 'one val', 'two' => 'two val', 'three' => 'three val'); $source = array('one' => 'one val', 'two' => 'two val', 'three' => 'three val');
$f = new LookupField('test', 'test', $source); $field = new LookupField('test', 'test', $source);
$f->setValue(array('one','two')); $field->setValue(array('one','two'));
$this->assertEquals( $result = trim($field->Field()->getValue());
'<span class="readonly" id="test">one val, two val</span>'
. '<input type="hidden" name="test" value="one, two" />', $this->assertContains('<span class="readonly" id="test">one val, two val</span>', $result);
trim($f->Field()->getValue()) $this->assertContains('<input type="hidden" name="test" value="one, two" />', $result);
);
} }
public function testArrayValueWithNumericArraySource() public function testArrayValueWithNumericArraySource()
{ {
// Array values (= multiple selections) might be set e.g. from ListboxField // Array values (= multiple selections) might be set e.g. from ListboxField
$source = array(1 => 'one', 2 => 'two', 3 => 'three'); $source = array(1 => 'one', 2 => 'two', 3 => 'three');
$f = new LookupField('test', 'test', $source); $field = new LookupField('test', 'test', $source);
$f->setValue(array(1,2)); $field->setValue(array(1,2));
$this->assertEquals( $result = trim($field->Field()->getValue());
'<span class="readonly" id="test">one, two</span><input type="hidden" name="test" value="1, 2" />',
trim($f->Field()->getValue()) $this->assertContains('<span class="readonly" id="test">one, two</span>', $result);
); $this->assertContains('<input type="hidden" name="test" value="1, 2" />', $result);
} }
public function testArrayValueWithSqlMapSource() public function testArrayValueWithSqlMapSource()
{ {
$member1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member1'); $member1 = $this->objFromFixture(Member::class, 'member1');
$member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member2'); $member2 = $this->objFromFixture(Member::class, 'member2');
$member3 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member3'); $member3 = $this->objFromFixture(Member::class, 'member3');
$source = DataObject::get('SilverStripe\\Security\\Member'); $source = DataObject::get(Member::class);
$f = new LookupField('test', 'test', $source->map('ID', 'FirstName')); $field = new LookupField('test', 'test', $source->map('ID', 'FirstName'));
$f->setValue(array($member1->ID, $member2->ID)); $field->setValue(array($member1->ID, $member2->ID));
$result = trim($field->Field()->getValue());
$this->assertEquals( $this->assertContains('<span class="readonly" id="test">member1, member2</span>', $result);
sprintf( $this->assertContains(sprintf(
'<span class="readonly" id="test">member1, member2</span>' '<input type="hidden" name="test" value="%s, %s" />',
. '<input type="hidden" name="test" value="%s, %s" />', $member1->ID,
$member1->ID, $member2->ID
$member2->ID ), $result);
),
trim($f->Field()->getValue())
);
} }
public function testWithMultiDimensionalSource() public function testWithMultiDimensionalSource()
@ -105,23 +100,17 @@ class LookupFieldTest extends SapphireTest
) )
); );
$f = new LookupField('test', 'test', $choices); $field = new LookupField('test', 'test', $choices);
$f->setValue(3); $field->setValue(3);
$result = trim($field->Field()->getValue());
$this->assertEquals( $this->assertContains('<span class="readonly" id="test">Carrots</span>', $result);
'<span class="readonly" id="test">Carrots</span><input type="hidden" name="test" value="3" />', $this->assertContains('<input type="hidden" name="test" value="3" />', $result);
trim($f->Field()->getValue())
);
$f->setValue( $field->setValue([3, 9]);
array( $result = trim($field->Field()->getValue());
3, 9
)
);
$this->assertEquals( $this->assertContains('<span class="readonly" id="test">Carrots, Vegan</span>', $result);
'<span class="readonly" id="test">Carrots, Vegan</span><input type="hidden" name="test" value="3, 9" />', $this->assertContains('<input type="hidden" name="test" value="3, 9" />', $result);
trim($f->Field()->getValue())
);
} }
} }

View File

@ -58,6 +58,7 @@ class SelectionGroupTest extends SapphireTest
$field->setValue('two'); $field->setValue('two');
$parser = new CSSContentParser($field->FieldHolder()); $parser = new CSSContentParser($field->FieldHolder());
$listEls = $parser->getBySelector('li'); $listEls = $parser->getBySelector('li');
$listElOne = $listEls[0]; $listElOne = $listEls[0];
$listElTwo = $listEls[1]; $listElTwo = $listEls[1];

View File

@ -196,15 +196,17 @@ class TreeDropdownFieldTest extends SapphireTest
public function testReadonly() public function testReadonly()
{ {
$field = new TreeDropdownField('TestTree', 'Test tree', File::class); $field = new TreeDropdownField('TestTree', 'Test tree', File::class);
$asdf = $this->objFromFixture(File::class, 'asdf'); $fileMock = $this->objFromFixture(File::class, 'asdf');
$field->setValue($asdf->ID); $field->setValue($fileMock->ID);
$readonlyField = $field->performReadonlyTransformation(); $readonlyField = $field->performReadonlyTransformation();
$this->assertEquals( $result = (string) $readonlyField->Field();
<<<"HTML" $this->assertContains(
<span class="readonly" id="TestTree">&lt;Special &amp; characters&gt;</span><input type="hidden" name="TestTree" value="{$asdf->ID}" /> '<span class="readonly" id="TestTree">&lt;Special &amp; characters&gt;</span>',
HTML $result
, );
(string)$readonlyField->Field() $this->assertContains(
'<input type="hidden" name="TestTree" value="' . $fileMock->ID . '" />',
$result
); );
} }
} }

View File

@ -30,4 +30,6 @@ class Dingo extends DataObject implements TestOnly
private static $belongs_many_many = [ private static $belongs_many_many = [
'Parents' => Dingo::class, 'Parents' => Dingo::class,
]; ];
private static $default_sort = '"ID" ASC';
} }