Added interface to extend eTemplates with new widgets.

The widget got automaticaly loaded from the app's inc dir (or etemplate's inc dir).
Two examples ilustrate how to use the interface:
 - date: class.date_widget.inc.php reads dates via sbox.getDate
 - datefield: class.datefield_widget.inc.php reads dates via 3 textfields
This commit is contained in:
Ralf Becker 2002-05-13 21:30:46 +00:00
parent 905c960a5a
commit daceac54ad
5 changed files with 365 additions and 82 deletions

View File

@ -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];
}
};

View File

@ -0,0 +1,127 @@
<?php
/**************************************************************************\
* phpGroupWare - eTemplate Extension - Date Widget *
* http://www.phpgroupware.org *
* Written by Ralf Becker <RalfBecker@outdoor-training.de> *
* -------------------------------------------- *
* 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);
}
}

View File

@ -0,0 +1,123 @@
<?php
/**************************************************************************\
* phpGroupWare - eTemplate Extension - DateField Widget *
* http://www.phpgroupware.org *
* Written by Ralf Becker <RalfBecker@outdoor-training.de> *
* -------------------------------------------- *
* 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;
}
}

View File

@ -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;
}
};

View File

@ -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 .= '<i>unknown type</i>';
if (!isset($this->extension[$cell['type']]))
{
$html .= '<i>unknown type</i>';
}
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 "<p>process_show_cell(c=$c, r=$r, name='$name',type='${cell['type']}) start: isset(value)=".(0+isset($value)).", value=";
echo "<p>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 "<p>value after post_process: '$value'";
}
}
if ($this->debug >= 3 || $this->debug == $this->name || $this->debug == $cell['type'])
{