This upgrade includes CMS and Framework version 4.1.1

Upgrade to Recipe 2.0.0 is optional, but is recommended as the base to start all new CWP projects from.

Upgrading Instructions

This is a major version change, and will require a fair amount of input from developers. All notes from the SilverStripe core team regarding general upgrades to Framework version 4 will need to be adhered to, and there should be appropriate investment in regression testing changes before release.

There is a new recipe format for CWP 2, providing a more modular approach to constructing your site. However, there is still the cwp/cwp-installer recipe, which provides feature parity in terms of functionality as it did with CWP 1.x.

In particular, if one is to replace cwp/cwp-recipe-basic, the following combination of new recipes should be used:

    "require": {
        "php": ">=5.6.0",
        "silverstripe/recipe-plugin": "^1",
        "cwp/cwp-recipe-cms": "2.0.0@stable",
        "cwp/cwp-recipe-core": "2.0.0@stable",
        "cwp/cwp-recipe-search": "2.0.0@stable",
        "silverstripe/recipe-blog": "1.0.0@stable",
        "silverstripe/recipe-form-building": "1.0.0@stable",
        "silverstripe/recipe-authoring-tools": "1.0.0@stable",
        "silverstripe/recipe-collaboration": "1.0.0@stable",
        "silverstripe/recipe-reporting-tools": "1.0.0@stable",
        "silverstripe/recipe-services": "1.0.0@stable",
        "silverstripe/subsites": "2.0.2@stable",
        "tractorcow/silverstripe-fluent": "4.0.2@stable",
        "silverstripe/registry": "2.0.1@stable",
        "cwp/starter-theme": "2.0.0@stable"

More information on upgrading major versions of CWP can be found in the online documentation

Please note that the following modules have been superseded and do not have a direct upgrade path:

  • silverstripe/translatable has been replaced by tractorcow/silverstripe-fluent
  • silverstripe/active-directory has been split into silverstripe/ldap (commercially supported) and silverstripe/saml (not commercially supported)
  • undefinedoffset/sortablegridfield was a dependency of supported modules, which have been updated to use the equivalent functionality provided by symbiote/silverstripe-gridfieldextensions. If your project makes use of this module, it will need to specifically require it rather than assume its presence (if it does not already).
  • silverstripe/selectupload is deprecated and is not upgraded for SilverStripe 4
  • silverstripe/secureassets has been replaced by SilverStripe core functionality
  • silverstripe/versionedfiles has been replaced by SilverStripe core functionality

The following optional CWP modules are yet to be upgraded for CWP 2.0 compatibility:

  • silverstripe/realme
  • silverstripe/textextraction

Notable changes

  • The minimum PHP version has been raised to 5.6 or higher.
  • All web server requests will be served from the /public project subfolder (see point below).
  • All module classes have had PHP namespaces added, and template file locations may have changed to support this.
  • Previously deprecated code has been removed. This includes the following:
    • BasePage::getBaseStyles: use the starter theme instead.
    • BasePage::getBaseScripts: use the starter theme instead.
    • SitemapPageController::Page: use the showpage() action instead.
    • CwpSolr::options_from_environment: use the implicit Solr configuration provided by the CwpSolr class in the cwp-core module.
  • Search related classes have been moved from cwp/cwp and cwp/cwp-core to cwp/cwp-search.
  • Public search related properties in BasePageController have been moved to SearchControllerExtension in the cwp/cwp-search module, and converted to configuration options:
    • $results_per_page
    • $classes_to_search
    • $search_index_class removed, use Injector::inst()->get(\CWP\Search\CwpSearchEngine::class . '.search_index') instead.
  • BasePage::getAvailableTranslations has been removed, use FluentExtension::Locales instead ($Locales from a template).
  • All PDF export functionality from BasePage and BasePageController has been removed and moved to a new module cwp/cwp-pdfexport.
  • CwpStatsReport has been moved from the cwp/cwp-core module to cwp/cwp.
  • CwpControllerExtension has been removed:
    • CwpControllerExtension.ssl_redirection_enabled moved to configuration in security.yml.
    • CwpControllerExtension.ssl_redirection_force_domain moved to configuration in security.yml.
    • Forced SSL rules and domain policies have been implemented with core middleware configurations settings - see cwp-core/_config/security.yml.
    • IP whitelisting rules for basic authentication have been moved to CwpBasicAuthMiddleware.

Public webroot

CWP 2.0 enforces the default SilverStripe 4.1 configuration to serve web requests from the /public project subfolder. This also applies to any frontend CSS, JavaScript and images that are exposed from modules and project code, as well as assets uploaded via the CMS.

The Common Web Platform servers set their webroot to your project root, but are automatically sending all requests to the /public folder via an .htaccess passthrough.

When configuring your local development environment, either set /public as the document root, or ensure that you're respecting the .htaccess passthrough. Also ensure that you prepend your themes configuration list to contain $public.

For more information please see here, but note that this configuration is mandatory in CWP 2.0.

Security changes

The CwpControllerExtension has been removed, which handled logic for UAT environment logins and basic authentication rule exclusions for users given a "can access UAT site" permission, IP address whitelisting for basic authentication and SSL redirection for specific URLs in test and live environments.

The IP whitelisting logic has been moved to CwpBasicAuthMiddleware, and will still be configured to read the CWP_IP_BYPASS_BASICAUTH environment variable by default. For more information on these configuration settings please see cwp-core/_config/security.yml.

This release removes the following file extensions from the default whitelist of accepted types for uploaded files: dotm, potm, jar, css, js and xltm.

If you require the ability to upload these file types in your projects, you will need to add them back in again. For more information, see "Configuring: File types".

For a detailed list of changes, see the full changelog below.

Accepted Failing Tests


  • SilverStripe\Assets\Tests\UploadTest::testUploadTarGzFileTwiceAppendsNumber: This test is now expected to fail as the 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 text as a gzip file (issue).

  • SilverStripe\Forms\Tests\EmailFieldTest::testEmailFieldPopulation (issue)

  • SilverStripe\Forms\Tests\FormTest::testValidationExemptActions (issue)

  • SilverStripe\Forms\Tests\FormTest::testSessionValidationMessage (issue)

  • SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest::testValidator (issue)

  • SilverStripe\Forms\Tests\LookupFieldTest::testNullValueWithNumericArraySource (issue)

  • SilverStripe\Forms\Tests\LookupFieldTest::testUnknownStringValueWithNumericArraySource (issue)

  • SilverStripe\Forms\Tests\LookupFieldTest::testArrayValueWithAssociativeArraySource (issue)

  • SilverStripe\Forms\Tests\LookupFieldTest::testArrayValueWithNumericArraySource (issue)

  • SilverStripe\Forms\Tests\LookupFieldTest::testArrayValueWithSqlMapSource (issue)

  • SilverStripe\Forms\Tests\LookupFieldTest::testWithMultiDimensionalSource (issue)

  • SilverStripe\Forms\Tests\SelectionGroupTest::testSelectedFieldHolder (issue)

  • SilverStripe\Forms\Tests\TreeDropdownFieldTest::testReadonly (issue)

  • SilverStripe\Assets\Tests\FileTest::testCanEdit (issue)

  • SilverStripe\Assets\Tests\FileTest::testCanCreate (issue)

  • SilverStripe\Assets\Tests\UploadTest::testPHPUploadErrors (issue)

  • SilverStripe\Control\Tests\DirectorTest::testForceSSLProtectsEntireSite (fix)

  • SilverStripe\Control\Tests\DirectorTest::testForceSSLandForceWWW (fix)


  • SilverStripe\CMS\Tests\Model\SiteTreeFolderExtensionTest::testFindsFiles: Affected by global test state (issue).

  • SilverStripe\AssetAdmin\Tests\Controller\AssetAdminTest::testSaveOrPublish (issue)

  • SilverStripe\CMS\Tests\Model\SiteTreeTest::testCanEditWithAccessToAllSections (issue)

  • SilverStripe\CMS\Tests\Model\SiteTreeTest::testCanPublish (issue)


  • SilverStripe\Comments\Tests\CommentingControllerTest::testRSS: Validated to not be an issue in practice (issue)
  • SilverStripe\Comments\Tests\CommentingControllerTest::testCommentsForm: Validated to not be an issue in practice (issue)
  • SilverStripe\Comments\Tests\CommentsExtensionTest::testCommentsForm (issue)


There are numerous test errors relating to missing database tables which are tests affected by global state (issue).

  • DNADesign\Elemental\Tests\ElementalAreaTest::testCanBePublished: Affected by global state (issue)
  • DNADesign\Elemental\Tests\Reports\ElementTypeReportTest::testReportShowsBlockTypes


  • SilverStripe\UserForms\Tests\Control\UserDefinedFormControllerTest::testRenderingIntoFormTemplate: Affected by starter theme templates (issue)
  • SilverStripe\UserForms\Tests\Control\UserDefinedFormControllerTest::testRenderingIntoTemplateWithSubstringReplacement: Affected by starter theme templates (issue)
  • Symbiote\QueuedJobs\Tests\QueuedJobsTest::testStartJob: Affected by global state (issue)
  • Symbiote\QueuedJobs\Tests\QueuedJobsTest::testImmediateQueuedJob: Affected by global state (issue)


  • SilverStripe\VersionFeed\Tests\VersionFeedTest::testDiffedChangesTitle: Compatibility issue with tractorcow/silverstripe-fluent (issue)


Error: Class 'org\bovigo\vfs\vfsStream' not found: the silverstripe/config suite will fail without this dev dependency installed in your project.

Change Log


  • 2018-05-24 3bddea7 Prevent php code execution in assets folder, and remove file extensions (Robbie Averill) - See ss-2018-012
  • 2018-04-26 02db1cc Update jQuery version, remove entwine from frontend use (Dylan Wagstaff) - See ss-2018-015
  • 2018-04-26 d665f60 Update jQuery version used in templates (Dylan Wagstaff) - See ss-2018-015
  • 2018-04-26 238ae51 Update jQuery version used in templates (Dylan Wagstaff) - See ss-2018-015
  • 2018-04-26 299131ed2 File security documentation (Damian Mooyman) - See ss-2018-012
  • 2018-04-25 be96858 Remove jar, dotm, potm, xltm from file extension whitelist, hard-code CSS and JS for TinyMCE support (Robbie Averill) - See ss-2018-014
  • 2018-04-24 f847f186b Remove password text from session data on failed submission (Aaron Carlino) - See ss-2018-013
  • 2018-04-23 aa365e0 Remove dotm, potm, jar, css, js, xltm from default File.allowed_extensions (Robbie Averill) - See ss-2018-014
  • 2018-04-23 cf330de Enforce HTTPS for all URLs when in test mode (Robbie Averill) - See ss-2018-009
  • 2018-04-23 f9c03fa Prevent php code execution in assets folder (Damian Mooyman) - See ss-2018-012
  • 2018-04-23 1e27835 Prevent php code execution in assets folder (Damian Mooyman) - See ss-2018-012
  • 2018-04-22 beec0c0d4 regression of SS-2017-002 (Robbie Averill) - See ss-2018-010
  • 2018-04-19 b2c5576 Fix search term escaping to prevent possible SQL injection attack (Robbie Averill) - See ss-2018-11
  • 2018-04-11 e409d6f67 Restrict non-admins from being assigned to admin groups (Damian Mooyman) - See ss-2018-001
  • 2018-04-10 9053014a7 Validate against malformed urls (Damian Mooyman) - See ss-2018-008
  • 2018-04-10 2e13ae746 Prevent code execution in template value resolution (Damian Mooyman) - See ss-2018-006
  • 2018-04-09 db04ed9 Remove on* events as allowed properties (Damian Mooyman) - See ss-2018-004
  • 2018-04-08 d935140a9 Prevent unauthenticated isDev / isTest being allowed (Damian Mooyman) - See ss-2018-005

API Changes

  • 2018-04-03 3e0cae0 Reintroduce abstract handler (previously removed in 192ddbb) and deprecate for future removal (Robbie Averill)
  • 2018-03-21 100be38 Remove use of getEscapedTitle() and deprecated for future removal. Use $Title directly instead. (Robbie Averill)
  • 2018-03-15 1f3fa7f Rename doUnpublish to onAfterUnpublish to prevent collisions with Versioned (Robbie Averill)
  • 2018-03-14 991fb0c Deprecate bind_manipulation_capture() and onBeforeInit() in AuditHook (Robbie Averill)
  • 2018-02-26 404d4dc Shift default comment extension from SiteTree to Blog and BlogPost (Robbie Averill)
  • 2018-02-25 192ddbb Use concrete Handler implementations for Spam and Approve bulk editing (Robbie Averill)
  • 2018-01-25 0e5f792 Update version (Raissa North)
  • 2018-01-25 79f07a2 Add namespaces (Raissa North)
  • 2018-01-24 590157b Update template file structure to align with namespacing (Raissa North)
  • 2018-01-10 5496abd Switch Translatable implementation for Fluent (Robbie Averill)
  • 2017-12-22 168cc1e Move other CWP templates to match new namespaces (Robbie Averill)
  • 2017-12-21 d3ab3be Move Sitemap page template into new namespaces cwp/cwp location (Robbie Averill)
  • 2017-10-31 4e596df Rename namespaces core and userforms templates, remove CreditCardField and PhoneNumberField (Robbie Averill)
  • 2017-10-31 7df9e65 Move Google Analytics to its own include template (Robbie Averill)
  • 2017-10-31 8a80d9b Update theme references and enable silverstripe-elemental if installed (Robbie Averill)
  • 2017-10-31 cf18c56 Use themed requirements and add SS4 as a dependency (Robbie Averill)

Features and Enhancements

  • 2018-04-13 24ff267 Ability to inject a different process manager class. (Frank Mullenger)
  • 2018-04-08 fa2bb55 Replace HeaderField with LiteralField (Raissa North)
  • 2018-04-04 ee6b9c8 Allow ProcessManager log path to be configurable via environment variable (Robbie Averill)
  • 2018-03-20 7a3e2d0 Allow autoconfigure to be disabled via configuration (Robbie Averill)
  • 2018-03-14 3f24858 added MinutesToRead() (zanderwar)
  • 2018-03-14 1e2ef35 Implement Database manipulate() method proxy for audit hook (Robbie Averill)
  • 2018-03-14 e7420a5 Update to use proxied DB instead of self-proxied (Raissa North)
  • 2018-02-23 6e5b37e Add SearchVariant::withCommon to run callbacks on relevant variants rather than all (Robbie Averill)
  • 2018-02-13 d241585 Add htaccess rule to rewrite traffic to public web directory (Robbie Averill)
  • 2018-01-24 4cc11d2 Update copyright date (Raissa North)
  • 2017-12-21 4d60f01 add test for a --no-dev build (Christopher Joe)
  • 2017-12-20 35fa3c3 Convert to vendor module, update use of cli-script with sake and some readme examples (Robbie Averill)
  • 2017-11-14 47f87be Log job output into the job messages. (Sam Minnee)
  • 2017-11-13 1f0d551 Add DeleteAllJobsTask (Sam Minnee)
  • 2017-11-10 a99f165 Allow queueing of build tasks (Sam Minnee)
  • 2017-11-01 cfd4c3e Add margin to bottom of file block (Robbie Averill)
  • 2017-11-01 66621b8 Add styles for banner block (Robbie Averill)


  • 2018-05-28 e272422 Refactor starter theme readme for consistency (Sacha Judd)

  • 2018-05-23 e7e32d13a Add namespace and encryptor to tests that expect blowfish to be available (Robbie Averill)

  • 2018-05-22 a0230a3 Manually replace Maori with Māori (intl bug) (Robbie Averill)

  • 2018-05-18 c7ab8df broken links (Raissa North)

  • 2018-05-18 4913290 Add extension to remap polymorphic relationship classes for Parent and Form fields (Robbie Averill)

  • 2018-05-09 8f363d6 Remove unnecessary translation of parameterised field value (Raissa North)

  • 2018-05-03 a40daef Set default_locale to en_NZ, and allow errors to be returned as 200 OK (Robbie Averill)

  • 2018-05-03 a3b586a Allow configurable default locale, or use the first defined locale (Robbie Averill)

  • 2018-05-03 c0bd59c Allow errors to be returned with 200 header codes (Robbie Averill)

  • 2018-04-23 838ce23 regex in performance guide htaccess rules (Tomas Cantwell)

  • 2018-04-22 dca8ae5 regex issue in performance docs (Tomas Cantwell)

  • 2018-04-20 b4943fb Automatically create default SiteTree records for new subsites (Robbie Averill)

  • 2018-04-20 f47a222 Unentice direct BasePage creation in the CMS (Dylan Wagstaff)

  • 2018-04-15 4d333b2 Move directory controller template into correct location (Robbie Averill)

  • 2018-04-11 caab511 the each loop to propperly get the field passed in (Simon Erkelens)

  • 2018-04-08 cbca821 comply with psr-2 (Andreas Piening)

  • 2018-04-08 d0149f8 add missing canView check in json (Andreas Piening)

  • 2018-04-06 30704f5 Update path to template (Raissa North)

  • 2018-04-05 b4aae0f Remove attempt to import environment into conifg for docvert (Dylan Wagstaff)

  • 2018-04-05 39044de Use correct CacheInterface API methods and remove doubled up logic (Robbie Averill)

  • 2018-04-04 a886f68 reintroduce extension hook for comment form rendering (Raissa North)

  • 2018-04-04 d45a407 make RestfulServer:: configurable (Andreas Piening)

  • 2018-04-03 4544cd3 module references and mention base module (Ingo Schommer)

  • 2018-04-03 7eba03a Switch example date format to match HTML5 datetime field format (Robbie Averill)

  • 2018-04-03 fbabf03 Use CLDR date formats and check for namespaced class names in conditions (Robbie Averill)

  • 2018-04-03 866619f Encode entities appropriately using the new core method (Dylan Wagstaff)

  • 2018-04-03 ff885e9 Remove rogue nbsp; from Start Time field labels (Robbie Averill)

  • 2018-04-03 b450b5c Only add File_ShowInSearch if File class is in query (Raissa North)

  • 2018-04-03 2b3b0c8 Cast IFrameURL right title as HTMLText to avoid double escaping (Robbie Averill)

  • 2018-03-29 0ca0b2c let CompositeField subclasses render themselves (Dylan Wagstaff)

  • 2018-03-29 0ca0b2c let CompositeField subclasses render themselves (Dylan Wagstaff)

  • 2018-03-26 9996e38 use correct case vars to correctly render (Dylan)

  • 2018-03-23 7e9f6ce Handle nullable $original object argument in onAfterPublish (Robbie Averill)

  • 2018-03-23 f7ffb70 Use userforms template for member list field, fixes display rule issue (Robbie Averill)

  • 2018-03-21 d1943c8 Rename dropdown field template, fixes #35 (Robbie Averill)

  • 2018-03-21 282d0d4 Correct template names for checkbox and checkbox set/group templates (Robbie Averill)

  • 2018-03-21 a833161 Move textarea field template to the correct filename, remove old field template and holder (Robbie Averill)

  • 2018-03-21 177656b Correctly render optionset fields with their labels inline (Robbie Averill)

  • 2018-03-20 bb3e9d6 Missing use statement for ProcessManager (Gordon Anderson)

  • 2018-03-20 be166bd Correct unprocessed count variable in translation for step progress (Robbie Averill)

  • 2018-03-20 9bb639d Remove reference to incorrect blog stylesheet (Robbie Averill)

  • 2018-02-26 4413db4 use appropriate constraints for our CI testing (Dylan Wagstaff)

  • 2018-02-25 ceba6c1 Update requirements & travis config to be consistent with acutal requirements (Dylan Wagstaff)

  • 2018-02-22 cf51eba Move template to correct location for SearchForm_header, update translation keys in Header template (Robbie Averill)

  • 2018-02-20 e91d10e Update resource references to actual locations (Dylan Wagstaff)

  • 2018-02-20 7e2a86d don't try to test non existent files (Dylan Wagstaff)

  • 2018-02-20 1f5e156 also expose ico and images from module root (Dylan Wagstaff)

  • 2018-02-20 6ad5822 expose public resources since it's necessary (Dylan Wagstaff)

  • 2018-02-06 5bff64b47 Fix Director::test() not persisting removed session keys on teardown (Damian Mooyman)

  • 2018-02-05 9a8c290 Tidy up, fix classname errors (Raissa North)

  • 2018-01-25 eca83bb Add class to re-enable click action (Raissa North)

  • 2018-01-24 8632bc6 Replace deprecated setWidth/Height functions with scaleWidth/Height (Raissa North)

  • 2018-01-24 4abe8e8 Fix EventHolder namespace (Raissa North)

  • 2018-01-23 ab67e5c Update to CLDR date format and update namespaces in PageUtilities (Robbie Averill)

  • 2018-01-09 5e6bbf8 Update form message handling to match core Form.ss template (Robbie Averill)

  • 2017-12-07 c96d479 Core has SearchForm template as an Include, copy this layout (Dylan Wagstaff)

  • 2017-11-07 4efffca Add max-height to banner block (Robbie Averill)

Was this article helpful?