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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/calendar/templates/default/importexport_wizard_ical_chooseowner.xet b/calendar/templates/default/importexport_wizard_ical_chooseowner.xet
new file mode 100644
index 0000000000..a375897f12
--- /dev/null
+++ b/calendar/templates/default/importexport_wizard_ical_chooseowner.xet
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/importexport/inc/class.importexport_widget_filter.inc.php b/importexport/inc/class.importexport_widget_filter.inc.php
index 47ce3cc7ba..809bf58123 100644
--- a/importexport/inc/class.importexport_widget_filter.inc.php
+++ b/importexport/inc/class.importexport_widget_filter.inc.php
@@ -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);