Merge branch '4.4' into 4

This commit is contained in:
Serge Latyntcev 2019-07-15 09:24:49 +12:00
commit 29a663c65d
14 changed files with 102 additions and 20 deletions

View File

@ -0,0 +1,38 @@
# 4.3.4
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### Features and Enhancements
* 2019-05-30 [c569cec4](https://github.com/silverstripe/silverstripe-cms/commit/c569cec4ea49612ddc9d430d7fe792971c93c586) Add updateHintsCacheKey extension point to fix invalid caching (Garion Herman)
* 2019-03-05 [39a29fa2f](https://github.com/silverstripe/silverstripe-framework/commit/39a29fa2f65ebd9a3ad486c6d85249322bcb9a64) has_extension() should allow injector overrides (Aaron Carlino)
### Bugfixes
* 2019-05-24 [25aa3af03](https://github.com/silverstripe/silverstripe-framework/commit/25aa3af032f24314ac458743db78028e1aa66ead) HeaderField requires the optional Title field (Dylan Wagstaff)
* 2019-05-14 [3f1479edb](https://github.com/silverstripe/silverstripe-framework/commit/3f1479edbbe406a6b9ca1c5284f2daabf455c8b5) DataQuery overwriting _SortColumn selects (#8974) (Aaron Carlino)
* 2019-05-13 [3a5c14f7c](https://github.com/silverstripe/silverstripe-framework/commit/3a5c14f7c288ce160012651869cb2458eee18b6b) password validation min length message (#8976) (Guy Marriott)
* 2019-05-13 [db0e6f710](https://github.com/silverstripe/silverstripe-framework/commit/db0e6f7104d6250d0afe3d717b70497ee6fade2d) Fix password validation min length message (matt-in-a-hat)
* 2019-05-10 [94f3054](https://github.com/silverstripe/silverstripe-admin/commit/94f3054e18f83680864f283f979ac8df4353688a) Add offending class to exception message (Guy Marriott)
* 2019-04-18 [e6c1061](https://github.com/silverstripe/silverstripe-asset-admin/commit/e6c1061600941ffa26ec42fc4fc7032d894e944d) folders always go first when ordering (#936) (Serge Latyntsev)
* 2019-04-17 [e0eaf61](https://github.com/silverstripe/silverstripe-versioned-admin/commit/e0eaf61af4bc9f4fa682c2af143f9f4665464442) Use Firefox compliant polyfill for ResizeAware (Robbie Averill)
* 2019-04-17 [e59ca40](https://github.com/silverstripe/silverstripe-campaign-admin/commit/e59ca40d1357be4ba6c1193de690573815d78c6c) Use Firefox compliant polyfill for ResizeAware (Robbie Averill)
* 2019-04-16 [9d6b5048a](https://github.com/silverstripe/silverstripe-framework/commit/9d6b5048a620f793a2910b858331a5141d161e63) Table aliases are retained on base tables in queries built using SQLConditionalExpression (#8918) (Guy Marriott)
* 2019-04-15 [63360f804](https://github.com/silverstripe/silverstripe-framework/commit/63360f80482d860495900a39282b54680f38cd45) Replace substr with mb_substr to get the correct position (Sheila Bañez)
* 2019-04-15 [4fbe0fd6](https://github.com/silverstripe/silverstripe-cms/commit/4fbe0fd6b9018d2ff16f5edc022daa92702e91a5) Fix linking anchor on the same page (#2388) (Will Rossiter)
* 2019-04-14 [a48beac84](https://github.com/silverstripe/silverstripe-framework/commit/a48beac84544ed2db89ac094cc80508742284c1c) Calculate threshold condition with SQL rather than PHP (Guy Marriott)
* 2019-04-09 [661a27e](https://github.com/silverstripe/silverstripe-assets/commit/661a27e93efcf98c2521b42ec802ecf625e0a6ea) Fix hash redirection logic on PostreSQL and add PostreSQL to the travis matrix (#237) (Serge Latyntsev)
* 2019-04-05 [594af7713](https://github.com/silverstripe/silverstripe-framework/commit/594af7713487da0fc200d6df8d9c706c26e3c767) prevent unnecessary field alterations for enums with empty defaults (Loz Calver)
* 2019-04-04 [759968bbe](https://github.com/silverstripe/silverstripe-framework/commit/759968bbe2f8e3a4087b2f08622abc4cc70f2867) Fix Undefined variable: result when catch Exception (Ian Patel)
* 2019-04-04 [a3c61e5](https://github.com/silverstripe/silverstripe-admin/commit/a3c61e546f77e78fdefd3e678b0dbe0ca52e933b) Long site names now display correctly in CMS menu with equal margins and alignment (Robbie Averill)
* 2019-03-26 [83ec0b69f](https://github.com/silverstripe/silverstripe-framework/commit/83ec0b69fa642ed1ad734fff10ea6dc3aeba6cf3) Resolve issue where schema changes between enum / non-enum types (Damian Mooyman)
* 2019-03-25 [fae19c16b](https://github.com/silverstripe/silverstripe-framework/commit/fae19c16b54f077bbd7665a50df516d290faa07e) has_one File form scaffolding (Jonathon Menz)
* 2019-03-22 [95344a6](https://github.com/silverstripe/silverstripe-asset-admin/commit/95344a6e291dc40c361ebbcb787eb9656b5aa905) Re-instate assuming redux knows best with more specific checks (See #922) (Guy Marriott)
* 2019-03-22 [cb670f4](https://github.com/silverstripe/silverstripe-admin/commit/cb670f4604dab8328b939ebe583f09928ecbe32d) TinyMCE editor.scss now applies to the correct body class, and has correct broken link colours (Robbie Averill)
* 2019-03-21 [595d8ec](https://github.com/silverstripe/silverstripe-asset-admin/commit/595d8ec8bc11e102ab6ef3ec1cbb99e9d5c09cab) UploadField now ensures that file data is copied to redux store of value updates (Guy Marriott)
* 2019-03-20 [388baa01b](https://github.com/silverstripe/silverstripe-framework/commit/388baa01b49fb47b7187c03bfdaa87b6712f5cdd) Fix linting (Aaron Carlino)
* 2019-03-19 [aa491d929](https://github.com/silverstripe/silverstripe-framework/commit/aa491d92940282a62748bbfe4f69a1e56b0ce2d8) Fix tests (Aaron Carlino)
* 2019-02-01 [3900b82](https://github.com/silverstripe/silverstripe-admin/commit/3900b82e2af96c96f20778fb7b9d7c51e84f6218) Scrolling out of auto-selected edit mode not switches back to split mode (Robbie Averill)
* 2019-01-18 [a4ec816](https://github.com/silverstripe/silverstripe-assets/commit/a4ec816839449605e579b36691e56a46354e9895) Add missing file upload error types (fixes #205) (Loz Calver)

View File

@ -795,7 +795,7 @@ class Email extends ViewableData
// Render plain part // Render plain part
if ($plainTemplate && !$plainPart) { if ($plainTemplate && !$plainPart) {
$plainPart = $this->renderWith($plainTemplate, $this->getData()); $plainPart = $this->renderWith($plainTemplate, $this->getData())->Plain();
} }
// Render HTML part, either if sending html email, or a plain part is lacking // Render HTML part, either if sending html email, or a plain part is lacking

View File

@ -33,6 +33,7 @@ class ConfirmationMiddleware implements HTTPMiddleware
/** /**
* Confirmation form URL * Confirmation form URL
* WARNING: excluding SS_BASE_URL
* *
* @var string * @var string
*/ */
@ -81,8 +82,15 @@ class ConfirmationMiddleware implements HTTPMiddleware
*/ */
protected function getConfirmationUrl(HTTPRequest $request, $confirmationStorageId) protected function getConfirmationUrl(HTTPRequest $request, $confirmationStorageId)
{ {
$url = $this->confirmationFormUrl;
if (substr($url, 0, 1) === '/') {
// add BASE_URL explicitly if not absolute
$url = Controller::join_links(Director::baseURL(), $url);
}
return Controller::join_links( return Controller::join_links(
$this->confirmationFormUrl, $url,
urlencode($confirmationStorageId) urlencode($confirmationStorageId)
); );
} }

View File

@ -2,6 +2,8 @@
namespace SilverStripe\Control\Middleware; namespace SilverStripe\Control\Middleware;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Control\Middleware\URLSpecialsMiddleware\FlushScheduler; use SilverStripe\Control\Middleware\URLSpecialsMiddleware\FlushScheduler;
use SilverStripe\Control\Middleware\URLSpecialsMiddleware\SessionEnvTypeSwitcher; use SilverStripe\Control\Middleware\URLSpecialsMiddleware\SessionEnvTypeSwitcher;
use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPRequest;
@ -63,7 +65,12 @@ class URLSpecialsMiddleware extends PermissionAwareConfirmationMiddleware
$request['urlspecialstoken'] = bin2hex(random_bytes(4)); $request['urlspecialstoken'] = bin2hex(random_bytes(4));
$result = new HTTPResponse(); $result = new HTTPResponse();
$result->redirect('/' . $request->getURL(true)); $result->redirect(
Controller::join_links(
Director::baseURL(),
$request->getURL(true)
)
);
return $result; return $result;
} }
} }

View File

@ -48,8 +48,11 @@ class MySQLQuery extends Query
public function seek($row) public function seek($row)
{ {
if (is_object($this->handle)) { if (is_object($this->handle)) {
// Fix for https://github.com/silverstripe/silverstripe-framework/issues/9097 without breaking the seek() API
$this->handle->data_seek($row); $this->handle->data_seek($row);
return $this->nextRecord(); $result = $this->nextRecord();
$this->handle->data_seek($row);
return $result;
} }
return null; return null;
} }

View File

@ -105,8 +105,12 @@ class MySQLStatement extends Query
public function seek($row) public function seek($row)
{ {
$this->rowNum = $row - 1; $this->rowNum = $row - 1;
// Fix for https://github.com/silverstripe/silverstripe-framework/issues/9097 without breaking the seek() API
$this->statement->data_seek($row); $this->statement->data_seek($row);
return $this->next(); $result = $this->next();
$this->statement->data_seek($row);
return $result;
} }
public function numRecords() public function numRecords()
@ -132,9 +136,4 @@ class MySQLStatement extends Query
} }
return $row; return $row;
} }
public function rewind()
{
return $this->seek(0);
}
} }

View File

@ -168,16 +168,15 @@ abstract class Query implements Iterator
* Iterator function implementation. Rewind the iterator to the first item and return it. * Iterator function implementation. Rewind the iterator to the first item and return it.
* Makes use of {@link seek()} and {@link numRecords()}, takes care of the plumbing. * Makes use of {@link seek()} and {@link numRecords()}, takes care of the plumbing.
* *
* @return array * @return void
*/ */
public function rewind() public function rewind()
{ {
if ($this->queryHasBegun && $this->numRecords() > 0) { if ($this->queryHasBegun && $this->numRecords() > 0) {
$this->queryHasBegun = false; $this->queryHasBegun = false;
$this->currentRecord = null; $this->currentRecord = null;
return $this->seek(0); $this->seek(0);
} }
return null;
} }
/** /**

View File

@ -2318,6 +2318,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
$fs->fieldClasses = $params['fieldClasses']; $fs->fieldClasses = $params['fieldClasses'];
$fs->ajaxSafe = $params['ajaxSafe']; $fs->ajaxSafe = $params['ajaxSafe'];
$this->extend('updateFormScaffolder', $fs, $this);
return $fs->getFieldList(); return $fs->getFieldList();
} }

View File

@ -77,7 +77,7 @@ abstract class DBString extends DBField
*/ */
public function getNullifyEmpty() public function getNullifyEmpty()
{ {
return $this->options['nullifyEmpty']; return !empty($this->options['nullifyEmpty']);
} }
/** /**
@ -99,7 +99,7 @@ abstract class DBString extends DBField
} }
// Return "empty" value // Return "empty" value
if ($this->options['nullifyEmpty'] || $value === null) { if ($this->getNullifyEmpty() || $value === null) {
return null; return null;
} }
return ''; return '';

View File

@ -2,7 +2,9 @@
namespace SilverStripe\Security\Confirmation; namespace SilverStripe\Security\Confirmation;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Cookie; use SilverStripe\Control\Cookie;
use SilverStripe\Control\Director;
use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\Session; use SilverStripe\Control\Session;
use SilverStripe\Security\SecurityToken; use SilverStripe\Security\SecurityToken;
@ -236,7 +238,8 @@ class Storage
*/ */
public function setSuccessRequest(HTTPRequest $request) public function setSuccessRequest(HTTPRequest $request)
{ {
$this->setSuccessUrl($request->getURL(true)); $url = Controller::join_links(Director::baseURL(), $request->getURL(true));
$this->setSuccessUrl($url);
$httpMethod = $request->httpMethod(); $httpMethod = $request->httpMethod();
$this->session->set($this->getNamespace('httpMethod'), $httpMethod); $this->session->set($this->getNamespace('httpMethod'), $httpMethod);

View File

@ -2,6 +2,7 @@
namespace SilverStripe\Control\Tests\Middleware; namespace SilverStripe\Control\Tests\Middleware;
use SilverStripe\Control\Director;
use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\Middleware\ConfirmationMiddleware; use SilverStripe\Control\Middleware\ConfirmationMiddleware;
use SilverStripe\Control\Middleware\ConfirmationMiddleware\Url; use SilverStripe\Control\Middleware\ConfirmationMiddleware\Url;
@ -67,7 +68,7 @@ class ConfirmationMiddlewareTest extends SapphireTest
$this->assertFalse($next); $this->assertFalse($next);
$this->assertInstanceOf(HTTPResponse::class, $response); $this->assertInstanceOf(HTTPResponse::class, $response);
$this->assertEquals(302, $response->getStatusCode()); $this->assertEquals(302, $response->getStatusCode());
$this->assertEquals('/dev/confirm/middleware', $response->getHeader('location')); $this->assertEquals(Director::baseURL().'dev/confirm/middleware', $response->getHeader('location'));
// Test bypasses have more priority than rules // Test bypasses have more priority than rules
$middleware->setBypasses([new Url('dev/build')]); $middleware->setBypasses([new Url('dev/build')]);

View File

@ -66,6 +66,7 @@ class MemoryLimitTest extends SapphireTest
// No argument means unlimited (but only if originally allowed) // No argument means unlimited (but only if originally allowed)
if (is_numeric($this->origMemLimitMax) && $this->origMemLimitMax < 0) { if (is_numeric($this->origMemLimitMax) && $this->origMemLimitMax < 0) {
Environment::setMemoryLimitMax(-1);
Environment::increaseMemoryLimitTo(); Environment::increaseMemoryLimitTo();
$this->assertEquals(-1, ini_get('memory_limit')); $this->assertEquals(-1, ini_get('memory_limit'));
} }

View File

@ -272,4 +272,25 @@ class DatabaseTest extends SapphireTest
$result = DB::query('SELECT TRUE')->first(); $result = DB::query('SELECT TRUE')->first();
$this->assertInternalType('int', reset($result)); $this->assertInternalType('int', reset($result));
} }
/**
* Test that repeated iteration of a query returns all records.
* See https://github.com/silverstripe/silverstripe-framework/issues/9097
*/
public function testRepeatedIteration()
{
$inputData = ['one', 'two', 'three', 'four'];
foreach ($inputData as $i => $text) {
$x = new MyObject();
$x->MyField = $text;
$x->MyInt = $i;
$x->write();
}
$query = DB::query('SELECT "MyInt", "MyField" FROM "DatabaseTest_MyObject" ORDER BY "MyInt"');
$this->assertEquals($inputData, $query->map());
$this->assertEquals($inputData, $query->map());
}
} }

View File

@ -69,7 +69,7 @@ class StorageTest extends SapphireTest
// ensure the data is persisted within the session // ensure the data is persisted within the session
$storage = new Storage($session, 'test', false); $storage = new Storage($session, 'test', false);
$this->assertEquals('dev/build?flush=all', $storage->getSuccessUrl()); $this->assertEquals('/dev/build?flush=all', $storage->getSuccessUrl());
$this->assertEquals('GET', $storage->getHttpMethod()); $this->assertEquals('GET', $storage->getHttpMethod());
} }