From dcb2424b05564727cba8486d3bfa2f1b14dc3caf Mon Sep 17 00:00:00 2001 From: Aaron Carlino Date: Thu, 13 Jul 2017 17:00:12 +1200 Subject: [PATCH] Docs for ownership API --- docs/en/04_Changelogs/4.0.0.md | 64 ++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/docs/en/04_Changelogs/4.0.0.md b/docs/en/04_Changelogs/4.0.0.md index e0de98e65..3156b5029 100644 --- a/docs/en/04_Changelogs/4.0.0.md +++ b/docs/en/04_Changelogs/4.0.0.md @@ -152,15 +152,15 @@ public function countDuplicates($model, $fieldToCheck) ##### Class name remapping -If you've namespaced one of your custom page types then loaded up the CMS and see -a message telling you it's obsolete. This is likely because the `ClassName` +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. `BlogPost` and that when you change it to `SilverStripe\Blog\Model\BlogPost` then everything works again. Luckily the `dev/build` task is configured to look for a legacy class name mapping configuration setting and will update this for you automatically. For an example -take a look at `_config/legacy.yml` in the CMS module. For the Blog module we used +take a look at `_config/legacy.yml` in the CMS module. The Blog module, for instance, uses this: ```yaml @@ -221,9 +221,9 @@ A better option is to replace it with `DataObject::getSchema()->tableName(BlogPo 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. Best to change it to `PageController` during your upgrade process. +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. -By default, a controller for a page type *must* reside in the same namespace as its page. To break this convention, override `SiteTree::getControllerName()`. +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 @@ -244,8 +244,8 @@ the `SilverStripe\Forms` namespace. #### Upgrade your member statics -If you've got some class configuration statics defined and they aren't private, -you may find that they don't register any more. For example, this code, taken from +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 = [ @@ -272,7 +272,7 @@ private static $allowed_actions = [ 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 into your composer configuration like so: +You can implement this in your composer configuration like so: ```js ... @@ -293,14 +293,15 @@ 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 compared to the +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 class's namespace +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`. #### Get on board with PSR-# logging, too + 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. @@ -322,7 +323,7 @@ in this case! ##### Unit tests and PSR-3 loggers -If you've got some code that you've tested originally using `SS_Log`, and now moved +If you have some code that you've tested originally using `SS_Log`, and now moved to using a Monolog Logger then you may notice occasions where your unit tests pass but output a bunch of warnings, debug information, etc. to `stderr`. This is because Monolog will use `stderr` as the default Handler unless you specify one. @@ -1317,10 +1318,45 @@ These methods are deprecated: #### Implementation of ownership API 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 -[versioned documentation](/developer_guides/model/versioning) for more information. +developers to declare dependencies between objects. This is done to ensure that the published state +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 or + unpublished 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 +* The [versioned](/developer_guides/model/versioning) documentation #### ChangeSet batch publishing