From 1f2770639c7afe113d61a7d00ebf05bb3665c315 Mon Sep 17 00:00:00 2001 From: nathangray Date: Wed, 14 Mar 2018 16:09:47 -0600 Subject: [PATCH] * Calendar - iCal import - Add option to specify owner of imported events - Add option to empty calendar before import --- .../inc/class.calendar_import_ical.inc.php | 85 +++++++++++++++++-- .../class.calendar_wizard_import_ical.inc.php | 70 ++++++++++++++- .../default/import.ical_conditions.xet | 13 +++ .../importexport_wizard_ical_chooseowner.xet | 29 +++++++ .../class.importexport_widget_filter.inc.php | 18 ++-- 5 files changed, 199 insertions(+), 16 deletions(-) create mode 100644 calendar/templates/default/import.ical_conditions.xet create mode 100644 calendar/templates/default/importexport_wizard_ical_chooseowner.xet diff --git a/calendar/inc/class.calendar_import_ical.inc.php b/calendar/inc/class.calendar_import_ical.inc.php index f8155491ce..1c04b45a29 100644 --- a/calendar/inc/class.calendar_import_ical.inc.php +++ b/calendar/inc/class.calendar_import_ical.inc.php @@ -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 diff --git a/calendar/inc/class.calendar_wizard_import_ical.inc.php b/calendar/inc/class.calendar_wizard_import_ical.inc.php index afb4ff1784..a3e1d2d805 100644 --- a/calendar/inc/class.calendar_wizard_import_ical.inc.php +++ b/calendar/inc/class.calendar_wizard_import_ical.inc.php @@ -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']]; } } diff --git a/calendar/templates/default/import.ical_conditions.xet b/calendar/templates/default/import.ical_conditions.xet new file mode 100644 index 0000000000..791748408b --- /dev/null +++ b/calendar/templates/default/import.ical_conditions.xet @@ -0,0 +1,13 @@ + + + + +