view()   F
last analyzed

Complexity

Conditions 30
Paths 1761

Size

Total Lines 146

Duplication

Lines 27
Ratio 18.49 %

Importance

Changes 0
Metric Value
dl 27
loc 146
rs 0
c 0
b 0
f 0
cc 30
nc 1761
nop 0

How to fix   Long Method    Complexity   

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
	 * Copyright: Deux Huit Huit 2014
4
	 * LICENCE: MIT https://deuxhuithuit.mit-license.org
5
	 */
6
7
	if(!defined("__IN_SYMPHONY__")) die("<h2>Error</h2><p>You cannot directly access this file</p>");
8
9
	require_once(TOOLKIT . '/class.jsonpage.php');
10
11
	class contentExtensionEntry_Relationship_FieldSave extends JSONPage {
12
13
		const NUMBER_OF_URL_PARAMETERS = 3;
14
		
15
		/**
16
		 *
17
		 * Builds the content view
18
		 */
19
		public function view() {
20
			if ($_SERVER['REQUEST_METHOD'] != 'POST') {
21
				$this->_Result['status'] = Page::HTTP_STATUS_BAD_REQUEST;
22
				$this->_Result['error'] = __('This page accepts posts only');
23
				$this->setHttpStatus($this->_Result['status']);
24
				return;
25
			}
26
			
27
			// _context[0] => entry values
28
			// _context[1] => fieldId
29
			// _context[2] => current entry id
30 View Code Duplication
			if (!is_array($this->_context) || empty($this->_context)) {
31
				$this->_Result['error'] = __('Parameters not found');
32
				return;
33
			}
34
			else if (count($this->_context) < self::NUMBER_OF_URL_PARAMETERS) {
35
				$this->_Result['error'] = __('Not enough parameters');
36
				return;
37
			}
38
			else if (count($this->_context) > self::NUMBER_OF_URL_PARAMETERS) {
39
				$this->_Result['error'] = __('Too many parameters');
40
				return;
41
			}
42
			
43
			// Validate ALL entries ID
44
			$rawEntriesId = array_filter(explode(',', MySQL::cleanValue(urldecode($this->_context[0]))));
45
			
46
			// Check for operators
47
			$operator = null;
48
			if (!empty($rawEntriesId)) {
49
				// '��' == '+''
50
				if (General::strpos($rawEntriesId[0], '+') === 0) {
51
					$operator = '+';
52
				} else if (General::strpos($rawEntriesId[0], '−') === 0) {
53
					$operator = '-';
54
				}
55
				if ($operator) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $operator of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
56
					$rawEntriesId[0] = General::substr($rawEntriesId[0], 1);
57
				}
58
			}
59
			
60
			// Convert all values to int
61
			$entriesId = array_map(array('General', 'intval'), $rawEntriesId);
62
			
63
			// Check result
64
			if (!is_array($entriesId) || empty($entriesId)) {
65
				$this->_Result['error'] = __('No entry no found');
66
				return;
67
			}
68
			if (in_array('null', $rawEntriesId)) {
69
				$entriesId = array();
70
			}
71
			foreach ($entriesId as $entryPos => $entryId) {
72
				if ($entryId < 1) {
73
					$this->_Result['error'] = sprintf(
74
						__('Entry id `%s` not valid'),
75
						$rawEntriesId[$entryPos]
76
					);
77
					return;
78
				}
79
			}
80
			
81
			// Validate parent field exists
82
			$parentFieldId = General::intval(MySQL::cleanValue($this->_context[1]));
83
			if ($parentFieldId < 1) {
84
				$this->_Result['error'] = __('Parent id not valid');
85
				return;
86
			}
87
			$parentField = FieldManager::fetch($parentFieldId);
88
			if (!$parentField || empty($parentField)) {
89
				$this->_Result['error'] = __('Parent field not found');
90
				return;
91
			}
92
			
93
			// Validate parent entry ID
94
			$rawEntryId = MySQL::cleanValue($this->_context[2]);
95
			$entryId = General::intval($rawEntryId );
96 View Code Duplication
			if ($entryId < 1) {
97
				$this->_Result['error'] = sprintf(
98
					__('Parent entry id `%s` not valid'),
99
					$rawEntryId
100
				);
101
				return;
102
			}
103
			
104
			// Validate parent entry exists
105
			$entry = EntryManager::fetch($entryId);
106 View Code Duplication
			if ($entry == null || count($entry) != 1) {
107
				$this->_Result['error'] = __('Parent entry not found');
108
				return;
109
			}
110
			if (is_array($entry)) {
111
				$entry = $entry[0];
112
			}
113 View Code Duplication
			if ($entry->get('section_id') != $parentField->get('parent_section')) {
114
				$this->_Result['error'] = __('Field and entry do not belong together');
115
				return;
116
			}
117
			$entryData = $entry->getData();
118
			
119
			// Perform operation, if needed
120
			if ($operator) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $operator of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
121
				$opEntries = array_filter(explode(',', $entryData[$parentFieldId]['entries']));
122
				if ($operator === '+') {
123
					$opEntries[] = $entriesId[0];
124
				} else if ($operator === '-') {
125
					$opEntries = array_filter($opEntries, function ($item) use ($entriesId) {
126
						return General::intval($item) !== $entriesId[0];
127
					});
128
				}
129
				$entriesId = $opEntries;
130
				unset($opEntries);
131
			}
132
			
133
			// Validate timestamp
134
			if (!$this->validateTimestamp($entryId, true)) {
135
				return;
136
			}
137
			
138
			// set new data
139
			$entryData[$parentFieldId]['entries'] = empty($entriesId) ? null : implode(',', $entriesId);
140
			
141
			// check if data are valid
142
			$resMessage = null;
143
			$res = $parentField->checkPostFieldData(
144
				$entryData[$parentFieldId],
145
				$resMessage,
146
				$entryId
147
			);
148
			if ($res != Field::__OK__) {
149
				$this->_Result['error'] = $resMessage;
150
				return;
151
			}
152
			
153
			// save the new data
154
			$entry->setData($parentFieldId, $entryData[$parentFieldId]);
155
			if (!$entry->commit()) {
156
				$this->_Result['error'] = __('Could not save entry');
157
				return;
158
			}
159
			
160
			$this->_Result['entry-id'] = $entryId;
161
			$this->_Result['ok'] = true;
162
			$this->_Result['entries'] = $entryData[$parentFieldId]['entries'];
163
			$this->_Result['timestamp'] = DateTimeObj::format($entry->get('modification_date'), 'c');
164
		}
165
		
166
		protected function validateTimestamp($entry_id, $checkMissing = false)
167
		{
168
			if ($checkMissing && !isset($_POST['timestamp'])) {
169
				$this->_Result['error'] = __('The entry could not be saved due to conflicting changes');
170
				return false;
171
			} elseif (isset($_POST['timestamp'])) {
172
				$tv = new TimestampValidator('entries');
173
				if (!$tv->check($entry_id, $_POST['timestamp'])) {
174
					$this->_Result['error'] = __('The entry could not be saved due to conflicting changes');
175
					return false;
176
				}
177
			}
178
			return true;
179
		}
180
	}
181