Completed
Pull Request — master (#1644)
by Damian
02:31
created

CMSPageAddController::AddForm()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 128
Code Lines 85

Duplication

Lines 14
Ratio 10.94 %

Importance

Changes 0
Metric Value
dl 14
loc 128
rs 8.1463
c 0
b 0
f 0
cc 6
eloc 85
nc 8
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\CMS\Controllers;
4
5
use SilverStripe\CMS\Model\SiteTree;
6
use SilverStripe\Control\Controller;
7
use SilverStripe\Control\Session;
8
use SilverStripe\Control\HTTPResponse;
9
use SilverStripe\Forms\FieldList;
10
use SilverStripe\Forms\Form;
11
use SilverStripe\Forms\FormAction;
12
use SilverStripe\Forms\LiteralField;
13
use SilverStripe\Forms\OptionsetField;
14
use SilverStripe\Forms\SelectionGroup;
15
use SilverStripe\Forms\SelectionGroup_Item;
16
use SilverStripe\Forms\TreeDropdownField;
17
use SilverStripe\ORM\DataObject;
18
use SilverStripe\ORM\FieldType\DBField;
19
use SilverStripe\ORM\ValidationException;
20
use SilverStripe\Security\Member;
21
use SilverStripe\Security\Security;
22
23
class CMSPageAddController extends CMSPageEditController {
24
25
	private static $url_segment = 'pages/add';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
26
	private static $url_rule = '/$Action/$ID/$OtherID';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
27
	private static $url_priority = 42;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
28
	private static $menu_title = 'Add page';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
29
	private static $required_permission_codes = 'CMS_ACCESS_CMSMain';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
30
31
	private static $allowed_actions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
32
		'AddForm',
33
		'doAdd',
34
		'doCancel'
35
	);
36
37
	/**
38
	 * @return Form
39
	 */
40
	public function AddForm() {
41
		$pageTypes = array();
42
		foreach($this->PageTypes() as $type) {
43
			$html = sprintf('<span class="page-icon class-%s"></span><span class="title">%s</span><span class="form__field-description">%s</span>',
44
				$type->getField('ClassName'),
45
				$type->getField('AddAction'),
46
				$type->getField('Description')
47
			);
48
			$pageTypes[$type->getField('ClassName')] = DBField::create_field('HTMLFragment', $html);
49
		}
50
		// Ensure generic page type shows on top
51
		if(isset($pageTypes['Page'])) {
52
			$pageTitle = $pageTypes['Page'];
53
			$pageTypes = array_merge(array('Page' => $pageTitle), $pageTypes);
54
		}
55
56
		$numericLabelTmpl = '<span class="step-label"><span class="flyout">Step %d. </span><span class="title">%s</span></span>';
57
58
		$topTitle = _t('CMSPageAddController.ParentMode_top', 'Top level');
59
		$childTitle = _t('CMSPageAddController.ParentMode_child', 'Under another page');
60
61
		$fields = new FieldList(
62
			$parentModeField = new SelectionGroup(
63
				"ParentModeField",
64
				array(
65
					new SelectionGroup_Item(
66
						"top",
67
						null,
68
						$topTitle
69
					),
70
					new SelectionGroup_Item(
71
						'child',
72
						$parentField = new TreeDropdownField(
73
							"ParentID",
74
							"",
75
							'SilverStripe\\CMS\\Model\\SiteTree',
76
							'ID',
77
							'TreeTitle'
78
						),
79
						$childTitle
80
					)
81
				)
82
			),
83
			new LiteralField(
84
				'RestrictedNote',
85
				sprintf(
86
					'<p class="message notice message-restricted">%s</p>',
87
					_t(
88
						'CMSMain.AddPageRestriction',
89
						'Note: Some page types are not allowed for this selection'
90
					)
91
				)
92
			),
93
			$typeField = new OptionsetField(
94
				"PageType",
95
				DBField::create_field(
96
					'HTMLFragment',
97
					sprintf($numericLabelTmpl, 2, _t('CMSMain.ChoosePageType', 'Choose page type'))
98
				),
99
				$pageTypes,
100
				'Page'
101
			)
102
		);
103
104
		$parentModeField->setTitle(DBField::create_field(
105
			'HTMLFragment',
106
			sprintf($numericLabelTmpl, 1, _t('CMSMain.ChoosePageParentMode', 'Choose where to create this page'))
107
		));
108
109
		$parentField->setSearchFunction(function ($sourceObject, $labelField, $search) {
110
			return DataObject::get($sourceObject)
111
				->filterAny([
112
					'MenuTitle:PartialMatch' => $search,
113
					'Title:PartialMatch' => $search,
114
				]);
115
		});
116
117
		// TODO Re-enable search once it allows for HTML title display,
118
		// see http://open.silverstripe.org/ticket/7455
119
		// $parentField->setShowSearch(true);
120
121
		$parentModeField->addExtraClass('parent-mode');
122
123
		// CMSMain->currentPageID() automatically sets the homepage,
124
		// which we need to counteract in the default selection (which should default to root, ID=0)
125
		if($parentID = $this->getRequest()->getVar('ParentID')) {
126
			$parentModeField->setValue('child');
127
			$parentField->setValue((int)$parentID);
128
		} else {
129
			$parentModeField->setValue('top');
130
		}
131
132
		$actions = new FieldList(
133
			FormAction::create("doAdd", _t('CMSMain.Create',"Create"))
134
				->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')
135
				->setUseButtonTag(true),
136
			FormAction::create("doCancel", _t('CMSMain.Cancel',"Cancel"))
137
				->addExtraClass('ss-ui-action-destructive ss-ui-action-cancel')
138
				->setUseButtonTag(true)
139
		);
140
141
		$this->extend('updatePageOptions', $fields);
142
143
		$negotiator = $this->getResponseNegotiator();
144
		$form = Form::create(
145
			$this, "AddForm", $fields, $actions
146
		)->setHTMLID('Form_AddForm');
147
		$form->setAttribute('data-hints', $this->SiteTreeHints());
148
		$form->setAttribute('data-childfilter', $this->Link('childfilter'));
149 View Code Duplication
		$form->setValidationResponseCallback(function() use ($negotiator, $form) {
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...
150
			$request = $this->getRequest();
151
			if($request->isAjax() && $negotiator) {
152
				$form->setupFormErrors();
153
				$result = $form->forTemplate();
154
155
				return $negotiator->respond($request, array(
156
					'CurrentForm' => function() use($result) {
157
						return $result;
158
					}
159
				));
160
			}
161
			return null;
162
		});
163
		$form->addExtraClass('cms-add-form cms-content center cms-edit-form ' . $this->BaseCSSClasses());
164
		$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
165
166
		return $form;
167
	}
168
169
	/**
170
	 * @param array $data
171
	 * @param Form $form
172
	 * @return HTTPResponse
173
	 */
174
	public function doAdd($data, $form) {
175
		$className = isset($data['PageType']) ? $data['PageType'] : "Page";
176
		$parentID = isset($data['ParentID']) ? (int)$data['ParentID'] : 0;
177
178
		$suffix = isset($data['Suffix']) ? "-" . $data['Suffix'] : null;
179
180
		if(!$parentID && isset($data['Parent'])) {
181
			$page = SiteTree::get_by_link($data['Parent']);
182
			if($page) $parentID = $page->ID;
183
		}
184
185
		if(is_numeric($parentID) && $parentID > 0) {
186
			$parentObj = SiteTree::get()->byID($parentID);
187
		} else {
188
			$parentObj = null;
189
		}
190
191
		if(!$parentObj || !$parentObj->ID) {
192
			$parentID = 0;
193
		}
194
195
		if(!singleton($className)->canCreate(Member::currentUser(), array('Parent' => $parentObj))) {
196
			return Security::permissionFailure($this);
197
		}
198
199
		$record = $this->getNewItem("new-$className-$parentID".$suffix, false);
200
		$this->extend('updateDoAdd', $record, $form);
201
202
		try {
203
			$record->write();
204
		} catch(ValidationException $ex) {
205
			$form->sessionMessage($ex->getResult()->message(), 'bad');
206
			return $this->getResponseNegotiator()->respond($this->getRequest());
207
		}
208
209
		$editController = CMSPageEditController::singleton();
210
		$editController->setCurrentPageID($record->ID);
211
212
		Session::set(
213
			"FormInfo.Form_EditForm.formError.message",
214
			_t('CMSMain.PageAdded', 'Successfully created page')
215
		);
216
		Session::set("FormInfo.Form_EditForm.formError.type", 'good');
217
218
		return $this->redirect(Controller::join_links($editController->Link('show'), $record->ID));
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->redirect(\SilverS...'show'), $record->ID)); of type string|null adds the type string to the return on line 218 which is incompatible with the return type documented by SilverStripe\CMS\Control...ageAddController::doAdd of type SilverStripe\Control\HTTPResponse|null.
Loading history...
219
	}
220
221
	public function doCancel($data, $form) {
0 ignored issues
show
Unused Code introduced by
The parameter $data 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...
Unused Code introduced by
The parameter $form 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...
222
		return $this->redirect(CMSMain::singleton()->Link());
223
	}
224
}
225