Merge remote-tracking branch 'origin/3.5' into 3.6

This commit is contained in:
Damian Mooyman 2017-12-06 17:21:09 +13:00
commit 91cf85087b
No known key found for this signature in database
GPG Key ID: 78B823A10DE27D1A
19 changed files with 75 additions and 54 deletions

View File

@ -23,10 +23,13 @@ class CMSBatchActionHandler extends RequestHandler {
'handleConfirmation', 'handleConfirmation',
); );
/**
* @var Controller
*/
protected $parentController; protected $parentController;
/** /**
* @var String * @var string
*/ */
protected $urlSegment; protected $urlSegment;
@ -38,7 +41,7 @@ class CMSBatchActionHandler extends RequestHandler {
protected $recordClass = 'SiteTree'; protected $recordClass = 'SiteTree';
/** /**
* @param string $parentController * @param Controller $parentController
* @param string $urlSegment * @param string $urlSegment
* @param string $recordClass * @param string $recordClass
*/ */

View File

@ -41,7 +41,7 @@ class CMSMenuItem extends Object {
* Attributes for the link. For instance, custom data attributes or standard * Attributes for the link. For instance, custom data attributes or standard
* HTML anchor properties. * HTML anchor properties.
* *
* @var string * @var array
*/ */
protected $attributes = array(); protected $attributes = array();

View File

@ -398,7 +398,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
Requirements::css(FRAMEWORK_DIR . '/css/GridField.css'); Requirements::css(FRAMEWORK_DIR . '/css/GridField.css');
// Browser-specific requirements // Browser-specific requirements
$ie = isset($_SERVER['HTTP_USER_AGENT']) ? strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') : false; $ie = isset($_SERVER['HTTP_USER_AGENT']) ? strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false : false;
if($ie) { if($ie) {
$version = substr($_SERVER['HTTP_USER_AGENT'], $ie + 5, 3); $version = substr($_SERVER['HTTP_USER_AGENT'], $ie + 5, 3);
@ -1838,6 +1838,16 @@ class LeftAndMainMarkingFilter {
*/ */
protected $params = array(); protected $params = array();
/**
* @var array
*/
public $ids = array();
/**
* @var array
*/
public $expanded = array();
/** /**
* @param array $params Request params (unsanitized) * @param array $params Request params (unsanitized)
*/ */

View File

@ -171,7 +171,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
$groupsTab->addExtraClass('ui-state-active'); $groupsTab->addExtraClass('ui-state-active');
} elseif($actionParam == 'users') { } elseif($actionParam == 'users') {
$usersTab->addExtraClass('ui-state-active'); $usersTab->addExtraClass('ui-state-active');
} elseif($actionParam == 'roles') { } elseif($actionParam == 'roles' && isset($rolesTab)) {
$rolesTab->addExtraClass('ui-state-active'); $rolesTab->addExtraClass('ui-state-active');
} }

View File

@ -1334,7 +1334,6 @@ jQuery.noConflict();
} }
var container = this.closest('.cms-container'); var container = this.closest('.cms-container');
container.find('.cms-edit-form').tabs('select',0); //always switch to the first tab (list view) when searching
container.loadPanel(url, "", {}, true); container.loadPanel(url, "", {}, true);
return false; return false;

View File

@ -173,7 +173,9 @@ class LeftAndMainTest extends FunctionalTest {
$adminuser = $this->objFromFixture('Member', 'admin'); $adminuser = $this->objFromFixture('Member', 'admin');
$securityonlyuser = $this->objFromFixture('Member', 'securityonlyuser'); $securityonlyuser = $this->objFromFixture('Member', 'securityonlyuser');
$allcmssectionsuser = $this->objFromFixture('Member', 'allcmssectionsuser'); $allcmssectionsuser = $this->objFromFixture('Member', 'allcmssectionsuser');
$allValsFn = create_function('$obj', 'return $obj->getValue();'); $allValsFn = function($obj) {
return $obj->getValue();
};
// anonymous user // anonymous user
$this->session()->inst_set('loggedInAs', null); $this->session()->inst_set('loggedInAs', null);

View File

@ -373,7 +373,9 @@ class RestfulService extends ViewableData implements Flushable {
if( preg_match('/([^:]+): (.+)/m', $field, $match) ) { if( preg_match('/([^:]+): (.+)/m', $field, $match) ) {
$match[1] = preg_replace_callback( $match[1] = preg_replace_callback(
'/(?<=^|[\x09\x20\x2D])./', '/(?<=^|[\x09\x20\x2D])./',
create_function('$matches', 'return strtoupper($matches[0]);'), function($matches) {
return strtoupper($matches[0]);
},
trim($match[1]) trim($match[1])
); );
if( isset($headers[$match[1]]) ) { if( isset($headers[$match[1]]) ) {
@ -418,7 +420,7 @@ class RestfulService extends ViewableData implements Flushable {
if($element) if($element)
$childElements = $xml->{$collection}->{$element}; $childElements = $xml->{$collection}->{$element};
if($childElements){ if(isset($childElements) && $childElements){
foreach($childElements as $child){ foreach($childElements as $child){
$data = array(); $data = array();
foreach($child->attributes() as $key => $value){ foreach($child->attributes() as $key => $value){
@ -448,7 +450,7 @@ class RestfulService extends ViewableData implements Flushable {
if($element) if($element)
$childElements = $xml->{$collection}->{$element}; $childElements = $xml->{$collection}->{$element};
if($childElements) if(isset($childElements[$attr]))
$attr_value = (string) $childElements[$attr]; $attr_value = (string) $childElements[$attr];
return Convert::raw2xml($attr_value); return Convert::raw2xml($attr_value);
@ -474,7 +476,7 @@ class RestfulService extends ViewableData implements Flushable {
if($element) if($element)
$childElements = $xml->{$collection}->{$element}; $childElements = $xml->{$collection}->{$element};
if($childElements){ if(isset($childElements) && $childElements){
foreach($childElements as $child){ foreach($childElements as $child){
$data = array(); $data = array();
$this->getRecurseValues($child,$data); $this->getRecurseValues($child,$data);
@ -523,7 +525,7 @@ class RestfulService extends ViewableData implements Flushable {
if($element) if($element)
$childElements = $xml->{$collection}->{$element}; $childElements = $xml->{$collection}->{$element};
if($childElements) if(isset($childElements) && $childElements)
return Convert::raw2xml($childElements); return Convert::raw2xml($childElements);
} }
@ -573,7 +575,7 @@ class RestfulService_Response extends SS_HTTPResponse {
protected $simpleXML; protected $simpleXML;
/** /**
* @var boolean It should be populated with cached request * @var RestfulService_Response|false It should be populated with cached request
* when a request referring to this response was unsuccessful * when a request referring to this response was unsuccessful
*/ */
protected $cachedResponse = false; protected $cachedResponse = false;
@ -600,14 +602,14 @@ class RestfulService_Response extends SS_HTTPResponse {
* get the cached response object. This allows you to access the cached * get the cached response object. This allows you to access the cached
* eaders, not just the cached body. * eaders, not just the cached body.
* *
* @return RestfulSerivice_Response The cached response object * @return RestfulService_Response|false The cached response object
*/ */
public function getCachedResponse() { public function getCachedResponse() {
return $this->cachedResponse; return $this->cachedResponse;
} }
/** /**
* @return string * @return string|false
*/ */
public function getCachedBody() { public function getCachedBody() {
if ($this->cachedResponse) { if ($this->cachedResponse) {

View File

@ -41,7 +41,7 @@ if(isset($_SERVER['argv'][2])) {
if(!isset($_GET)) $_GET = array(); if(!isset($_GET)) $_GET = array();
if(!isset($_REQUEST)) $_REQUEST = array(); if(!isset($_REQUEST)) $_REQUEST = array();
foreach($args as $arg) { foreach($args as $arg) {
if(strpos($arg,'=') == false) { if(strpos($arg,'=') === false) {
$_GET['args'][] = $arg; $_GET['args'][] = $arg;
} else { } else {
$newItems = array(); $newItems = array();

View File

@ -144,7 +144,7 @@ class CookieJar implements Cookie_Backend {
* @see http://uk3.php.net/manual/en/function.setcookie.php * @see http://uk3.php.net/manual/en/function.setcookie.php
* *
* @param string $name The name of the cookie * @param string $name The name of the cookie
* @param string|array $value The value for the cookie to hold * @param string|array|false $value The value for the cookie to hold
* @param int $expiry The number of days until expiry * @param int $expiry The number of days until expiry
* @param string $path The path to save the cookie on (falls back to site base) * @param string $path The path to save the cookie on (falls back to site base)
* @param string $domain The domain to make the cookie available on * @param string $domain The domain to make the cookie available on

View File

@ -948,7 +948,9 @@ abstract class Object {
*/ */
protected function createMethod($method, $code) { protected function createMethod($method, $code) {
self::$extra_methods[get_class($this)][strtolower($method)] = array ( self::$extra_methods[get_class($this)][strtolower($method)] = array (
'function' => create_function('$obj, $args', $code) 'function' => function($obj, $args) use ($code) {
eval($code);
}
); );
} }

View File

@ -1307,7 +1307,9 @@ class Installer extends InstallRequirements {
$locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\'") : 'en_US'; $locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\'") : 'en_US';
$type = addcslashes($config['db']['type'], "\'"); $type = addcslashes($config['db']['type'], "\'");
$dbConfig = $config['db'][$type]; $dbConfig = $config['db'][$type];
$dbConfig = array_map(create_function('$v', 'return addcslashes($v, "\\\'");'), $dbConfig); $dbConfig = array_map(function($v) {
return addcslashes($v, "\\'");
}, $dbConfig);
if(!isset($dbConfig['path'])) $dbConfig['path'] = ''; if(!isset($dbConfig['path'])) $dbConfig['path'] = '';
if(!$dbConfig) { if(!$dbConfig) {
echo "<p style=\"color: red\">Bad config submitted</p><pre>"; echo "<p style=\"color: red\">Bad config submitted</p><pre>";

View File

@ -859,7 +859,9 @@ class Form extends RequestHandler {
$attrs = $this->getAttributes(); $attrs = $this->getAttributes();
// Remove empty // Remove empty
$attrs = array_filter((array)$attrs, create_function('$v', 'return ($v || $v === 0);')); $attrs = array_filter((array)$attrs, function($v) {
return ($v || $v === 0);
});
// Remove excluded // Remove excluded
if($exclude) $attrs = array_diff_key($attrs, array_flip($exclude)); if($exclude) $attrs = array_diff_key($attrs, array_flip($exclude));

View File

@ -136,8 +136,10 @@ class ListboxField extends DropdownField {
public function setSource($source) { public function setSource($source) {
if($source) { if($source) {
$hasCommas = array_filter(array_keys($source), $hasCommas = array_filter(array_keys($source),
create_function('$key', 'return strpos($key, ",") !== FALSE;')); function($key) {
if($hasCommas) { return strpos($key, ",") !== FALSE;
});
if(!empty($hasCommas)) {
throw new InvalidArgumentException('No commas allowed in $source keys'); throw new InvalidArgumentException('No commas allowed in $source keys');
} }
} }

View File

@ -1050,7 +1050,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
$oldMode = self::get_reading_mode(); $oldMode = self::get_reading_mode();
self::reading_stage('Stage'); self::reading_stage('Stage');
$list = DataObject::get(get_class($this->owner), $filter, $sort, $join, $limit); $list = DataObject::get(ClassInfo::baseDataClass($this->owner), $filter, $sort, $join, $limit);
if($having) $having = $list->having($having); if($having) $having = $list->having($having);
$query = $list->dataQuery()->query(); $query = $list->dataQuery()->query();

View File

@ -118,7 +118,9 @@ class HTMLText extends Text {
$doc = new DOMDocument(); $doc = new DOMDocument();
// Catch warnings thrown by loadHTML and turn them into a failure boolean rather than a SilverStripe error // Catch warnings thrown by loadHTML and turn them into a failure boolean rather than a SilverStripe error
set_error_handler(create_function('$no, $str', 'throw new Exception("HTML Parse Error: ".$str);'), E_ALL); set_error_handler(function($no, $str) {
throw new Exception("HTML Parse Error: " . $str);
}, E_ALL);
// Nonbreaking spaces get converted into weird characters, so strip them // Nonbreaking spaces get converted into weird characters, so strip them
$value = str_replace('&nbsp;', ' ', $this->RAW()); $value = str_replace('&nbsp;', ' ', $this->RAW());
try { try {

View File

@ -984,8 +984,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
$encryption_details = Security::encrypt_password( $encryption_details = Security::encrypt_password(
$this->Password, // this is assumed to be cleartext $this->Password, // this is assumed to be cleartext
$this->Salt, $this->Salt,
($this->PasswordEncryption) ? $this->isChanged('PasswordEncryption') ? $this->PasswordEncryption : null,
$this->PasswordEncryption : Security::config()->password_encryption_algorithm,
$this $this
); );

View File

@ -728,7 +728,9 @@ class UploadFieldTest extends FunctionalTest {
// A bit too much coupling with GridField, but a full template overload would make things too complex // A bit too much coupling with GridField, but a full template overload would make things too complex
$parser = new CSSContentParser($response->getBody()); $parser = new CSSContentParser($response->getBody());
$items = $parser->getBySelector('.ss-gridfield-item'); $items = $parser->getBySelector('.ss-gridfield-item');
$itemIDs = array_map(create_function('$el', 'return (int)$el["data-id"];'), $items); $itemIDs = array_map(function($el) {
return (int)$el["data-id"];
}, $items);
$this->assertContains($file4->ID, $itemIDs, 'Contains file in assigned folder'); $this->assertContains($file4->ID, $itemIDs, 'Contains file in assigned folder');
$this->assertContains($fileSubfolder->ID, $itemIDs, 'Contains file in subfolder'); $this->assertContains($fileSubfolder->ID, $itemIDs, 'Contains file in subfolder');
} }
@ -746,7 +748,9 @@ class UploadFieldTest extends FunctionalTest {
// A bit too much coupling with GridField, but a full template overload would make things too complex // A bit too much coupling with GridField, but a full template overload would make things too complex
$parser = new CSSContentParser($response->getBody()); $parser = new CSSContentParser($response->getBody());
$items = $parser->getBySelector('.ss-gridfield-item'); $items = $parser->getBySelector('.ss-gridfield-item');
$itemIDs = array_map(create_function('$el', 'return (int)$el["data-id"];'), $items); $itemIDs = array_map(function($el) {
return (int)$el["data-id"];
}, $items);
$this->assertContains($file4->ID, $itemIDs, 'Contains file in assigned folder'); $this->assertContains($file4->ID, $itemIDs, 'Contains file in assigned folder');
$this->assertNotContains($fileSubfolder->ID, $itemIDs, 'Does not contain file in subfolder'); $this->assertNotContains($fileSubfolder->ID, $itemIDs, 'Does not contain file in subfolder');
} }

View File

@ -45,7 +45,21 @@ class MemberTest extends FunctionalTest {
parent::tearDown(); parent::tearDown();
} }
public function testPasswordEncryptionUpdatedOnChangedPassword()
{
Config::inst()->update('Security', 'password_encryption_algorithm', 'none');
$member = Member::create();
$member->SetPassword = 'password';
$member->write();
$this->assertEquals('password', $member->Password);
$this->assertEquals('none', $member->PasswordEncryption);
Config::inst()->update('Security', 'password_encryption_algorithm', 'blowfish');
$member->SetPassword = 'newpassword';
$member->write();
$this->assertNotEquals('password', $member->Password);
$this->assertNotEquals('newpassword', $member->Password);
$this->assertEquals('blowfish', $member->PasswordEncryption);
}
/** /**
* @expectedException ValidationException * @expectedException ValidationException
@ -94,28 +108,6 @@ class MemberTest extends FunctionalTest {
); );
} }
public function testDefaultPasswordEncryptionDoesntChangeExistingMembers() {
$member = new Member();
$member->Password = 'mypassword';
$member->PasswordEncryption = 'sha1_v2.4';
$member->write();
$origAlgo = Security::config()->password_encryption_algorithm;
Security::config()->password_encryption_algorithm = 'none';
$member->Password = 'mynewpassword';
$member->write();
$this->assertEquals(
$member->PasswordEncryption,
'sha1_v2.4'
);
$result = $member->checkPassword('mynewpassword');
$this->assertTrue($result->valid());
Security::config()->password_encryption_algorithm = $origAlgo;
}
public function testKeepsEncryptionOnEmptyPasswords() { public function testKeepsEncryptionOnEmptyPasswords() {
$member = new Member(); $member = new Member();
$member->Password = 'mypassword'; $member->Password = 'mypassword';
@ -126,8 +118,8 @@ class MemberTest extends FunctionalTest {
$member->write(); $member->write();
$this->assertEquals( $this->assertEquals(
$member->PasswordEncryption, Security::config()->get('password_encryption_algorithm'),
'sha1_v2.4' $member->PasswordEncryption
); );
$result = $member->checkPassword(''); $result = $member->checkPassword('');
$this->assertTrue($result->valid()); $this->assertTrue($result->valid());

View File

@ -135,7 +135,7 @@ class sfYamlInline
if ( if (
(1 == count($keys) && '0' == $keys[0]) (1 == count($keys) && '0' == $keys[0])
|| ||
(count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2)) (count($keys) > 1 && array_reduce($keys, function($v,$w) { return (integer) $v + $w;}, 0) == count($keys) * (count($keys) - 1) / 2))
{ {
$output = array(); $output = array();
foreach ($value as $val) foreach ($value as $val)