mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #7169 from open-sausages/pulls/4.0/upgrade-docs-need-an-upgrade
Upgrade the upgrading docs
This commit is contained in:
commit
2bd24e0f98
@ -10,6 +10,7 @@ guide developers in preparing existing 3.x code for compatibility with 4.0
|
|||||||
* [Upgrading Guide](#upgrading)
|
* [Upgrading Guide](#upgrading)
|
||||||
* [Standard Upgrade](#upgrading-primary)
|
* [Standard Upgrade](#upgrading-primary)
|
||||||
* [API Specific Upgrades](#upgrading-specifics)
|
* [API Specific Upgrades](#upgrading-specifics)
|
||||||
|
* [User code style upgrades](#usercode-style-upgrades)
|
||||||
* [API Changes](#api-changes)
|
* [API Changes](#api-changes)
|
||||||
* [General and Core API](#overview-general)
|
* [General and Core API](#overview-general)
|
||||||
* [ORM API](#overview-orm)
|
* [ORM API](#overview-orm)
|
||||||
@ -18,7 +19,7 @@ guide developers in preparing existing 3.x code for compatibility with 4.0
|
|||||||
* [i18n](#overview-i18n)
|
* [i18n](#overview-i18n)
|
||||||
* [Email and Mailer](#overview-mailer)
|
* [Email and Mailer](#overview-mailer)
|
||||||
* [SapphireTest](#overview-testing)
|
* [SapphireTest](#overview-testing)
|
||||||
* [Commit History](#commit-history)
|
* [Security](#overview-security)
|
||||||
|
|
||||||
## <a name="overview"></a>Highlights of major changes
|
## <a name="overview"></a>Highlights of major changes
|
||||||
|
|
||||||
@ -26,10 +27,12 @@ guide developers in preparing existing 3.x code for compatibility with 4.0
|
|||||||
is required.
|
is required.
|
||||||
* All code earlier marked as deprecated for 4.0 has now been removed. See
|
* All code earlier marked as deprecated for 4.0 has now been removed. See
|
||||||
[deprecation documentation](/contributing/release_process) for information on code deprecation.
|
[deprecation documentation](/contributing/release_process) for information on code deprecation.
|
||||||
* All SilverStripe classes are now namespaced, and some have been renamed. This has major implications for
|
* All code has been migrated to follow the PSR-2 coding standard. Most significantly, all SilverStripe
|
||||||
|
classes are now namespaced, and some have been renamed. This has major implications for
|
||||||
arrangement of templates, as well as other references to classes via string literals or configuration.
|
arrangement of templates, as well as other references to classes via string literals or configuration.
|
||||||
Automatic upgrading tools have been developed to cope with the bulk of these changes (see
|
Automatic upgrading tools have been developed to cope with the bulk of these changes (see
|
||||||
[upgrading notes](#upgrading)).
|
[upgrading notes](#upgrading)). Some classes have been rearranged so that each file contains only one class definition. It is recommended that user code follow the same convention.
|
||||||
|
For example, page types and their controllers should longer be collated in a single file.
|
||||||
* Object class has been removed.
|
* Object class has been removed.
|
||||||
* Asset storage has been abstracted, and a new concept of `DBFile` references via database column references
|
* Asset storage has been abstracted, and a new concept of `DBFile` references via database column references
|
||||||
now exists in addition to references via the existing `File` dataobject. File security and protected files
|
now exists in addition to references via the existing `File` dataobject. File security and protected files
|
||||||
@ -74,7 +77,14 @@ as a standard first point of upgrade.
|
|||||||
#### Upgrade references to renamed and namespaced classes
|
#### Upgrade references to renamed and namespaced classes
|
||||||
|
|
||||||
Nearly all core PHP classes have been namespaced. For example, `DataObject` is now called `SilverStripe\ORM\DataObject`.
|
Nearly all core PHP classes have been namespaced. For example, `DataObject` is now called `SilverStripe\ORM\DataObject`.
|
||||||
We have developed an [upgrader tool](https://github.com/silverstripe/silverstripe-upgrader/) to (semi-)automatically update your 3.x code to the new naming. Here's an example how to upgrade your `mysite` folder:
|
The below tasks describe how to upgrade an existing site to remain compatible with the newly upgraded classes.
|
||||||
|
|
||||||
|
##### Using the upgrader tool to automatically upgrade
|
||||||
|
|
||||||
|
This task should be run on every upgraded project.
|
||||||
|
|
||||||
|
We have developed an [upgrader tool](https://github.com/silverstripe/silverstripe-upgrader/) to (semi-)automatically
|
||||||
|
update your 3.x code to the new naming. Here's an example how to upgrade your `mysite` folder:
|
||||||
|
|
||||||
```
|
```
|
||||||
composer global require silverstripe/upgrader
|
composer global require silverstripe/upgrader
|
||||||
@ -92,6 +102,83 @@ For a full list of renamed classes, check the `.upgrade.yml` definitions in each
|
|||||||
|
|
||||||
The rename won't affect class-based permission codes or database table names.
|
The rename won't affect class-based permission codes or database table names.
|
||||||
|
|
||||||
|
##### Upgrade references to literal or class table names
|
||||||
|
|
||||||
|
In 3.x the class name of any DataObject matched the table name, but in 4.x all classes are namespaced, and it is
|
||||||
|
necessary to map between table and class for querying the database.
|
||||||
|
|
||||||
|
In order to ensure you are using the correct table for any class a new
|
||||||
|
[DataObjectSchema](api:SilverStripe\ORM\DataObjectSchema) service is available to manage these mappings
|
||||||
|
(see [versioned documentation](/developer_guides/model/data_model_and_orm)).
|
||||||
|
|
||||||
|
For example, the below shows how you would update a query with a hard-coded table name:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
public function countDuplicates($model, $fieldToCheck)
|
||||||
|
{
|
||||||
|
$query = new SilverStripe\ORM\Queries\SQLSelect();
|
||||||
|
+ $table = SilverStripe\ORM\DataObject::getSchema()->tableForField($model, $field);
|
||||||
|
- $query->setFrom("\"{$model}\"");
|
||||||
|
+ $query->setFrom("\"{$table}\"");
|
||||||
|
- $query->setWhere(["\"{$model}\".\"{$field}\"" => $model->$fieldToCheck]);
|
||||||
|
+ $query->setWhere(["\"{$table}\".\"{$field}\"" => $model->$fieldToCheck]);
|
||||||
|
return $query->count();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Replacing literal strings with fully qualified class name, or ::class constant
|
||||||
|
|
||||||
|
You'll need to update any strings that represent class names and make sure they're fully
|
||||||
|
qualified. In particular, relationship definitions such as `has_one` and `has_many` will need
|
||||||
|
to be updated to refer to fully qualified class names.
|
||||||
|
|
||||||
|
In configs and with literal PHP strings it is recommended to use the php `::class` constant,
|
||||||
|
as demonstrated below.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
<?php
|
||||||
|
+ use SilverStripe\ORM\DataObject;
|
||||||
|
+ use SilverStripe\Security\Member;
|
||||||
|
class MyClass extends DataObject
|
||||||
|
{
|
||||||
|
private static $has_one = [
|
||||||
|
- 'Author' => 'Member',
|
||||||
|
+ 'Author' => Member::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In the context of YAML, the magic constant `::class` does not apply. Fully qualified class names must be hard coded.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
-MyObject:
|
||||||
|
+My\Project\MyObject:
|
||||||
|
property: value
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Update references to literal classes to use Injector
|
||||||
|
|
||||||
|
In many places, classes namespaced in SilverStripe 4.x will still have a non-namespaced service
|
||||||
|
name that can be accessed via Injector. You should upgrade direct object constructors with
|
||||||
|
the Injector API.
|
||||||
|
|
||||||
|
E.g.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- $field = new Varchar();
|
||||||
|
+ $field = Injector::inst()->create('Varchar');
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Migrate your controllers to their own files
|
||||||
|
|
||||||
|
The convention for naming controllers is now `[MyPageType]Controller`, where it used to be `[MyPageType]_Controller`. This change was made to be more compatible with the PSR-2 standards.
|
||||||
|
|
||||||
|
You can still use, for example, `Page_Controller`, but you will get a deprecation notice. It is
|
||||||
|
best to change it to `PageController` during your upgrade process. Keep in mind any modules or
|
||||||
|
other thirdparty code that extend `PageController` are likely to assume that class exists.
|
||||||
|
|
||||||
|
By default, a controller for a page type *must* reside in the same namespace as its page. To use different logic, override `SiteTree::getControllerName()`.
|
||||||
|
|
||||||
#### Upgrade template locations and references
|
#### Upgrade template locations and references
|
||||||
|
|
||||||
Templates are now much more strict about their locations. You can no longer put a template in an arbitrary
|
Templates are now much more strict about their locations. You can no longer put a template in an arbitrary
|
||||||
@ -109,6 +196,28 @@ Core template locations have moved - if you're including or overriding these
|
|||||||
no longer exists, and instead template locations will be placed in paths that match
|
no longer exists, and instead template locations will be placed in paths that match
|
||||||
the `SilverStripe\Forms` namespace.
|
the `SilverStripe\Forms` namespace.
|
||||||
|
|
||||||
|
#### Upgrade static config settings to `private static`
|
||||||
|
|
||||||
|
If you have some class configuration statics defined and they aren't private,
|
||||||
|
you may find that they don't register anymore. For example, this code, taken from
|
||||||
|
the `silverstripe/tagfield` module will no longer work in SilverStripe 4.0.
|
||||||
|
|
||||||
|
```php
|
||||||
|
public static $allowed_actions = [
|
||||||
|
'suggest'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Changing the visibility to `private` (as per `RequestHandler::$allowed_actions`
|
||||||
|
visibility) will make it 4.0 compatible.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
-public static $allowed_actions = [
|
||||||
|
+private static $allowed_actions = [
|
||||||
|
'suggest'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
#### Upgrade module paths in file references
|
#### Upgrade module paths in file references
|
||||||
|
|
||||||
You should no longer rely on modules being placed in a deterministic folder (e.g. `/framework`),
|
You should no longer rely on modules being placed in a deterministic folder (e.g. `/framework`),
|
||||||
@ -172,15 +281,89 @@ To ensure consistency, we've also deprecated support for path constants:
|
|||||||
The below sections deal with upgrades to specific parts of various API. Projects which rely on certain
|
The below sections deal with upgrades to specific parts of various API. Projects which rely on certain
|
||||||
API should be upgraded as appropriate using any of the relevant processes documented below.
|
API should be upgraded as appropriate using any of the relevant processes documented below.
|
||||||
|
|
||||||
|
#### Upgrade references of SS_Log to use PSR-3 logging
|
||||||
|
|
||||||
|
One of the great changes that comes with SilverStripe 4 is the introduction of
|
||||||
|
[PSR-3](http://www.php-fig.org/psr/psr-3/) compatible logger interfaces. This
|
||||||
|
means we can use thirdparty services like Monolog. `SS_Log` has been replaced
|
||||||
|
with a logger which can be accessed using the LoggerInterface::class service.
|
||||||
|
|
||||||
|
For instance, code which logs errors should be upgraded as below:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
-SS_Log::log('My error message', SS_Log::ERR);
|
||||||
|
+use Psr\Log\LoggerInterface;
|
||||||
|
+Injector::inst()->get(LoggerInterface::class)->error('My error message');
|
||||||
|
```
|
||||||
|
|
||||||
|
##### How to customise the default PSR-3 logger
|
||||||
|
|
||||||
|
If necessary, you may need to customise either the default logging handler, or
|
||||||
|
one of the error formatters. For example, if running unit tests you may want to
|
||||||
|
suppress errors. You can temporarily disable logging by setting a `NullHandler`
|
||||||
|
|
||||||
|
```yml
|
||||||
|
---
|
||||||
|
Name: custom-dev-logging
|
||||||
|
After: dev-logging
|
||||||
|
Only:
|
||||||
|
environment: dev
|
||||||
|
---
|
||||||
|
# Replace default handler with null
|
||||||
|
SilverStripe\Core\Injector\Injector:
|
||||||
|
Monolog\Handler\HandlerInterface: Monolog\Handler\NullHandler
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively you can customise one or both of the below services:
|
||||||
|
- `Monolog\Formatter\FormatterInterface.detailed` service, which is used for displaying
|
||||||
|
detailed error messages useful for developers.
|
||||||
|
- `Monolog\Formatter\FormatterInterface.friendly` service, which is used to display "error"
|
||||||
|
page content to visitors of the site who encounter errors.
|
||||||
|
|
||||||
|
For example, a custom error page generator could be added as below:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
---
|
||||||
|
Name: custom-errorpage
|
||||||
|
After:
|
||||||
|
- '#loggingformatters'
|
||||||
|
---
|
||||||
|
SilverStripe\Core\Injector\Injector:
|
||||||
|
Monolog\Formatter\FormatterInterface.friendly:
|
||||||
|
class: WebDesignGroup\ShopSite\Logging\ErrorPageFormatter
|
||||||
|
```
|
||||||
|
|
||||||
|
`WebDesignGroup\ShopSite\Logging\ErrorPageFormatter` should be a class that
|
||||||
|
implements the `Monolog\Formatter\FormatterInterface` interface.
|
||||||
|
|
||||||
#### Upgrade `mysite/_config.php`
|
#### Upgrade `mysite/_config.php`
|
||||||
|
|
||||||
The globals `$database` and `$databaseConfig` are deprecated. You should upgrade your
|
The globals `$database` and `$databaseConfig` are deprecated. You should upgrade your
|
||||||
site _config.php files to use the `.env` configuration (below).
|
site _config.php files to use the `.env` configuration (below).
|
||||||
|
|
||||||
If you need to configure database details in PHP, use the new `DB::setConfig()` api instead.
|
`conf/ConfigureFromEnv.php` is also no longer used, and references to this file should be deleted.
|
||||||
|
|
||||||
You should remove any references to `ConfigureFromEnv.php` in your project, as this file
|
If you need to configure database details in PHP you should configure these details via `.env` file,
|
||||||
is no longer necessary.
|
or alternatively (but less recommended) use the new `DB::setConfig()` api.
|
||||||
|
|
||||||
|
The global `$project` is deprecated in favour of the configuration setting
|
||||||
|
`SilverStripe\Core\Manifest\ModuleManifest.project`.
|
||||||
|
|
||||||
|
Changes to `mysite/_config.php`:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
<?php
|
||||||
|
-global $project;
|
||||||
|
-$project = 'mysite';
|
||||||
|
-include 'conf/ConfigureFromEnv.php';
|
||||||
|
```
|
||||||
|
|
||||||
|
And also add to `mysite/_config/mysite.yml`:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
SilverStripe\Core\Manifest\ModuleManifest:
|
||||||
|
project: mysite
|
||||||
|
```
|
||||||
|
|
||||||
#### Upgrade of `_ss_environment.php` to `.env` configuration
|
#### Upgrade of `_ss_environment.php` to `.env` configuration
|
||||||
|
|
||||||
@ -204,7 +387,7 @@ $_FILE_TO_URL_MAPPING[__DIR__] = 'http://localhost';
|
|||||||
// Database
|
// Database
|
||||||
define('SS_DATABASE_CHOOSE_NAME', true);
|
define('SS_DATABASE_CHOOSE_NAME', true);
|
||||||
define('SS_DATABASE_CLASS', 'MySQLDatabase');
|
define('SS_DATABASE_CLASS', 'MySQLDatabase');
|
||||||
define('SS_DATABASE_USERNAME', 'root')
|
define('SS_DATABASE_USERNAME', 'root');
|
||||||
define('SS_DATABASE_PASSWORD', '');
|
define('SS_DATABASE_PASSWORD', '');
|
||||||
define('SS_DATABASE_SERVER', '127.0.0.1');
|
define('SS_DATABASE_SERVER', '127.0.0.1');
|
||||||
```
|
```
|
||||||
@ -548,7 +731,7 @@ In YML format this will be expressed as the below:
|
|||||||
`mymodule/lang/en.yml`:
|
`mymodule/lang/en.yml`:
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
en:
|
en:
|
||||||
MyObject:
|
MyObject:
|
||||||
SINGULAR_NAME: 'object'
|
SINGULAR_NAME: 'object'
|
||||||
@ -561,7 +744,7 @@ en:
|
|||||||
`extendedmodule/lang/en.yml`:
|
`extendedmodule/lang/en.yml`:
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
en:
|
en:
|
||||||
AnotherSection:
|
AnotherSection:
|
||||||
DESCRIPTION: 'This is the description for this section'
|
DESCRIPTION: 'This is the description for this section'
|
||||||
@ -612,7 +795,7 @@ In order to retain existing file paths in line with framework version 3 you shou
|
|||||||
Note that this will not allow you to utilise certain file versioning features in 4.0.
|
Note that this will not allow you to utilise certain file versioning features in 4.0.
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
SilverStripe\Filesystem\Flysystem\FlysystemAssetStore:
|
SilverStripe\Filesystem\Flysystem\FlysystemAssetStore:
|
||||||
legacy_paths: true
|
legacy_paths: true
|
||||||
```
|
```
|
||||||
@ -629,7 +812,7 @@ this task is run manually during an explicit migration process, as this process
|
|||||||
large amounts of memory and run for an extended time.
|
large amounts of memory and run for an extended time.
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
File:
|
File:
|
||||||
migrate_legacy_file: true
|
migrate_legacy_file: true
|
||||||
```
|
```
|
||||||
@ -850,14 +1033,14 @@ use SilverStripe\ORM\FieldType\DBComposite;
|
|||||||
|
|
||||||
class MyAddressField extends DBComposite
|
class MyAddressField extends DBComposite
|
||||||
{
|
{
|
||||||
private static $composite_db = ]
|
private static $composite_db = [
|
||||||
'Street' => 'Varchar(200)',
|
'Street' => 'Varchar(200)',
|
||||||
'Suburb' => 'Varchar(100)',
|
'Suburb' => 'Varchar(100)',
|
||||||
'City' => 'Varchar(100)',
|
'City' => 'Varchar(100)',
|
||||||
'Country' => 'Varchar(100)'
|
'Country' => 'Varchar(100)'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function scaffoldFormField($title = null)
|
public function scaffoldFormField($title = null, $params = null)
|
||||||
{
|
{
|
||||||
new SilverStripe\Forms\TextField($this->getName(), $title);
|
new SilverStripe\Forms\TextField($this->getName(), $title);
|
||||||
}
|
}
|
||||||
@ -891,39 +1074,6 @@ these references should be replaced with `SQLSelect`. Legacy code which generate
|
|||||||
`SQLQuery` can still communicate with new code that expects `SQLSelect` as it is a
|
`SQLQuery` can still communicate with new code that expects `SQLSelect` as it is a
|
||||||
subclass of `SQLSelect`, but the inverse is not true.
|
subclass of `SQLSelect`, but the inverse is not true.
|
||||||
|
|
||||||
#### Upgrade code that references table names
|
|
||||||
|
|
||||||
A major change in 4.0.0 is that now tables and class names can differ from model to model. In order to
|
|
||||||
fix a table name, to prevent it being changed (for instance, when applying a namespace to a model)
|
|
||||||
the `table_name` config can be applied to any DataObject class.
|
|
||||||
|
|
||||||
|
|
||||||
```php
|
|
||||||
namespace SilverStripe\BannerManager;
|
|
||||||
|
|
||||||
use SilverStripe\ORM\DataObject;
|
|
||||||
|
|
||||||
class BannerImage extends DataObject
|
|
||||||
{
|
|
||||||
private static $table_name = 'BannerImage';
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In order to ensure you are using the correct table for any class a new [DataObjectSchema](api:SilverStripe\ORM\DataObjectSchema) service
|
|
||||||
is available to manage these mappings (see [versioned documentation](/developer_guides/model/data_model_and_orm)).
|
|
||||||
|
|
||||||
|
|
||||||
```php
|
|
||||||
public function countDuplicates($model, $fieldToCheck)
|
|
||||||
{
|
|
||||||
$table = SilverStripe\ORM\DataObject::getSchema()->tableForField($model, $field);
|
|
||||||
$query = new SilverStripe\ORM\Queries\SQLSelect();
|
|
||||||
$query->setFrom("\"{$table}\"");
|
|
||||||
$query->setWhere(["\"{$table}\".\"{$field}\"" => $model->$fieldToCheck]);
|
|
||||||
return $query->count();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Upgrade BuildTask classes
|
#### Upgrade BuildTask classes
|
||||||
|
|
||||||
Similarly to the `$table_name` configuration property for DataObjects, you should define a `private static $segment` for `BuildTask`
|
Similarly to the `$table_name` configuration property for DataObjects, you should define a `private static $segment` for `BuildTask`
|
||||||
@ -1105,10 +1255,43 @@ These methods are deprecated:
|
|||||||
#### Implementation of ownership API
|
#### Implementation of ownership API
|
||||||
|
|
||||||
In order to support the recursive publishing of dataobjects, a new API has been developed to allow
|
In order to support the recursive publishing of dataobjects, a new API has been developed to allow
|
||||||
developers to declare dependencies between objects. See the
|
developers to declare dependencies between objects. This is done to ensure that the published state
|
||||||
[versioned documentation](/developer_guides/model/versioning) for more information.
|
of linked components are consistent with their "owner." Without the concept of ownership, these linked
|
||||||
|
components could be implicitly exposed on the frontend, which may not align with the intent of the
|
||||||
|
content author.
|
||||||
|
|
||||||
By default all versioned dataobjects will automatically publish objects that they own.
|
For instance, on a products page which has a list of products, the products should not be published unless the products page is, too. The ownership API solves this by allowing you to declare
|
||||||
|
a two-way relationship between objects, typically, but not necessarily, linked by a database relationship
|
||||||
|
(`has_many`, `many_many`, etc.).
|
||||||
|
|
||||||
|
```php
|
||||||
|
class ProductPage extends Page
|
||||||
|
{
|
||||||
|
private static $has_many = [
|
||||||
|
'Products' => Product::class
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $owns = [
|
||||||
|
'Products'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Product extends DataObject
|
||||||
|
{
|
||||||
|
private static $extensions = [
|
||||||
|
Versioned::class
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $has_one = [
|
||||||
|
'Parent' => ProductPage::class
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
If your objects are linked by something other than a database relationship, for instance, a custom
|
||||||
|
getter that is computed at runtime, the same rules can be applied, as long as you provide an `$owned_by`
|
||||||
|
setting on the child object.
|
||||||
|
|
||||||
|
For more information, see the [DataObject ownership](https://docs.silverstripe.org/en/4/developer_guides/model/versioning/#dataobject-ownership) documentation and the [versioning](/developer_guides/model/versioning) documentation
|
||||||
|
|
||||||
#### ChangeSet batch publishing
|
#### ChangeSet batch publishing
|
||||||
|
|
||||||
@ -1210,7 +1393,7 @@ specific functions.
|
|||||||
|
|
||||||
The methods `register` and `unregister` on `Authenticator` are deprecated in favor of the `Config` system. This means that any custom Authenticator needs to be registered through the yml config:
|
The methods `register` and `unregister` on `Authenticator` are deprecated in favor of the `Config` system. This means that any custom Authenticator needs to be registered through the yml config:
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
SilverStripe\Security\Authenticator;
|
SilverStripe\Security\Authenticator;
|
||||||
authenticators:
|
authenticators:
|
||||||
- MyVendor\MyModule\MyAuthenticator
|
- MyVendor\MyModule\MyAuthenticator
|
||||||
@ -1218,7 +1401,7 @@ SilverStripe\Security\Authenticator;
|
|||||||
|
|
||||||
If there is no authenticator registered, `Authenticator` will try to fall back on the `default_authenticator`, which can be changed using the following config, replacing the MemberAuthenticator with your authenticator:
|
If there is no authenticator registered, `Authenticator` will try to fall back on the `default_authenticator`, which can be changed using the following config, replacing the MemberAuthenticator with your authenticator:
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
SilverStripe\Security\Authenticator:
|
SilverStripe\Security\Authenticator:
|
||||||
default_authenticator: SilverStripe\Security\MemberAuthenticator
|
default_authenticator: SilverStripe\Security\MemberAuthenticator
|
||||||
```
|
```
|
||||||
@ -1254,7 +1437,6 @@ This also allowed us to remove SilverStripe's `Cache` API and use dependency inj
|
|||||||
Caches should be retrieved through `Injector` instead of `Cache::factory()`,
|
Caches should be retrieved through `Injector` instead of `Cache::factory()`,
|
||||||
and have a slightly different API (e.g. `set()` instead of `save()`).
|
and have a slightly different API (e.g. `set()` instead of `save()`).
|
||||||
|
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
-$cache = Cache::factory('myCache');
|
-$cache = Cache::factory('myCache');
|
||||||
+use Psr\SimpleCache\CacheInterface;
|
+use Psr\SimpleCache\CacheInterface;
|
||||||
@ -1281,10 +1463,9 @@ and have a slightly different API (e.g. `set()` instead of `save()`).
|
|||||||
+$cache->delete('myCacheKey');
|
+$cache->delete('myCacheKey');
|
||||||
```
|
```
|
||||||
|
|
||||||
With the necessary minimal config in `_config/mycache.yml`
|
With the necessary minimal config in _config/mycache.yml
|
||||||
|
|
||||||
|
```yml
|
||||||
```yaml
|
|
||||||
---
|
---
|
||||||
Name: mycache
|
Name: mycache
|
||||||
---
|
---
|
||||||
@ -1295,13 +1476,12 @@ SilverStripe\Core\Injector\Injector:
|
|||||||
namespace: 'mycache'
|
namespace: 'mycache'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
##### Configuration Changes
|
##### Configuration Changes
|
||||||
|
|
||||||
Caches are now configured through dependency injection services instead of PHP.
|
Caches are now configured through dependency injection services instead of PHP.
|
||||||
See our ["Caching" docs](/developer-guides/performance/caching) for more details.
|
See our ["Caching" docs](/developer-guides/performance/caching) for more details.
|
||||||
|
|
||||||
Before (`mysite/_config.php`):
|
Before (mysite/_config.php):
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cache::add_backend(
|
Cache::add_backend(
|
||||||
@ -1317,9 +1497,9 @@ Cache::add_backend(
|
|||||||
Cache::pick_backend('primary_memcached', 'any', 10);
|
Cache::pick_backend('primary_memcached', 'any', 10);
|
||||||
```
|
```
|
||||||
|
|
||||||
After (`mysite/_config/config.yml`):
|
After (mysite/_config/config.yml):
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
---
|
---
|
||||||
After:
|
After:
|
||||||
- '#corecache'
|
- '#corecache'
|
||||||
@ -1335,6 +1515,158 @@ SilverStripe\Core\Injector\Injector:
|
|||||||
client: '%$MemcachedClient
|
client: '%$MemcachedClient
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name="usercode-style-upgrades"></a>User-code style upgrades
|
||||||
|
|
||||||
|
Although it is not mandatory to upgrade project code to follow SilverStripe and
|
||||||
|
PSR-2 standard it is highly recommended to ensure that code is consistent. The below sections
|
||||||
|
will assist you with bringing yourself up to speed.
|
||||||
|
|
||||||
|
Please note that before upgrading user code style it is necessary to run the standard upgrade path
|
||||||
|
to fix references and usages of framework API.
|
||||||
|
|
||||||
|
#### Upgrading user-code to use namespaces
|
||||||
|
|
||||||
|
Upgrading code to use namespaces is quite a complex process, and as such we have provided
|
||||||
|
several development tools and processes to help make the upgrade user friendly and as
|
||||||
|
automated as possible.
|
||||||
|
|
||||||
|
##### Using the upgrader tool to automatically apply namespaces
|
||||||
|
|
||||||
|
The [upgrader tool](https://github.com/silverstripe/silverstripe-upgrader/) provides a feature
|
||||||
|
to not only automatically namespace code, but will provide automatic upgrade of other code
|
||||||
|
references to those classes.
|
||||||
|
|
||||||
|
Use the below to setup upgrader, and apply a namespace to a given code folder.
|
||||||
|
|
||||||
|
```
|
||||||
|
composer global require silverstripe/upgrader
|
||||||
|
cd ~/Project/Root
|
||||||
|
~/.composer/vendor/bin/upgrade-code add-namespace "WebDesignGroup\ShopSite" ./mysite/code --recursive --write
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to do a dry-run, omit the `--write` option to see a preview of a diff of
|
||||||
|
all changed project files.
|
||||||
|
|
||||||
|
This task will do the following:
|
||||||
|
|
||||||
|
- Add the given namespace to all files in the code class, and subdirectories.
|
||||||
|
- Sub-namespaces will be applied based on directory structure
|
||||||
|
- All references to classes in any namespaced files will be safely retained with additional `use` directives
|
||||||
|
added as necessary.
|
||||||
|
- Register all namespaced classese in a mysite/.upgrade.yml file for migration of other code
|
||||||
|
|
||||||
|
This task will not do the following, and must be done manually:
|
||||||
|
|
||||||
|
- Adding `table_name` to any namespaced classes
|
||||||
|
- Upgrade other references to namespaced classes outside of this folder
|
||||||
|
- Migrate any database table records
|
||||||
|
|
||||||
|
Please see the following steps for more information.
|
||||||
|
|
||||||
|
##### Using the upgrader tool to update references to namespaced user classes
|
||||||
|
|
||||||
|
Once a project has been namespaced all newly renamed classes will have a mapping included in the `mysite/.upgrade.yml`
|
||||||
|
file. If you have any user-code that references these, you may need to run the upgrader again (as you did did
|
||||||
|
to upgrade your project to namespaced framework classe).
|
||||||
|
|
||||||
|
```
|
||||||
|
composer global require silverstripe/upgrader
|
||||||
|
cd ~/Project/Root
|
||||||
|
~/.composer/vendor/bin/upgrade-code upgrade ./othercode --write
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Updating custom dataobjects to use existing table names
|
||||||
|
|
||||||
|
Once you have namespaced your user code it will be necessary to customise the `table_name` config
|
||||||
|
for your dataobjects, in order to ensure the correct table is used after upgrade. It is recommended
|
||||||
|
to point this to the base name of the class, excluding namespace, as in 3.x.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
namespace WebDesignGroup\ShopSite;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use Page;
|
||||||
|
class GalleryPage extends Page
|
||||||
|
{
|
||||||
|
+ private static $table_name = 'GalleryPage';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Class name remapping
|
||||||
|
|
||||||
|
If you've namespaced one of your custom page types, you may notice a message in the CMS
|
||||||
|
telling you it's obsolete. This is likely because the `ClassName`
|
||||||
|
field in the `SiteTree` table still contains the singular model name, e.g. `GalleryPage`
|
||||||
|
and that when you change it to `WebDesignGroup\ShopSite\GalleryPage` then everything
|
||||||
|
works again.
|
||||||
|
|
||||||
|
The `dev/build` task is configured to look for a legacy class name mapping
|
||||||
|
configuration setting and will update this for you automatically. You can use
|
||||||
|
this to add DB upgrading rules for your own classes.
|
||||||
|
|
||||||
|
For example, you could upgrade references to the newly namespaced Banner class by adding
|
||||||
|
this to your `mysite/_config/upgrade.yml` file:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
SilverStripe\ORM\DatabaseAdmin:
|
||||||
|
classname_value_remapping:
|
||||||
|
GalleryPage: WebDesignGroup\ShopSite\GalleryPage
|
||||||
|
```
|
||||||
|
|
||||||
|
The next time you run a dev/build the class name for all `GalleryPage` pages will
|
||||||
|
be automatically updated to the new `WebDesignGroup\ShopSite\GalleryPage`
|
||||||
|
|
||||||
|
#### Using php code checker to automatically update to PSR-2
|
||||||
|
|
||||||
|
You can use the [php codesniffer](https://github.com/squizlabs/PHP_CodeSniffer) tool
|
||||||
|
to not only detect and lint PSR-2 coding errors, but also do some minimal automatic
|
||||||
|
code style migration.
|
||||||
|
|
||||||
|
- Install the necessary library:
|
||||||
|
`composer require squizlabs/php_codesniffer`
|
||||||
|
- Copy silverstripe standards config file from framework/phpcs.xml to your project root:
|
||||||
|
`cp ./framework/phpcs.xml ./phpcs.xml`
|
||||||
|
- Run the automatic upgrade tool on your code folder
|
||||||
|
`vendor/bin/phpcbf ./mysite/code`
|
||||||
|
- Run the automatic linting tool to detect and manually fix other errors:
|
||||||
|
`vendor/bin/phpcs ./mysite/code`
|
||||||
|
|
||||||
|
Repeat the final step and manually repair suggested changes, as necessary,
|
||||||
|
until you no longer have any linting issues.
|
||||||
|
|
||||||
|
#### Upgrade user-code to use PSR-4 autoloading
|
||||||
|
|
||||||
|
While not critical to an upgrade, SilverStripe 4.0 has adopted the [PS-4 autoloading](http://www.php-fig.org/psr/psr-4/)
|
||||||
|
standard for the core modules, so it's probably a good idea to be consistent.
|
||||||
|
|
||||||
|
You can implement this in your composer configuration like so:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"WebDesignGroup\\ShopSite\\": "mysite/src/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you just need to ensure that each class site in the correct folder location
|
||||||
|
(including case sensitivity) to match its namespace. For example,
|
||||||
|
`WebDesignGroup\ShopSite\Model\GalleryItem.php` should live at `mysite/src/Model/GalleryItem.php`.
|
||||||
|
|
||||||
|
Note that you don’t have to use `src/` as the root folder name. You can continue
|
||||||
|
to use `code/` if you want to. SilverStripe has adopted the PSR-4 approach and
|
||||||
|
have also started to use `src/` as a default folder location instead of
|
||||||
|
`code/`. If you’re going to change, it's probably a good time to do it while you're
|
||||||
|
upgrading.
|
||||||
|
|
||||||
|
For examples, take a look at the file/folder structure and to the
|
||||||
|
`composer.json` configuration in either the `framework` or `cms` modules.
|
||||||
|
|
||||||
|
Please note that there are changes to template structure which in some cases
|
||||||
|
require templates to be in a folder location that matches the namespace of the class
|
||||||
|
that it belongs to, e.g. `themes/mytheme/templates/MyVendor/Foobar/Model/MyModel.ss`.
|
||||||
|
|
||||||
## <a name="api-changes"></a>API Changes
|
## <a name="api-changes"></a>API Changes
|
||||||
|
|
||||||
### <a name="overview-general"></a>General and Core API
|
### <a name="overview-general"></a>General and Core API
|
||||||
@ -2057,9 +2389,7 @@ New `TimeField` methods replace `getConfig()` / `setConfig()`
|
|||||||
* `i18n::get_common_locales()` removed.
|
* `i18n::get_common_locales()` removed.
|
||||||
* `i18n.common_locales` config removed
|
* `i18n.common_locales` config removed
|
||||||
|
|
||||||
### <a name="overview-mailer"></a>Email and Mailer
|
#### <a name="overview-mailer"></a>Email Additions / Changes
|
||||||
|
|
||||||
#### <a name="overview-mailer-api"></a>Email Additions / Changes
|
|
||||||
|
|
||||||
* `Mailer` converted to an interface
|
* `Mailer` converted to an interface
|
||||||
* `SwfitMailer` added as new default mailer
|
* `SwfitMailer` added as new default mailer
|
||||||
@ -2080,7 +2410,7 @@ New `TimeField` methods replace `getConfig()` / `setConfig()`
|
|||||||
* `SapphireTest::$extraDataObjects` renamed to `SapphireTest::$extra_dataobjects` and made static
|
* `SapphireTest::$extraDataObjects` renamed to `SapphireTest::$extra_dataobjects` and made static
|
||||||
* `SapphireTest::$extraControllers` renamed to `SapphireTest::$extra_controllers` and made static
|
* `SapphireTest::$extraControllers` renamed to `SapphireTest::$extra_controllers` and made static
|
||||||
|
|
||||||
### <a name="overview-testing"></a>Security
|
### <a name="overview-security"></a>Security
|
||||||
|
|
||||||
* `LoginForm` now has an abstract method `getAuthenticatorName()`. If you have made subclasses of this,
|
* `LoginForm` now has an abstract method `getAuthenticatorName()`. If you have made subclasses of this,
|
||||||
you will need to define this method and return a short name describing the login method.
|
you will need to define this method and return a short name describing the login method.
|
||||||
|
Loading…
Reference in New Issue
Block a user