2002-02-06 10:03:11 +01:00
< ? php
2008-03-09 15:41:22 +01:00
/**
2008-03-20 19:43:11 +01:00
* eGroupWare EditableTemplates - Storage Objects
*
* @ link http :// www . egroupware . org
* @ author Ralf Becker < RalfBecker @ outdoor - training . de >
2009-03-16 13:58:24 +01:00
* @ copyright 2002 - 9 by RalfBecker @ outdoor - training . de
2008-03-20 19:43:11 +01:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ package etemplate
* @ subpackage api
* @ version $Id $
*/
2008-03-09 15:41:22 +01:00
/**
2008-03-20 19:43:11 +01:00
* Storage Objects : Everything to store and retrive and eTemplate .
*
* eTemplates are stored in the db in table 'phpgw_etemplate' and gets distributed
* through the file 'etemplates.inc.php' in the setup dir of each app . That file gets
* automatically imported in the db , whenever you show a eTemplate of the app . For
* performace reasons the timestamp of the file is stored in the db , so 'new'
* eTemplates need to have a newer file . The distribution - file is generated with the
* function dump , usually by pressing a button in the editor .
* writeLangFile writes an lang - file with all Labels , incorporating an existing one .
* Beside a name eTemplates use the following keys to find the most suitable template
* for an user ( in order of precedence ) :
* 1 ) User -/ Group - Id ( not yet implemented )
* 2 ) preferd languages of the user ( templates for all langs have $lang = '' )
* 3 ) selected template : verdilak , ... ( the default is called '' in the db , not default )
* 4 ) a version - number of the form , eg : '0.9.13.001' ( filled up with 0 same size )
*/
2008-03-09 15:41:22 +01:00
class soetemplate
{
2009-03-16 13:58:24 +01:00
public $debug ; // =1 show some debug-messages, = 'app.name' show messages only for eTemplate 'app.name'
public $name ; // name of the template, e.g. 'infolog.edit'
public $template ; // '' = default (not 'default')
public $lang ; // '' if general template else language short, e.g. 'de'
public $group ; // 0 = not specific else groupId or if < 0 userId
public $version ; // like 0.9.13.001
public $style ; // embeded CSS style-sheet
public $children ; // array with children
public $data ; // depricated: first grid of the children
public $size ; // depricated: witdh,height,border of first grid
2006-04-20 19:12:30 +02:00
/**
2008-03-09 15:41:22 +01:00
* private reference to the global db - object
2006-04-20 19:12:30 +02:00
*
2009-03-16 13:58:24 +01:00
* @ public egw_db
2006-04-20 19:12:30 +02:00
*/
2008-03-09 15:41:22 +01:00
private $db ;
/**
* name of table
*/
const TABLE = 'egw_etemplate' ;
static $db_key_cols = array (
'et_name' => 'name' ,
'et_template' => 'template' ,
'et_lang' => 'lang' ,
'et_group' => 'group' ,
'et_version' => 'version'
);
static $db_data_cols = array (
'et_data' => 'data' ,
'et_size' => 'size' ,
'et_style' => 'style' ,
'et_modified' => 'modified'
);
static $db_cols ;
/**
* widgets that contain other widgets , eg . for tree_walk method
* widget - type is the key , the value specifys how the children are stored .
2008-06-22 09:16:40 +02:00
*
2009-03-16 13:58:24 +01:00
* @ public array
2008-03-09 15:41:22 +01:00
*/
static $widgets_with_children = array (
'template' => 'template' ,
'grid' => 'grid' ,
'box' => 'box' ,
'vbox' => 'box' ,
'hbox' => 'box' ,
'groupbox' => 'box' ,
'deck' => 'box' ,
);
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
/**
* constructor of the class
*
* calls init or read depending on a name for the template is given
*
* @ param string $name name of the eTemplate or array with the values for all keys
* @ param string $template template - set , '' loads the prefered template of the user , 'default' loads the default one '' in the db
* @ param string $lang language , '' loads the pref . lang of the user , 'default' loads the default one '' in the db
* @ param int $group id of the ( primary ) group of the user or 0 for none , not used at the moment !!!
* @ param string $version version of the eTemplate
* @ param int $rows initial size of the template , default 1 , only used if no name given !!!
* @ param int $cols initial size of the template , default 1 , only used if no name given !!!
* @ return soetemplate
*/
2009-03-16 13:58:24 +01:00
function __construct ( $name = '' , $template = '' , $lang = '' , $group = 0 , $version = '' , $rows = 1 , $cols = 1 )
2008-03-09 15:41:22 +01:00
{
2009-03-16 13:58:24 +01:00
if ( isset ( $GLOBALS [ 'egw' ] -> db ))
2008-03-09 15:41:22 +01:00
{
$this -> db = $GLOBALS [ 'egw' ] -> db ;
}
else
{
$GLOBALS [ 'egw_info' ][ 'server' ][ 'eTemplate-source' ] = 'files' ;
}
if ( empty ( $name ))
{
$this -> init ( $name , $template , $lang , $group , $version , $rows , $cols );
}
else
{
$this -> read ( $name , $template , $lang , $group , $version );
}
}
2002-02-06 10:03:11 +01:00
2004-10-07 23:53:10 +02:00
/**
2008-03-09 15:41:22 +01:00
* generates column - names from index : 'A' , 'B' , ... , 'AA' , 'AB' , ... , 'ZZ' ( not more ! )
2004-10-07 23:53:10 +02:00
*
2008-03-09 15:41:22 +01:00
* @ param int $num numerical index to generate name from 1 => 'A'
* @ return string the name
*/
static function num2chrs ( $num )
{
$min = ord ( 'A' );
$max = ord ( 'Z' ) - $min + 1 ;
if ( $num >= $max )
{
$chrs = chr (( $num / $max ) + $min - 1 );
}
$chrs .= chr (( $num % $max ) + $min );
return $chrs ;
}
/**
* generates column - names from index : 'A' , 'B' , ... , 'AA' , 'AB' , ... , 'ZZ' ( not more ! )
2004-10-07 23:53:10 +02:00
*
2008-03-09 15:41:22 +01:00
* @ param string $chrs column letter to generate name from 'A' => 1
* @ return int the index
2004-10-07 23:53:10 +02:00
*/
2008-03-09 15:41:22 +01:00
static function chrs2num ( $chrs )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$min = ord ( 'A' );
$max = ord ( 'Z' ) - $min + 1 ;
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
$num = 1 + ord ( $chrs { 0 }) - $min ;
if ( strlen ( $chrs ) > 1 )
{
$num *= 1 + $max - $min ;
$num += 1 + ord ( $chrs { 1 }) - $min ;
}
return $num ;
}
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
/**
* constructor for a new / empty cell / widget
*
* nothing fancy so far
*
* @ param string $type type of the widget
* @ param string $name name of widget
* @ param array $attributes = null array with further attributes
* @ return array the cell
*/
static function empty_cell ( $type = 'label' , $name = '' , $attributes = null )
{
$cell = array (
'type' => $type ,
'name' => $name ,
);
if ( $attributes && is_array ( $attributes ))
{
2008-06-22 09:16:40 +02:00
$cell += $attributes ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
return $cell ;
}
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
/**
* constructs a new cell in a give row or the last row , not existing rows will be created
*
* @ deprecated as it uses this -> data
* @ param int $row row - number starting with 1 ( ! )
* @ param string $type type of the cell
* @ param string $label label for the cell
* @ param string $name name of the cell ( index in the content - array )
* @ param array $attributes other attributes for the cell
* @ return array a reference to the new cell , use $new_cell = & $tpl -> new_cell (); ( ! )
*/
function & new_cell ( $row = False , $type = 'label' , $label = '' , $name = '' , $attributes = False )
{
$row = $row >= 0 ? intval ( $row ) : 0 ;
if ( $row && ! isset ( $this -> data [ $row ]) || ! isset ( $this -> data [ 1 ])) // new row ?
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
if ( ! $row ) $row = 1 ;
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
$this -> data [ $row ] = array ();
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
if ( ! $row ) // use last row
2007-03-07 13:30:17 +01:00
{
2008-03-09 15:41:22 +01:00
$row = count ( $this -> data );
while ( ! isset ( $this -> data [ $row ]))
2007-03-07 13:30:17 +01:00
{
2008-03-09 15:41:22 +01:00
-- $row ;
2007-03-07 13:30:17 +01:00
}
2008-03-09 15:41:22 +01:00
}
$row = & $this -> data [ $row ];
$col = $this -> num2chrs ( count ( $row ));
$cell = & $row [ $col ];
$cell = $this -> empty_cell ( $type , $name );
if ( $label !== '' )
{
$attributes [ 'label' ] = $label ;
}
if ( is_array ( $attributes ))
{
foreach ( $attributes as $name => $value )
2005-10-31 10:06:24 +01:00
{
2008-03-09 15:41:22 +01:00
$cell [ $name ] = $value ;
2005-10-31 10:06:24 +01:00
}
2008-03-09 15:41:22 +01:00
}
return $cell ;
}
2003-08-28 16:31:11 +02:00
2008-03-09 15:41:22 +01:00
/**
* adds $cell to it ' s parent at the parent - type spezific location for childs
*
* @ param array & $parent referenc to the parent
* @ param array & $cell cell to add ( need to be unset after the call to add_child , as it ' s a referenc ! )
*/
static function add_child ( & $parent , & $cell )
{
if ( is_object ( $parent )) // parent is the template itself
{
$parent -> children [] = & $cell ;
return ;
}
switch ( $parent [ 'type' ])
{
case 'vbox' :
case 'hbox' :
case 'groupbox' :
case 'box' :
case 'deck' :
list ( $n , $options ) = explode ( ',' , $parent [ 'size' ], 2 );
$parent [ ++ $n ] = & $cell ;
$parent [ 'size' ] = $n . ( $options ? ',' . $options : '' );
break ;
case 'grid' :
$data = & $parent [ 'data' ];
$cols = & $parent [ 'cols' ];
$rows = & $parent [ 'rows' ];
$row = & $data [ $rows ];
$col = count ( $row );
if ( ! $rows || ! is_array ( $cell )) // create a new row
2003-08-28 16:31:11 +02:00
{
2008-03-09 15:41:22 +01:00
$row = & $data [ ++ $rows ];
$row = array ();
2003-08-28 16:31:11 +02:00
}
2008-03-09 15:41:22 +01:00
if ( is_array ( $cell )) // real cell to add
2003-08-28 16:31:11 +02:00
{
2008-03-09 15:41:22 +01:00
$row [ soetemplate :: num2chrs ( $col ++ )] = & $cell ;
list ( $spanned ) = explode ( ',' , $cell [ 'span' ]);
$spanned = $spanned == 'all' ? 1 + $cols - $col : $spanned ;
while ( -- $spanned > 0 )
{
$row [ soetemplate :: num2chrs ( $col ++ )] = soetemplate :: empty_cell ();
}
if ( $col > $cols ) $cols = $col ;
2003-08-28 16:31:11 +02:00
}
2008-03-09 15:41:22 +01:00
break ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
}
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
/**
* initialises internal vars rows & cols from the data of a grid
*
* @ param array & $grid to calc rows and cols
*/
static function set_grid_rows_cols ( & $grid )
{
$grid [ 'rows' ] = count ( $grid [ 'data' ]) - 1 ;
$grid [ 'cols' ] = 0 ;
for ( $r = 1 ; $r <= $grid [ 'rows' ]; ++ $r )
2005-02-08 13:29:06 +01:00
{
2008-03-09 15:41:22 +01:00
$cols = count ( $grid [ 'data' ][ $r ]);
if ( $grid [ 'cols' ] < $cols )
2005-10-31 10:06:24 +01:00
{
2008-03-09 15:41:22 +01:00
$grid [ 'cols' ] = $cols ;
2005-10-31 10:06:24 +01:00
}
2008-03-09 15:41:22 +01:00
}
}
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
/**
* initialises internal vars rows & cols from the data of the first ( ! ) grid
*
* @ deprecated as it uses this -> data
*/
function set_rows_cols ()
{
if ( is_null ( $this -> data )) // tmpl contains no grid
{
$this -> rows = $this -> cols = 0 ;
}
else
{
$grid [ 'data' ] = & $this -> data ;
$grid [ 'rows' ] = & $this -> rows ;
$grid [ 'cols' ] = & $this -> cols ;
$this -> set_grid_rows_cols ( $grid );
unset ( $grid );
}
}
2005-02-08 13:29:06 +01:00
2008-03-09 15:41:22 +01:00
/**
* initialises all internal data - structures of the eTemplate and sets the keys
*
* @ param string $name name of the eTemplate or array with the values for all keys and possibly data
* @ param string $template template - set or '' for the default one
* @ param string $lang language or '' for the default one
* @ param int $group id of the ( primary ) group of the user or 0 for none , not used at the moment !!!
* @ param string $version version of the eTemplate
* @ param int $rows initial size of the template , default 1
* @ param int $cols initial size of the template , default 1
*/
function init ( $name = '' , $template = '' , $lang = '' , $group = 0 , $version = '' , $rows = 1 , $cols = 1 )
{
// unset children and data as they are referenzes to each other
unset ( $this -> children ); unset ( $this -> data );
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
foreach ( self :: $db_cols as $db_col => $col )
{
if ( $col != 'data' ) $this -> $col = is_array ( $name ) ? ( string ) $name [ $col ] : $$col ;
}
if ( $this -> template == 'default' )
{
$this -> template = '' ;
}
if ( $this -> lang == 'default' )
{
$this -> lang = '' ;
2005-02-08 13:29:06 +01:00
}
2008-03-09 15:41:22 +01:00
$this -> tpls_in_file = is_array ( $name ) ? $name [ 'tpls_in_file' ] : 0 ;
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
if ( is_array ( $name ) && $name [ 'onclick_handler' ]) $this -> onclick_handler = $name [ 'onclick_handler' ];
if ( is_array ( $name ) && isset ( $name [ 'data' ]))
{
// data/children are in $name['data']
$this -> children = is_array ( $name [ 'data' ]) ? $name [ 'data' ] : unserialize ( $name [ 'data' ]);
2005-02-08 13:29:06 +01:00
2008-03-09 15:41:22 +01:00
$this -> fix_old_template_format ();
}
else
2002-09-25 18:36:07 +02:00
{
2008-03-09 15:41:22 +01:00
$this -> size = $this -> style = '' ;
$this -> data = array ( 0 => array ());
$this -> rows = $rows < 0 ? 1 : $rows ;
$this -> cols = $cols < 0 ? 1 : $cols ;
for ( $row = 1 ; $row <= $rows ; ++ $row )
2003-11-03 16:43:55 +01:00
{
2008-03-09 15:41:22 +01:00
for ( $col = 0 ; $col < $cols ; ++ $col )
2003-11-03 16:43:55 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> data [ $row ][ $this -> num2chrs ( $col )] = $this -> empty_cell ();
2003-11-03 16:43:55 +01:00
}
}
2008-03-09 15:41:22 +01:00
$this -> children [ 0 ][ 'type' ] = 'grid' ;
$this -> children [ 0 ][ 'data' ] = & $this -> data ;
$this -> children [ 0 ][ 'rows' ] = & $this -> rows ;
$this -> children [ 0 ][ 'cols' ] = & $this -> cols ;
$this -> children [ 0 ][ 'size' ] = & $this -> size ;
2002-09-25 18:36:07 +02:00
}
2008-03-09 15:41:22 +01:00
}
/**
* reads an eTemplate from the database
*
* @ param string $name name of the eTemplate or array with the values for all keys
* @ param string $template template - set , '' loads the prefered template of the user , 'default' loads the default one '' in the db
* @ param string $lang language , '' loads the pref . lang of the user , 'default' loads the default one '' in the db
* @ param int $group id of the ( primary ) group of the user or 0 for none , not used at the moment !!!
* @ param string $version version of the eTemplate
* @ return boolean True if a fitting template is found , else False
*/
function read ( $name , $template = 'default' , $lang = 'default' , $group = 0 , $version = '' )
{
$this -> init ( $name , $template , $lang , $group , $version );
if ( $this -> debug == 1 || $this -> debug == $this -> name )
{
echo " <p>soetemplate::read(' $this->name ',' $this->template ',' $this->lang ', $this->group ,' $this->version ')</p> \n " ;
2005-02-08 13:29:06 +01:00
}
2008-03-09 15:41:22 +01:00
if (( $GLOBALS [ 'egw_info' ][ 'server' ][ 'eTemplate-source' ] == 'files' ||
$GLOBALS [ 'egw_info' ][ 'server' ][ 'eTemplate-source' ] == 'xslt' ) && $this -> readfile ())
{
return True ;
}
if ( $this -> name )
{
$this -> test_import ( $this -> name ); // import updates in setup-dir
}
$pref_lang = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'lang' ];
$pref_templ = $GLOBALS [ 'egw_info' ][ 'server' ][ 'template_set' ];
2002-09-25 18:36:07 +02:00
2008-03-09 15:41:22 +01:00
$where = array (
'et_name' => $this -> name ,
);
if ( is_array ( $name ))
{
$template = $name [ 'template' ];
}
if ( $template == 'default' )
{
$where [] = '(et_template=' . $this -> db -> quote ( $pref_templ ) . " OR et_template='') " ;
}
else
{
$where [ 'et_template' ] = $this -> template ;
}
if ( is_array ( $name ))
{
$lang = $name [ 'lang' ];
}
if ( $lang == 'default' || $name [ 'lang' ] == 'default' )
{
$where [] = '(et_lang=' . $this -> db -> quote ( $pref_lang ) . " OR et_lang='') " ;
}
else
{
$where [ 'et_lang' ] = $this -> lang ;
}
if ( $this -> version != '' )
{
$where [ 'et_version' ] = $this -> version ;
}
if ( ! ( $row = $this -> db -> select ( self :: TABLE , '*' , $where , __LINE__ , __FILE__ , false , 'ORDER BY et_lang DESC,et_template DESC,et_version DESC' , 'etemplate' ) -> fetch ()))
{
$version = $this -> version ;
return $this -> readfile () && ( empty ( $version ) || $version == $this -> version );
}
$this -> db2obj ( $row );
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
if ( $this -> debug == $this -> name )
{
$this -> echo_tmpl ();
}
return True ;
}
2002-09-25 18:36:07 +02:00
2008-03-09 15:41:22 +01:00
/**
* Reads an eTemplate from the filesystem , the keys are already set by init in read
*
* @ return boolean True if a template was found , else False
*/
function readfile ()
{
list ( $app , $name ) = explode ( '.' , $this -> name , 2 );
$template = $this -> template == '' ? 'default' : $this -> template ;
2005-02-06 16:49:50 +01:00
2008-03-09 15:41:22 +01:00
if ( $this -> lang )
{
$lang = '.' . $this -> lang ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
$first_try = $ext = $GLOBALS [ 'egw_info' ][ 'server' ][ 'eTemplate-source' ] == 'xslt' ? '.xsl' : '.xet' ;
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
while (( ! $lang || !@ file_exists ( $file = EGW_SERVER_ROOT . " / $app /templates/ $template / $name $lang $ext " ) &&
!@ file_exists ( $file = EGW_SERVER_ROOT . " / $app /templates/default/ $name $lang $ext " )) &&
!@ file_exists ( $file = EGW_SERVER_ROOT . " / $app /templates/ $template / $name $ext " ) &&
!@ file_exists ( $file = EGW_SERVER_ROOT . " / $app /templates/default/ $name $ext " ))
{
if ( $ext == $first_try )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$ext = $ext == '.xet' ? '.xsl' : '.xet' ;
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
if ( $this -> debug == 1 || $this -> name != '' && $this -> debug == $this -> name )
{
echo " <p>tried ' $file ' now trying it with extension ' $ext ' !!!</p> \n " ;
}
2002-02-06 10:03:11 +01:00
}
else
{
2008-03-09 15:41:22 +01:00
break ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
}
if ( $this -> name == '' || $app == '' || $name == '' || !@ file_exists ( $file ) || ! ( $f = @ fopen ( $file , 'r' )))
{
if ( $this -> debug == 1 || $this -> name != '' && $this -> debug == $this -> name )
2005-02-18 23:44:42 +01:00
{
2008-03-09 15:41:22 +01:00
echo " <p>Can't open template ' $this->name ' / ' $file ' !!!</p> \n " ;
2005-02-18 23:44:42 +01:00
}
2008-03-09 15:41:22 +01:00
return False ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
$xml = fread ( $f , filesize ( $file ));
fclose ( $f );
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
if ( $ext == '.xsl' )
2002-09-17 15:27:37 +02:00
{
2008-03-09 15:41:22 +01:00
$cell = $this -> empty_cell ();
$cell [ 'type' ] = 'xslt' ;
$cell [ 'size' ] = $this -> name ;
//$cell['xslt'] = &$xml; xslttemplate class cant use it direct at the moment
$cell [ 'name' ] = '' ;
$this -> data = array ( 0 => array (), 1 => array ( 'A' => & $cell ));
$this -> rows = $this -> cols = 1 ;
}
else
{
if ( ! is_object ( $this -> xul_io ))
2002-09-17 15:27:37 +02:00
{
2008-03-09 15:41:22 +01:00
$this -> xul_io =& CreateObject ( 'etemplate.xul_io' );
2002-09-17 15:27:37 +02:00
}
2008-03-09 15:41:22 +01:00
$loaded = $this -> xul_io -> import ( $this , $xml );
2002-09-17 15:27:37 +02:00
2008-03-09 15:41:22 +01:00
if ( ! is_array ( $loaded ))
2002-09-30 21:06:29 +02:00
{
2002-09-17 15:27:37 +02:00
return False ;
}
2008-03-09 15:41:22 +01:00
$this -> name = $app . '.' . $name ; // if template was copied or app was renamed
2002-09-17 15:27:37 +02:00
2008-03-09 15:41:22 +01:00
$this -> tpls_in_file = count ( $loaded );
}
return True ;
}
2002-09-17 15:27:37 +02:00
2008-03-09 15:41:22 +01:00
/**
* Convert the usual * , ? wildcards to the sql ones and quote % , _
*
* @ param string $pattern
* @ return string
*/
static function sql_wildcards ( $pattern )
{
return str_replace ( array ( '%' , '_' , '*' , '?' ), array ( '\\%' , '\\_' , '%' , '_' ), $pattern );
}
2002-09-25 18:36:07 +02:00
2008-03-09 15:41:22 +01:00
/**
* Lists the eTemplates matching the given criteria , sql wildcards % and _ possible
*
* @ param string $name name of the eTemplate or array with the values for all keys
* @ param string $template template - set , '' loads the prefered template of the user , 'default' loads the default one '' in the db
* @ param string $lang language , '' loads the pref . lang of the user , 'default' loads the default one '' in the db
* @ param int $group id of the ( primary ) group of the user or 0 for none , not used at the moment !!!
* @ param string $version version of the eTemplate
* @ return array of arrays with the template - params
*/
function search ( $name , $template = 'default' , $lang = 'default' , $group = 0 , $version = '' )
{
if ( $this -> name )
{
$this -> test_import ( $this -> name ); // import updates in setup-dir
2002-09-17 15:27:37 +02:00
}
2008-03-09 15:41:22 +01:00
if ( is_array ( $name ))
2005-05-07 15:55:19 +02:00
{
2008-03-09 15:41:22 +01:00
$template = ( string ) $name [ 'template' ];
$lang = ( string ) $name [ 'lang' ];
$group = ( int ) $name [ 'group' ];
$version = ( string ) $name [ 'version' ];
$name = ( string ) $name [ 'name' ];
2005-05-07 15:55:19 +02:00
}
2008-03-09 15:41:22 +01:00
$where [] = 'et_name LIKE ' . $this -> db -> quote ( $this -> sql_wildcards ( $name ) . '%' );
if ( $template != '' && $template != 'default' )
2002-09-04 00:59:47 +02:00
{
2008-03-09 15:41:22 +01:00
$where [] = 'et_template LIKE ' . $this -> db -> quote ( $this -> sql_wildcards ( $template ) . '%' );
}
if ( $lang != '' && $lang != 'default' )
{
$where [] = 'et_lang LIKE ' . $this -> db -> quote ( $this -> sql_wildcards ( $lang ) . '%' );
}
if ( $this -> version != '' )
{
$where [] = 'et_version LIKE ' . $this -> db -> quote ( $this -> sql_wildcards ( $version ) . '%' );
}
$result = array ();
foreach ( $this -> db -> select ( self :: TABLE , 'et_name,et_template,et_lang,et_group,et_version' , $where , __LINE__ , __FILE__ , false , 'ORDER BY et_name DESC,et_lang DESC,et_template DESC,et_version DESC' , 'etemplate' ) as $row )
{
if ( $row [ 'et_lang' ] != '##' ) // exclude or import-time-stamps
2003-03-28 00:43:37 +01:00
{
2008-03-09 15:41:22 +01:00
$result [] = egw_db :: strip_array_keys ( $row , 'et_' );
2003-03-28 00:43:37 +01:00
}
2002-09-04 00:59:47 +02:00
}
2008-03-09 15:41:22 +01:00
if ( $this -> debug )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
_debug_array ( $result );
}
return $result ;
}
/**
* copies all cols into the obj and unserializes the data - array
*/
function db2obj ( array $row )
{
// unset children and data as they are referenzes to each other
unset ( $this -> children ); unset ( $this -> data );
2005-02-06 16:49:50 +01:00
2008-03-09 15:41:22 +01:00
foreach ( self :: $db_cols as $db_col => $name )
{
2008-06-22 09:16:40 +02:00
if ( $name != 'data' )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> $name = $row [ $db_col ];
}
else
{
$this -> children = unserialize ( $row [ $db_col ]);
2002-02-06 10:03:11 +01:00
}
2005-02-06 16:49:50 +01:00
}
2008-03-09 15:41:22 +01:00
$this -> fix_old_template_format ();
}
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
/**
* test if we have an old / original template - format and fixes it to the new format
*/
2008-03-10 16:54:21 +01:00
function fix_old_template_format ()
2008-03-09 15:41:22 +01:00
{
if ( ! is_array ( $this -> children )) $this -> children = array ();
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
if ( ! isset ( $this -> children [ 0 ][ 'type' ]))
2005-02-06 16:49:50 +01:00
{
2008-03-09 15:41:22 +01:00
// old templates are treated as having one children of type grid (the original template)
$this -> data = & $this -> children ;
unset ( $this -> children );
$this -> children [ 0 ][ 'type' ] = 'grid' ;
$this -> children [ 0 ][ 'data' ] = & $this -> data ;
$this -> children [ 0 ][ 'rows' ] = & $this -> rows ;
$this -> children [ 0 ][ 'cols' ] = & $this -> cols ;
$this -> children [ 0 ][ 'size' ] = & $this -> size ;
// that code fixes a bug in very old templates, not sure if it's still needed
if ( $this -> name [ 0 ] != '.' && is_array ( $this -> data ))
2005-02-06 16:49:50 +01:00
{
2008-03-09 15:41:22 +01:00
reset ( $this -> data ); each ( $this -> data );
while ( list ( $row , $cols ) = each ( $this -> data ))
2005-02-06 16:49:50 +01:00
{
2008-03-09 15:41:22 +01:00
while ( list ( $col , $cell ) = each ( $cols ))
2005-02-06 16:49:50 +01:00
{
2008-03-09 15:41:22 +01:00
if ( is_array ( $cell [ 'type' ]))
2005-02-08 13:29:06 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> data [ $row ][ $col ][ 'type' ] = $cell [ 'type' ][ 0 ];
//echo "corrected in $this->name cell $col$row attribute type<br>\n";
2005-02-08 13:29:06 +01:00
}
2008-03-09 15:41:22 +01:00
if ( is_array ( $cell [ 'align' ]))
2005-02-08 13:29:06 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> data [ $row ][ $col ][ 'align' ] = $cell [ 'align' ][ 0 ];
//echo "corrected in $this->name cell $col$row attribute align<br>\n";
2005-02-08 13:29:06 +01:00
}
2005-02-06 16:49:50 +01:00
}
}
}
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
else
{
unset ( $this -> data );
// for the moment we make $this->data as a referenz to the first grid
foreach ( $this -> children as $key => $child )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
if ( $child [ 'type' ] == 'grid' )
2005-02-06 16:49:50 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> data = & $this -> children [ $key ][ 'data' ];
$this -> rows = & $this -> children [ $key ][ 'rows' ];
$this -> cols = & $this -> children [ $key ][ 'cols' ];
if ( ! isset ( $this -> children [ $key ][ 'size' ]) && ! empty ( $this -> size ))
2005-02-18 23:44:42 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> children [ $key ][ 'size' ] = & $this -> size ;
2005-02-18 23:44:42 +01:00
}
2008-03-09 15:41:22 +01:00
else
{
$this -> size = & $this -> children [ $key ][ 'size' ];
}
break ;
2005-02-06 16:49:50 +01:00
}
2005-02-23 15:33:00 +01:00
}
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
$this -> set_rows_cols ();
}
2002-02-06 10:03:11 +01:00
2009-03-16 13:58:24 +01:00
static private $compress_array_recursion = array ();
2008-03-09 15:41:22 +01:00
/**
* all empty values and objects in the array got unset ( to save space in the db )
*
* The never empty type field ensures a cell does not disapear completely .
* Calls it self recursivly for arrays / the rows
*
* @ param array $arr the array to compress
* @ param boolean $remove_all_objs if true unset all objs , on false use as_array to save only the data of objs
* @ return array
*/
2008-03-09 16:48:21 +01:00
function compress_array ( $arr , $remove_objs = false )
2008-03-09 15:41:22 +01:00
{
2009-03-16 13:58:24 +01:00
static $recursion = array ();
2008-03-09 15:41:22 +01:00
if ( ! is_array ( $arr ))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
return $arr ;
}
foreach ( $arr as $key => $val )
{
if ( $remove_objs && $key === 'obj' ) // it can be an array too
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
unset ( $arr [ $key ]);
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
elseif ( is_array ( $val ))
2002-02-06 10:03:11 +01:00
{
2008-03-09 16:48:21 +01:00
$arr [ $key ] = $this -> compress_array ( $val , $remove_objs );
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
elseif ( ! $remove_objs && $key == 'obj' && is_object ( $val ) && method_exists ( $val , 'as_array' ) &&
// this test prevents an infinit recursion of templates calling itself, atm. etemplate.editor.new
2009-03-16 13:58:24 +01:00
self :: $compress_array_recursion [ $this -> name ] ++ < 2 )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$arr [ 'obj' ] = $val -> as_array ( 2 );
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
elseif ( $val == '' || is_object ( $val ))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
unset ( $arr [ $key ]);
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
}
return $arr ;
}
/**
* returns obj - data /- vars as array
*
2008-06-22 09:16:40 +02:00
* the returned array ( $data_too > 0 ) can be used with init to recreate the template
2008-03-09 15:41:22 +01:00
*
2008-06-22 09:16:40 +02:00
* @ param int $data_too - 1 = only keys , 0 = no data array , 1 = data array too , 2 = serialize data array ,
2008-03-09 15:41:22 +01:00
* 3 = only data values and data serialized
* @ param boolean $db_keys use db - column - names or internal names , default false = internal names
* @ return array with template - data
*/
function as_array ( $data_too = 0 , $db_keys = false )
{
//echo "<p>soetemplate::as_array($data_too,$db_keys) name='$this->name', ver='$this->version'</p>\n";
$arr = array ();
switch ( $data_too )
{
case - 1 :
$cols = self :: $db_key_cols ;
break ;
case 3 :
$cols = self :: $db_data_cols ;
break ;
default :
$cols = self :: $db_cols ;
}
foreach ( $cols as $db_col => $col )
{
if ( $col == 'data' )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
if ( $data_too > 0 )
{
$arr [ $db_keys ? $db_col : $col ] = $data_too < 2 ? $this -> children :
serialize ( $this -> compress_array ( $this -> children , $db_keys ));
}
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
else
2002-09-27 18:17:39 +02:00
{
2008-03-09 15:41:22 +01:00
$arr [ $db_keys ? $db_col : $col ] = $this -> $col ;
2002-09-27 18:17:39 +02:00
}
2008-03-09 15:41:22 +01:00
}
2008-06-22 09:16:40 +02:00
if ( $data_too != - 1 && $this -> tpls_in_file && ! $db_keys )
2008-03-09 15:41:22 +01:00
{
$arr [ 'tpls_in_file' ] = $this -> tpls_in_file ;
}
2008-06-22 09:16:40 +02:00
if ( $data_too != - 1 && $this -> onclick_handler && ! $db_keys )
2008-03-09 15:41:22 +01:00
{
$arr [ 'onclick_handler' ] = $this -> onclick_handler ;
}
return $arr ;
}
/**
* saves eTemplate - object to db , can be used as saveAs by giving keys as params
*
* @ param string $name name of the eTemplate or array with the values for all keys
* @ param string $template template - set
* @ param string $lang language or ''
* @ param int $group id of the ( primary ) group , not used at the moment !!!
* @ param string $version version of the eTemplate
* @ return int number of affected rows , 1 should be ok , 0 somethings wrong
*/
function save ( $name = '' , $template = '.' , $lang = '.' , $group = '' , $version = '.' )
{
if ( is_array ( $name ))
{
$template = $name [ 'template' ];
$lang = $name [ 'lang' ];
$group = $name [ 'group' ];
$version = $name [ 'version' ];
$name = $name [ 'name' ];
}
if ( $name != '' )
{
$this -> name = $name ;
}
if ( $lang != '.' )
{
$this -> lang = $lang ;
}
if ( $template != '.' )
{
$this -> template = $template ;
}
if ( $group != '' )
{
$this -> group = $group ;
}
if ( $version != '.' )
{
$this -> version = $version ;
}
if ( $this -> name == '' ) // name need to be set !!!
{
return False ;
}
if ( $this -> debug > 0 || $this -> debug == $this -> name )
{
echo " <p>soetemplate::save(' $this->name ',' $this->template ',' $this->lang ', $this->group ,' $this->version ')</p> \n " ;
}
if ( $this -> name [ 0 ] != '.' && is_array ( $this -> data )) // correct old messed up templates
{
reset ( $this -> data ); each ( $this -> data );
while ( list ( $row , $cols ) = each ( $this -> data ))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
while ( list ( $col , $cell ) = each ( $cols ))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
if ( is_array ( $cell [ 'type' ])) {
$this -> data [ $row ][ $col ][ 'type' ] = $cell [ 'type' ][ 0 ];
//echo "corrected in $this->name cell $col$row attribute type<br>\n";
}
if ( is_array ( $cell [ 'align' ])) {
$this -> data [ $row ][ $col ][ 'align' ] = $cell [ 'align' ][ 0 ];
//echo "corrected in $this->name cell $col$row attribute align<br>\n";
2002-02-06 10:03:11 +01:00
}
}
}
}
2008-03-09 15:41:22 +01:00
if ( ! $this -> modified )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> modified = time ();
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
if ( is_null ( $this -> group ) && ! is_int ( $this -> group )) $this -> group = 0 ;
$this -> db -> insert ( self :: TABLE , $this -> as_array ( 3 , true ), $this -> as_array ( - 1 , true ), __LINE__ , __FILE__ , 'etemplate' );
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
if ( ! ( $rows = $this -> db -> affected_rows ()))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
echo " <p>soetemplate::save(' $this->name ',' $this->template ',' $this->lang ', $this->group ,' $this->version ') <b>nothing written!!!</b></p> \n " ;
function_backtrace ();
_debug_array ( $this -> db );
}
return $rows ;
}
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
/**
* Deletes the eTemplate from the db , object itself is unchanged
*
* @ return int number of affected rows , 1 should be ok , 0 somethings wrong
*/
function delete ()
{
$this -> db -> delete ( self :: TABLE , $this -> as_array ( - 1 , true ), __LINE__ , __FILE__ , 'etemplate' );
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
return $this -> db -> affected_rows ();
}
2002-02-15 06:27:30 +01:00
2006-04-21 12:31:06 +02:00
/**
2008-03-09 15:41:22 +01:00
* dumps all eTemplates to < app >/ setup / etemplates . inc . php for distribution
2006-04-21 12:31:06 +02:00
*
2008-03-09 15:41:22 +01:00
* @ param string $app app - or template - name contain app
* @ return string translated message with number of dumped templates or error - message ( webserver has no write access )
*/
function dump4setup ( $app )
{
list ( $app ) = explode ( '.' , $app );
2002-10-03 13:10:52 +02:00
2008-03-09 15:41:22 +01:00
$dir = EGW_SERVER_ROOT . " / $app /setup " ;
if ( ! is_writeable ( $dir ))
{
return lang ( " Error: webserver is not allowed to write into '%1' !!! " , $dir );
}
$file = " $dir /etemplates.inc.php " ;
if ( file_exists ( $file ))
{
$old_file = " $dir /etemplates.old.inc.php " ;
if ( file_exists ( $old_file ))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
unlink ( $old_file );
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
rename ( $file , $old_file );
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
if ( ! ( $f = fopen ( $file , 'w' )))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
return 0 ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
fwrite ( $f , ' < ? php
/**
* eGroupWare - eTemplates for Application '. $app. '
2008-06-22 09:16:40 +02:00
* http :// www . egroupware . org
2008-03-09 15:41:22 +01:00
* generated by soetemplate :: dump4setup () '.date(' Y - m - d H : i '). '
*
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ package '. $app. '
* @ subpackage setup
* @ version $Id $
*/ ' . " \n \n \$ templ_version=1; \n \n " );
$n = 0 ;
foreach ( $this -> db -> select ( self :: TABLE , '*' , 'et_name LIKE ' . $this -> db -> quote ( $app . '%' ), __LINE__ , __FILE__ , false , '' , egw_db :: FETCH_ASSOC ) as $row )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$str = '$templ_data[] = array(' ;
foreach ( self :: $db_cols as $db_col => $name )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
// escape only backslashes and single quotes (in that order)
$str .= " ' $name ' => ' " . str_replace ( array ( '\\' , '\'' , " \r " ), array ( '\\\\' , '\\\'' , '' ), $row [ $db_col ]) . " ', " ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
$str .= " ); \n \n " ;
fwrite ( $f , $str );
++ $n ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
fclose ( $f );
return lang ( " %1 eTemplates for Application '%2' dumped to '%3' " , $n , $app , $file );
}
/**
* extracts all texts : labels and helptexts from the cells of an eTemplate - object
*
* some extensions use a '|' to squezze multiple texts in a label or help field
*
* @ return array with messages as key AND value
*/
function getToTranslate ()
{
$to_trans = array ();
$this -> widget_tree_walk ( array ( 'soetemplate' , 'getToTranslateCell' ), $to_trans );
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
//echo '<b>'.$this->name.'</b>'; _debug_array($to_trans);
return $to_trans ;
}
/**
* Read all eTemplates of an app an extracts the texts to an array
*
* @ param string $app name of the app
* @ return array with texts
*/
function getToTranslateApp ( $app )
{
$to_trans = array ();
$tpls = $this -> search ( $app );
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
$tpl =& new soetemplate ; // to not alter our own data
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
while ( list (, $keys ) = each ( $tpls ))
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
if (( $keys [ 'name' ] != $last [ 'name' ] || // write only newest version
$keys [ 'template' ] != $last [ 'template' ]) &&
strpos ( $keys [ 'name' ], 'test' ) === false )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$tpl -> read ( $keys );
$to_trans += $tpl -> getToTranslate ();
$last = $keys ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
}
return $to_trans ;
}
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
/**
* Write new lang - file using the existing one and all text from the eTemplates
*
* @ param string $app app - or template - name
* @ param string $lang language the messages in the template are , defaults to 'en'
* @ param array $additional extra texts to translate , if you pass here an array with all messages and
* select - options they get writen too ( form is < unique key > => < message > )
* @ return string translated message with number of messages written ( total and new ), or error - message
*/
function writeLangFile ( $app , $lang = 'en' , $additional = '' )
{
if ( ! $additional )
{
$additional = array ();
}
list ( $app ) = explode ( '.' , $app );
if ( ! file_exists ( EGW_SERVER_ROOT . '/developer_tools/inc/class.solangfile.inc.php' ))
{
$solangfile =& CreateObject ( 'etemplate.solangfile' );
}
else
{
$solangfile =& CreateObject ( 'developer_tools.solangfile' );
}
$langarr = $solangfile -> load_app ( $app , $lang );
if ( ! is_array ( $langarr ))
{
$langarr = array ();
}
$commonarr = $solangfile -> load_app ( 'phpgwapi' , $lang ) + $solangfile -> load_app ( 'etemplate' , $lang );
2003-08-28 16:31:11 +02:00
2008-03-09 15:41:22 +01:00
$to_trans = $this -> getToTranslateApp ( $app );
if ( is_array ( $additional ))
{
//echo "writeLangFile: additional ="; _debug_array($additional);
foreach ( $additional as $msg )
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
if ( ! is_array ( $msg )) $to_trans [ trim ( strtolower ( $msg ))] = $msg ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
}
unset ( $to_trans [ '' ]);
2002-10-12 18:37:44 +02:00
2008-03-09 15:41:22 +01:00
for ( $new = $n = 0 ; list ( $message_id , $content ) = each ( $to_trans ); ++ $n )
{
if ( ! isset ( $langarr [ $message_id ]) && ! isset ( $commonarr [ $message_id ]))
2003-08-28 16:31:11 +02:00
{
2008-03-09 15:41:22 +01:00
if ( @ isset ( $langarr [ $content ])) // caused by not lowercased-message_id's
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
unset ( $langarr [ $content ]);
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
$langarr [ $message_id ] = array (
'message_id' => $message_id ,
'app_name' => $app ,
'content' => $content
);
++ $new ;
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
}
ksort ( $langarr );
2002-02-14 15:06:53 +01:00
2008-03-09 15:41:22 +01:00
$dir = EGW_SERVER_ROOT . " / $app /setup " ;
if ( ! is_writeable ( $dir ))
{
return lang ( " Error: webserver is not allowed to write into '%1' !!! " , $dir );
}
$file = " $dir /phpgw_ $lang .lang " ;
if ( file_exists ( $file ))
{
$old_file = " $dir /phpgw_ $lang .old.lang " ;
if ( file_exists ( $old_file ))
2002-02-14 15:06:53 +01:00
{
2008-03-09 15:41:22 +01:00
unlink ( $old_file );
2002-02-14 15:06:53 +01:00
}
2008-03-09 15:41:22 +01:00
rename ( $file , $old_file );
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
$solangfile -> write_file ( $app , $langarr , $lang );
$solangfile -> loaddb ( $app , $lang );
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
return lang ( " %1 (%2 new) Messages writen for Application '%3' and Languages '%4' " , $n , $new , $app , $lang );
}
/**
* Imports the dump - file / $app / setup / etempplates . inc . php unconditional ( ! )
*
* @ param string $app app name
* @ return string translated message with number of templates imported
*/
static function import_dump ( $app )
{
$templ_version = 0 ;
2005-02-18 23:44:42 +01:00
2008-03-09 15:41:22 +01:00
include ( $path = EGW_SERVER_ROOT . " / $app /setup/etemplates.inc.php " );
$templ =& new etemplate ( $app );
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
foreach ( $templ_data as $data )
{
if (( int ) $templ_version < 1 ) // we need to stripslashes
2002-02-06 10:03:11 +01:00
{
2008-03-09 15:41:22 +01:00
$data [ 'data' ] = stripslashes ( $data [ 'data' ]);
}
$templ -> init ( $data );
2005-02-06 16:49:50 +01:00
2008-03-09 15:41:22 +01:00
if ( ! $templ -> modified )
{
$templ -> modified = filemtime ( $path );
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
$templ -> save ();
2002-02-06 10:03:11 +01:00
}
2008-03-09 15:41:22 +01:00
return lang ( " %1 new eTemplates imported for Application '%2' " , $n , $app );
}
2002-02-06 10:03:11 +01:00
2009-03-16 13:58:24 +01:00
static private $import_tested = array ();
2008-03-09 15:41:22 +01:00
/**
* test if new template - import necessary for app and does the import
*
* Get called on every read of a eTemplate , caches the result in phpgw_info .
* The timestamp of the last import for app gets written into the db .
*
* @ param string $app app - or template - name
* @ return string translated message with number of templates imported
*/
static function test_import ( $app ) // should be done from the setup-App
{
list ( $app ) = explode ( '.' , $app );
2002-02-06 10:03:11 +01:00
2009-03-16 13:58:24 +01:00
if ( ! $app || self :: $import_tested [ $app ])
2008-03-09 15:41:22 +01:00
{
return '' ; // ensure test is done only once per call and app
}
2009-03-16 13:58:24 +01:00
self :: $import_tested [ $app ] = True ; // need to be done before new ...
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
$path = EGW_SERVER_ROOT . " / $app /setup/etemplates.inc.php " ;
2002-02-06 10:03:11 +01:00
2008-03-09 15:41:22 +01:00
if ( $time = @ filemtime ( $path ))
{
$templ =& new soetemplate ( " . $app " , '' , '##' );
if ( $templ -> lang != '##' || $templ -> modified < $time ) // need to import
2002-02-06 10:03:11 +01:00
{
2008-03-09 16:54:52 +01:00
$ret = self :: import_dump ( $app );
2008-03-09 15:41:22 +01:00
$templ -> modified = $time ;
$templ -> save ( '.' . $app , '' , '##' );
2002-02-06 10:03:11 +01:00
}
}
2008-03-09 15:41:22 +01:00
return $ret ;
}
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
/**
* prints / echos the template ' s content , eg . for debuging
*
* @ param boolean $backtrace = true give a function backtrace
* @ param boolean $no_other_objs = true dump other objs ( db , html , ... ) too
*/
function echo_tmpl ( $backtrace = true , $no_other_objs = true )
{
static $objs = array ( 'db' , 'html' , 'xul_io' );
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
if ( $backtrace ) echo " <p> " . function_backtrace ( 1 ) . " </p> \n " ;
2005-02-06 16:49:50 +01:00
2008-03-09 15:41:22 +01:00
if ( $no_other_objs )
{
foreach ( $objs as $obj )
2005-02-06 16:49:50 +01:00
{
2008-03-09 15:41:22 +01:00
$$obj = & $this -> $obj ;
unset ( $this -> $obj );
2005-02-06 16:49:50 +01:00
}
2008-03-09 15:41:22 +01:00
}
_debug_array ( $this );
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
if ( $no_other_objs )
{
foreach ( $objs as $obj )
2005-02-06 16:49:50 +01:00
{
2008-03-09 15:41:22 +01:00
$this -> $obj = & $$obj ;
unset ( $$obj );
2005-02-06 16:49:50 +01:00
}
}
2008-03-09 15:41:22 +01:00
}
2005-02-13 14:03:01 +01:00
2008-03-09 15:41:22 +01:00
/**
* applys a function to each widget in the children tree of the template
*
* The function should be defined as [ & ] func ([ & ] $widget ,[ & ] $extra [, $path ])
2008-06-22 09:16:40 +02:00
* If the function returns anything but null or sets $extra [ '__RETURN__NOW__' ] ( func has to reference $extra !!! ),
2008-03-09 15:41:22 +01:00
* the walk stops imediatly and returns that result
*
* Only some widgets have a sub - tree of children : * box , grid , template , ...
* For them we call tree_walk ( $widget , $func , $extra ) instead of func direct
2008-06-22 09:16:40 +02:00
*
2008-03-09 15:41:22 +01:00
* Please note : as call_user_func_array does not return references , methods ( $func is an array ) can not either !!!
*
* @ param string / array $func function to use or array ( $obj , 'method' )
* @ param mixed & $extra extra parameter passed to function
* @ param string $path = '/' start - path
* @ return mixed return - value of func or null if nothing returned at all
*/
function & widget_tree_walk ( $func , & $extra , $path = '/' )
{
if ( ! is_callable ( $func ))
{
echo " <p><b>boetemplate( $this->name )::widget_tree_walk</b>( " . print_r ( $func , true ) . " , " . print_r ( $extra , true ) . " , " . print_r ( $opts , true ) . " ) func is not callable !!!<br> " . function_backtrace () . " </p> " ;
return false ;
2005-02-13 14:03:01 +01:00
}
2008-03-09 15:41:22 +01:00
foreach ( $this -> children as $c => & $child )
{
$child = & $this -> children [ $c ];
if ( isset ( soetemplate :: $widgets_with_children [ $child [ 'type' ]]))
2005-02-13 14:03:01 +01:00
{
2008-03-09 15:41:22 +01:00
$result =& $this -> tree_walk ( $child , $func , $extra , $path . $c );
2005-02-13 14:03:01 +01:00
}
2008-03-09 15:41:22 +01:00
elseif ( is_array ( $func ))
2007-03-07 13:30:17 +01:00
{
2008-03-09 15:41:22 +01:00
$result =& call_user_func_array ( $func , array ( & $child , & $extra , $path . $c ));
2007-03-07 13:30:17 +01:00
}
else
{
2008-03-09 15:41:22 +01:00
$result =& $func ( $child , $extra , $path . $c );
2005-02-13 14:03:01 +01:00
}
2008-03-09 15:41:22 +01:00
if ( ! is_null ( $result ) || is_array ( $extra ) && isset ( $extra [ '__RETURN_NOW__' ])) break ;
}
return $result ;
}
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
/**
2008-06-22 09:16:40 +02:00
* applys a function to each child in the tree of a widget ( incl . the widget itself )
2008-03-09 15:41:22 +01:00
*
* The function should be defined as [ & ] func ([ & ] $widget ,[ & ] $extra [, $path ]) [] = optional
2008-06-22 09:16:40 +02:00
* If the function returns anything but null or sets $extra [ '__RETURN__NOW__' ] ( func has to reference $extra !!! ),
2008-03-09 15:41:22 +01:00
* the walk stops imediatly and returns that result
*
* Only some widgets have a sub - tree of children : * box , grid , template , ...
2008-06-22 09:16:40 +02:00
* For performance reasons the function use recursion only if a widget with children contains
2008-03-09 15:41:22 +01:00
* a further widget with children .
*
* @ param array $widget the widget ( - tree ) the function should be applied too
* @ param string / array $func function to use or array ( $obj , 'method' )
* @ param mixed & $extra extra parameter passed to function
* @ param string $path path of widget in the widget - tree
* @ return mixed return - value of func or null if nothing returned at all
*/
function & tree_walk ( & $widget , $func , & $extra , $path = '' )
{
if ( ! is_callable ( $func ))
{
echo " <p><b>boetemplate::tree_walk</b>(, " . print_r ( $func , true ) . " , " . print_r ( $extra , true ) . " , " . print_r ( $opts , true ) . " ) func is not callable !!!<br> " . function_backtrace () . " </p> " ;
return false ;
}
if ( is_array ( $func ))
{
$result =& call_user_func_array ( $func , array ( & $widget , & $extra , $path ));
}
else
{
$result =& $func ( $widget , $extra , $path );
}
2008-06-22 09:16:40 +02:00
if ( ! is_null ( $result ) || is_array ( $extra ) && isset ( $extra [ '__RETURN__NOW__' ]) ||
2008-03-09 15:41:22 +01:00
! isset ( soetemplate :: $widgets_with_children [ $widget [ 'type' ]]))
{
return $result ;
}
switch ( $widget [ 'type' ])
{
case 'box' :
case 'vbox' :
case 'hbox' :
case 'groupbox' :
case 'deck' :
for ( $n = 1 ; is_array ( $widget [ $n ]); ++ $n )
{
$child = & $widget [ $n ];
if ( isset ( soetemplate :: $widgets_with_children [ $child [ 'type' ]]))
{
$result =& $this -> tree_walk ( $child , $func , $extra , $path . '/' . $n );
}
elseif ( is_array ( $func ))
{
$result =& call_user_func_array ( $func , array ( & $child , & $extra , $path . '/' . $n ));
}
else
{
$result =& $func ( $child , $extra , $path . '/' . $n );
}
if ( ! is_null ( $result ) || is_array ( $extra ) && isset ( $extra [ '__RETURN__NOW__' ])) return $result ;
}
break ;
case 'grid' :
$data = & $widget [ 'data' ];
if ( ! is_array ( $data )) break ; // no children
foreach ( $data as $r => $row )
{
if ( ! $r || ! is_array ( $row )) continue ;
foreach ( $row as $c => $col )
2005-02-13 14:03:01 +01:00
{
2008-03-09 15:41:22 +01:00
$child = & $data [ $r ][ $c ];
if ( isset ( soetemplate :: $widgets_with_children [ $child [ 'type' ]]))
2005-02-13 14:03:01 +01:00
{
2008-03-09 15:41:22 +01:00
$result =& $this -> tree_walk ( $child , $func , $extra , $path . '/' . $r . $c );
2005-02-13 14:03:01 +01:00
}
2007-03-07 13:30:17 +01:00
elseif ( is_array ( $func ))
{
2008-03-09 15:41:22 +01:00
$result =& call_user_func_array ( $func , array ( & $child , & $extra , $path . '/' . $r . $c ));
2007-03-07 13:30:17 +01:00
}
2005-02-13 14:03:01 +01:00
else
{
2008-03-09 15:41:22 +01:00
$result =& $func ( $child , $extra , $path . '/' . $r . $c );
2005-02-13 14:03:01 +01:00
}
2005-02-16 00:22:10 +01:00
if ( ! is_null ( $result ) || is_array ( $extra ) && isset ( $extra [ '__RETURN__NOW__' ])) return $result ;
2008-03-09 15:41:22 +01:00
unset ( $child );
2005-02-13 14:03:01 +01:00
}
2008-03-09 15:41:22 +01:00
}
break ;
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
case 'template' :
if ( ! isset ( $widget [ 'obj' ]) && $widget [ 'name' ][ 0 ] != '@' )
{
$widget [ 'obj' ] =& new etemplate ;
if ( ! $widget [ 'obj' ] -> read ( $widget [ 'name' ])) $widget [ 'obj' ] = false ;
}
if ( ! is_object ( $widget [ 'obj' ])) break ; // cant descent into template
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
$result =& $widget [ 'obj' ] -> widget_tree_walk ( $func , $extra , $path . '/' );
break ;
2005-02-13 14:03:01 +01:00
}
2008-03-09 15:41:22 +01:00
return $result ;
2005-02-13 14:03:01 +01:00
}
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
/**
* extracts all translatable labels from a widget
*
* @ param array $cell the widget
* @ param array & $to_trans array with ( lowercased ) label => translation pairs
*/
static function getToTranslateCell ( $cell , & $to_trans )
2005-02-13 14:03:01 +01:00
{
2008-03-09 15:41:22 +01:00
//echo $cell['name']; _debug_array($cell);
$strings = explode ( '|' , $cell [ 'help' ]);
if ( $cell [ 'type' ] != 'image' )
{
$strings = array_merge ( $strings , explode ( '|' , $cell [ 'label' ]));
}
list ( $extra_row ) = explode ( ',' , $cell [ 'size' ]);
if ( substr ( $cell [ 'type' ], 0 , 6 ) == 'select' && ! empty ( $extra_row ) && ! intval ( $extra_row ))
{
$strings [] = $extra_row ;
}
if ( ! empty ( $cell [ 'blur' ]))
{
$strings [] = $cell [ 'blur' ];
}
foreach ( $strings as $str )
{
2008-06-22 09:16:40 +02:00
if ( strlen ( $str ) > 1 && $str { 0 } != '@' && $str { 0 } != '$' &&
2008-03-09 15:41:22 +01:00
strpos ( $str , '$row' ) === false && strpos ( $str , '$cont' ) === false )
2005-02-13 14:03:01 +01:00
{
2008-03-09 15:41:22 +01:00
$to_trans [ trim ( strtolower ( $str ))] = $str ;
2005-02-13 14:03:01 +01:00
}
}
}
2008-06-22 09:16:40 +02:00
2008-03-09 15:41:22 +01:00
/**
* init our static vars
*/
static function _init_static ()
{
self :: $db_cols = self :: $db_key_cols + self :: $db_data_cols ;
}
}
soetemplate :: _init_static ();