* Calendar - iCal import - Add option to specify owner of imported events

- Add option to empty calendar before import
This commit is contained in:
nathangray 2018-03-14 16:09:47 -06:00
parent b5a4b050d5
commit 1f2770639c
5 changed files with 199 additions and 16 deletions

View File

@ -133,17 +133,24 @@ class calendar_import_ical implements importexport_iface_import_plugin {
}
// switch off notifications by default
$plugin_options = $_definition->plugin_options;
if (!isset($_definition->plugin_options['no_notification']))
if (!array_key_exists('no_notification', $_definition->plugin_options))
{
$plugin_options['no_notification'] = true;
$_definition->plugin_options = $plugin_options;
}
// Set owner, if not set will be null (current user)
$owner = $plugin_options['cal_owner'];
// Purge
$this->purge_calendar($owner, $_definition->filter['purge'], $plugin_options['no_notification']);
// User wants conflicting events to not be imported
if($_definition->plugin_options['skip_conflicts'])
{
$calendar_ical->conflict_callback = array($this, 'conflict_warning');
}
if (!$calendar_ical->importVCal($_stream, -1,null,false,0,'',null,null,null,$_definition->plugin_options['no_notification']))
if (!$calendar_ical->importVCal($_stream, -1,null,false,0,'',$owner,null,null,$_definition->plugin_options['no_notification']))
{
$this->errors[] = lang('Error: importing the iCal');
}
@ -155,10 +162,10 @@ class calendar_import_ical implements importexport_iface_import_plugin {
return $calendar_ical->events_imported;
}
/**
* Add a warning message about conflicting events
*
*
* @param int $record_num Current record index
* @param Array $conflicts List of found conflicting events
*/
@ -173,10 +180,50 @@ class calendar_import_ical implements importexport_iface_import_plugin {
// iCal will always count as imported, even if it wasn't
$this->results['imported'] -= 1;
$this->results['skipped']++;
}
/**
* Empty the calendar before importing
*
* @param string $owner
* @param array|string $timespan
*/
protected function purge_calendar($owner, $timespan, $skip_notification)
{
if(!$owner)
{
$owner = $GLOBALS['egw_info']['user']['account_id'];
}
if(!is_array($timespan))
{
$timespan = importexport_helper_functions::date_rel2abs($timespan);
}
if (!$timespan)
{
return;
}
// Get events in timespan
$events = $this->bo->search(array(
'start' => $timespan['from'],
'end' => $timespan['to'],
'users' => $owner,
'num_rows' => -1
));
// Delete
foreach($events as $event)
{
$result = $this->bo->delete($event['id'], $event['recur_date'], true, $skip_notification);
if($result)
{
$this->results['deleted']++;
}
}
}
/**
* returns translated name of plugin
*
@ -229,6 +276,34 @@ class calendar_import_ical implements importexport_iface_import_plugin {
// lets do it!
}
/**
* Filter while importing
*
* The only one currently supported is purge range, nothing on actual fields
*
* @see importexport_helper_functions::get_filter_fields
*
* @param array $fields
*/
public function get_filter_fields(&$fields) {
$fields = array(
'purge' => array(
'type' => 'date',
'name' =>'purge',
'label'=>'Empty target calendar before importing',
'empty_label' => 'No'
)
);
}
/**
* Get the class name for the egw_record to use
*
* @return string;
*/
public static function get_egw_record_class()
{
return 'calendar_egw_record';
}
/**
* Returns warnings that were encountered during importing
* Maximum of one warning message per record, but you can append if you need to

View File

@ -23,15 +23,19 @@ class calendar_wizard_import_ical
* List of eTemplates to use for each step. You can override this with your own etemplates steps.
*/
protected $step_templates = array(
'wizard_step55' => 'calendar.import.conditions'
'wizard_step55' => 'calendar.import.ical_conditions',
'wizard_step60' => 'calendar.importexport_wizard_ical_chooseowner'
);
/**
* constructor
*/
function __construct()
{
Api\Framework::includeJS('.','et2_widget_owner','calendar');
Api\Framework::includeCSS('calendar','calendar');
$this->steps = array(
'wizard_step55' => lang('Edit conditions'),
'wizard_step60' => lang('Choose owner of imported data'),
);
}
@ -49,6 +53,16 @@ class calendar_wizard_import_ical
// return from step55
if ($content['step'] == 'wizard_step55')
{
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']);
switch (array_search('pressed', $content['button']))
{
case 'next':
@ -72,10 +86,62 @@ class calendar_wizard_import_ical
}
$preserv = $content;
unset ($preserv['button']);
// No real conditions, but we share a template
$content['no_conditions'] = true;
// Filter - Purge
$content['set_filter']['fields'] = importexport_helper_functions::get_filter_fields(
$content['application'],$content['plugin'],$this
);
// Load existing filter from either content or definition
foreach($content['set_filter']['fields'] as $field => $settings)
{
$content['set_filter'][$field] = $content['filter'][$field];
}
return $this->step_templates[$content['step']];
}
}
/**
* Set / override owner
*/
function wizard_step60(&$content, &$sel_options, &$readonlys, &$preserv)
{
if($this->debug) error_log('addressbook.importexport.addressbook_csv_import::wizard_step60->$content '.print_r($content,true));
unset($content['no_owner_map']);
// return from step60
if ($content['step'] == 'wizard_step60')
{
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_step60($content,$sel_options,$readonlys,$preserv);
}
}
// init step60
else
{
$content['text'] = $this->steps['wizard_step60'];
$content['step'] = 'wizard_step60';
if(!array_key_exists('cal_owner', $content) && $content['plugin_options']) {
$content['cal_owner'] = $content['plugin_options']['cal_owner'];
}
// Include calendar-owner widget
$response = Api\Json\Response::get();
$response->includeScript(Api\Egw::link('/calendar/js/et2_widget_owner.js'));
Api\Framework::includeJS('','et2_widget_owner');
$preserv = $content;
unset ($preserv['button']);
return $this->step_templates[$content['step']];
}
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<overlay>
<template id="calendar.import.ical_conditions" template="" lang="" group="0" version="16.1">
<template id="importexport.wizard_basic_import_csv.conditions" disabled="@no_conditions"/>
<hbox>
<description value="Do not import conflicting events"/>
<checkbox id="skip_conflicts" />
</hbox>
<filter id="set_filter" relative_dates="true"/>
</template>
</overlay>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<overlay>
<template id="calendar.importexport_wizard_ical_chooseowner" template="" lang="" group="0" version="1.9.001">
<grid>
<columns>
<column/>
</columns>
<rows>
<row>
<description id="msg" no_lang="1"/>
</row>
<row>
<select-account id="cal_owner" empty_label="Select"/>
</row>
<row>
<description/>
</row>
<row>
<checkbox label="Skip notifications" id="no_notification"/>
</row>
<row>
<description/>
</row>
</rows>
</grid>
</template>
</overlay>

View File

@ -28,11 +28,11 @@ class importexport_widget_filter extends Etemplate\Widget\Transformer
{
protected static $prefix = '';
protected static $transformation = array(
'type' => 'customfields'
);
/**
* Adapt the settings to custom fields widget
*
@ -67,15 +67,15 @@ class importexport_widget_filter extends Etemplate\Widget\Transformer
self::$transformation['label'] = '';
$this->setElementAttribute($form_name, 'prefix', self::$prefix);
$n = 1;
foreach($fields as $lname => &$field)
{
$type =& $field['type'];
// No filters are required
$field['needed'] = false;
switch($type)
{
case 'date':
@ -84,7 +84,7 @@ class importexport_widget_filter extends Etemplate\Widget\Transformer
$type = $field['type'] = 'date-range';
$options = '';
$this->setElementAttribute($form_name.'['.self::$prefix.$lname.']', 'relative', $relative_dates);
$this->setElementAttribute($form_name.'['.self::$prefix.$lname.']', 'empty_label', lang('All...'));
$this->setElementAttribute($form_name.'['.self::$prefix.$lname.']', 'blur', $field['empty_label'] ? $field['empty_label'] : lang('All...'));
break;
case 'ajax_select' :
// Set some reasonable defaults for the widget
@ -108,7 +108,7 @@ class importexport_widget_filter extends Etemplate\Widget\Transformer
}
$options = array_merge($options, array_intersect_key($field['values'], array_flip(ajax_select_widget::$known_options)));
break;
case 'select':
default:
@ -163,14 +163,14 @@ class importexport_widget_filter extends Etemplate\Widget\Transformer
}
unset($widget);
}
parent::beforeSendToClient($cname, $expand);
$this->setElementAttribute($form_name, 'customfields', $fields);
$this->setElementAttribute($form_name, 'fields',array_fill_keys(array_keys($fields), true));
return false;
}
public function validate($cname, array $expand, array $content, &$validated=array())
{
$form_name = self::form_name($cname, $this->id, $expand);