TYPO3 CMS  TYPO3_6-2
AbstractElementView.php
Go to the documentation of this file.
1 <?php
3 
22 abstract class AbstractElementView {
23 
29  protected $model;
30 
36  protected $elementWrap = '
37  <tr>
38  <element />
39  </tr>
40  ';
41 
48  protected $noWrap = FALSE;
49 
55  public function __construct($model) {
56  $this->model = $model;
57  }
58 
70  protected function parseXML(\DOMDocument $dom, \DOMNode $reference, $emptyElement = FALSE) {
71  $node = $reference->firstChild;
72  while (!is_null($node)) {
73  $deleteNode = FALSE;
74  $nodeType = $node->nodeType;
75  $nodeName = $node->nodeName;
76  switch ($nodeType) {
77  case XML_TEXT_NODE:
78  break;
79  case XML_ELEMENT_NODE:
80  switch ($nodeName) {
81  case 'containerWrap':
82  $containerWrap = $this->render('containerWrap');
83  if ($containerWrap) {
84  $this->replaceNodeWithFragment($dom, $node, $containerWrap);
85  } else {
86  $emptyElement = TRUE;
87  }
88  $deleteNode = TRUE;
89  break;
90  case 'elements':
91  $replaceNode = $this->getChildElements($dom);
92  if ($replaceNode) {
93  $node->parentNode->replaceChild($replaceNode, $node);
94  } else {
95  $emptyElement = TRUE;
96  }
97  break;
98  case 'label':
99  if (!strrchr(get_class($this), 'AdditionalElement')) {
100  if ($this->model->additionalIsSet($nodeName)) {
101  $this->replaceNodeWithFragment($dom, $node, $this->getAdditional('label'));
102  } else {
103  $replaceNode = $dom->createTextNode(htmlspecialchars($this->model->getName()));
104  $node->parentNode->insertBefore($replaceNode, $node);
105  }
106  $deleteNode = TRUE;
107  }
108  break;
109  case 'legend':
110  if (!strrchr(get_class($this), 'AdditionalElement')) {
111  if ($this->model->additionalIsSet($nodeName)) {
112  $this->replaceNodeWithFragment($dom, $node, $this->getAdditional('legend'));
113  }
114  $deleteNode = TRUE;
115  }
116  break;
117  case 'inputvalue':
118  if (
119  (array_key_exists('checked', $this->model->getAllowedAttributes()) && !$this->model->hasAttribute('checked'))
120  || (array_key_exists('selected', $this->model->getAllowedAttributes()) && !$this->model->hasAttribute('selected'))
121  ) {
122  $emptyElement = TRUE;
123  } else {
124  $inputValue = $this->getInputValue();
125  if ($inputValue != '') {
126  $replaceNode = $dom->createTextNode($this->getInputValue());
127  $node->parentNode->insertBefore($replaceNode, $node);
128  }
129  }
130  $deleteNode = TRUE;
131  break;
132  case 'labelvalue':
133 
134  case 'legendvalue':
135  $replaceNode = $dom->createTextNode($this->getAdditionalValue());
136  $node->parentNode->insertBefore($replaceNode, $node);
137  $deleteNode = TRUE;
138  break;
139  }
140  break;
141  }
142  // Parse the child nodes of this node if available
143  if ($node->hasChildNodes()) {
144  $emptyElement = $this->parseXML($dom, $node, $emptyElement);
145  }
146  // Get the current node for deletion if replaced. We need this because nextSibling can be empty
147  $oldNode = $node;
148  // Go to next sibling to parse
149  $node = $node->nextSibling;
150  // Delete the old node. This can only be done after going to the next sibling
151  if ($deleteNode) {
152  $oldNode->parentNode->removeChild($oldNode);
153  }
154  }
155  return $emptyElement;
156  }
157 
165  public function render($type = 'element', $returnFirstChild = TRUE) {
166  // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
167  $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
168  $useLayout = $this->getLayout((string) $type);
169  $dom = new \DOMDocument('1.0', 'utf-8');
170  $dom->formatOutput = TRUE;
171  $dom->preserveWhiteSpace = FALSE;
172  $dom->loadXML($useLayout);
173  $emptyElement = $this->parseXML($dom, $dom);
174  libxml_disable_entity_loader($previousValueOfEntityLoader);
175  if ($emptyElement) {
176  return NULL;
177  } elseif ($returnFirstChild) {
178  return $dom->firstChild;
179  } else {
180  return $dom;
181  }
182  }
183 
190  public function getLayout($type) {
192  $layoutHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\Layout');
193  $layout = '';
194  switch ($type) {
195  case 'element':
196  $layoutDefault = $this->layout;
197  $layout = $layoutHandler->getLayoutByObject(\TYPO3\CMS\Form\Utility\FormUtility::getInstance()->getLastPartOfClassName($this, TRUE), $layoutDefault);
198  break;
199  case 'elementWrap':
200  $layoutDefault = $this->elementWrap;
201  $elementWrap = $layoutHandler->getLayoutByObject($type, $layoutDefault);
202  $layout = str_replace('<element />', $this->getLayout('element'), $elementWrap);
203  break;
204  case 'containerWrap':
205  $layoutDefault = $this->containerWrap;
206  $layout = $layoutHandler->getLayoutByObject($type, $layoutDefault);
207  break;
208  }
209  return $layout;
210  }
211 
220  public function replaceNodeWithFragment(\DOMDocument $dom, \DOMNode $node, \DOMNode $value) {
221  $replaceNode = $dom->createDocumentFragment();
222  $domNode = $dom->importNode($value, TRUE);
223  $replaceNode->appendChild($domNode);
224  $node->parentNode->insertBefore($replaceNode, $node);
225  }
226 
234  public function setAttributes(\DOMElement $domElement) {
235  $attributes = $this->model->getAttributes();
236  foreach ($attributes as $key => $attribute) {
237  if (!empty($attribute)) {
238  $value = htmlspecialchars($attribute->getValue(), ENT_QUOTES);
239  if ($value !== '') {
240  $domElement->setAttribute($key, $value);
241  }
242  }
243  }
244  }
245 
253  public function setAttribute(\DOMElement $domElement, $key) {
254  $value = htmlspecialchars($this->model->getAttributeValue((string) $key), ENT_QUOTES);
255  if ($value !== '') {
256  $domElement->setAttribute($key, $value);
257  }
258  }
259 
269  public function setAttributeWithValueofOtherAttribute(\DOMElement $domElement, $key, $other) {
270  $value = htmlspecialchars($this->model->getAttributeValue((string) $other), ENT_QUOTES);
271  if ($value !== '') {
272  $domElement->setAttribute($key, $value);
273  }
274  }
275 
282  protected function createAdditional($class) {
283  $class = strtolower((string) $class);
284  $className = 'TYPO3\\CMS\\Form\\View\\Mail\\Html\\Additional\\' . ucfirst($class) . 'AdditionalElementView';
285  return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($className, $this->model);
286  }
287 
294  public function getAdditional($key) {
295  $additional = $this->createAdditional($key);
296  return $additional->render();
297  }
298 
302  public function getInputValue() {
303  if (method_exists($this->model, 'getData')) {
304  $inputValue = $this->model->getData();
305  } else {
306  $inputValue = $this->model->getAttributeValue('value');
307  }
308 
309  $inputValue = htmlspecialchars($inputValue, ENT_QUOTES);
310  $inputValue = nl2br($inputValue, TRUE);
311  return $inputValue;
312  }
313 
320  public function getElementWrapId() {
321  $elementId = (int)$this->model->getElementId();
322  $wrapId = 'csc-form-' . $elementId;
323  return $wrapId;
324  }
325 
332  public function getElementWrapType() {
333  $elementType = strtolower(\TYPO3\CMS\Form\Utility\FormUtility::getInstance()->getLastPartOfClassName($this->model));
334  $wrapType = 'csc-form-element csc-form-element-' . $elementType;
335  return $wrapType;
336  }
337 
343  public function getElementWraps() {
344  $wraps = array(
345  $this->getElementWrapId(),
346  $this->getElementWrapType()
347  );
348  return implode(' ', $wraps);
349  }
350 
358  public function noWrap() {
359  return $this->noWrap;
360  }
361 
362 }
replaceNodeWithFragment(\DOMDocument $dom, \DOMNode $node, \DOMNode $value)
parseXML(\DOMDocument $dom, \DOMNode $reference, $emptyElement=FALSE)
setAttributeWithValueofOtherAttribute(\DOMElement $domElement, $key, $other)