4 +-----------------------------------------------------------------------+
7 | This file is part of the RoundCube PHP suite |
8 | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
9 | Licensed under the GNU GPL |
12 | Common Classes to create HTML output |
14 +-----------------------------------------------------------------------+
15 | Author: Thomas Bruederli <roundcube@gmail.com> |
16 +-----------------------------------------------------------------------+
24 * HTML page builder class
30 var $scripts_path = '';
31 var $script_files = array();
32 var $scripts = array();
33 var $charset = 'UTF-8';
35 var $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n";
36 var $script_tag = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n";
37 var $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
39 var $title = 'RoundCube Mail';
43 var $body_attrib = array();
44 var $meta_tags = array();
48 * Link an external script file
50 * @param string File URL
51 * @param string Target position [head|foot]
53 function include_script($file, $position='head')
55 static $sa_files = array();
57 if (in_array($file, $sa_files))
60 if (!is_array($this->script_files[$position]))
61 $this->script_files[$position] = array();
63 $this->script_files[$position][] = $file;
67 * Add inline javascript code
69 * @param string JS code snippet
70 * @param string Target position [head|head_top|foot]
72 function add_script($script, $position='head')
74 if (!isset($this->scripts[$position]))
75 $this->scripts[$position] = "\n".rtrim($script);
77 $this->scripts[$position] .= "\n".rtrim($script);
81 * Add HTML code to the page header
83 function add_header($str)
85 $this->header .= "\n".$str;
89 * Add HTML code to the page footer
90 * To be added right befor </body>
92 function add_footer($str)
94 $this->footer .= "\n".$str;
98 * Setter for page title
100 function set_title($t)
107 * Setter for output charset.
108 * To be specified in a meta tag and sent as http-header
110 function set_charset($charset)
114 $this->charset = $charset;
116 if ($MBSTRING && function_exists("mb_internal_encoding"))
118 if(!@mb_internal_encoding($charset))
124 * Getter for output charset
126 function get_charset()
128 return $this->charset;
133 * Reset all saved properties
137 $this->script_files = array();
138 $this->scripts = array();
146 * Process template and write to stdOut
148 * @param string HTML template
149 * @param string Base for absolute paths
151 function write($templ='', $base_path='')
153 $output = empty($templ) ? $this->default_template : trim($templ);
155 // replace specialchars in content
156 $__page_title = Q($this->title, 'show', FALSE);
157 $__page_header = $__page_body = $__page_footer = '';
160 // include meta tag with charset
161 if (!empty($this->charset))
163 header('Content-Type: text/html; charset='.$this->charset, true);
164 $__page_header = '<meta http-equiv="content-type" content="text/html; charset='.$this->charset.'" />'."\n";
168 // definition of the code to be placed in the document header and footer
169 if (is_array($this->script_files['head']))
170 foreach ($this->script_files['head'] as $file)
171 $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file);
173 $head_script = $this->scripts['head_top'] . $this->scripts['head'];
174 if (!empty($head_script))
175 $__page_header .= sprintf($this->script_tag, $head_script);
177 if (!empty($this->header))
178 $__page_header .= $this->header;
180 if (is_array($this->script_files['foot']))
181 foreach ($this->script_files['foot'] as $file)
182 $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file);
184 if (!empty($this->scripts['foot']))
185 $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']);
187 if (!empty($this->footer))
188 $__page_footer .= $this->footer;
191 if ($hpos = strpos(strtolower($output), '</head>'))
192 $__page_header .= "\n";
195 if (!is_numeric($hpos))
196 $hpos = strpos(strtolower($output), '<body');
197 if (!is_numeric($hpos) && ($hpos = strpos(strtolower($output), '<html')))
199 while($output[$hpos]!='>')
204 $__page_header = "<head>\n<title>$__page_title</title>\n$__page_header\n</head>\n";
209 $output = substr($output,0,$hpos) . $__page_header . substr($output,$hpos,strlen($output));
211 $output = $__page_header . $output;
215 if($bpos = strpos(strtolower($output), '<body'))
217 while($output[$bpos]!='>') $bpos++;
221 $bpos = strpos(strtolower($output), '</head>')+7;
224 if($bpos && $__page_body)
225 $output = substr($output,0,$bpos) . "\n$__page_body\n" . substr($output,$bpos,strlen($output));
228 // find and add page footer
229 $output_lc = strtolower($output);
230 if(($fpos = strrstr($output_lc, '</body>')) ||
231 ($fpos = strrstr($output_lc, '</html>')))
232 $output = substr($output, 0, $fpos) . "$__page_footer\n" . substr($output, $fpos);
234 $output .= "\n$__page_footer";
237 // reset those global vars
238 $__page_header = $__page_footer = '';
241 // correct absolute paths in images and other tags
242 $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output);
243 $output = str_replace('$__skin_path', $base_path, $output);
245 print rcube_charset_convert($output, 'UTF-8', $this->charset);
248 } // end class rcube_html_page
253 * Base class to build a HTML for element
257 class rcube_form_element
259 var $uppertags = FALSE;
260 var $upperattribs = FALSE;
261 var $upperprops = FALSE;
262 var $newline = FALSE;
264 var $attrib = array();
268 * Create string with saved attributes
270 * @return string HTML formatted tag attributes
272 function create_attrib_string()
274 if (!sizeof($this->attrib))
278 $this->attrib['name'] = $this->name;
280 $attrib_arr = array();
281 foreach ($this->attrib as $key => $value)
283 // don't output some internally used attributes
284 if (in_array($key, array('form', 'quicksearch')))
287 // skip if size if not numeric
288 if (($key=='size' && !is_numeric($value)))
291 // skip empty eventhandlers
292 if ((strpos($key,'on')===0 && $value==''))
295 // attributes with no value
296 if (in_array($key, array('checked', 'multiple', 'disabled', 'selected', 'nowrap')))
299 $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $key);
301 // don't convert size of value attribute
302 else if ($key=='value')
303 $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), Q($value, 'strict', false));
305 // regular tag attributes
307 $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $this->_conv_case(Q($value), 'value'));
310 return sizeof($attrib_arr) ? ' '.implode(' ', $attrib_arr) : '';
315 * Convert tags and attributes to upper-/lowercase
317 * @param string Input string
318 * @param string Value type (can either be "tag" or "attrib")
319 * @return string Converted output string
322 function _conv_case($str, $type='attrib')
325 return $this->uppertags ? strtoupper($str) : strtolower($str);
326 else if ($type == 'attrib')
327 return $this->upperattribs ? strtoupper($str) : strtolower($str);
328 else if ($type == 'value')
329 return $this->upperprops ? strtoupper($str) : strtolower($str);
335 * Builder for an <input> field
339 class input_field extends rcube_form_element
345 * @param array Named tag attributes
347 function input_field($attrib=array())
349 if (is_array($attrib))
350 $this->attrib = $attrib;
353 $this->type = $attrib['type'];
355 if ($attrib['newline'])
356 $this->newline = TRUE;
362 * @param string Field value
363 * @param array Additional tag attributes
364 * @return string Final HTML code
366 function show($value=NULL, $attrib=NULL)
368 // overwrite object attributes
369 if (is_array($attrib))
370 $this->attrib = array_merge($this->attrib, $attrib);
372 // set value attribute
374 $this->attrib['value'] = $value;
376 $this->attrib['type'] = $this->type;
381 $this->_conv_case('input', 'tag'),
382 $this->create_attrib_string(),
383 ($this->newline ? "\n" : ""));
389 * Builder for a <input type="text"> field
393 class textfield extends input_field
399 * Builder for a <input type="password"> field
403 class passwordfield extends input_field
405 var $type = 'password';
409 * Builder for <input type="radio"> fields
413 class radiobutton extends input_field
419 * Builder for <input type="checkbox"> fields
423 class checkbox extends input_field
425 var $type = 'checkbox';
431 * @param string Field value
432 * @param array Additional tag attributes
433 * @return string Final HTML code
435 function show($value='', $attrib=NULL)
437 // overwrite object attributes
438 if (is_array($attrib))
439 $this->attrib = array_merge($this->attrib, $attrib);
441 $this->attrib['type'] = $this->type;
443 if ($value && (string)$value==(string)$this->attrib['value'])
444 $this->attrib['checked'] = TRUE;
446 $this->attrib['checked'] = FALSE;
451 $this->_conv_case('input', 'tag'),
452 $this->create_attrib_string(),
453 ($this->newline ? "\n" : ""));
459 * Builder for a <textarea> field
463 class textarea extends rcube_form_element
468 * @param array Named tag attributes
470 function textarea($attrib=array())
472 $this->attrib = $attrib;
474 if ($attrib['newline'])
475 $this->newline = TRUE;
479 * Create HTML representation for this field
481 * @param string Field value
482 * @param array Additional tag attributes
483 * @return string Final HTML code
485 function show($value='', $attrib=NULL)
487 // overwrite object attributes
488 if (is_array($attrib))
489 $this->attrib = array_merge($this->attrib, $attrib);
491 // take value attribute as content
493 $value = $this->attrib['value'];
495 // make shure we don't print the value attribute
496 if (isset($this->attrib['value']))
497 unset($this->attrib['value']);
499 if (!empty($value) && !isset($this->attrib['mce_editable']))
500 $value = Q($value, 'strict', FALSE);
505 $this->_conv_case('textarea', 'tag'),
506 $this->create_attrib_string(),
508 $this->_conv_case('textarea', 'tag'),
509 ($this->newline ? "\n" : ""));
515 * Builder for group of hidden form fields
519 class hiddenfield extends rcube_form_element
521 var $fields_arr = array();
527 * @param array Named tag attributes
529 function hiddenfield($attrib=NULL)
531 if (is_array($attrib))
536 * Add a hidden field to this instance
537 * @param array Named tag attributes
539 function add($attrib)
541 $this->fields_arr[] = $attrib;
546 * Create HTML code for the hidden fields
548 * @return string Final HTML code
553 foreach ($this->fields_arr as $attrib)
555 $this->attrib = $attrib;
556 $this->attrib['type'] = 'hidden';
560 $this->_conv_case('input', 'tag'),
561 $this->create_attrib_string(),
562 ($this->newline ? "\n" : ""));
571 * Builder for HTML drop-down menus
573 * // create instance. arguments are used to set attributes of select-tag
574 * $select = new select(array('name' => 'fieldname'));
577 * $select->add('Switzerland', 'CH');
579 * // add multiple options
580 * $select->add(array('Switzerland','Germany'), array('CH','DE'));
582 * // generate pulldown with selection 'Switzerland' and return html-code
583 * // as second argument the same attributes available to instanciate can be used
584 * print $select->show('CH');
589 class select extends rcube_form_element
591 var $options = array();
596 * @param array Named tag attributes
598 function select($attrib=NULL)
600 if (is_array($attrib))
601 $this->attrib = $attrib;
603 if ($attrib['newline'])
604 $this->newline = TRUE;
609 * Add one ore more menu options
611 * @param mixed Array with names or single option name
612 * @param mixed Array with values or single option value
614 function add($names, $values=NULL)
616 if (is_array($names))
618 foreach ($names as $i => $text)
619 $this->options[] = array('text' => $text, 'value' => $values[$i]);
622 $this->options[] = array('text' => $names, 'value' => $values);
627 * Generate HTML code for this drop-down menu
629 * @param string Value of the selected option
630 * @param array Additional tag attributes
631 * @return string Final HTML code
633 function show($select=array(), $attrib=NULL)
636 $value_str = $this->_conv_case(' value="%s"', 'attrib');
638 if (!is_array($select))
639 $select = array($select);
641 foreach ($this->options as $option)
643 $selected = ((isset($option['value']) &&
644 in_array($option['value'], $select, TRUE)) ||
645 (in_array($option['text'], $select, TRUE))) ?
646 $this->_conv_case(' selected="selected"', 'attrib') : '';
648 $options_str .= sprintf("<%s%s%s>%s</%s>\n",
649 $this->_conv_case('option', 'tag'),
650 isset($option['value']) ? sprintf($value_str, Q($option['value'])) : '',
652 Q($option['text'], 'strict', FALSE),
653 $this->_conv_case('option', 'tag'));
657 return sprintf('<%s%s>%s</%s>%s',
658 $this->_conv_case('select', 'tag'),
659 $this->create_attrib_string(),
661 $this->_conv_case('select', 'tag'),
662 ($this->newline ? "\n" : ""));