2002-09-17 23:31:45 +02:00
< ? php
2008-06-22 09:16:40 +02:00
/**
* eGroupWare eTemplate Extension - Nextmatch Widget
*
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
2009-03-16 13:58:24 +01:00
* @ copyright 2002 - 9 by RalfBecker @ outdoor - training . de
2008-06-22 09:16:40 +02:00
* @ package etemplate
* @ subpackage extensions
* @ link http :// www . egroupware . org
* @ author Ralf Becker < RalfBecker @ outdoor - training . de >
* @ version $Id $
*/
/**
* eTemplate Extension : Widget that show only a certain number of data - rows and allows to modifiy the rows shown ( scroll ) .
*
* This widget replaces the old nextmatch - class . It is independent of the UI ,
* as it only uses etemplate - widgets and has therefor no render - function
*
* $content [ $id ] = array ( // I = value set by the app, 0 = value on return / output
* 'get_rows' => // I method/callback to request the data for the rows eg. 'notes.bo.get_rows'
* 'filter_label' => // I label for filter (optional)
* 'filter_help' => // I help-msg for filter (optional)
* 'no_filter' => True // I disable the 1. filter
* 'no_filter2' => True // I disable the 2. filter (params are the same as for filter)
* 'no_cat' => True // I disable the cat-selectbox
* 'cat_app' => // I application the cat's should be from, default app in get_rows
* 'template' => // I template to use for the rows, if not set via options
* 'header_left' => // I template to show left of the range-value, left-aligned (optional)
* 'header_right' => // I template to show right of the range-value, right-aligned (optional)
* 'bottom_too' => True // I show the nextmatch-line (arrows, filters, search, ...) again after the rows
* 'never_hide' => True // I never hide the nextmatch-line if less then maxmatch entries
* 'lettersearch' => True // I show a lettersearch
* 'searchletter' => // I0 active letter of the lettersearch or false for [all]
* 'start' => // IO position in list
* 'num_rows' => // IO number of rows to show, defaults to maxmatches from the general prefs
* 'cat_id' => // IO category, if not 'no_cat' => True
* 'search' => // IO search pattern
* 'order' => // IO name of the column to sort after (optional for the sortheaders)
* 'sort' => // IO direction of the sort: 'ASC' or 'DESC'
* 'col_filter' => // IO array of column-name value pairs (optional for the filterheaders)
* 'filter' => // IO filter, if not 'no_filter' => True
* 'filter_no_lang' => True // I set no_lang for filter (=dont translate the options)
* 'filter_onchange' => 'this.form.submit();' // I onChange action for filter, default: this.form.submit();
* 'filter2' => // IO filter2, if not 'no_filter2' => True
* 'filter2_no_lang' => True // I set no_lang for filter2 (=dont translate the options)
* 'filter2_onchange' => 'this.form.submit();' // I onChange action for filter2, default: this.form.submit();
* 'rows' => // O content set by callback
* 'total' => // O the total number of entries
* 'sel_options' => // O additional or changed sel_options set by the callback and merged into $tmpl->sel_options
* 'no_columnselection' => // I turns off the columnselection completly, turned on by default
* 'columnselection-pref' => // I name of the preference (plus 'nextmatch-' prefix), default = template-name
* 'default_cols' => // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
* 'options-selectcols' => // I array with name/label pairs for the column-selection, this gets autodetected by default. A name => false suppresses a column completly.
* 'return' => // IO allows to return something from the get_rows function if $query is a var-param!
* 'csv_fields' => // I false=disable csv export, true or unset=enable it with auto-detected fieldnames,
* or array with name => label or name => array ( 'label' => label , 'type' => type ) pairs ( type is a eT widget - type )
* );
*/
class nextmatch_widget
{
2006-04-20 19:12:30 +02:00
/**
2008-06-22 09:16:40 +02:00
* Prefix for custom field names
2006-04-20 19:12:30 +02:00
*
*/
2008-06-22 09:16:40 +02:00
const CF_PREFIX = '#' ;
2002-09-17 23:31:45 +02:00
2008-06-22 09:16:40 +02:00
/**
* exported methods of this class
* @ var array
*/
var $public_functions = array (
'pre_process' => True ,
'post_process' => True ,
);
/**
* availible extensions and there names for the editor
* @ var array
*/
var $human_name = array (
'nextmatch' => 'Nextmatch' ,
'nextmatch-sortheader' => 'Nextmatch Sortheader' ,
'nextmatch-filterheader' => 'Nextmatch Filterheader' ,
'nextmatch-accountfilter' => 'Nextmatch Accountfilter' ,
'nextmatch-customfilter' => 'Nextmatch Custom Filterheader' ,
'nextmatch-header' => 'Nextmatch Header' ,
'nextmatch-customfields' => 'Nextmatch Custom Fields Header' ,
);
2008-06-11 06:05:10 +02:00
2005-02-18 23:44:42 +01:00
/**
2008-06-22 09:16:40 +02:00
* Turn on debug messages ( mostly in post_process )
2005-02-18 23:44:42 +01:00
*
2008-06-22 09:16:40 +02:00
* @ var boolean
*/
var $debug = false ;
/**
* Vars used to comunicated for the custom field header
2005-02-18 23:44:42 +01:00
*
2008-06-22 09:16:40 +02:00
* @ var unknown_type
2005-02-18 23:44:42 +01:00
*/
2008-06-22 09:16:40 +02:00
private $selectcols ;
public $cf_header ;
private $cfs ;
/**
* Constructor of the extension
*
* @ param string $ui '' for html
*/
function nextmatch_widget ( $ui )
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
}
2008-01-19 06:36:20 +01:00
2008-06-22 09:16:40 +02:00
/**
* returns last part of a form - name
*
* @ param string $name
* @ return string
*/
static private function last_part ( $name )
{
list ( $last ) = self :: get_parts ( $name , - 1 , 1 );
return $last ;
}
2002-09-17 23:31:45 +02:00
2008-06-22 09:16:40 +02:00
/**
* returns last part of a form - name
*
* @ param string $name
* @ param int $offset positive or negative offset ( negative is count from the end )
* @ param int $length = null positiv means return $length elements , negative return til negative offset in $length , default = null means all
* @ return array
*/
static private function get_parts ( $name , $offset , $length = null )
{
$parts = explode ( '[' , str_replace ( ']' , '' , $name ));
2008-08-16 09:40:04 +02:00
// php5.1 seems to have a bug: array_slice($parts,$offeset) != array_slice($parts,$offeset,null)
return is_null ( $length ) ? array_slice ( $parts , $offset ) : array_slice ( $parts , $offset , $length );
2008-06-22 09:16:40 +02:00
}
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
/**
* Return global storages shared within the parts of a nextmatch widget ( including all nextmatch -* subwidgets )
*
* @ param string $name
* @ param string $type
* @ return mixed reference to storage : use =& to assign !
*/
static private function & get_nm_global ( $name , $type )
{
static $nm_globals = array ();
2003-12-09 01:03:41 +01:00
2008-06-22 09:16:40 +02:00
// extract the original nextmatch name from $name, taken into account the type of nextmatch-* subwidgets
$nm_global = implode ( '/' , self :: get_parts ( $name , 1 , $type == 'nextmatch' ? null : - 2 ));
//echo '<p>'.__METHOD__."($name,$type) = $nm_global</p>\n";
2008-06-11 06:20:39 +02:00
2008-06-22 09:16:40 +02:00
return $nm_globals [ $nm_global ];
}
2008-06-11 06:20:39 +02:00
2008-06-22 09:16:40 +02:00
/**
* pre - processing of the extension
*
* This function is called before the extension gets rendered
*
* @ param string $name form - name of the control
* @ param mixed & $value value / existing content , can be modified
* @ param array & $cell array with the widget , can be modified for ui - independent widgets
* @ param array & $readonlys names of widgets as key , to be made readonly
* @ param mixed & $extension_data data the extension can store persisten between pre - and post - process
* @ param etemplate & $tmpl reference to the template we belong too
* @ return boolean true if extra label is allowed , false otherwise
*/
function pre_process ( $name , & $value , array & $cell , & $readonlys , & $extension_data , etemplate & $tmpl )
{
$nm_global =& self :: get_nm_global ( $name , $cell [ 'type' ]);
//echo "<p>nextmatch_widget.pre_process(name='$name',type='$cell[type]'): value = "; _debug_array($value);
//echo "<p>nextmatch_widget.pre_process(name='$name',type='$cell[type]'): nm_global = "; _debug_array($nm_global);
2008-06-11 06:20:39 +02:00
2008-06-22 09:16:40 +02:00
$extension_data = array (
'type' => $cell [ 'type' ]
);
switch ( $cell [ 'type' ])
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
case 'nextmatch-header' :
$cell [ 'type' ] = 'label' ;
return true ; // false = no extra label
case 'nextmatch-sortheader' : // Option: default sort: ASC(default) or DESC
$extension_data [ 'default_sort' ] = $cell [ 'size' ] && preg_match ( '/^(ASC|DESC)/i' , $cell [ 'size' ], $matches ) ? strtoupper ( $matches [ 1 ]) : 'ASC' ;
2008-10-05 18:56:37 +02:00
$cell [ 'type' ] = $cell [ 'readonly' ] ? 'label' : 'button' ;
2008-06-22 09:16:40 +02:00
$cell [ 'onchange' ] = True ;
if ( ! $cell [ 'help' ])
2006-03-27 17:08:47 +02:00
{
2008-06-22 09:16:40 +02:00
$cell [ 'help' ] = 'click to order after that criteria' ;
2006-03-27 17:08:47 +02:00
}
2008-10-05 18:56:37 +02:00
if ( self :: last_part ( $name ) == $nm_global [ 'order' ] && ! $cell [ 'readonly' ]) // we're the active column
2005-03-14 00:38:37 +01:00
{
2008-06-22 09:16:40 +02:00
$sorting = $cell ;
unset ( $sorting [ 'align' ]);
unset ( $sorting [ 'span' ]);
$cell = etemplate :: empty_cell ( 'hbox' , '' , array (
'span' => $cell [ 'span' ],
'size' => '2,,0,0' ,
1 => $sorting ,
2 => etemplate :: empty_cell ( 'image' , $nm_global [ 'sort' ] != 'DESC' ? 'down' : 'up' ),
));
$class = 'activ_sortcolumn' ;
2005-03-14 00:38:37 +01:00
}
else
{
2008-06-22 09:16:40 +02:00
$class = 'inactiv_sortcolumn' ;
}
$parts = explode ( ',' , $cell [ 'span' ]);
$parts [ 1 ] .= ( $parts [ 1 ] ? ' ' : '' ) . $class ;
$cell [ 'span' ] = implode ( ',' , $parts );
return True ;
case 'nextmatch-accountfilter' : // Option: as for selectbox: [extra-label(default ALL)[,#lines(default 1)]]
$cell [ 'size' ] = 'select-account,' . $cell [ 'size' ];
// fall through
case 'nextmatch-customfilter' : // Option: widget-name, options as for selectbox
list ( $type , $cell [ 'size' ]) = explode ( ',' , $cell [ 'size' ], 2 );
// fall through
case 'nextmatch-filterheader' : // Option: as for selectbox: [extra-label(default ALL)[,#lines(default 1)]]
if ( ! $type ) $type = 'select' ;
$cell [ 'type' ] = $type ;
if ( ! $cell [ 'size' ])
{
$cell [ 'size' ] = 'All' ;
}
if ( ! $cell [ 'help' ])
{
$cell [ 'help' ] = 'select which values to show' ;
2005-03-14 00:38:37 +01:00
}
2008-06-22 09:16:40 +02:00
$cell [ 'onchange' ] = $cell [ 'noprint' ] = True ;
$parts = explode ( ',' , $cell [ 'span' ]);
$parts [ 1 ] .= ( $parts [ 1 ] ? ' ' : '' ) . 'filterheader' ;
$cell [ 'span' ] = implode ( ',' , $parts );
$extension_data [ 'old_value' ] = $value = $nm_global [ 'col_filter' ][ self :: last_part ( $name )];
return True ;
case 'nextmatch-customfields' :
return $this -> _pre_process_cf_header ( $cell , $tmpl );
}
2008-06-23 08:46:58 +02:00
// does NOT work with php5.2.6 ...
if ( version_compare ( PHP_VERSION , '5.2.6' , '>=' ))
{
$value [ 'bottom_too' ] = false ;
}
2008-06-22 09:16:40 +02:00
// presetting the selectboxes with their default values, to NOT loop, because post-process thinks they changed
if ( ! isset ( $value [ 'cat_id' ])) $value [ 'cat_id' ] = '' ;
if ( ! isset ( $value [ 'search' ])) $value [ 'search' ] = '' ;
foreach ( array ( 'filter' , 'filter2' ) as $f )
{
if ( ! isset ( $value [ $f ]))
{
list ( $value [ $f ]) = isset ( $tmpl -> sel_options [ $f ]) ? @ each ( $tmpl -> sel_options [ $f ]) : @ each ( $value [ 'options-' . $f ]);
if ( ! is_string ( $value [ $f ])) $value [ $f ] = ( string ) $value [ $f ];
2005-03-05 10:25:17 +01:00
}
2008-06-22 09:16:40 +02:00
}
// save values in persistent extension_data to be able use it in post_process
2008-11-13 17:55:03 +01:00
unset ( $value [ 'rows' ]);
2008-06-22 09:16:40 +02:00
$extension_data += $value ;
$value [ 'no_csv_export' ] = $value [ 'csv_fields' ] === false ||
2008-10-16 13:17:49 +02:00
$GLOBALS [ 'egw_info' ][ 'server' ][ 'export_limit' ] && ! is_numeric ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'export_limit' ]) &&
! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ]);
2008-06-22 09:16:40 +02:00
if ( ! $value [ 'filter_onchange' ]) $value [ 'filter_onchange' ] = 'this.form.submit();' ;
if ( ! $value [ 'filter2_onchange' ]) $value [ 'filter2_onchange' ] = 'this.form.submit();' ;
2006-12-04 15:39:22 +01:00
2008-06-22 09:16:40 +02:00
list ( $app , $class , $method ) = explode ( '.' , $value [ 'get_rows' ]);
if ( $app && $class )
{
if ( is_object ( $GLOBALS [ $class ])) // use existing instance (put there by a previous CreateObject)
2006-03-27 00:17:55 +02:00
{
2008-06-22 09:16:40 +02:00
$obj =& $GLOBALS [ $class ];
2006-03-27 00:17:55 +02:00
}
2008-06-22 09:16:40 +02:00
else
2006-03-27 00:17:55 +02:00
{
2008-06-22 09:16:40 +02:00
$obj =& CreateObject ( $app . '.' . $class );
2006-03-27 00:17:55 +02:00
}
2008-06-22 09:16:40 +02:00
}
if ( ! isset ( $value [ 'cat_app' ])) $value [ 'cat_app' ] = $app ; // if no cat_app set, use the app from the get_rows func
2006-03-27 00:17:55 +02:00
2008-06-22 09:16:40 +02:00
if ( ! ( $max = ( int ) $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'maxmatchs' ])) $max = 15 ;
$row_options = array ();
foreach ( array ( 5 , 12 , 25 , 50 , 100 , 200 , 500 , 999 ) as $n )
{
if ( $n - 5 <= $max && $max <= $n + 5 ) $n = $max ;
$row_options [ $n ] = $n ;
}
2009-01-23 20:33:19 +01:00
if ( ! isset ( $row_options [ $max ]) || ! isset ( $row_options [ $value [ 'num_rows' ]]))
2008-06-22 09:16:40 +02:00
{
$row_options [ $max ] = $max ;
2009-01-23 20:33:19 +01:00
$row_options [ $value [ 'num_rows' ]] = $value [ 'num_rows' ];
2008-06-22 09:16:40 +02:00
ksort ( $row_options );
}
$value [ 'options-num_rows' ] =& $row_options ;
if ( ! isset ( $value [ 'num_rows' ])) $extension_data [ 'num_rows' ] = $value [ 'num_rows' ] = $max ;
if ( $value [ 'num_rows' ] != $max )
{
$GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'maxmatchs' ] = $max = ( int ) $value [ 'num_rows' ];
}
if ( ! $value [ 'no_columnselection' ])
{
// presetting the options for selectcols empty, so the get_rows function can set it
$value [ 'options-selectcols' ] = array ();
}
2008-11-13 17:55:03 +01:00
$rows = array ();
2008-06-22 09:16:40 +02:00
if ( ! is_object ( $obj ) || ! method_exists ( $obj , $method ))
{
2009-03-16 13:58:24 +01:00
etemplate :: set_validation_error ( $name , " nextmatch_widget::pre_process( $cell[name] ): ' $value[get_rows] ' is no valid method !!! " );
2008-06-22 09:16:40 +02:00
}
else
{
if ( ! is_array ( $readonlys )) $readonlys = array ();
2008-11-13 17:55:03 +01:00
$total = $extension_data [ 'total' ] = $value [ 'total' ] = $obj -> $method ( $value , $rows , $readonlys [ 'rows' ]);
2008-06-22 09:16:40 +02:00
}
if ( $method && $total && $value [ 'start' ] >= $total )
{
$value [ 'start' ] = 0 ;
2008-11-13 17:55:03 +01:00
$total = $extension_data [ 'total' ] = $value [ 'total' ] = $obj -> $method ( $value , $rows , $readonlys [ 'rows' ]);
2008-06-22 09:16:40 +02:00
}
2008-11-13 17:55:03 +01:00
// allow the get_rows function to override / set sel_options
2008-11-16 08:20:23 +01:00
if ( isset ( $rows [ 'sel_options' ]) && is_array ( $rows [ 'sel_options' ]))
2008-06-22 09:16:40 +02:00
{
2008-11-13 17:55:03 +01:00
$tmpl -> sel_options = array_merge ( $tmpl -> sel_options , $rows [ 'sel_options' ]);
unset ( $rows [ 'sel_options' ]);
2008-06-22 09:16:40 +02:00
}
2008-11-13 17:55:03 +01:00
$value [ 'rows' ] =& $rows ;
unset ( $rows );
2008-06-22 09:16:40 +02:00
list ( $template , $options ) = explode ( ',' , $cell [ 'size' ]);
if ( ! $value [ 'template' ] && $template ) // template name can be supplied either in $value['template'] or the options-field
{
$value [ 'template' ] = $template ;
}
if ( ! is_object ( $value [ 'template' ]))
{
$value [ 'template' ] =& new etemplate ( $value [ 'template' ], $tmpl -> as_array ());
}
2009-02-24 08:42:12 +01:00
if ( is_array ( $value [ 'rows' ][ 0 ])) // pad 0 based arrays with rows-1 false values
{
for ( $i = 1 ; $i < $value [ 'template' ] -> rows ; $i ++ )
{
array_unshift ( $value [ 'rows' ], false );
}
}
2008-06-22 09:16:40 +02:00
$extension_data [ 'template' ] = $value [ 'template' ] -> name ; // used for the column-selection, and might be set in get_rows()
$extension_data [ 'columnselection_pref' ] = $value [ 'columnselection_pref' ];
if ( $total < 1 && $value [ 'template' ] -> rows > 1 )
{
$value [ 'template' ] -> data [ 0 ][ 'h' . $value [ 'template' ] -> rows ] .= ',1' ; // disable the last data row
}
if ( ! $value [ 'never_hide' ] && $total <= $max && $options && $value [ 'search' ] == '' &&
( $value [ 'no_cat' ] || ! $value [ 'cat_id' ]) &&
( $value [ 'no_filter' ] || ! $value [ 'filter' ] || $value [ 'filter' ] == 'none' ) &&
( $value [ 'no_filter2' ] || ! $value [ 'filter2' ] || $value [ 'filter2' ] == 'none' ))
{ // disable whole nextmatch line if no scrolling necessary
if ( $value [ 'header_left' ] || $value [ 'header_right' ])
2002-10-01 20:26:30 +02:00
{
2008-06-22 09:16:40 +02:00
$nextmatch =& new etemplate ( 'etemplate.nextmatch_widget.header_only' );
$cell [ 'size' ] = $cell [ 'name' ];
$cell [ 'obj' ] = & $nextmatch ;
$cell [ 'name' ] = $nextmatch -> name ;
2002-10-16 16:11:36 +02:00
}
else
{
2008-06-22 09:16:40 +02:00
$cell [ 'size' ] = $cell [ 'name' ] . '[rows]' ;
$cell [ 'obj' ] = & $value [ 'template' ];
$cell [ 'name' ] = $value [ 'template' ] -> name ;
}
}
else
{
$nextmatch =& new etemplate ( 'etemplate.nextmatch_widget' );
2008-08-21 20:09:20 +02:00
$nextmatch -> read ( 'etemplate.nextmatch_widget' );
2008-06-22 09:16:40 +02:00
// keep the editor away from the generated tmpls
$nextmatch -> no_onclick = true ;
2007-02-14 08:11:42 +01:00
2008-06-22 09:16:40 +02:00
if ( $value [ 'lettersearch' ])
{
$lettersearch =& $nextmatch -> get_widget_by_name ( 'lettersearch' ); // hbox for the letters
if (( $alphabet = lang ( 'alphabet' )) == 'alphabet*' ) $alphabet = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z' ;
$alphabet = explode ( ',' , $alphabet );
$alphabet [ 'all' ] = lang ( 'all' );
foreach ( $alphabet as $key => $letter )
2005-03-14 00:38:37 +01:00
{
2008-06-22 09:16:40 +02:00
// make each letter internally behave like a button
$form_name = $name . '[searchletter][' . ( $key === 'all' ? $key : $letter ) . ']' ;
2009-03-16 13:58:24 +01:00
etemplate :: $request -> set_to_process ( $form_name , 'button' );
2008-06-22 09:16:40 +02:00
if ( ! $key ) $letterbox =& $lettersearch [ 1 ]; // to re-use the first child
$letterbox = etemplate :: empty_cell ( 'label' , $letter , array (
'label' => $letter ,
'span' => ',lettersearch' . ( $letter == ( string ) $value [ 'searchletter' ] ||
$key === 'all' && ! $value [ 'searchletter' ] ? '_active' : '' ),
'no_lang' => 2 ,
'align' => $key == 'all' ? 'right' : '' ,
2009-03-16 13:58:24 +01:00
'onclick' => 'return submitit(' . etemplate :: $name_form . " ,' $form_name '); " ,
2008-06-22 09:16:40 +02:00
));
// if not the first (re-used) child, add it to the parent
if ( $key ) etemplate :: add_child ( $lettersearch , $letterbox );
unset ( $letterbox );
2005-03-14 00:38:37 +01:00
}
2009-03-16 13:58:24 +01:00
//_debug_array(etemplate::$request->to_process);
2002-10-01 20:26:30 +02:00
}
2008-06-22 09:16:40 +02:00
if ( isset ( $value [ 'no_search' ])) $value [ 'no_start_search' ] = $value [ 'no_search' ];
foreach ( array ( 'no_cat' => 'cat_id' , 'no_filter' => 'filter' , 'no_filter2' => 'filter2' , 'no_search' => 'search' , 'no_start_search' => 'start_search' ) as $val_name => $cell_name )
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
if ( isset ( $value [ $val_name ])) $nextmatch -> disable_cells ( $cell_name , $value [ $val_name ]);
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
foreach ( array ( 'header_left' , 'header_right' ) as $name )
2005-02-27 22:32:06 +01:00
{
2008-06-22 09:16:40 +02:00
if ( ! $value [ $name ]) $nextmatch -> disable_cells ( '@' . $name );
2005-02-27 22:32:06 +01:00
}
2008-06-22 09:16:40 +02:00
foreach ( array ( 'filter' , 'filter2' ) as $cell_name )
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
if ( isset ( $value [ $cell_name . '_no_lang' ])) $nextmatch -> set_cell_attribute ( $cell_name , 'no_lang' , $value [ $cell_name . '_no_lang' ]);
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
$start = $value [ 'start' ];
$end = $start + $max > $total ? $total : $start + $max ;
$value [ 'range' ] = $total ? ( 1 + $start ) . ' - ' . $end : '0' ;
$nextmatch -> set_cell_attribute ( 'first' , 'readonly' , $start <= 0 );
$nextmatch -> set_cell_attribute ( 'left' , 'readonly' , $start <= 0 );
$nextmatch -> set_cell_attribute ( 'right' , 'readonly' , $start + $max >= $total );
$nextmatch -> set_cell_attribute ( 'last' , 'readonly' , $start + $max >= $total );
$cell [ 'size' ] = $cell [ 'name' ];
$cell [ 'obj' ] = & $nextmatch ;
$cell [ 'name' ] = $nextmatch -> name ;
}
// preset everything for the column selection
if ( ! $value [ 'no_columnselection' ])
{
$name = is_object ( $value [ 'template' ]) ? $value [ 'template' ] -> name : $value [ 'template' ];
list ( $app ) = explode ( '.' , $name );
if ( isset ( $value [ 'columnselection_pref' ])) $name = $value [ 'columnselection_pref' ];
$this -> selectcols = $value [ 'selectcols' ] = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ $app ][ 'nextmatch-' . $name ];
// fetching column-names & -labels from the template
if ( $this -> _cols_from_tpl ( $value [ 'template' ], $value [ 'options-selectcols' ], $name2col , $value [ 'rows' ], $value [ 'selectcols' ]))
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
//_debug_array($name2col);
//_debug_array($value['options-selectcols']);
// getting the selected colums from the prefs (or if not set a given default or all)
if ( ! $value [ 'selectcols' ])
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
$value [ 'selectcols' ] = array_keys ( $value [ 'options-selectcols' ]);
if ( isset ( $value [ 'default_cols' ]))
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
if ( $value [ 'default_cols' ]{ 0 } == '!' )
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
$value [ 'selectcols' ] = array_diff ( $value [ 'selectcols' ], explode ( ',' , substr ( $value [ 'default_cols' ], 1 )));
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
else
2008-01-19 06:36:20 +01:00
{
2008-06-22 09:16:40 +02:00
$value [ 'selectcols' ] = $value [ 'default_cols' ];
2008-01-19 06:36:20 +01:00
}
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
$this -> selectcols = $value [ 'selectcols' ];
}
if ( ! is_array ( $value [ 'selectcols' ])) $value [ 'selectcols' ] = explode ( ',' , $value [ 'selectcols' ]);
foreach ( array_keys ( $value [ 'options-selectcols' ]) as $name )
{
// set 'no_'.$col for each column-name to true, if the column is not selected
// (and the value is not set be the get_rows function / programmer!)
if ( ! isset ( $value [ 'rows' ][ 'no_' . $name ])) $value [ 'rows' ][ 'no_' . $name ] = ! in_array ( $name , $value [ 'selectcols' ]);
// setting '@no_'.$name as disabled attr for each column, that has only a single nextmatch-header
if ( is_object ( $value [ 'template' ]))
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
$col = $name2col [ $name ];
list (, $disabled ) = $value [ 'template' ] -> set_column_attributes ( $col );
//echo "<p>$col: $name: $disabled</p>\n";
if ( ! isset ( $disabled )) $value [ 'template' ] -> set_column_attributes ( $col , 0 , '@no_' . $name );
2007-03-07 13:30:17 +01:00
}
}
2008-06-22 09:16:40 +02:00
//_debug_array($value);
if ( is_object ( $nextmatch ))
{
$size =& $nextmatch -> get_cell_attribute ( 'selectcols' , 'size' );
if ( $size > count ( $value [ 'options-selectcols' ])) $size = '0' . count ( $value [ 'options-selectcols' ]);
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ])
{
$nextmatch -> disable_cells ( 'default_prefs' );
}
}
// should reset on each submit
unset ( $value [ 'default_prefs' ]);
2007-03-07 13:30:17 +01:00
}
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
$cell [ 'type' ] = 'template' ;
$cell [ 'label' ] = $cell [ 'help' ] = '' ;
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
foreach ( array ( 'sort' , 'order' , 'col_filter' ) as $n ) // save them for the sortheader
2008-01-19 06:36:20 +01:00
{
2008-06-22 09:16:40 +02:00
$nm_global [ $n ] = $value [ $n ];
}
$value [ 'bottom' ] = $value ; // copy the values for the bottom-bar
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
return False ; // NO extra Label
}
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
/**
* Preprocess for the custom fields header
*
* @ param array & $cell
*/
private function _pre_process_cf_header ( array & $cell , etemplate $tmpl )
{
//echo __CLASS__.'::'.__METHOD__."() selectcols=$this->selectcols\n";
if ( is_null ( $this -> cfs ))
{
list ( $app ) = explode ( '.' , $tmpl -> name );
$this -> cfs = config :: get_customfields ( $app );
2008-01-19 06:36:20 +01:00
}
2008-06-22 09:16:40 +02:00
$cell [ 'type' ] = 'vbox' ;
$cell [ 'name' ] = '' ;
$cell [ 'size' ] = '0,,0,0' ;
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
if ( $this -> selectcols )
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
foreach ( explode ( ',' , $this -> selectcols ) as $col )
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
if ( $col [ 0 ] == self :: CF_PREFIX ) $allowed [] = $col ;
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
}
foreach ( $this -> cfs as $name => $field )
{
if ( ! $allowed || in_array ( self :: CF_PREFIX . $name , $allowed ))
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
if ( $field [ 'type' ] == 'select' )
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
$header =& etemplate :: empty_cell ( 'nextmatch-filterheader' , self :: CF_PREFIX . $name , array (
'sel_options' => $field [ 'values' ],
'size' => $field [ 'label' ],
'no_lang' => True ,
2008-10-05 18:56:37 +02:00
'readonly' => $cell [ 'readonly' ],
2008-06-22 09:16:40 +02:00
));
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
else
2008-01-19 06:36:20 +01:00
{
2008-06-22 09:16:40 +02:00
$header =& etemplate :: empty_cell ( 'nextmatch-sortheader' , self :: CF_PREFIX . $name , array (
'label' => $field [ 'label' ],
2008-10-05 18:56:37 +02:00
'readonly' => $cell [ 'readonly' ],
2008-06-22 09:16:40 +02:00
));
2008-01-19 06:36:20 +01:00
}
2008-06-22 09:16:40 +02:00
etemplate :: add_child ( $cell , $header );
unset ( $header );
2007-03-07 13:30:17 +01:00
}
}
2008-06-22 09:16:40 +02:00
return false ; // no extra label
}
2007-03-07 13:30:17 +01:00
2008-06-22 09:16:40 +02:00
/**
* Extract the column names and labels from the template
*
* @ param etemplate & $tmpl
* @ param array & $cols here we add the column - name /- label
* @ param array & $name2col
* @ param array $content nextmatch content , to be able to resolve labels with @ name
* @ param array $selectcols selected colums
* @ return int columns found , count ( $cols )
*/
function _cols_from_tpl ( etemplate $tmpl , & $cols , & $name2col , & $content , $selectcols )
{
//_debug_array($cols);
// fetching column-names & -labels from the template
$cols [ '__content__' ] =& $content ;
$tmpl -> widget_tree_walk ( array ( $this , '_cols_from_tpl_walker' ), $cols );
unset ( $cols [ '__content__' ]);
$name2col = is_array ( $cols [ 'name2col' ]) ? $cols [ 'name2col' ] : array (); unset ( $cols [ 'name2col' ]);
//_debug_array($cols);
foreach ( $cols as $name => $label )
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
if ( ! $label ) unset ( $cols [ $name ]);
}
//_debug_array($cols);
//_debug_array($name2col);
// now we check if a column of the grid has more then one header
$col2names = array ();
foreach ( $name2col as $name => $col )
{
if ( $name != $col ) $col2names [ $col ][] = $name ;
}
//_debug_array($col2names);
$cols2 = $cols ;
$cols = array ();
foreach ( $cols2 as $name => $label )
{
$col = $name ;
// and replace the column letter then with the name concatinated by an underscore
if ( is_array ( $col2names [ $name ]))
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
$name = implode ( '_' , $col2names [ $name ]);
$name2col [ $name ] = $col ;
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
$cols [ $name ] = $label ;
2007-03-07 13:30:17 +01:00
2008-06-22 09:16:40 +02:00
// we are behind the column of a custom fields header --> add the individual fields
if ( $name == $this -> cf_header && ( ! $selectcols ||
in_array ( $this -> cf_header , explode ( ',' , $selectcols ))))
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
$cols [ $name ] .= ':' ;
list ( $app ) = explode ( '.' , $tmpl -> name );
if (( $this -> cfs = config :: get_customfields ( $app )))
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
foreach ( $this -> cfs as $name => $field )
{
$cols [ self :: CF_PREFIX . $name ] = '- ' . $field [ 'label' ];
}
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
else
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
unset ( $cols [ $name ]); // no cf's defined -> no header
2007-03-07 13:30:17 +01:00
}
}
}
2008-06-22 09:16:40 +02:00
//_debug_array($cols);
return count ( $cols );
}
/**
* Extract the column names and labels from the template ( callback for etemplate :: widget_tree_walk ())
*
* @ param array & $widget
* @ param array & $cols here we add the column - name /- label
* @ param string $path
*/
function _cols_from_tpl_walker ( & $widget , & $cols , $path )
{
list ( $type , $subtype ) = explode ( '-' , $widget [ 'type' ]);
2002-09-17 23:31:45 +02:00
2008-06-22 09:16:40 +02:00
if ( $subtype == 'customfields' )
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
if ( ! $widget [ 'name' ]) $widget [ 'name' ] = 'customfields' ;
if ( ! $widget [ 'label' ]) $widget [ 'label' ] = 'Custom fields' ;
$this -> cf_header = $widget [ 'name' ];
}
if ( $type != 'nextmatch' || ! $subtype || ! $widget [ 'name' ] || $widget [ 'disabled' ])
{
return ;
}
$options = explode ( ',' , $widget [ 'size' ]);
if ( ! ( $label = $widget [ 'label' ]) || in_array ( $subtype , array ( 'header' , 'sortheader' )) && $options [ 1 ])
{
if ( in_array ( $subtype , array ( 'customfilter' , 'sortheader' ))) $subtype = array_shift ( $options );
2007-06-21 11:59:53 +02:00
2008-06-22 09:16:40 +02:00
$label = $options [ 0 ];
}
list (,, $col , $sub ) = explode ( '/' , $path );
$row = ( int ) $col ;
$col = substr ( $col , $row > 9 ? 2 : 1 );
if (( $label { 0 } == '@' || strchr ( $lable , '$' ) !== false ) && is_array ( $cols [ '__content__' ]))
{
$label = etemplate :: expand_name ( $label , $col , $row , '' , '' , $cols [ '__content__' ]);
}
if ( ! isset ( $cols [ $widget [ 'name' ]]) && $label )
{
$label = substr ( $label , - 3 ) == '...' ? lang ( substr ( $label , 0 , - 3 )) : lang ( $label );
2007-06-21 11:59:53 +02:00
2008-06-22 09:16:40 +02:00
if ( ! $sub )
{
$cols [ $widget [ 'name' ]] = $label ;
}
elseif ( strpos ( $cols [ $col ], $label ) === false )
2003-12-09 01:03:41 +01:00
{
2008-06-22 09:16:40 +02:00
$cols [ $col ] .= ( $cols [ $col ] ? ', ' : '' ) . $label ;
$cols [ 'name2col' ][ $col ] = $col ;
}
}
$cols [ 'name2col' ][ $widget [ 'name' ]] = $col ;
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
//echo "<p>$path: $widget[name] $label</p>\n";
}
2003-12-09 01:03:41 +01:00
2008-06-22 09:16:40 +02:00
/**
* postprocessing method , called after the submission of the form
*
* It has to copy the allowed / valid data from $value_in to $value , otherwise the widget
* will return no data ( if it has a preprocessing method ) . The framework insures that
* the post - processing of all contained widget has been done before .
*
* Only used by select - dow so far
*
* @ param string $name form - name of the widget
* @ param mixed & $value the extension returns here it 's input, if there' s any
* @ param mixed & $extension_data persistent storage between calls or pre - and post - process
* @ param boolean & $loop can be set to true to request a re - submision of the form / dialog
* @ param object & $tmpl the eTemplate the widget belongs too
* @ param mixed & value_in the posted values ( already striped of magic - quotes )
* @ return boolean true if $value has valid content , on false no content will be returned !
*/
function post_process ( $name , & $value , & $extension_data , & $loop , & $tmpl , $value_in )
{
$nm_global =& self :: get_nm_global ( $name , $extension_data [ 'type' ]);
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
if ( $this -> debug ) { echo " <p>nextmatch_widget.post_process(type=' $extension_data[type] ', name=' $name ',value_in= " . print_r ( $value_in , true ) . " ,order=' $nm_global[order] '): value = " ; _debug_array ( $value ); }
2002-09-17 23:31:45 +02:00
2008-06-22 09:16:40 +02:00
switch ( $extension_data [ 'type' ])
{
case 'nextmatch' :
break ;
2002-10-16 17:22:06 +02:00
2008-06-22 09:16:40 +02:00
case 'nextmatch-sortheader' :
if ( $value_in )
2003-06-29 19:00:05 +02:00
{
2008-06-22 09:16:40 +02:00
$nm_global [ 'order' ] = self :: last_part ( $name );
$nm_global [ 'default_sort' ] = $extension_data [ 'default_sort' ];
2003-06-29 19:00:05 +02:00
}
2008-06-22 09:16:40 +02:00
return False ; // dont report value back, as it's in the wrong location (rows)
default :
case 'select-account' : // used by nextmatch-accountfilter
case 'nextmatch-filterheader' :
if (( string ) $value_in != ( string ) $extension_data [ 'old_value' ])
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
if ( $this -> debug ) echo " <p>setting nm_global[filter][ " . self :: last_part ( $name ) . " ]=' $value_in ' (was ' $extension_data[old_value] ')</p> \n " ;
$nm_global [ 'filter' ][ self :: last_part ( $name )] = $value_in ;
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
return False ; // dont report value back, as it's in the wrong location (rows)
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
case 'nextmatch-header' :
return False ; // nothing to report
}
$old_value = $extension_data ;
if ( $this -> debug ) { echo " old_value= " ; _debug_array ( $old_value ); }
$value [ 'start' ] = $old_value [ 'start' ]; // need to be set, to be reported back
$value [ 'return' ] = $old_value [ 'return' ];
if ( is_array ( $value [ 'bottom' ])) // we have a second bottom-bar
{
$inputs = array ( 'search' , 'cat_id' , 'filter' , 'filter2' , 'num_rows' );
foreach ( $inputs as $name )
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
if ( isset ( $value [ 'bottom' ][ $name ]) && $value [ $name ] == $old_value [ $name ])
2007-06-21 11:59:53 +02:00
{
2008-06-22 09:16:40 +02:00
if ( $this -> debug ) echo " value[ $name ] overwritten by bottom-value[ $name ]=' " . $value [ 'bottom' ][ $name ] . " ', old_value[ $name ]=' " . $old_value [ $name ] . " '<br> \n " ;
$value [ $name ] = $value [ 'bottom' ][ $name ];
2007-06-21 11:59:53 +02:00
}
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
$buttons = array ( 'start_search' , 'first' , 'left' , 'right' , 'last' , 'export' );
foreach ( $buttons as $name )
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
if ( isset ( $value [ 'bottom' ][ $name ]) && $value [ 'bottom' ][ $name ])
{
$value [ $name ] = $value [ 'bottom' ][ $name ];
}
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
if ( $value [ 'bottom' ][ 'savecols' ])
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
$value [ 'selectcols' ] = $value [ 'bottom' ][ 'selectcols' ];
$value [ 'default_prefs' ] = $value [ 'bottom' ][ 'default_prefs' ];
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
unset ( $value [ 'bottom' ]);
}
if ( isset ( $old_value [ 'num_rows' ]) && ! is_null ( $value [ 'num_rows' ]) && $value [ 'num_rows' ] != $old_value [ 'num_rows' ])
{
if ( $this -> debug ) echo " <p>nextmatch_widget::post_process() num_rows changed { $old_value [ 'num_rows' ] } --> { $value [ 'num_rows' ] } ==> looping</p> \n " ;
$loop = true ; // num_rows changed
}
// num_rows: use old value in extension data, if $value['num_rows'] is not set because nm-header is not shown
$value [ 'num_rows' ] = isset ( $value [ 'num_rows' ]) ? ( int ) $value [ 'num_rows' ] : ( int ) $extension_data [ 'num_rows' ];
$max = $value [ 'num_rows' ] ? $value [ 'num_rows' ] : ( int ) $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'maxmatchs' ];
if ( strpos ( $value [ 'search' ], 'xjxquery' )) {
// We deal with advancedsearch
$aXml = $value [ 'search' ];
$value [ 'search' ] = '' ;
$aXml = str_replace ( " <xjxquery><q> " , " & " , $aXml );
$aXml = str_replace ( " </q></xjxquery> " , " " , $aXml );
$value [ 'advsearch_cont' ] = explode ( '&' , $aXml );
//$GLOBALS['egw']->boetemplate = &CreateObject('etemplate.boetemplate');
//print_r($GLOBALS['egw']->boetemplate->get_array($value['advsearch_cont'],'exec[]',true));
//$value['advsearch_cont'] = preg_replace("/exec\[ (.*)/",'$1',$value['advsearch_cont']);
//$value['advsearch_cont'] = preg_replace("\]",'',$value['advsearch_cont']);
//print_r($value['advsearch_cont']);
}
if ( $value [ 'start_search' ] || $value [ 'search' ] != $old_value [ 'search' ] ||
isset ( $value [ 'cat_id' ]) && $value [ 'cat_id' ] != $old_value [ 'cat_id' ] ||
isset ( $value [ 'filter' ]) && $value [ 'filter' ] != $old_value [ 'filter' ] ||
isset ( $value [ 'filter2' ]) && $value [ 'filter2' ] != $old_value [ 'filter2' ])
{
if ( $this -> debug )
2002-09-17 23:31:45 +02:00
{
2008-06-22 09:16:40 +02:00
echo " <p>search=' $old_value[search] '->' $value[search] ', filter=' $old_value[filter] '->' $value[filter] ', filter2=' $old_value[filter2] '->' $value[filter2] '<br> " ;
echo " new filter --> loop</p> " ;
echo " value = " ; _debug_array ( $value );
echo " old_value = " ; _debug_array ( $old_value );
2002-09-22 11:30:29 +02:00
}
2008-06-22 09:16:40 +02:00
$loop = True ;
}
elseif ( $value [ 'first' ] || $value [ 'left' ] && $old_value [ 'start' ] < $max )
{
$value [ 'start' ] = 0 ;
unset ( $value [ 'first' ]);
$loop = True ;
}
elseif ( $value [ 'left' ])
{
$value [ 'start' ] = $old_value [ 'start' ] - $max ;
unset ( $value [ 'left' ]);
$loop = True ;
}
elseif ( $value [ 'right' ])
{
$value [ 'start' ] = $old_value [ 'start' ] + $max ;
unset ( $value [ 'right' ]);
$loop = True ;
}
elseif ( $value [ 'last' ])
{
$value [ 'start' ] = ( int ) (( $old_value [ 'total' ] - 1 ) / $max ) * $max ;
unset ( $value [ 'last' ]);
$loop = True ;
}
elseif ( $nm_global [ 'order' ])
{
$value [ 'order' ] = $nm_global [ 'order' ];
if ( $old_value [ 'order' ] != $value [ 'order' ])
2002-09-22 11:30:29 +02:00
{
2008-06-22 09:16:40 +02:00
$value [ 'sort' ] = $nm_global [ 'default_sort' ];
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
else
2003-12-09 01:03:41 +01:00
{
2008-06-22 09:16:40 +02:00
$value [ 'sort' ] = $old_value [ 'sort' ] != 'DESC' ? 'DESC' : 'ASC' ;
2003-12-09 01:03:41 +01:00
}
2008-06-22 09:16:40 +02:00
if ( $this -> debug ) echo " <p>old_value= $old_value[order] / $old_value[sort] ==> $value[order] / $value[sort] </p> \n " ;
$loop = True ;
}
elseif ( $nm_global [ 'filter' ])
{
if ( ! is_array ( $value [ 'col_filter' ])) $value [ 'col_filter' ] = array ();
2005-07-14 08:47:14 +02:00
2008-06-22 09:16:40 +02:00
$value [ 'col_filter' ] += $nm_global [ 'filter' ];
$loop = True ;
}
elseif ( isset ( $value [ 'searchletter' ]))
{
list ( $value [ 'searchletter' ]) = @ each ( $value [ 'searchletter' ]);
if ( $value [ 'searchletter' ] === 'all' ) $value [ 'searchletter' ] = false ;
$loop = True ;
}
if ( $value [ 'savecols' ])
{
$name = is_object ( $extension_data [ 'template' ]) ? $extension_data [ 'template' ] -> name : $extension_data [ 'template' ];
list ( $app ) = explode ( '.' , $name );
if ( isset ( $extension_data [ 'columnselection_pref' ])) $name = $extension_data [ 'columnselection_pref' ];
$pref = ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ] && $value [ 'default_prefs' ] ? 'default' : 'user' ;
$GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ] = $GLOBALS [ 'egw' ] -> preferences -> add ( $app , 'nextmatch-' . $name , is_array ( $value [ 'selectcols' ]) ?
implode ( ',' , $value [ 'selectcols' ]) : $value [ 'selectcols' ], $pref );
$GLOBALS [ 'egw' ] -> preferences -> save_repository ( false , $pref );
$loop = True ;
}
if ( $value [ 'export' ])
{
$this -> _csv_export ( $extension_data );
}
return True ;
}
var $separator = ';' ;
var $charset_out ;
var $charset ;
/**
* Export the list as csv file download
*
* @ param array $value content of the nextmatch widget
* @ param boolean false = error , eg . get_rows callback does not exits , true = nothing to export , otherwise we do NOT return !
*/
function _csv_export ( & $value )
{
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ]))
{
$export_limit = $GLOBALS [ 'egw_info' ][ 'server' ][ 'export_limit' ];
}
list ( $app , $class , $method ) = explode ( '.' , $value [ 'get_rows' ]);
if ( $app && $class )
{
if ( is_object ( $GLOBALS [ $class ])) // use existing instance (put there by a previous CreateObject)
2007-03-07 13:30:17 +01:00
{
2008-06-22 09:16:40 +02:00
$obj =& $GLOBALS [ $class ];
2007-03-07 13:30:17 +01:00
}
2008-06-22 09:16:40 +02:00
else
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$obj =& CreateObject ( $app . '.' . $class );
2007-09-22 16:58:10 +02:00
}
2002-09-17 23:31:45 +02:00
}
2008-06-22 09:16:40 +02:00
if ( ! is_object ( $obj ) || ! method_exists ( $obj , $method ))
{
2009-03-16 13:58:24 +01:00
etemplate :: set_validation_error ( $name , " nextmatch_widget::pre_process( $cell[name] ): ' $value[get_rows] ' is no valid method !!! " );
2008-06-22 09:16:40 +02:00
return false ;
}
$this -> charset = $this -> charset_out = $GLOBALS [ 'egw' ] -> translation -> charset ();
if ( isset ( $value [ 'csv_charset' ]))
{
$this -> charset_out = $value [ 'csv_charset' ];
}
elseif ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'csv_charset' ])
{
$this -> charset_out = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'csv_charset' ];
}
$backup_start = $value [ 'start' ];
$backup_num_rows = $value [ 'num_rows' ];
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
$value [ 'start' ] = 0 ;
$value [ 'num_rows' ] = 500 ;
$value [ 'csv_export' ] = true ; // so get_rows method _can_ produce different content or not store state in the session
do
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
if ( ! ( $total = $obj -> $method ( $value , $rows , $readonlys = array ())))
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
break ; // nothing to export
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
if ( $export_limit && ( ! is_numeric ( $export_limit ) || $export_limit < $total ))
2007-09-22 16:58:10 +02:00
{
2009-03-16 13:58:24 +01:00
etemplate :: set_validation_error ( $name , lang ( 'You are not allowed to export more then %1 entries!' , $export_limit ));
2007-09-22 16:58:10 +02:00
return false ;
}
2008-06-22 09:16:40 +02:00
if ( ! isset ( $value [ 'no_csv_support' ])) $value [ 'no_csv_support' ] = ! is_array ( $value [ 'csv_fields' ]);
//echo "<p>start=$value[start], num_rows=$value[num_rows]: total=$total, count(\$rows)=".count($rows)."</p>\n";
if ( ! $value [ 'start' ]) // send the neccessary headers
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$fp = $this -> _csv_open ( $rows [ 0 ], $value [ 'csv_fields' ], $app );
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
//_debug_array($rows);
foreach ( $rows as $key => $row )
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
if ( ! is_numeric ( $key )) continue ; // not a real rows
fwrite ( $fp , $this -> _csv_encode ( $row , $value [ 'csv_fields' ]) . " \n " );
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
$value [ 'start' ] += $value [ 'num_rows' ];
2007-09-22 16:58:10 +02:00
2008-06-22 09:16:40 +02:00
@ set_time_limit ( 10 ); // 10 more seconds
}
while ( $total > $value [ 'start' ]);
2007-09-22 16:58:10 +02:00
2008-06-22 09:16:40 +02:00
unset ( $value [ 'csv_export' ]);
$value [ 'start' ] = $backup_start ;
$value [ 'num_rows' ] = $backup_num_rows ;
if ( $value [ 'no_csv_support' ]) // we need to call the get_rows method in case start&num_rows are stored in the session
{
$obj -> $method ( $value , $rows , $readonlys = array ());
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
if ( $fp )
{
fclose ( $fp );
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
}
return true ;
}
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
/**
* Opens the csv output ( download ) and writes the header line
*
* @ param array $row0 first row to guess the available fields
* @ param array $fields name => label or name => array ( 'lable' => label , 'type' => type ) pairs
* @ param string $app app - name
* @ return FILE
*/
function _csv_open ( $row0 , & $fields , $app )
{
if ( ! is_array ( $fields ) || ! count ( $fields ))
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$fields = $this -> _autodetect_fields ( $row0 , $app );
}
$browser =& CreateObject ( 'phpgwapi.browser' );
$browser -> content_header ( 'export.csv' , 'text/comma-separated-values' );
//echo "<pre>";
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
if (( $fp = fopen ( 'php://output' , 'w' )))
{
$labels = array ();
foreach ( $fields as $field => $label )
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
if ( is_array ( $label )) $label = $label [ 'label' ];
$labels [ $field ] = $label ? $label : $field ;
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
fwrite ( $fp , $this -> _csv_encode ( $labels , $fields , false ) . " \n " );
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
return $fp ;
}
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
/**
* CSV encode a single row , including some basic type conversation
*
* @ param array $data
* @ param array $fields
* @ param boolean $use_type = true
* @ return string
*/
function _csv_encode ( $data , $fields , $use_type = true )
{
static $date_format , $time_format ;
if ( is_null ( $date_format ))
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$time_format = $date_format = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ];
$time_format .= ' ' . ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'timeformat' ] == 12 ? 'h:ia' : 'H:i' );
}
$out = array ();
foreach ( $fields as $field => $label )
{
$value = ( array ) $data [ $field ];
2007-09-22 16:58:10 +02:00
2008-06-22 09:16:40 +02:00
if ( $use_type && is_array ( $label ) && in_array ( $label [ 'type' ], array ( 'select-account' , 'select-cat' , 'date-time' , 'date' )))
{
foreach ( $value as $key => $val )
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
switch ( $label [ 'type' ])
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
case 'select-account' :
if ( $val ) $value [ $key ] = $GLOBALS [ 'egw' ] -> common -> grab_owner_name ( $val );
break ;
case 'select-cat' :
if ( $val )
{
$value [ $key ] = $GLOBALS [ 'egw' ] -> categories -> id2name ( $val );
}
break ;
case 'date-time' :
if ( $val ) $value [ $key ] = date ( $time_format , $val );
break ;
case 'date' :
if ( $val ) $value [ $key ] = date ( $date_format , $val );
break ;
2007-09-22 16:58:10 +02:00
}
}
}
2008-06-22 09:16:40 +02:00
$value = implode ( ', ' , $value );
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
if ( strpos ( $value , $this -> separator ) !== false || strpos ( $value , " \n " ) !== false || strpos ( $value , " \r " ) !== false )
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$value = '"' . str_replace ( array ( '\\' , '"' ), array ( '\\\\' , '\\"' ), $value ) . '"' ;
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
$out [] = $value ;
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
$out = implode ( $this -> separator , $out );
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
if ( $this -> charset_out && $this -> charset != $this -> charset_out )
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$out = $GLOBALS [ 'egw' ] -> translation -> convert ( $out , $this -> charset , $this -> charset_out );
}
return $out ;
}
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
/**
* Try to autodetect the fields from the first data - row and the app - name
*
* @ param array $row0 first data - row
* @ param string $app
*/
function _autodetect_fields ( $row0 , $app )
{
$fields = array_combine ( array_keys ( $row0 ), array_keys ( $row0 ));
foreach ( $fields as $name => $label )
{
// try to guess field-type from the fieldname
if ( preg_match ( '/(modified|created|start|end)/' , $name ) && strpos ( $name , 'by' ) === false &&
( ! $row0 [ $name ] || is_numeric ( $row0 [ $name ]))) // only use for real timestamps
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$fields [ $name ] = array ( 'label' => $label , 'type' => 'date-time' );
}
elseif ( preg_match ( '/(cat_id|category|cat)/' , $name ))
{
$fields [ $name ] = array ( 'label' => $label , 'type' => 'select-cat' );
}
elseif ( preg_match ( '/(owner|creator|modifier|assigned|by|coordinator|responsible)/' , $name ))
{
$fields [ $name ] = array ( 'label' => $label , 'type' => 'select-account' );
2007-09-22 16:58:10 +02:00
}
2008-06-22 09:16:40 +02:00
elseif ( preg_match ( '/(jpeg|photo)/' , $name ))
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
unset ( $fields [ $name ]);
}
}
if ( $app )
{
include_once ( EGW_API_INC . '/class.config.inc.php' );
$config =& new config ( $app );
$config -> read_repository ();
2008-06-11 06:05:10 +02:00
2008-06-22 09:16:40 +02:00
$customfields = isset ( $config -> config_data [ 'customfields' ]) ? $config -> config_data [ 'customfields' ] : $config -> config_data [ 'custom_fields' ];
if ( is_array ( $customfields ))
{
foreach ( $customfields as $name => $data )
2007-09-22 16:58:10 +02:00
{
2008-06-22 09:16:40 +02:00
$fields [ '#' . $name ] = array (
'label' => $data [ 'label' ],
'type' => $data [ 'type' ],
);
2007-09-22 16:58:10 +02:00
}
}
}
2008-06-22 09:16:40 +02:00
//_debug_array($fields);
return $fields ;
2002-10-16 16:11:36 +02:00
}
2008-06-22 09:16:40 +02:00
}