silverstripe-framework/docs/en/04_Changelogs/3.2.0.md

982 lines
55 KiB
Markdown
Raw Normal View History

2015-06-11 06:12:59 +02:00
# 3.2.0
## Contents
* [Major Changes](#major-changes)
* [Deprecated classes/methods](#deprecated-classesmethods-removed)
* [New and changed API](#new-and-changed-api)
2015-06-11 06:12:59 +02:00
* [Bugfixes](#bugfixes)
* [Upgrading Notes](#upgrading-notes)
## Major changes
* Minimum PHP version raised to 5.3.3
* Introduction of new parameterised ORM
* Default support for PDO
* Moved SS_Report and ReportAdmin out to a separate module. If you're using
composer or downloading a release, this module should be included for you.
Otherwise, you'll need to include the module yourself
(https://github.com/silverstripe-labs/silverstripe-reports)
* Moved SiteConfig also out to its own module. This will be included by
default if you include the CMS module.
(https://github.com/silverstripe/silverstripe-siteconfig)
* Implementation of new "Archive" concept for page removal, which supercedes
"delete from draft". Where deletion removed pages only from draft, archiving
removes from both draft and live simultaneously.
* Most of the `Image` manipulation methods have been renamed
## Deprecated classes/methods
The following functionality deprecated in 3.0 has been removed:
2015-06-11 06:12:59 +02:00
* `DataList::getRange()` removed. Use `limit()` instead.
* `SQLMap` removed. Call `map()` on a `DataList` or use `SS_Map` directly instead.
* `SQLQuery` methods `select()`, `limit()`, `orderby()`, `groupby()`, `having()`, `from()`, `leftjoin()`, `innerjoin()`, `where()` and `whereAny()` removed.
Use `set*()` and `add*()` methods instead.
2015-06-11 06:12:59 +02:00
## New and changed API
* Implementation of a parameterised query framework eliminating the need to manually escape variables for
use in SQL queries. This has been integrated into nearly every level of the database ORM.
* Refactor of database connectivity classes into separate components linked together through dependency injection
2015-06-15 08:35:01 +02:00
* Refactor of `SQLQuery` into separate objects for each query type: `SQLSelect`, `SQLDelete`, `SQLUpdate` and `SQLInsert`
2015-06-11 06:12:59 +02:00
* PDO is now a standard connector, and is available for all database interfaces
* `DataObject::doValidate()` method visibility added to access `DataObject::validate` externally
2015-06-11 06:12:59 +02:00
* `NumericField` now uses HTML5 "number" type instead of "text"
* `UploadField` "Select from files" shows files in all folders by default
* `UploadField` won't display an overwrite warning unless `Upload::replaceFile` is true
* `HtmlEditorField` no longer substitutes `<blockquote />` for indented text
* `ClassInfo::dataClassesFor` now returns classes which should have tables, regardless of whether those
tables actually exist.
* `SS_Filterable`, `SS_Limitable` and `SS_Sortable` now explicitly extend `SS_List`
* `Convert::html2raw` no longer wraps text by default and can decode single quotes.
* `Mailer` no longer calls `xml2raw` on all email subject line, and now must be passed in via plain text.
* `ErrorControlChain` now supports reload on exceptions
* `FormField::validate` now requires an instance of `Validator`
* API: Removed URL routing by controller name
* Security: The multiple authenticator login page should now be styled manually - i.e. without the default jQuery
UI layout. A new template, Security_MultiAuthenticatorLogin.ss is available.
* Security: This controller's templates can be customised by overriding the `getTemplatesFor` function.
* `Deprecation::set_enabled()` or `SS_DEPRECATION_ENABLED` can now be used to
enable or disable deprecation notices. Deprecation notices are no longer displayed on test.
2015-06-11 06:12:59 +02:00
* API: Form and FormField ID attributes rewritten.
* `SearchForm::getSearchQuery` no longer pre-escapes search keywords and must
be cast in your template
* Helper function `DB::placeholders` can be used to generate a comma separated list of placeholders
useful for creating "WHERE ... IN (?,...)" SQL fragments
* Implemented Convert::symbol2sql to safely encode database and table names and identifiers.
E.g. `Convert::symbol2sql('table.column') => '"table"."column"';`
* `Convert::raw2sql` may now quote the escaped value, as well as safely escape it, according to the current
database adaptor's preference.
* `DB` class has been updated and many static methods have been renamed to conform to coding convention.
* Renamed API:
* `affectedRows` -> `affected_rows`
* `checkAndRepairTable` -> `check_and_repair_table`
* `createDatabase` -> `create_database`
* `createField` -> `create_field`
* `createTable` -> `create_table`
* `dontRequireField` -> `dont_require_field`
* `dontRequireTable` -> `dont_require_table`
* `fieldList` -> `field_list`
* `getConn` -> `get_conn`
* `getGeneratedID` -> `get_generated_id`
* `isActive` -> `is_active`
* `requireField` -> `require_field`
* `requireIndex` -> `require_index`
* `requireTable` -> `require_table`
* `setConn` -> `set_conn`
* `tableList` -> `table_list`
* Deprecated API:
* `getConnect` (Was placeholder for PDO connection string building code, but is made
redundant after the PDOConnector being fully abstracted)
* New API:
* `build_sql` - Hook into new SQL generation code
* `get_connector` (Nothing to do with getConnect)
* `get_schema`
* `placeholders`
* `prepared_query`
* `SS_Database` class has been updated and many functions have been deprecated, or refactored into
the various other database classes. Most of the database management classes remain in the database
controller, due to individual databases (changing, creating of, etc) varying quite a lot from
API to API, but schema updates within a database itself is managed by an attached DBSchemaManager
* Refactored into DBSchemaManager:
* `createTable`
* `alterTable`
* `renameTable`
* `createField`
* `renameField`
* `fieldList`
* `tableList`
* `hasTable`
* `enumValuesForField`
* `beginSchemaUpdate` and `endSchemaUpdate` -> Use `schemaUpdate` with a callback
* `cancelSchemaUpdate`
* `isSchemaUpdating`
* `doesSchemaNeedUpdating`
* `transCreateTable`
* `transAlterTable`
* `transCreateField`
* `transCreateField`
* `transCreateIndex`
* `transAlterField`
* `transAlterIndex`
* `requireTable`
* `dontRequireTable`
* `requireIndex`
* `hasField`
* `requireField`
* `dontRequireField`
* Refactored into DBQueryBuilder
* `sqlQueryToString`
* Deprecated:
* `getConnect` - Was intended for use with PDO, but was never implemented, and is now
redundant, now that there is a stand-alone `PDOConnector`
* `prepStringForDB` - Use `quoteString` instead
* `dropDatabase` - Use `dropSelectedDatabase`
* `createDatabase` - Use `selectDatabase` with the second parameter set to true instead
* `allDatabaseNames` - Use `databaseList` instead
* `currentDatabase` - Use `getSelectedDatabase` instead
* `addslashes` - Use `escapeString` instead
* `LogErrorEmailFormatter` now better displays SQL queries in errors by respecting line breaks
* Installer has been majorly upgraded to handle the new database configuration options
and additional PDO functionality.
* Created `SS_DatabaseException` to emit database errors. Query information such as SQL
and any relevant parameters may be used by error handling user code that catches
this exception.
* The `SQLConditionGroup` interface has been created to represent dynamically
evaluated SQL conditions. This may be used to wrap a class that generates
a custom SQL clause(s) to be evaluated at the time of execution.
* `DataObject` constants CHANGE_NONE, CHANGE_STRICT, and CHANGE_VALUE have been created
to provide more verbosity to field modification detection. This replaces the use of
various magic numbers with the same meaning.
* create_table_options now uses constants as API specific filters rather than strings.
This is in order to promote better referencing of elements across the codebase.
See `FulltextSearchable->enable` for example.
* `$FromEnd` iterator variable now available in templates.
* Support for multiple HtmlEditorConfigs on the same page.
* Object::singleton() method for better type-friendly singleton generation
* New `Image` methods `CropWidth` and `CropHeight` added
* 'Max' versions of `Image` methods introduced to prevent up-sampling
* Update Image method names in PHP code and templates
* `SetRatioSize` -> `Fit`
* `CroppedImage` -> `Fill`
* `PaddedImage` -> `Pad`
* `SetSize` -> `Pad`
* `SetWidth` -> `ScaleWidth`
* `SetHeight` -> `ScaleHeight`
2015-06-11 06:12:59 +02:00
## Bugfixes
2013-10-23 10:10:42 +02:00
2015-06-11 06:12:59 +02:00
* Reduced database regeneration chances on subsequent rebuilds after the initial dev/build
* Elimination of various SQL injection vulnerability points
* `DataObject::writeComponents()` now called correctly during `DataObject::write()`
* Fixed missing theme declaration in installer
* Fixed incorrect use of non-existing exception classes (e.g. `HTTPResponse_exception`)
* `GridState` fixed to distinguish between check for missing values, and creation of
nested state values, in order to prevent non-empty values being returned for
missing keys. This was breaking `DataObject::get_by_id` by passing in an object
for the ID.
* Fixed order of `File` fulltext searchable fields to use same order as actual fields.
This is required to prevent unnecessary rebuild of MS SQL databases when fulltext
searching is enabled.
2015-06-16 02:29:29 +02:00
* In the past E_RECOVERABLE_ERROR would be ignored, and now correctly appear as warnings.
2015-06-11 06:12:59 +02:00
## Upgrading Notes
### Enable PDO
Although this is not a mandatory upgrade step, the new `[PDOConnector](api:SilverStripe\ORM\Connect\PDOConnector)` class offers improved database
performance and security, and should be integrated into any project using 3.2.
In order to update your connector you can do so in one of two ways, depending on whether or not
your project is using `_ss_environment.php` to configure your database, or via `mysite/_config.php`
If using `_ss_environment.php`:
:::php
define('SS_DATABASE_CLASS', 'MySQLPDODatabase');
If using `mysite/_config.php`:
:::php
global $databaseConfig;
$databaseConfig = array(
"type" => "MySQLPDODatabase"
// other config settings
);
### Disable `LastVisited` and `NumVisits` counter
These fields were deprecated in 3.1 due to performance concerns, and should be disabled unless required by
your application.
In order to disable these functions you can add the following yml to your configuration:
:::yaml
---
Name: disablevisits
---
Member:
log_num_visits: false
log_last_visited: false
This functionality will be removed in 4.0
[Howto: Track Member Logins](/developer-guides/extending/how_tos/track_member_logins) to restore functionality
as custom code
### UploadField "Select from files" shows files in all folders by default
In order to list files in a single folder by default (previous default behaviour),
use `setDisplayFolderName()` with a folder path relative to `assets/`:
2015-06-11 06:12:59 +02:00
:::php
UploadField::create('MyField')->setDisplayFolderName('Uploads');
2015-06-11 06:12:59 +02:00
### UploadField won't display an overwrite warning unless Upload:replaceFile is true
The configuration setting `UploadField:overwriteWarning` is dependent on `Upload:replaceFile`
which is set to false by default.
To display a warning before overwriting a file:
Via config:
2015-06-11 06:12:59 +02:00
::yaml
Upload:
# Replace an existing file rather than renaming the new one.
replaceFile: true
UploadField:
# Warning before overwriting existing file (only relevant when Upload: replaceFile is true)
overwriteWarning: true
2015-06-11 06:12:59 +02:00
Or per instance:
2015-06-11 06:12:59 +02:00
::php
$uploadField->getUpload()->setReplaceFile(true);
$uploadField->setOverwriteWarning(true);
2015-06-11 06:12:59 +02:00
### File.allowed_extensions restrictions
Certain file types such as swf, html, htm, xhtml and xml have been removed from the list
of allowable file uploads. If your application requires the ability to upload these,
you will need to append these to the `File.allowed_extensions` config as necessary.
Also if uploading other file types, it's necessary to ensure that `File.allowed_extensions`
includes that extension, as extensions passed to `[UploadField](api:SilverStripe\AssetAdmin\Forms\UploadField)` will be filtered against
this list.
### Removed format detection in i18n::$date_format and i18n::$time_format
Localized dates cause inconsistencies in client-side vs. server-side formatting
and validation, particularly in abbreviated month names. The default date
format has been changed to "yyyy-MM-dd" (e.g. 2014-12-31).
New users will continue to have the option for a localized date
format in their profile (based on their chosen locale).
If you have existing users with `Member.DateFormat` set to a format
including "MMM" or "MMMM", consider deleting those formats to fall back to
the global (and more stable) default.
### Cookies set via Cookie::set() are now HTTP only by default
Cookies set through `Cookie::set()` now default to "HTTP only". This means that scripting
languages like JavaScript won't be able to read them.
To set it back to be non-HTTP only, you need to set the `$httpOnly` argument to false when calling
`Cookie::set()`.
2015-06-11 06:12:59 +02:00
### API: Removed URL routing by controller name
2015-06-11 06:12:59 +02:00
The auto-routing of controller class names to URL endpoints
has been removed (rule: `'$Controller//$Action/$ID/$OtherID': '*'`).
This increases clarity in routing since it makes URL entpoints explicit,
and thereby simplifies system and security reviews.
2015-06-11 06:12:59 +02:00
Please access any custom controllers exclusively through self-defined
[routes](/reference/director). For controllers extending `Page_Controller`,
simply use the provided page URLs.
:::php
2017-08-03 05:57:29 +02:00
class MyController extends Controller
{
2015-06-11 06:12:59 +02:00
static $allowed_actions = array('myaction');
2017-08-03 06:25:49 +02:00
public function myaction($request)
{
2015-06-11 06:12:59 +02:00
// ...
}
}
Create a new file `mysite/_config/routes.yml`
(read more about the [config format](/topics/configuration)).
Your controller is now available on `http://yourdomain.com/my-controller-endpoint`,
after refreshing the configuration cache through `?flush=all`.
:::yaml
---
Name: my-routes
After: framework/routes#coreroutes
---
Director:
rules:
'my-controller-endpoint//$Action' : 'MyController'
The auto-routing is still in place for unit tests,
since its a frequently used feature there. Although we advise against it,
you can reinstate the old behaviour through a director rule:
2015-06-11 06:12:59 +02:00
:::yaml
---
Name: my-routes
After: framework/routes#coreroutes
---
Director:
rules:
'$Controller//$Action/$ID/$OtherID': '*'
### API: Default Form and FormField ID attributes rewritten.
Previously the automatic generation of ID attributes throughout the Form API
could generate invalid ID values such as Password[ConfirmedPassword] as well
as duplicate ID values between forms on the same page. For example, if you
created a field called `Email` on more than one form on the page, the resulting
HTML would have multiple instances of `#Email`. ID should be a unique
identifier for a single element within the document.
This rewrite has several angles, each of which is described below. If you rely
on ID values in your CSS files, Javascript code or application unit tests *you
will need to update your code*.
#### Conversion of invalid form ID values
ID attributes on Form and Form Fields will now follow the
[HTML specification](http://www.w3.org/TR/REC-html40/types.html#type-cdata).
Generating ID attributes is now handled by the new `FormTemplateHelper` class.
Please test each of your existing site forms to ensure that they work
correctly in particular, javascript and css styles which rely on specific ID
values.
#### Invalid ID attributes stripped
ID attributes will now be run through `Convert::raw2htmlid`. Invalid characters
are replaced with a single underscore character. Duplicate, leading and trailing
underscores are removed. Custom ID attributes (set through `setHTMLID`) will not
be altered.
Before:
:::html
<form id="MyForm[Form]"
<div id="MyForm[Form][ID]">
Now:
:::html
<form id="MyForm_Form">
<div id="MyForm_Form_ID">
#### Namespaced FormField ID's
Form Field ID values will now be namespaced with the parent form ID.
Before:
:::html
<div id="Email">
Now:
:::html
<div id="MyForm_Email">
#### FormField wrapper containers suffixed with `_Holder`
Previously both the container div and FormField tag shared the same ID in
certain cases. Now, the wrapper div in the default `FormField` template will be
suffixed with `_Holder`.
Before:
:::html
<div id="Email">
<input id="Email" />
After:
:::html
<div id="MyForm_Email_Holder"
<input id="MyForm_Email" />
#### Reverting to the old specification
If upgrading existing forms is not feasible, developers can opt out of the new
specifications by using the `FormTemplateHelper_Pre32` class rules instead of
the default ones.
`mysite/config/_config.yml`:
:::yaml
Injector:
FormTemplateHelper:
class: FormTemplateHelper_Pre32
### <a name="sqlquery"></a>Update code that uses SQLQuery
2014-12-03 21:20:39 +01:00
SQLQuery has been changed. Previously this class was used for both selecting and deleting, but
deletion is now handled by the new SQLDelete class.
Additionally, 3.2 now provides SQLUpdate and SQLInsert to generate parameterised query friendly
data updates.
2014-12-03 21:20:39 +01:00
SQLQuery, SQLDelete and SQLUpdate all inherit from SQLConditionalExpression, which
implements toSelect, toDelete, and toUpdate to generate basic transformations
between query types.
In the past SQLQuery->setDelete(true) would be used to turn a select into a delete,
2014-12-03 21:20:39 +01:00
although now a new SQLDelete object should be created from the original SQLQuery.
Before:
2015-06-11 06:12:59 +02:00
:::php
<?php
$query = new SQLQuery('*');
$query->setFrom('"SiteTree"');
$query->setWhere('"SiteTree"."ShowInMenus" = 0');
$query->setDelete(true);
$query->execute();
2015-06-11 06:12:59 +02:00
After:
2015-06-11 06:12:59 +02:00
:::php
<?php
$query = SQLDelete::create()
->setFrom('"SiteTree"')
->setWhere(array('"SiteTree"."ShowInMenus"' => 0));
$query->execute();
2015-06-11 06:12:59 +02:00
2015-06-15 08:35:01 +02:00
When working with SQLQuery passed into user code, it is advisable to strictly
cast it into either a SQLSelect or SQLDelete. This can be done by using the new
`SQLQuery::toAppropriateExpression()` method, which will automatically convert
to the correct type based on whether the SQLQuery is set to delete or not.
If a SQLQuery is not converted, then the result of `getWhere` will not be parameterised.
This is because user code written for 3.1 expects this list to be a flat array
of strings. This format is inherently unsafe, and should be avoided where possible.
:::php
<?php
2017-08-03 06:25:49 +02:00
public function augmentSQL(SQLQuery &$query)
{
2015-06-15 08:35:01 +02:00
$query->getWhere(); // Will be flattened (unsafe 3.1 compatible format)
$expression = $query->toAppropriateExpression(); // Either SQLSelect or SQLDelete
$expression->getWhere(); // Will be parameterised (preferred 3.2 compatible format)
}
Alternatively:
2015-06-11 06:12:59 +02:00
:::php
<?php
2014-12-03 21:20:39 +01:00
$query = SQLQuery::create()
->setFrom('"SiteTree"')
->setWhere(array('"SiteTree"."ShowInMenus"' => 0))
2015-06-15 08:35:01 +02:00
->setDelete(true)
->toAppropriateExpression();
$query->execute();
2015-06-11 06:12:59 +02:00
### Update code that interacts with SQL strings to use parameters
The Silverstripe ORM (object relation model) has moved from using escaped SQL strings
to query the database, to a combination of parameterised SQL expressions alongside
a related list of parameter values. As a result of this, it is necessary to assume
2014-12-03 21:20:39 +01:00
that any `SQLQuery` object may, and will usually, have un-injected parameters.
All database queries performed through `DataList`, `DataQuery` and `SQLQuery` will continue
to work, as will those through `DataObject::get()` (which returns a filterable `DataList`).
However, any conditional expression that includes values escaped with `Convert::raw2sql()`
should use the new standard syntax. This new querying standard method enforces a much
higher level of security than was previously available, and all code using manual
escaping should be upgraded.
See [the security topic](/topics/security#parameterised-queries) for details on why this is necessary, or
[the databamodel topic](/topics/datamodel#raw-sql-options-for-advanced-users) for more information.
As a result of this upgrade there are now very few cases where `Convert::raw2sql` needs to be used.
Examples of areas where queries should be upgraded are below:
2015-06-11 06:12:59 +02:00
#### 1. Querying the database directly through DB, including non-SELECT queries
2015-06-11 06:12:59 +02:00
Before:
2015-06-11 06:12:59 +02:00
:::php
<?php
// Note: No deprecation notices will be caused here
DB::query("UPDATE \"SiteTree\" SET \"Title\" LIKE '%" . Convert::raw2sql($myTitle) . "%' WHERE \"ID\" = 1");
$myPages = DB::query(sprintf('SELECT "ID" FROM "MyObject" WHERE "Title" = \'%s\'', Convert::raw2sql($parentTitle)));
After:
:::php
<?php
DB::prepared_query(
'UPDATE "SiteTree" SET "Title" LIKE ? WHERE "ID" = ?',
array("%{$myTitle}%", 1)
);
$myPages = DB::prepared_query(
'SELECT "ID" FROM "MyObject" WHERE "Title" = ?',
array($parentTitle)
);
#### 2. Querying the database through `DataList`, `DataQuery`, `SQLQuery`, and `DataObject`
Before:
:::php
<?php
$items = DataObject::get_one('MyObject', '"Details" = \''.Convert::raw2sql($details).'\'');
$things = MyObject::get()->where('"Name" = \''.Convert::raw2sql($name).'\'');
$list = DataList::create('Banner')->where(array(
'"ParentID" IS NOT NULL',
'"Title" = \'' . Convert::raw2sql($title) . '\''
);
After:
:::php
<?php
$items = DataObject::get_one('MyObject', array('"MyObject"."Details"' => $details));
$things = MyObject::get()->where(array('"MyObject"."Name" = ?' => $name));
$list = DataList::create('Banner')->where(array(
'"ParentID" IS NOT NULL',
'"Title" = ?' => $title,
));
2015-06-11 06:12:59 +02:00
#### 3. Interaction with `DataList::sql()`, `DataQuery::sql()`, `SQLQuery::sql()`, or `SQLQuery::getJoins()` methods
The place where legacy code would almost certainly fail is any code that calls
DataList::sql`, `DataQuery::sql`, `SQLQuery::sql` or `SQLQuery::getJoins()`, as the api requires that user
code passes in an argument here to retrieve SQL parameters by value.
User code that assumes parameterless queries will likely fail, and need to be
updated to handle this case properly.
Before:
:::php
<?php
// Generate query
$argument = 'whatever';
$query = SQLQuery::create()
->setFrom('"SiteTree"')
->setWhere(array("\"SiteTree\".\"Title\" LIKE '" . Convert::raw2sql($argument) . "'"));
// Inspect elements of the query
$sql = $query->sql();
$sql = preg_replace('/LIKE \'(.+)\'/', 'LIKE \'%${1}%\'', $sql); // Adds %% around the argument
// Pass new query to database connector
DB::query($sql);
After:
2015-06-11 06:12:59 +02:00
:::php
<?php
2015-06-11 06:12:59 +02:00
// Generate query
$argument = 'whatever';
$query = SQLQuery::create()
->setFrom('"SiteTree"')
->setWhere(array('"SiteTree"."Title" LIKE ?' => $argument));
2015-06-11 06:12:59 +02:00
// Inspect elements of the query
$sql = $query->sql($parameters);
foreach($parameters as $key => $value) {
// Adds %% around arguments
$parameters[$key] = "%{$value}%";
}
2015-06-11 06:12:59 +02:00
// Pass new query to database connector
// Note that DB::query($sql) would fail, as it would contain ? with missing parameters
DB::prepared_query($sql, $parameters);
2015-06-11 06:12:59 +02:00
Also note that the parameters may not be a single level array, as certain values
may be forced to be cast as a certain type (where supported by the current API).
2015-06-11 06:12:59 +02:00
E.g.
2015-06-11 06:12:59 +02:00
:::php
<?php
2015-06-11 06:12:59 +02:00
$parameters = array(
10,
array('value' => 0, 'type' => 'boolean') // May also contain other database API specific options
)
DB::prepared_query('DELETE FROM "MyObject" WHERE ParentID = ? OR IsValid = ?', $parameters);
2015-06-15 08:35:01 +02:00
#### 4. Interaction with `SQLSelect::getWhere()` method
The `SQLSelect` class supercedes the old `SQLQuery` object for performing select queries. Although
both implement the `getWhere()` method, the results returned by `SQLSelect::getWhere()` will be
parameterised while `SQLQuery::getWhere()` will be a flattened array of strings.
2015-06-15 08:35:01 +02:00
`SQLSelect::getWhere()` returns a list of conditions, each of which is an
associative array mapping the condition string to a list of parameters provided.
2015-06-11 06:12:59 +02:00
Before:
2015-06-11 06:12:59 +02:00
:::php
<?php
2015-06-11 06:12:59 +02:00
// Increment value of a single condition
2015-06-15 08:35:01 +02:00
$query = new SQLQuery(/*...*/);
2015-06-11 06:12:59 +02:00
$conditions = $query->getWhere();
$new = array();
foreach($conditions as $condition) {
if(preg_match('/\"Count\" = (?<count>\d+)/', $condition, $matches)) {
$condition = '"Count" = '.($matches['count'] + 1);
}
$new[] = $condition;
}
$query->setWhere($new);
2015-06-11 06:12:59 +02:00
After:
2015-06-11 06:12:59 +02:00
:::php
// Increment value of a single condition
2015-06-15 08:35:01 +02:00
$query = new SQLSelect(/*...*/);
2015-06-11 06:12:59 +02:00
$conditions = $query->getWhere();
$new = array();
foreach($conditions as $condition) {
// $condition will be a single length array
foreach($condition as $predicate => $parameters) {
if('"Count" = ?' === $predicate) {
$parameters[0] = $parameters[0] + 1;
}
$new[] = array($predicate => $parameters);
}
2015-06-11 06:12:59 +02:00
}
$query->setWhere($new);
2015-06-11 06:12:59 +02:00
In cases where user code will manipulate the results of this value, it may be useful to
replace this method call with the new `getWhereParameterised($parameters)` method, where
applicable.
2015-06-11 06:12:59 +02:00
This method returns a manipulated form of the where conditions stored by the query, so
2015-06-15 08:35:01 +02:00
that it matches the list of strings similar to the old 3.1 `SQLQuery::getWhere()` behaviour.
2015-06-11 06:12:59 +02:00
Additionally, the list of parameters is safely extracted, flattened, and can be passed out
through the `$parameters` argument which is passed by reference.
2015-06-11 06:12:59 +02:00
Before:
2015-06-11 06:12:59 +02:00
:::php
2017-08-03 06:25:49 +02:00
public function filtersOnColumn($query, $column)
{
2015-06-11 06:12:59 +02:00
$regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/';
foreach($this->getWhere() as $predicate) {
if(preg_match($regexp, $predicate)) return true;
}
return false;
}
After:
:::php
2017-08-03 06:25:49 +02:00
public function filtersOnColumn($query, $column)
{
2015-06-11 06:12:59 +02:00
$regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/';
foreach($this->getWhereParameterised($parameters) as $predicate) {
if(preg_match($regexp, $predicate)) return true;
}
return false;
}
#### 5. Update code that interacts with the DB schema
Updating database schema is now done by `updateSchema` with a callback, rather than relying
on user code to call `beginSchemaUpdate` and `endSchemaUpdate` around the call.
Since the schema management object is separate from the database controller you
interact with it via `DB::get_schema` instead of `DB::get_conn` (previously named
`DB::getConn`)
Before:
2015-06-11 06:12:59 +02:00
:::php
<?php
$conn = DB::getConn();
$conn->beginSchemaUpdate();
foreach($dataClasses as $dataClass) {
singleton($dataClass)->requireTable();
}
$conn->endSchemaUpdate();
2015-06-11 06:12:59 +02:00
After:
2015-06-11 06:12:59 +02:00
:::php
<?php
$schema = DB::get_schema();
$schema->schemaUpdate(function() use($dataClasses){
foreach($dataClasses as $dataClass) {
singleton($dataClass)->requireTable();
}
});
2015-06-11 06:12:59 +02:00
Also should be noted is that many functions have been renamed to conform better with
coding conventions. E.g. `DB::requireTable` is now `DB::require_table`
### Revert to legacy CMS page actions
By default "delete from live" and "delete" actions are deprecated in favour of "unpublish" and "archive".
"unpublish" is an existing action which is functionally equivalent to "delete from live", and "archive" is a new
feature which performs both unpublish and deletion simultaneously.
To restore "delete from live" add the following config to your site's config.yml.
2015-06-11 06:12:59 +02:00
:::yml
CMSMain:
enabled_legacy_actions:
- CMSBatchAction_DeleteFromLive
In order to remove the new "archive" action and restore the old "delete" action you can use the following config
:::yml
CMSMain:
enabled_legacy_actions:
- CMSBatchAction_Delete
2015-10-11 21:44:34 +02:00
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### API Changes
* 2015-08-03 [f2c39aa](https://github.com/silverstripe/silverstripe-framework/commit/f2c39aac200f50157d9163b825ea7a7dd1f7aa18) batch restore action (Damian Mooyman)
* 2015-08-03 [e22b653](https://github.com/silverstripe/silverstripe-cms/commit/e22b653e06207bfdc0b36ac7a9e6be250e10bde8) batch restore action (Damian Mooyman)
* 2015-07-10 [a6677b1](https://github.com/silverstripe/silverstripe-cms/commit/a6677b1653cf338d66b8b6d1e4d5b14d66250c0e) respect custom attributes on OptionsetField and CheckboxSetField (Damian Mooyman)
* 2015-07-10 [560f9a6](https://github.com/silverstripe/silverstripe-framework/commit/560f9a6e39df4f09dfe4bed5978f6dcddc0bb299) respect custom attributes on OptionsetField and CheckboxSetField (Damian Mooyman)
* 2015-06-15 [f3e1472](https://github.com/silverstripe/silverstripe-cms/commit/f3e1472493b15758c67bb2c8814bc28765eac401) Revert DataObject::validate to 3.1 method signature (protected) (Damian Mooyman)
* 2015-06-15 [58cc3da](https://github.com/silverstripe/silverstripe-framework/commit/58cc3da8d8005d6a367d88fb7c5d41c96dd8946f) Revert DataObject::validate to 3.1 method signature (protected) (Damian Mooyman)
* 2015-06-13 [e766658](https://github.com/silverstripe/silverstripe-framework/commit/e766658ee3b9e70988b79d99d75124857f2a7ccc) Allow HTTP Cache Headers to be customised (Jeremy Shipman)
2015-10-11 21:44:34 +02:00
* 2015-06-12 [8389260](https://github.com/silverstripe/silverstripe-framework/commit/838926085cac00ec65ee5aecb67e6102ea8b6f20) and renamed image functions (Jonathon Menz)
* 2015-06-09 [914d734](https://github.com/silverstripe/silverstripe-framework/commit/914d734df004947eb869de2abb6fb2fc463be574) Disable deprecation notices by default (Damian Mooyman)
* 2015-06-09 [a8ace75](https://github.com/silverstripe/silverstripe-framework/commit/a8ace7534194b5e1a636c96eca4607d08726dfeb) Support for multiple HTMLEditorConfig per page (Damian Mooyman)
* 2015-05-14 [b169823](https://github.com/silverstripe/silverstripe-cms/commit/b169823a00fed190bcd55054339baa3bc818cd75) Deprecate delete in favour of archive (Damian Mooyman)
* 2015-05-14 [a72bd16](https://github.com/silverstripe/silverstripe-framework/commit/a72bd16f420915d4ef2301ee1bec3dcfe2ed2305) Deprecate delete in favour of archive (Damian Mooyman)
* 2015-04-30 [c5e0c8f](https://github.com/silverstripe/silverstripe-cms/commit/c5e0c8f007c814e82f2c7f84b1fb4eacbcf5ab4d) Enable tree filter highlighting (Damian Mooyman)
* 2015-04-30 [8863797](https://github.com/silverstripe/silverstripe-framework/commit/8863797b76fd1f81d9e9f4900fc6c387966554da) Enable tree filter highlighting (Damian Mooyman)
* 2015-04-29 [e8d6f15](https://github.com/silverstripe/silverstripe-framework/commit/e8d6f15f2883b765bf17bb7027013ebd2a79cf9c) Use mysql buffered statements (Damian Mooyman)
* 2015-04-09 [e91606e](https://github.com/silverstripe/silverstripe-framework/commit/e91606e4943a1725d51f5c0f7bf80165995bc814) Introduce $FromEnd variable for iterators (Damian Mooyman)
* 2015-03-31 [95c162e](https://github.com/silverstripe/silverstripe-framework/commit/95c162ef0d645a2af9ad355ef195ab426a881fd4) Security better respects BackURL on login (Damian Mooyman)
* 2015-03-04 [9367fd2](https://github.com/silverstripe/silverstripe-framework/commit/9367fd2456a1f3f535f55249f9d6d5a2d7399af9) enable PaginatedList to be disabled by setting page length to 0 (Damian Mooyman)
* 2015-01-14 [5d4c2c4](https://github.com/silverstripe/silverstripe-framework/commit/5d4c2c4b34e1a0d544ce1b39a8d6fd74420025d4) Adding default_classes to FormField (Daniel Hensby)
* 2015-01-14 [6d00027](https://github.com/silverstripe/silverstripe-framework/commit/6d0002780dc89af91354979cba4d09d2cf8946da) Adding default_classes to Form (Daniel Hensby)
* 2014-09-25 [e478009](https://github.com/silverstripe/silverstripe-framework/commit/e47800917a5482b1dce455f4fbcb564ff73d7576) Mailer can be configured to use different encoding mechanisms, and added support for unicode quoted-string encoding (Damian Mooyman)
* 2014-09-25 [29e3347](https://github.com/silverstripe/silverstripe-framework/commit/29e33475621fd9e4be20ecdea45d017bbd4f65f8) Convert::html2raw no longer wraps text automatically (Damian Mooyman)
* 2014-09-24 [5631553](https://github.com/silverstripe/silverstripe-framework/commit/563155391f02dca5017dfc2a967eb1e93f0f1014) Cookies set via Cookie::set() are now HTTP only by default (Sean Harvey)
* 2014-09-15 [062ad8e](https://github.com/silverstripe/silverstripe-framework/commit/062ad8e6850efa4a1b8895bd361cb93079685cfa) Allow parameterised joins / subselects (Damian Mooyman)
* 2014-08-15 [2ba1c46](https://github.com/silverstripe/silverstripe-cms/commit/2ba1c46bc86b3c8fdea723e6b936ede4806314be) broken link hihglighting to write to database. (Mateusz Uzdowski)
* 2014-08-13 [784e292](https://github.com/silverstripe/silverstripe-framework/commit/784e292d4e57b82c372f3db2edbbc6e0e067d4d3) Add a getter for customisedObject property. (Mateusz Uzdowski)
* 2014-08-09 [18d6c53](https://github.com/silverstripe/silverstripe-cms/commit/18d6c538a7d8865dca44f4e37d88b54dc30c20e6) Extract siteconfig out to an external module. (Will Rossiter)
* 2014-08-04 [1759d5d](https://github.com/silverstripe/silverstripe-framework/commit/1759d5d017068693b20f82ac7009004fd0163375) Use "number" HTML5 type for NumericField by default (Sean Harvey)
* 2014-07-29 [26a0e91](https://github.com/silverstripe/silverstripe-framework/commit/26a0e915536f067c5c5429ffa5224f3cff37b886) SS_Filterable, SS_Limitable and SS_Sortable now explicitly extend SS_List (Damian Mooyman)
* 2014-04-22 [d16db2d](https://github.com/silverstripe/silverstripe-framework/commit/d16db2d4f4b2fbd65722f40305fbc075edf72eb1) tinymce editor no longer transforms paragraphs with margin-left into blockquotes (Damian Mooyman)
* 2014-04-16 [5f7ebd3](https://github.com/silverstripe/silverstripe-framework/commit/5f7ebd3c235d663b5ad5c0fbcd3d393d2e893306) UploadField: move replaceFile to the front end config (Devlin)
* 2014-04-10 [5b55361](https://github.com/silverstripe/silverstripe-framework/commit/5b553616dc2438b3ad7803e2765bd37b0d1d8736) DateTime.Ago better infers significance of date units. (Damian Mooyman)
* 2014-04-09 [2e73dcb](https://github.com/silverstripe/silverstripe-framework/commit/2e73dcb8912223abb88354e09b13aafa902af8af) Remove swf,html,htm,xhtml,xml as default allowed upload able file types (Damian Mooyman)
* 2014-04-04 [bf4e9eb](https://github.com/silverstripe/silverstripe-framework/commit/bf4e9eb0443c00e1e8a06d0db5636edd627d55eb) Singleton method allowing type inference (Damian Mooyman)
* 2014-02-11 [6906c9b](https://github.com/silverstripe/silverstripe-framework/commit/6906c9bd1a5535e6e2674c26446f4fd6d81e8490) Removed auto-detection for i18n date/time formats (Ingo Schommer)
* 2014-01-17 [973b967](https://github.com/silverstripe/silverstripe-framework/commit/973b967e6b9ce68e0e03b97ae49f28a155a28c6e) Adding chaining to i18nTextCollector::write() (Daniel Hensby)
* 2014-01-02 [791ee71](https://github.com/silverstripe/silverstripe-framework/commit/791ee7171b20ffd66f2d6d0c18589adfc22b6680) Prevent large images from repeatedly crashing PHP on resize (Loz Calver)
* 2013-12-23 [5fff5af](https://github.com/silverstripe/silverstripe-framework/commit/5fff5afb478381a23e6b8b5b9079ae1fe5724fdd) moved useTestTheme to base Sapphire test class so that it can be used elsewhere (eg CMS test) (micmania1)
* 2013-12-19 [6fc9db6](https://github.com/silverstripe/silverstripe-framework/commit/6fc9db6f0e87fe935ccb46daff880158453ad04b) DataObject::validate() visibility changed to public (issue #1659) (Sean Harvey)
* 2013-11-26 [b88a095](https://github.com/silverstripe/silverstripe-framework/commit/b88a0955a5b314cc57573ec573f9839ec9d17f7a) Support string descriptors for unique indexes in Versioned (Fred Condo)
* 2013-10-17 [fee54c7](https://github.com/silverstripe/silverstripe-framework/commit/fee54c75f05d7bbc2b7c221c3150d201e1fffb59) Change DropdownField::getSource() to not return the emptyString value. (Nathan J. Brauer)
* 2013-10-17 [1c983bc](https://github.com/silverstripe/silverstripe-framework/commit/1c983bc16d7479c2c9bac3984e36545dc4a301e8) LookupField::Field now returns an HTMLText instance. (Will Rossiter)
* 2013-10-16 [52f6581](https://github.com/silverstripe/silverstripe-framework/commit/52f6581ecf1d09f8c368e2de15e4a64e69ff4a40) Better declaration of DataObject field change levels. (Damian Mooyman)
* 2013-10-10 [b6b3cd9](https://github.com/silverstripe/silverstripe-framework/commit/b6b3cd98891e0f6134c77225e76147d8721d0129) GridState_Data values can have default values specified during retrieval. (Damian Mooyman)
* 2013-10-09 [b367dd6](https://github.com/silverstripe/silverstripe-framework/commit/b367dd6237e56cc88744befa98e6c8f2cdd503f2) Removed Member.LastVisited and Member.NumVisits (Ingo Schommer)
* 2013-09-27 [c7f656c](https://github.com/silverstripe/silverstripe-framework/commit/c7f656cd0051a051bca2e60011c52ff812596d8a) Removed "PastMember" cookie and template getter (Ingo Schommer)
* 2013-08-08 [4385264](https://github.com/silverstripe/silverstripe-framework/commit/4385264aa9da453d3a9fcf28d92c61ef31d928f2) Make GridFieldConfig objects decoratable (unclecheese)
* 2013-07-10 [7c60c73](https://github.com/silverstripe/silverstripe-framework/commit/7c60c73dbb2559cc5950eb40efa640e04bde2d17) Polymorphic has_one behaviour (Damian Mooyman)
* 2013-06-30 [47147eb](https://github.com/silverstripe/silverstripe-framework/commit/47147eb3dfc39a13da9ff9b9644c0ce0375bd669) delete simplepie from framework thirdparty (carlos barberis)
* 2013-06-20 [a395c53](https://github.com/silverstripe/silverstripe-cms/commit/a395c5322fc1965b775be50149a38cdff36cca59) Move of codebase to parameterised query database abstraction layer (Damian Mooyman)
* 2013-06-20 [d8e9af8](https://github.com/silverstripe/silverstripe-framework/commit/d8e9af8af8d59b3ee16f404f2f2b0a528d503022) Database abstraction layer. Ticket #7429 (Damian Mooyman)
* 2013-05-31 [0c4ec47](https://github.com/silverstripe/silverstripe-framework/commit/0c4ec4708bcbb8fb09a1bb9acf75639077cbaaa9) Using $HolderID for form field container templates (Ingo Schommer)
* 2013-05-25 [ca87b8b](https://github.com/silverstripe/silverstripe-framework/commit/ca87b8b79496a78454d63c225f1f4f38fa55a150) Form Field ID attribute should follow HTML specification (Will Rossiter)
* 2013-05-22 [cb1f95e](https://github.com/silverstripe/silverstripe-framework/commit/cb1f95e51eff1ce762456e0fa6b7eca38ccc3198) Remove AjaxUniqueTextField, since its operation is very limited (#1947) (Ingo Schommer)
* 2013-01-29 [957469d](https://github.com/silverstripe/silverstripe-framework/commit/957469d770c555d5461ea476906fbaa64ac2bc02) Removed auto-routing of controller name (Ingo Schommer)
* 2013-01-17 [56346a5](https://github.com/silverstripe/silverstripe-cms/commit/56346a50bf161a2a840517cf8bf5d38cf8174103) moved reports API to separate module (Will Rossiter)
### Features and Enhancements
* 2015-06-02 [a9d22f1](https://github.com/silverstripe/silverstripe-framework/commit/a9d22f1fbf6e499ac0cc7f12e3f389015a07834d) Files can be uploaded directly in the 'Insert Link' form (scott1702)
* 2015-05-29 [44b1ff1](https://github.com/silverstripe/silverstripe-framework/commit/44b1ff193106e55aa754f64ddab28146f8857290) Configurable file version prefix (Jonathon Menz)
* 2015-05-11 [ce5a8f2](https://github.com/silverstripe/silverstripe-framework/commit/ce5a8f2b415d4c4f0680f5adece2686f0a490f48) Cookie names with dots are now handled more gracefully (Daniel Hensby)
* 2015-03-31 [ae8dbe3](https://github.com/silverstripe/silverstripe-framework/commit/ae8dbe309b797a20a91088351d70486cf3dfea79) - Added maximum upload file size by type (Turnerj)
* 2015-03-24 [16f0e7b](https://github.com/silverstripe/silverstripe-framework/commit/16f0e7b0d3f1b25af325c224ea4111303b50785b) ViewableData_Debugger implements __toString (Daniel Hensby)
* 2015-03-03 [835ee69](https://github.com/silverstripe/silverstripe-framework/commit/835ee69339fbfca0c477c3717cc12c1c1e7737e0) Only validate DataObject model definitions during a build (Loz Calver)
* 2015-02-24 [8ee9130](https://github.com/silverstripe/silverstripe-framework/commit/8ee9130bcf10339c3eed54e10aa55f297ec89efd) CMS site tree status icons (Jonathon Menz)
* 2015-02-08 [5f31983](https://github.com/silverstripe/silverstripe-framework/commit/5f31983ded7a7a08586a74a9b5ff594d84a8a11c) updateAttributes hook in FormField (Ingo Schommer)
* 2015-01-23 [3f1805b](https://github.com/silverstripe/silverstripe-framework/commit/3f1805bfd2934bdf2a489fdd00b5c21308cf9837) Support multiple many_manys between the same classes (closes #1377) (Josh)
* 2014-12-15 [6ad8f7c](https://github.com/silverstripe/silverstripe-framework/commit/6ad8f7c3dd1d4b18d9982ac33e709dac6436a664) Subject line for email links in HtmlEditorField (Loz Calver)
* 2014-11-12 [41ea83b](https://github.com/silverstripe/silverstripe-framework/commit/41ea83b3374d026da9575f5256a02bdcfbb82059) add validation to form field subclasses (Stevie Mayhew)
* 2014-10-17 [dc7bc46](https://github.com/silverstripe/silverstripe-framework/commit/dc7bc4673e6860938519bb7cb9fba9e3835fd5de) Text - Limit characters to closest word (Anton Smith)
* 2014-10-03 [23fc498](https://github.com/silverstripe/silverstripe-framework/commit/23fc498c275db92ba182be3bf13e672b20866ba3) Allow 'null' limit for database queries (closes #3487) (Loz Calver)
* 2014-05-04 [3b9056f](https://github.com/silverstripe/silverstripe-framework/commit/3b9056fc014d1a9432aa1142174904ac6c1f8e08) Cookie_Backend for managing cookie state (Daniel Hensby)
* 2013-10-17 [e8287cd](https://github.com/silverstripe/silverstripe-framework/commit/e8287cd2f56952345be65e98fb732476b8c0b481) Hook for `Member::registerFailedLogin` (Thomas Speak)
* 2013-08-23 [7d7c754](https://github.com/silverstripe/silverstripe-cms/commit/7d7c75414c338bfd906f7e63eccaccff913951ef) Track broken anchors (Russell Michell)
* 2013-06-05 [60333f6](https://github.com/silverstripe/silverstripe-framework/commit/60333f68ee3557ce9ecef1984c988a08c2fe6b51) UploadField lists all files, shows path info (Ingo Schommer)
* 2013-06-03 [2a91d27](https://github.com/silverstripe/silverstripe-framework/commit/2a91d27ccb15ea4bb2e8501b7735f977a206d83b) use Injector pattern to create ValidationResult in validate (Will Morgan)
* 2013-05-25 [736bde8](https://github.com/silverstripe/silverstripe-framework/commit/736bde8fe578a8702e72e801996b9cc2c989b9c2) Add Convert::raw2htmlid() (Will Rossiter)
* 2013-03-26 [64349fe](https://github.com/silverstripe/silverstripe-framework/commit/64349fefb5fdc2c8a189a49d72e6a68a6c95afbc) Allow setting of ASSETS_DIR in _ss_environment.php (Loz Calver)
### Bugfixes
* 2015-10-06 [df805af](https://github.com/silverstripe/silverstripe-framework/commit/df805af67bda15888d17f49817903bf136561773) Imagick tests compare image dimensions rather than image hashes (Damian Mooyman)
* 2015-10-05 [ad42f80](https://github.com/silverstripe/silverstripe-framework/commit/ad42f802c4a621916a352c3a7c5d4f849b896c3e) Fix duplicate HolderID on TreeDropdownField (Damian Mooyman)
* 2015-10-05 [6c117cd](https://github.com/silverstripe/silverstripe-framework/commit/6c117cd62960670239c5a6f6b3832c819e21332a) fix imagick interface and add to travis (Damian Mooyman)
* 2015-09-30 [cb55a0a](https://github.com/silverstripe/silverstripe-framework/commit/cb55a0a621494873a04c697ecd326bb7a4d02173) GridFieldSortableHeader incorrectly reporting fields as sortable (Loz Calver)
* 2015-09-29 [666ce26](https://github.com/silverstripe/silverstripe-framework/commit/666ce269292521288eef8aeac4af30378f775576) Permission::checkMember() use of undefined variable $codes (Manuel Teuber)
* 2015-09-23 [8f0f647](https://github.com/silverstripe/silverstripe-framework/commit/8f0f6475daa6cb32a33089ef60f18d5f4f8735ed) Issues with field focus in edit forms (fixes #4621) (Loz Calver)
* 2015-09-23 [052aba1](https://github.com/silverstripe/silverstripe-cms/commit/052aba17acee51a276e42bcc0bd5a26b4cc2ae58) Incorrect field IDs breaking SiteTree settings toggles (fixes #1280) (Loz Calver)
* 2015-09-22 [0d89a13](https://github.com/silverstripe/silverstripe-framework/commit/0d89a13c2d02dc08d8ff14884b12f22b2f1cf4f2) GridFieldDetailForm failing to save many_many relations (Loz Calver)
* 2015-09-14 [81ca74b](https://github.com/silverstripe/silverstripe-framework/commit/81ca74bc30cb8f128c48672fd9807943c924145d) #103 (David Alexander)
* 2015-09-10 [6056e9c](https://github.com/silverstripe/silverstripe-framework/commit/6056e9cb1bc4f8073aef07b83f7417edbe7f2ac4) Editing existing file links in HtmlEditorField was broken (Loz Calver)
* 2015-08-31 [e86b45b](https://github.com/silverstripe/silverstripe-framework/commit/e86b45bf5db663b03e006a132e04afba37ee4bf3) Remove html5 number field due to insufficient localisation support (Damian Mooyman)
* 2015-08-24 [f7c1983](https://github.com/silverstripe/silverstripe-framework/commit/f7c19830d663ee05d81f7fa504b1ef043b8361fe) Fix JS error on clicking collapsed panel (Damian Mooyman)
* 2015-08-24 [6c17397](https://github.com/silverstripe/silverstripe-cms/commit/6c173973229acc198cb467ee369bab5af96b7f13) block adding children from archived pages (Damian Mooyman)
* 2015-08-21 [0f81d5e](https://github.com/silverstripe/silverstripe-framework/commit/0f81d5ece57a50c0daaf0d86c2faa977f323663b) Fix bulk actions making sitetree unclickable (Damian Mooyman)
* 2015-08-09 [cf9d2d1](https://github.com/silverstripe/silverstripe-framework/commit/cf9d2d12ac7fc6a2509ee70f8e6f304b3b232019) Fix duplicate primary key crash on duplicate (Damian Mooyman)
* 2015-08-07 [1f0602d](https://github.com/silverstripe/silverstripe-framework/commit/1f0602d42fd9e1c0a4268f3a51aa7f483100a935) Fixed regression from ClassInfo case-sensitivity fix. (Sam Minnee)
* 2015-07-30 [66ca540](https://github.com/silverstripe/silverstripe-framework/commit/66ca5405d0cb8116e5cdf5f886b96d321b20477c) Fix change detection on browser back button (Damian Mooyman)
* 2015-07-30 [97b226a](https://github.com/silverstripe/silverstripe-framework/commit/97b226abe023bbc059633cd944ff04c281a675a8) Fix semver violation in create_table_options (Damian Mooyman)
* 2015-07-27 [aa286ef](https://github.com/silverstripe/silverstripe-framework/commit/aa286ef7d77d78cde1aaedb2eca5b3c07803366b) Missing thumbnails and inconsistencies (Jonathon Menz)
* 2015-07-23 [10b2fdc](https://github.com/silverstripe/silverstripe-cms/commit/10b2fdc3181310ec3ca75361852deca57ccbbe4c) ContentController::getViewer() not returning all found templates (fixes #1244) (Loz Calver)
* 2015-07-22 [b7480b9](https://github.com/silverstripe/silverstripe-framework/commit/b7480b92a9c734058135a3259a1c4432c6bb474d) Hide 'Logged Passwords' tab in member CMS fields (fixes #4422) (Loz Calver)
* 2015-07-05 [a5b3083](https://github.com/silverstripe/silverstripe-framework/commit/a5b3083dccaedf6a78a5bfd5ecfc5d12ca7cdfba) memory exhaustion in MySQLStatement-&gt;bind() (micmania1)
* 2015-07-01 [3b90fef](https://github.com/silverstripe/silverstripe-cms/commit/3b90fef04f914aa6d4a43322771ea1d6b3329af2) fix behat tests (Damian Mooyman)
* 2015-06-24 [3507ddb](https://github.com/silverstripe/silverstripe-framework/commit/3507ddb0e8f85cb2a2cb20595590b1c89cc27c67) MemberPassword history removed with with Members (Daniel Hensby)
* 2015-06-19 [a58e595](https://github.com/silverstripe/silverstripe-framework/commit/a58e59565b7b092451b084643d58ddb6ccfbee31) docs not included in composer package installs (through export-ignore git attribute) (Sam Minnee)
* 2015-06-16 [ce3b5a5](https://github.com/silverstripe/silverstripe-framework/commit/ce3b5a5ace556f65a23348ed6e7bd50dd639f9e0) Fix major segfault on PDOConnector after any DDL (Damian Mooyman)
* 2015-06-09 [24a268a](https://github.com/silverstripe/silverstripe-framework/commit/24a268a12b5ade6e513694e6e7d826f5f0759ee2) Image test cleanup (Jonathon Menz)
* 2015-06-09 [07c21e2](https://github.com/silverstripe/silverstripe-framework/commit/07c21e28805236807387b984e988f62043728620) Fix deletion of orphaned versioned records when a parent _versions table has been deleted (Damian Mooyman)
* 2015-06-08 [acf19b7](https://github.com/silverstripe/silverstripe-framework/commit/acf19b72e2a6fb52527a788b1ed87f552e57f314) Fix false values for many_many_ExtraFields not being saved (Damian Mooyman)
* 2015-06-04 [a819bcf](https://github.com/silverstripe/silverstripe-cms/commit/a819bcfc97a6594787cea738bda2596787ab673f) explicitly call get functions for site tree checks (Stevie Mayhew)
* 2015-05-22 [68d8df4](https://github.com/silverstripe/silverstripe-framework/commit/68d8df4e04556b3f9ad63a6d8cff84e63f972d66) DropdownField didn't consider disabled items (Loz Calver)
* 2015-05-11 [9e8a5c9](https://github.com/silverstripe/silverstripe-framework/commit/9e8a5c9ba557298eed319744d3cc5689483063ab) remove validation type constraint from form fields for 3.2 release (Stevie Mayhew)
* 2015-04-02 [dd0e2dc](https://github.com/silverstripe/silverstripe-framework/commit/dd0e2dc36200e3931923693c2b9dc978aea99825) Image_Cached exists method doesnt check for positive ID (Daniel Hensby)
* 2015-02-14 [bee642a](https://github.com/silverstripe/silverstripe-framework/commit/bee642a6b9de946f507b73f07412d4ee2127fe45) make class loader classExists check interface_exists as per docs (Daniel Hensby)
* 2015-02-13 [66391ab](https://github.com/silverstripe/silverstripe-framework/commit/66391ab57ad49c2a40bad59fc1fc9e1f12e39d97) Imported namespaces now correctly used to determine class inheritance (Daniel Hensby)
* 2015-02-08 [6212b4b](https://github.com/silverstripe/silverstripe-framework/commit/6212b4bd4bd9adcc79042ffffe88144796239b57) Versioned not ignoring obsolete fields (Benjamin R. White)
* 2015-01-30 [e724d6f](https://github.com/silverstripe/silverstripe-framework/commit/e724d6f578af8878226665f189c596276e4b1536) notice level error when value is not set on CreditCardField (Will Rossiter)
* 2015-01-07 [cee7adc](https://github.com/silverstripe/silverstripe-framework/commit/cee7adc12c9a05f14e956f8ff23f06c43e337b5f) . Placeholder isn't completely translated (Elvinas L)
* 2014-12-15 [c358ac6](https://github.com/silverstripe/silverstripe-framework/commit/c358ac6496a837e86e5b0ab97fcc56ae8a78a250) How to folder on forms (Cam Findlay)
* 2014-12-08 [bdb3b7f](https://github.com/silverstripe/silverstripe-framework/commit/bdb3b7f085d9ddc1152a98cc93418bcfd10d63d5) Feedback to name the fields section to "field types" to make it clearer what the section is about. (Cam Findlay)
* 2014-12-08 [aba9667](https://github.com/silverstripe/silverstripe-framework/commit/aba966729ac7570435fc33227e3ca88f4e4d955f) use GFMD code blocks to fix code formatting consistency. (Cam Findlay)
* 2014-11-03 [51337ac](https://github.com/silverstripe/silverstripe-framework/commit/51337acda91a68d0d353c521fb4541531dfa82bc) Image backend ignoring config. (Michael Strong)
* 2014-10-26 [ec0c259](https://github.com/silverstripe/silverstripe-framework/commit/ec0c259c17cd3b1df6235378692ed8b6a7630dfc) Reinstate tab and form focus states (fixes CMS #732 and #817) (Naomi Guyer)
* 2014-09-26 [db0cad4](https://github.com/silverstripe/silverstripe-framework/commit/db0cad461670a11f9ba27f979812be4d70ab37c9) ErrorControlChain now supports exception handling (Damian Mooyman)
* 2014-09-01 [c140459](https://github.com/silverstripe/silverstripe-framework/commit/c140459ac624738630ac8bec6a665fa3040e2e54) Fix versioned (Damian Mooyman)
* 2014-09-01 [3644110](https://github.com/silverstripe/silverstripe-framework/commit/364411034947b78d9077caf91ad215ae79d2afba) Ensure that columns are unique within a gridfield (Will Rossiter)
* 2014-08-01 [b0239f4](https://github.com/silverstripe/silverstripe-framework/commit/b0239f43302110f250d6121a518c5119a76d1fca) Fix PDOConnector issues (Damian Mooyman)
* 2014-07-25 [81c0a34](https://github.com/silverstripe/silverstripe-framework/commit/81c0a3499bea4aa4191011616e2cbaf9ed075748) Remove caching of statements due to risk of instability (Damian Mooyman)
* 2014-07-14 [0433ba1](https://github.com/silverstripe/silverstripe-framework/commit/0433ba1642efdd32c5667c12cc3ef7f2f5e7db04) Revert some changes to ManyManyList (Damian Mooyman)
* 2014-05-22 [3213630](https://github.com/silverstripe/silverstripe-framework/commit/32136305be887fe3118f078c3f73df569c86ca53) fix listview not working with IE9 (Igor)
* 2014-05-09 [8335de4](https://github.com/silverstripe/silverstripe-framework/commit/8335de49b3dacd614819af5f7ce12157bb38d6b9) remove redundant DB name switch in TestRunner (Will Morgan)
* 2014-05-02 [9cbfd14](https://github.com/silverstripe/silverstripe-framework/commit/9cbfd14d9d75628bdfd97a31ab571b5ad597b5eb) TemplateManifest prevent cache collision (Will Morgan)
* 2014-04-29 [5dd0583](https://github.com/silverstripe/silverstripe-cms/commit/5dd058338af08dd3ee5956e7a7c66c30160f6cd4) Fix encoding of SearchForm::getSearchQuery (Damian Mooyman)
* 2014-04-08 [438fe02](https://github.com/silverstripe/silverstripe-framework/commit/438fe02116365569893f3370d08c4b1f20f0b19e) change action variable source to getViewer (Will Morgan)
* 2014-03-27 [cf5d524](https://github.com/silverstripe/silverstripe-framework/commit/cf5d524235b82c3f13a0643333ffcd140788da14) Fix regressions from #2206 in hasValue and dbObject (Damian Mooyman)
* 2014-03-25 [4b87b2e](https://github.com/silverstripe/silverstripe-cms/commit/4b87b2e2e6ab1aac546d707f79ce00dc17ca07f8) Fix ContentControllerTest (Damian Mooyman)
* 2014-02-28 [ab52b67](https://github.com/silverstripe/silverstripe-framework/commit/ab52b677aac5caae974928642aee42cc76f54f65) Log out current member when forgotten password (Daniel Hensby)
* 2014-02-20 [f6b72a2](https://github.com/silverstripe/silverstripe-framework/commit/f6b72a20919c77615d222f28adaa735ff0f0a49b) Fixed regression in ContentController template selection. (Sam Minnee)
* 2014-02-14 [d0a4fc2](https://github.com/silverstripe/silverstripe-cms/commit/d0a4fc206542242362a753414bd28366c9c1a84e) Fix failover to index template in ContentController::getViewer() (Sam Minnee)
* 2014-02-03 [cd213ab](https://github.com/silverstripe/silverstripe-framework/commit/cd213ab4884958d45cccaaf75cde15c0c525584b) Fixed handing of false values in GridState_Data (Damian Mooyman)
* 2014-01-31 [6df276c](https://github.com/silverstripe/silverstripe-framework/commit/6df276c843621ca07da3ace5be681cef82dc1ae3) GridState_Data doesn't hold falsey values (Daniel Hensby)
* 2013-10-30 [4102cc6](https://github.com/silverstripe/silverstripe-framework/commit/4102cc64a07992639ea8e9fa91ad55f3c771e430) Issues with CMSForm not consistently respecting new form naming scheme. (Damian Mooyman)
* 2013-10-22 [8534982](https://github.com/silverstripe/silverstripe-framework/commit/85349820e4da838236064681d72405737850b438) Debug error handler breaks error_get_last (Damian Mooyman)
* 2013-10-19 [ab10c2e](https://github.com/silverstripe/silverstripe-framework/commit/ab10c2ecdc8522d11becb59fe7020ab0526d59e9) An enum field in the search panel model admin misses an option to not filter on that field (Nico Haase)
* 2013-10-17 [d22ca62](https://github.com/silverstripe/silverstripe-framework/commit/d22ca62c6f324548b7c494c84b39a4197e7a5f35) FailedLoginCount reset (Thomas Speak)
* 2013-10-02 [fb5bb64](https://github.com/silverstripe/silverstripe-framework/commit/fb5bb646fe2734464ef3fd500765146cdd63dbeb) Fixed cross-platform issues with test cases and file utilities (Damian Mooyman)
* 2013-05-30 [c7468ca](https://github.com/silverstripe/silverstripe-framework/commit/c7468caeb67ad680ef748621348b0d82e2fed992) Generate Form::FormName() through (Will Rossiter)
* 2013-05-25 [831a507](https://github.com/silverstripe/silverstripe-framework/commit/831a507c90b8a4560742e86ecb5defd6fe1e259d) Update references to ID values from 79c9433 (Will Rossiter)
* 2013-05-17 [3728907](https://github.com/silverstripe/silverstripe-framework/commit/372890703ca96abfa8695277c1851c0b8ca52428) allow children to be accessed via template (Will Morgan)
* 2013-01-23 [60c4d99](https://github.com/silverstripe/silverstripe-framework/commit/60c4d999d8a5892132ef3e29d47d8ced410c7061) PHPUnit latest not working with composer installed builds (Hamish Friedlander)
* 2012-12-13 [31255fc](https://github.com/silverstripe/silverstripe-framework/commit/31255fc8f0b03cd70ef3dc50c206c943b07c4c01) Set visibility on login form methods to public. (Justin Martin)
* 2012-12-11 [379b561](https://github.com/silverstripe/silverstripe-framework/commit/379b561cdbd599134196cd7801087f725d8fa993) RSSFeed now sets the Content-Type on the current HTTPResponse (Simon Welsh)