Completed
Push — dev ( 9c7928...5573ef )
by Nicolas
02:08
created

ERFXSLTUTilities::fieldToXML()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
rs 9.4285
cc 1
eloc 16
nc 1
nop 1
1
<?php
2
	/*
3
	Copyright: Deux Huit Huit 2016
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
	class ERFXSLTUTilities {
10
		public static function processXSLT($parentField, $entry, $entrySectionHandle, $entryFields, $mode, $debug = false, $select = 'entry')
11
		{
12
			$date = new DateTime();
13
			$params = array(
14
				'today' => $date->format('Y-m-d'),
15
				'current-time' => $date->format('H:i'),
16
				'this-year' => $date->format('Y'),
17
				'this-month' => $date->format('m'),
18
				'this-day' => $date->format('d'),
19
				'timezone' => $date->format('P'),
20
				'website-name' => Symphony::Configuration()->get('sitename', 'general'),
21
				'root' => URL,
22
				'workspace' => URL . '/workspace',
23
				'http-host' => HTTP_HOST
24
			);
25
			
26
			$xslFilePath = WORKSPACE . '/er-templates/' . $entrySectionHandle . '.xsl';
27
			if (!!@file_exists($xslFilePath)) {
28
				$xmlData = new XMLElement('data');
29
				$xmlData->setIncludeHeader(true);
30
				
31
				// params
32
				$xmlData->appendChild(self::getXmlParams($params));
33
				
34
				// entry data
35
				if ($entry) {
36
					$includedElements = FieldEntry_relationship::parseElements($parentField);
37
					$xmlData->appendChild(self::entryToXML($entry, $entrySectionHandle, $includedElements, $entryFields));
38
				}
39
				
40
				// field data
41
				$xmlData->appendChild(self::fieldToXML($parentField));
42
				
43
				// process XSLT
44
				$indent = false;
45
				$mode = $parentField->get($mode);
46
				if ($debug) {
47
					$mode = 'debug';
48
				}
49
				if ($mode == 'debug') {
50
					$indent = true;
51
				}
52
				$xmlMode = empty($mode) ? '' : 'mode="' . $mode . '"';
53
				$xmlString = $xmlData->generate($indent, 0);
54
				$xsl = '<?xml version="1.0" encoding="UTF-8"?>
55
				<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
56
					<xsl:import href="' . str_replace('\\', '/',  $xslFilePath) . '"/>
57
					<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no" />
58
					<xsl:template match="/">
59
						<xsl:apply-templates select="/data" ' . $xmlMode . ' />
60
					</xsl:template>
61
					<xsl:template match="/data" ' . $xmlMode . '>
62
						<xsl:apply-templates select="' . $select . '" ' . $xmlMode . ' />
63
					</xsl:template>
64
					<xsl:template match="/data" mode="debug">
65
						<xsl:copy-of select="/" />
66
					</xsl:template>
67
				</xsl:stylesheet>';
68
				$xslt = new XsltProcess();
69
				$result = $xslt->process($xmlString, $xsl, $params);
70
				
71
				if ($mode == 'debug') {
72
					$result = '<pre><code>' .
73
						str_replace('<', '&lt;', str_replace('>', '&gt;', $xmlString)) .
74
						'</code></pre>';
75
				}
76
				
77
				if ($xslt->isErrors()) {
78
					$error = $xslt->getError();
79
					$result = $error[1]['message'];
80
				}
81
				
82
				if (General::strlen(trim($result)) > 0) {
83
					return $result;
84
				}
85
			}
86
			return null;
87
		}
88
		
89
		public static function getXmlParams(array $params) {
90
			$xmlparams = new XMLElement('params');
91
			foreach ($params as $key => $value) {
92
				$xmlparams->appendChild(new XMLElement($key, $value));
93
			}
94
			return $xmlparams;
95
		}
96
		
97
		public static function fieldToXML($field) {
98
			// field data
99
			$xmlField = new XMLElement('field');
100
			$xmlField->setAttribute('id', $field->get('id'));
101
			$xmlField->setAttribute('handle', $field->get('element_name'));
102
			$xmlField->appendChild(new XMLElement('allow-new', $field->get('allow_new')));
103
			$xmlField->appendChild(new XMLElement('allow-edit', $field->get('allow_edit')));
104
			$xmlField->appendChild(new XMLElement('allow-delete', $field->get('allow_delete')));
105
			$xmlField->appendChild(new XMLElement('allow-link', $field->get('allow_link')));
106
			$xmlField->appendChild(new XMLElement('allow-collapse', $field->get('allow_collapse')));
107
			$xmlField->appendChild(new XMLElement('show-header', $field->get('show_header')));
108
			$xmlField->appendChild(new XMLElement('show-association', $field->get('show_association')));
109
			$xmlField->appendChild(new XMLElement('deepness', $field->get('deepness')));
110
			$xmlField->appendChild(new XMLElement('required', $field->get('required')));
111
			$xmlField->appendChild(new XMLElement('min-entries', $field->get('min_entries')));
112
			$xmlField->appendChild(new XMLElement('max-entries', $field->get('max_entries')));
113
			return $xmlField;
114
		}
115
		
116
		public static function entryToXML($entry, $entrySectionHandle, $includedElements, $entryFields) {
117
			$entryData = $entry->getData();
118
			$entryId = General::intval($entry->get('id'));
119
			$xml = new XMLElement('entry');
120
			$xml->setAttribute('id', $entryId);
121
			if (!empty($entryData)) {
122
				foreach ($entryData as $fieldId => $data) {
123
					$filteredData = array_filter($data, function ($value) {
124
						return $value != null;
125
					});
126
					if (empty($filteredData)) {
127
						continue;
128
					}
129
					$field = $entryFields[$fieldId];
130
					$fieldName = $field->get('element_name');
131
					$fieldIncludedElement = $includedElements[$entrySectionHandle];
132
					
133
					try {
134
						if (FieldEntry_relationship::isFieldIncluded($fieldName, $fieldIncludedElement)) {
135
							$parentIncludableElement = FieldEntry_relationship::getSectionElementName($fieldName, $fieldIncludedElement);
136
							$parentIncludableElementMode = FieldEntry_relationship::extractMode($fieldName, $parentIncludableElement);
137
							
138
							// Special treatments for ERF
139
							if ($field instanceof FieldEntry_relationship) {
140
								// Increment recursive level
141
								$field->recursiveLevel = $recursiveLevel + 1;
0 ignored issues
show
Bug introduced by
The property recursiveLevel cannot be accessed from this context as it is declared protected in class FieldEntry_relationship.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
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...
142
								$field->recursiveDeepness = $deepness;
0 ignored issues
show
Bug introduced by
The property recursiveDeepness cannot be accessed from this context as it is declared protected in class FieldEntry_relationship.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
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...
143
							}
144
							
145 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...
146
								$submodes = array_map(function ($fieldIncludableElement) use ($fieldName) {
147
									return FieldEntry_relationship::extractMode($fieldName, $fieldIncludableElement);
148
								}, $field->fetchIncludableElements());
149
							}
150
							else {
151
								$submodes = array($parentIncludableElementMode);
152
							}
153
							
154
							foreach ($submodes as $submode) {
155
								$field->appendFormattedElement($xml, $filteredData, false, $submode, $entryId);
156
							}
157
						}
158
					}
159
					catch (Exception $ex) {
160
						$xml->appendChild(new XMLElement('error', $ex->getMessage() . ' on ' . $ex->getLine() . ' of file ' . $ex->getFile()));
161
					}
162
				}
163
			}
164
			return $xml;
165
		}
166
	}