silverstripe-framework/src/Dev/FixtureBlueprint.php

367 lines
13 KiB
PHP
Raw Normal View History

<?php
namespace SilverStripe\Dev;
API Refactor bootstrap, request handling See https://github.com/silverstripe/silverstripe-framework/pull/7037 and https://github.com/silverstripe/silverstripe-framework/issues/6681 Squashed commit of the following: commit 8f65e5653211240650eaa4fa65bb83b45aae6d58 Author: Ingo Schommer <me@chillu.com> Date: Thu Jun 22 22:25:50 2017 +1200 Fixed upgrade guide spelling commit 76f95944fa89b0b540704b8d744329f690f9698c Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 16:38:34 2017 +1200 BUG Fix non-test class manifest including sapphiretest / functionaltest commit 9379834cb4b2e5177a2600049feec05bf111c16b Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 15:50:47 2017 +1200 BUG Fix nesting bug in Kernel commit 188ce35d82599360c40f0f2de29579c56fb90761 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 15:14:51 2017 +1200 BUG fix db bootstrapping issues commit 7ed4660e7a63915e8e974deeaba9807bc4d38b0d Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 14:49:07 2017 +1200 BUG Fix issue in DetailedErrorFormatter commit 738f50c497166f81ccbe3f40fbcff895ce71f82f Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 11:49:19 2017 +1200 Upgrading notes on mysite/_config.php commit 6279d28e5e455916f902a2f963c014d8899f7fc7 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 11:43:28 2017 +1200 Update developer documentation commit 5c90d53a84ef0139c729396949a7857fae60436f Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 10:48:44 2017 +1200 Update installer to not use global databaseConfig commit f9b2ba4755371f08bd95f6908ac612fcbb7ca205 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 21:04:39 2017 +1200 Fix behat issues commit 5b59a912b60282b4dad4ef10ed3b97c5d0a761ac Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 17:07:11 2017 +1200 Move HTTPApplication to SilverStripe\Control namespace commit e2c4a18f637bdd3d276619554de60ee8b4d95ced Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 16:29:03 2017 +1200 More documentation Fix up remaining tests Refactor temp DB into TempDatabase class so it’s available outside of unit tests. commit 5d235e64f341d6251bfe9f4833f15cc8593c5034 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 12:13:15 2017 +1200 API HTTPRequestBuilder::createFromEnvironment() now cleans up live globals BUG Fix issue with SSViewer Fix Security / View tests commit d88d4ed4e48291cb65407f222f190064b1f1deeb Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 16:39:43 2017 +1200 API Refactor AppKernel into CoreKernel commit f7946aec3391139ae1b4029c353c327a36552b36 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 16:00:40 2017 +1200 Docs and minor cleanup commit 12bd31f9366327650b5c0c0f96cd0327d44faf0a Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 15:34:34 2017 +1200 API Remove OutputMiddleware API Move environment / global / ini management into Environment class API Move getTempFolder into TempFolder class API Implement HTTPRequestBuilder / CLIRequestBuilder BUG Restore SS_ALLOWED_HOSTS check in original location API CoreKernel now requires $basePath to be passed in API Refactor installer.php to use application to bootstrap API move memstring conversion globals to Convert BUG Fix error in CoreKernel nesting not un-nesting itself properly. commit bba979114624247cf463cf2a8c9e4be9a7c3a772 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 18:07:53 2017 +1200 API Create HTTPMiddleware and standardise middleware for request handling commit 2a10c2397bdc53001013f607b5d38087ce6c0730 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 17:42:42 2017 +1200 Fixed ORM tests commit d75a8d1d93398af4bd0432df9e4bc6295c15a3fe Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 17:15:07 2017 +1200 FIx i18n tests commit 06364af3c379c931889c4cc34dd920fee3db204a Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 16:59:34 2017 +1200 Fix controller namespace Move states to sub namespace commit 2a278e2953d2dbb19f78d91c919048e1fc935436 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 12:49:45 2017 +1200 Fix forms namespace commit b65c21241bee019730027071d815dbf7571197a4 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 15 18:56:48 2017 +1200 Update API usages commit d1d4375c95a264a6b63cbaefc2c1d12f808bfd82 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 15 18:41:44 2017 +1200 API Refactor $flush into HTPPApplication API Enforce health check in Controller::pushCurrent() API Better global backup / restore Updated Director::test() to use new API commit b220534f06732db4fa940d8724c2a85c0ba2495a Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 22:05:57 2017 +1200 Move app nesting to a test state helper commit 603704165c08d0c1c81fd5e6bb9506326eeee17b Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 21:46:04 2017 +1200 Restore kernel stack to fix multi-level nesting commit 2f6336a15bf79dc8c2edd44cec1931da2dd51c28 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 17:23:21 2017 +1200 API Implement kernel nesting commit fc7188da7d6ad6785354bab61f08700454c81d91 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:43:13 2017 +1200 Fix core tests commit a0ae7235148fffd71f2f02d1fe7fe45bf3aa39eb Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:23:52 2017 +1200 Fix manifest tests commit ca033952513633e182040d3d13e1caa9000ca184 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:00:00 2017 +1200 API Move extension management into test state commit c66d4339777663a8a04661fea32a0cf35b95d20f Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 14:10:59 2017 +1200 API Refactor SapphireTest state management into SapphireTestState API Remove Injector::unregisterAllObjects() API Remove FakeController commit f26ae75c6ecaafa0dec1093264e0187191e6764d Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 12 18:04:34 2017 +1200 Implement basic CLI application object commit 001d5596621404892de0a5413392379eff990641 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 12 17:39:38 2017 +1200 Remove references to SapphireTest::is_running_test() Upgrade various code commit de079c041dacd96bc4f4b66421fa2b2cc4c320f8 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 7 18:07:33 2017 +1200 API Implement APP object API Refactor of Session
2017-06-22 12:50:45 +02:00
use Exception;
use InvalidArgumentException;
use SilverStripe\Assets\File;
use SilverStripe\Core\Config\Config;
API Refactor bootstrap, request handling See https://github.com/silverstripe/silverstripe-framework/pull/7037 and https://github.com/silverstripe/silverstripe-framework/issues/6681 Squashed commit of the following: commit 8f65e5653211240650eaa4fa65bb83b45aae6d58 Author: Ingo Schommer <me@chillu.com> Date: Thu Jun 22 22:25:50 2017 +1200 Fixed upgrade guide spelling commit 76f95944fa89b0b540704b8d744329f690f9698c Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 16:38:34 2017 +1200 BUG Fix non-test class manifest including sapphiretest / functionaltest commit 9379834cb4b2e5177a2600049feec05bf111c16b Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 15:50:47 2017 +1200 BUG Fix nesting bug in Kernel commit 188ce35d82599360c40f0f2de29579c56fb90761 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 15:14:51 2017 +1200 BUG fix db bootstrapping issues commit 7ed4660e7a63915e8e974deeaba9807bc4d38b0d Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 14:49:07 2017 +1200 BUG Fix issue in DetailedErrorFormatter commit 738f50c497166f81ccbe3f40fbcff895ce71f82f Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 11:49:19 2017 +1200 Upgrading notes on mysite/_config.php commit 6279d28e5e455916f902a2f963c014d8899f7fc7 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 11:43:28 2017 +1200 Update developer documentation commit 5c90d53a84ef0139c729396949a7857fae60436f Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 10:48:44 2017 +1200 Update installer to not use global databaseConfig commit f9b2ba4755371f08bd95f6908ac612fcbb7ca205 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 21:04:39 2017 +1200 Fix behat issues commit 5b59a912b60282b4dad4ef10ed3b97c5d0a761ac Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 17:07:11 2017 +1200 Move HTTPApplication to SilverStripe\Control namespace commit e2c4a18f637bdd3d276619554de60ee8b4d95ced Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 16:29:03 2017 +1200 More documentation Fix up remaining tests Refactor temp DB into TempDatabase class so it’s available outside of unit tests. commit 5d235e64f341d6251bfe9f4833f15cc8593c5034 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 12:13:15 2017 +1200 API HTTPRequestBuilder::createFromEnvironment() now cleans up live globals BUG Fix issue with SSViewer Fix Security / View tests commit d88d4ed4e48291cb65407f222f190064b1f1deeb Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 16:39:43 2017 +1200 API Refactor AppKernel into CoreKernel commit f7946aec3391139ae1b4029c353c327a36552b36 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 16:00:40 2017 +1200 Docs and minor cleanup commit 12bd31f9366327650b5c0c0f96cd0327d44faf0a Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 15:34:34 2017 +1200 API Remove OutputMiddleware API Move environment / global / ini management into Environment class API Move getTempFolder into TempFolder class API Implement HTTPRequestBuilder / CLIRequestBuilder BUG Restore SS_ALLOWED_HOSTS check in original location API CoreKernel now requires $basePath to be passed in API Refactor installer.php to use application to bootstrap API move memstring conversion globals to Convert BUG Fix error in CoreKernel nesting not un-nesting itself properly. commit bba979114624247cf463cf2a8c9e4be9a7c3a772 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 18:07:53 2017 +1200 API Create HTTPMiddleware and standardise middleware for request handling commit 2a10c2397bdc53001013f607b5d38087ce6c0730 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 17:42:42 2017 +1200 Fixed ORM tests commit d75a8d1d93398af4bd0432df9e4bc6295c15a3fe Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 17:15:07 2017 +1200 FIx i18n tests commit 06364af3c379c931889c4cc34dd920fee3db204a Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 16:59:34 2017 +1200 Fix controller namespace Move states to sub namespace commit 2a278e2953d2dbb19f78d91c919048e1fc935436 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 12:49:45 2017 +1200 Fix forms namespace commit b65c21241bee019730027071d815dbf7571197a4 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 15 18:56:48 2017 +1200 Update API usages commit d1d4375c95a264a6b63cbaefc2c1d12f808bfd82 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 15 18:41:44 2017 +1200 API Refactor $flush into HTPPApplication API Enforce health check in Controller::pushCurrent() API Better global backup / restore Updated Director::test() to use new API commit b220534f06732db4fa940d8724c2a85c0ba2495a Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 22:05:57 2017 +1200 Move app nesting to a test state helper commit 603704165c08d0c1c81fd5e6bb9506326eeee17b Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 21:46:04 2017 +1200 Restore kernel stack to fix multi-level nesting commit 2f6336a15bf79dc8c2edd44cec1931da2dd51c28 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 17:23:21 2017 +1200 API Implement kernel nesting commit fc7188da7d6ad6785354bab61f08700454c81d91 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:43:13 2017 +1200 Fix core tests commit a0ae7235148fffd71f2f02d1fe7fe45bf3aa39eb Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:23:52 2017 +1200 Fix manifest tests commit ca033952513633e182040d3d13e1caa9000ca184 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:00:00 2017 +1200 API Move extension management into test state commit c66d4339777663a8a04661fea32a0cf35b95d20f Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 14:10:59 2017 +1200 API Refactor SapphireTest state management into SapphireTestState API Remove Injector::unregisterAllObjects() API Remove FakeController commit f26ae75c6ecaafa0dec1093264e0187191e6764d Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 12 18:04:34 2017 +1200 Implement basic CLI application object commit 001d5596621404892de0a5413392379eff990641 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 12 17:39:38 2017 +1200 Remove references to SapphireTest::is_running_test() Upgrade various code commit de079c041dacd96bc4f4b66421fa2b2cc4c320f8 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 7 18:07:33 2017 +1200 API Implement APP object API Refactor of Session
2017-06-22 12:50:45 +02:00
use SilverStripe\Core\Injector\Injector;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB;
/**
* A blueprint on how to create instances of a certain {@link DataObject} subclass.
*
* Relies on a {@link FixtureFactory} to manage database relationships between instances,
* and manage the mappings between fixture identifiers and their database IDs.
*/
2016-11-29 00:31:16 +01:00
class FixtureBlueprint
{
/**
* @var array Map of field names to values. Supersedes {@link DataObject::$defaults}.
*/
protected $defaults = [];
2016-11-29 00:31:16 +01:00
/**
* @var String Arbitrary name by which this fixture type can be referenced.
*/
protected $name;
/**
* @var String Subclass of {@link DataObject}
*/
protected $class;
/**
* @var array
*/
protected $callbacks = [
'beforeCreate' => [],
'afterCreate' => [],
];
2016-11-29 00:31:16 +01:00
/** @config */
private static $dependencies = [
2018-01-16 19:39:30 +01:00
'factory' => '%$' . FixtureFactory::class,
];
2016-11-29 00:31:16 +01:00
/**
2020-12-21 22:23:23 +01:00
* @param string $name
* @param string $class Defaults to $name
2016-11-29 00:31:16 +01:00
* @param array $defaults
*/
public function __construct($name, $class = null, $defaults = [])
2016-11-29 00:31:16 +01:00
{
if (!$class) {
$class = $name;
}
if (!is_subclass_of($class, DataObject::class)) {
throw new InvalidArgumentException(sprintf(
'Class "%s" is not a valid subclass of DataObject',
$class
));
}
$this->name = $name;
$this->class = $class;
$this->defaults = $defaults;
}
/**
* @param string $identifier Unique identifier for this fixture type
* @param array $data Map of property names to their values.
* @param array $fixtures Map of fixture names to an associative array of their in-memory
* identifiers mapped to their database IDs. Used to look up
* existing fixtures which might be referenced in the $data attribute
* via the => notation.
* @return DataObject
* @throws Exception
*/
public function createObject($identifier, $data = null, $fixtures = null)
{
// We have to disable validation while we import the fixtures, as the order in
// which they are imported doesnt guarantee valid relations until after the import is complete.
// Also disable filesystem manipulations
Config::nest();
Config::modify()->set(DataObject::class, 'validation_enabled', false);
Config::modify()->set(File::class, 'update_filesystem', false);
2016-11-29 00:31:16 +01:00
$this->invokeCallbacks('beforeCreate', [$identifier, &$data, &$fixtures]);
2016-11-29 00:31:16 +01:00
try {
$class = $this->class;
$schema = DataObject::getSchema();
API Refactor bootstrap, request handling See https://github.com/silverstripe/silverstripe-framework/pull/7037 and https://github.com/silverstripe/silverstripe-framework/issues/6681 Squashed commit of the following: commit 8f65e5653211240650eaa4fa65bb83b45aae6d58 Author: Ingo Schommer <me@chillu.com> Date: Thu Jun 22 22:25:50 2017 +1200 Fixed upgrade guide spelling commit 76f95944fa89b0b540704b8d744329f690f9698c Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 16:38:34 2017 +1200 BUG Fix non-test class manifest including sapphiretest / functionaltest commit 9379834cb4b2e5177a2600049feec05bf111c16b Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 15:50:47 2017 +1200 BUG Fix nesting bug in Kernel commit 188ce35d82599360c40f0f2de29579c56fb90761 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 15:14:51 2017 +1200 BUG fix db bootstrapping issues commit 7ed4660e7a63915e8e974deeaba9807bc4d38b0d Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 14:49:07 2017 +1200 BUG Fix issue in DetailedErrorFormatter commit 738f50c497166f81ccbe3f40fbcff895ce71f82f Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 11:49:19 2017 +1200 Upgrading notes on mysite/_config.php commit 6279d28e5e455916f902a2f963c014d8899f7fc7 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 11:43:28 2017 +1200 Update developer documentation commit 5c90d53a84ef0139c729396949a7857fae60436f Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 22 10:48:44 2017 +1200 Update installer to not use global databaseConfig commit f9b2ba4755371f08bd95f6908ac612fcbb7ca205 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 21:04:39 2017 +1200 Fix behat issues commit 5b59a912b60282b4dad4ef10ed3b97c5d0a761ac Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 17:07:11 2017 +1200 Move HTTPApplication to SilverStripe\Control namespace commit e2c4a18f637bdd3d276619554de60ee8b4d95ced Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 16:29:03 2017 +1200 More documentation Fix up remaining tests Refactor temp DB into TempDatabase class so it’s available outside of unit tests. commit 5d235e64f341d6251bfe9f4833f15cc8593c5034 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 21 12:13:15 2017 +1200 API HTTPRequestBuilder::createFromEnvironment() now cleans up live globals BUG Fix issue with SSViewer Fix Security / View tests commit d88d4ed4e48291cb65407f222f190064b1f1deeb Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 16:39:43 2017 +1200 API Refactor AppKernel into CoreKernel commit f7946aec3391139ae1b4029c353c327a36552b36 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 16:00:40 2017 +1200 Docs and minor cleanup commit 12bd31f9366327650b5c0c0f96cd0327d44faf0a Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 20 15:34:34 2017 +1200 API Remove OutputMiddleware API Move environment / global / ini management into Environment class API Move getTempFolder into TempFolder class API Implement HTTPRequestBuilder / CLIRequestBuilder BUG Restore SS_ALLOWED_HOSTS check in original location API CoreKernel now requires $basePath to be passed in API Refactor installer.php to use application to bootstrap API move memstring conversion globals to Convert BUG Fix error in CoreKernel nesting not un-nesting itself properly. commit bba979114624247cf463cf2a8c9e4be9a7c3a772 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 18:07:53 2017 +1200 API Create HTTPMiddleware and standardise middleware for request handling commit 2a10c2397bdc53001013f607b5d38087ce6c0730 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 17:42:42 2017 +1200 Fixed ORM tests commit d75a8d1d93398af4bd0432df9e4bc6295c15a3fe Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 17:15:07 2017 +1200 FIx i18n tests commit 06364af3c379c931889c4cc34dd920fee3db204a Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 16:59:34 2017 +1200 Fix controller namespace Move states to sub namespace commit 2a278e2953d2dbb19f78d91c919048e1fc935436 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 19 12:49:45 2017 +1200 Fix forms namespace commit b65c21241bee019730027071d815dbf7571197a4 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 15 18:56:48 2017 +1200 Update API usages commit d1d4375c95a264a6b63cbaefc2c1d12f808bfd82 Author: Damian Mooyman <damian@silverstripe.com> Date: Thu Jun 15 18:41:44 2017 +1200 API Refactor $flush into HTPPApplication API Enforce health check in Controller::pushCurrent() API Better global backup / restore Updated Director::test() to use new API commit b220534f06732db4fa940d8724c2a85c0ba2495a Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 22:05:57 2017 +1200 Move app nesting to a test state helper commit 603704165c08d0c1c81fd5e6bb9506326eeee17b Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 21:46:04 2017 +1200 Restore kernel stack to fix multi-level nesting commit 2f6336a15bf79dc8c2edd44cec1931da2dd51c28 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 17:23:21 2017 +1200 API Implement kernel nesting commit fc7188da7d6ad6785354bab61f08700454c81d91 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:43:13 2017 +1200 Fix core tests commit a0ae7235148fffd71f2f02d1fe7fe45bf3aa39eb Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:23:52 2017 +1200 Fix manifest tests commit ca033952513633e182040d3d13e1caa9000ca184 Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 15:00:00 2017 +1200 API Move extension management into test state commit c66d4339777663a8a04661fea32a0cf35b95d20f Author: Damian Mooyman <damian@silverstripe.com> Date: Tue Jun 13 14:10:59 2017 +1200 API Refactor SapphireTest state management into SapphireTestState API Remove Injector::unregisterAllObjects() API Remove FakeController commit f26ae75c6ecaafa0dec1093264e0187191e6764d Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 12 18:04:34 2017 +1200 Implement basic CLI application object commit 001d5596621404892de0a5413392379eff990641 Author: Damian Mooyman <damian@silverstripe.com> Date: Mon Jun 12 17:39:38 2017 +1200 Remove references to SapphireTest::is_running_test() Upgrade various code commit de079c041dacd96bc4f4b66421fa2b2cc4c320f8 Author: Damian Mooyman <damian@silverstripe.com> Date: Wed Jun 7 18:07:33 2017 +1200 API Implement APP object API Refactor of Session
2017-06-22 12:50:45 +02:00
$obj = Injector::inst()->create($class);
2016-11-29 00:31:16 +01:00
// If an ID is explicitly passed, then we'll sort out the initial write straight away
// This is just in case field setters triggered by the population code in the next block
// Call $this->write(). (For example, in FileTest)
if (isset($data['ID'])) {
$obj->ID = $data['ID'];
// The database needs to allow inserting values into the foreign key column (ID in our case)
$conn = DB::get_conn();
$baseTable = DataObject::getSchema()->baseDataTable($class);
if (method_exists($conn, 'allowPrimaryKeyEditing')) {
$conn->allowPrimaryKeyEditing($baseTable, true);
}
$obj->write(false, true);
if (method_exists($conn, 'allowPrimaryKeyEditing')) {
$conn->allowPrimaryKeyEditing($baseTable, false);
}
}
// Populate defaults
if ($this->defaults) {
foreach ($this->defaults as $fieldName => $fieldVal) {
if (isset($data[$fieldName]) && $data[$fieldName] !== false) {
continue;
}
if (!is_string($fieldVal) && is_callable($fieldVal)) {
2016-11-29 00:31:16 +01:00
$obj->$fieldName = $fieldVal($obj, $data, $fixtures);
} else {
$obj->$fieldName = $fieldVal;
}
}
}
// Populate overrides
if ($data) {
foreach ($data as $fieldName => $fieldVal) {
if ($schema->manyManyComponent($class, $fieldName)
|| $schema->hasManyComponent($class, $fieldName)
|| $schema->hasOneComponent($class, $fieldName)
) {
continue;
2016-11-29 00:31:16 +01:00
}
$this->setValue($obj, $fieldName, $fieldVal, $fixtures);
}
}
$obj->write();
// Save to fixture before relationship processing in case of reflexive relationships
if (!isset($fixtures[$class])) {
$fixtures[$class] = [];
2016-11-29 00:31:16 +01:00
}
$fixtures[$class][$identifier] = $obj->ID;
// Populate all relations
if ($data) {
foreach ($data as $fieldName => $fieldVal) {
$isManyMany = $schema->manyManyComponent($class, $fieldName);
$isHasMany = $schema->hasManyComponent($class, $fieldName);
if ($isManyMany && $isHasMany) {
throw new InvalidArgumentException("$fieldName is both many_many and has_many");
}
if ($isManyMany || $isHasMany) {
$obj->write();
// Many many components need a little extra work to extract extrafields
if (is_array($fieldVal) && $isManyMany) {
// handle lists of many_many relations. Each item can
// specify the many_many_extraFields against each
// related item.
foreach ($fieldVal as $relVal) {
// Check for many_many_extrafields
$extrafields = [];
if (is_array($relVal)) {
// Item is either first row, or key in yet another nested array
2022-04-14 03:12:59 +02:00
$item = key($relVal ?? []);
if (is_array($relVal[$item]) && count($relVal ?? []) === 1) {
2016-11-29 00:31:16 +01:00
// Extra fields from nested array
$extrafields = $relVal[$item];
} else {
// Extra fields from subsequent items
array_shift($relVal);
$extrafields = $relVal;
}
} else {
$item = $relVal;
}
$id = $this->parseValue($item, $fixtures);
$obj->getManyManyComponents($fieldName)->add(
$id,
$extrafields
);
}
} else {
$items = is_array($fieldVal)
? $fieldVal
2022-04-14 03:12:59 +02:00
: preg_split('/ *, */', trim($fieldVal ?? ''));
2016-11-29 00:31:16 +01:00
$parsedItems = [];
foreach ($items as $item) {
// Check for correct format: =><relationname>.<identifier>.
// Ignore if the item has already been replaced with a numeric DB identifier
2022-04-14 03:12:59 +02:00
if (!is_numeric($item) && !preg_match('/^=>[^\.]+\.[^\.]+/', $item ?? '')) {
2016-11-29 00:31:16 +01:00
throw new InvalidArgumentException(sprintf(
'Invalid format for relation "%s" on class "%s" ("%s")',
$fieldName,
$class,
$item
));
}
$parsedItems[] = $this->parseValue($item, $fixtures);
}
if ($isHasMany) {
$obj->getComponents($fieldName)->setByIDList($parsedItems);
} elseif ($isManyMany) {
$obj->getManyManyComponents($fieldName)->setByIDList($parsedItems);
}
}
} else {
2022-04-14 03:12:59 +02:00
$hasOneField = preg_replace('/ID$/', '', $fieldName ?? '');
2016-11-29 00:31:16 +01:00
if ($className = $schema->hasOneComponent($class, $hasOneField)) {
2018-01-16 19:39:30 +01:00
$obj->{$hasOneField . 'ID'} = $this->parseValue($fieldVal, $fixtures, $fieldClass);
2016-11-29 00:31:16 +01:00
// Inject class for polymorphic relation
if ($className === 'SilverStripe\\ORM\\DataObject') {
2018-01-16 19:39:30 +01:00
$obj->{$hasOneField . 'Class'} = $fieldClass;
2016-11-29 00:31:16 +01:00
}
}
}
}
}
$obj->write();
// If LastEdited was set in the fixture, set it here
2022-04-14 03:12:59 +02:00
if ($data && array_key_exists('LastEdited', $data ?? [])) {
2016-11-29 00:31:16 +01:00
$this->overrideField($obj, 'LastEdited', $data['LastEdited'], $fixtures);
}
} catch (Exception $e) {
Config::unnest();
throw $e;
}
Config::unnest();
$this->invokeCallbacks('afterCreate', [$obj, $identifier, &$data, &$fixtures]);
2016-11-29 00:31:16 +01:00
return $obj;
}
/**
* @param array $defaults
* @return $this
*/
public function setDefaults($defaults)
{
$this->defaults = $defaults;
return $this;
}
/**
* @return array
*/
public function getDefaults()
{
return $this->defaults;
}
/**
* @return string
*/
public function getClass()
{
return $this->class;
}
/**
* See class documentation.
*
* @param string $type
* @param callable $callback
* @return $this
*/
public function addCallback($type, $callback)
{
2022-04-14 03:12:59 +02:00
if (!array_key_exists($type, $this->callbacks ?? [])) {
2016-11-29 00:31:16 +01:00
throw new InvalidArgumentException(sprintf('Invalid type "%s"', $type));
}
$this->callbacks[$type][] = $callback;
return $this;
}
/**
* @param string $type
* @param callable $callback
* @return $this
*/
public function removeCallback($type, $callback)
{
2022-04-14 03:12:59 +02:00
$pos = array_search($callback, $this->callbacks[$type] ?? []);
2016-11-29 00:31:16 +01:00
if ($pos !== false) {
unset($this->callbacks[$type][$pos]);
}
return $this;
}
protected function invokeCallbacks($type, $args = [])
2016-11-29 00:31:16 +01:00
{
foreach ($this->callbacks[$type] as $callback) {
2022-04-14 03:12:59 +02:00
call_user_func_array($callback, $args ?? []);
2016-11-29 00:31:16 +01:00
}
}
/**
* Parse a value from a fixture file. If it starts with =>
* it will get an ID from the fixture dictionary
*
* @param string $value
* @param array $fixtures See {@link createObject()}
* @param string $class If the value parsed is a class relation, this parameter
* will be given the value of that class's name
* @return string Fixture database ID, or the original value
*/
protected function parseValue($value, $fixtures = null, &$class = null)
{
2022-04-14 03:12:59 +02:00
if (substr($value ?? '', 0, 2) == '=>') {
2016-11-29 00:31:16 +01:00
// Parse a dictionary reference - used to set foreign keys
2022-04-14 03:12:59 +02:00
list($class, $identifier) = explode('.', substr($value ?? '', 2), 2);
2016-11-29 00:31:16 +01:00
if ($fixtures && !isset($fixtures[$class][$identifier])) {
throw new InvalidArgumentException(sprintf(
'No fixture definitions found for "%s"',
$value
));
}
return $fixtures[$class][$identifier];
} else {
// Regular field value setting
return $value;
}
}
protected function setValue($obj, $name, $value, $fixtures = null)
{
$obj->$name = $this->parseValue($value, $fixtures);
}
protected function overrideField($obj, $fieldName, $value, $fixtures = null)
{
$class = get_class($obj);
$table = DataObject::getSchema()->tableForField($class, $fieldName);
$value = $this->parseValue($value, $fixtures);
DB::manipulate([
$table => [
2016-11-29 00:31:16 +01:00
"command" => "update",
"id" => $obj->ID,
"class" => $class,
"fields" => [$fieldName => $value],
]
]);
2016-11-29 00:31:16 +01:00
$obj->$fieldName = $value;
}
}