$content // If is_null($content), a single tag will be createed (<$tag $paramkey="$paramvalue"/>). // If a value or key of the $parameter hash is NULL, the key="value" entry will not appear. // The content and the parameter are not encoded in any way. function html_tag($tagname, $parameter, $content) { $result = "<$tagname"; foreach($parameter as $key => $value) { if (!is_null($value) && !is_null($key)) $result .= " $key=\"$value\""; } if (is_null($content)) return $result . '/>'; return $result . ">$content"; } // Applies the function htmlentities on every value of an array. function html_escape_array($array, $keystoo = FALSE) { $newarray = array(); foreach($array as $key => $value) { if (is_string($value)) $value = htmlspecialchars($value, ENT_COMPAT, 'ISO-8859-1'); if ($keystoo && is_string($key)) $key = htmlspecialchars($key, ENT_COMPAT, 'ISO-8859-1'); $newarray[$key] = $value; } return $newarray; } // indents a text function text_indent($text, $indentchar = "\t") { if (strlen($text) == 0) return ''; $result = $indentchar . str_replace("\n", "\n$indentchar", $text); if (substr($result, -2) == "\n$indentchar") $result = substr($result, 0, -strlen($indentchar)); return $result; } // Cuts a text to the specified max length and adds fill char. The cutting is done at word ends. // If the text is shorter than maxlength, it returns text. function text_cut($text, $maxlength, $fillchar = ' ...') { if (strlen($text) <= $maxlength) return $text; $text = wordwrap($text, $maxlength); $lines = explode("\n", $text); return $lines[0] . $fillchar; } // Shortcuts for creating simple things // ==================================== // Shortcut for html_tag: You can use it in the following ways: // html_element($tagname); // html_element($tagname, $content [, $encode]); // html_element($tagname, $parameter [, $encode]); // html_element($tagname, $parameter, $content, [, $encode]); // The optional argument $encode is FALSE by default. // If $encode is TRUE, the $content _and_ the parameters _and_ the keys of the parameters will be encoded. function html_element($tagname) { list($tagname, $parameter, $content) = html_element_decode(func_get_args()); return html_tag($tagname, $parameter, $content); } // same as html_element but it does not result in // content // but // \n // \t content\n // function html_ielement($tagname) { list($tagname, $parameter, $content) = html_element_decode(func_get_args()); if (!is_null($content) && !$content == '') { $content = "\n" . text_indent($content); if (substr($content, -1) != "\n") $content .= "\n"; } return html_tag($tagname, $parameter, $content); } // "internal" function to use at html_element and html_ielement // Brings the arguments in the correct order and does the encoding function html_element_decode($args) { // Parameter $tagname = $args[0]; $encode = FALSE; $parameter = array(); $content = NULL; for ($i=1; $i != count($args); ++$i) { $arg = $args[$i]; if (is_bool($arg)) $encode = $arg; else if (is_array($arg)) $parameter = $arg; else if (is_string($arg)) $content = $arg; else die('unknown arguments in html_element'); } // Encoding if ($encode) { $parameter = html_escape_array($parameter, TRUE); if (!is_null($content)) $content = htmlspecialchars($content, ENT_COMPAT, 'ISO-8859-1'); } return array($tagname, $parameter, $content); } // Shortcuts for form fields // ========================= // Helper function for the following form-field-generating functions function html_input_basic($name, $value, $type, $additionalParameter = array()) { $parameter = array('type' => $type, 'name' => $name, 'value' => $value); $parameter = array_merge($parameter, $additionalParameter); return html_element('input', $parameter, TRUE); } // Creates an hidden field function html_input_hidden($name, $value) { return html_input_basic($name, $value, 'hidden'); } // Creates an input text field function html_input_text($name, $value=NULL, $length=NULL, $size=NULL) { return html_input_basic($name, $value, 'text', array('maxlength' => $length, 'size' => $size)); } // Creates an input password field function html_input_password($name, $value=NULL, $length=NULL, $size=NULL) { return html_input_basic($name, $value, 'password', array('maxlength' => $length, 'size' => $size)); } // Creates a submit field function html_input_submit($name, $value) { return html_input_basic($name, $value, 'submit'); } // Creates a reset field function html_input_reset($value) { return html_input_basic(NULL, $value, 'reset'); } // Creates a select box field function html_input_select($name, $value=NULL, $hash, $encode=FALSE, $format=TRUE, $size=1) { $options = ''; foreach($hash as $k => $v) { $parameter = array('value' => $k); if ($value == $k) $parameter['selected'] = 'selected'; $options .= html_element('option', $parameter, $v, $encode) . "\n"; } if ($format) $options = "\n" . text_indent($options); if ($encode) $name = htmlspecialchars($name, ENT_COMPAT, 'ISO-8859-1'); return html_element('select', array('name' => $name, 'size' => $size), $options); } // Creates a textarea field function html_textarea($name, $value, $cols, $rows, $encode=FALSE) { $parameter = array('name' => $name, 'cols' => $cols, 'rows' => $rows); if (is_null($value)) $value = ''; return html_element('textarea', $parameter, $value, $encode); } // Creates a string for an img element. You can use the function as follows: // html_img($src) // alt="" // html_img($src, [$alt,] [$encode,] [$keyvaluearray]) // html_img($src, [$alt,] [$keyvaluearray,] [$encode]) // keyvaluearray: supply additional attributes. default: array() // encode: default: FALSE // alt: default: '' function html_img($src, $alt='') { $encode = FALSE; $attributes = array('src' => $src, 'alt' => $alt); $args = func_get_args(); for($i = 2; $i != count($args); ++$i) { $arg = $args[$i]; if (is_bool($arg)) $encode=$arg; if (is_array($arg)) $attributes=array_merge($attributes, $arg); } return html_element('img', $attributes, $encode); } // Same as above with additional title. If title is NULL, $title = $alt. function html_img_title($src, $alt='', $title=NULL) { $func_parameter = func_get_args(); if (is_null($title)) $title = $alt; unset($func_parameter[2]); $found = FALSE; foreach($func_parameter as $k => $v) { if (is_array($v)) { $func_parameter[$k]['title'] = $title; $found = TRUE; } } if (!$found) $func_parameter[] = array('title' => $title); return call_user_func_array('html_img', $func_parameter); } // DataInfo classes // ================ // These classes are intended for use with EditForm. // For all class fields, the value NULL means that a default value should be taken. class DataInfo { var $header; var $name; // name for form. var $default; // default value for insert function DataInfo($name = NULL, $header = NULL, $default = NULL) { $this->name = $name; $this->header = $header; $this->default = $default; } // virtual... // creates the head cell of the table function createHtmlTableHeader() { if (!is_null($this->header)) return html_element('span', array('class'=>'th'), $this->header, TRUE); } // virtual... // creates the body cell of the table function createHtmlTableBody($value) { return html_element('span', array('class'=>'td'), $this->createHtml($value)); } // virtual... // creates the body cell of an insert row of the table function createHtmlTableInsertBody() { return html_element('span', array('class'=>'td'), $this->createInsertHtml()); } // virtual... function createHtml($value) { return ''; } // virtual... function createInsertHtml() { return $this->createHtml($this->default); } }; // This shows the text but is not "database sensitive" class DiReadOnly extends DataInfo { function DiReadOnly($header = NULL, $default = NULL) { $this->DataInfo(NULL, $header, $default); } function createHtml($value) { return htmlspecialchars($value, ENT_COMPAT, 'ISO-8859-1'); } }; class DiHidden extends DataInfo { function DiHidden($name, $default = NULL) { $this->DataInfo($name, NULL, $default); } function createHtmlTableBody($value) { return $this->createHtml($value); } function createHtmlTableInsertBody() { return $this->createInsertHtml(); } function createHtml($value) { return html_input_hidden($this->name, $value); } function createInsertHtml() { if (is_null($this->default)) return ''; return $this->createHtml($this->default); } }; /* class DiRawHtml extends DataInfo { function createHtml($value) { return $value; } }; */ class DiTextEdit extends DataInfo { var $length = NULL; var $size = NULL; function DiTextEdit($name, $header, $length = NULL, $size = NULL, $default = NULL) { $this->DataInfo($name, $header, $default); $this->length = $length; $this->size = $size; } function createHtml($value) { return html_input_text($this->name, $value, $this->length, $this->size); } function createInsertHtml() { return $this->createHtml($this->default); } }; class DiPasswordEdit extends DiTextEdit { function createHtml($value) { return html_input_password($this->name, 'XXXXXX', $this->length, $this->size); } function createInsertHtml() { return html_input_password($this->name, '', $this->length, $this->size); } }; // input: 1D array of arrays with 2 entries. // the first will be used as key, the second as value. // Useful to crate hash for DiSelect out of database query result. function array_to_hash($array) { $result = array(); foreach ($array as $row) { $result[$row[0]] = (string) $row[1]; } return $result; } class DiSelect extends DataInfo { var $hash; function DiSelect($name, $heading, $hash) { $this->DataInfo($name, $heading); $this->hash = $hash; } function createHtml($value) { $hash = html_escape_array($this->hash, TRUE); return html_input_select($this->name, $value, $hash, TRUE); } }; class DiBoolEdit extends DataInfo { function createHtml($value) { $hash = array('' => '---', 't' => _('Yes'), 'f' => _('No')); return html_input_select($this->name, $value, $hash); } }; class DiBoolReadOnly extends DataInfo { function DiBoolReadOnly($header = NULL, $default = NULL) { $this->DataInfo(NULL, $header, $default); } function createHtml($value) { if ($value == 't') return htmlspecialchars(_('Yes'), ENT_COMPAT, 'ISO-8859-1'); if ($value == 'f') return htmlspecialchars(_('No'), ENT_COMPAT, 'ISO-8859-1'); return ''; } }; // The data are not editable (but are shown) in normal rows. // Therefore a lookup hash is used. // In the "insert" row, a combobox is used. class DiOnlyInputSelect extends DataInfo { var $lookupHash; // hash for "normal" lines to lookup. var $insertHash; // hash for comboBox for "insert" line. function DiOnlyInputSelect($name, $header, $default, $lookupHash, $insertHash) { $this->DataInfo($name, $header, $default); $this->lookupHash = $lookupHash; $this->insertHash = $insertHash; } function createHtml($value) { $hash = html_escape_array($this->lookupHash, TRUE); $hiddenField = html_input_hidden($this->name, $value); if (array_key_exists($value, $hash)) return $hiddenField . $hash[$value]; return $hiddenField . '(' . htmlentities($value, ENT_COMPAT, 'ISO-8859-1') . ')'; } function createInsertHtml() { $hash = html_escape_array($this->insertHash, TRUE); return html_input_select($this->name, $this->default, $hash, TRUE); } }; class DiTextareaEdit extends DataInfo { var $cols = NULL; var $rows = NULL; function DiTextareaEdit($name, $header, $cols = NULL, $rows = NULL) { $this->DataInfo($name, $header); $this->cols = $cols; $this->rows = $rows; } function createHtml($value) { return html_textarea($this->name, $value, $this->cols, $this->rows, TRUE); } }; // EditForm classes and functions // ============================== // creates an array of DataInfo classes suitable for the $dbresult. // if fieldnamekeys === TRUE, the field names will be taken as keys, // else numbers will be taken. // $header: the names of the header // $size: the size of the field, if the type has a size. // $length: the length of the field, if the type has a length. If NULL, // the $size will be taken. // $header, $size, $length can each be: // * assoziative array (hash): columnname => value // * normal array: values "from left to right" // * string functionname to apply to the default values i.e. ucwords. // The value NULL means that this property is not taken, // a value TRUE means that the default property is taken. function html_defaultColumns( $dbresult, $fieldnamekeys = FALSE, $header = NULL, $size = NULL, $length = NULL ) { for ($col = 0; $col != pg_num_fields($dbresult); ++$col) { // Name $cname = pg_field_name($dbresult, $col); // Type $ctype = pg_field_type($dbresult, $col); // Size $dsize = pg_field_size($dbresult, $col); $csize = FALSE; if (is_string($size)) $csize = $size($dsize); elseif (is_array($size) && array_key_exists($cname, $size)) $csize = $size[$cname]; elseif (is_array($size) && array_key_exists($col, $size)) $csize = $size[$col]; if ($csize === FALSE) $csize = $dsize; if ($csize == -1) $csize = NULL; // Length $clength = FALSE; if (is_string($length)) $clength = $length($csize); elseif (is_array($length) && array_key_exists($cname, $length)) $clength = $length[$cname]; elseif (is_array($length) && array_key_exists($col, $length)) $clength = $length[$col]; if ($clength === FALSE) $clength = $csize; // Header $cheader = FALSE; if (is_string($header)) $cheader = $header($cname); elseif (is_array($header) && array_key_exists($cname, $header)) $cheader = $header[$cname]; elseif (is_array($header) && array_key_exists($col, $header)) $cheader = $header[$col]; if ($cheader === FALSE) $cheader = $cname; // Create DataInfo class $di = NULL; if ($ctype == 'bool') $di = new DiBoolEdit($cname, $cheader); if (is_null($di)) $di = new DiTextEdit($cname, $cheader, $csize, $clength); if ($fieldnamekeys) $columns[$cname] = $di; else $columns[] = $di; } return $columns; } function html_createEditForm( $action, $nextpage, // data to fill in in the field :nextpage (needed by editdb.php) $tablename, $columns, // 1D Array of EfDataInfo classes $data, // Array of rows, that are again arrays of columns $insert=TRUE, $update=TRUE, $delete=TRUE ) { if (count($data) == 0 && !$insert) return; $action = htmlspecialchars($action, ENT_COMPAT, 'ISO-8859-1'); // fill in nextpage $columns[] = new DiHidden(':nextpage', $nextpage); foreach ($data as $rownum => $datarow) { $data[$rownum][] = $nextpage; } // fill in tablename $columns[] = new DiHidden(':tablename', $tablename); foreach ($data as $rownum => $datarow) { $data[$rownum][] = $tablename; } // head $head = ''; foreach($columns as $column) { $h = $column->createHtmlTableHeader(); if (strlen($h) > 0) $h .= "\n"; $head .= $h; } $head .= html_element('span', array('class'=>'th'), ' '); $result = html_ielement('div', array('class'=>'tr_head'), $head) . "\n"; // update $rownr = 0; foreach($data as $datarow) { $row = ''; $columnnr = 0; foreach ($datarow as $field) { $column = $columns[$columnnr]; $html = $column->createHtmlTableBody($field); if (strlen($html) > 0) $html .= "\n"; $row .= $html; ++$columnnr; } $buttons = ''; if ($update) $buttons .= html_input_submit(':operation_update', _('update')); if ($delete) $buttons .= html_input_submit(':operation_delete', _('delete')); $row .= html_element('span', array('class'=>'td'), $buttons); $class = ($rownr % 2 == 0) ? 'tr_even' : 'tr_odd'; $result .= html_ielement('form', array('action' => $action, 'method' => 'post', 'class' => $class), $row) . "\n"; ++$rownr; } // insert if ($insert) { $row = ''; foreach($columns as $column) { $html = $column->createHtmlTableInsertBody(); if (strlen($html) > 0) $html .= "\n"; $row .= $html; } $button = html_input_submit(':operation_insert', _('insert')) . "\n"; $row .= html_element('span', array('class'=>'td'), $button); $result .= html_ielement('form', array('action' => $action, 'method' => 'post', 'class' => 'tr_insert'), $row); // $result .= html_ielement('div', array('class' => 'tr_insert'), $row); } return html_ielement('div', array('class'=>'table'), $result); } function html_createVEditForm( $action, $tablename, $columns, // 1D Array of EfDataInfo classes $data, // Array of rows, that are again arrays of columns $insert=TRUE, $update=TRUE, $delete=TRUE ) { // fill in tablename $columns[] = new DiHidden(':tablename', $tablename); foreach ($data as $rownum => $datarow) { $data[$rownum][] = $tablename; } // Rows $rows = ''; $rownr = 0; foreach($data as $row) { $coltext = ''; reset($columns); reset($row); while($column = current($columns)) { $head = $column->createHtmlTableHeader(); $field = $column->createHtmlTableBody(current($row)); $text = "$head\n$field"; if (!is_null($column->header)) $text = html_ielement('tr', $text); $coltext .= "$text\n"; next($columns); next($row); } $buttons = ''; if ($update) $buttons .= html_input_submit(':operation_update', _('update')); if ($delete) $buttons .= html_input_submit(':operation_delete', _('delete')); $coltext .= ' ' . html_element('td', $buttons) . "\n"; $coltext = html_ielement('form', array('action' => $action, 'method' => 'post'), $coltext) . "\n"; $class = ($rownr % 2 == 0) ? 'even' : 'odd'; $coltext = html_ielement('table', array('class' => $class), $coltext) . "\n"; $coltext = html_ielement('p', $coltext) . "\n"; $rows .= $coltext; ++$rownr; } // Insert if ($insert) { $coltext = ''; reset($columns); while($column = current($columns)) { $head = $column->createHtmlTableHeader(); $field = $column->createHtmlTableInsertBody(); $text = "$head\n$field"; if (!is_null($column->header)) $text = html_ielement('tr', $text); $coltext .= "$text\n"; next($columns); } $button = html_input_submit(':operation_insert', _('insert')); $coltext .= ' ' . html_element('td', $button) . "\n"; $coltext = html_ielement('form', array('action' => $action, 'method' => 'post'), $coltext) . "\n"; $coltext = html_ielement('table', array('class' => 'insert'), $coltext) . "\n"; $coltext = html_ielement('p', $coltext) . "\n"; $rows .= $coltext; } return $rows; } function html_createTable( $head, // 1D Array of Head fields $data // Array of rows, that are again arrays of columns ) { html_escape_array($head); $thead = '' . implode('', $head) . "\n"; $tbody = ''; $num = 0; foreach($data as $row) { html_escape_array($row); $trow = '' . implode('', $row) . ''; $tbody .= html_element('tr', array('class' => ($num % 2 == 0 ? 'even' : 'odd')), $trow); ++$num; } return html_ielement('table', "$thead$tbody"); } ?>