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  <li>
38  <element />
39  </li>
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  }
103  $deleteNode = TRUE;
104  } else {
105  if (!$this->model->additionalIsSet($nodeName)) {
106  $deleteNode = TRUE;
107  }
108  }
109  break;
110  case 'legend':
111  if (!strrchr(get_class($this), 'AdditionalElement')) {
112  if ($this->model->additionalIsSet($nodeName)) {
113  $this->replaceNodeWithFragment($dom, $node, $this->getAdditional('legend'));
114  }
115  $deleteNode = TRUE;
116  }
117  break;
118  case 'inputvalue':
119  if (array_key_exists('checked', $this->model->getAllowedAttributes())) {
120  if (!$this->model->hasAttribute('checked')) {
121  $emptyElement = TRUE;
122  }
123  } elseif (array_key_exists('selected', $this->model->getAllowedAttributes()) && !$this->model->hasAttribute('selected')) {
124  $emptyElement = TRUE;
125  } else {
126  $inputValue = $this->getInputValue();
127  if ($inputValue != '') {
128  $replaceNode = $dom->createTextNode($this->getInputValue());
129  $node->parentNode->insertBefore($replaceNode, $node);
130  } else {
131  $emptyElement = TRUE;
132  }
133  }
134  $deleteNode = TRUE;
135  break;
136  case 'labelvalue':
137 
138  case 'legendvalue':
139  $replaceNode = $dom->createTextNode($this->getAdditionalValue());
140  $node->parentNode->insertBefore($replaceNode, $node);
141  $deleteNode = TRUE;
142  break;
143  }
144  break;
145  }
146  // Parse the child nodes of this node if available
147  if ($node->hasChildNodes()) {
148  $emptyElement = $this->parseXML($dom, $node, $emptyElement);
149  }
150  // Get the current node for deletion if replaced. We need this because nextSibling can be empty
151  $oldNode = $node;
152  // Go to next sibling to parse
153  $node = $node->nextSibling;
154  // Delete the old node. This can only be done after going to the next sibling
155  if ($deleteNode) {
156  $oldNode->parentNode->removeChild($oldNode);
157  }
158  }
159  return $emptyElement;
160  }
161 
169  public function render($type = 'element', $returnFirstChild = TRUE) {
170  // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
171  $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
172  $useLayout = $this->getLayout((string) $type);
173  $dom = new \DOMDocument('1.0', 'utf-8');
174  $dom->formatOutput = TRUE;
175  $dom->preserveWhiteSpace = FALSE;
176  $dom->loadXML($useLayout);
177  $emptyElement = $this->parseXML($dom, $dom);
178  libxml_disable_entity_loader($previousValueOfEntityLoader);
179  if ($emptyElement) {
180  return NULL;
181  } elseif ($returnFirstChild) {
182  return $dom->firstChild;
183  } else {
184  return $dom;
185  }
186  }
187 
194  public function getLayout($type) {
196  $layoutHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\Layout');
197  switch ($type) {
198  case 'element':
199  $layoutDefault = $this->layout;
200  $layout = $layoutHandler->getLayoutByObject(\TYPO3\CMS\Form\Utility\FormUtility::getInstance()->getLastPartOfClassName($this, TRUE), $layoutDefault);
201  break;
202  case 'elementWrap':
203  $layoutDefault = $this->elementWrap;
204  $elementWrap = $layoutHandler->getLayoutByObject($type, $layoutDefault);
205  $layout = str_replace('<element />', $this->getLayout('element'), $elementWrap);
206  break;
207  case 'containerWrap':
208  $layoutDefault = $this->containerWrap;
209  $layout = $layoutHandler->getLayoutByObject($type, $layoutDefault);
210  break;
211  }
212  return $layout;
213  }
214 
223  public function replaceNodeWithFragment(\DOMDocument $dom, \DOMNode $node, \DOMNode $value) {
224  $replaceNode = $dom->createDocumentFragment();
225  $domNode = $dom->importNode($value, TRUE);
226  $replaceNode->appendChild($domNode);
227  $node->parentNode->insertBefore($replaceNode, $node);
228  }
229 
237  public function setAttributes(\DOMElement $domElement) {
238  $attributes = $this->model->getAttributes();
239  foreach ($attributes as $key => $attribute) {
240  if (!empty($attribute)) {
241  $value = htmlspecialchars($attribute->getValue(), ENT_QUOTES);
242  if ($value !== '') {
243  $domElement->setAttribute($key, $value);
244  }
245  }
246  }
247  }
248 
256  public function setAttribute(\DOMElement $domElement, $key) {
257  $attribute = htmlspecialchars($this->model->getAttributeValue((string) $key), ENT_QUOTES);
258  if (!empty($attribute)) {
259  $domElement->setAttribute($key, $attribute);
260  }
261  }
262 
272  public function setAttributeWithValueofOtherAttribute(\DOMElement $domElement, $key, $other) {
273  $attribute = htmlspecialchars($this->model->getAttributeValue((string) $other), ENT_QUOTES);
274  if (!empty($attribute)) {
275  $domElement->setAttribute($key, $attribute);
276  }
277  }
278 
285  protected function createAdditional($class) {
286  $class = strtolower((string) $class);
287  $className = 'TYPO3\\CMS\\Form\\View\\Confirmation\\Additional\\' . ucfirst($class) . 'AdditionalElementView';
288  return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($className, $this->model);
289  }
290 
297  public function getAdditional($key) {
298  $additional = $this->createAdditional($key);
299  return $additional->render();
300  }
301 
305  public function getInputValue() {
306  if (method_exists($this->model, 'getData')) {
307  $inputValue = $this->model->getData();
308  } else {
309  $inputValue = $this->model->getAttributeValue('value');
310  }
311  $inputValue = htmlspecialchars($inputValue, ENT_QUOTES);
312  $inputValue = nl2br($inputValue, TRUE);
313  return $inputValue;
314  }
315 
322  public function getElementWrapId() {
323  $elementId = (int)$this->model->getElementId();
324  $wrapId = 'csc-form-' . $elementId;
325  return $wrapId;
326  }
327 
334  public function getElementWrapType() {
335  $elementType = strtolower(\TYPO3\CMS\Form\Utility\FormUtility::getInstance()->getLastPartOfClassName($this->model));
336  $wrapType = 'csc-form-element csc-form-element-' . $elementType;
337  return $wrapType;
338  }
339 
345  public function getElementWraps() {
346  $wraps = array(
347  $this->getElementWrapId(),
348  $this->getElementWrapType()
349  );
350  return implode(' ', $wraps);
351  }
352 
360  public function noWrap() {
361  return $this->noWrap;
362  }
363 
364 }
setAttributeWithValueofOtherAttribute(\DOMElement $domElement, $key, $other)
replaceNodeWithFragment(\DOMDocument $dom, \DOMNode $node, \DOMNode $value)
parseXML(\DOMDocument $dom, \DOMNode $reference, $emptyElement=FALSE)