* Installer: Improved the installer module.
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / mod / class.tx_install_view.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2006-2007 Thomas Hempel (thomas@work.de)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 define('WARNING', 1);
29 define('FATAL', 2);
30
31 require_once(PATH_site.'t3lib/class.t3lib_parsehtml.php');
32
33 /**
34 * Contains all stuff that is needed to print out the results from the modules.
35 *
36 * $Id$
37 *
38 * @author Thomas Hempel <thomas@work.de>
39 * @author Sebastian Kurfuerst <sebastian@typo3.org>
40 * @author Ingo Renner <ingo@typo3.org>
41 */
42 class tx_install_view {
43 /**
44 * The local doc object
45 *
46 * @var template
47 */
48 private $doc = NULL;
49
50 /**
51 * The plain content section which is included in the doc
52 *
53 * @var string
54 */
55 private $content = '';
56
57 /**
58 * A read-only array with all allowed render methods
59 *
60 * @var array
61 */
62 private $availableRenderMethods = array('plain', 'html', 'errors', 'box', 'list', 'checklist', 'message', 'table', 'cell', 'image', 'form', 'formelement');
63
64 /**
65 * This holds all error messages that might occur during run time.
66 *
67 * @var array
68 */
69 private $errors = array ('general' => array(), 'fields' => array());
70
71 /**
72 * Contains the last message
73 *
74 * @var string
75 */
76 private $lastMessage = '';
77
78 /**
79 * parent tx_install object
80 *
81 * @var tx_install
82 */
83 private $pObj = NULL;
84
85 /**
86 * Last openend fieldset
87 *
88 * @var string
89 */
90 private $lastFieldset = NULL;
91
92 /**
93 * Constructor
94 *
95 * @return void
96 */
97 public function __construct() {
98 $this->doc = t3lib_div::makeInstance('bigDoc');
99 }
100
101 /**
102 * Initialisation
103 *
104 * TODO move this into the constructor
105 *
106 * @param object reference to "tx_install" object
107 */
108 public function init($pObj) {
109 $this->pObj = $pObj;
110 $this->doc->backPath = $this->pObj->getBackPath();
111 $this->doc->JScode .= '<script src="'.$this->doc->backPath.'contrib/prototype/prototype.js"></script>';
112 $this->doc->JScode .= '<script src="'.$this->doc->backPath.'contrib/scriptaculous/scriptaculous.js?load=effects,controls"></script>';
113 $this->doc->JScode .= '<script src="'.$this->pObj->getBasicsObject()->getInstallerWebPath().'mod/scripts.js"></script>';
114 $this->doc->styleSheetFile2 = t3lib_extMgm::extRelPath('install').'modules/setup/res/styles.css';
115 }
116
117 /**
118 * Returns the complete document with all content on it.
119 *
120 * @return string content
121 */
122 public function getDocCode() {
123 $this->content .= $this->doc->sectionEnd().
124 $this->doc->postCode.
125 $this->doc->endPageJS().
126 $this->doc->parseTime().
127 ($this->doc->form ? '</form>' : '');
128
129 $this->content .= '</html>';
130
131 return $this->doc->startPage('').$this->content;
132 }
133
134 /**
135 * Appends the given content as new section to the document.
136 *
137 * @param string The title of the new section
138 * @param string The content of the new section
139 * @return void
140 */
141 public function addContent($title, $content) {
142 $this->content .= $this->doc->section($title, $content);
143 }
144
145 /**
146 * Getter for private variable content
147 *
148 * @return string
149 */
150 public function getContent() {
151 return $this->content;
152 }
153
154 /**
155 * adds a message which will be displayed using a JS alert()
156 *
157 * @param string message to display
158 */
159 public function addJSmessage($message) {
160 $this->content = '<script language="javascript" type="text/javascript">alert(unescape(\''.rawurlencode($message).'\'));</script>' .$this->content;
161 }
162
163 /**
164 * adds javascript code
165 *
166 * @param string javascript code
167 */
168 public function addJS($js) {
169 $this->doc->JScodeArray[] = $js;
170 }
171
172
173 /**
174 * Renders an option from a module. This method checks if an option should be
175 * displayed and how it should be rendered.
176 *
177 * @param string option name
178 * @param array option configuration
179 * @param boolean whether the configuration shall be returned or not
180 * @return mixed
181 */
182 public function renderOption($optionName, $optionConfig, $returnConfig = false) {
183 $basicsObj = $this->pObj->getBasicsObject();
184
185 if(isset($optionConfig['displayFunc'])) {
186 if(!$basicsObj->executeMethod($optionConfig['displayFunc'])) {
187 return false;
188 }
189 }
190
191 // get the value of the field. Basically, the value of this field is defined by the field value.
192 $value = $optionConfig['value'];
193
194 // load value from localconfCache
195 if(substr($value, 0, 3) == 'LC:') {
196 $value = $basicsObj->getLocalconfValue(substr($value, 3));
197 }
198
199 // if a userfunction is set, call it and send the current value as argument
200 if(isset($optionConfig['valueFunc']) && !empty($optionConfig['valueFunc'])) {
201 // $value = t3lib_div::callUserFunction($optionConfig['valueFunc'], $value, $this);
202 $value = $basicsObj->executeMethod($optionConfig['valueFunc'], $value);
203 }
204
205 // if the value is empty now, set it to the default value
206 if(empty($value)) {
207 $value = $optionConfig['default'];
208 }
209
210 $renderConfig = array (
211 'elementType' => $optionConfig['elementType'],
212 'label' => $optionConfig['title'],
213 'options' => array(
214 'value' => $value,
215 'id' => $optionName,
216 'name' => $optionName
217 )
218 );
219
220 if(isset($optionConfig['overruleOptions']) && is_array($optionConfig['overruleOptions'])) {
221 $renderConfig['options'] = t3lib_div::array_merge_recursive_overrule($renderConfig['options'], $optionConfig['overruleOptions']);
222 }
223
224 if($returnConfig) {
225 return array('type' => 'formelement', 'value' => $renderConfig);
226 } else {
227 return $this->renderFormelement($renderConfig);
228 }
229 }
230
231
232 /**
233 * RENDER-OBJECT
234 *
235 * Render a single element. This method is a dispatcher to more methods
236 *
237 * Format:
238 * type => $availableRenderMethods
239 * value => RENDER-OBJECT
240 *
241 * @param array single element to render. array ( 'type' => ..., 'value' => ...)
242 * @return string HTML output
243 */
244 public function render($element) {
245 $content = '';
246
247 if(is_array($element)) {
248 // look for the keys "value" and "type" and render them
249 if(isset($element['value']) && $element['type']) {
250 $data = $element['value'];
251 $type = $element['type'];
252
253 if(!in_array($type, $this->availableRenderMethods)){
254 $type = 'list';
255 }
256 $renderMethod = 'render'.ucfirst($type);
257
258 if(method_exists($this, $renderMethod)) {
259 $content = $this->$renderMethod($data);
260 } else {
261 $content = sprintf($this->pObj->getBasicsObject()->getLabel('no_method'), $type);
262 }
263 } else {
264 // if those elements where not found, try to render each single element
265 foreach ($element as $subElement) {
266 $content .= $this->render($subElement);
267 }
268 }
269 } else {
270 $content = $this->renderPlain($element);
271 }
272
273 return $content;
274 }
275
276 /**
277 * Renders the value wraped by a given tag
278 *
279 * @param string The HTML Tag (e.g. strong)
280 * @param string The wrapped value
281 * @return string
282 */
283 public function renderTag($tag, $value, $extraParameters = null) {
284 $tag = htmlspecialchars(strtolower($tag));
285 $result = '<'.$tag;
286 if (is_array($extraParameters)) {
287 foreach ($extraParameters as $paramName => $paramValue) {
288 $result .= ' '.$paramName.'="'.((empty($paramValue)) ? $paramName : $paramValue).'"';
289 }
290 }
291 $result .= '>'.$value.'</'.$tag.'>';
292 return $result;
293 }
294
295
296 private function renderBox($data) {
297 $elementCode = '';
298 if (is_array($data['elements'])) {
299 foreach ($data['elements'] as $elementConfig) {
300 $elementCode .= $this->render($elementConfig);
301 }
302 }
303
304 return $this->renderTag('div', $elementCode, array('class' => $data['class'], 'id' => $data['id']));
305 }
306
307
308 /**
309 * Returns a box with all errors requested. Which errors are returned depends on the mode the method
310 * is called with.
311 * Mode can be "general" or "fields". If mode is "field", a fieldname has to be given. The method will
312 * return all errors for this field.
313 *
314 * @param boolean whether headers should be rendered or not
315 * @param string mode, which errors should be returned (general, fields)
316 * @param string required field name
317 * @return mixed error messages if erros where found, false in case there were no errors
318 */
319 public function renderErrors($renderHeader = false, $mode = 'general', $reqFieldName = '') {
320 $hasErrors = false;
321 $content = '<div class="errors">';
322
323 if($renderHeader) {
324 $content .= '<div class="error-header">'.$this->pObj->getBasicsObject()->getLabel('msg_error_occured').'</div>';
325 }
326 $content .= '<ul>';
327
328 switch ($mode) {
329 case 'general':
330 if(is_array($this->errors['general'])) {
331 $hasErrors = true;
332
333 foreach ($this->errors['general'] as $errorItem) {
334 $content .= $this->renderErrorListItem($errorItem);
335 }
336 }
337 break;
338 case 'fields':
339 if(is_array($this->errors['fields'][$reqFieldName])) {
340 $hasErrors = true;
341
342 foreach ($this->errors['fields'][$reqFieldName] as $errorItem) {
343 $content .= $this->renderErrorListItem($errorItem);
344 }
345 }
346 break;
347 }
348
349 $content .= '</ul></div>';
350
351 $returnValue = $content;
352 if(!$hasErrors) {
353 $returnValue = $hasErrors;
354 }
355
356 return $returnValue;
357 }
358
359 /**
360 * Renders a list item for a single error. (<li>error message</li>)
361 *
362 * @param array $errorItem: The data of the error item (array('severity', 'message'))
363 * @return XHTML for a single list item <li>...
364 */
365 private function renderErrorListItem($errorItem) {
366 $result = '<li';
367
368 switch ($errorItem['severity']) {
369 case WARNING:
370 $result .= ' class="severity-warning"';
371 break;
372 case FATAL:
373 $result .= ' class="severity-fatal"';
374 break;
375 }
376
377 $result .= '>'.$this->renderError($errorItem).'</li>';
378 return $result;
379 }
380
381 /**
382 * Returns the HTML markup for a single error message, adds CSS class depending on the severity,
383 * adds a "FATAL" if we have a fatal error and wraps the message with <span></span>.
384 *
385 * @param array array with error severity and message.
386 * @return string The error message with HTML markup
387 */
388 private function renderError($error) {
389 $content = $error['message'];
390 $class = '';
391
392 switch($error['severity']) {
393 case WARNING:
394 $content = 'Warning! '.$content;
395 $class = ' error-warning';
396 break;
397 case FATAL:
398 $content = 'FATAL! '.$content;
399 $class = ' error-fatal';
400 break;
401 }
402
403 return '<span class="error'.$class.'">'.$content.'</span>';
404 }
405
406 /**
407 * Clears the local error array
408 *
409 */
410 public function clearErrors() {
411 $this->errors = array('general' => array(), 'fields' => array());
412 }
413
414
415 /**
416 * LIST
417 *
418 * Renders a list with UL and LI
419 *
420 * Format:
421 * type => list
422 * value => array (
423 * item1 => RENDER-OBJECT
424 * itemN => RENDER-OBJECT
425 * )
426 *
427 * @param array $data: An array of elements. Every element can be another render-objects
428 * @return string HTML output
429 */
430 private function renderList($data) {
431 $content = '';
432 if(count($data)) {
433 foreach ($data as $singleElement) {
434 switch ($singleElement['status']) {
435 case 'ok':
436 $style = 'list-style-image: url('.$this->pObj->getBasicsObject()->getInstallerWebPath().'imgs/icons/ok.png)';
437 break;
438 case 'warning':
439 $style = 'list-style-image: url('.$this->pObj->getBasicsObject()->getInstallerWebPath().'imgs/icons/warning.png)';
440 break;
441 default:
442 $style = '';
443 break;
444 }
445 $content .= $this->renderTag('li', $this->render($singleElement), array('style' => $style));
446 }
447
448 $content = $this->renderTag('ul', $content);
449 }
450
451 return $content;
452 }
453
454 /**
455 * RENDER-OBJECT::CHECKLIST
456 *
457 * Wraps the render-objects in the incomming array into table rows. The first column of each row
458 * will contain an image based on the property "severity" in the value of that row.
459 *
460 * Format:
461 * type => checklist
462 * value => array (
463 * row1 => RENDER-OBJECT::MESSAGE
464 * rowN => RENDER-OBJECT::MESSAGE
465 * )
466 *
467 * @patam array $data: An array of elements. Every element can be another render-objects
468 * @return string HTML output
469 */
470 private function renderChecklist($data) {
471 $tableData = array();
472
473 // FIXME: The path is very ugly. I think this is a sideeffect with the installation as local extension.
474 foreach ($data as $dataRow) {
475 $row = array(
476 '<img src="../../typo3conf/ext/install/imgs/'.$dataRow['value']['severity'].'.png" width="22" height="22" alt="'.$dataRow['value']['severity'].'" />',
477 $dataRow
478 );
479 $tableData[] = $row;
480 }
481
482 return $this->renderTable($tableData);
483 }
484
485 /**
486 * RENDER-OBJECT::IMAGE
487 *
488 * Renders an image from a given path
489 *
490 * Format:
491 * type => image
492 * value => array (
493 * path => string
494 * link => string
495 * )
496 *
497 * @param string $data: The content that should be rendered
498 * @return string HTML output
499 */
500 private function renderImage($data) {
501 $content = '';
502 $imgServerPath = t3lib_extMgm::extPath('install').$data['path'];
503
504 if(file_exists($imgServerPath)) {
505 $imgSize = getimagesize($imgServerPath);
506 $imgWebPath = $this->pObj->getBasicsObject()->getInstallerWebPath().$data['path'];
507 $imgTag = '<img src="'.$imgWebPath.'" '.$imgSize[3].' border="0" alt="'.$data['altTitle'].'" title="'.$data['altTitle'].'" />';
508
509 if(!empty($data['link'])) {
510 $imgTag = '<a href="'.$data['link'].'">'.$imgTag.'</a>';
511 }
512
513 $content = $imgTag;
514 } else {
515 $content = $data['default'];
516 }
517
518 return $content;
519 }
520
521 /**
522 * RENDER-OBJECT::HTML
523 *
524 * Renders HTML content
525 *
526 * Format:
527 * type => html
528 * value => array (
529 * template => HTML-Template
530 * marker => array with markers
531 * )
532 *
533 * @param string $data: The content that should be rendered
534 * @return string HTML output
535 */
536 private function renderHtml($data) {
537 $result = $data['template'];
538
539 if(is_array($data['marker'])) {
540 foreach ($data['marker'] as $marker => $value) {
541 $result = str_replace($marker, $value, $result);
542 }
543 }
544
545 if(is_array($data['subparts'])) {
546 foreach ($data['subparts'] as $subpart => $value) {
547 // var_dump(array($subpart, $value));
548 $result = t3lib_parsehtml::substituteSubpart($result, $subpart, $value, 0);
549 }
550 }
551
552 return $result;
553 }
554
555
556 /**
557 * RENDER-OBJECT::PLAIN
558 *
559 * Render plain text, only uses nl2br
560 *
561 * Format:
562 * type => plain
563 * value => string
564 *
565 * @param array $data: The content that should be rendered
566 * @return string HTML output
567 */
568 private function renderPlain($data) {
569 return nl2br($data);
570 }
571
572 /**
573 * RENDER-OBJECT::MESSAGE
574 *
575 * Render a message. A message has a severity, a label and an explanation
576 *
577 * Format:
578 * type => message
579 * value => array (
580 * severity => string
581 * label => string
582 * message => string
583 * addBR => boolean
584 * )
585 *
586 * @param array $data: The content that should be rendered
587 * @return string HTML output
588 */
589 private function renderMessage($data) {
590 $out = '<div class="installer-message'.(($data['severity']) ? ' severity_'.$data['severity'] : '').'">';
591 if ($data['label']) {
592 if (is_array($data['label'])) {
593 $tag = $data['label'][0];
594 $label = $data['label'][1];
595 $br = '';
596 } else {
597 $tag = 'strong';
598 $label = $data['label'];
599 $br = '<br />';
600 }
601 $out .= $this->renderTag($tag, $label, array('class' => 'message-header')).(($data['addBR'] === true) ? $br : '');
602 }
603 $out .= ($data['message']) ? $this->render($data['message']) : '';
604 $out .= '</div>';
605
606 return $out;
607 }
608
609 /**
610 * RENDER-OBJECT::FORM
611 *
612 * Renders a form that consits of a set of form-elements
613 *
614 * Format:
615 * type => form
616 * value => array (
617 * elements => array of RENDER-OBJECT
618 * hidden => array of name=>value pairs for hidden fields
619 * options => array (
620 * submit => string
621 * name => string
622 * id => string
623 * method => set(post,get)
624 * action => string
625 * )
626 * )
627 */
628 private function renderForm($data) {
629 $content = '<form'.
630 $this->getAttributeString('name', $data['options']['name']).
631 $this->getAttributeString('id', $data['options']['id']).
632 $this->getAttributeString('method', $data['options']['method'], 'post');
633
634 if(isset($data['options']['action']) && $data['options']['ajax'] == false) {
635 $content .= $this->getAttributeString('action', $data['options']['action']);
636 }
637 $content .= '>'."\n";
638
639 if(is_array($data['hidden'])) {
640 foreach ($data['hidden'] as $name => $value) {
641 $content .= '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
642 }
643 }
644
645 if(is_array($data['elements'])) {
646 foreach ($data['elements'] as $formElement) {
647 if(is_array($formElement) && $formElement['value']['elementType'] == 'password' && $formElement['value']['renderTwice']) {
648 $formElementName = $formElement['value']['options']['name'];
649 $formElement['value']['options']['name'] = $formElementName.'1';
650 $content .= $this->render($formElement);
651
652 $formElement['value']['options']['name'] = $formElementName.'2';
653 $formElement['value']['label'] = $formElement['value']['label'].'_2';
654 $content .= $this->render($formElement);
655 } else {
656 $content .= $this->render($formElement);
657 }
658 }
659 }
660
661 if (!is_null($this->lastFieldset)) {
662 $content .= '</fieldset>';
663 }
664
665 if ($data['options']['ajax'] == true) {
666 $content .= '<br /><button class="submit" onclick="return '.$data['options']['action'].'">'.$data['options']['submit'].'</button>';
667 } else {
668 $content .= '<br /><input type="submit" class="submit bg" value="'.$data['options']['submit'].'" />';
669 }
670
671 $content .= '</form>';
672
673 return $content;
674 }
675
676 /**
677 * RENDER-OBJECT::FORMELEMENT
678 *
679 * Renders any kind of form element
680 *
681 * Format:
682 * type => form_element
683 * value => array (
684 * elementType => set(input,text,submit,checkbox,radio,checkbox_group,radio_group)
685 * options => array with field settings (see field render methods) {
686 * name => string
687 * id => string
688 * label => string
689 * description => string
690 * }
691 * )
692 *
693 * @param string $data: The content that should be rendered
694 * @return string HTML output
695 */
696 public function renderFormelement($data) {
697 $content = '';
698 $basicsObj = $this->pObj->getBasicsObject();
699
700 if ($data['elementType'] == 'fieldset') {
701 if (!is_null($this->lastFieldset) && $this->lastFieldset != $data['label']) {
702 $content = '</fieldset>';
703 }
704
705 $content .= '<fieldset'.
706 (isset($data['class']) ? ' class="'.htmlspecialchars($data['class']).'"' : '').
707 '><legend>'.$data['label'].'</legend>';
708 $this->lastFieldset = $data['label'];
709 } else {
710
711 $elementRenderMethod = 'renderFormelement'.ucfirst($data['elementType']);
712 if(method_exists($this, $elementRenderMethod)) {
713 // set the value of the field from the environment if no error is recognized for it
714 // also set an error string if error was found
715 $errors = $this->getErrors();
716
717 if(!isset($errors['fields'][$data['options']['name']])) {
718 $environment = $this->pObj->getEnvironment();
719 if(!empty($environment[$data['options']['name']])) {
720 $data['options']['value'] = $environment[$data['options']['name']];
721 }
722 $errorStr = '';
723 } else {
724 $errorStr = $this->renderErrors(true, 'fields', $data['options']['name']);
725 }
726
727 // render the form element
728 $formElementCode = $this->$elementRenderMethod($data['options']);
729
730 // create a label if set in option
731 if(isset($data['label'])) {
732 $label = '<label for="'.$data['options']['id'].'">'.$basicsObj->getLabel($data['label'], $data['label']).'</label>';
733
734 // align the label (default is left)
735 switch ($data['label_align']) {
736 case 'top':
737 $formElementCode = $label.'<br />'.$errorStr.$formElementCode;
738 break;
739 case 'right':
740 $formElementCode = $errorStr.$formElementCode.$label;
741 break;
742 case 'left':
743 default:
744 $formElementCode = $label.$errorStr.$formElementCode;
745 }
746 }
747
748 // return the element wrapped in a div
749 $content = '<div class="formElement formElement'.ucfirst($data['elementType']).'">'.$formElementCode.'</div>';
750 }
751 }
752
753 return $content;
754 }
755
756 /**
757 * RENDER-OBJECT::FORMELEMENT::INPUT
758 *
759 * Renders a simple input field
760 *
761 * Format:
762 * type => input
763 * value => array (
764 * size => integer
765 * value => string
766 * )
767 */
768 private function renderFormelementInput($data) {
769 // debug($data, 'renderFormelement_input');
770 $content = '<input type="text"'.
771 $this->getAttributeString('name', $data['name']).
772 $this->getAttributeString('id', $data['id']).
773 $this->getAttributeString('size', $data['size'], 20).
774 $this->getAttributeString('value', $data['value'], '').
775 $this->getAttributeString('class', $data['class']).
776 ' />';
777
778 return $content;
779 }
780
781 /**
782 * RENDER-OBJECT::FORMELEMENT::PASSWORD
783 *
784 * Renders a password input field
785 *
786 * Format:
787 * type => password
788 * value => array (
789 * size => integer
790 * value => string
791 * )
792 */
793 private function renderFormelementPassword($data) {
794 // debug($data, 'renderFormelement_password');
795 $content = '<input type="password"'.
796 $this->getAttributeString('name', $data['name']).
797 $this->getAttributeString('id', $data['id']).
798 $this->getAttributeString('size', $data['size'], 20).
799 $this->getAttributeString('class', $data['class']).
800 ' />';
801
802 return $content;
803 }
804
805 /**
806 * RENDER-OBJECT::FORMELEMENT::SELECTBOX
807 *
808 * Renders a selectbox from a list of elements
809 *
810 * Format:
811 * type => selectbox
812 * value => array (
813 * size => integer
814 * selected => string
815 * elements => array with key => value pairs
816 * )
817 */
818 private function renderFormelementSelectbox($data) {
819 // t3lib_div::debug($data, 'renderFormelement_selectbox');
820 $basicsObj = $this->pObj->getBasicsObject();
821
822 $content = '<select'.
823 $this->getAttributeString('name', $data['name']).
824 $this->getAttributeString('id', $data['id']).
825 $this->getAttributeString('size', $data['size']).
826 '>';
827
828 if($data['empty'] == true) {
829 $content .= '<option value="">'.$data['empty'].'</option>';
830 }
831
832 if(is_string($data['elements'])) {
833 $data['elements'] = $basicsObj->executeMethod($data['elements']);
834 }
835
836 if(is_array($data['elements'])) {
837 foreach ($data['elements'] as $key => $value) {
838 if (!empty($data['default'])) {
839 if (empty($data['value'])) {
840 $selected = ($key == $data['default']);
841 } else {
842 $selected = ($key == $data['value']);
843 }
844 } else {
845 $selected = ($key == $data['value']);
846 }
847 $selected = ($selected == true) ? $this->getAttributeString('selected', 'selected') : '';
848 $content .= '<option value="'.$key.'"'.$selected.'>'.$value.'</option>'."\n";
849 }
850 }
851 $content .= '</select>';
852
853 return $content;
854 }
855
856 /**
857 * RENDER-OBJECT::FORMELEMENT::CHECKBOX
858 *
859 * Renders a checkbox
860 *
861 * Format:
862 * type => checkbox
863 * value => array (
864 * name => string
865 * id => string
866 * value => integer (0 | 1)
867 * )
868 *
869 * @param array $data: configuration array
870 * @return HTML
871 */
872 private function renderFormelementCheckbox($data) {
873 $content = '<input type="checkbox"'.
874 $this->getAttributeString('name', $data['name']).
875 $this->getAttributeString('id', $data['id']).
876 $this->getAttributeString('value', $data['name']);
877
878 $checked = $data['default'];
879
880 if (isset($data['value'])) {
881 $checked = $data['value'] == 1;
882 }
883
884 if ($checked) {
885 $content .= $this->getAttributeString('checked', 'checked');
886 }
887
888 $content .= ' />';
889
890 return $content;
891 }
892
893 /**
894 * Renders a div with a help text that can be toggled via a button
895 *
896 * @param string $helpStr
897 * @param string $id: A unique ID for the container. A random value is appended
898 * @return array ('button', 'container')
899 */
900 public function renderHelp($helpStr, $id) {
901 if (empty($helpStr)) {
902 $result = false;
903 } else {
904 $result = array('button' => '', 'container' => '');
905
906 $id = $id.'_'.md5(microtime());
907
908 $helpLabel = $this->renderImage(array('path' => 'imgs/icons/help.png', 'altTitle' => $this->pObj->getBasicsObject()->getLabel('label_help')));
909
910 $result['button'] = '<a href="#" onclick="toggleHelp(\''.$id.'\'); return false;">'.$helpLabel.'</a>';
911 $result['container'] = '<div id="'.$id.'" style="display:none" class="help_container">'.$helpStr.'</div>';
912 }
913
914 return $result;
915 }
916
917 /**
918 * Retrieves a name and a value and returns a HTML attribute string (name="value") if the value is not empty.
919 * Otherwise it will return an empty string.
920 *
921 * @param string $name: The name of the attribute
922 * @param string $value: The value of the attribute
923 * @return string The HTML attribute string prepended with a whitespace
924 */
925 private function getAttributeString($name, $value = NULL, $default = NULL) {
926 $content = '';
927
928 $value = (isset($value)) ? $value : $default;
929 // $value = ($value == NULL && $default == NULL) ? $name : '';
930
931 if(!is_null($value)) {
932 $content = ' '.strtolower($name).'="'.$value.'"';
933 }
934
935 return $content;
936 }
937
938 /**
939 * gets the errors
940 *
941 * @param string optional type to narrow down the request range of errors
942 * @return array
943 */
944 public function getErrors($type = '') {
945 $errors = $this->errors;
946
947 if($type) {
948 $errors = $this->errors[$type];
949 }
950
951 return $errors;
952 }
953
954 /**
955 * adds an error message
956 *
957 * TODO add checks
958 *
959 * @param string error type
960 * @param string error message
961 */
962 public function addError($type, $errorMessage, $errorField = '', $onTop = false) {
963
964 if ($onTop) {
965 if($type == 'fields') {
966 array_unshift($this->errors[$type][$errorField], $errorMessage);
967 } else {
968 array_unshift($this->errors[$type], $errorMessage);
969 }
970 } else {
971 if($type == 'fields') {
972 $this->errors[$type][$errorField][] = $errorMessage;
973 } else {
974 $this->errors[$type][] = $errorMessage;
975 }
976 }
977 }
978
979 /**
980 * Adds a string to this->lastMessage
981 *
982 * @param string message
983 */
984 public function addMessage($message) {
985 $this->lastMessage .= '<br />'.$message;
986 }
987
988 /**
989 * Returns the value in this->lastMessage
990 *
991 * @param boolean $clear: If set, the lastMessage is cleared after return
992 * @return string
993 */
994 public function getLastMessage($clear = false) {
995 $result = $this->lastMessage;
996 if ($clear) {
997 $this->clearLastMessage();
998 }
999 return empty($result) ? false : $result;
1000 }
1001
1002 /**
1003 * Clears the value of this->lastMessage
1004 *
1005 */
1006 public function clearLastMessage() {
1007 $this->lastMessage = '';
1008 }
1009
1010 }
1011
1012 if(defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install_view.php']) {
1013 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install_view.php']);
1014 }
1015
1016 ?>