Completed
Pull Request — master (#386)
by
unknown
36:03
created

UserFormFieldEditorExtension::onAfterUnpublish()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 5
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
/**
4
 * @package userforms
5
 */
6
class UserFormFieldEditorExtension extends DataExtension {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
7
8
	/**
9
	 * @var array
10
	 */
11
	private static $has_many = array(
0 ignored issues
show
Unused Code introduced by
The property $has_many is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
12
		'Fields' => 'EditableFormField'
13
	);
14
15
	/**
16
	 * Adds the field editor to the page.
17
	 *
18
	 * @return FieldList
19
	 */
20
	public function updateCMSFields(FieldList $fields) {
21
		$fieldEditor = $this->getFieldEditorGrid();
22
23
		$fields->insertAfter(new Tab('FormFields', _t('UserFormFieldEditorExtension.FORMFIELDS', 'Form Fields')), 'Main');
0 ignored issues
show
Documentation introduced by
'Main' is of type string, but the function expects a object<FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
24
		$fields->addFieldToTab('Root.FormFields', $fieldEditor);
25
26
		return $fields;
27
	}
28
29
	/**
30
	 * Gets the field editor, for adding and removing EditableFormFields.
31
	 *
32
	 * @return GridField
33
	 */
34
	public function getFieldEditorGrid() {
35
		Requirements::javascript(USERFORMS_DIR . '/javascript/FieldEditor.js');
36
37
		$fields = $this->owner->Fields();
38
39
		$this->createInitialFormStep(true);
40
41
		$editableColumns = new GridFieldEditableColumns();
42
		$fieldClasses = singleton('EditableFormField')->getEditableFieldClasses();
43
		$editableColumns->setDisplayFields(array(
44
			'ClassName' => function($record, $column, $grid) use ($fieldClasses) {
0 ignored issues
show
Unused Code introduced by
The parameter $grid is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
45
				if($record instanceof EditableFormField) {
0 ignored issues
show
Bug introduced by
The class EditableFormField does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
46
					return $record->getInlineClassnameField($column, $fieldClasses);
47
				}
48
			},
49
			'Title' => function($record, $column, $grid) {
0 ignored issues
show
Unused Code introduced by
The parameter $grid is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
50
				if($record instanceof EditableFormField) {
0 ignored issues
show
Bug introduced by
The class EditableFormField does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
51
					return $record->getInlineTitleField($column);
52
				}
53
			}
54
		));
55
56
		$config = GridFieldConfig::create()
57
			->addComponents(
58
				$editableColumns,
59
				new GridFieldButtonRow(),
60
				GridFieldAddClassesButton::create('EditableTextField')
61
					->setButtonName(_t('UserFormFieldEditorExtension.ADD_FIELD', 'Add Field'))
62
					->setButtonClass('ss-ui-action-constructive'),
63
				GridFieldAddClassesButton::create('EditableFormStep')
64
					->setButtonName(_t('UserFormFieldEditorExtension.ADD_PAGE_BREAK', 'Add Page Break')),
65
				GridFieldAddClassesButton::create(array('EditableFieldGroup', 'EditableFieldGroupEnd'))
66
					->setButtonName(_t('UserFormFieldEditorExtension.ADD_FIELD_GROUP', 'Add Field Group')),
67
				new GridFieldEditButton(),
68
				new GridFieldDeleteAction(),
69
				new GridFieldToolbarHeader(),
70
				new GridFieldOrderableRows('Sort'),
71
				new GridFieldDetailForm()
72
			);
73
74
		$fieldEditor = GridField::create(
75
			'Fields',
76
			_t('UserDefinedForm.FIELDS', 'Fields'),
77
			$fields,
78
			$config
79
		)->addExtraClass('uf-field-editor');
80
81
		return $fieldEditor;
82
	}
83
84
	/**
85
	 * A UserForm must have at least one step.
86
	 * If no steps exist, create an initial step, and put all fields inside it.
87
	 *
88
	 * @param bool $force
89
	 * @return void
90
	 */
91
	public function createInitialFormStep($force = false) {
92
		// Only invoke once saved
93
		if(!$this->owner->exists()) {
94
			return;
95
		}
96
97
		// Check if first field is a step
98
		$fields = $this->owner->Fields();
99
		$firstField = $fields->first();
100
		if($firstField instanceof EditableFormStep) {
101
			return;
102
		}
103
104
		// Don't create steps on write if there are no formfields, as this
105
		// can create duplicate first steps during publish of new records
106
		if(!$force && !$firstField) {
107
			return;
108
		}
109
110
		// Re-apply sort to each field starting at 2
111
		$next = 2;
112
		foreach($fields as $field) {
113
			$field->Sort = $next++;
114
			$field->write();
115
		}
116
117
		// Add step
118
		$step = EditableFormStep::create();
119
		$step->Title = _t('EditableFormStep.TITLE_FIRST', 'First Page');
120
		$step->Sort = 1;
121
		$step->write();
122
		$fields->add($step);
123
	}
124
125
	/**
126
	 * Ensure that at least one page exists at the start
127
	 */
128
	public function onAfterWrite() {
129
		$this->createInitialFormStep();
130
	}
131
132
	/**
133
	 * @see SiteTree::doPublish
134
	 * @param Page $original
135
	 *
136
	 * @return void
137
	 */
138
	public function onAfterPublish($original) {
139
		// Remove fields on the live table which could have been orphaned.
140
		$live = Versioned::get_by_stage("EditableFormField", "Live")
141
			->filter('ParentID', $original->ID);
142
143
		if($live) {
144
			foreach($live as $field) {
145
				$field->doDeleteFromStage('Live');
146
			}
147
		}
148
149
		foreach($this->owner->Fields() as $field) {
150
			$field->doPublish('Stage', 'Live');
151
		}
152
	}
153
154
	/**
155
	 * @see SiteTree::doUnpublish
156
	 * @param Page $page
157
	 *
158
	 * @return void
159
	 */
160
	public function onAfterUnpublish($page) {
161
		foreach($page->Fields() as $field) {
162
			$field->doDeleteFromStage('Live');
163
		}
164
	}
165
166
	/**
167
	 * @see SiteTree::duplicate
168
	 * @param DataObject $newPage
169
	 *
170
	 * @return DataObject
171
	 */
172
	public function onAfterDuplicate($newPage) {
173
		// List of EditableFieldGroups, where the
174
		// key of the array is the ID of the old end group
175
		$fieldGroups = array();
176
		foreach($this->owner->Fields() as $field) {
177
			$newField = $field->duplicate(false);
178
			$newField->ParentID = $newPage->ID;
179
			$newField->ParentClass = $newPage->ClassName;
180
			$newField->Version = 0;
181
			$newField->write();
182
183
			// If we encounter a group start, record it for later use
184
			if($field instanceof EditableFieldGroup) {
185
				$fieldGroups[$field->EndID] = $newField;
186
			}
187
188
			// If we encounter an end group, link it back to the group start
189
			if($field instanceof EditableFieldGroupEnd && isset($fieldGroups[$field->ID])) {
190
				$groupStart = $fieldGroups[$field->ID];
191
				$groupStart->EndID = $newField->ID;
192
				$groupStart->write();
193
			}
194
195 View Code Duplication
			foreach ($field->DisplayRules() as $customRule) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
196
				$newRule = $customRule->duplicate(false);
197
				$newRule->ParentID = $newField->ID;
198
				$newRule->Version = 0;
199
				$newRule->write();
200
			}
201
		}
202
203
		return $newPage;
204
	}
205
206
	/**
207
	 * @see SiteTree::getIsModifiedOnStage
208
	 * @param boolean $isModified
209
	 *
210
	 * @return boolean
211
	 */
212
	public function getIsModifiedOnStage($isModified) {
213
		if(!$isModified) {
214
			foreach($this->owner->Fields() as $field) {
215
				if($field->getIsModifiedOnStage()) {
216
					$isModified = true;
217
					break;
218
				}
219
			}
220
		}
221
222
		return $isModified;
223
	}
224
225
	/**
226
	 * @see SiteTree::doRevertToLive
227
	 * @param Page $page
228
	 *
229
	 * @return void
230
	 */
231
	public function onAfterRevertToLive($page) {
232
		foreach($page->Fields() as $field) {
233
			$field->publish('Live', 'Stage', false);
234
			$field->writeWithoutVersion();
235
		}
236
	}
237
}
238