Completed
Push — dev ( 542d9d...ce2181 )
by Nicolas
01:48
created

contentExtensionEntry_Relationship_FieldRender::parseIncludedElements()   C

Complexity

Conditions 8
Paths 2

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 31
rs 5.3846
cc 8
eloc 19
nc 2
nop 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A contentExtensionEntry_Relationship_FieldRender::getXmlParams() 0 8 2
1
<?php
2
	/*
3
	Copyright: Deux Huit Huit 2014
4
	LICENCE: MIT http://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.xmlpage.php');
10
	require_once(EXTENSIONS . '/entry_relationship_field/lib/class.cacheablefetch.php');
11
12
	class contentExtensionEntry_Relationship_FieldRender extends XMLPage {
13
		
14
		const NUMBER_OF_URL_PARAMETERS = 2;
15
16
		private $sectionManager;
17
		private $fieldManager;
18
		private $entryManager;
19
		private $params;
20
		
21
		public function __construct() {
22
			parent::__construct();
23
			$this->sectionManager = new CacheableFetch('SectionManager');
24
			$this->fieldManager = new CacheableFetch('FieldManager');
25
			$this->entryManager = new CacheableFetch('EntryManager');
26
			$date = new DateTime();
27
			$this->params = array(
28
				'today' => $date->format('Y-m-d'),
29
				'current-time' => $date->format('H:i'),
30
				'this-year' => $date->format('Y'),
31
				'this-month' => $date->format('m'),
32
				'this-day' => $date->format('d'),
33
				'timezone' => $date->format('P'),
34
				'website-name' => Symphony::Configuration()->get('sitename', 'general'),
35
				'root' => URL,
36
				'workspace' => URL . '/workspace',
37
				'http-host' => HTTP_HOST
38
			);
39
			// fix jquery
40
			$this->_Result->setIncludeHeader(false);
41
			$this->addHeaderToPage('Content-Type', 'text/html');
42
		}
43
		
44
		/**
45
		 *
46
		 * Builds the content view
47
		 */
48
		public function view() {
49
			// _context[0] => entry values
50
			// _context[1] => fieldId
51
			if (!is_array($this->_context) || empty($this->_context)) {
52
				$this->_Result->appendChild(new XMLElement('error', __('Parameters not found')));
53
				return;
54
			}
55
			else if (count($this->_context) < self::NUMBER_OF_URL_PARAMETERS) {
56
				$this->_Result->appendChild(new XMLElement('error', __('Not enough parameters')));
57
				return;
58
			}
59
			else if (count($this->_context) > self::NUMBER_OF_URL_PARAMETERS) {
60
				$this->_Result->appendChild(new XMLElement('error', __('Too many parameters')));
61
				return;
62
			}
63
			
64
			$entriesId = explode(',', MySQL::cleanValue($this->_context[0]));
65
			$entriesId = array_map(array('General', 'intval'), $entriesId);
66 View Code Duplication
			if (!is_array($entriesId) || empty($entriesId)) {
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...
67
				$this->_Result->appendChild(new XMLElement('error', __('No entry no found')));
68
				return;
69
			}
70
			
71
			$parentFieldId = General::intval($this->_context[1]);
72
			if ($parentFieldId < 1) {
73
				$this->_Result->appendChild(new XMLElement('error', __('Parent field id not valid')));
74
				return;
75
			}
76
			
77
			$parentField = $this->fieldManager->fetch($parentFieldId);
78 View Code Duplication
			if (!$parentField || empty($parentField)) {
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...
79
				$this->_Result->appendChild(new XMLElement('error', __('Parent field not found')));
80
				return;
81
			}
82
			
83
			if ($parentField->get('type') != 'entry_relationship') {
84
				$this->_Result->appendChild(new XMLElement('error', __('Parent field is `%s`, not `entry_relationship`', array($parentField->get('type')))));
85
				return;
86
			}
87
			
88
			$includedElements = FieldEntry_relationship::parseElements($parentField);
89
			$xmlParams = self::getXmlParams();
90
			
91
			// Get entries one by one since they may belong to
92
			// different sections, which prevents us from
93
			// passing an array of entryId.
94
			foreach ($entriesId as $key => $entryId) {
95
				$entry = $this->entryManager->fetch($entryId);
96
				if (empty($entry)) {
97
					$li = new XMLElement('li', null, array(
98
						'data-entry-id' => $entryId
99
					));
100
					$header = new XMLElement('header', null, array('class' => 'frame-header'));
101
					$title = new XMLElement('h4');
102
					$title->appendChild(new XMLElement('strong', __('Entry %s not found', array($entryId))));
103
					$header->appendChild($title);
104
					$options = new XMLElement('div', null, array('class' => 'destructor'));
105 View Code Duplication
					if ($parentField->is('allow_link')) {
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...
106
						$options->appendChild(new XMLElement('a', __('Un-link'), array(
107
							'class' => 'unlink',
108
							'data-unlink' => $entryId,
109
						)));
110
					}
111
					$header->appendChild($options);
112
					$li->appendChild($header);
113
					$this->_Result->appendChild($li);
114
				} else {
115
					$entry = $entry[0];
116
					$entryData = $entry->getData();
117
					$entrySection = $this->sectionManager->fetch($entry->get('section_id'));
118
					$entryVisibleFields = $entrySection->fetchVisibleColumns();
119
					$entryFields = $entrySection->fetchFields();
120
					$entrySectionHandle = $this->getSectionName($entry, 'handle');
121
					
122
					$li = new XMLElement('li', null, array(
123
						'data-entry-id' => $entryId,
124
						'data-section' => $entrySectionHandle,
125
						'data-section-id' => $entrySection->get('id'),
126
					));
127
					$header = new XMLElement('header', null, array('class' => 'frame-header'));
128
					$title = new XMLElement('h4');
129
					$title->appendChild(new XMLElement('strong', $this->getEntryTitle($entry, $entryVisibleFields, $entryFields)));
130
					$title->appendChild(new XMLElement('span', $this->getSectionName($entry)));
131
					$header->appendChild($title);
132
					$options = new XMLElement('div', null, array('class' => 'destructor'));
133
					if ($parentField->is('allow_edit')) {
134
						$title->setAttribute('data-edit', $entryId);
135
						$options->appendChild(new XMLElement('a', __('Edit'), array(
136
							'class' => 'edit',
137
							'data-edit' => $entryId,
138
						)));
139
					}
140
					if ($parentField->is('allow_delete')) {
141
						$options->appendChild(new XMLElement('a', __('Delete'), array(
142
							'class' => 'delete',
143
							'data-delete' => $entryId,
144
						)));
145
					}
146
					if ($parentField->is('allow_link')) {
147
						$options->appendChild(new XMLElement('a', __('Replace'), array(
148
							'class' => 'unlink',
149
							'data-replace' => $entryId,
150
						)));
151
					}
152 View Code Duplication
					if ($parentField->is('allow_delete') || $parentField->is('allow_link')) {
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...
153
						$options->appendChild(new XMLElement('a', __('Un-link'), array(
154
							'class' => 'unlink',
155
							'data-unlink' => $entryId,
156
						)));
157
					}
158
					$header->appendChild($options);
159
					$li->appendChild($header);
160
					
161
					$xslFilePath = WORKSPACE . '/er-templates/' . $entrySectionHandle . '.xsl';
162
					
163
					if (!empty($entryData) && !!@file_exists($xslFilePath)) {
164
						$xmlData = new XMLElement('data');
165
						$xmlData->setIncludeHeader(true);
166
						$xml = new XMLElement('entry');
167
						$xml->setAttribute('id', $entryId);
168
						$xmlData->appendChild($xmlParams);
169
						$xmlData->appendChild($xml);
170
						foreach ($entryData as $fieldId => $data) {
171
							$filteredData = array_filter($data, function ($value) {
172
								return $value != null;
173
							});
174
							if (empty($filteredData)) {
175
								continue;
176
							}
177
							$field = $entryFields[$fieldId];
178
							$fieldName = $field->get('element_name');
179
							$fieldIncludedElement = $includedElements[$entrySectionHandle];
180
							
181
							try {
182
								if (FieldEntry_relationship::isFieldIncluded($fieldName, $fieldIncludedElement)) {
183
									$parentIncludableElement = FieldEntry_relationship::getSectionElementName($fieldName, $fieldIncludedElement);
184
									$parentIncludableElementMode = FieldEntry_relationship::extractMode($fieldName, $parentIncludableElement);
185
									
186
									// Special treatments for ERF
187
									if ($field instanceof FieldEntry_relationship) {
188
										// Increment recursive level
189
										$field->recursiveLevel = $recursiveLevel + 1;
0 ignored issues
show
Bug introduced by
The variable $recursiveLevel does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
190
										$field->recursiveDeepness = $deepness;
0 ignored issues
show
Bug introduced by
The variable $deepness does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
191
									}
192
									
193 View Code Duplication
									if ($parentIncludableElementMode == null) {
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...
194
										$submodes = array_map(function ($fieldIncludableElement) use ($fieldName) {
195
											return FieldEntry_relationship::extractMode($fieldName, $fieldIncludableElement);
196
										}, $field->fetchIncludableElements());
197
									}
198
									else {
199
										$submodes = array($parentIncludableElementMode);
200
									}
201
									
202
									foreach ($submodes as $submode) {
203
										$field->appendFormattedElement($xml, $filteredData, false, $submode, $entryId);
204
									}
205
								}
206
							}
207
							catch (Exception $ex) {
208
								$xml->appendChild(new XMLElement('error', $ex->getMessage() . ' on ' . $ex->getLine() . ' of file ' . $ex->getFile()));
209
							}
210
						}
211
						
212
						$indent = false;
213
						$mode = $parentField->get('mode');
214
						if (isset($_REQUEST['debug'])) {
215
							$mode = 'debug';
216
						}
217
						if ($mode == 'debug') {
218
							$indent = true;
219
						}
220
						$xmlMode = empty($mode) ? '' : 'mode="' . $mode . '"';
221
						$xmlString = $xmlData->generate($indent, 0);
222
						$xsl = '<?xml version="1.0" encoding="UTF-8"?>
223
						<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
224
							<xsl:import href="' . str_replace('\\', '/',  $xslFilePath) . '"/>
225
							<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no" />
226
							<xsl:template match="/">
227
								<xsl:apply-templates select="/data" ' . $xmlMode . ' />
228
							</xsl:template>
229
							<xsl:template match="/data" ' . $xmlMode . '>
230
								<xsl:apply-templates select="entry" ' . $xmlMode . ' />
231
							</xsl:template>
232
							<xsl:template match="/data" mode="debug">
233
								<xsl:copy-of select="/" />
234
							</xsl:template>
235
						</xsl:stylesheet>';
236
						$xslt = new XsltProcess();
237
						$result = $xslt->process($xmlString, $xsl, $this->params);
238
						
239
						if ($mode == 'debug') {
240
							$result = '<pre><code>' .
241
								str_replace('<', '&lt;', str_replace('>', '&gt;', $xmlString)) .
242
								'</code></pre>';
243
						}
244
						
245
						if ($xslt->isErrors()) {
246
							$error = $xslt->getError();
247
							$result = $error[1]['message'];
248
						}
249
						
250
						if (!!$xslt && strlen($result) > 0) {
251
							$content = new XMLElement('div', $result, array('class' => 'content'));
252
							$li->appendChild($content);
253
						}
254
					}
255
					
256
					$this->_Result->appendChild($li);
257
				}
258
				
259
			}
260
		}
261
		
262
		public function getSectionName($entry, $name = 'name') {
263
			$sectionId = $entry->get('section_id');
264
			return $this->sectionManager->fetch($sectionId)->get($name);
265
		}
266
		
267
		public function getEntryTitle($entry, $entryVisibleFields, $entryFields) {
268
			$data = $entry->getData();
269
			$field = empty($entryVisibleFields) ? $entryFields : $entryVisibleFields;
270
			if (is_array($field)) {
271
				$field = current($field);
272
			}
273
			
274
			if ($field == null) {
275
				return __('None');
276
			}
277
			
278
			return $field->prepareReadableValue($data[$field->get('id')], $entry->get('id'), true);
279
		}
280
		
281
		public function getXmlParams() {
282
			$params = new XMLElement('params');
283
			foreach ($this->params as $key => $value) {
284
				$params->appendChild(new XMLElement($key, $value));
285
			}
286
			
287
			return $params;
288
		}
289
	}