2018-05-18 03:41:02 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace SilverStripe\UserForms\Extension;
|
|
|
|
|
|
|
|
use SilverStripe\Control\Director;
|
|
|
|
use SilverStripe\Core\Injector\Injector;
|
|
|
|
use SilverStripe\ORM\DataExtension;
|
|
|
|
use SilverStripe\ORM\DataList;
|
|
|
|
use SilverStripe\ORM\DataObject;
|
|
|
|
use SilverStripe\ORM\ValidationException;
|
|
|
|
use SilverStripe\UserForms\Model\EditableFormField;
|
|
|
|
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
|
|
|
|
use SilverStripe\UserForms\Model\Submission\SubmittedForm;
|
|
|
|
use SilverStripe\UserForms\Model\UserDefinedForm;
|
|
|
|
use SilverStripe\UserForms\UserForm;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This extension provides a hook that runs during a dev/build which will check for existing data in various
|
|
|
|
* polymorphic relationship fields for userforms models, and ensure that the data is correct.
|
|
|
|
*
|
|
|
|
* Various `Parent` relationships in silverstripe/userforms for SilverStripe 3 were mapped directly to UserDefinedForm
|
|
|
|
* instances, and were made polymorphic in SilverStripe 4 (which also requires a class name). This means that a
|
|
|
|
* certain amount of manual checking is required to ensure that upgrades are performed smoothly.
|
|
|
|
*
|
|
|
|
* @internal This API is likely to be removed in later major versions of silverstripe/userforms
|
|
|
|
*/
|
|
|
|
class UpgradePolymorphicExtension extends DataExtension
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* A list of userforms classes that have had polymorphic relationships added in SilverStripe 4, and the fields
|
|
|
|
* on them that are polymorphic
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $targets = [
|
|
|
|
EditableFormField::class => ['ParentClass'],
|
|
|
|
EmailRecipient::class => ['FormClass'],
|
|
|
|
SubmittedForm::class => ['ParentClass'],
|
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The default class name that will be used to replace values with
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $defaultReplacement = UserDefinedForm::class;
|
|
|
|
|
|
|
|
public function requireDefaultRecords()
|
|
|
|
{
|
|
|
|
if (!UserDefinedForm::config()->get('upgrade_on_build')) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$updated = 0;
|
|
|
|
foreach ($this->targets as $className => $fieldNames) {
|
|
|
|
foreach ($fieldNames as $fieldName) {
|
|
|
|
/** @var DataList $list */
|
|
|
|
$list = $className::get();
|
|
|
|
|
|
|
|
foreach ($list as $entry) {
|
|
|
|
/** @var DataObject $relationshipObject */
|
|
|
|
$relationshipObject = Injector::inst()->get($entry->$fieldName);
|
|
|
|
if (!$relationshipObject) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the defined data class doesn't have the UserForm trait applied, it's probably wrong. Re-map
|
|
|
|
// it to a default value that does
|
|
|
|
$classTraits = class_uses($relationshipObject);
|
|
|
|
if (in_array(UserForm::class, $classTraits)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-09-07 12:50:34 +02:00
|
|
|
// Don't rewrite class values when an existing value is set and is an instance of UserDefinedForm
|
|
|
|
if ($relationshipObject instanceof UserDefinedForm) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-18 03:41:02 +02:00
|
|
|
$entry->$fieldName = $this->defaultReplacement;
|
|
|
|
try {
|
|
|
|
$entry->write();
|
|
|
|
$updated++;
|
|
|
|
} catch (ValidationException $ex) {
|
|
|
|
// no-op, allow the rest of dev/build to continue. There may be an error indicating that the
|
|
|
|
// object's class doesn't exist, which can be fixed by {@link DatabaseAdmin::doBuild} and this
|
|
|
|
// logic will work the next time dev/build is run.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($updated) {
|
|
|
|
$message = "Corrected {$updated} default polymorphic class names to {$this->defaultReplacement}";
|
|
|
|
if (Director::is_cli()) {
|
|
|
|
echo sprintf(" * %s\n", $message);
|
|
|
|
} else {
|
|
|
|
echo sprintf("<li>%s</li>\n", $message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|