diff --git a/.scrutinizer.yml b/.scrutinizer.yml index be463575b..a6f4a0634 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,7 +1,17 @@ + inherit: true + +build: + environment: + variables: + # Must match actual branch, not alias. E.g. 4.x-dev rather than 4.1.x-dev for 4 branch, but 4.0.x-dev for 4.0 branch + COMPOSER_ROOT_VERSION: 4.x-dev + nodes: + analysis: + tests: + override: [php-scrutinizer-run] + filter: - excluded_paths: - - thirdparty/* - - parsers/* - - docs/* - - images/* + paths: + - src/* + - tests/* diff --git a/.travis.yml b/.travis.yml index 9b0ca5a5f..87e6b7007 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,11 @@ matrix: - DB=MYSQL - PDO=1 - PHPUNIT_TEST=framework + - php: nightly + env: + - DB=MYSQL + - PDO=1 + - PHPUNIT_TEST=framework - php: 7.0 env: - DB=MYSQL @@ -54,6 +59,12 @@ matrix: env: - DB=MYSQL - BEHAT_TEST=cms + allow_failures: + - php: nightly + env: + - DB=MYSQL + - PDO=1 + - PHPUNIT_TEST=framework before_script: # Init PHP diff --git a/docs/en/00_Getting_Started/01_Installation/index.md b/docs/en/00_Getting_Started/01_Installation/index.md index b24991bba..87d4e6c82 100644 --- a/docs/en/00_Getting_Started/01_Installation/index.md +++ b/docs/en/00_Getting_Started/01_Installation/index.md @@ -22,3 +22,6 @@ SilverStripe ships with default rewriting rules specific to your web server. Apa routing requests to the framework, they also prevent access to sensitive files in the webroot, for example YAML configuration files. Please refer to the [secure coding](/developer_guides/security/secure_coding/#filesystem) documentation for details. + +## Related Lessons +* [Up and running: Setting up a local SilverStripe dev environment](https://www.silverstripe.org/learn/lessons/v4/up-and-running-setting-up-a-local-silverstripe-dev-environment-1) \ No newline at end of file diff --git a/docs/en/00_Getting_Started/04_Directory_Structure.md b/docs/en/00_Getting_Started/04_Directory_Structure.md index 5a827d2b1..c9f7ffd41 100644 --- a/docs/en/00_Getting_Started/04_Directory_Structure.md +++ b/docs/en/00_Getting_Started/04_Directory_Structure.md @@ -100,4 +100,4 @@ by using a `flush=1` query parameter. See the ["Manifests" documentation](/devel ## Best Practices ### Making /assets readonly -See [Secure coding](/developer_guides/security/secure_coding#filesystem) +See [Secure coding](/developer_guides/security/secure_coding#filesystem) \ No newline at end of file diff --git a/docs/en/00_Getting_Started/index.md b/docs/en/00_Getting_Started/index.md index 5cb43f81d..2d821e5d2 100644 --- a/docs/en/00_Getting_Started/index.md +++ b/docs/en/00_Getting_Started/index.md @@ -64,6 +64,15 @@ ready for download or installation on a cloud platform. If you run into trouble, see [common-problems](installation/common_problems) or post to the [SilverStripe forums](http://silverstripe.org/community/forums/). -## Related + +## Related Lessons +* [Up and running](https://www.silverstripe.org/learn/lessons/v4/up-and-running-setting-up-a-local-silverstripe-dev-environment-1) +* [Creating your first theme](https://www.silverstripe.org/learn/lessons/v4/creating-your-first-theme-1) +* [Migrating static templates into your theme](https://www.silverstripe.org/learn/lessons/v4/migrating-static-templates-into-your-theme-1) +* [Working with multiple templates](https://www.silverstripe.org/learn/lessons/v4/working-with-multiple-templates-1) + +## Related Documentation * [Module installation](/developer_guides/extending/modules) + + diff --git a/docs/en/01_Tutorials/03_Forms.md b/docs/en/01_Tutorials/03_Forms.md index 271aa6c8a..c150ca6d7 100644 --- a/docs/en/01_Tutorials/03_Forms.md +++ b/docs/en/01_Tutorials/03_Forms.md @@ -403,4 +403,4 @@ We use the normal tactic of putting the data into an unordered list and using CS In this tutorial we have explored custom php forms, and displayed result sets through Grouped Lists. We have briefly covered the different approaches to creating and using forms. Whether you decide to use the [userforms module](http://addons.silverstripe.org/add-ons/silverstripe/userforms) or create a form in PHP depends on the situation and flexibility required. -[Next Tutorial >>](/tutorials/site_search) +[Next Tutorial >>](/tutorials/site_search) \ No newline at end of file diff --git a/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md b/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md index 23e0b44d4..064241149 100644 --- a/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md +++ b/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md @@ -744,6 +744,11 @@ record #2 in Page refers to the same object as record #2 in [SiteTree](api:Silve To retrieve a news article, SilverStripe joins the [SiteTree](api:SilverStripe\CMS\Model\SiteTree), [Page](api:SilverStripe\CMS\Model\SiteTree\Page) and NewsPage tables by their ID fields. +## Related Lessons +* [Introduction to the ORM](https://www.silverstripe.org/learn/lessons/v4/introduction-to-the-orm-1) +* [Adding custom fields to a page](https://www.silverstripe.org/learn/lessons/v4/adding-custom-fields-to-a-page-1) + + ## Related Documentation * [Data Types and Casting](/developer_guides/model/data_types_and_casting) diff --git a/docs/en/02_Developer_Guides/00_Model/02_Relations.md b/docs/en/02_Developer_Guides/00_Model/02_Relations.md index 7397c127b..36661aa98 100644 --- a/docs/en/02_Developer_Guides/00_Model/02_Relations.md +++ b/docs/en/02_Developer_Guides/00_Model/02_Relations.md @@ -479,6 +479,10 @@ As these lists are not backed by the database, most of the filtering methods on this type. As such, an `UnsavedRelationList` should only be used for setting a relation before saving an object, not for displaying the objects contained in the relation. +## Related Lessons +* [Working with data relationships -- has_many](https://www.silverstripe.org/learn/lessons/v4/working-with-data-relationships-has-many-1) +* [Working with data relationships -- many_many](https://www.silverstripe.org/learn/lessons/v4/working-with-data-relationships-many-many-1) + ## Related Documentation * [Introduction to the Data Model and ORM](data_model_and_orm) diff --git a/docs/en/02_Developer_Guides/00_Model/03_Lists.md b/docs/en/02_Developer_Guides/00_Model/03_Lists.md index 71db5466c..a5d56cc8a 100644 --- a/docs/en/02_Developer_Guides/00_Model/03_Lists.md +++ b/docs/en/02_Developer_Guides/00_Model/03_Lists.md @@ -92,6 +92,9 @@ echo $list->Count(); // returns '2' ``` +## Related Lessons +* [Lists and pagination](https://www.silverstripe.org/learn/lessons/v4/lists-and-pagination-1) + ## API Documentation * [SS_List](api:SilverStripe\ORM\SS_List) diff --git a/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md b/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md index b35da9a15..5128306ea 100644 --- a/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md +++ b/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md @@ -89,3 +89,6 @@ class Player extends DataObject Note: There are no separate methods for *onBeforeCreate* and *onBeforeUpdate*. Please check `$this->isInDb()` to toggle these two modes, as shown in the example above. + +## Related Lessons +* [Working with data relationships - $has_many](https://www.silverstripe.org/learn/lessons/v4/working-with-data-relationships-has-many-1) diff --git a/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md b/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md index 0599e9709..2fd1131c9 100644 --- a/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md +++ b/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md @@ -61,6 +61,10 @@ $players = Player::get()->filter([ ]); ``` +## Related Lessons +* [Introduction to ModelAdmin](https://www.silverstripe.org/learn/lessons/v4/introduction-to-modeladmin-1) +* [Building a search form](https://www.silverstripe.org/learn/lessons/v4/building-a-search-form-1) + ## API Documentation * [SearchFilter](api:SilverStripe\ORM\Filters\SearchFilter) diff --git a/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md b/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md index 887b283dc..dc85ec060 100644 --- a/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md +++ b/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md @@ -291,7 +291,11 @@ $players = Player::get(); $map = $players->map('Name', 'NameWithBirthyear'); ``` -## Related +## Related Lessons +* [Building custom SQL](https://www.silverstripe.org/learn/lessons/v4/beyond-the-orm-building-custom-sql-1) + + +## Related Documentation * [Introduction to the Data Model and ORM](data_model_and_orm) diff --git a/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md b/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md index e7cd93381..a360b742c 100644 --- a/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md +++ b/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md @@ -551,7 +551,10 @@ for adding notes for other developers but for things you don't want published in $EditForm <%-- Some hidden comment about the form --%> ``` -## Related +## Related Lessons +* [Creating your first theme](https://www.silverstripe.org/learn/lessons/v4/creating-your-first-theme-1) + +## Related Documentation [CHILDREN] @@ -563,3 +566,5 @@ $EditForm <%-- Some hidden comment about the form --%> * [SSViewer](api:SilverStripe\View\SSViewer) * [ThemeManifest](api:SilverStripe\View\ThemeManifest) + + diff --git a/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md b/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md index 076336c20..f1260eaf6 100644 --- a/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md +++ b/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md @@ -365,7 +365,10 @@ Placing it just below `$Content` is a good default. You can add your own forms by implementing new form instances (see the [Forms tutorial](/tutorials/forms)). -## Related +## Related Lessons +* [Adding dynamic content](https://www.silverstripe.org/learn/lessons/v4/adding-dynamic-content-1) + +## Related Documentation * [Casting and Formating Variables](casting) * [Template Inheritance](template_inheritance) diff --git a/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md b/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md index f7c8687ec..2b2ac35d3 100644 --- a/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md +++ b/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md @@ -392,6 +392,10 @@ $file = ModuleResourceLoader::singleton() ->resolveURL('silverstripe/admin:client/dist/images/spinner.gif'); ``` +## Related Lessons +* [Creating your first theme](https://www.silverstripe.org/learn/lessons/v4/creating-your-first-theme-1) +* [AJAX behaviour and ViewableData](https://www.silverstripe.org/learn/lessons/v4/ajax-behaviour-and-viewabledata-1) + ## API Documentation * [Requirements](api:SilverStripe\View\Requirements) diff --git a/docs/en/02_Developer_Guides/01_Templates/04_Rendering_Templates.md b/docs/en/02_Developer_Guides/01_Templates/04_Rendering_Templates.md index 02e4631ad..b907aa573 100644 --- a/docs/en/02_Developer_Guides/01_Templates/04_Rendering_Templates.md +++ b/docs/en/02_Developer_Guides/01_Templates/04_Rendering_Templates.md @@ -99,3 +99,9 @@ class PageController extends ContentController } ``` + +## Related Lessons +* [Controller actions/DataObjects as pages](https://www.silverstripe.org/learn/lessons/v4/controller-actions-dataobjects-as-pages-1) +* [AJAX behaviour and ViewableData](https://www.silverstripe.org/learn/lessons/v4/ajax-behaviour-and-viewabledata-1) +* [Dealing with arbitrary template data](https://www.silverstripe.org/learn/lessons/v4/dealing-with-arbitrary-template-data-1) +* [Creating filtered views](https://www.silverstripe.org/learn/lessons/v4/creating-filtered-views-1) \ No newline at end of file diff --git a/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md b/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md index ccc3bf069..986717c2c 100644 --- a/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md +++ b/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md @@ -180,3 +180,6 @@ Module names are derived their local `composer.json` files using the following p * The value of the `name` attribute in `composer.json` * The value of `extras.installer_name` in `composer.json` * The basename of the directory that contains the module + +## Related Lessons +* [Working with multiple templates](https://www.silverstripe.org/learn/lessons/v4/working-with-multiple-templates-1) diff --git a/docs/en/02_Developer_Guides/01_Templates/06_Themes.md b/docs/en/02_Developer_Guides/01_Templates/06_Themes.md index 4b2c1ae76..e2850e74e 100644 --- a/docs/en/02_Developer_Guides/01_Templates/06_Themes.md +++ b/docs/en/02_Developer_Guides/01_Templates/06_Themes.md @@ -103,3 +103,7 @@ The final step is to [submit your theme to Packagist](https://packagist.org/abou * [Themes Listing on silverstripe.org](http://addons.silverstripe.org/add-ons?search=&type=theme) * [Themes Forum on silverstripe.org](https://www.silverstripe.org/community/forums/themes-2/) * [Themes repositories on github.com](http://github.com/silverstripe-themes) + +## Related Lessons +* [Creating your first theme](https://www.silverstripe.org/learn/lessons/v4/creating-your-first-theme-1) +* [Migrating static templates into your theme](https://www.silverstripe.org/learn/lessons/v4/migrating-static-templates-into-your-theme-1) \ No newline at end of file diff --git a/docs/en/02_Developer_Guides/01_Templates/09_Casting.md b/docs/en/02_Developer_Guides/01_Templates/09_Casting.md index 36cac3350..52179c24d 100644 --- a/docs/en/02_Developer_Guides/01_Templates/09_Casting.md +++ b/docs/en/02_Developer_Guides/01_Templates/09_Casting.md @@ -167,3 +167,7 @@ Text / HTMLText methods: version of emails. * `$LimitSentences()` Will limit to the first `` sentences in the content. If called on HTML content this will have all HTML stripped and converted to plain text. + +## Related Lessons +* [Dealing with arbitrary template data](https://www.silverstripe.org/learn/lessons/v4/dealing-with-arbitrary-template-data-1) + diff --git a/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md b/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md index 7dae00134..e10e50623 100644 --- a/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md +++ b/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md @@ -113,6 +113,8 @@ list. | `$Link` | Links to the current controller URL, setting this page as current via a GET parameter | | `$CurrentBool` | Returns true if you're currently on that page | +## Related Lessons +* [Lists and pagination](https://www.silverstripe.org/learn/lessons/v4/lists-and-pagination-1) ## API Documentation diff --git a/docs/en/02_Developer_Guides/01_Templates/index.md b/docs/en/02_Developer_Guides/01_Templates/index.md index f5449c003..d022b85b8 100644 --- a/docs/en/02_Developer_Guides/01_Templates/index.md +++ b/docs/en/02_Developer_Guides/01_Templates/index.md @@ -15,3 +15,6 @@ templates from your controllers. ## How to's [CHILDREN Folder=How_Tos] + +## Related Lessons +* [Migrating static templates into your theme](https://www.silverstripe.org/learn/lessons/v4/migrating-static-templates-into-your-theme-1) \ No newline at end of file diff --git a/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md b/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md index a0e01f942..398fc525d 100644 --- a/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md +++ b/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md @@ -174,6 +174,10 @@ public function Link($action = null) The [Controller::join_links()](api:SilverStripe\Control\Controller::join_links()) is optional, but makes `Link()` more flexible by allowing an `$action` argument, and concatenates the path segments with slashes. The action should map to a method on your controller. +## Related Lessons +* [Controller actions/DataObjects as pages](https://www.silverstripe.org/learn/lessons/v4/controller-actions-dataobjects-as-pages-1) +* [Creating filtered views](https://www.silverstripe.org/learn/lessons/v4/creating-filtered-views-1) + ## Related Documentation * [Execution Pipeline](../execution_pipeline) diff --git a/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md b/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md index c4dccb298..4cf305a59 100644 --- a/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md +++ b/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md @@ -213,6 +213,9 @@ Director: 'feed': 'FeedController' ``` +## Related Lessons +* [Creating filtered views](https://www.silverstripe.org/learn/lessons/v4/creating-filtered-views-1) +* [Controller actions / DataObjects as pages](https://www.silverstripe.org/learn/lessons/v4/controller-actions-dataobjects-as-pages-1) ## Links * [Controller](api:SilverStripe\Control\Controller) API documentation diff --git a/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md b/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md index d2cc94dfa..7dbd6f057 100644 --- a/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md +++ b/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md @@ -346,6 +346,9 @@ $validator = new SilverStripe\Forms\RequiredFields([ $form = new Form($this, 'MyForm', $fields, $actions, $validator); ``` +## Related Lessons +* [Intoduction to frontend forms](https://www.silverstripe.org/learn/lessons/v4/introduction-to-frontend-forms-1) + ## API Documentation * [Form](api:SilverStripe\Forms\Form) diff --git a/docs/en/02_Developer_Guides/03_Forms/01_Validation.md b/docs/en/02_Developer_Guides/03_Forms/01_Validation.md index b5d6aaa0a..e2d4b3964 100644 --- a/docs/en/02_Developer_Guides/03_Forms/01_Validation.md +++ b/docs/en/02_Developer_Guides/03_Forms/01_Validation.md @@ -307,6 +307,10 @@ class Page extends SiteTree ``` +## Related Lessons +* [Intoduction to frontend forms](https://www.silverstripe.org/learn/lessons/v4/introduction-to-frontend-forms-1) + + ## API Documentation * [RequiredFields](api:SilverStripe\Forms\RequiredFields) diff --git a/docs/en/02_Developer_Guides/04_Configuration/00_Configuration.md b/docs/en/02_Developer_Guides/04_Configuration/00_Configuration.md index bf72c60e8..e0ad2520b 100644 --- a/docs/en/02_Developer_Guides/04_Configuration/00_Configuration.md +++ b/docs/en/02_Developer_Guides/04_Configuration/00_Configuration.md @@ -351,3 +351,6 @@ That is, the fragment will be included if all Only rules match, except if all Ex ## API Documentation * [Config](api:SilverStripe\Core\Config\Config) + +## Related Lessons +* [DataExtensions and SiteConfig](https://www.silverstripe.org/learn/lessons/v4/data-extensions-and-siteconfig-1) diff --git a/docs/en/02_Developer_Guides/04_Configuration/01_SiteConfig.md b/docs/en/02_Developer_Guides/04_Configuration/01_SiteConfig.md index d805d3234..553214f2f 100644 --- a/docs/en/02_Developer_Guides/04_Configuration/01_SiteConfig.md +++ b/docs/en/02_Developer_Guides/04_Configuration/01_SiteConfig.md @@ -81,3 +81,7 @@ provide the users a place to configure settings then the `SiteConfig` panel is t ## API Documentation * [SiteConfig](api:SilverStripe\SiteConfig\SiteConfig) + + +## Related Lessons +* [DataExtensions and SiteConfig](https://www.silverstripe.org/learn/lessons/v4/data-extensions-and-siteconfig-1) diff --git a/docs/en/02_Developer_Guides/04_Configuration/03_Environment_Variables.md b/docs/en/02_Developer_Guides/04_Configuration/03_Environment_Variables.md index 3bf84b7cd..924074ad3 100644 --- a/docs/en/02_Developer_Guides/04_Configuration/03_Environment_Variables.md +++ b/docs/en/02_Developer_Guides/04_Configuration/03_Environment_Variables.md @@ -11,3 +11,7 @@ For more information see our docs on [Environment Management](../../getting_star Data which isn't sensitive that can be in version control but is mostly static such as constants is best suited to be included through the [Configuration API](configuration) based on the standard environment types (dev / test / live). + +## Related Lessons +* [Up and running](https://www.silverstripe.org/learn/lessons/v4/up-and-running-setting-up-a-local-silverstripe-dev-environment-1) +* [Advanced environment configuration](https://www.silverstripe.org/learn/lessons/v4/advanced-environment-configuration-1) \ No newline at end of file diff --git a/docs/en/02_Developer_Guides/05_Extending/01_Extensions.md b/docs/en/02_Developer_Guides/05_Extending/01_Extensions.md index 6fd32962b..caa3d9306 100644 --- a/docs/en/02_Developer_Guides/05_Extending/01_Extensions.md +++ b/docs/en/02_Developer_Guides/05_Extending/01_Extensions.md @@ -311,6 +311,10 @@ public function getCMSFields() } ``` +## Related Lessons +* [DataExtensions and SiteConfig](https://www.silverstripe.org/learn/lessons/v4/data-extensions-and-siteconfig-1) + + ## Related Documentaion * [Injector](injector/) diff --git a/docs/en/02_Developer_Guides/07_Debugging/00_Environment_Types.md b/docs/en/02_Developer_Guides/07_Debugging/00_Environment_Types.md index fb4e01efd..f47218dcd 100644 --- a/docs/en/02_Developer_Guides/07_Debugging/00_Environment_Types.md +++ b/docs/en/02_Developer_Guides/07_Debugging/00_Environment_Types.md @@ -81,4 +81,5 @@ if (Director::isLive()) { } ``` - +## Related Lessons +* [Advanced environment configuration](https://www.silverstripe.org/learn/lessons/v4/advanced-environment-configuration-1) diff --git a/docs/en/02_Developer_Guides/07_Debugging/01_Error_Handling.md b/docs/en/02_Developer_Guides/07_Debugging/01_Error_Handling.md index 943b5b19f..f78a143f1 100644 --- a/docs/en/02_Developer_Guides/07_Debugging/01_Error_Handling.md +++ b/docs/en/02_Developer_Guides/07_Debugging/01_Error_Handling.md @@ -265,3 +265,6 @@ In SilverStripe 3, logging was based on the Zend Log module. Customisations were This function no longer works, and any Zend Log writers will need to be replaced with Monolog handlers. Fortunately, a range of handlers are available, both in the core package and in add-ons. See the [Monolog documentation](https://github.com/Seldaek/monolog/blob/master/doc/01-usage.md) for more information. + +## Related Lessons +* [Advanced environment configuration](https://www.silverstripe.org/learn/lessons/v4/advanced-environment-configuration-1) diff --git a/docs/en/02_Developer_Guides/14_Files/01_File_Management.md b/docs/en/02_Developer_Guides/14_Files/01_File_Management.md index f9d209a58..957459099 100644 --- a/docs/en/02_Developer_Guides/14_Files/01_File_Management.md +++ b/docs/en/02_Developer_Guides/14_Files/01_File_Management.md @@ -202,3 +202,6 @@ storage. SilverStripe\Assets\File: keep_archived_assets: true ``` + +## Related Lessons +* [Working with files and images](https://www.silverstripe.org/learn/lessons/v4/working-with-files-and-images-1) diff --git a/docs/en/02_Developer_Guides/14_Files/02_Images.md b/docs/en/02_Developer_Guides/14_Files/02_Images.md index 7696a953b..a58c87998 100644 --- a/docs/en/02_Developer_Guides/14_Files/02_Images.md +++ b/docs/en/02_Developer_Guides/14_Files/02_Images.md @@ -214,3 +214,7 @@ SilverStripe\Core\Injector\Injector: * [Image](api:SilverStripe\Assets\Image) * [DBFile](api:SilverStripe\Assets\Storage\DBFile) * [ImageManipulation](api:SilverStripe\Assets\ImageManipulation) + +## Related Lessons +* [Working with files and images](https://www.silverstripe.org/learn/lessons/v4/working-with-files-and-images-1) + diff --git a/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/01_ModelAdmin.md b/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/01_ModelAdmin.md index e5e794903..f70f884af 100644 --- a/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/01_ModelAdmin.md +++ b/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/01_ModelAdmin.md @@ -360,6 +360,9 @@ class MyAdmin extends ModelAdmin } ``` +## Related Lessons +* [Intoduction to ModelAdmin](https://www.silverstripe.org/learn/lessons/v4/introduction-to-modeladmin-1) + ## Related Documentation * [GridField](../forms/field_types/gridfield) diff --git a/src/Core/CoreKernel.php b/src/Core/CoreKernel.php index 951f78ef6..3f5e4cee1 100644 --- a/src/Core/CoreKernel.php +++ b/src/Core/CoreKernel.php @@ -359,7 +359,7 @@ class CoreKernel implements Kernel } // Allow database adapters to handle their own configuration - DatabaseAdapterRegistry::autoconfigure(); + DatabaseAdapterRegistry::autoconfigure($databaseConfig); return $databaseConfig; } diff --git a/src/Dev/Install/DatabaseAdapterRegistry.php b/src/Dev/Install/DatabaseAdapterRegistry.php index 4af6c7505..ae5cbf101 100644 --- a/src/Dev/Install/DatabaseAdapterRegistry.php +++ b/src/Dev/Install/DatabaseAdapterRegistry.php @@ -3,6 +3,7 @@ namespace SilverStripe\Dev\Install; use InvalidArgumentException; +use SilverStripe\Dev\Deprecation; /** * This class keeps track of the available database adapters @@ -111,7 +112,7 @@ class DatabaseAdapterRegistry /** * Detects all _register_database.php files and invokes them. - * Searches through vendor/ folder only, + * Searches through vendor/*\/* folders only, * does not support "legacy" folder location in webroot */ public static function autodiscover() @@ -131,10 +132,19 @@ class DatabaseAdapterRegistry * Called by ConfigureFromEnv.php. * Searches through vendor/ folder only, * does not support "legacy" folder location in webroot + * + * @param array $config Config to update. If not provided fall back to global $databaseConfig. + * In 5.0.0 this will be mandatory and the global will be removed. */ - public static function autoconfigure() + public static function autoconfigure(&$config = null) { - // Search through all composer packages in vendor + if (!isset($config)) { + Deprecation::notice('5.0', 'Configuration via global is deprecated'); + global $databaseConfig; + } else { + $databaseConfig = $config; + } + // Search through all composer packages in vendor, updating $databaseConfig foreach (glob(BASE_PATH . '/vendor/*', GLOB_ONLYDIR) as $vendor) { foreach (glob($vendor . '/*', GLOB_ONLYDIR) as $directory) { if (file_exists($directory . '/_configure_database.php')) { @@ -142,6 +152,8 @@ class DatabaseAdapterRegistry } } } + // Update modified variable + $config = $databaseConfig; } /** diff --git a/src/Dev/Install/InstallRequirements.php b/src/Dev/Install/InstallRequirements.php index 736603b95..6affcfd6f 100644 --- a/src/Dev/Install/InstallRequirements.php +++ b/src/Dev/Install/InstallRequirements.php @@ -227,8 +227,9 @@ class InstallRequirements /** * Check everything except the database */ - public function check() + public function check($originalIni) { + $this->originalIni = $originalIni; $this->errors = []; $isApache = $this->isApache(); $isIIS = $this->isIIS(); diff --git a/src/Dev/Install/install5.php b/src/Dev/Install/install5.php index a55be3f6e..d238e9259 100755 --- a/src/Dev/Install/install5.php +++ b/src/Dev/Install/install5.php @@ -66,7 +66,7 @@ $theme = $config->getTheme($_REQUEST); // Check requirements $req = new InstallRequirements(); -$req->check(); +$req->check($originalIni); if ($req->isIIS()) { $webserverConfigFile = 'web.config'; diff --git a/src/Forms/HTMLEditor/TinyMCEConfig.php b/src/Forms/HTMLEditor/TinyMCEConfig.php index feaabbb69..a2f90546c 100644 --- a/src/Forms/HTMLEditor/TinyMCEConfig.php +++ b/src/Forms/HTMLEditor/TinyMCEConfig.php @@ -74,49 +74,49 @@ class TinyMCEConfig extends HTMLEditorConfig 'fa_PK' => 'fa', 'fi_FI' => 'fi', 'fi_SE' => 'fi', - 'fr_BE' => 'fr', - 'fr_BF' => 'fr', - 'fr_BI' => 'fr', - 'fr_BJ' => 'fr', - 'fr_CA' => 'fr_ca', - 'fr_CF' => 'fr', - 'fr_CG' => 'fr', - 'fr_CH' => 'fr', - 'fr_CI' => 'fr', - 'fr_CM' => 'fr', - 'fr_DJ' => 'fr', - 'fr_DZ' => 'fr', - 'fr_FR' => 'fr', - 'fr_GA' => 'fr', - 'fr_GF' => 'fr', - 'fr_GN' => 'fr', - 'fr_GP' => 'fr', - 'fr_HT' => 'fr', - 'fr_KM' => 'fr', - 'fr_LU' => 'fr', - 'fr_MA' => 'fr', - 'fr_MC' => 'fr', - 'fr_MG' => 'fr', - 'fr_ML' => 'fr', - 'fr_MQ' => 'fr', - 'fr_MU' => 'fr', - 'fr_NC' => 'fr', - 'fr_NE' => 'fr', - 'fr_PF' => 'fr', - 'fr_PM' => 'fr', - 'fr_RE' => 'fr', - 'fr_RW' => 'fr', - 'fr_SC' => 'fr', - 'fr_SN' => 'fr', - 'fr_SY' => 'fr', - 'fr_TD' => 'fr', - 'fr_TG' => 'fr', - 'fr_TN' => 'fr', - 'fr_VU' => 'fr', - 'fr_WF' => 'fr', - 'fr_YT' => 'fr', - 'fr_GB' => 'fr', - 'fr_US' => 'fr', + 'fr_BE' => 'fr_FR', + 'fr_BF' => 'fr_FR', + 'fr_BI' => 'fr_FR', + 'fr_BJ' => 'fr_FR', + 'fr_CA' => 'fr_FR', + 'fr_CF' => 'fr_FR', + 'fr_CG' => 'fr_FR', + 'fr_CH' => 'fr_FR', + 'fr_CI' => 'fr_FR', + 'fr_CM' => 'fr_FR', + 'fr_DJ' => 'fr_FR', + 'fr_DZ' => 'fr_FR', + 'fr_FR' => 'fr_FR', + 'fr_GA' => 'fr_FR', + 'fr_GF' => 'fr_FR', + 'fr_GN' => 'fr_FR', + 'fr_GP' => 'fr_FR', + 'fr_HT' => 'fr_FR', + 'fr_KM' => 'fr_FR', + 'fr_LU' => 'fr_FR', + 'fr_MA' => 'fr_FR', + 'fr_MC' => 'fr_FR', + 'fr_MG' => 'fr_FR', + 'fr_ML' => 'fr_FR', + 'fr_MQ' => 'fr_FR', + 'fr_MU' => 'fr_FR', + 'fr_NC' => 'fr_FR', + 'fr_NE' => 'fr_FR', + 'fr_PF' => 'fr_FR', + 'fr_PM' => 'fr_FR', + 'fr_RE' => 'fr_FR', + 'fr_RW' => 'fr_FR', + 'fr_SC' => 'fr_FR', + 'fr_SN' => 'fr_FR', + 'fr_SY' => 'fr_FR', + 'fr_TD' => 'fr_FR', + 'fr_TG' => 'fr_FR', + 'fr_TN' => 'fr_FR', + 'fr_VU' => 'fr_FR', + 'fr_WF' => 'fr_FR', + 'fr_YT' => 'fr_FR', + 'fr_GB' => 'fr_FR', + 'fr_US' => 'fr_FR', 'he_IL' => 'he', 'hu_HU' => 'hu', 'hu_AT' => 'hu', diff --git a/src/ORM/Connect/DBSchemaManager.php b/src/ORM/Connect/DBSchemaManager.php index d8f4a2789..2eccafaa7 100644 --- a/src/ORM/Connect/DBSchemaManager.php +++ b/src/ORM/Connect/DBSchemaManager.php @@ -899,8 +899,7 @@ abstract class DBSchemaManager * * @param string $tableName The name of the table. * @param string $indexName The name of the index. - * @param string $indexSpec The specification of the index, see {@link SS_Database::requireIndex()} - * for more details. + * @param array $indexSpec The specification of the index, see Database::requireIndex() for more details. * @todo Find out where this is called from - Is it even used? Aren't indexes always dropped and re-added? */ abstract public function alterIndex($tableName, $indexName, $indexSpec); diff --git a/src/ORM/DataObjectSchema.php b/src/ORM/DataObjectSchema.php index 0944dd762..34890d759 100644 --- a/src/ORM/DataObjectSchema.php +++ b/src/ORM/DataObjectSchema.php @@ -6,6 +6,7 @@ use Exception; use SilverStripe\Core\Injector\Injectable; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Injector\Injector; +use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\FieldType\DBComposite; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; @@ -126,6 +127,7 @@ class DataObjectSchema } return null; } + /** * Returns the root class (the first to extend from DataObject) for the * passed class. @@ -301,11 +303,26 @@ class DataObjectSchema $table = Config::inst()->get($class, 'table_name', Config::UNINHERITED); // Generate default table name - if (!$table) { - $separator = DataObjectSchema::config()->uninherited('table_namespace_separator'); - $table = str_replace('\\', $separator, trim($class, '\\')); + if ($table) { + return $table; } + if (strpos($class, '\\') === false) { + return $class; + } + + if (!ClassInfo::classImplements($class, TestOnly::class)) { + trigger_error( + "It is recommended to define a table_name for your '$class'." . + ' Not defining a table_name may cause subsequent table names to be too long and may not be supported' . + ' by your current database engine, the generated naming scheme will also change when upgrading to' . + ' SilverStripe 5.0 and potentially break.', + E_USER_WARNING + ); + } + $separator = DataObjectSchema::config()->uninherited('table_namespace_separator'); + $table = str_replace('\\', $separator, trim($class, '\\')); + return $table; } diff --git a/src/Security/MemberAuthenticator/LogoutHandler.php b/src/Security/MemberAuthenticator/LogoutHandler.php index 1bbb253da..9b870a259 100644 --- a/src/Security/MemberAuthenticator/LogoutHandler.php +++ b/src/Security/MemberAuthenticator/LogoutHandler.php @@ -2,6 +2,7 @@ namespace SilverStripe\Security\MemberAuthenticator; +use SilverStripe\Control\Controller; use SilverStripe\Control\Director; use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\RequestHandler; @@ -109,6 +110,14 @@ class LogoutHandler extends RequestHandler return $this->redirect($backURL); } - return $this->redirect(Security::config()->get('login_url')); + $link = Security::config()->get('login_url'); + $referer = $this->getReturnReferer(); + if ($referer) { + $link = Controller::join_links($link, '?' . http_build_query([ + 'BackURL' => Director::makeRelative($referer) + ])); + } + + return $this->redirect($link); } } diff --git a/src/View/ViewableData.php b/src/View/ViewableData.php index aca9ffa77..79d3a239f 100644 --- a/src/View/ViewableData.php +++ b/src/View/ViewableData.php @@ -3,9 +3,12 @@ namespace SilverStripe\View; use Exception; +use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Extensible; use SilverStripe\Core\Injector\Injectable; +use SilverStripe\Core\Manifest\ModuleResourceLoader; +use SilverStripe\Dev\Deprecation; use SilverStripe\ORM\ArrayLib; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBHTMLText; @@ -586,6 +589,35 @@ class ViewableData implements IteratorAggregate return $this; } + /** + * Return the directory if the current active theme (relative to the site root). + * + * This method is useful for things such as accessing theme images from your template without hardcoding the theme + * page - e.g. . + * + * This method should only be used when a theme is currently active. However, it will fall over to the current + * project directory. + * + * @return string URL to the current theme + * @deprecated 4.0.0..5.0.0 Use $resourcePath or $resourceURL template helpers instead + */ + public function ThemeDir() + { + Deprecation::notice('5.0', 'Use $resourcePath or $resourceURL template helpers instead'); + $themes = SSViewer::get_themes(); + foreach ($themes as $theme) { + // Skip theme sets + if (strpos($theme, '$') === 0) { + continue; + } + // Map theme path to url + $themePath = ThemeResourceLoader::inst()->getPath($theme); + return ModuleResourceLoader::resourceURL($themePath); + } + + return project(); + } + /** * Get part of the current classes ancestry to be used as a CSS class. * diff --git a/src/i18n/Data/Intl/IntlLocales.php b/src/i18n/Data/Intl/IntlLocales.php index a23360b96..b098f8e50 100644 --- a/src/i18n/Data/Intl/IntlLocales.php +++ b/src/i18n/Data/Intl/IntlLocales.php @@ -793,7 +793,7 @@ class IntlLocales implements Locales, Resettable 'pl' => 'pl_PL', 'pon' => 'pon_FM', 'ps' => 'ps_AF', - 'pt' => 'pt_BR', + 'pt' => 'pt_PT', 'qu' => 'qu_PE', 'rm' => 'rm_CH', 'rn' => 'rn_BI', diff --git a/src/i18n/TextCollection/i18nTextCollector.php b/src/i18n/TextCollection/i18nTextCollector.php index e724e28a2..6d57f7ad9 100644 --- a/src/i18n/TextCollection/i18nTextCollector.php +++ b/src/i18n/TextCollection/i18nTextCollector.php @@ -558,6 +558,7 @@ class i18nTextCollector $inNamespace = false; $inClass = false; // after `class` but before `{` $inArrayClosedBy = false; // Set to the expected closing token, or false if not in array + $inSelf = false; // Tracks progress of collecting self::class $currentEntity = array(); $currentClass = []; // Class components $previousToken = null; @@ -584,10 +585,20 @@ class i18nTextCollector if ($id === T_CLASS) { // Skip if previous token was '::'. E.g. 'Object::class' if (is_array($previousToken) && $previousToken[0] === T_DOUBLE_COLON) { + if ($inSelf) { + // Handle self::class by allowing logic further down + // for __CLASS__ to handle an array of class parts + $id = T_CLASS_C; + $inSelf = false; + } else { + // Don't handle other ::class definitions. We can't determine which + // class was invoked, so parent::class is not possible at this point. + continue; + } + } else { + $inClass = true; continue; } - $inClass = true; - continue; } if ($inClass && $id === T_STRING) { $currentClass[] = $text; @@ -614,7 +625,7 @@ class i18nTextCollector // If inside this translation, some elements might be unreachable if (in_array($id, [T_VARIABLE, T_STATIC]) || - ($id === T_STRING && in_array($text, ['self', 'static', 'parent'])) + ($id === T_STRING && in_array($text, ['static', 'parent'])) ) { // Un-collectable strings such as _t(static::class.'.KEY'). // Should be provided by i18nEntityProvider instead @@ -625,6 +636,12 @@ class i18nTextCollector continue; } + // Start collecting self::class declarations + if ($id === T_STRING && $text === 'self') { + $inSelf = true; + continue; + } + // Check text if ($id == T_CONSTANT_ENCAPSED_STRING) { // Fixed quoting escapes, and remove leading/trailing quotes @@ -648,7 +665,7 @@ class i18nTextCollector throw new LogicException("Invalid string escape: " .$text); } } elseif ($id === T_CLASS_C) { - // Evaluate __CLASS__ . '.KEY' concatenation + // Evaluate __CLASS__ . '.KEY' and self::class concatenation $text = implode('\\', $currentClass); } else { continue; diff --git a/tests/php/Core/ClassInfoTest/ChildClass.php b/tests/php/Core/ClassInfoTest/ChildClass.php index 663b9c0e4..c9d69b992 100644 --- a/tests/php/Core/ClassInfoTest/ChildClass.php +++ b/tests/php/Core/ClassInfoTest/ChildClass.php @@ -2,7 +2,9 @@ namespace SilverStripe\Core\Tests\ClassInfoTest; -class ChildClass extends BaseClass +use SilverStripe\Dev\TestOnly; + +class ChildClass extends BaseClass implements TestOnly { } diff --git a/tests/php/View/ViewableDataTest.php b/tests/php/View/ViewableDataTest.php index 421b8b320..0f8582070 100644 --- a/tests/php/View/ViewableDataTest.php +++ b/tests/php/View/ViewableDataTest.php @@ -5,6 +5,7 @@ namespace SilverStripe\View\Tests; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\Dev\SapphireTest; use SilverStripe\View\ArrayData; +use SilverStripe\View\SSViewer; use SilverStripe\View\ViewableData; /** @@ -204,4 +205,19 @@ class ViewableDataTest extends SapphireTest $this->assertSame($failover, $container->getFailover(), 'getFailover() returned a different object'); $this->assertFalse($container->hasMethod('testMethod'), 'testMethod() incorrectly reported as existing'); } + + public function testThemeDir() + { + $themes = [ + "silverstripe/framework:/tests/php/View/ViewableDataTest/testtheme", + SSViewer::DEFAULT_THEME + ]; + SSViewer::set_themes($themes); + + $data = new ViewableData(); + $this->assertContains( + 'tests/php/View/ViewableDataTest/testtheme', + $data->ThemeDir() + ); + } } diff --git a/tests/php/View/ViewableDataTest/testtheme/empty.txt b/tests/php/View/ViewableDataTest/testtheme/empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/php/i18n/i18nTextCollectorTest.php b/tests/php/i18n/i18nTextCollectorTest.php index ddbf43519..f02abe58e 100644 --- a/tests/php/i18n/i18nTextCollectorTest.php +++ b/tests/php/i18n/i18nTextCollectorTest.php @@ -323,13 +323,21 @@ class MyClass extends Base implements SomeService { "Slash=\\\\, Quote=\\"" ); } + public function getMagicConstantStringFromSelf() + { + return _t( + self::class . '.SELF_CLASS', + 'Self Class' + ); + } } PHP; $this->assertEquals( [ 'SilverStripe\\Framework\\Core\\MyClass.NEWLINES' => "New Lines", 'SilverStripe\\Framework\\MyClass.ANOTHER_STRING' => 'Slash=\\, Quote=\'', - 'SilverStripe\\Framework\\MyClass.DOUBLE_STRING' => 'Slash=\\, Quote="' + 'SilverStripe\\Framework\\MyClass.DOUBLE_STRING' => 'Slash=\\, Quote="', + 'SilverStripe\\Framework\\Core\\MyClass.SELF_CLASS' => 'Self Class', ], $c->collectFromCode($php, null, $mymodule) ); @@ -434,7 +442,7 @@ PHP; $php = <<