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

4.2 KiB

4.0.0 (unreleased)

Overview

Framework

  • Deprecate SQLQuery in favour SQLSelect
  • DataList::filter by null now internally generates "IS NULL" or "IS NOT NULL" conditions appropriately on queries
  • DataObject::database_fields now returns all fields on that table.
  • DataObject::db now returns composite fields.
  • DataObject::ClassName field has been refactored into a DBClassName type field.

Upgrading

New asset storage mechanism

File system has been abstracted into an abstract interface. By default, the out of the box filesystem uses Flysystem with a local storage mechanism (under the assets directory).

Because the filesystem now uses the sha1 of file contents in order to version multiple versions under the same filename, the default storage paths in 4.0 will not be the same as in 3.

In order to retain existing file paths in line with framework version 3 you should set the \SilverStripe\Filesystem\Flysystem\FlysystemAssetStore.legacy_paths config to true. Note that this will not allow you to utilise certain file versioning features in 4.0.

:::yaml
\SilverStripe\Filesystem\Flysystem\FlysystemAssetStore:
	legacy_paths: true

See [/developer_guides/files/file_management] for more information on how the new system works.

Upgrading code that uses composite db fields.

CompositeDBField is now an abstract class, not an interface. In many cases, custom code that handled saving of content into composite fields can be removed, as it is now handled by the base class.

The below describes the minimum amount of effort required to implement a composite DB field.

:::php
<?
class MyAddressField extends CompositeDBField {

	private static $composite_db = array(
		'Street' => 'Varchar(200)',
		'Suburb' => 'Varchar(100)',
		'City' => 'Varchar(100)',
		'Country' => 'Varchar(100)'
	);

	public function scaffoldFormField($title = null) {
		new AddressFormField($this->getName(), $title);
	}
}

Upgrading code that references DataObject::database_fields or DataObject::db

These methods have been updated to include base fields (such as ID, ClassName, Created, and LastEdited), as well as composite DB fields.

DataObject::database_fields does not have a second parameter anymore, and can be called directly on an object or class. E.g. Member::database_fields()

If user code requires the list of fields excluding base fields, then use custom_database_fields instead, or make sure to call unset($fields['ID']); if this field should be excluded.

DataObject:db() will return all logical fields, including foreign key ids and composite DB Fields, alongside any child fields of these composites. This method can now take a second parameter $includesTable, which when set to true (with a field name as the first parameter), will also include the table prefix in Table.ClassName(args) format.

Update code that uses SQLQuery

SQLQuery is still implemented, but now extends the new SQLSelect class and has some methods deprecated. Previously this class was used for both selecting and deleting, but these have been superceded by the specialised SQLSelect and SQLDelete classes.

Take care for any code or functions which expect an object of type SQLQuery, as these references should be replaced with SQLSelect. Legacy code which generates SQLQuery can still communicate with new code that expects SQLSelect as it is a subclass of SQLSelect, but the inverse is not true.

Update implementations of augmentSQL

Since this method now takes a SQLSelect as a first parameter, existing code referencing the deprecated SQLQuery type will raise a PHP error.

E.g.

Before:

:::php
function augmentSQL(SQLQuery &$query, DataQuery &$dataQuery = null) {
	$locale = Translatable::get_current_locale();
	if(!preg_match('/("|\'|`)Locale("|\'|`)/', implode(' ', $query->getWhere())))  {
		$qry = sprintf('"Locale" = \'%s\'', Convert::raw2sql($locale));
		$query->addWhere($qry); 
	}
}

After:

:::php
function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null) {
	$locale = Translatable::get_current_locale();
	if(!preg_match('/("|\'|`)Locale("|\'|`)/', implode(' ', $query->getWhereParameterised($parameters))))  {
		$query->addWhere(array(
			'"Locale"' => $locale
		));
	}
}