Merge branch '4.0' into 4

This commit is contained in:
Daniel Hensby 2017-11-14 13:24:15 +00:00
commit cf321895ba
No known key found for this signature in database
GPG Key ID: B00D1E9767F0B06E
8 changed files with 55 additions and 15 deletions

View File

@ -58,7 +58,6 @@ matrix:
before_script: before_script:
# Init PHP # Init PHP
- pecl channel-update pecl.php.net - pecl channel-update pecl.php.net
- travis_retry printf "\n" | pecl install imagick
- phpenv rehash - phpenv rehash
- phpenv config-rm xdebug.ini || true - phpenv config-rm xdebug.ini || true
- echo 'memory_limit = 2048M' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - echo 'memory_limit = 2048M' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini

View File

@ -41,7 +41,7 @@ For those that use WAMP as a development environment, [detailed information is a
Composer can create a new site for you, using the installer as a template (by default composer will download the latest stable version): Composer can create a new site for you, using the installer as a template (by default composer will download the latest stable version):
``` ```
composer create-project silverstripe/installer ./my/website/folder composer create-project silverstripe/installer ./my/website/folder ^4
``` ```
If you want to get all additional fixtures for testing, such as behat and phpunit configuration, If you want to get all additional fixtures for testing, such as behat and phpunit configuration,
@ -282,7 +282,7 @@ the latest unstable silverstripe/installer
composer create-project silverstripe/installer ./my/website/folder dev-master composer create-project silverstripe/installer ./my/website/folder dev-master
``` ```
Or for the latest development version in the 3.0.x series Or for the latest development version in the 4.0.x series
``` ```
composer create-project silverstripe/installer ./my/website/folder 4.0.x-dev composer create-project silverstripe/installer ./my/website/folder 4.0.x-dev

View File

@ -1,4 +1,4 @@
# 4.0.0 (unreleased) # 4.0.0
## Introduction ## Introduction
@ -81,7 +81,6 @@ Backup your existing `composer.json` and overwrite it with the following content
This composer file uses the new [recipe](https://github.com/silverstripe/recipe-plugin) approach This composer file uses the new [recipe](https://github.com/silverstripe/recipe-plugin) approach
which bundles all core dependencies in a meta package. If you want more granular control over what gets installed, which bundles all core dependencies in a meta package. If you want more granular control over what gets installed,
check the `composer.json` files in [recipe-core](https://github.com/silverstripe/recipe-core) and [recipe-cms](https://github.com/silverstripe/recipe-cms). check the `composer.json` files in [recipe-core](https://github.com/silverstripe/recipe-core) and [recipe-cms](https://github.com/silverstripe/recipe-cms).
Since this is a pre-release, you need to allow composer to install unstable dependencies via `minimum-stability: dev`.
Now run a `composer update`. This will remove all existing modules from your local codebase Now run a `composer update`. This will remove all existing modules from your local codebase
since we replaced your project's `composer.json`. Now you can move back your modules since we replaced your project's `composer.json`. Now you can move back your modules
@ -488,6 +487,7 @@ For instance, code which logs errors should be upgraded as below:
```diff ```diff
-SS_Log::log('My error message', SS_Log::ERR); -SS_Log::log('My error message', SS_Log::ERR);
+use Psr\Log\LoggerInterface; +use Psr\Log\LoggerInterface;
+use SilverStripe\Core\Injector\Injector;
+Injector::inst()->get(LoggerInterface::class)->error('My error message'); +Injector::inst()->get(LoggerInterface::class)->error('My error message');
``` ```

View File

@ -621,6 +621,12 @@ class Email extends ViewableData
*/ */
public function setBody($body) public function setBody($body)
{ {
$plainPart = $this->findPlainPart();
if ($plainPart) {
$this->getSwiftMessage()->detach($plainPart);
}
unset($plainPart);
$body = HTTP::absoluteURLs($body); $body = HTTP::absoluteURLs($body);
$this->getSwiftMessage()->setBody($body); $this->getSwiftMessage()->setBody($body);
@ -856,6 +862,12 @@ class Email extends ViewableData
*/ */
public function generatePlainPartFromBody() public function generatePlainPartFromBody()
{ {
$plainPart = $this->findPlainPart();
if ($plainPart) {
$this->getSwiftMessage()->detach($plainPart);
}
unset($plainPart);
$this->getSwiftMessage()->addPart( $this->getSwiftMessage()->addPart(
Convert::xml2raw($this->getBody()), Convert::xml2raw($this->getBody()),
'text/plain', 'text/plain',

View File

@ -343,12 +343,18 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly
* - Custom state helpers * - Custom state helpers
* *
* User code should call parent::setUpBeforeClass() before custom setup code * User code should call parent::setUpBeforeClass() before custom setup code
*
* @throws Exception
*/ */
public static function setUpBeforeClass() public static function setUpBeforeClass()
{ {
// Start tests // Start tests
static::start(); static::start();
if (!static::$state) {
throw new Exception('SapphireTest failed to bootstrap!');
}
// Call state helpers // Call state helpers
static::$state->setUpOnce(static::class); static::$state->setUpOnce(static::class);

View File

@ -44,7 +44,7 @@ class RequiredFields extends Validator
/** /**
* Clears all the validation from this object. * Clears all the validation from this object.
* *
* @return RequiredFields * @return $this
*/ */
public function removeValidation() public function removeValidation()
{ {
@ -56,6 +56,7 @@ class RequiredFields extends Validator
/** /**
* Debug helper * Debug helper
* @return string
*/ */
public function debug() public function debug()
{ {
@ -152,7 +153,7 @@ class RequiredFields extends Validator
* *
* @param string $field * @param string $field
* *
* @return RequiredFields * @return $this
*/ */
public function addRequiredField($field) public function addRequiredField($field)
{ {
@ -166,7 +167,7 @@ class RequiredFields extends Validator
* *
* @param string $field * @param string $field
* *
* @return RequiredFields * @return $this
*/ */
public function removeRequiredField($field) public function removeRequiredField($field)
{ {
@ -179,7 +180,7 @@ class RequiredFields extends Validator
* Add {@link RequiredField} objects together * Add {@link RequiredField} objects together
* *
* @param RequiredFields $requiredFields * @param RequiredFields $requiredFields
* @return RequiredFields * @return $this
*/ */
public function appendRequiredFields($requiredFields) public function appendRequiredFields($requiredFields)
{ {

View File

@ -198,7 +198,7 @@ class DBText extends DBString
$keywords = Convert::raw2xml($keywords); $keywords = Convert::raw2xml($keywords);
// Find the search string // Find the search string
$position = (int) stripos($text, $keywords); $position = (int) mb_stripos($text, $keywords);
// We want to search string to be in the middle of our block to give it some context // We want to search string to be in the middle of our block to give it some context
$position = max(0, $position - ($characters / 2)); $position = max(0, $position - ($characters / 2));
@ -206,19 +206,19 @@ class DBText extends DBString
if ($position > 0) { if ($position > 0) {
// We don't want to start mid-word // We don't want to start mid-word
$position = max( $position = max(
(int) strrpos(substr($text, 0, $position), ' '), (int) mb_strrpos(substr($text, 0, $position), ' '),
(int) strrpos(substr($text, 0, $position), "\n") (int) mb_strrpos(substr($text, 0, $position), "\n")
); );
} }
$summary = substr($text, $position, $characters); $summary = mb_substr($text, $position, $characters);
$stringPieces = explode(' ', $keywords); $stringPieces = explode(' ', $keywords);
if ($highlight) { if ($highlight) {
// Add a span around all key words from the search term as well // Add a span around all key words from the search term as well
if ($stringPieces) { if ($stringPieces) {
foreach ($stringPieces as $stringPiece) { foreach ($stringPieces as $stringPiece) {
if (strlen($stringPiece) > 2) { if (mb_strlen($stringPiece) > 2) {
// Maintain case of original string // Maintain case of original string
$summary = preg_replace( $summary = preg_replace(
'/' . preg_quote($stringPiece, '/') . '/i', '/' . preg_quote($stringPiece, '/') . '/i',

View File

@ -41,6 +41,7 @@ class DBTextTest extends SapphireTest
['The little brown fox jumped over the lazy cow.', 'The little brown fox...'], ['The little brown fox jumped over the lazy cow.', 'The little brown fox...'],
['<p>Short & Sweet</p>', '&lt;p&gt;Short &amp; Sweet&lt;/p&gt;'], ['<p>Short & Sweet</p>', '&lt;p&gt;Short &amp; Sweet&lt;/p&gt;'],
['This text contains &amp; in it', 'This text contains &amp;...'], ['This text contains &amp; in it', 'This text contains &amp;...'],
['Is an umault in schön?', 'Is an umault in schö...'],
]; ];
} }
@ -80,7 +81,10 @@ class DBTextTest extends SapphireTest
['<p>Lorem ipsum dolor sit amet</p>', 24, '&lt;p&gt;Lorem ipsum dolor...'], ['<p>Lorem ipsum dolor sit amet</p>', 24, '&lt;p&gt;Lorem ipsum dolor...'],
['<p><span>Lorem ipsum dolor sit amet</span></p>', 24, '&lt;p&gt;&lt;span&gt;Lorem ipsum...'], ['<p><span>Lorem ipsum dolor sit amet</span></p>', 24, '&lt;p&gt;&lt;span&gt;Lorem ipsum...'],
['<p>Lorem ipsum</p>', 24, '&lt;p&gt;Lorem ipsum&lt;/p&gt;'], ['<p>Lorem ipsum</p>', 24, '&lt;p&gt;Lorem ipsum&lt;/p&gt;'],
['Lorem &amp; ipsum dolor sit amet', 24, 'Lorem &amp;amp; ipsum dolor...'] ['Lorem &amp; ipsum dolor sit amet', 24, 'Lorem &amp;amp; ipsum dolor...'],
['Is an umault in schön or not?', 22, 'Is an umault in schön...'],
]; ];
} }
@ -124,6 +128,9 @@ class DBTextTest extends SapphireTest
// If storing HTML you should use DBHTMLText instead // If storing HTML you should use DBHTMLText instead
['<p>Text inside a paragraph tag should also work</p>', 3, '&lt;p&gt;Text inside a...'], ['<p>Text inside a paragraph tag should also work</p>', 3, '&lt;p&gt;Text inside a...'],
['<p>Two words</p>', 3, '&lt;p&gt;Two words&lt;/p&gt;'], ['<p>Two words</p>', 3, '&lt;p&gt;Two words&lt;/p&gt;'],
// Check UTF8
['Is an umault in schön or not?', 5, 'Is an umault in schön...'],
]; ];
} }
@ -156,6 +163,9 @@ class DBTextTest extends SapphireTest
// If storing HTML you should use DBHTMLText instead // If storing HTML you should use DBHTMLText instead
['<p>First sentence.</p>', 2, '&lt;p&gt;First sentence.&lt;/p&gt;'], ['<p>First sentence.</p>', 2, '&lt;p&gt;First sentence.&lt;/p&gt;'],
['<p>First sentence. Second sentence. Third sentence</p>', 2, '&lt;p&gt;First sentence. Second sentence.'], ['<p>First sentence. Second sentence. Third sentence</p>', 2, '&lt;p&gt;First sentence. Second sentence.'],
// Check UTF8
['Is schön. Isn\'t schön.', 1, 'Is schön.'],
]; ];
} }
@ -187,6 +197,9 @@ class DBTextTest extends SapphireTest
// If storing HTML you should use DBHTMLText instead // If storing HTML you should use DBHTMLText instead
['<br />First sentence.', '&lt;br /&gt;First sentence.'], ['<br />First sentence.', '&lt;br /&gt;First sentence.'],
['<p>First sentence. Second sentence. Third sentence</p>', '&lt;p&gt;First sentence.'], ['<p>First sentence. Second sentence. Third sentence</p>', '&lt;p&gt;First sentence.'],
// Check UTF8
['Is schön. Isn\'t schön.', 'Is schön.'],
]; ];
} }
@ -243,7 +256,16 @@ class DBTextTest extends SapphireTest
'ate', 'ate',
// it should highlight 3 letters or more. // it should highlight 3 letters or more.
'A dog <mark>ate</mark> a cat while looking at a Foobar', 'A dog <mark>ate</mark> a cat while looking at a Foobar',
],
[
'both schön and können have umlauts',
21,
'schön',
// check UTF8 support
'both <mark>schön</mark> and können...',
] ]
]; ];
} }