diff --git a/etemplate/inc/class.boetemplate.inc.php b/etemplate/inc/class.boetemplate.inc.php index 2736bd746b..03d349e3cf 100644 --- a/etemplate/inc/class.boetemplate.inc.php +++ b/etemplate/inc/class.boetemplate.inc.php @@ -22,6 +22,8 @@ */ class boetemplate extends soetemplate { + var $extensions = array(); + var $types = array( 'label' => 'Label', // Label $cell['label'] is (to be translated) textual content 'text' => 'Text', // Textfield 1 Line (size = [length][,maxlength]) @@ -34,7 +36,7 @@ 'hrule' => 'Horizontal Rule', 'template' => 'Template', // $cell['name'] contains template-name, $cell['size'] index into $content,$cname,$readonlys 'image' => 'Image', // label = url, name=link or method, help=alt or title - 'date' => 'Date', // Datefield, size='' timestamp or size=format like 'm/d/Y' + 'date' => '', // Datefield, size='' timestamp or size=format like 'm/d/Y' 'select' => 'Selectbox', // Selectbox ($sel_options[$name] or $content[options-$name] is array with options) // if size > 1 then multiple selections, size lines showed 'select-percent' => 'Select Percentage', @@ -47,12 +49,6 @@ // size: -1=Single+not assigned, 0=Single, >0=Multiple 'raw' => 'Raw', // Raw html in $content[$cell['name']] ); - var $aligns = array( - '' => 'Left', - 'right' => 'Right', - 'center' => 'Center' - ); - /*! @function boetemplate @abstract constructor of class @@ -61,6 +57,10 @@ function boetemplate() { $this->soetemplate(); + + $this->public_functions += array( + 'disable_cells' => True + ); } /*! @@ -219,4 +219,40 @@ return $n; } + + /*! + @function loadExtension($name,$ui='') + @abstact trys to load the Extension / Widget-class from the app or etemplate + @param $name name of the extension the classname should be class.${name}_widget.inc.php + @note the $name might be "$name.$app" to give a app-name (default is the current app) + */ + function loadExtension($name,&$parent,$ui='html') + { + list($class,$app) = explode('.',$name); + $class .= '_widget'; + + if ($app == '') + { + $app = $GLOBALS['phpgw_info']['flags']['current_app']; + } + if (!file_exists(PHPGW_SERVER_ROOT."/$app/inc/class.$class.inc.php")) + { + $app = 'etemplate'; + } + if (!file_exists(PHPGW_SERVER_ROOT."/$app/inc/class.$class.inc.php")) + { + return $this->extension[$name] = False; + } + $this->extension[$name] = CreateObject($app.'.'.$class,$ui); + + if(floor(phpversion()) >= 4) + { + $this->extension[$name]->et = &$parent; + } + else + { + $this->extension[$name]->et = $parent; + } + return $this->extension[$name]; + } }; \ No newline at end of file diff --git a/etemplate/inc/class.date_widget.inc.php b/etemplate/inc/class.date_widget.inc.php new file mode 100644 index 0000000000..afa5c8e886 --- /dev/null +++ b/etemplate/inc/class.date_widget.inc.php @@ -0,0 +1,127 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + /*! + @class date_widget + @abstract widget that reads dates in via 3 select-boxes + @note This widget is generates html vi the sbox-class, so it does not work (without an extra implementation) in an other UI + */ + class date_widget + { + var $public_functions = array( + 'pre_process' => True, + 'render' => True, + 'post_process' => True + ); + var $human_name = 'Date'; // this is the name for the editor + + function date_widget($ui) + { + switch($ui) + { + case '': + case 'html': + $this->ui = 'html'; + break; + case 'gtk': + $this->ui = 'gtk'; + break; + default: + return "UI='$ui' not implemented"; + } + return 0; + } + + function pre_process($cell,&$value) + { + if ($cell['size'] != '') + { + $date = split('[/.-]',$value); + $mdy = split('[/.-]',$cell['size']); + for ($value=array(),$n = 0; $n < 3; ++$n) + { + switch($mdy[$n]) + { + case 'Y': $value[0] = $date[$n]; break; + case 'm': $value[1] = $date[$n]; break; + case 'd': $value[2] = $date[$n]; break; + } + } + } + else + { + $value = array(date('Y',$value),date('m',$value),date('d',$value)); + } + return True; // extra Label is ok + } + + function render($cell,$form_name,$value,$readonly) + { + $func = 'render_'.$this->ui; + + return $this->$func($cell,$form_name,$value,$readonly); + } + + function post_process($cell,&$value) + { + if (!isset($value)) + { + return False; + } + if ($value['d']) + { + if (!$value['m']) + { + $value['m'] = date('m'); + } + if (!$value['Y']) + { + $value['Y'] = date('Y'); + } + if ($cell['size'] == '') + { + $value = mktime(0,0,0,$value['m'],$value['d'],$value['Y']); + } + else + { + for ($n = 0,$str = ''; $n < strlen($cell['size']); ++$n) + { + if (strstr('Ymd',$c = $cell['size'][$n])) + { + $str .= sprintf($c=='Y'?'%04d':'%02d',$value[$c]); + } + else + { + $str .= $c; + } + } + $value = $str; + } + } + else + { + $value = ''; + } + return True; + } + + function render_html($cell,$form_name,$value,$readonly) + { + if ($readonly) + { + return $GLOBALS['phpgw']->common->dateformatorder($value[0],$value[1],$value[2],True); + } + return $this->et->sbox->getDate($form_name.'[Y]',$form_name.'[m]',$form_name.'[d]',$value,$options); + } + } \ No newline at end of file diff --git a/etemplate/inc/class.datefield_widget.inc.php b/etemplate/inc/class.datefield_widget.inc.php new file mode 100644 index 0000000000..83b4b93900 --- /dev/null +++ b/etemplate/inc/class.datefield_widget.inc.php @@ -0,0 +1,123 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + /*! + @class datefield_widget + @abstract widget that reads date in via 3 input-fields + @note This widget is independent of the UI as it only uses etemplate-widgets and has therefor no render-function + */ + class datefield_widget + { + var $public_functions = array( + 'pre_process' => True, + 'post_process' => True + ); + var $human_name = 'DateField'; // this is the name for the editor + + function datefield_widget($ui) + { + } + + function pre_process(&$cell,&$value) + { + if ($cell['size'] != '') + { + $date = split('[/.-]',$value); + $mdy = split('[/.-]',$cell['size']); + for ($value=array(),$n = 0; $n < 3; ++$n) + { + switch($mdy[$n]) + { + case 'Y': $value['Y'] = $date[$n]; break; + case 'm': $value['m'] = $date[$n]; break; + case 'd': $value['d'] = $date[$n]; break; + } + } + } + else + { + $value = array( + 'Y' => date('Y',$value), + 'm' => date('m',$value), + 'd' => date('d',$value) + ); + } + $format = split('[/.-]',$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat']); + $value = array( + 'f1' => $value[$format[0]], + 'f2' => $value[$format[1]], + 'f3' => $value[$format[2]], + 'sep' => $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'][1] + ); + $cell['size'] = $cell['name']; + $cell['type'] = 'template'; + $cell['name'] = 'etemplate.datefield'; + + return True; // extra Label is ok + } + + function post_process($cell,&$value) + { + if (!isset($value)) + { + return False; + } + $format = split('[/.-]',$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat']); + + $value = array( + $format[0] => $value['f1'], + $format[1] => $value['f2'], + $format[2] => $value['f3'] + ); + if ($value['d']) + { + if (!$value['m']) + { + $value['m'] = date('m'); + } + if (!$value['Y']) + { + $value['Y'] = date('Y'); + } + elseif ($value['Y'] < 100) + { + $value['Y'] += $value['Y'] < 30 ? 2000 : 1900; + } + if ($cell['size'] == '') + { + $value = mktime(0,0,0,$value['m'],$value['d'],$value['Y']); + } + else + { + for ($n = 0,$str = ''; $n < strlen($cell['size']); ++$n) + { + if (strstr('Ymd',$c = $cell['size'][$n])) + { + $str .= sprintf($c=='Y'?'%04d':'%02d',$value[$c]); + } + else + { + $str .= $c; + } + } + $value = $str; + } + } + else + { + $value = ''; + } + return True; + } + } \ No newline at end of file diff --git a/etemplate/inc/class.editor.inc.php b/etemplate/inc/class.editor.inc.php index 3455d56709..9fb44bff5b 100644 --- a/etemplate/inc/class.editor.inc.php +++ b/etemplate/inc/class.editor.inc.php @@ -24,6 +24,12 @@ 'error_writing' => 'Error: while saveing !!!', 'other_version' => 'only an other Version found !!!' ); + var $aligns = array( + '' => 'Left', + 'right' => 'Right', + 'center' => 'Center' + ); + var $extensions = ''; var $public_functions = array ( @@ -57,6 +63,15 @@ { $msg .= $this->messages['not_found']; } + if ($this->extensions == '') + { + $this->extensions = $this->scan_for_extensions(); + list($app) = explode('.',$this->name); + if ($app != '' && $app != 'etemplate') + { + $this->extensions += $this->scan_for_extensions($app); + } + } $content = $this->etemplate->as_array() + array( 'cols' => $this->etemplate->cols, 'msg' => $msg @@ -123,10 +138,10 @@ } $this->editor->exec('etemplate.editor.process_edit',$content, array( - 'type' => $this->etemplate->types, - 'align' => $this->etemplate->aligns + 'type' => array_merge($this->etemplate->types,$this->extensions), + 'align' => $this->aligns ), - $no_button,$cols_spanned); + $no_button,$cols_spanned + array('**extensions**' => $this->extensions)); } function swap(&$a,&$b) @@ -136,12 +151,11 @@ function process_edit($content) { - //$content = $GLOBALS['HTTP_POST_VARS']['cont']; - if ($this->debug) { echo "editor.process_edit: content ="; _debug_array($content); } + $this->extensions = $content['**extensions**']; unset($content['**extensions**']); $this->etemplate->init($content); $this->etemplate->size = $content['size']; $this->etemplate->style = $content['style']; @@ -306,7 +320,7 @@ if (substr($content['name'],0,9) == 'etemplate') { $m = new editor(False); - $additional = $m->messages + $this->etemplate->types + $this->etemplate->aligns; + $additional = $m->messages + $this->etemplate->types + $this->aligns; } $msg = $this->etemplate->writeLangFile($content['name'],'en',$additional); } @@ -392,7 +406,7 @@ if (!$msg && isset($post_vars['values']) && !isset($post_vars['vals'])) { $cont = $post_vars['cont']; - $this->etemplate->process_show($cont); // need to be done manually as name is set to $this->etemplate object + $this->etemplate->process_show($cont); // need to be done manually as name is set to $this->etemplate object for ($r = 1; list($key,$val) = @each($cont); ++$r) { $vals["@$r"] = $key; @@ -415,6 +429,29 @@ } $show->exec('etemplate.editor.show',$content,array(),$no_buttons,array('olds' => $vals),''); } + + /*! + @function scan_for_extensions() + @abstract search the inc-dirs of etemplate and the app whichs template is edited for extensions / custom widgets + @note extensions are class-files in $app/inc/class.${name}_widget.inc.php + @returns array with name => human_name of the extensions found + */ + function scan_for_extensions($app='etemplate') + { + $extensions = array(); + + $dir = @opendir(PHPGW_SERVER_ROOT.'/'.$app.'/inc'); + + while ($dir && ($file = readdir($dir))) + { + if (ereg('class\\.([a-zA-Z0-9_]*)_widget.inc.php',$file,$regs) && + ($ext = $this->etemplate->loadExtension($regs[1].'.'.$app,$this->etemplate))) + { + $extensions[$regs[1]] = $ext->human_name; + } + } + return $extensions; + } }; diff --git a/etemplate/inc/class.uietemplate.inc.php b/etemplate/inc/class.uietemplate.inc.php index d163084906..cda31e65c1 100644 --- a/etemplate/inc/class.uietemplate.inc.php +++ b/etemplate/inc/class.uietemplate.inc.php @@ -326,6 +326,14 @@ $cell = $this->empty_cell(); // show nothing $value = ''; } + $extra_label = True; + + if (!$this->types[$cell['type']] && + (isset($this->extension[$cell['type']]) || $this->loadExtension($cell['type'],$this))) + { + $extra_label = $this->extension[$cell['type']]->pre_process($cell,$value); + $content[$name] = $value; // set result for template + } if ($cell['help']) { $options .= " onFocus=\"self.status='".addslashes(lang($cell['help']))."'; return true;\""; @@ -374,34 +382,6 @@ $html .= $this->html->textarea($form_name,$value, $options.$this->html->formatOptions($cell['size'],'ROWS,COLS')); break; - case 'date': - if ($cell['size'] != '') - { - $date = split('[/.-]',$value); - $mdy = split('[/.-]',$cell['size']); - for ($value=array(),$n = 0; $n < 3; ++$n) - { - switch($mdy[$n]) - { - case 'Y': $value[0] = $date[$n]; break; - case 'm': $value[1] = $date[$n]; break; - case 'd': $value[2] = $date[$n]; break; - } - } - } - else - { - $value = array(date('Y',$value),date('m',$value),date('d',$value)); - } - if ($readonly) - { - $html .= $GLOBALS['phpgw']->common->dateformatorder($value[0],$value[1],$value[2]); - } - else - { - $html .= $this->sbox->getDate($name.'[Y]',$name.'[m]',$name.'[d]',$value,$options); - } - break; case 'checkbox': if ($value) { @@ -419,6 +399,7 @@ case 'button': $html .= $this->html->submit_button($form_name,$cell['label'],'', strlen($cell['label']) <= 1 || $cell['no_lang'],$options); + $extra_label = False; break; case 'hrule': $html .= $this->html->hr($cell['size']); @@ -446,7 +427,7 @@ { $readonlys['__ALL__'] = True; } - $templ = is_object($cell['name']) ? $cell['name'] : new etemplate($name); + $templ = is_object($cell['name']) ? $cell['name'] : new etemplate($cell['name']); $html .= $templ->show($content,$sel_options,$readonlys,$cname,$show_c,$show_row); break; case 'select': // size:[linesOnMultiselect] @@ -495,12 +476,20 @@ $image = $this->html->image(substr($this->name,0,strpos($this->name,'.')), $cell['label'],lang($cell['help']),'BORDER=0'); $html .= $name == '' ? $image : $this->html->a_href($image,$name); + $extra_label = False; break; default: - $html .= 'unknown type'; + if (!isset($this->extension[$cell['type']])) + { + $html .= 'unknown type'; + } + else + { + $html .= $this->extension[$cell['type']]->render($cell,$form_name,$value,$readonly); + } break; } - if ($cell['type'] != 'button' && $cell['type'] != 'image' && (($label = $cell['label']) != '' || $html == '')) + if ($extra_label && (($label = $cell['label']) != '' || $html == '')) { if (strlen($label) > 1) { @@ -667,7 +656,7 @@ } if ($this->debug >= 3 || $this->debug == $this->name || $this->debug == $cell['type']) { - echo "

process_show_cell(c=$c, r=$r, name='$name',type='${cell['type']}) start: isset(value)=".(0+isset($value)).", value="; + echo "

process_show_cell(c=$c, r=$r, name='$name',type='${cell['type']}') start: isset(value)=".(0+isset($value)).", value="; if (is_array($value)) { _debug_array($value); @@ -693,42 +682,6 @@ $value = stripslashes($value); } break; - case 'date': - if ($value['d']) - { - if (!$value['m']) - { - $value['m'] = date('m'); - } - if (!$value['Y']) - { - $value['Y'] = date('Y'); - } - if ($cell['size'] == '') - { - $value = mktime(0,0,0,$value['m'],$value['d'],$value['Y']); - } - else - { - for ($n = 0,$str = ''; $n < strlen($cell['size']); ++$n) - { - if (strstr('Ymd',$c = $cell['size'][$n])) - { - $str .= sprintf($c=='Y'?'%04d':'%02d',$value[$c]); - } - else - { - $str .= $c; - } - } - $value = $str; - } - } - else - { - $value = ''; - } - break; case 'checkbox': if (!isset($value)) // checkbox was not checked { @@ -748,6 +701,13 @@ } break; default: // do nothing, $value is correct as is + if ((isset($this->extension[$cell['type']]) || $this->loadExtension($cell['type'],$this)) && + isset($this->extension[$cell['type']]->public_functions['post_process'])) + { + //echo "value for post_process: "; _debug_array($value); + $this->extension[$cell['type']]->post_process($cell,$value); + //echo "

value after post_process: '$value'"; + } } if ($this->debug >= 3 || $this->debug == $this->name || $this->debug == $cell['type']) {