mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-28 19:03:14 +01:00
Add support for filtering records to be exported.
Filterable fields are attempted to be autodetected by using the exportable fields. Records can be filtered by fields with type select,select-cat,select-account,date,date-time (according to egw_record class) only at this time. Filters are saved in the definition and used with scheduled exports. They are also available to the user for modification in the export dialog.
This commit is contained in:
parent
841d3b67bd
commit
0a91bc5aa9
257
importexport/inc/class.filter_widget.inc.php
Normal file
257
importexport/inc/class.filter_widget.inc.php
Normal file
@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* Widget for setting filters
|
||||
*
|
||||
* @author Nathan Gray
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extend custom fields and make an general advanced filter
|
||||
*
|
||||
* Much of this is copied from customfields_widget and adapted.
|
||||
* We assume that the app can handle pretty much any field => value combination
|
||||
* we send via col_filter, but the plugin gets a chance to interpret the filter
|
||||
* settings.
|
||||
*
|
||||
* Selectboxes are easy, we just turn them into multi-selects.
|
||||
*
|
||||
* For dates we either use a relative date selection, or a literal date selection.
|
||||
* Relative date options are in importexport_helper_functions::$relative_dates
|
||||
*
|
||||
* Most text fields are ignored.
|
||||
*/
|
||||
class filter_widget extends customfields_widget
|
||||
{
|
||||
|
||||
public $prefix = '';
|
||||
public $human_name = array(
|
||||
'filter' => 'Import|Export filter'
|
||||
);
|
||||
|
||||
public function __construct($ui, $appname = null)
|
||||
{
|
||||
$this->advanced_search = true;
|
||||
parent::__construct($ui, $appname);
|
||||
}
|
||||
|
||||
/**
|
||||
* pre-processing of the extension
|
||||
*
|
||||
* This function is called before the extension gets rendered
|
||||
*
|
||||
* @param string $form_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
|
||||
*/
|
||||
public function pre_process($form_name,&$value,&$cell,&$readonlys,&$extension_data,$tmpl)
|
||||
{
|
||||
$fields = $value['fields'];
|
||||
unset($value['fields']);
|
||||
|
||||
list($relative_dates) = explode(',',$cell['size']);
|
||||
if($cell['relative_dates']) $relative_dates = true;
|
||||
|
||||
// Fallback, so there's something there...
|
||||
if(!is_array($fields))
|
||||
{
|
||||
$cell['type'] = 'label';
|
||||
$cell['label'] = 'No fields';
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
// making the cell an empty grid
|
||||
$cell['type'] = 'grid';
|
||||
$cell['data'] = array(array());
|
||||
$cell['rows'] = $cell['cols'] = 0;
|
||||
$cell['size'] = '';
|
||||
|
||||
$n = 1;
|
||||
foreach($fields as $lname => $field)
|
||||
{
|
||||
$new_row = null; boetemplate::add_child($cell,$new_row);
|
||||
$row_class = 'row';
|
||||
boetemplate::add_child($cell,$label =& boetemplate::empty_cell('label','',array(
|
||||
'label' => $field['label'],
|
||||
'no_lang' => substr(lang($field['label']),-1) == '*' ? 2 : 0,
|
||||
'span' => $field['type'] === 'label' ? '2' : '',
|
||||
)));
|
||||
|
||||
switch($field['type'])
|
||||
{
|
||||
case 'date':
|
||||
case 'date-time':
|
||||
// Need a range here
|
||||
$options = '';
|
||||
if($relative_dates)
|
||||
{
|
||||
$input = self::do_relative_date($lname, $value, $options, $readonly);
|
||||
}
|
||||
else
|
||||
{
|
||||
$input = self::do_absolute_date($lname, $value, $options, $readonly);
|
||||
}
|
||||
break;
|
||||
case 'ajax_select' :
|
||||
// Set some reasonable defaults for the widget
|
||||
$options = array(
|
||||
'get_title' => 'etemplate.ajax_select_widget.array_title',
|
||||
'get_rows' => 'etemplate.ajax_select_widget.array_rows',
|
||||
'id_field' => ajax_select_widget::ARRAY_KEY,
|
||||
);
|
||||
if($field['rows']) {
|
||||
$options['num_rows'] = $field['rows'];
|
||||
}
|
||||
|
||||
// If you specify an option known to the AJAX Select widget, it will be pulled from the list of values
|
||||
// and used as such. All unknown values will be used for selection, not passed through to the query
|
||||
if (isset($field['values']['@']))
|
||||
{
|
||||
$options['values'] = $this->_get_options_from_file($field['values']['@']);
|
||||
unset($field['values']['@']);
|
||||
} else {
|
||||
$options['values'] = array_diff_key($field['values'], array_flip(ajax_select_widget::$known_options));
|
||||
}
|
||||
$options = array_merge($options, array_intersect_key($field['values'], array_flip(ajax_select_widget::$known_options)));
|
||||
|
||||
$input = boetemplate::empty_cell('ajax_select', $lname, array(
|
||||
'readonly' => $readonly,
|
||||
'no_lang' => True,
|
||||
'size' => $options
|
||||
));
|
||||
break;
|
||||
|
||||
case 'link-entry':
|
||||
$input =& boetemplate::empty_cell('link-entry',$this->prefix.$lname,array(
|
||||
'size' => $field['type'] == 'link-entry' ? '' : $field['type'],
|
||||
));
|
||||
// register post-processing of link widget to get eg. needed/required validation
|
||||
etemplate_old::$request->set_to_process(etemplate_old::form_name($form_name,$this->prefix.$lname), 'ext-link');
|
||||
break;
|
||||
case 'select':
|
||||
default:
|
||||
if(strpos($field['type'],'select') === 0)
|
||||
{
|
||||
if (count($field['values']) == 1 && isset($field['values']['@']))
|
||||
{
|
||||
$field['values'] = $this->_get_options_from_file($field['values']['@']);
|
||||
}
|
||||
foreach((array)$field['values'] as $key => $val)
|
||||
{
|
||||
if (substr($val = lang($val),-1) != '*')
|
||||
{
|
||||
$field['values'][$key] = $val;
|
||||
}
|
||||
}
|
||||
$input =& boetemplate::empty_cell($field['type'],$lname,array(
|
||||
'sel_options' => $field['values'],
|
||||
'size' => $field['rows'],
|
||||
'enhance' => true,
|
||||
'no_lang' => True,
|
||||
));
|
||||
}
|
||||
elseif (in_array($field['type'], array_keys(egw_link::app_list())))
|
||||
{
|
||||
// Link entry to a specific app
|
||||
$input =& boetemplate::empty_cell('link-entry',$lname,array(
|
||||
'size' => $field['type'] == 'link-entry' ? '' : $field['type'],
|
||||
));
|
||||
// register post-processing of link widget to get eg. needed/required validation
|
||||
etemplate_old::$request->set_to_process(etemplate_old::form_name($form_name,$lname), 'ext-link');
|
||||
|
||||
} else {
|
||||
error_log('Trying to filter with unsupported field type: ' . $field['type']);
|
||||
$input =& boetemplate::empty_cell($field['type'],$lname,array(
|
||||
'sel_options' => $field['values'],
|
||||
'size' => $field['rows'],
|
||||
'no_lang' => True,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
$cell['data'][0]['c'.$n++] = $row_class.',top';
|
||||
|
||||
if (!is_null($input))
|
||||
{
|
||||
if ($readonly) $input['readonly'] = true;
|
||||
|
||||
$input['needed'] = $cell['needed'] || $field['needed'];
|
||||
|
||||
if (!empty($field['help']) && $row_class != 'th')
|
||||
{
|
||||
$input['help'] = $field['help'];
|
||||
$input['no_lang'] = substr(lang($help),-1) == '*' ? 2 : 0;
|
||||
}
|
||||
boetemplate::add_child($cell,$input);
|
||||
unset($input);
|
||||
}
|
||||
unset($label);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create widgets to select a relative date range
|
||||
*
|
||||
* @param $lname Field name
|
||||
* @param $options
|
||||
* @param $readonly
|
||||
*
|
||||
* @return Array of widget info
|
||||
*/
|
||||
protected static function do_relative_date($lname, Array &$value, $options, $readonly)
|
||||
{
|
||||
// Maybe this could be moved to date widget
|
||||
$input = boetemplate::empty_cell('select',$lname, array(
|
||||
'readonly' => $readonly,
|
||||
'no_lang' => true,
|
||||
'options' => $options,
|
||||
'sel_options' => array('' => lang('all'))
|
||||
));
|
||||
foreach(importexport_helper_functions::$relative_dates as $label => $values)
|
||||
{
|
||||
$input['sel_options'][$label] = lang($label);
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create widgets to select an absolute date range
|
||||
*
|
||||
* @param $lname Field name
|
||||
* @param $options
|
||||
* @param $readonly
|
||||
*
|
||||
* @return Array of widget info
|
||||
*/
|
||||
protected static function do_absolute_date($lname, Array &$value, $options, $readonly)
|
||||
{
|
||||
$input = boetemplate::empty_cell('hbox',$lname);
|
||||
|
||||
$type = 'date';
|
||||
$from = boetemplate::empty_cell($type, $lname.'[from]',array(
|
||||
'readonly' => $readonly,
|
||||
'no_lang' => True,
|
||||
'size' => $options
|
||||
));
|
||||
|
||||
$to = boetemplate::empty_cell($type, $lname.'[to]', array(
|
||||
'readonly' => $readonly,
|
||||
'no_lang' => True,
|
||||
'size' => $options
|
||||
));
|
||||
boetemplate::add_child($input, $from);
|
||||
boetemplate::add_child($input,boetemplate::empty_cell('label','',array(
|
||||
'label' => lang('to'),
|
||||
'no_lang' => true
|
||||
)));
|
||||
boetemplate::add_child($input, $to);
|
||||
return $input;
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
'type' => 'string',
|
||||
'allowed_users' => 'array',
|
||||
'plugin_options' => 'array',
|
||||
'filter' => 'array',
|
||||
'owner' => 'int',
|
||||
'description' => 'string',
|
||||
'modified' => 'timestamp'
|
||||
@ -79,6 +80,8 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
}
|
||||
$options_data = importexport_arrayxml::xml2array( $this->definition['plugin_options'] );
|
||||
$this->definition['plugin_options'] = $options_data['root'];
|
||||
if($this->definition['filter']) $filter = importexport_arrayxml::xml2array( $this->definition['filter'] );
|
||||
$this->definition['filter'] = $filter['root'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,6 +113,8 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
return $this->get_allowed_users();
|
||||
case 'plugin_options' :
|
||||
return $this->get_options();
|
||||
case 'filter':
|
||||
return $this->get_filter();
|
||||
default :
|
||||
return $this->definition[$_attribute_name];
|
||||
}
|
||||
@ -124,6 +129,8 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
return $this->set_allowed_users($_data);
|
||||
case 'plugin_options' :
|
||||
return $this->set_options($_data);
|
||||
case 'filter':
|
||||
return $this->set_filter($_data);
|
||||
default :
|
||||
$this->definition[$_attribute_name] = $_data;
|
||||
return;
|
||||
@ -166,6 +173,24 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
$this->definition['plugin_options'] = $_plugin_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored data filter
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_filter() {
|
||||
return $this->definition['filter'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set stored data filter
|
||||
*
|
||||
* @param filter array of field => settings
|
||||
*/
|
||||
private function set_filter(Array $filter) {
|
||||
$this->definition['filter'] = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts this object to array.
|
||||
* @abstract We need such a function cause PHP5
|
||||
@ -178,6 +203,7 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
$definition = $this->definition;
|
||||
$definition['allowed_users'] = $this->get_allowed_users();
|
||||
$definition['plugin_options'] = $this->get_options();
|
||||
$definition['filter'] = $this->get_filter();
|
||||
return $definition;
|
||||
}
|
||||
|
||||
@ -211,6 +237,7 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
// convert plugin_options into internal representation
|
||||
$this->set_allowed_users( $this->definition['allowed_users'] );
|
||||
$this->set_options( $this->definition['plugin_options'] ? $this->definition['plugin_options'] : array());
|
||||
$this->set_filter( $this->definition['filter'] ? $this->definition['filter'] : array());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,6 +262,7 @@ class importexport_definition implements importexport_iface_egw_record {
|
||||
|
||||
$this->so_sql->data = $this->definition;
|
||||
$this->so_sql->data['plugin_options'] = importexport_arrayxml::array2xml( $this->definition['plugin_options'] );
|
||||
$this->so_sql->data['filter'] = importexport_arrayxml::array2xml( $this->definition['filter'] );
|
||||
$this->so_sql->data['modified'] = time();
|
||||
if ($this->so_sql->save( array( 'definition_id' => $_dst_identifier ))) {
|
||||
throw new Exception('Error: so_sql was not able to save definition: '.$this->get_identifier());
|
||||
|
@ -612,6 +612,7 @@ class importexport_definitions_ui
|
||||
{
|
||||
$this->response = new xajaxResponse();
|
||||
|
||||
egw_framework::include_css_js_response();
|
||||
if ($content['closewindow'])
|
||||
{
|
||||
$this->response->addScript("opener.location.reload();");
|
||||
@ -639,6 +640,7 @@ class importexport_definitions_ui
|
||||
{
|
||||
$GLOBALS['egw']->js->set_onload("document.getElementById('picturebox').style.display = 'none';");
|
||||
egw_framework::validate_file('.', 'etemplate', 'etemplate');
|
||||
egw_framework::validate_file('.', 'etemplate', 'etemplate');
|
||||
common::egw_header();
|
||||
echo '<div id="divMain">'."\n";
|
||||
echo '<div><h3>{Im|Ex}port Wizard</h3></div>';
|
||||
|
@ -173,13 +173,31 @@ class importexport_export_ui {
|
||||
$content['plugin_options_template'] = $options;
|
||||
}
|
||||
}
|
||||
$content['filter'] = $definition->filter;
|
||||
$content['filter']['fields'] = importexport_helper_functions::get_filter_fields($_appname, $selected_plugin);
|
||||
if(!$content['filter']['fields'])
|
||||
{
|
||||
$this->js->set_onload("\$j('input[value=\"filter\"]').parent().hide();");
|
||||
$content['no_filter'] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process relative dates into the current absolute date
|
||||
foreach($content['filter']['fields'] as $field => $settings)
|
||||
{
|
||||
if($content['filter'][$field] && strpos($settings['type'],'date') === 0)
|
||||
{
|
||||
$content['filter'][$field] = importexport_helper_functions::date_rel2abs($content['filter'][$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill selection tab
|
||||
if($definition && $definition->plugin_options['selection'] && !$content['selection_passed']) {
|
||||
$_selection = $definition->plugin_options['selection'];
|
||||
}
|
||||
|
||||
|
||||
if ($_selection && ($content['old_definition'] == $content['definition'] || $content['selection_passed'])) {
|
||||
$readonlys[$tabs]['selection_tab'] = true;
|
||||
$content['selection'] = $_selection;
|
||||
@ -209,9 +227,18 @@ class importexport_export_ui {
|
||||
disable_button('exec[export]');
|
||||
");
|
||||
}
|
||||
|
||||
// Disable / hide definition filter if not selected
|
||||
if($content['selection'] !== 'filter')
|
||||
{
|
||||
$this->js->set_onload("
|
||||
\$j('div.filters').hide();
|
||||
");
|
||||
}
|
||||
|
||||
$preserv['old_definition'] = $content['definition'];
|
||||
if (($prefs = $GLOBALS['egw_info']['user']['preferences']['importexport'][$definition->definition_id]) &&
|
||||
($prefs = unserialize($prefs)) && !$content['selection']['plugin_override'])
|
||||
($prefs = unserialize($prefs)) && is_array($content['selection']) && !$content['selection']['plugin_override'])
|
||||
{
|
||||
$selection = $content['selection'];
|
||||
$content = array_merge_recursive($content,$prefs);
|
||||
@ -260,6 +287,26 @@ class importexport_export_ui {
|
||||
'mapping' => array()
|
||||
);
|
||||
}
|
||||
|
||||
// Set filter
|
||||
// Note that because not all dates are DB dates, the plugin has to handle them
|
||||
$filter = $definition->filter;
|
||||
foreach($_content['filter'] as $key => $value)
|
||||
{
|
||||
// Handle multiple values
|
||||
if(!is_array($value) && strpos($value,',') !== false) $value = explode(',',$value);
|
||||
|
||||
$filter[$key] = $value;
|
||||
|
||||
// Skip empty values or empty ranges
|
||||
if(!$value || is_array($value) && array_key_exists('from',$value) && !$value['from'] && !$value['to'] )
|
||||
{
|
||||
unset($filter[$key]);
|
||||
}
|
||||
}
|
||||
unset($_content['filter']);
|
||||
$definition->filter = $filter;
|
||||
|
||||
$definition->plugin_options = array_merge(
|
||||
$definition->plugin_options,
|
||||
$_content
|
||||
|
@ -26,6 +26,25 @@ class importexport_helper_functions {
|
||||
*/
|
||||
public static $dry_run = false;
|
||||
|
||||
/**
|
||||
* Relative date ranges for filtering
|
||||
*/
|
||||
public static $relative_dates = array( // Start: year,month,day,week, End: year,month,day,week
|
||||
'Today' => array(0,0,0,0, 0,0,1,0),
|
||||
'Yesterday' => array(0,0,-1,0, 0,0,0,0),
|
||||
'This week' => array(0,0,0,0, 0,0,0,1),
|
||||
'Last week' => array(0,0,0,-1, 0,0,0,0),
|
||||
'This month' => array(0,0,0,0, 0,1,0,0),
|
||||
'Last month' => array(0,-1,0,0, 0,0,0,0),
|
||||
'Last 3 months' => array(0,-3,0,0, 0,1,0,0),
|
||||
'This quarter'=> array(0,0,0,0, 0,0,0,0), // Just a marker, needs special handling
|
||||
'Last quarter'=> array(0,-4,0,0, 0,-4,0,0), // Just a marker
|
||||
'This year' => array(0,0,0,0, 1,0,0,0),
|
||||
'Last year' => array(-1,0,0,0, 0,0,0,0),
|
||||
'2 years ago' => array(-2,0,0,0, -1,0,0,0),
|
||||
'3 years ago' => array(-3,0,0,0, -2,0,0,0),
|
||||
);
|
||||
|
||||
/**
|
||||
* Files known to cause problems, and will be skipped in a plugin scan
|
||||
* If you put appname => true, the whole app will be skipped.
|
||||
@ -515,4 +534,181 @@ class importexport_helper_functions {
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of filterable fields, and options for those fields
|
||||
*
|
||||
* It tries to automatically pull filterable fields from the list of fields in the wizard,
|
||||
* and sets widget properties. The plugin can edit / set the fields by implementing
|
||||
* get_filter_fields(Array &$fields).
|
||||
*
|
||||
* Currently only supports select,select-cat,select-account,date,date-time
|
||||
*
|
||||
* @param $app_name String name of app
|
||||
* @param $plugin_name Name of the plugin
|
||||
*
|
||||
* @return Array ([fieldname] => array(widget settings), ...)
|
||||
*/
|
||||
public static function get_filter_fields($app_name, $plugin_name, $wizard_plugin = null, $record_classname = null)
|
||||
{
|
||||
$fields = array();
|
||||
try {
|
||||
if($record_classname == null) $record_classname = $app_name . '_egw_record';
|
||||
if(!class_exists($record_classname)) throw new Exception('Bad class name ' . $record_classname);
|
||||
|
||||
$plugin = is_object($plugin_name) ? $plugin_name : new $plugin_name();
|
||||
$plugin_name = get_class($plugin);
|
||||
|
||||
if(!$wizard_plugin)
|
||||
{
|
||||
$wizard_name = $app_name . '_wizard_' . str_replace($app_name . '_', '', $plugin_name);
|
||||
if(!class_exists($wizard_name)) throw new Exception('Bad wizard name ' . $wizard_name);
|
||||
$wizard_plugin = new $wizard_name;
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
error_log($e->getMessage());
|
||||
return array();
|
||||
}
|
||||
|
||||
// Get field -> label map and initialize fields using wizard field order
|
||||
$fields = $export_fields = $wizard_plugin->get_export_fields();
|
||||
|
||||
foreach($record_classname::$types as $type => $type_fields)
|
||||
{
|
||||
// Only these for now, until filter methods for others are figured out
|
||||
if(!in_array($type, array('select','select-cat','select-account','date','date-time'))) continue;
|
||||
foreach($type_fields as $field_name)
|
||||
{
|
||||
$fields[$field_name] = array(
|
||||
'name' => $field_name,
|
||||
'label' => $export_fields[$field_name] ? $export_fields[$field_name] : $field_name,
|
||||
'type' => $type
|
||||
);
|
||||
}
|
||||
}
|
||||
// Add custom fields
|
||||
$custom = config::get_customfields($app_name);
|
||||
foreach($custom as $field_name => $settings)
|
||||
{
|
||||
$settings['name'] = '#'.$field_name;
|
||||
$fields['#'.$field_name] = $settings;
|
||||
}
|
||||
|
||||
foreach($fields as $field_name => &$settings) {
|
||||
// Can't really filter on these (or at least no generic, sane way figured out yet)
|
||||
if(!is_array($settings) || in_array($settings['type'], array('text','button', 'label','url','url-email','url-phone','htmlarea')))
|
||||
{
|
||||
unset($fields[$field_name]);
|
||||
continue;
|
||||
}
|
||||
if($settings['type'] == 'radio') $settings['type'] = 'select';
|
||||
switch($settings['type'])
|
||||
{
|
||||
case 'checkbox':
|
||||
// This isn't quite right - there's only 2 options and you can select both
|
||||
$settings['type'] = 'select-bool';
|
||||
$settings['rows'] = 1;
|
||||
$settings['enhance'] = true;
|
||||
break;
|
||||
case 'select-cat':
|
||||
$settings['rows'] = "5,,,$app_name";
|
||||
$settings['enhance'] = true;
|
||||
break;
|
||||
case 'select-account':
|
||||
$settings['rows'] = '5,both';
|
||||
$settings['enhance'] = true;
|
||||
break;
|
||||
case 'select':
|
||||
$settings['rows'] = 5;
|
||||
$settings['enhance'] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(method_exists($plugin, 'get_filter_fields'))
|
||||
{
|
||||
$plugin->get_filter_fields($fields);
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a relative date (Yesterday) into absolute (2012-12-31) date
|
||||
*
|
||||
* @param $value String description of date matching $relative_dates
|
||||
*
|
||||
* @return Array([from] => timestamp, [to]=> timestamp), inclusive
|
||||
*/
|
||||
public static function date_rel2abs($value)
|
||||
{
|
||||
if(is_array($value))
|
||||
{
|
||||
$abs = array();
|
||||
foreach($value as $key => $val)
|
||||
{
|
||||
$abs[$key] = self::date_rel2abs($val);
|
||||
}
|
||||
return $abs;
|
||||
}
|
||||
if($date = self::$relative_dates[$value])
|
||||
{
|
||||
$year = (int) date('Y');
|
||||
$month = (int) date('m');
|
||||
$day = (int) date('d');
|
||||
$today = mktime(0,0,0,date('m'),date('d'),date('Y'));
|
||||
|
||||
list($syear,$smonth,$sday,$sweek,$eyear,$emonth,$eday,$eweek) = $date;
|
||||
|
||||
if(stripos($value, 'quarter') !== false)
|
||||
{
|
||||
// Handle quarters
|
||||
$start = mktime(0,0,0,((int)floor(($smonth+$month) / 3.1)) * 3 + 1, 1, $year);
|
||||
$end = mktime(0,0,0,((int)floor(($emonth+$month) / 3.1)+1) * 3 + 1, 1, $year);
|
||||
}
|
||||
elseif ($syear || $eyear)
|
||||
{
|
||||
$start = mktime(0,0,0,1,1,$syear+$year);
|
||||
$end = mktime(0,0,0,1,1,$eyear+$year);
|
||||
}
|
||||
elseif ($smonth || $emonth)
|
||||
{
|
||||
$start = mktime(0,0,0,$smonth+$month,1,$year);
|
||||
$end = mktime(0,0,0,$emonth+$month,1,$year);
|
||||
}
|
||||
elseif ($sday || $eday)
|
||||
{
|
||||
$start = mktime(0,0,0,$month,$sday+$day,$year);
|
||||
$end = mktime(0,0,0,$month,$eday+$day,$year);
|
||||
}
|
||||
elseif ($sweek || $eweek)
|
||||
{
|
||||
$wday = (int) date('w'); // 0=sun, ..., 6=sat
|
||||
switch($GLOBALS['egw_info']['user']['preferences']['calendar']['weekdaystarts'])
|
||||
{
|
||||
case 'Sunday':
|
||||
$weekstart = $today - $wday * 24*60*60;
|
||||
break;
|
||||
case 'Saturday':
|
||||
$weekstart = $today - (6-$wday) * 24*60*60;
|
||||
break;
|
||||
case 'Moday':
|
||||
default:
|
||||
$weekstart = $today - ($wday ? $wday-1 : 6) * 24*60*60;
|
||||
break;
|
||||
}
|
||||
$start = $weekstart + $sweek*7*24*60*60;
|
||||
$end = $weekstart + $eweek*7*24*60*60;
|
||||
}
|
||||
$end_param = $end - 24*60*60;
|
||||
|
||||
// Take 1 second off end to provide an inclusive range.for filtering
|
||||
$end -= 1;
|
||||
|
||||
//echo __METHOD__."($value,$start,$end) today=".date('l, Y-m-d H:i',$today)." ==> <br />".date('l, Y-m-d H:i:s',$start)." <= date <= ".date('l, Y-m-d H:i:s',$end)."</p>\n";
|
||||
return array('from' => $start, 'to' => $end);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} // end of importexport_helper_functions
|
||||
|
@ -460,8 +460,30 @@
|
||||
|
||||
if($type == 'export')
|
||||
{
|
||||
// Set to export all
|
||||
$definition->plugin_options = array_merge($definition->plugin_options, array('selection' => 'all'));
|
||||
// Set to export all or filter, if set
|
||||
$selection = array('selection' => 'all');
|
||||
if($definition->filter)
|
||||
{
|
||||
$fields = importexport_helper_functions::get_filter_fields($definition->application, $po);
|
||||
$selection = array('selection' => 'filter');
|
||||
$filters = array();
|
||||
foreach($definition->filter as $field => $value)
|
||||
{
|
||||
// Handle multiple values
|
||||
if(!is_array($value) && strpos($value,',') !== false) $value = explode(',',$value);
|
||||
|
||||
$filters[$field] = $value;
|
||||
|
||||
// Process relative dates into the current absolute date
|
||||
if($filters[$field] && strpos($fields[$field]['type'],'date') === 0)
|
||||
{
|
||||
$filters[$field] = importexport_helper_functions::date_rel2abs($value);
|
||||
}
|
||||
}
|
||||
// Update filter to use current absolute dates
|
||||
$definition->filter = $filters;
|
||||
}
|
||||
$definition->plugin_options = array_merge($definition->plugin_options, $selection);
|
||||
}
|
||||
|
||||
foreach($targets as $target)
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* eGroupWare - A basic implementation of a wizard to go with the basic CSV plugin.
|
||||
*
|
||||
*
|
||||
* To add or remove steps, change $this->steps appropriately. The key is the function, the value is the title.
|
||||
* Don't go past 80, as that's where the wizard picks it back up again to finish it off.
|
||||
*
|
||||
*
|
||||
* For the field list to work properly, you'll have to populate $export_fields with the fields available
|
||||
*
|
||||
*
|
||||
* NB: Your wizard class must be in <appname>/inc/class.appname_wizard_<plugin_name>.inc.php
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
@ -15,7 +15,7 @@
|
||||
* @author Nathan Gray
|
||||
*/
|
||||
|
||||
class importexport_wizard_basic_export_csv
|
||||
class importexport_wizard_basic_export_csv
|
||||
{
|
||||
|
||||
const TEMPLATE_MARKER = '-eTemplate-';
|
||||
@ -31,6 +31,7 @@ class importexport_wizard_basic_export_csv
|
||||
protected $step_templates = array(
|
||||
'wizard_step30' => 'importexport.wizard_basic_export_csv.choose_fields',
|
||||
'wizard_step40' => 'importexport.wizard_basic_export_csv.choosesepncharset',
|
||||
'wizard_step50' => 'importexport.wizard_basic_export_csv.filter',
|
||||
);
|
||||
|
||||
|
||||
@ -58,6 +59,7 @@ class importexport_wizard_basic_export_csv
|
||||
$this->steps = array(
|
||||
'wizard_step30' => lang('Choose fields to export'),
|
||||
'wizard_step40' => lang('Choose seperator and charset'),
|
||||
'wizard_step50' => lang('Filters'),
|
||||
);
|
||||
list($appname, $part2) = explode('_', get_class($this));
|
||||
if(!$GLOBALS['egw_info']['apps'][$appname]) $appname .= '_'.$part2; // Handle apps with _ in the name
|
||||
@ -222,6 +224,73 @@ class importexport_wizard_basic_export_csv
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set export filters
|
||||
*
|
||||
* @param array $content
|
||||
* @param array $sel_options
|
||||
* @param array $readonlys
|
||||
* @param array $preserv
|
||||
* @return string template name
|
||||
*/
|
||||
function wizard_step50(&$content, &$sel_options, &$readonlys, &$preserv)
|
||||
{
|
||||
if($this->debug) error_log(get_class($this) . '::' . __METHOD__ .'->$content '.print_r($content,true));
|
||||
// return from submit
|
||||
if ($content['step'] == 'wizard_step50') {
|
||||
// Process submitted
|
||||
unset($content['filter']);
|
||||
unset($content['set_filter']['fields']);
|
||||
foreach($content['set_filter'] as $key => $value)
|
||||
{
|
||||
if($value) {
|
||||
$content['filter'][$key] = $value;
|
||||
}
|
||||
}
|
||||
unset($content['set_filter']);
|
||||
|
||||
// Next step
|
||||
switch (array_search('pressed', $content['button']))
|
||||
{
|
||||
case 'next':
|
||||
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],1);
|
||||
case 'previous' :
|
||||
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],-1);
|
||||
case 'finish':
|
||||
return 'wizard_finish';
|
||||
default :
|
||||
return $this->wizard_step50($content,$sel_options,$readonlys,$preserv);
|
||||
}
|
||||
} else {
|
||||
|
||||
// Step 50 - filters
|
||||
$content['msg'] = $this->steps['wizard_step50'];
|
||||
$content['step'] = 'wizard_step50';
|
||||
|
||||
// Find filterable fields
|
||||
if(!$content['set_filter'] && $content['filter']) {
|
||||
$load = true;
|
||||
}
|
||||
$content['set_filter']['fields'] = importexport_helper_functions::get_filter_fields(
|
||||
$content['application'],$content['plugin'],$this
|
||||
);
|
||||
// Load existing filter from either content or definition
|
||||
if($load)
|
||||
{
|
||||
foreach($content['set_filter']['fields'] as $field => $settings)
|
||||
{
|
||||
$content['set_filter'][$field] = $content['filter'][$field];
|
||||
}
|
||||
}
|
||||
|
||||
$sel_options = array();
|
||||
|
||||
$preserv = $content;
|
||||
unset ($preserv['button']);
|
||||
return $this->step_templates[$content['step']];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose export fields for use elsewhere
|
||||
*/
|
||||
|
@ -10,5 +10,8 @@ function clear_options(id) {
|
||||
for(var count = list.options.length - 1; count >= 0; count--) {
|
||||
list.options[count] = null;
|
||||
}
|
||||
if($j().chosen && list) {
|
||||
$j(list).trigger("liszt:updated");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* EGroupware - eTemplates for Application importexport
|
||||
* http://www.egroupware.org
|
||||
* generated by soetemplate::dump4setup() 2012-12-17 16:23
|
||||
* generated by soetemplate::dump4setup() 2012-12-31 13:19
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package importexport
|
||||
@ -89,7 +89,14 @@ $templ_data[] = array('name' => 'importexport.export_dialog.options_tab','templa
|
||||
display: none;
|
||||
}','modified' => '1286482130',);
|
||||
|
||||
$templ_data[] = array('name' => 'importexport.export_dialog.selection_tab','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:2:{s:2:"c1";s:4:",top";s:2:"h1";s:27:",@plugin_selectors_template";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:4:"html";s:4:"name";s:21:"plugin_selectors_html";s:7:"no_lang";s:1:"1";}}i:2;a:1:{s:1:"A";a:2:{s:4:"type";s:8:"template";s:4:"name";s:26:"@plugin_selectors_template";}}}s:4:"rows";i:2;s:4:"cols";i:1;s:4:"size";s:6:",200px";s:7:"options";a:1:{i:1;s:5:"200px";}}}','size' => ',200px','style' => '','modified' => '1158223796',);
|
||||
$templ_data[] = array('name' => 'importexport.export_dialog.selection_tab','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:10:{s:2:"h3";s:30:"20,!@plugin_selectors_template";s:2:"h2";s:27:",@plugin_selectors_template";s:2:"c2";s:4:",top";s:2:"h4";s:28:",!@plugin_selectors_template";s:2:"c3";s:2:"th";s:2:"h1";s:29:"20,@plugin_selectors_template";s:2:"c1";s:2:"th";s:2:"c4";s:4:",top";s:1:"B";s:14:"300,@no_filter";s:1:"A";s:3:"150";}i:1;a:2:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:17:"Definition filter";}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:4:"html";s:4:"name";s:21:"plugin_selectors_html";s:7:"no_lang";s:1:"1";}s:1:"B";a:4:{s:4:"type";s:3:"box";s:4:"span";s:8:",filters";s:4:"size";s:1:"1";i:1;a:2:{s:4:"type";s:6:"filter";s:4:"name";s:6:"filter";}}}i:3;a:2:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:17:"Definition filter";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:8:"template";s:4:"name";s:26:"@plugin_selectors_template";}s:1:"B";a:5:{s:4:"type";s:3:"box";s:4:"span";s:8:",filters";s:4:"size";s:1:"1";i:1;a:2:{s:4:"type";s:6:"filter";s:4:"name";s:6:"filter";}s:7:"onclick";s:105:"\\$j(\'input[value=\\\'filter\\\']\').not(\':checked\').attr(\'checked\',true).parent().effect(\'highlight\',{},2000);";}}}s:4:"rows";i:4;s:4:"cols";i:2;s:4:"size";s:10:"100%,200px";s:7:"options";a:2:{i:0;s:4:"100%";i:1;s:5:"200px";}}}','size' => '100%,200px','style' => 'select[multiple] {
|
||||
width: 400px;
|
||||
}
|
||||
.filters {
|
||||
max-height: 300px;
|
||||
min-height: 150px;
|
||||
overflow-y: auto;
|
||||
}','modified' => '1158223796',);
|
||||
|
||||
$templ_data[] = array('name' => 'importexport.import_definition','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:92:"Import definitions (Attension: Existing definitions with equal names will be overwritten!!!)";}}i:2;a:1:{s:1:"A";a:2:{s:4:"type";s:4:"file";s:4:"name";s:11:"import_file";}}i:3;a:1:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:6:"button";s:5:"label";s:6:"Import";s:4:"name";s:6:"import";}i:2;a:3:{s:4:"type";s:6:"button";s:4:"name";s:6:"update";s:5:"label";s:26:"Update default-definitions";}}}}s:4:"rows";i:3;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1306253183',);
|
||||
|
||||
@ -122,6 +129,10 @@ $templ_data[] = array('name' => 'importexport.wizard_basic_export_csv.choosesepn
|
||||
|
||||
$templ_data[] = array('name' => 'importexport.wizard_basic_export_csv.choose_fields','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:4:"name";s:3:"msg";}}i:2;a:1:{s:1:"A";a:7:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:1:{s:2:"c1";s:2:"th";}i:1;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Field";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Export";}i:2;a:7:{s:4:"type";s:10:"buttononly";s:4:"size";s:5:"check";s:5:"label";s:9:"Check all";s:4:"name";s:9:"check_all";s:4:"help";s:9:"Check all";s:7:"onclick";s:98:"jQuery(\'input:checkbox\').attr(\'checked\', !jQuery(\'input:checkbox\').attr(\'checked\')); return false;";s:6:"needed";s:1:"1";}}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[name]";s:7:"no_lang";s:1:"1";}s:1:"B";a:4:{s:4:"type";s:8:"checkbox";s:7:"no_lang";s:1:"1";s:4:"name";s:14:"export[${row}]";s:4:"size";s:18:"{$row_cont[field]}";}}}s:4:"rows";i:2;s:4:"cols";i:2;s:4:"size";s:10:",,,,,,auto";s:4:"name";s:6:"fields";s:7:"options";a:1:{i:6;s:4:"auto";}}}}s:4:"rows";i:2;s:4:"cols";i:1;s:7:"options";a:0:{}}}','size' => '','style' => '','modified' => '1286466690',);
|
||||
|
||||
$templ_data[] = array('name' => 'importexport.wizard_basic_export_csv.filter','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:6:"filter";s:4:"name";s:10:"set_filter";s:4:"size";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => 'select {
|
||||
width: 200px;
|
||||
}','modified' => '1356969972',);
|
||||
|
||||
$templ_data[] = array('name' => 'importexport.wizard_basic_import_csv.choosesepncharset','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:7:{i:0;a:2:{s:1:"B";s:5:"180px";s:2:"h5";s:9:",@no_cats";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:14:"Fieldseperator";}s:1:"B";a:4:{s:4:"type";s:4:"text";s:7:"no_lang";s:1:"1";s:4:"name";s:8:"fieldsep";s:4:"size";s:1:"1";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:15:"Charset of file";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:7:"charset";s:4:"span";s:9:",width180";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:20:"Header lines to skip";}s:1:"B";a:3:{s:4:"type";s:3:"int";s:4:"name";s:16:"num_header_lines";s:4:"size";s:1:"0";}}i:5;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:17:"Update categories";}s:1:"B";a:2:{s:4:"type";s:6:"select";s:4:"name";s:11:"update_cats";}}i:6;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:14:"Import data is";}s:1:"B";a:2:{s:4:"type";s:6:"select";s:4:"name";s:7:"convert";}}}s:4:"rows";i:6;s:4:"cols";i:2;}}','size' => '','style' => '.width180 select { width:150px;}','modified' => '1287425796',);
|
||||
|
||||
$templ_data[] = array('name' => 'importexport.wizard_basic_import_csv.conditions','template' => '','lang' => '','group' => '0','version' => '1.9.002','data' => 'a:1:{i:0;a:8:{s:4:"type";s:4:"vbox";s:4:"data";a:2:{i:0;a:0:{}i:1;a:4:{s:1:"A";a:2:{s:4:"type";s:6:"select";s:4:"name";s:14:"${row}[string]";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"${row}[type]";}i:2;a:2:{s:4:"type";s:4:"text";s:4:"name";s:12:"${row}[op_2]";}}s:1:"C";a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"${row}[true]";}s:1:"D";a:2:{s:4:"type";s:6:"select";s:4:"name";s:13:"${row}[false]";}}}s:4:"rows";i:1;s:4:"cols";i:4;s:4:"size";s:1:"3";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:142:"How to merge with existing data? For each record, all conditions are evaluated from top to bottom, or stop. For blind insert, leave blank. ";}i:2;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:1:{s:2:"c1";s:2:"th";}i:1;a:6:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Field";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Condition";}s:1:"C";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";s:4:"span";s:1:"2";i:1;a:4:{s:4:"type";s:5:"label";s:4:"span";s:1:"2";s:5:"label";s:4:"True";s:5:"align";s:6:"center";}i:2;a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,2,0";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Action";}i:2;a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"Stop";s:5:"align";s:5:"right";}}}s:1:"D";a:1:{s:4:"type";s:5:"label";}s:1:"E";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";s:4:"span";s:1:"2";i:1;a:4:{s:4:"type";s:5:"label";s:4:"span";s:1:"2";s:5:"label";s:5:"False";s:5:"align";s:6:"center";}i:2;a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,2,0";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Action";}i:2;a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"Stop";s:5:"align";s:5:"right";}}}s:1:"F";a:1:{s:4:"type";s:5:"label";}}i:2;a:6:{s:1:"A";a:4:{s:4:"type";s:6:"select";s:4:"name";s:14:"${row}[string]";s:4:"size";s:6:"Select";s:7:"no_lang";s:1:"1";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"type";s:6:"select";s:4:"name";s:12:"${row}[type]";s:7:"no_lang";s:1:"1";}i:2;a:3:{s:4:"type";s:4:"text";s:4:"name";s:12:"${row}[op_2]";s:7:"no_lang";s:1:"1";}}s:1:"C";a:4:{s:4:"type";s:6:"select";s:4:"name";s:20:"${row}[true][action]";s:4:"size";s:6:"Select";s:7:"no_lang";s:1:"1";}s:1:"D";a:3:{s:4:"type";s:8:"checkbox";s:5:"align";s:6:"center";s:4:"name";s:18:"${row}[true][stop]";}s:1:"E";a:4:{s:4:"type";s:6:"select";s:4:"name";s:21:"${row}[false][action]";s:4:"size";s:6:"Select";s:7:"no_lang";s:1:"1";}s:1:"F";a:4:{s:4:"type";s:8:"checkbox";s:5:"align";s:6:"center";s:4:"name";s:19:"${row}[false][stop]";s:4:"size";s:7:"1,false";}}}s:4:"rows";i:2;s:4:"cols";i:6;s:4:"name";s:10:"conditions";s:7:"options";a:0:{}}i:3;a:5:{s:4:"type";s:6:"button";s:4:"name";s:11:"button[add]";s:5:"label";s:3:"add";s:4:"help";s:27:"Add an additional condition";s:7:"onclick";s:37:"xajax_eT_wrapper(this); return false;";}}}','size' => '','style' => '','modified' => '1320350666',);
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
$setup_info['importexport']['name'] = 'importexport';
|
||||
$setup_info['importexport']['version'] = '1.9.003';
|
||||
$setup_info['importexport']['version'] = '1.9.004';
|
||||
$setup_info['importexport']['app_order'] = 2;
|
||||
$setup_info['importexport']['enable'] = 2;
|
||||
$setup_info['importexport']['tables'] = array('egw_importexport_definitions');
|
||||
@ -57,3 +57,4 @@ $setup_info['importexport']['check_install'] = array(
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
@ -25,7 +25,8 @@ $phpgw_baseline = array(
|
||||
'plugin_options' => array('type' => 'longtext'),
|
||||
'owner' => array('type' => 'int','precision' => '20'),
|
||||
'description' => array('type' => 'varchar','precision' => '255'),
|
||||
'modified' => array('type' => 'timestamp')
|
||||
'modified' => array('type' => 'timestamp'),
|
||||
'filter' => array('type' => 'longtext')
|
||||
),
|
||||
'pk' => array('definition_id'),
|
||||
'fk' => array(),
|
||||
|
@ -100,3 +100,13 @@ function importexport_upgrade1_9_002()
|
||||
|
||||
return $GLOBALS['setup_info']['importexport']['currentver'] = '1.9.003';
|
||||
}
|
||||
|
||||
function importexport_upgrade1_9_003()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->AddColumn('egw_importexport_definitions','filter',array(
|
||||
'type' => 'longtext'
|
||||
));
|
||||
|
||||
return $GLOBALS['setup_info']['importexport']['currentver'] = '1.9.004';
|
||||
}
|
||||
|
||||
|
@ -52,19 +52,44 @@
|
||||
</grid>
|
||||
</template>
|
||||
<template id="importexport.export_dialog.selection_tab" template="" lang="" group="0" version="">
|
||||
<grid height="200px">
|
||||
<grid width="100%" height="200px">
|
||||
<columns>
|
||||
<column/>
|
||||
<column width="150"/>
|
||||
<column width="300" disabled="@no_filter"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th" height="20" disabled="@plugin_selectors_template">
|
||||
<description/>
|
||||
<description value="Definition filter"/>
|
||||
</row>
|
||||
<row valign="top" disabled="@plugin_selectors_template">
|
||||
<html id="plugin_selectors_html" no_lang="1"/>
|
||||
<box class="filters">
|
||||
<filter id="filter"/>
|
||||
</box>
|
||||
</row>
|
||||
<row>
|
||||
<row class="th" height="20" disabled="!@plugin_selectors_template">
|
||||
<description/>
|
||||
<description value="Definition filter"/>
|
||||
</row>
|
||||
<row valign="top" disabled="!@plugin_selectors_template">
|
||||
<template id="@plugin_selectors_template"/>
|
||||
<box onclick="\$j('input[value=\'filter\']').not(':checked').attr('checked',true).parent().effect('highlight',{},2000);" class="filters">
|
||||
<filter id="filter"/>
|
||||
</box>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<styles>
|
||||
select[multiple] {
|
||||
width: 400px;
|
||||
}
|
||||
.filters {
|
||||
max-height: 300px;
|
||||
min-height: 150px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</styles>
|
||||
</template>
|
||||
<template id="importexport.export_dialog.options_tab" template="" lang="" group="0" version="">
|
||||
<grid height="200px">
|
||||
|
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="importexport.wizard_basic_export_csv.choose_fields" template="" lang="" group="0" version="1.9.001">
|
||||
<grid>
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<description id="msg" span="all"/>
|
||||
</row>
|
||||
<row>
|
||||
<grid overflow="auto" id="fields">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<description value="Field"/>
|
||||
<hbox>
|
||||
<description value="Export"/>
|
||||
<buttononly statustext="Check all" label="Check all" id="check_all" needed="1" onclick="jQuery('input:checkbox').attr('checked', !jQuery('input:checkbox').attr('checked')); return false;" options="check"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row>
|
||||
<description id="${row}[name]" no_lang="1"/>
|
||||
<checkbox id="export[${row}]" no_lang="1" options="{$row_cont[field]}"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
</overlay>
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="importexport.wizard_basic_export_csv.filter" template="" lang="" group="0" version="1.9.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<filter id="set_filter" options="1"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<styles>select {
|
||||
width: 200px;
|
||||
}</styles>
|
||||
</template>
|
||||
</overlay>
|
Loading…
Reference in New Issue
Block a user