Base CliController or BuildTask instead, with custom cron job intervals.
11 KiB
3.1.0 (unreleased)
Overview
CMS
- "Split view" editing with side-by-side preview of the edited website
- Resizing of preview to common screen widths ("desktop", "tablet" and "smartphone")
- Decluttered "Edit Page" buttons by moving minor actions into a "more options" panel
- Auto-detect CMS changes and highlight the save button for better informancy
- Display "last edited" and "last published" data for pages in CMS
- CMS form fields now support help text through
setDescription()
, both inline and as tooltips - Removed SiteTree "MetaTitle" and "MetaKeywords" fields
- More legible and simplified tab and menu styling in the CMS
Framework
DataList
andArrayList
are now immutable, they'll return cloned instances on modification- Behaviour testing support through Behat, with CMS test coverage (see the SilverStripe Behat Extension for details)
- Removed legacy table APIs (e.g.
TableListField
), use GridField instead - Deny URL access if
Controller::$allowed_actions
is undefined - Removed support for "*" rules in
Controller::$allowed_actions
- Removed support for overriding rules on parent classes through
Controller::$allowed_actions
- Editing of relation table data (
$many_many_extraFields
) inGridField
- Optional integration with ImageMagick as a new image manipulation backend
- Support for PHP 5.4's built-in webserver
- Support for Composer dependency manager (also works with 3.0)
Upgrading
Deny URL access if Controller::$allowed_actions
is undefined or empty array
In order to make controller access checks more consistent and easier to
understand, the routing will require definition of $allowed_actions
on your own Controller
subclasses if they contain any actions
accessible through URLs, or any forms.
:::php
class MyController extends Controller {
// This action is now denied because no $allowed_actions are specified
public function myaction($request) {}
}
Please review all rules governing allowed actions in the "controller" topic.
Removed support for "*" rules in Controller::$allowed_actions
The wildcard ('*') character allowed to define fallback rules in case they weren't explicitly defined. This caused a lot of confusion, particularly around inherited rules. We've decided to remove the feature, you'll need to specificy each accessible action individually.
:::php
class MyController extends Controller {
public static $allowed_actions = array('*' => 'ADMIN');
// Always denied because not explicitly listed in $allowed_actions
public function myaction($request) {}
// Always denied because not explicitly listed in $allowed_actions
public function myotheraction($request) {}
}
Please review all rules governing allowed actions in the "controller" topic.
Removed support for overriding rules on parent classes through Controller::$allowed_actions
Since 3.1, the $allowed_actions
definitions only apply
to methods defined on the class they're also defined on.
Overriding inherited access definitions is no longer possible.
:::php
class MyController extends Controller {
public static $allowed_actions = array('myaction' => 'ADMIN');
public function myaction($request) {}
}
class MySubController extends MyController {
// No longer works
public static $allowed_actions = array('myaction' => 'CMS_ACCESS_CMSMAIN');
}
This also applies for custom implementations of handleAction()
and handleRequest()
,
which now have to be listed in the $allowed_actions
specifically.
It also restricts Extension
classes applied to controllers, which now
can only grant or deny access or methods they define themselves.
New approach with the Config API
:::php
class MySubController extends MyController {
public function init() {
parent::init();
Config::inst()->update('MyController', 'allowed_actions',
array('myaction' => 'CMS_ACCESS_CMSMAIN')
);
}
}
Please review all rules governing allowed actions in the "controller" topic.
Grouped CMS Buttons
The CMS buttons are now grouped, in order to hide minor actions by default and declutter the interface.
This required changing the form field structure from a simple FieldList
to a FieldList
which contains a CompositeField
for all "major actions",
and a TabSet
with a single tab for all "minor actions".
If you have previously added, removed or altered built-in CMS actions in any way,
you'll need to adjust your code.
:::php
class MyPage extends Page {
function getCMSActions() {
$actions = parent::getCMSActions();
// Inserting a new toplevel action (old)
$actions->push(new FormAction('MyAction'));
// Inserting a new toplevel action (new)
$actions->insertAfter(new FormAction('MyAction'), 'MajorActions');
// Removing an action, both toplevel and nested (no change required)
$actions->removeByName('action_unpublish');
// Inserting a new minor action (new)
$actions->addFieldToTab(
'Root.ActionMenus.MoreOptions',
new FormAction('MyMinorAction')
);
// Finding a toplevel action (no change required)
$match = $actions->dataFieldByName('action_save');
// Finding a nested action (new)
$match = $actions->fieldByName('ActionMenus.MoreOptions')
->fieldByName('action_MyMinorAction');
return $actions;
}
}
GridField and ModelAdmin Permission Checks
GridFieldDetailForm
now checks for canEdit()
and canDelete()
permissions
on your model. GridFieldAddNewButton
checks canCreate()
.
The default implementation requires ADMIN
permissions.
You'll need to loosen those permissions if you want other users with CMS
access to interact with your data.
Since GridField
is used in ModelAdmin
, this change will affect both classes.
Example: Require "CMS: Pages section" access
:::php
class MyModel extends DataObject {
public function canView($member = null) {
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
}
public function canEdit($member = null) {
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
}
public function canDelete($member = null) {
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
}
public function canCreate($member = null) {
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
}
You can also implement custom permission codes. For 3.1.0 stable, we aim to further simplify the permission definitions, in order to reduce the boilerplate code required to get a model editable in the CMS.
Note: GridField is already relying on the permission checks performed through the CMS controllers, providing a simple level of security.
Other
TableListField
,ComplexTableField
,TableField
,HasOneComplexTableField
,HasManyComplexTableField
andManyManyComplexTableField
have been removed from the core and placed into a module called "legacytablefields" located at https://github.com/silverstripe-labs/legacytablefieldsprototype.js
andbehaviour.js
have been removed from the core, they are no longer used. If you have custom code relying on these two libraries, please update your code to include the files yourselfObject::has_extension()
andObject::add_extension()
deprecated in favour of using late static binding, please use{class}::has_extension()
and{class}::add_extension()
instead, where {class} is the class name of your DataObject class.- Removed
SiteTree.MetaKeywords
since they are irrelevant in terms of SEO (seomoz article) and general page informancy - Removed
SiteTree.MetaTitle
as a means to customize the window title, useSiteTree.Title
instead - Deprecated
Profiler
class, use third-party solutions like xhprof - Removed defunct or unnecessary debug GET parameters:
debug_profile
,debug_memory
,profile_trace
,debug_javascript
,debug_behaviour
- Removed
Member_ProfileForm
, useCMSProfileController
instead SiteTree::$nested_urls
enabled by default. To disable, callSiteTree::disable_nested_urls()
.- Removed CMS permission checks from
File->canEdit()
andFile->canDelete()
. If you have unsecured controllers relying on these permissions, please override them through aDataExtension
. - Moved email bounce handling to new "emailbouncehandler" module,
including
Email_BounceHandler
andEmail_BounceRecord
classes, as well as theMember->Bounced
property. - Deprecated global email methods
htmlEmail()
andplaintextEmail
, as well as various email helper methods likeencodeMultipart()
. Use theEmail
API, or theMailer
class where applicable. - Removed non-functional
$inlineImages
option for sending emails - Removed support for keyed arrays in
SelectionGroup
, use newSelectionGroup_Item
object to populate the list instead (see API docs). FormField->setDescription()
now renders in a<span class="description">
by default, rather than atitle
attribute * RemovedForm->Name()
: Use getName()- Removed
FormField->setContainerFieldSet()
: Use setContainerFieldList() - Removed
FormField->rootFieldSet()
: Use rootFieldList() - Removed
Group::map()
: Use DataList::("Group")->map() - Removed
Member->generateAutologinHash()
: Tokens are no longer saved directly into the database in plaintext. Use the return value of the Member::generateAutologinTokenAndHash to get the token - Removed
Member->sendInfo()
: use Member_ChangePasswordEmail or Member_ForgotPasswordEmail directly - Removed
SQLMap::map()
: Use DataList::("Member")->map() - Removed
SQLMap::mapInGroups()
: Use Member::map_in_groups() - Removed
PasswordEncryptor::register()/unregister()
: Use config system instead - Methods on DataList and ArrayList that used to both modify the existing list & return a new version now just return a new version. Make sure you change statements like
$list->filter(...)
to $list = $list->filter(...)
for these methods:ArrayList#reverse
ArrayList#sort
ArrayList#filter
ArrayList#exclude
DataList#where
DataList#limit
DataList#sort
DataList#addFilter
DataList#applyFilterContext
DataList#innerJoin
DataList#leftJoin
DataList#find
DataList#byIDs
DataList#reverse
DataList#dataQuery
has been changed to return a clone of the query, and so can't be used to modify the list's query directly. UseDataList#alterDataQuery
instead to modify dataQuery in a safe manner.ScheduledTask
,QuarterHourlyTask
,HourlyTask
,DailyTask
,MonthlyTask
,WeeklyTask
andYearlyTask
are deprecated, please extend fromBuildTask
orCliController
, and invoke them in self-defined frequencies through Unix cronjobs etc.