Overview

This upgrade includes CMS and Framework version 3.6.0 which includes bugfixes and some feature and API enhancements.

Upgrade to Recipe 1.6.0 is optional, but is recommended for all CWP sites.

This upgrade can be carried out by any development team familiar with SilverStripe CMS, but if you would like SilverStripe's assistance, please let us know.

The following functionality has been moved from cwp/cwp to the cwp/agency-extensions module. Please install this module for continued use.

  • Carousel functionality and associated translations
  • Functionality for adding Requirements for the cwp-themes/default theme
  • Most user-configurable SiteConfig settings (e.g. logo uploads) and associated translations

Details of security issues

This release includes fixes for the following minor security issues:

  • SS-2017-002 Member disclosure in login form: There is a user ID enumeration vulnerability in our brute force error messages. Users that don't exist in will never get a locked out message, users that do exist, will get a locked out message. This means an attacker can infer or confirm user details that exist in the member table. This issue has been resolved by ensuring that login attempt logging and lockout process works equivalently for non-existent users as it does for existant users.
  • SS-2017-003 XSS in redirector page: RedirectorPage will allow users to specify a non-url malicious script as the redirection path without validation. Users which follow this url may allow this script to execute within their browser.
  • SS-2017-004 XSS in page history comparison: Authenticated user with page edit permission can craft HTML, which when rendered in a page history comparison can execute client scripts.

No user action is necessary to receive these security fixes. Upgrading to the latest recipe will automatically apply these fixes.

Upgrading Instructions

If you require any of the functionality that has been moved to the cwp/agency-extensions module, please add it to your Composer requirements:

composer require cwp/agency-extensions

Using cwp-themes/default

If you're upgrading from a project that uses the cwp-themes/default theme, or has a theme that was based on this theme in the past, you may need to install the agency-extensions module (instructions above) to reinstate some functionality such as combined scripts and styles, hero/carousel etc.

If you have renamed the "default" theme to something else, you will need to add your custom theme name to a configuration array of "default themes". Without doing so your pages may render with no CSS or Javascript. This can be defined either in YAML or PHP (in mysite/_config.php).

YAML: mysite/_config/config.yml

CwpThemeHelper:
  default_themes:
    - my_custom_theme_name

PHP: mysite/_config.php

<?php

Config::inst()->update('CwpThemeHelper', 'default_themes', array('my_custom_theme_name'));

SSViewer Theme

One potential issue you may encounter is that your Security login page is not styled. To ensure this doesn't happen, please check your config.yml and ensure that you have specified the theme your SSViewer uses like this:

SSViewer:
  theme: 'my_custom_theme_name'

Customised getBaseStyles and getBaseScripts

In previous versions of the recipe, you may have followed the "Adding JS and CSS files" instructions. If you have overriden the getBaseStyles and/or getBaseScripts methods in Page_Controller (which inherits from BasePage_Controller), you will need to make a few more adjustments.

BasePage_Controller no longer has the methods getBaseStyles and getBaseScripts. Meaning, overriding them in Page_Controller will no longer give you the results you might expect. Instead, you will have to create an extension for BasePage_Controller so you can hook your custom Styles and Scripts back in.

Step 1: Create and Apply a BasePageControllerExtension

Let's start with creating our Extension. You could name it BasePageControllerExtension for example. It should look something like this:

class BasePageControllerExtension extends Extension 
{ 
   ... 
}

And it can live in mysite/code/extensions/BasePageControllerExtension.php. Now you need to apply it to your BasePage_Controller. In your config.yml, you will need to add:

BasePage_Controller:
  extensions:
    - BasePageControllerExtension

You're now all set up for Steps 2 and 3. Let's get to it!

Step 2: From getBaseScripts to updateBaseScripts

If you have overriden getBaseScripts, you will need to add the updateBaseScripts method to your BasePageControllerExtension. There are two ways this is likely to go for you depending on how you have overridden getBaseScripts and if you have (or have not) made use of the parent::getBaseScripts() method:

1. Page_Controller has the method getBaseScripts and it makes use of parent::getBaseScripts() like this:
public function getBaseScripts() 
{
    $scripts = parent::getBaseScripts();

    $themeDir = SSViewer::get_theme_folder();
    array_push($scripts, "$themeDir/js/my.js");

    return $scripts;
}

In 1.6.0, you will need to remove the above method from Page_Controller and then add the following method to the BasePageControllerExtension:

public function updateBaseScripts(&$scripts)
{
    $themeDir = SSViewer::get_theme_folder();

    $scripts = array_merge($scripts, array(
        "$themeDir/js/my.js"
    ));
}
2. Page_Controller has the method getBaseScripts and it does not make use of parent::getBaseScripts() like this:
public function getBaseScripts()
{
    $themeDir = SSViewer::get_theme_folder();

    return array(
        "$themeDir/js/my.js"
    );
}

Again, you will need to remove the above method from Page_Controller and then add the following method to the BasePageControllerExtension:

public function updateBaseScripts(&$scripts)
{
    $themeDir = SSViewer::get_theme_folder();

    $scripts = array_merge($scripts, array(
        "$themeDir/js/my.js"
    ));
}

And finally, you have to disable the default theme scripts in your config.yml:

DefaultThemeExtension:
  disable_default_scripts: true
Step 3: From getBaseStyles to updateBaseStyles

If you have overriden getBaseStyles, you will need to add the updateBaseStyles method to your BasePageControllerExtension. There are two ways this is likely to go for you depending on how you have overridden getBaseStyles and if you have (or have not) made use of the parent::getBaseStyles() method:

1. Page_Controller has the method getBaseStyles and it makes use of parent:: getBaseStyles() like this:
public function getBaseStyles()
{
    $styles = parent::getBaseStyles();

    $themeDir = SSViewer::get_theme_folder();
    $styles['all'][] = "$themeDir/css/my.css"

    return $styles;
}

In 1.6.0, you will need to remove the above method from Page_Controller and then add the following method to the BasePageControllerExtension:

public function updateBaseStyles(&$styles)
{
    $themeDir = SSViewer::get_theme_folder();

    $styles['all'] = array_merge($styles['all'], array(
        "$themeDir/css/my.css"
    ));
}
2. Page_Controller has the method getBaseStyles and it does not make use of parent:: getBaseStyles() like this:
public function getBaseStyles()
{
    $themeDir = SSViewer::get_theme_folder();

    return array(
        "all" => "$themeDir/css/my.css"
    );
}

Again, you will need to remove the above method from Page_Controller and then add the following method to the BasePageControllerExtension:

public function updateBaseStyles(&$styles)
{
    $themeDir = SSViewer::get_theme_folder();

    $styles['all'] = array_merge($styles['all'], array(
        "$themeDir/css/my.css"
    ));
}

And finally, you have to disable the default theme scripts in your config.yml:

DefaultThemeExtension:
  disable_default_styles: true

Theme migration conclusion

That's it! You should be all ready to go! We do understand this is a bit of a tricky update, so if you have any questions, do not hesitate to submit a Support Request with any questions or suggestions you might have. Happy to discuss!

Accepted failing tests

In recipe 1.6.0 these module unit tests cause external errors, but do not represent legitimate issues.

silverstripe/framework

  • UploadFieldTest.testAllowedExtensions — Behaviour intentionally altered by the MimeValidator module
  • UploadFieldTest.testSelect — Behaviour altered by SelectUploadField intentionally
  • UploadTest.testUploadTarGzFileTwiceAppendsNumber — This test is now expected to fail as the new MimeValidator module will no longer allow random content to be uploaded with a mismatched mime and file extension. The original test is attempting to upload a bunch of text as a gzip file.

silverstripe/queuedjobs

  • QueuedJobsTest.testImmediateQueuedJob - Test self-aborts when detecting lack of available system resources (inconclusive).
  • QueuedJobsTest.testStartJob - Test self-aborts when detecting lack of available system resources (inconclusive).

silverstripe/translatable

silverstripe/userforms

  • UserDefinedFormControllerTest.testValidation - Test failure affected by global state (starter theme template overrides).
  • UserDefinedFormControllerTest.testRenderingIntoFormTemplate - Test failure affected by global state.
  • UserDefinedFormControllerTest.testRenderingIntoTemplateWithSubstringReplacement - Test failure affected by global state.

Change Log

Security

  • 2017-05-24 41270fcf Only allow HTTP(S) links for external redirector pages (Daniel Hensby) - See ss-2017-003
  • 2017-05-09 447ce0f84 Lock out users who dont exist in the DB (Daniel Hensby) - See ss-2017-002
  • 2017-05-09 61cf72c0 Unescaped fields in CMSPageHistroyController::compare() (Daniel Hensby) - See ss-2017-004

API Changes

  • 2017-04-28 457a8a7 Moving placeholder variable to EditableFormField (#581) (3Dgoo)
  • 2017-03-07 c7107d2 Add ability to disable page utilities for a page (Robbie Averill)
  • 2017-03-07 f4ea811 Move most user controllable custom SiteConfig settings to agency-extensions module (Robbie Averill)
  • 2017-03-06 f484290 Add getSelectedLanguage method to BasePage, rename BasePageTests so they run (Robbie Averill)
  • 2017-03-05 f1b99b6fa Enable theming of GroupedDropdownField (Damian Mooyman)
  • 2017-03-03 b254897 Remove carousel, deprecate BasePage methods for default theme. Carousel has moved to agency-extensions. (Robbie Averill)
  • 2017-03-02 b09c0f3 Add BuildTask to populate sample data, starting with a contact user form (Robbie Averill)
  • 2017-01-23 3583f1f79 Convert::raw2json can be passed an optional bitmask of JSON constants as options (Robbie Averill)

Features and Enhancements

  • 2017-04-27 a94f0e3 Implemented and/or display rules for UserForms (Franco Springveldt)
  • 2017-04-20 7983a7f added an extension point to UserDefinedForm.finished (Juan van den Anker)
  • 2017-04-12 1a651880 Make page urls bookmarkable (Damian Mooyman)
  • 2017-04-03 40bf94532 PHP 7 compatibility (Loz Calver)
  • 2017-01-13 88f90bfc7 Merge pull request #6499 from SilbinaryWolf/feat-decoratorsetlist (Damian Mooyman)
  • 2016-12-13 d0bf02d Add autocomplete to EditableTextField (Elliot Goode)
  • 2016-12-13 52cad6ce9 Added ImagickBackend::crop() for compatibility with GDBackend (UndefinedOffset)
  • 2016-12-05 b4ba606ff HTMLEditorField default alignment setting (Damian Mooyman)
  • 2016-12-02 24dc3428d HTMLEditorField default alignment setting (Jonathon Menz)
  • 2016-11-16 6e10acf setEmptyString option on EditableDropdown (Nic Horstmeier)
  • 2016-10-31 776d2fbc6 Allow setting of unlimited row counts on GridFieldPaginator (Daniel Hensby)

Bugfixes

  • 2017-06-01 d353aba Update changelog prefix number. 04 is now performance guides. (Robbie Averill)
  • 2017-05-30 51164768 Issue where CMS SiteTree can result in infinite recursion if parent and child relation is swapped (Daniel Hensby)
  • 2017-05-28 16a74bc8a DataDifferencer needs to expliclty cast HTMLText values (Daniel Hensby)
  • 2017-05-24 e86306c incorrect calculation of MAX_FILE_SIZE (#600) (Reece Alexander)
  • 2017-05-24 ca1e2ab Remove empty column in display logic GridField for form field (Sacha Judd)
  • 2017-05-22 7c3edd4 Hide and show form fields by toggling the "hide" class instead of jQuery methods (Robbie Averill)
  • 2017-05-17 11f43c2 Make EditableLiteralField extensible, have its own template, honour visibility rules (Robbie Averill)
  • 2017-05-11 33cc3a1 Ensure that version feeds are enabled by default in tests (Robbie Averill)
  • 2017-05-11 fc309d0 SitemapTest referencing default theme, changed to use starter (Robbie Averill)
  • 2017-05-08 14540729 Use framework 3.5 to test cms 3.5 (Sam Minnee)
  • 2017-05-03 2d138b0ef class name reference consistency (Gregory Smirnov)
  • 2017-05-02 2187c160b ing pagination api doc typo (3Dgoo)
  • 2017-04-28 a511e3511 #6855: Mangled JS in Requirements, escaping replacement values prior to passing to preg_replace(). (Patrick Nelson)
  • 2017-04-26 1ff6f3f1 ing doArchive (John Milmine)
  • 2017-04-26 000a5f72 Fix page history / settings forms (Damian Mooyman)
  • 2017-04-24 1d36f354e Create Image_Cached with Injector. (Gregory Smirnov)
  • 2017-04-21 7e777532 intl test (Daniel Hensby)
  • 2017-04-07 41eddfcc ing cms page history controller to use new page id param (Tim Kung)
  • 2017-04-07 55eb7ebdc Do not insert requirements more than once in includeInHTML (Robbie Averill)
  • 2017-04-05 85d5dd3 array to string conversion error (Rob Ingram)
  • 2017-04-05 a7920b1f9 regression from #6668 - ModelAdmin form widths (Loz Calver)
  • 2017-04-05 197bc53c4 Add transparency percent argument to Image::generatePad to ensure transparency works from ::Pad (Robbie Averill)
  • 2017-04-05 80e89673 Fix VirtualPage::init() content-modification check. (Sam Minnee)
  • 2017-04-04 2ddb6168 Correct case of CopyContentFrom method (Daniel Hensby)
  • 2017-04-04 ec15c713 Add __isset to VirtualPage for PHP7 support. (Daniel Hensby)
  • 2017-04-04 ae0fe75fb non-numeric warnings in GDBackend/ImagickBackend (Loz Calver)
  • 2017-04-04 f101697f8 File::ini2bytes() in PHP 7 (Loz Calver)
  • 2017-04-04 e22cd4db0 TabSet attempting to access undeclared property (Loz Calver)
  • 2017-04-04 f083a06f3 Fix ViewableData::__isset() for getXXX() getters. (Sam Minnee)
  • 2017-04-03 e5f51b14 Relax PHP version requirement. (Sam Minnee)
  • 2017-04-03 454646c4d invalid closure param in ShortcodeParserTest (Loz Calver)
  • 2017-04-03 82f62c818 illegal string offset in spyc component (Loz Calver)
  • 2017-04-02 bf39169 casting bug with email previews (#549) (Loz Calver)
  • 2017-03-23 b3d37880e many_many_extraFields breaks _SortColumn0 ordering (fixes #6730) (Loz Calver)
  • 2017-03-16 4d83481 Remove double (required) label, add translations to the text (Robbie Averill)
  • 2017-03-16 dc85ba9 Ensure "cwp" module Page CMS fields are added before extension hooks are run (Robbie Averill)
  • 2017-03-15 5a22f6f Improve delete reply confirmation message (Robbie Averill)
  • 2017-03-14 cd0aee9 CWPT-475: Remove extra spaces in external links around nonvisual-indicator span, breaks ::after (Robbie Averill)
  • 2017-03-12 cc749d3a1 Give DatetimeField its own template (which is extensible) (Robbie Averill)
  • 2017-03-10 c349ae9 Use non-destructive pubilshing for editable options (Damian Mooyman)
  • 2017-03-08 bbaf427 Fix delete / unpublish (Damian Mooyman)
  • 2017-03-06 a428d0c DateRangeForm construction and script inclusion order (Damian Mooyman)
  • 2017-03-03 37a1c3a Add localisation to FilterDescription terms (Robbie Averill)
  • 2017-03-02 707fb30 twitter Bootstrap links (Brett Tasker)
  • 2017-02-21 f647b1c , check whether sortable exists before trying to use it. (Nathan Glasl)
  • 2017-02-15 e3eb082 (WorkflowPublishTargetJob) Use draft stage (Marcus Nyeholt)
  • 2017-02-15 30725916d Array to string conversion message after CSV export (#6622) (Juan van den Anker)
  • 2017-02-14 7122e1fde Comments ignored by classmanifest (#6619) (Daniel Hensby)
  • 2017-02-14 bb000ca Change delete() to deleteFromStage() for EditableMultipleOptionField::doPublish(). This fixes the issue where options were being removed from the draft table instead of the Live table, effectively deleting them from the CMS (#545) (Danae)
  • 2017-02-09 6e2797ffc es for using dblib PDO driver. (Andrew O'Neil)
  • 2017-02-08 c25c443d9 Fix minor mysql 5.7 warning in SQLQueryTest (#6608) (Damian Mooyman)
  • 2017-01-30 8c27891 for #185 and #194 (#539) (torleif)
  • 2017-01-18 72b6fb49b bug: In addOrderBy method, _SortColumn will only keep the last one if there are more than 1 multi-word columns (Shawn)
  • 2017-01-15 4f9800e Travis builds broken with external code coverage (Robbie Averill)
  • 2016-12-13 1743ed1 Fix issue with UserFormsCheckboxSetField (Damian Mooyman)
  • 2016-12-13 63f096f Stop the default SolrSearchIndex from using addAllFulltextFields() (Matt Peel)
  • 2016-12-08 dc530c0 es #529 (torleif)
  • 2016-11-30 cbdb7d4 Prevent duplicate HTML IDs when adding new records inline (Loz Calver)
  • 2016-11-28 1732269 upgrading notes for auditor module (Damian Mooyman)
  • 2016-11-20 aa171f8 Enable Shortcode parsing for the Content in EditableLiteralField (Damian Mooyman)
  • 2016-10-26 22ad39e5a Fix SSViewerTest in PHP7 (Sam Minnee)
  • 2016-10-16 86f1778 (GridFieldAddNewMultiClass): Fix bug where class doesn't exist. (ie. ClassInfo says the class exists, but PHP itself doesn't, since ClassInfo is based on parsed tokens) (Jake Bentvelzen)
  • 2016-10-12 d722881 Swap DataList code to SS_List (Marcus Nyeholt)
  • 2015-08-28 f224849cc Don’t use SplFixedArray in PHP 7. (Sam Minnee)
  • 2015-08-27 cca7e9697 Correct PHP4-style constructors in SimpleTest. (Sam Minnee)

Was this article helpful?