mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 09:23:28 +01:00
Add flag in calendar import definitions (CSV & iCal) to not import conflicting events
This commit is contained in:
parent
980b967071
commit
4bb16b2bec
@ -168,7 +168,13 @@ class calendar_ical extends calendar_boupdate
|
||||
var $log = false;
|
||||
var $logfile="/tmp/log-vcal";
|
||||
|
||||
|
||||
/**
|
||||
* Conflict callback
|
||||
* If set, conflict checking will be enabled, and the event as well as
|
||||
* conflicts are passed as parameters to this callback
|
||||
*/
|
||||
var $conflict_callback = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -1386,7 +1392,7 @@ class calendar_ical extends calendar_boupdate
|
||||
// to not loose him, as EGroupware knows events without owner/ORGANIZER as participant
|
||||
if (isset($event_info['stored_event']['participants'][$event['owner']]) && !isset($event['participants'][$event['owner']]))
|
||||
{
|
||||
$event['participant'][$event['owner']] = $event_info['stored_event']['participants'][$event['owner']];
|
||||
$event['participants'][$event['owner']] = $event_info['stored_event']['participants'][$event['owner']];
|
||||
}
|
||||
}
|
||||
else // common adjustments for new events
|
||||
@ -1765,6 +1771,41 @@ class calendar_ical extends calendar_boupdate
|
||||
return $updated_id === 0 ? 0 : $return_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent update function to handle conflict checking callback, if set
|
||||
*
|
||||
* @param array &$event event-array, on return some values might be changed due to set defaults
|
||||
* @param boolean $ignore_conflicts =false just ignore conflicts or do a conflict check and return the conflicting events.
|
||||
* Set to false if $this->conflict_callback is set
|
||||
* @param boolean $touch_modified =true NOT USED ANYMORE (was only used in old csv-import), modified&modifier is always updated!
|
||||
* @param boolean $ignore_acl =false should we ignore the acl
|
||||
* @param boolean $updateTS =true update the content history of the event
|
||||
* @param array &$messages=null messages about because of missing ACL removed participants or categories
|
||||
* @param boolean $skip_notification =false true: send NO notifications, default false = send them
|
||||
* @return mixed on success: int $cal_id > 0, on error or conflicts false.
|
||||
* Conflicts are passed to $this->conflict_callback
|
||||
*/
|
||||
public function update(&$event,$ignore_conflicts=false,$touch_modified=true,$ignore_acl=false,$updateTS=true,&$messages=null, $skip_notification=false)
|
||||
{
|
||||
if($this->conflict_callback !== null)
|
||||
{
|
||||
// calendar_ical overrides search(), which breaks conflict checking
|
||||
// so we make sure to use the original from parent
|
||||
static $bo;
|
||||
if(!$bo)
|
||||
{
|
||||
$bo = new calendar_boupdate();
|
||||
}
|
||||
$conflicts = $bo->conflicts($event);
|
||||
if(is_array($conflicts) && count($conflicts) > 0)
|
||||
{
|
||||
call_user_func_array($this->conflict_callback, array(&$event, &$conflicts));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return parent::update($event, $ignore_conflicts, $touch_modified, $ignore_acl, $updateTS, $messages, $skip_notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync alarms of current user: add alarms added on client and remove the ones removed
|
||||
*
|
||||
|
@ -97,7 +97,7 @@ class calendar_import_csv extends importexport_basic_import_csv {
|
||||
{
|
||||
$record->owner = $options['owner'];
|
||||
}
|
||||
|
||||
|
||||
// Handle errors in length or start/end date
|
||||
if($record->start > $record->end)
|
||||
{
|
||||
@ -148,7 +148,8 @@ class calendar_import_csv extends importexport_basic_import_csv {
|
||||
else
|
||||
{
|
||||
// Search app via link query
|
||||
$result = Link::query($resource['app'], $search, $options);
|
||||
$link_options = array();
|
||||
$result = Link::query($resource['app'], $search, $link_options);
|
||||
|
||||
if($result)
|
||||
{
|
||||
@ -294,13 +295,39 @@ class calendar_import_csv extends importexport_basic_import_csv {
|
||||
}
|
||||
if ( $this->dry_run ) {
|
||||
//print_r($_data);
|
||||
// User is interested in conflict checks, do so for dry run
|
||||
// Otherwise, conflicts are just ignored and imported anyway
|
||||
if($this->definition->plugin_options['skip_conflicts'])
|
||||
{
|
||||
$conflicts = $this->bo->conflicts($_data);
|
||||
if($conflicts)
|
||||
{
|
||||
$this->conflict_warning($record_num, $conflicts);
|
||||
$this->results['skipped']++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->results[$_action]++;
|
||||
return true;
|
||||
} else {
|
||||
$result = $this->bo->save( $_data, $this->is_admin);
|
||||
if(!$result) {
|
||||
$messages = null;
|
||||
$result = $this->bo->update( $_data,
|
||||
!$this->definition->plugin_options['skip_conflicts'],
|
||||
true, $this->is_admin, true, $messages,
|
||||
$this->definition->plugin_options['no_notification']
|
||||
);
|
||||
if(!$result)
|
||||
{
|
||||
$this->errors[$record_num] = lang('Unable to save');
|
||||
} else {
|
||||
}
|
||||
else if (is_array($result))
|
||||
{
|
||||
$this->conflict_warning($record_num, $result);
|
||||
$this->results['skipped']++;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->results[$_action]++;
|
||||
// This does nothing (yet?) but update the identifier
|
||||
$record->save($result);
|
||||
@ -312,6 +339,21 @@ class calendar_import_csv extends importexport_basic_import_csv {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a warning message about conflicting events
|
||||
*
|
||||
* @param int $record_num Current record index
|
||||
* @param Array $conflicts List of found conflicting events
|
||||
*/
|
||||
protected function conflict_warning($record_num, &$conflicts)
|
||||
{
|
||||
$this->warnings[$record_num] = lang('Conflicts') . ':';
|
||||
foreach($conflicts as $conflict)
|
||||
{
|
||||
$this->warnings[$record_num] .= "<br />\n" . Api\DateTime::to($conflict['start']) . "\t" . $conflict['title'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns translated name of plugin
|
||||
|
@ -94,9 +94,9 @@ class calendar_import_ical implements importexport_iface_import_plugin {
|
||||
protected $errors = array();
|
||||
|
||||
/**
|
||||
* List of actions, and how many times that action was taken
|
||||
*/
|
||||
protected $results = array();
|
||||
* List of actions, and how many times that action was taken
|
||||
*/
|
||||
protected $results = array();
|
||||
|
||||
/**
|
||||
* imports entries according to given definition object.
|
||||
@ -136,18 +136,44 @@ class calendar_import_ical implements importexport_iface_import_plugin {
|
||||
{
|
||||
$_definition->plugin_options['no_notification'] = true;
|
||||
}
|
||||
// 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']))
|
||||
{
|
||||
$this->errors[] = lang('Error: importing the iCal');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->results['imported'] = $calendar_ical->events_imported;
|
||||
$this->results['imported'] += $calendar_ical->events_imported;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
public function conflict_warning(&$event, &$conflicts)
|
||||
{
|
||||
$warning = EGroupware\Api\DateTime::to($event['start']) . ' ' . $event['title'] . ' ' . lang('Conflicts') . ':';
|
||||
foreach($conflicts as $conflict)
|
||||
{
|
||||
$warning .= "<br />\n" . EGroupware\Api\DateTime::to($conflict['start']) . "\t" . $conflict['title'];
|
||||
}
|
||||
$this->warnings[] = $warning;
|
||||
|
||||
// iCal will always count as imported, even if it wasn't
|
||||
$this->results['imported'] -= 1;
|
||||
|
||||
$this->results['skipped']++;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns translated name of plugin
|
||||
|
@ -15,7 +15,7 @@ use EGroupware\Api;
|
||||
class calendar_wizard_import_csv extends importexport_wizard_basic_import_csv
|
||||
{
|
||||
|
||||
/**
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
function __construct()
|
||||
@ -26,6 +26,9 @@ class calendar_wizard_import_csv extends importexport_wizard_basic_import_csv
|
||||
'wizard_step50' => lang('Manage mapping'),
|
||||
);
|
||||
|
||||
// Override conditions template to add conflict option
|
||||
$this->step_templates['wizard_step55'] = 'calendar.import.conditions';
|
||||
|
||||
// Field mapping
|
||||
$tracking = new calendar_tracking();
|
||||
$this->mapping_fields = array('id' => 'Calendar ID') + $tracking->field2label;
|
||||
@ -67,6 +70,11 @@ class calendar_wizard_import_csv extends importexport_wizard_basic_import_csv
|
||||
$sel_options['string'] = array(
|
||||
'id' => 'Calendar ID'
|
||||
);
|
||||
|
||||
if(!$content['skip_conflicts'] && $content['plugin_options']['skip_conflicts'])
|
||||
{
|
||||
$content['skip_conflicts'] = $content['plugin_options']['skip_conflicts'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
84
calendar/inc/class.calendar_wizard_import_ical.inc.php
Normal file
84
calendar/inc/class.calendar_wizard_import_ical.inc.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware - Wizard for user CSV import
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package calendar
|
||||
* @subpackage importexport
|
||||
* @link http://www.egroupware.org
|
||||
* @author Nathan Gray
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
use EGroupware\Api;
|
||||
|
||||
class calendar_wizard_import_ical
|
||||
{
|
||||
/**
|
||||
* List of steps. Key is the function, value is the translated title.
|
||||
*/
|
||||
public $steps;
|
||||
|
||||
/**
|
||||
* 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'
|
||||
);
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->steps = array(
|
||||
'wizard_step55' => lang('Edit conditions'),
|
||||
);
|
||||
}
|
||||
|
||||
function wizard_step50(&$content, &$sel_options, &$readonlys, &$preserv)
|
||||
{
|
||||
$result = parent::wizard_step50($content, $sel_options, $readonlys, $preserv);
|
||||
$content['msg'] .= "\n*" ;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Conditions
|
||||
function wizard_step55(&$content, &$sel_options, &$readonlys, &$preserv)
|
||||
{
|
||||
// return from step55
|
||||
if ($content['step'] == 'wizard_step55')
|
||||
{
|
||||
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_step55($content,$sel_options,$readonlys,$preserv);
|
||||
}
|
||||
}
|
||||
// init step30
|
||||
else
|
||||
{
|
||||
$content['text'] = $this->steps['wizard_step55'];
|
||||
$content['step'] = 'wizard_step55';
|
||||
if(!$content['skip_conflicts'] && array_key_exists('skip_conflicts', $content['plugin_options']))
|
||||
{
|
||||
$content['skip_conflicts'] = $content['plugin_options']['skip_conflicts'];
|
||||
}
|
||||
$preserv = $content;
|
||||
unset ($preserv['button']);
|
||||
|
||||
// No real conditions, but we share a template
|
||||
$content['no_conditions'] = true;
|
||||
|
||||
return $this->step_templates[$content['step']];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
12
calendar/templates/default/import.conditions.xet
Normal file
12
calendar/templates/default/import.conditions.xet
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE overlay PUBLIC "-//Stylite AG//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="calendar.import.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>
|
||||
</template>
|
||||
</overlay>
|
Loading…
Reference in New Issue
Block a user