diff --git a/docs/en/04_Changelogs/4.3.4.md b/docs/en/04_Changelogs/4.3.4.md new file mode 100644 index 000000000..d2755b10b --- /dev/null +++ b/docs/en/04_Changelogs/4.3.4.md @@ -0,0 +1,38 @@ +# 4.3.4 + + + +## 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) diff --git a/src/Control/Email/Email.php b/src/Control/Email/Email.php index 8d79db709..c343fade4 100644 --- a/src/Control/Email/Email.php +++ b/src/Control/Email/Email.php @@ -792,10 +792,10 @@ class Email extends ViewableData // Do not interfere with emails styles Requirements::clear(); - + // Render plain part 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 @@ -809,7 +809,7 @@ class Email extends ViewableData $htmlPartObject = DBField::create_field('HTMLFragment', $htmlPart); $plainPart = $htmlPartObject->Plain(); } - + // Rendering is finished Requirements::restore(); diff --git a/src/Control/Middleware/ConfirmationMiddleware.php b/src/Control/Middleware/ConfirmationMiddleware.php index f4f903d6a..79acbfe21 100644 --- a/src/Control/Middleware/ConfirmationMiddleware.php +++ b/src/Control/Middleware/ConfirmationMiddleware.php @@ -33,6 +33,7 @@ class ConfirmationMiddleware implements HTTPMiddleware /** * Confirmation form URL + * WARNING: excluding SS_BASE_URL * * @var string */ @@ -81,8 +82,15 @@ class ConfirmationMiddleware implements HTTPMiddleware */ 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( - $this->confirmationFormUrl, + $url, urlencode($confirmationStorageId) ); } diff --git a/src/Control/Middleware/URLSpecialsMiddleware.php b/src/Control/Middleware/URLSpecialsMiddleware.php index 073e52e76..b2fb10a6d 100644 --- a/src/Control/Middleware/URLSpecialsMiddleware.php +++ b/src/Control/Middleware/URLSpecialsMiddleware.php @@ -2,6 +2,8 @@ namespace SilverStripe\Control\Middleware; +use SilverStripe\Control\Controller; +use SilverStripe\Control\Director; use SilverStripe\Control\Middleware\URLSpecialsMiddleware\FlushScheduler; use SilverStripe\Control\Middleware\URLSpecialsMiddleware\SessionEnvTypeSwitcher; use SilverStripe\Control\HTTPRequest; @@ -63,7 +65,12 @@ class URLSpecialsMiddleware extends PermissionAwareConfirmationMiddleware $request['urlspecialstoken'] = bin2hex(random_bytes(4)); $result = new HTTPResponse(); - $result->redirect('/' . $request->getURL(true)); + $result->redirect( + Controller::join_links( + Director::baseURL(), + $request->getURL(true) + ) + ); return $result; } } diff --git a/src/ORM/Connect/MySQLQuery.php b/src/ORM/Connect/MySQLQuery.php index 22f11a3eb..f1dbfefd2 100644 --- a/src/ORM/Connect/MySQLQuery.php +++ b/src/ORM/Connect/MySQLQuery.php @@ -48,8 +48,11 @@ class MySQLQuery extends Query public function seek($row) { 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); - return $this->nextRecord(); + $result = $this->nextRecord(); + $this->handle->data_seek($row); + return $result; } return null; } diff --git a/src/ORM/Connect/MySQLStatement.php b/src/ORM/Connect/MySQLStatement.php index 9c7fdce26..ca2cdbd32 100644 --- a/src/ORM/Connect/MySQLStatement.php +++ b/src/ORM/Connect/MySQLStatement.php @@ -105,8 +105,12 @@ class MySQLStatement extends Query public function seek($row) { $this->rowNum = $row - 1; + + // Fix for https://github.com/silverstripe/silverstripe-framework/issues/9097 without breaking the seek() API $this->statement->data_seek($row); - return $this->next(); + $result = $this->next(); + $this->statement->data_seek($row); + return $result; } public function numRecords() @@ -132,9 +136,4 @@ class MySQLStatement extends Query } return $row; } - - public function rewind() - { - return $this->seek(0); - } } diff --git a/src/ORM/Connect/Query.php b/src/ORM/Connect/Query.php index 1f994dd7f..b1c3d4247 100644 --- a/src/ORM/Connect/Query.php +++ b/src/ORM/Connect/Query.php @@ -168,16 +168,15 @@ abstract class Query implements Iterator * 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. * - * @return array + * @return void */ public function rewind() { if ($this->queryHasBegun && $this->numRecords() > 0) { $this->queryHasBegun = false; $this->currentRecord = null; - return $this->seek(0); + $this->seek(0); } - return null; } /** diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index ab41e0388..22c1ed53a 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -2318,6 +2318,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $fs->fieldClasses = $params['fieldClasses']; $fs->ajaxSafe = $params['ajaxSafe']; + $this->extend('updateFormScaffolder', $fs, $this); + return $fs->getFieldList(); } diff --git a/src/ORM/FieldType/DBString.php b/src/ORM/FieldType/DBString.php index d40481dd7..5c40ac337 100644 --- a/src/ORM/FieldType/DBString.php +++ b/src/ORM/FieldType/DBString.php @@ -77,7 +77,7 @@ abstract class DBString extends DBField */ public function getNullifyEmpty() { - return $this->options['nullifyEmpty']; + return !empty($this->options['nullifyEmpty']); } /** @@ -99,7 +99,7 @@ abstract class DBString extends DBField } // Return "empty" value - if ($this->options['nullifyEmpty'] || $value === null) { + if ($this->getNullifyEmpty() || $value === null) { return null; } return ''; diff --git a/src/Security/Confirmation/Storage.php b/src/Security/Confirmation/Storage.php index e27931590..0794e3646 100644 --- a/src/Security/Confirmation/Storage.php +++ b/src/Security/Confirmation/Storage.php @@ -2,7 +2,9 @@ namespace SilverStripe\Security\Confirmation; +use SilverStripe\Control\Controller; use SilverStripe\Control\Cookie; +use SilverStripe\Control\Director; use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\Session; use SilverStripe\Security\SecurityToken; @@ -236,7 +238,8 @@ class Storage */ 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(); $this->session->set($this->getNamespace('httpMethod'), $httpMethod); diff --git a/tests/php/Control/Middleware/ConfirmationMiddlewareTest.php b/tests/php/Control/Middleware/ConfirmationMiddlewareTest.php index cec934bc6..9b2f43f51 100644 --- a/tests/php/Control/Middleware/ConfirmationMiddlewareTest.php +++ b/tests/php/Control/Middleware/ConfirmationMiddlewareTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\Control\Tests\Middleware; +use SilverStripe\Control\Director; use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\Middleware\ConfirmationMiddleware; use SilverStripe\Control\Middleware\ConfirmationMiddleware\Url; @@ -67,7 +68,7 @@ class ConfirmationMiddlewareTest extends SapphireTest $this->assertFalse($next); $this->assertInstanceOf(HTTPResponse::class, $response); $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 $middleware->setBypasses([new Url('dev/build')]); diff --git a/tests/php/Core/MemoryLimitTest.php b/tests/php/Core/MemoryLimitTest.php index 37dccd8d3..842e77645 100644 --- a/tests/php/Core/MemoryLimitTest.php +++ b/tests/php/Core/MemoryLimitTest.php @@ -66,6 +66,7 @@ class MemoryLimitTest extends SapphireTest // No argument means unlimited (but only if originally allowed) if (is_numeric($this->origMemLimitMax) && $this->origMemLimitMax < 0) { + Environment::setMemoryLimitMax(-1); Environment::increaseMemoryLimitTo(); $this->assertEquals(-1, ini_get('memory_limit')); } diff --git a/tests/php/ORM/DatabaseTest.php b/tests/php/ORM/DatabaseTest.php index babcdb402..607515613 100644 --- a/tests/php/ORM/DatabaseTest.php +++ b/tests/php/ORM/DatabaseTest.php @@ -272,4 +272,25 @@ class DatabaseTest extends SapphireTest $result = DB::query('SELECT TRUE')->first(); $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()); + } } diff --git a/tests/php/Security/Confirmation/StorageTest.php b/tests/php/Security/Confirmation/StorageTest.php index 4c36f71a9..a3075769d 100644 --- a/tests/php/Security/Confirmation/StorageTest.php +++ b/tests/php/Security/Confirmation/StorageTest.php @@ -69,7 +69,7 @@ class StorageTest extends SapphireTest // ensure the data is persisted within the session $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()); }