mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
292 lines
9.0 KiB
PHP
292 lines
9.0 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Service to support upgrade of userforms module
|
|
*/
|
|
class UserFormsUpgradeService
|
|
{
|
|
|
|
/**
|
|
* @var bool
|
|
*/
|
|
protected $quiet;
|
|
|
|
public function run()
|
|
{
|
|
$this->log("Upgrading formfield rules and custom settings");
|
|
|
|
// List of rules that have been created in all stages
|
|
$fields = Versioned::get_including_deleted('EditableFormField');
|
|
foreach ($fields as $field) {
|
|
$this->upgradeField($field);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migrate a versioned field in all stages
|
|
*
|
|
* @param EditableFormField $field
|
|
*/
|
|
protected function upgradeField(EditableFormField $field)
|
|
{
|
|
$this->log("Upgrading formfield ID = ".$field->ID);
|
|
|
|
// Check versions this field exists on
|
|
$filter = sprintf('"EditableFormField"."ID" = \'%d\' AND "Migrated" = 0', $field->ID);
|
|
$stageField = Versioned::get_one_by_stage('EditableFormField', 'Stage', $filter);
|
|
$liveField = Versioned::get_one_by_stage('EditableFormField', 'Live', $filter);
|
|
|
|
if ($stageField) {
|
|
$this->upgradeFieldInStage($stageField, 'Stage');
|
|
}
|
|
|
|
if ($liveField) {
|
|
$this->upgradeFieldInStage($liveField, 'Live');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migrate a versioned field in a single stage
|
|
*
|
|
* @param EditableFormField $field
|
|
* @param stage $stage
|
|
*/
|
|
protected function upgradeFieldInStage(EditableFormField $field, $stage)
|
|
{
|
|
Versioned::reading_stage($stage);
|
|
|
|
// Migrate field rules
|
|
$this->migrateRules($field, $stage);
|
|
|
|
// Migrate custom settings
|
|
$this->migrateCustomSettings($field, $stage);
|
|
|
|
// Flag as migrated
|
|
$field->Migrated = true;
|
|
$field->write();
|
|
}
|
|
|
|
/**
|
|
* Migrate custom rules for the given field
|
|
*
|
|
* @param EditableFormField $field
|
|
* @param string $stage
|
|
*/
|
|
protected function migrateRules(EditableFormField $field, $stage)
|
|
{
|
|
$rulesData = $field->CustomRules
|
|
? unserialize($field->CustomRules)
|
|
: array();
|
|
|
|
// Skip blank rules or fields with custom rules already
|
|
if (empty($rulesData) || $field->DisplayRules()->count()) {
|
|
return;
|
|
}
|
|
|
|
// Check value of this condition
|
|
foreach ($rulesData as $ruleDataItem) {
|
|
if (empty($ruleDataItem['ConditionOption']) || empty($ruleDataItem['Display'])) {
|
|
continue;
|
|
}
|
|
|
|
// Get data for this rule
|
|
$conditionOption = $ruleDataItem['ConditionOption'];
|
|
$display = $ruleDataItem['Display'];
|
|
$conditionFieldName = empty($ruleDataItem['ConditionField']) ? null : $ruleDataItem['ConditionField'];
|
|
$value = isset($ruleDataItem['Value'])
|
|
? $ruleDataItem['Value']
|
|
: null;
|
|
|
|
// Create rule
|
|
$rule = $this->findOrCreateRule($field, $stage, $conditionOption, $display, $conditionFieldName, $value);
|
|
$this->log("Upgrading rule ID = " . $rule->ID);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Migrate custom settings for the given field
|
|
*
|
|
* @param EditableFormField $field
|
|
* @param string $stage
|
|
*/
|
|
protected function migrateCustomSettings(EditableFormField $field, $stage)
|
|
{
|
|
// Custom settings include:
|
|
// - ExtraClass
|
|
// - RightTitle
|
|
// - ShowOnLoad (show or '' are treated as true)
|
|
//
|
|
// - CheckedDefault (new field on EditableCheckbox - should be read from old "default" value)
|
|
// - Default (EditableCheckbox)
|
|
// - DefaultToToday (EditableDateField)
|
|
// - Folder (EditableFileField)
|
|
// - Level (EditableFormHeading)
|
|
// - HideFromReports (EditableFormHeading / EditableLiteralField)
|
|
// - Content (EditableLiteralField)
|
|
// - GroupID (EditableMemberListField)
|
|
// - MinValue (EditableNumericField)
|
|
// - MaxValue (EditableNumericField)
|
|
// - MinLength (EditableTextField)
|
|
// - MaxLength (EditableTextField)
|
|
// - Rows (EditableTextField)
|
|
// - Placeholder (EditableTextField / EditableEmailField / EditableNumericField)
|
|
|
|
$customSettings = $field->CustomSettings
|
|
? unserialize($field->CustomSettings)
|
|
: array();
|
|
|
|
// Skip blank rules or fields with custom rules already
|
|
if (empty($customSettings)) {
|
|
return;
|
|
}
|
|
|
|
$field->migrateSettings($customSettings);
|
|
|
|
if ($field->config()->has_placeholder) {
|
|
$this->migratePlaceholder($field, $field->ClassName);
|
|
}
|
|
|
|
$field->write();
|
|
}
|
|
|
|
/**
|
|
* Create or find an existing field with the matched specification
|
|
*
|
|
* @param EditableFormField $field
|
|
* @param string $stage
|
|
* @param string $conditionOption
|
|
* @param string $display
|
|
* @param string $conditionFieldName
|
|
* @param string $value
|
|
* @return EditableCustomRule
|
|
*/
|
|
protected function findOrCreateRule(EditableFormField $field, $stage, $conditionOption, $display, $conditionFieldName, $value)
|
|
{
|
|
// Get id of field
|
|
$conditionField = $conditionFieldName
|
|
? EditableFormField::get()->filter('Name', $conditionFieldName)->first()
|
|
: null;
|
|
|
|
// If live, search stage record for matching one
|
|
if ($stage === 'Live') {
|
|
$list = Versioned::get_by_stage('EditableCustomRule', 'Stage')
|
|
->filter(array(
|
|
'ParentID' => $field->ID,
|
|
'ConditionFieldID' => $conditionField ? $conditionField->ID : 0,
|
|
'Display' => $display,
|
|
'ConditionOption' => $conditionOption
|
|
));
|
|
if ($value) {
|
|
$list = $list->filter('FieldValue', $value);
|
|
} else {
|
|
$list = $list->where('"FieldValue" IS NULL OR "FieldValue" = \'\'');
|
|
}
|
|
$rule = $list->first();
|
|
if ($rule) {
|
|
$rule->write();
|
|
$rule->publish("Stage", "Live");
|
|
return $rule;
|
|
}
|
|
}
|
|
|
|
// If none found, or in stage, create new record
|
|
$rule = new EditableCustomRule();
|
|
$rule->ParentID = $field->ID;
|
|
$rule->ConditionFieldID = $conditionField ? $conditionField->ID : 0;
|
|
$rule->Display = $display;
|
|
$rule->ConditionOption = $conditionOption;
|
|
$rule->FieldValue = $value;
|
|
$rule->write();
|
|
return $rule;
|
|
}
|
|
|
|
public function log($message)
|
|
{
|
|
if ($this->getQuiet()) {
|
|
return;
|
|
}
|
|
if (Director::is_cli()) {
|
|
echo "{$message}\n";
|
|
} else {
|
|
echo "{$message}<br />";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set if this service should be quiet
|
|
*
|
|
* @param bool $quiet
|
|
* @return $ths
|
|
*/
|
|
public function setQuiet($quiet)
|
|
{
|
|
$this->quiet = $quiet;
|
|
return $this;
|
|
}
|
|
|
|
public function getQuiet()
|
|
{
|
|
return $this->quiet;
|
|
}
|
|
|
|
|
|
/**
|
|
* Migrate Placeholder data from field specific table to the EditableFormField table
|
|
*
|
|
* @param EditableFormField $field
|
|
* @param string $tableName
|
|
*/
|
|
private function migratePlaceholder($field, $tableName)
|
|
{
|
|
// Migrate Placeholder setting from $tableName table to EditableFormField table
|
|
if ($field->Placeholder) {
|
|
return;
|
|
}
|
|
// Check if draft table exists
|
|
if (!DB::get_schema()->hasTable($tableName)) {
|
|
// Check if _obsolete_ draft table exists
|
|
$tableName = '_obsolete_' . $tableName;
|
|
if (!DB::get_schema()->hasTable($tableName)) {
|
|
return;
|
|
}
|
|
}
|
|
// Check if old Placeholder column exists
|
|
if (!DB::get_schema()->hasField($tableName, 'Placeholder')) {
|
|
return;
|
|
}
|
|
// Fetch existing draft Placeholder value
|
|
$query = "SELECT \"Placeholder\" FROM \"$tableName\" WHERE \"ID\" = '$field->ID'";
|
|
$draftPlaceholder = DB::query($query)->value();
|
|
|
|
if (!$draftPlaceholder) {
|
|
return;
|
|
}
|
|
// Update draft Placeholder value
|
|
DB::prepared_query(
|
|
"UPDATE \"EditableFormField\" SET \"Placeholder\" = ? WHERE \"ID\" = ?",
|
|
array($draftPlaceholder, $field->ID)
|
|
);
|
|
|
|
$livePlaceholder = $draftPlaceholder;
|
|
|
|
// Check if live table exists
|
|
$tableName = $tableName . '_Live';
|
|
if (DB::get_schema()->hasTable($tableName)) {
|
|
// Fetch existing live Placeholder value
|
|
$query = "SELECT \"Placeholder\" FROM \"$tableName\" WHERE \"ID\" = '" . $field->ID . "'";
|
|
$livePlaceholder = DB::query($query)->value();
|
|
if (!$livePlaceholder) {
|
|
$livePlaceholder = $draftPlaceholder;
|
|
}
|
|
}
|
|
|
|
// Update live Placeholder value
|
|
DB::prepared_query(
|
|
"UPDATE \"EditableFormField_Live\" SET \"Placeholder\" = ? WHERE \"ID\" = ?",
|
|
array($draftPlaceholder, $field->ID)
|
|
);
|
|
}
|
|
}
|