Completed
Pull Request — master (#5278)
by Ingo
12:05
created

CampaignAdmin::getListItems()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 7
rs 9.4285
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
3
/**
4
 * Campaign section of the CMS
5
 *
6
 * @package framework
7
 * @subpackage admin
8
 */
9
class CampaignAdmin extends LeftAndMain implements PermissionProvider {
10
11
	private static $allowed_actions = [
12
		'set',
13
		'sets',
14
		'schema',
15
		'DetailEditForm',
16
		'readCampaigns',
17
		'createCampaign',
18
		'readCampaign',
19
		'updateCampaign',
20
		'deleteCampaign',
21
	];
22
23
	private static $menu_priority = 11;
24
25
	private static $menu_title = 'Campaigns';
26
27
	private static $url_handlers = [
28
		'GET sets' => 'readCampaigns',
29
		'POST set/$ID' => 'createCampaign',
30
		'GET set/$ID' => 'readCampaign',
31
		'PUT set/$ID' => 'updateCampaign',
32
		'DELETE set/$ID' => 'deleteCampaign',
33
	];
34
35
	private static $url_segment = 'campaigns';
36
37
	public function getClientConfig() {
38
		return array_merge(parent::getClientConfig(), [
39
			'forms' => [
40
				// TODO Use schemaUrl instead
41
				'editForm' => [
42
					'schemaUrl' => $this->Link('schema/EditForm')
43
				]
44
			]
45
		]);
46
	}
47
48
	public function schema($request) {
49
		// TODO Hardcoding schema until we can get GridField to generate a schema dynamically
50
		$json = <<<JSON
51
{
52
	"id": "EditForm",
53
	"schema": {
54
		"name": "EditForm",
55
		"id": "EditForm",
56
		"action": "schema",
57
		"method": "GET",
58
		"schema_url": "admin\/campaigns\/schema\/EditForm",
59
		"attributes": {
60
			"id": "Form_EditForm",
61
			"action": "admin\/campaigns\/EditForm",
62
			"method": "POST",
63
			"enctype": "multipart\/form-data",
64
			"target": null,
65
			"class": "cms-edit-form CampaignAdmin LeftAndMain"
66
		},
67
		"data": [],
68
		"fields": [{
69
			"name": "ID",
70
			"id": "Form_EditForm_ID",
71
			"type": "Hidden",
72
			"component": null,
73
			"holder_id": null,
74
			"title": false,
75
			"source": null,
76
			"extraClass": "hidden nolabel",
77
			"description": null,
78
			"rightTitle": null,
79
			"leftTitle": null,
80
			"readOnly": false,
81
			"disabled": false,
82
			"customValidationMessage": "",
83
			"attributes": [],
84
			"data": []
85
		}, {
86
			"name": "ChangeSets",
87
			"id": "Form_EditForm_ChangeSets",
88
			"type": "Custom",
89
			"component": "GridField",
90
			"holder_id": null,
91
			"title": "Campaigns",
92
			"source": null,
93
			"extraClass": null,
94
			"description": null,
95
			"rightTitle": null,
96
			"leftTitle": null,
97
			"readOnly": false,
98
			"disabled": false,
99
			"customValidationMessage": "",
100
			"attributes": [],
101
			"data": {
102
				"recordType": "ChangeSet",
103
				"collectionReadEndpoint": {
104
					"url": "admin\/campaigns\/sets",
105
					"method": "GET"
106
				},
107
				"itemReadEndpoint": {
108
					"url": "admin\/campaigns\/set\/:id",
109
					"method": "GET"
110
				},
111
				"itemUpdateEndpoint": {
112
					"url": "admin\/campaigns\/set\/:id",
113
					"method": "PUT"
114
				},
115
				"itemCreateEndpoint": {
116
					"url": "admin\/campaigns\/set\/:id",
117
					"method": "POST"
118
				},
119
				"itemDeleteEndpoint": {
120
					"url": "admin\/campaigns\/set\/:id",
121
					"method": "DELETE"
122
				},
123
				"editFormSchemaEndpoint": "admin\/campaigns\/schema\/DetailEditForm",
124
				"columns": [
125
					{"name": "Title", "field": "Name"},
126
					{"name": "Changes", "field": "_embedded.ChangeSetItems.length"},
127
					{"name": "Description", "field": "Description"}
128
				]
129
			}
130
		}, {
131
			"name": "SecurityID",
132
			"id": "Form_EditForm_SecurityID",
133
			"type": "Hidden",
134
			"component": null,
135
			"holder_id": null,
136
			"title": "Security ID",
137
			"source": null,
138
			"extraClass": "hidden",
139
			"description": null,
140
			"rightTitle": null,
141
			"leftTitle": null,
142
			"readOnly": false,
143
			"disabled": false,
144
			"customValidationMessage": "",
145
			"attributes": [],
146
			"data": []
147
		}],
148
		"actions": []
149
	}
150
}
151
JSON;
152
153
		$formName = $request->param('ID');
154
		if($formName == 'EditForm') {
155
			$response = $this->getResponse();
156
			$response->addHeader('Content-Type', 'application/json');
157
			$response->setBody($json);
158
			return $response;
159
		} else {
160
			return parent::schema($request);
161
		}
162
	}
163
164
	/**
165
	 * REST endpoint to create a campaign.
166
	 *
167
	 * @param SS_HTTPRequest $request
168
	 *
169
	 * @return SS_HTTPResponse
170
	 */
171
	public function createCampaign(SS_HTTPRequest $request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
172
		$response = new SS_HTTPResponse();
173
		$response->addHeader('Content-Type', 'application/json');
174
		$response->setBody(Convert::raw2json(['campaign' => 'create']));
175
176
		// TODO Implement permission check and data creation
177
178
		return $response;
179
	}
180
181
	/**
182
	 * REST endpoint to get a list of campaigns.
183
	 *
184
	 * @param SS_HTTPRequest $request
185
	 *
186
	 * @return SS_HTTPResponse
187
	 */
188
	public function readCampaigns(SS_HTTPRequest $request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
189
		$response = new SS_HTTPResponse();
190
		$response->addHeader('Content-Type', 'application/json');
191
		$hal = $this->getListResource();
192
		$response->setBody(Convert::array2json($hal));
193
		return $response;
194
		}
195
196
	/**
197
	 * Get list contained as a hal wrapper
198
	 *
199
	 * @return array
200
	 */
201
	protected function getListResource() {
202
		$items = $this->getListItems();
203
		$count = $items->count();
204
		$hal = [
205
			'count' => $count,
206
			'total' => $count,
207
			'_links' => [
208
				'self' => [
209
					'href' => $this->Link('items')
210
				]
211
			],
212
			'_embedded' => ['ChangeSets' => []]
213
		];
214
		foreach($items as $item) {
215
			/** @var ChangeSet $item */
216
			$resource = $this->getChangeSetResource($item);
217
			$hal['_embedded']['ChangeSets'][] = $resource;
218
		}
219
		return $hal;
220
	}
221
222
	/**
223
	 * Build item resource from a changeset
224
	 *
225
	 * @param ChangeSet $changeSet
226
	 * @return array
227
	 */
228
	protected function getChangeSetResource(ChangeSet $changeSet) {
229
		$hal = [
230
			'_links' => [
231
				'self' => [
232
					'href' => $this->SetLink($changeSet->ID)
233
				]
234
			],
235
			'ID' => $changeSet->ID,
236
			'Name' => $changeSet->Name,
237
			'Created' => $changeSet->Created,
238
			'LastEdited' => $changeSet->LastEdited,
239
			'State' => $changeSet->State,
240
			'_embedded' => ['ChangeSetItems' => []]
241
		];
242
		foreach($changeSet->Changes() as $changeSetItem) {
243
			if(!$changeSetItem) {
244
				continue;
245
			}
246
247
			/** @var ChangesetItem $changeSetItem */
248
			$resource = $this->getChangeSetItemResource($changeSetItem);
249
			$hal['_embedded']['ChangeSetItems'][] = $resource;
250
		}
251
		return $hal;
252
	}
253
254
	/**
255
	 * Build item resource from a changesetitem
256
	 *
257
	 * @param ChangeSetItem $changeSetItem
258
	 * @return array
259
	 */
260
	protected function getChangeSetItemResource(ChangeSetItem $changeSetItem) {
261
		$hal = [
262
			'_links' => [
263
				'self' => [
264
					'href' => $this->ItemLink($changeSetItem->ID)
265
				]
266
			],
267
			'ID' => $changeSetItem->ID,
268
			'Created' => $changeSetItem->Created,
269
			'LastEdited' => $changeSetItem->LastEdited,
270
			'Title' => $changeSetItem->getTitle(),
271
			'ChangeType' => $changeSetItem->getChangeType(),
272
			'Added' => $changeSetItem->Added,
273
		];
274
		// Depending on whether the object was added implicitly or explicitly, set
275
		// other related objects.
276
		if($changeSetItem->Added === ChangeSetItem::IMPLICITLY) {
277
			$referencedItems = $changeSetItem->ReferencedBy();
278
			$referencedBy = [];
279
			foreach($referencedItems as $referencedItem) {
280
				$referencedBy[] = [
281
					'href' => $this->SetLink($referencedItem->ID)
282
				];
283
			}
284
			if($referencedBy) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $referencedBy of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
285
				$hal['_links']['referenced_by'] = $referencedBy;
286
			}
287
		}
288
289
		return $hal;
290
	}
291
292
293
294
	/**
295
	 * Gets viewable list of campaigns
296
	 *
297
	 * @return SS_List
298
	 */
299
	protected function getListItems() {
300
		return ChangeSet::get()
301
			->filter('State', ChangeSet::STATE_OPEN)
302
			->filterByCallback(function($item) {
303
				return ($item->canView());
304
			});
305
	}
306
307
308
	/**
309
	 * REST endpoint to get a campaign.
310
	 *
311
	 * @param SS_HTTPRequest $request
312
	 *
313
	 * @return SS_HTTPResponse
314
	 */
315
	public function readCampaign(SS_HTTPRequest $request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
316
		$response = new SS_HTTPResponse();
317
		$response->addHeader('Content-Type', 'application/json');
318
		$response->setBody('');
319
320
		// TODO Implement data retrieval and serialisation
321
322
		return $response;
323
	}
324
325
	/**
326
	 * REST endpoint to update a campaign.
327
	 *
328
	 * @param SS_HTTPRequest $request
329
	 *
330
	 * @return SS_HTTPResponse
331
	 */
332
	public function updateCampaign(SS_HTTPRequest $request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
333
		$response = new SS_HTTPResponse();
334
		$response->addHeader('Content-Type', 'application/json');
335
		$response->setBody(Convert::raw2json(['campaign' => 'update']));
336
337
		// TODO Implement data update and permission checks
338
339
		return $response;
340
	}
341
342
	/**
343
	 * REST endpoint to delete a campaign.
344
	 *
345
	 * @param SS_HTTPRequest $request
346
	 *
347
	 * @return SS_HTTPResponse
348
	 */
349
	public function deleteCampaign(SS_HTTPRequest $request) {
350
		$id = $request->param('ID');
351
		if (!$id || !is_numeric($id)) {
352
            return (new SS_HTTPResponse(json_encode(['status' => 'error']), 400))
353
                ->addHeader('Content-Type', 'application/json');
354
        }
355
356
		$record = ChangeSet::get()->byID($id);
357
		if(!$record) {
358
			return (new SS_HTTPResponse(json_encode(['status' => 'error']), 404))
359
                ->addHeader('Content-Type', 'application/json');
360
		}
361
362
		if(!$record->canDelete()) {
363
			return (new SS_HTTPResponse(json_encode(['status' => 'error']), 401))
364
                ->addHeader('Content-Type', 'application/json');
365
		}
366
367
		$record->delete();
368
369
		return (new SS_HTTPResponse('', 204));
370
	}
371
372
	/**
373
	 * @todo Use GridFieldDetailForm once it can handle structured data and form schemas
374
	 *
375
	 * @return Form
376
	 */
377
	public function getDetailEditForm() {
378
		return Form::create(
379
			$this,
380
			'DetailEditForm',
381
			ChangeSet::singleton()->getCMSFields(),
382
			FieldList::create(
383
				FormAction::create('save', 'Save')
384
			)
385
		);
386
	}
387
388
	/**
389
	 * Gets user-visible url to edit a specific {@see ChangeSet}
390
	 *
391
	 * @param $itemID
392
	 * @return string
393
	 */
394
	public function SetLink($itemID) {
395
		return Controller::join_links(
396
			$this->Link('set'),
397
			$itemID
398
		);
399
	}
400
401
	/**
402
	 * Gets user-visible url to edit a specific {@see ChangeSetItem}
403
	 *
404
	 * @param int $itemID
405
	 * @return string
406
	 */
407
	public function ItemLink($itemID) {
408
		return Controller::join_links(
409
			$this->Link('item'),
410
			$itemID
411
		);
412
	}
413
414
	/**
415
	 *
416
	 */
417
	public function FindReferencedChanges() {
418
419
	}
420
421
}
422