forked from extern/egroupware
- modified etag/optimistic locking, to always increment the etag, was before only via the GUI
- replaced own "locks" via egw_cal.cal_edit_user/time with the new egw_vfs::lock() methods
This commit is contained in:
parent
641817662b
commit
5d50d41004
@ -51,7 +51,7 @@ class bocalupdate extends bocal
|
||||
* @var mixed
|
||||
*/
|
||||
var $debug;
|
||||
|
||||
|
||||
/**
|
||||
* @var string/boolean $log_file filename to enable the login or false for no update-logging
|
||||
*/
|
||||
@ -65,12 +65,12 @@ class bocalupdate extends bocal
|
||||
if ($this->debug > 0) $this->debug_message('bocalupdate::bocalupdate() started',True);
|
||||
|
||||
$this->bocal(); // calling the parent constructor
|
||||
|
||||
|
||||
if ($this->debug > 0) $this->debug_message('bocalupdate::bocalupdate() finished',True);
|
||||
}
|
||||
|
||||
/**
|
||||
* updates or creates an event, it (optionaly) checks for conflicts and sends the necessary notifications
|
||||
* updates or creates an event, it (optionaly) checks for conflicts and sends the necessary notifications
|
||||
*
|
||||
* @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
|
||||
@ -81,6 +81,7 @@ class bocalupdate extends bocal
|
||||
*/
|
||||
function update(&$event,$ignore_conflicts=false,$touch_modified=true,$ignore_acl=false)
|
||||
{
|
||||
//error_log(__METHOD__."(".str_replace(array("\n",' '),'',print_r($event,true)).",$ignore_conflicts,$touch_modified,$ignore_acl)");
|
||||
if ($this->debug > 1 || $this->debug == 'update')
|
||||
{
|
||||
$this->debug_message('bocalupdate::update(%1,ignore_conflict=%2,touch_modified=%3,ignore_acl=%4)',
|
||||
@ -90,7 +91,7 @@ class bocalupdate extends bocal
|
||||
// - new events need start, end and title
|
||||
// - updated events cant set start, end or title to empty
|
||||
if (!$event['id'] && (!$event['start'] || !$event['end'] || !$event['title']) ||
|
||||
$event['id'] && (isset($event['start']) && !$event['start'] || isset($event['end']) && !$event['end'] ||
|
||||
$event['id'] && (isset($event['start']) && !$event['start'] || isset($event['end']) && !$event['end'] ||
|
||||
isset($event['title']) && !$event['title']))
|
||||
{
|
||||
return false;
|
||||
@ -104,7 +105,7 @@ class bocalupdate extends bocal
|
||||
if (!$event['id'] && (!is_array($event['participants']) || !count($event['participants'])))
|
||||
{
|
||||
$event['participants'][$event['owner']] = 'U';
|
||||
}
|
||||
}
|
||||
// set the status of the current user to 'A' = accepted
|
||||
if (isset($event['participants'][$this->user]) && $event['participants'][$this->user] != 'A')
|
||||
{
|
||||
@ -113,7 +114,7 @@ class bocalupdate extends bocal
|
||||
}
|
||||
// check if user has the permission to update / create the event
|
||||
if (!$ignore_acl && ($event['id'] && !$this->check_perms(EGW_ACL_EDIT,$event['id']) ||
|
||||
!$event['id'] && !$this->check_perms(EGW_ACL_EDIT,0,$event['owner'])) &&
|
||||
!$event['id'] && !$this->check_perms(EGW_ACL_EDIT,0,$event['owner'])) &&
|
||||
!$this->check_perms(EGW_ACL_ADD,0,$event['owner']))
|
||||
{
|
||||
// Just update the status, if the user is in the event already
|
||||
@ -147,7 +148,7 @@ class bocalupdate extends bocal
|
||||
foreach($event['participants'] as $uid => $status)
|
||||
{
|
||||
if ($status[0] == 'R') continue; // ignore rejected participants
|
||||
|
||||
|
||||
if ($uid < 0) // group, check it's members too
|
||||
{
|
||||
$users += $GLOBALS['egw']->accounts->members($uid,true);
|
||||
@ -187,7 +188,7 @@ class bocalupdate extends bocal
|
||||
$common_parts = array_intersect($users,array_keys($overlap['participants']));
|
||||
foreach($common_parts as $n => $uid)
|
||||
{
|
||||
if ($overlap['participants'][$uid]{0} == 'R')
|
||||
if ($overlap['participants'][$uid]{0} == 'R')
|
||||
{
|
||||
unset($common_parts[$uid]);
|
||||
continue;
|
||||
@ -231,7 +232,7 @@ class bocalupdate extends bocal
|
||||
}
|
||||
}
|
||||
unset($possible_quantity_conflicts);
|
||||
|
||||
|
||||
if (count($conflicts))
|
||||
{
|
||||
foreach($conflicts as $key => $conflict)
|
||||
@ -252,7 +253,7 @@ class bocalupdate extends bocal
|
||||
$this->debug_message('bocalupdate::update() %1 conflicts found %2',false,count($conflicts),$conflicts);
|
||||
}
|
||||
return $conflicts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save the event to the database
|
||||
@ -304,11 +305,11 @@ class bocalupdate extends bocal
|
||||
*
|
||||
* @param array $new_event the updated event
|
||||
* @param array $old_event the event before the update
|
||||
*/
|
||||
*/
|
||||
function check4update($new_event,$old_event)
|
||||
{
|
||||
$modified = $added = $deleted = array();
|
||||
|
||||
|
||||
//echo "<p>bocalupdate::check4update() new participants = ".print_r($new_event['participants'],true).", old participants =".print_r($old_event['participants'],true)."</p>\n";
|
||||
|
||||
// Find modified and deleted participants ...
|
||||
@ -509,7 +510,7 @@ class bocalupdate extends bocal
|
||||
$notify_msg = $this->cal_prefs['notifyAdded']; // use a default
|
||||
}
|
||||
$details = $this->_get_event_details($event,$action,$event_arr,$disinvited);
|
||||
|
||||
|
||||
// add all group-members to the notification, unless they are already participants
|
||||
foreach($to_notify as $userid => $statusid)
|
||||
{
|
||||
@ -532,7 +533,7 @@ class bocalupdate extends bocal
|
||||
{
|
||||
$res_info = $this->resource_info($userid);
|
||||
$userid = $res_info['responsible'];
|
||||
if (!isset($userid)) continue;
|
||||
if (!isset($userid)) continue;
|
||||
}
|
||||
|
||||
if ($statusid == 'R' || $GLOBALS['egw']->accounts->get_type($userid) == 'g')
|
||||
@ -550,11 +551,11 @@ class bocalupdate extends bocal
|
||||
}
|
||||
$GLOBALS['egw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']);
|
||||
$details['to-fullname'] = $GLOBALS['egw']->common->display_fullname('',$details['to-firstname'],$details['to-lastname']);
|
||||
|
||||
|
||||
$GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'] = $part_prefs['common']['tz_offset'];
|
||||
$GLOBALS['egw_info']['user']['preferences']['common']['timeformat'] = $part_prefs['common']['timeformat'];
|
||||
$GLOBALS['egw_info']['user']['preferences']['common']['dateformat'] = $part_prefs['common']['dateformat'];
|
||||
|
||||
|
||||
$GLOBALS['egw']->datetime->tz_offset = 3600 * (int) $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
|
||||
|
||||
// event is in user-time of current user, now we need to calculate the tz-difference to the notified user and take it into account
|
||||
@ -587,7 +588,7 @@ class bocalupdate extends bocal
|
||||
|
||||
case 'ical':
|
||||
$ics = ExecMethod2('calendar.boical.exportVCal',$event['id'],'2.0',$method);
|
||||
if ($method == 'REQUEST')
|
||||
if ($method == 'REQUEST')
|
||||
{
|
||||
$attachment = array( 'string' => $ics,
|
||||
'filename' => 'cal.ics',
|
||||
@ -638,7 +639,7 @@ class bocalupdate extends bocal
|
||||
* Function called via async service, when an alarm is to be send
|
||||
*
|
||||
* @param array $alarm array with keys owner, cal_id, all
|
||||
* @return boolean
|
||||
* @return boolean
|
||||
*/
|
||||
function send_alarm($alarm)
|
||||
{
|
||||
@ -684,6 +685,7 @@ class bocalupdate extends bocal
|
||||
*/
|
||||
function save($event)
|
||||
{
|
||||
//error_log(__METHOD__."(".str_replace(array("\n",' '),'',print_r($event,true)).",$etag)");
|
||||
// check if user has the permission to update / create the event
|
||||
if ($event['id'] && !$this->check_perms(EGW_ACL_EDIT,$event['id']) ||
|
||||
!$event['id'] && !$this->check_perms(EGW_ACL_EDIT,0,$event['owner']) &&
|
||||
@ -702,9 +704,6 @@ class bocalupdate extends bocal
|
||||
// we convert here from user-time to timestamps in server-time!
|
||||
if (isset($event[$ts])) $event[$ts] = $event[$ts] ? $this->date2ts($event[$ts],true) : 0;
|
||||
}
|
||||
// Lock realized with a counter, that is checked and incremented as we save the entry
|
||||
$check_etag = ($event['etag'] ? $event['etag']:0);
|
||||
|
||||
// same with the recur exceptions
|
||||
if (isset($event['recur_exception']) && is_array($event['recur_exception']))
|
||||
{
|
||||
@ -721,7 +720,7 @@ class bocalupdate extends bocal
|
||||
$event['alarm'][$id]['time'] = $this->date2ts($alarm['time'],true);
|
||||
}
|
||||
}
|
||||
if (($cal_id = $this->so->save($event,$set_recurrences,NULL,$check_etag)) && $set_recurrences && $event['recur_type'] != MCAL_RECUR_NONE)
|
||||
if (($cal_id = $this->so->save($event,$set_recurrences,NULL,$event['etag'])) && $set_recurrences && $event['recur_type'] != MCAL_RECUR_NONE)
|
||||
{
|
||||
$save_event['id'] = $cal_id;
|
||||
$this->set_recurrences($save_event);
|
||||
@ -730,10 +729,10 @@ class bocalupdate extends bocal
|
||||
|
||||
return $cal_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the current user has the necessary ACL rights to change the status of $uid
|
||||
*
|
||||
*
|
||||
* For contacts we use edit rights of the owner of the event (aka. edit rights of the event).
|
||||
*
|
||||
* @param int/string $uid account_id or 1-char type-identifer plus id (eg. c15 for addressbook entry #15)
|
||||
@ -804,19 +803,19 @@ class bocalupdate extends bocal
|
||||
function delete($cal_id,$recur_date=0)
|
||||
{
|
||||
$event = $this->read($cal_id,$recur_date);
|
||||
|
||||
|
||||
if (!($event = $this->read($cal_id,$recur_date)) ||
|
||||
!$this->check_perms(EGW_ACL_DELETE,$event))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$this->send_update(MSG_DELETED,$event['participants'],$event);
|
||||
|
||||
|
||||
if (!$recur_date || $event['recur_type'] == MCAL_RECUR_NONE)
|
||||
{
|
||||
$this->so->delete($cal_id);
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,'delete',time());
|
||||
|
||||
|
||||
// delete all links to the event
|
||||
egw_link::unlink(0,'calendar',$cal_id);
|
||||
}
|
||||
@ -858,7 +857,7 @@ class bocalupdate extends bocal
|
||||
$link;
|
||||
}
|
||||
$event_arr['link']['data'] = $details['link'] = $link;
|
||||
|
||||
|
||||
/* this is needed for notification-app
|
||||
* notification-app creates the link individual for
|
||||
* every user, so we must provide a neutral link-style
|
||||
@ -872,7 +871,7 @@ class bocalupdate extends bocal
|
||||
);
|
||||
$link_arr['popup'] = '750x400';
|
||||
$details['link_arr'] = $link_arr;
|
||||
|
||||
|
||||
$dis = array();
|
||||
foreach($disinvited as $uid)
|
||||
{
|
||||
@ -1102,18 +1101,4 @@ class bocalupdate extends bocal
|
||||
|
||||
return $cat_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* updates the edit user information for timelocking an event
|
||||
*
|
||||
* @param array &$event2update event-array, on return some values might be changed due to set defaults
|
||||
* this is a wrapper for the socal function
|
||||
* cal_edit_time is set to current timestamp
|
||||
* @return the returnvalue of so->save_edit_user (0 (someone else modified the entry), true (saved) or false (could not save)))
|
||||
*/
|
||||
function update_edit_user(&$event2update)
|
||||
{
|
||||
$event2update['edit_time']=$this->now_su;
|
||||
return $this->so->save_edit_user($event2update);
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class socal
|
||||
|
||||
/**
|
||||
* internal copy of the global db-object
|
||||
*
|
||||
*
|
||||
* @var egw_db
|
||||
*/
|
||||
var $db;
|
||||
@ -464,12 +464,13 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
* @param array $event
|
||||
* @param boolean &$set_recurrences on return: true if the recurrences need to be written, false otherwise
|
||||
* @param int $change_since=0 time from which on the repetitions should be changed, default 0=all
|
||||
* @return boolean/int false on error, cal_id otherwise
|
||||
* @return int $check_etag check etag from GUI, if there is any Change since the last save SB:Lock for etag
|
||||
* @param int &$etag etag=null etag to check or null, on return new etag
|
||||
* @return boolean/int false on error, 0 if etag does not match, cal_id otherwise
|
||||
*/
|
||||
function save($event,&$set_recurrences,$change_since=0,$check_modified=0)
|
||||
function save($event,&$set_recurrences,$change_since=0,&$etag=null)
|
||||
{
|
||||
//echo "<p>socal::save(,$change_since) event="; _debug_array($event);
|
||||
error_log(__METHOD__."(".str_replace(array("\n",' '),'',print_r($event,true)).",$set_recurrences,$change_since,$etag)");
|
||||
|
||||
$cal_id = (int) $event['id'];
|
||||
unset($event['id']);
|
||||
@ -486,36 +487,21 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
}
|
||||
if (is_array($event['cal_category'])) $event['cal_category'] = implode(',',$event['cal_category']);
|
||||
|
||||
// while saving handle the etag as condition for the update, to check if an entry was saved before this action occured
|
||||
$check_etag = ($check_modified ? $check_modified : $event['cal_etag']);
|
||||
if ($cal_id && $check_etag && $check_modified)
|
||||
{
|
||||
//$event2update[]= 'cal_etag=cal_etag+1';
|
||||
$event2update['cal_etag']= $event['cal_etag']=$check_etag+1;
|
||||
$event2update['cal_edit_user']= $event['cal_edit_user']=NULL;
|
||||
$event2update['cal_edit_time']= $event['cal_edit_time']=NULL;
|
||||
// cal_etag will be set on first save (if not set)
|
||||
$where = array('cal_id' => $cal_id,'(cal_etag is NULL or cal_etag='.$check_etag.')');
|
||||
#if ($check_etag) $where['cal_etag'] = $check_etag;
|
||||
if (!$this->db->update($this->cal_table,$event2update,$where,__LINE__,__FILE__,'calendar'))
|
||||
{
|
||||
//error_log("### socal::write(".print_r($event,true).") where=".print_r($where,true)." returning false");
|
||||
return false; // Error
|
||||
}
|
||||
//echo $this->db->affected_rows()."##";
|
||||
if ($check_etag && $this->db->affected_rows() < 1)
|
||||
{
|
||||
//error_log("### socal::write(".print_r($event,true).") where=".print_r($where,true)." returning 0 (nothing updated, eg. condition not met)");
|
||||
return 0; // someone else updated the modtime or deleted the entry
|
||||
}
|
||||
|
||||
} else {
|
||||
$event['cal_etag']=($check_etag?$check_etag:1);
|
||||
}
|
||||
|
||||
if ($cal_id)
|
||||
{
|
||||
$this->db->update($this->cal_table,$event,array('cal_id' => $cal_id),__LINE__,__FILE__,'calendar');
|
||||
$where = array('cal_id' => $cal_id);
|
||||
if (!is_null($etag)) $where['cal_etag'] = $etag;
|
||||
|
||||
unset($event['cal_etag']);
|
||||
$event[] = 'cal_etag=cal_etag+1'; // always update the etag, even if none given to check
|
||||
|
||||
$this->db->update($this->cal_table,$event,$where,__LINE__,__FILE__,'calendar');
|
||||
|
||||
if (!is_null($etag) && $this->db->affected_rows() < 1)
|
||||
{
|
||||
return 0; // wrong etag, someone else updated the entry
|
||||
}
|
||||
if (!is_null($etag)) ++$etag;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -534,6 +520,7 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
$event['cal_uid'] = $GLOBALS['egw']->common->generate_uid('calendar',$cal_id);
|
||||
$this->db->update($this->cal_table,array('cal_uid' => $event['cal_uid']),array('cal_id' => $cal_id),__LINE__,__FILE__,'calendar');
|
||||
}
|
||||
$etag = 0;
|
||||
// new events need to have at least one participant, default to the owner
|
||||
if (!isset($event['cal_participants']))
|
||||
{
|
||||
@ -635,6 +622,10 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
$this->save_alarm($cal_id,$alarm);
|
||||
}
|
||||
}
|
||||
if (is_null($etag))
|
||||
{
|
||||
$etag = $this->db->select($this->cal_table,'cal_etag',array('cal_id' => $cal_id),__LINE__,__FILE__,false,'','calendar')->fetchSingle();
|
||||
}
|
||||
return $cal_id;
|
||||
}
|
||||
|
||||
@ -1104,45 +1095,4 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
),__LINE__,__FILE__,'calendar');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save actually User, who is working on the Calenar Data if there is no user set or the timestamp is "expired"
|
||||
*
|
||||
* @param array $event2update
|
||||
*
|
||||
* @return (0 (someone else modified the entry), true (saved) or false (could not save)))
|
||||
*/
|
||||
function save_edit_user($event2update)
|
||||
{
|
||||
$cal_id = (int) $event2update['id'];
|
||||
//unset($event2update['id']);
|
||||
|
||||
// add colum prefix 'cal_' if there's not already a 'recur_' prefix
|
||||
foreach($event2update as $col => $val)
|
||||
{
|
||||
if ($col{0} != '#' && substr($col,0,6) != 'recur_' && $col != 'alarm')
|
||||
{
|
||||
$event2update['cal_'.$col] = $val;
|
||||
unset($event2update[$col]);
|
||||
}
|
||||
}
|
||||
if ($cal_id && $event2update['cal_edit_user'] && $event2update['cal_edit_time'])
|
||||
{
|
||||
$locktime = ($GLOBALS['egw_info']['server']['Lock_Time_Calender'] ? $GLOBALS['egw_info']['server']['Lock_Time_Calender'] : 1);
|
||||
$lockborder=$event2update['cal_edit_time']-$locktime;
|
||||
$where = array('cal_id' => $cal_id,'(cal_edit_user is NULL or cal_edit_time<'.$lockborder.')');
|
||||
if (!$this->db->update($this->cal_table,$event2update,$where,__LINE__,__FILE__,'calendar'))
|
||||
{
|
||||
//error_log("### socal::write(".print_r($event,true).") where=".print_r($where,true)." returning false");
|
||||
return false; // Error
|
||||
}
|
||||
//echo $this->db->affected_rows()."##";
|
||||
if ($this->db->affected_rows() < 1)
|
||||
{
|
||||
//error_log("### socal::write(".print_r($event,true).") where=".print_r($where,true)." returning 0 (nothing updated, eg. condition not met)");
|
||||
return 0; // someone else updated the modtime or deleted the entry
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,21 +38,21 @@ class uiforms extends uical
|
||||
* @var bolink
|
||||
*/
|
||||
var $link;
|
||||
|
||||
|
||||
/**
|
||||
* Standard durations used in edit and freetime search
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $durations = array();
|
||||
|
||||
|
||||
/**
|
||||
* Name of the tabs used in edit
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $tabs = 'general|description|participants|recurrence|custom|links|alarms';
|
||||
|
||||
|
||||
/**
|
||||
* default timelock for entries, that are opened by another user
|
||||
*
|
||||
@ -66,20 +66,20 @@ class uiforms extends uical
|
||||
function uiforms()
|
||||
{
|
||||
$this->uical(true); // call the parent's constructor
|
||||
|
||||
|
||||
$this->link =& $this->bo->link;
|
||||
|
||||
|
||||
for ($n=15; $n <= 8*60; $n+=($n < 60 ? 15 : ($n < 240 ? 30 : 60)))
|
||||
{
|
||||
$this->durations[$n*60] = sprintf('%d:%02d',$n/60,$n%60);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a default event (adding a new event) by evaluating certain _GET vars
|
||||
*
|
||||
* @return array event-array
|
||||
*/
|
||||
*/
|
||||
function &default_add_event()
|
||||
{
|
||||
$extra_participants = $_GET['participants'] ? explode(',',$_GET['participants']) : array();
|
||||
@ -93,7 +93,7 @@ class uiforms extends uical
|
||||
{
|
||||
$owner = $this->owner;
|
||||
}
|
||||
if (!$owner || !is_numeric($owner) || $GLOBALS['egw']->accounts->get_type($owner) != 'u' ||
|
||||
if (!$owner || !is_numeric($owner) || $GLOBALS['egw']->accounts->get_type($owner) != 'u' ||
|
||||
!$this->bo->check_perms(EGW_ACL_ADD,0,$owner))
|
||||
{
|
||||
if ($owner) // make an owner who is no user or we have no add-rights a participant
|
||||
@ -113,7 +113,7 @@ class uiforms extends uical
|
||||
'minute' => (int) $_GET['minute'],
|
||||
));
|
||||
//echo "<p>_GET[date]=$_GET[date], _GET[hour]=$_GET[hour], _GET[minute]=$_GET[minute], this->date=$this->date ==> start=$start=".date('Y-m-d H:i',$start)."</p>\n";
|
||||
|
||||
|
||||
$participant_types['u'] = $participant_types = $participants = array();
|
||||
foreach($extra_participants as $uid)
|
||||
{
|
||||
@ -130,7 +130,7 @@ class uiforms extends uical
|
||||
$participants[$uid] = $participant_types[$uid{0}][$id] = ($res_data['new_status'] ? ExecMethod($res_data['new_status'],$id) : 'U').
|
||||
((int) $quantity > 1 ? (int)$quantity : '');
|
||||
// if new_status == 'x', resource is not bookable
|
||||
if(strpos($participant_types[$uid{0}][$id],'x') !== false)
|
||||
if(strpos($participant_types[$uid{0}][$id],'x') !== false)
|
||||
{
|
||||
unset($participant_types[$uid{0}][$id]);
|
||||
unset($participants[$uid]);
|
||||
@ -148,7 +148,7 @@ class uiforms extends uical
|
||||
'alarm' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the edited event and evtl. call edit to redisplay it
|
||||
*
|
||||
@ -182,7 +182,7 @@ class uiforms extends uical
|
||||
{
|
||||
list($id) = each($content['alarm']['delete_alarm']);
|
||||
//echo "delete alarm $id"; _debug_array($content['alarm']['delete_alarm']);
|
||||
|
||||
|
||||
if ($content['id'])
|
||||
{
|
||||
if ($this->bo->delete_alarm($id))
|
||||
@ -192,7 +192,7 @@ class uiforms extends uical
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg = lang('Permission denied');
|
||||
$msg = lang('Permission denied');
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -256,7 +256,7 @@ class uiforms extends uical
|
||||
{
|
||||
$status = isset($this->bo->resources[$type]['new_status']) ? ExecMethod($this->bo->resources[$type]['new_status'],$id) : 'U';
|
||||
$quantity = $content['participants']['quantity'] ? $content['participants']['quantity'] : 1;
|
||||
if ($uid) $event['participants'][$uid] = $event['participant_types'][$type][$id] =
|
||||
if ($uid) $event['participants'][$uid] = $event['participant_types'][$type][$id] =
|
||||
$status.((int) $quantity > 1 ? (int)$quantity : '');
|
||||
break;
|
||||
}
|
||||
@ -264,7 +264,7 @@ class uiforms extends uical
|
||||
case 'account':
|
||||
foreach(is_array($data) ? $data : explode(',',$data) as $uid)
|
||||
{
|
||||
if ($uid) $event['participants'][$uid] = $event['participant_types']['u'][$uid] =
|
||||
if ($uid) $event['participants'][$uid] = $event['participant_types']['u'][$uid] =
|
||||
$uid == $this->bo->user ? 'A' : 'U';
|
||||
}
|
||||
break;
|
||||
@ -282,12 +282,12 @@ class uiforms extends uical
|
||||
{
|
||||
if (is_numeric($uid))
|
||||
{
|
||||
$id = $uid;
|
||||
$id = $uid;
|
||||
$type = 'u';
|
||||
}
|
||||
else
|
||||
{
|
||||
$id = substr($uid,1);
|
||||
$id = substr($uid,1);
|
||||
$type = $uid{0};
|
||||
}
|
||||
if ($data['old_status'] != $status)
|
||||
@ -307,7 +307,7 @@ class uiforms extends uical
|
||||
}
|
||||
if ($uid && $status != 'G')
|
||||
{
|
||||
$event['participants'][$uid] = $event['participant_types'][$type][$id] =
|
||||
$event['participants'][$uid] = $event['participant_types'][$type][$id] =
|
||||
$status.((int) $quantity > 1 ? (int)$quantity : '');
|
||||
}
|
||||
}
|
||||
@ -344,7 +344,7 @@ class uiforms extends uical
|
||||
$msg = lang('Event copied - the copy can now be edited');
|
||||
$event['title'] = lang('Copy of:').' '.$event['title'];
|
||||
break;
|
||||
|
||||
|
||||
case 'ignore':
|
||||
$ignore_conflicts = true;
|
||||
$button = $event['button_was']; // save or apply
|
||||
@ -353,15 +353,15 @@ class uiforms extends uical
|
||||
case 'mail':
|
||||
case 'save':
|
||||
case 'apply':
|
||||
if ($event['id'] && !$this->bo->check_perms(EGW_ACL_EDIT,$event))
|
||||
{
|
||||
if ($event['id'] && !$this->bo->check_perms(EGW_ACL_EDIT,$event))
|
||||
{
|
||||
if ($button == 'mail') // just mail without edit-rights is ok
|
||||
{
|
||||
$js = $this->custom_mail($event,false);
|
||||
break;
|
||||
}
|
||||
$msg = lang('Permission denied');
|
||||
break;
|
||||
$msg = lang('Permission denied');
|
||||
break;
|
||||
}
|
||||
if ($event['start'] > $event['end'])
|
||||
{
|
||||
@ -409,7 +409,7 @@ class uiforms extends uical
|
||||
$event['button_was'] = $button; // remember for ignore
|
||||
return $this->conflicts($event,$conflicts,$preserv);
|
||||
}
|
||||
elseif ($conflicts ===0)
|
||||
elseif ($conflicts ===0)
|
||||
{
|
||||
$msg .= ($msg ? ', ' : '') .lang('Error: the entry has been updated since you opened it for editing!').'<br />'.
|
||||
lang('Copy your changes to the clipboard, %1reload the entry%2 and merge them.','<a href="'.
|
||||
@ -419,14 +419,14 @@ class uiforms extends uical
|
||||
'referer' => $referer,
|
||||
))).'">','</a>');
|
||||
$noerror=false;
|
||||
|
||||
|
||||
}
|
||||
elseif ($conflicts>0)
|
||||
elseif ($conflicts>0)
|
||||
{
|
||||
$msg .= ($msg ? ', ' : '') . lang('Event saved');
|
||||
|
||||
// writing links for new entry, existing ones are handled by the widget itself
|
||||
if (!$content['id'] && is_array($content['link_to']['to_id']))
|
||||
if (!$content['id'] && is_array($content['link_to']['to_id']))
|
||||
{
|
||||
egw_link::link('calendar',$event['id'],$content['link_to']['to_id']);
|
||||
}
|
||||
@ -445,7 +445,7 @@ class uiforms extends uical
|
||||
$msg = lang('Error: saving the event !!!');
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'cancel':
|
||||
if($content['cancel_needs_refresh'])
|
||||
{
|
||||
@ -466,12 +466,12 @@ class uiforms extends uical
|
||||
))).'\';';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'freetime':
|
||||
// the "click" has to be in onload, to make sure the button is already created
|
||||
$GLOBALS['egw']->js->set_onload("document.getElementsByName('exec[freetime]')[0].click();");
|
||||
break;
|
||||
|
||||
|
||||
case 'add_alarm':
|
||||
if ($this->bo->check_perms(EGW_ACL_EDIT,!$content['new_alarm']['owner'] ? $event : 0,$content['new_alarm']['owner']))
|
||||
{
|
||||
@ -492,7 +492,7 @@ class uiforms extends uical
|
||||
{
|
||||
$alarm['id'] = $alarm_id;
|
||||
$event['alarm'][$alarm_id] = $alarm;
|
||||
|
||||
|
||||
$msg = lang('Alarm added');
|
||||
}
|
||||
else
|
||||
@ -514,6 +514,10 @@ class uiforms extends uical
|
||||
}
|
||||
if (in_array($button,array('cancel','save','delete')) && $noerror)
|
||||
{
|
||||
if ($content['lock_token']) // remove an existing lock
|
||||
{
|
||||
egw_vfs::unlock(egw_vfs::app_entry_lock_path('calendar',$content['id']),$content['lock_token'],false);
|
||||
}
|
||||
if ($content['no_popup'])
|
||||
{
|
||||
$GLOBALS['egw']->redirect_link('/index.php',array(
|
||||
@ -527,10 +531,10 @@ class uiforms extends uical
|
||||
}
|
||||
return $this->edit($event,$preserv,$msg,$js,$event['id'] ? $event['id'] : $content['link_to']['to_id']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an exception from the clicked event
|
||||
*
|
||||
*
|
||||
* It's not stored to the DB unless the user saves it!
|
||||
*
|
||||
* @param array &$event
|
||||
@ -562,13 +566,13 @@ class uiforms extends uical
|
||||
foreach($event['participants'] as $uid => $status)
|
||||
{
|
||||
if ($status == 'R' || $uid == $this->user) continue;
|
||||
|
||||
|
||||
if (is_numeric($uid) && $GLOBALS['egw']->accounts->get_type($uid) == 'u')
|
||||
{
|
||||
if (!($email = $GLOBALS['egw']->accounts->id2name($uid,'account_email'))) continue;
|
||||
|
||||
$GLOBALS['egw']->accounts->get_account_name($uid,$lid,$firstname,$lastname);
|
||||
|
||||
|
||||
$to[] = $firstname.' '.$lastname.' <'.$email.'>';
|
||||
}
|
||||
elseif ($uid < 0)
|
||||
@ -578,7 +582,7 @@ class uiforms extends uical
|
||||
if (!($email = $GLOBALS['egw']->accounts->id2name($uid,'account_email'))) continue;
|
||||
|
||||
$GLOBALS['egw']->accounts->get_account_name($uid,$lid,$firstname,$lastname);
|
||||
|
||||
|
||||
$to[] = $firstname.' '.$lastname.' <'.$email.'>';
|
||||
}
|
||||
}
|
||||
@ -657,7 +661,7 @@ class uiforms extends uical
|
||||
|
||||
if (!$cal_id || $cal_id && !($event = $this->bo->read($cal_id,$_GET['date'])) || !$this->bo->check_perms(EGW_ACL_READ,$event))
|
||||
{
|
||||
if ($cal_id)
|
||||
if ($cal_id)
|
||||
{
|
||||
if (!$preserv['no_popup'])
|
||||
{
|
||||
@ -702,6 +706,39 @@ class uiforms extends uical
|
||||
}
|
||||
$view = $preserv['view'] = $preserv['view'] || $event['id'] && !$this->bo->check_perms(EGW_ACL_EDIT,$event);
|
||||
//echo "view=$view, event="; _debug_array($event);
|
||||
|
||||
// shared locking of entries to edit
|
||||
if (!$view && ($locktime = $GLOBALS['egw_info']['server']['Lock_Time_Calender']) && $event['id'])
|
||||
{
|
||||
$lock_path = egw_vfs::app_entry_lock_path('calendar',$event['id']);
|
||||
$lock_owner = 'mailto:'.$GLOBALS['egw_info']['user']['account_email'];
|
||||
|
||||
if (($preserv['lock_token'] = $content['lock_token'])) // already locked --> refresh the lock
|
||||
{
|
||||
egw_vfs::lock($lock_path,$preserv['lock_token'],$locktime,$lock_owner,$scope='shared',$type='write',true,false);
|
||||
}
|
||||
if (($lock = egw_vfs::checkLock($lock_path)) && $lock['owner'] != $lock_owner)
|
||||
{
|
||||
$msg .= ' '.lang('This entry is currently opened by %1!',
|
||||
(($lock_uid = $GLOBALS['egw']->accounts->name2id(substr($lock['owner'],7),'account_email')) ?
|
||||
$GLOBALS['egw']->common->grab_owner_name($lock_uid) : $lock['owner']));
|
||||
}
|
||||
elseif($lock)
|
||||
{
|
||||
$preserv['lock_token'] = $lock['token'];
|
||||
}
|
||||
elseif(egw_vfs::lock($lock_path,$preserv['lock_token'],$locktime,$lock_owner,$scope='shared',$type='write',false,false))
|
||||
{
|
||||
// install ajax handler to unlock the entry again, if the window get's closed by the user
|
||||
$GLOBALS['egw']->js->set_onunload("xajax_doXMLHTTP('calendar.uiforms.ajax_unlock',$event[id],'$preserv[lock_token]');");
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg .= ' '.lang("Can't aquire lock!"); // eg. an exclusive lock via CalDAV ...
|
||||
$view = true;
|
||||
}
|
||||
//echo "<p>lock_path=$lock_path, lock_owner=$lock_owner, lock_token=$preserv[lock_token], msg=$msg</p>\n";
|
||||
}
|
||||
$content = array_merge($event,array(
|
||||
'link_to' => array(
|
||||
'to_id' => $link_to_id,
|
||||
@ -710,6 +747,7 @@ class uiforms extends uical
|
||||
'edit_single' => $preserv['edit_single'], // need to be in content too, as it is used in the template
|
||||
$this->tabs => $preserv[$this->tabs],
|
||||
'view' => $view,
|
||||
'msg' => $msg,
|
||||
));
|
||||
$content['duration'] = $content['end'] - $content['start'];
|
||||
if (isset($this->durations[$content['duration']])) $content['end'] = '';
|
||||
@ -736,9 +774,9 @@ class uiforms extends uical
|
||||
$readonlys[$row.'[quantity]'] = $type == 'u' || !isset($this->bo->resources[$type]['max_quantity']);
|
||||
$readonlys[$row.'[status]'] = $readonlys[$row.'[status_recurrence]'] = !$this->bo->check_status_perms($uid,$event);
|
||||
$readonlys["delete[$uid]"] = !$this->bo->check_perms(EGW_ACL_EDIT,$event);
|
||||
$content['participants'][$row++]['title'] = $name == 'accounts' ?
|
||||
$content['participants'][$row++]['title'] = $name == 'accounts' ?
|
||||
$GLOBALS['egw']->common->grab_owner_name($id) : egw_link::title($name,$id);
|
||||
|
||||
|
||||
// enumerate group-invitations, so people can accept/reject them
|
||||
if ($name == 'accounts' && $GLOBALS['egw']->accounts->get_type($id) == 'g' &&
|
||||
($members = $GLOBALS['egw']->accounts->members($id,true)))
|
||||
@ -787,7 +825,7 @@ class uiforms extends uical
|
||||
if ($minutes) $label[] = $minutes.' '.lang('Minutes');
|
||||
$alarm['offset'] = implode(', ',$label);
|
||||
$content['alarm'][] = $alarm;
|
||||
|
||||
|
||||
$readonlys['delete_alarm['.$id.']'] = !$this->bo->check_perms(EGW_ACL_EDIT,$alarm['all'] ? $event : 0,$alarm['owner']);
|
||||
}
|
||||
}
|
||||
@ -811,7 +849,7 @@ class uiforms extends uical
|
||||
$readonlys['button[save]'] = $readonlys['button[apply]'] = $readonlys['freetime'] = true;
|
||||
$readonlys['link_to'] = $readonlys['customfields'] = true;
|
||||
$readonlys['duration'] = true;
|
||||
|
||||
|
||||
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
||||
{
|
||||
$onclick =& $etpl->get_cell_attribute('button[delete]','onclick');
|
||||
@ -821,10 +859,6 @@ class uiforms extends uical
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_object($GLOBALS['egw']->js))
|
||||
{
|
||||
$GLOBALS['egw']->js = CreateObject('phpgwapi.javascript');
|
||||
}
|
||||
// We hide the enddate if one of our predefined durations fits
|
||||
// the call to set_style_by_class has to be in onload, to make sure the function and the element is already created
|
||||
$GLOBALS['egw']->js->set_onload("set_style_by_class('table','end_hide','visibility','".($content['duration'] && isset($sel_options['duration'][$content['duration']]) ? 'hidden' : 'visible')."');");
|
||||
@ -868,7 +902,7 @@ class uiforms extends uical
|
||||
$content['no_add_alarm'] = !count($sel_options['owner']); // no rights to set any alarm
|
||||
if (!$event['id'])
|
||||
{
|
||||
$etpl->set_cell_attribute('button[new_alarm]','type','checkbox');
|
||||
$etpl->set_cell_attribute('button[new_alarm]','type','checkbox');
|
||||
}
|
||||
if ($preserv['no_popup'])
|
||||
{
|
||||
@ -878,31 +912,12 @@ class uiforms extends uical
|
||||
//echo "preserv="; _debug_array($preserv);
|
||||
//echo "readonlys="; _debug_array($readonlys);
|
||||
//echo "sel_options="; _debug_array($sel_options);
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . (!$event['id'] ? lang('Add') : ($view ? lang('View') :
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . (!$event['id'] ? lang('Add') : ($view ? lang('View') :
|
||||
($content['edit_single'] ? lang('Create exception') : ($content['recur_type'] ? lang('Edit series') : lang('Edit')))));
|
||||
$GLOBALS['egw_info']['flags']['java_script'] .= "<script>\n$js\n</script>\n";
|
||||
|
||||
$content['cancel_needs_refresh'] = (bool)$_GET['cancel_needs_refresh'];
|
||||
|
||||
// time locking for entries
|
||||
$locktime = $GLOBALS['egw_info']['server']['Lock_Time_Calender'];
|
||||
if ($locktime) {
|
||||
// the warning and the saving of edit_user and time will only be performed, if there is a lock time set
|
||||
if (($this->bo->now_su>($event['edit_time']+$locktime)) || ($event['edit_time']==''))
|
||||
{
|
||||
//echo "write Lock!!->DB";
|
||||
$event2update['id']=$event['id'];
|
||||
$event2update['edit_user']=$this->user;
|
||||
$event2update['edit_time']=''; // this is set in bo->update_edit_user
|
||||
$this->bo->update_edit_user($event2update);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($event['edit_user'] && $event['edit_user']!=$this->user) $content['msg'].=" ".lang('This entry is opened by user: ').$GLOBALS['egw']->accounts->id2name($event['edit_user']);
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
$content['cancel_needs_refresh'] = (bool)$_GET['cancel_needs_refresh'];
|
||||
|
||||
// non_interactive==true from $_GET calls immediate save action without displaying the edit form
|
||||
if(isset($_GET['non_interactive']) && (bool)$_GET['non_interactive'] === true)
|
||||
{
|
||||
@ -916,21 +931,41 @@ class uiforms extends uical
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove (shared) lock via ajax, when edit popup get's closed
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $token
|
||||
*/
|
||||
function ajax_unlock($id,$token)
|
||||
{
|
||||
$lock_path = egw_vfs::app_entry_lock_path('calendar',$id);
|
||||
$lock_owner = 'mailto:'.$GLOBALS['egw_info']['user']['account_email'];
|
||||
|
||||
if (($lock = egw_vfs::checkLock($lock_path)) && $lock['owner'] == $lock_owner || $lock['token'] == $token)
|
||||
{
|
||||
egw_vfs::unlock($lock_path,$token,false);
|
||||
}
|
||||
$response = new xajaxResponse();
|
||||
$response->addScript('window.close();');
|
||||
return $response->getXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* displays a sheduling conflict
|
||||
*
|
||||
* @param array $event
|
||||
* @param array $event
|
||||
* @param array $conflicts array with conflicting events, the events are not garantied to be readable by the user!
|
||||
* @param array $preserv data to preserv
|
||||
*/
|
||||
function conflicts($event,$conflicts,$preserv)
|
||||
{
|
||||
$etpl =& CreateObject('etemplate.etemplate','calendar.conflicts');
|
||||
|
||||
|
||||
foreach($conflicts as $k => $conflict)
|
||||
{
|
||||
$is_readable = $this->bo->check_perms(EGW_ACL_READ,$conflict);
|
||||
|
||||
|
||||
$conflicts[$k] += array(
|
||||
'icon_participants' => $is_readable ? (count($conflict['participants']) > 1 ? 'users' : 'single') : 'private',
|
||||
'tooltip_participants' => $is_readable ? implode(', ',$this->bo->participants($conflict)) : '',
|
||||
@ -940,7 +975,7 @@ class uiforms extends uical
|
||||
),true,true)), // show group invitations too
|
||||
'icon_recur' => $conflict['recur_type'] != MCAL_RECUR_NONE ? 'recur' : '',
|
||||
'text_recur' => $conflict['recur_type'] != MCAL_RECUR_NONE ? lang('Recurring event') : ' ',
|
||||
);
|
||||
);
|
||||
}
|
||||
$content = $event + array(
|
||||
'conflicts' => array_values($conflicts), // conflicts have id-start as key
|
||||
@ -1018,12 +1053,12 @@ class uiforms extends uical
|
||||
$content['end_time'] = 0; // no end-time limit, as duration would never fit
|
||||
}
|
||||
$content['weekdays'] = MCAL_M_WEEKDAYS;
|
||||
|
||||
|
||||
$content['search_window'] = 7 * DAY_s;
|
||||
// pick a searchwindow fitting the duration (search for a 10 day slot in a one week window never succeeds)
|
||||
foreach($sel_options['search_window'] as $window => $label)
|
||||
{
|
||||
if ($window > $content['duration'])
|
||||
if ($window > $content['duration'])
|
||||
{
|
||||
$content['search_window'] = $window;
|
||||
break;
|
||||
@ -1032,8 +1067,8 @@ class uiforms extends uical
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$content['duration']) $content['duration'] = $content['end'] - $content['start'];
|
||||
|
||||
if (!$content['duration']) $content['duration'] = $content['end'] - $content['start'];
|
||||
|
||||
if (is_array($content['freetime']['select']))
|
||||
{
|
||||
list($selected) = each($content['freetime']['select']);
|
||||
@ -1059,7 +1094,7 @@ class uiforms extends uical
|
||||
'exec[end][a]' => date('a',$end),
|
||||
);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
$fields_to_set += array(
|
||||
'exec[start][H]' => (int) date('H',$start),
|
||||
@ -1081,7 +1116,7 @@ class uiforms extends uical
|
||||
}
|
||||
}
|
||||
}
|
||||
window.close();
|
||||
window.close();
|
||||
</script>
|
||||
</html>\n";
|
||||
exit;
|
||||
@ -1098,7 +1133,7 @@ class uiforms extends uical
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . lang('freetime search');
|
||||
// let the window popup, if its already there
|
||||
$GLOBALS['egw_info']['flags']['java_script'] .= "<script>\nwindow.focus();\n</script>\n";
|
||||
|
||||
|
||||
if (!is_object($GLOBALS['egw']->js))
|
||||
{
|
||||
$GLOBALS['egw']->js = CreateObject('phpgwapi.javascript');
|
||||
@ -1113,9 +1148,9 @@ class uiforms extends uical
|
||||
'participants' => $content['participants'],
|
||||
'cal_id' => $content['cal_id'],
|
||||
'recur_type' => $content['recur_type'],
|
||||
),2);
|
||||
),2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* calculate the freetime of given $participants in a certain time-span
|
||||
*
|
||||
@ -1139,7 +1174,7 @@ class uiforms extends uical
|
||||
$busy[] = array( // add end-of-search-date as event, to cope with empty search and get freetime til that date
|
||||
'start' => $end,
|
||||
'end' => $end,
|
||||
);
|
||||
);
|
||||
$ft_start = $start;
|
||||
$freetime = array();
|
||||
$n = 0;
|
||||
@ -1179,14 +1214,14 @@ class uiforms extends uical
|
||||
'end' => $ft_end,
|
||||
);
|
||||
if ($this->debug > 1) echo "<p>freetime: ".date('D d.m.Y H:i',$ft_start)." - ".date('D d.m.Y H:i',$ft_end)."</p>\n";
|
||||
}
|
||||
}
|
||||
$ft_start = $event['end'];
|
||||
}
|
||||
if ($this->debug > 0) $this->bo->debug_message('uiforms::freetime(participants=%1, start=%2, end=%3, duration=%4, cal_id=%5) freetime=%6',true,$participants,$start,$end,$duration,$cal_id,$freetime);
|
||||
|
||||
|
||||
return $freetime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* split the freetime in daywise slot, taking into account weekdays, start- and stop-times
|
||||
*
|
||||
@ -1203,18 +1238,18 @@ class uiforms extends uical
|
||||
function split_freetime_daywise($freetime,$duration,$weekdays,$start_time,$end_time,&$sel_options)
|
||||
{
|
||||
if ($this->debug > 1) $this->bo->debug_message('uiforms::split_freetime_daywise(freetime=%1, duration=%2, start_time=%3, end_time=%4)',true,$freetime,$duration,$start_time,$end_time);
|
||||
|
||||
|
||||
$freetime_daywise = array();
|
||||
if (!is_array($sel_options)) $sel_options = array();
|
||||
$time_format = $this->common_prefs['timeformat'] == 12 ? 'h:i a' : 'H:i';
|
||||
|
||||
|
||||
$start_time = (int) $start_time; // ignore leading zeros
|
||||
$end_time = (int) $end_time;
|
||||
|
||||
// ignore the end_time, if duration would never fit
|
||||
if (($end_time - $start_time)*HOUR_s < $duration)
|
||||
if (($end_time - $start_time)*HOUR_s < $duration)
|
||||
{
|
||||
$end_time = 0;
|
||||
$end_time = 0;
|
||||
if ($this->debug > 1) $this->bo->debug_message('uiforms::split_freetime_daywise(, duration=%2, start_time=%3,..) end_time set to 0, it never fits durationn otherwise',true,$duration,$start_time);
|
||||
}
|
||||
$n = 0;
|
||||
@ -1224,7 +1259,7 @@ class uiforms extends uical
|
||||
$daybegin['hour'] = $daybegin['minute'] = $daybegin['second'] = 0;
|
||||
unset($daybegin['raw']);
|
||||
$daybegin = $this->bo->date2ts($daybegin);
|
||||
|
||||
|
||||
for($t = $daybegin; $t < $ft['end']; $t += DAY_s,$daybegin += DAY_s)
|
||||
{
|
||||
$dow = date('w',$daybegin+DAY_s/2); // 0=Sun, .., 6=Sat
|
||||
@ -1235,7 +1270,7 @@ class uiforms extends uical
|
||||
continue; // wrong day of week
|
||||
}
|
||||
$start = $t < $ft['start'] ? $ft['start'] : $t;
|
||||
|
||||
|
||||
if ($start-$daybegin < $start_time*HOUR_s) // start earlier then start_time
|
||||
{
|
||||
$start = $daybegin + $start_time*HOUR_s;
|
||||
@ -1266,7 +1301,7 @@ class uiforms extends uical
|
||||
}
|
||||
return $freetime_daywise;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Export events as vCalendar version 2.0 files (iCal)
|
||||
*
|
||||
@ -1281,7 +1316,7 @@ class uiforms extends uical
|
||||
if (!($ical =& ExecMethod2('calendar.boical.exportVCal',$cal_id,'2.0')))
|
||||
{
|
||||
$msg = lang('Permission denied');
|
||||
|
||||
|
||||
if ($return_error) return $msg;
|
||||
}
|
||||
else
|
||||
@ -1325,13 +1360,13 @@ class uiforms extends uical
|
||||
);
|
||||
}
|
||||
$content['msg'] = $msg;
|
||||
|
||||
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . lang('iCal Export');
|
||||
$etpl =& CreateObject('etemplate.etemplate','calendar.export');
|
||||
|
||||
|
||||
$etpl->exec('calendar.uiforms.export',$content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import events as vCalendar version 2.0 files (iCal)
|
||||
*
|
||||
@ -1362,7 +1397,7 @@ class uiforms extends uical
|
||||
);
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . lang('iCal Import');
|
||||
$etpl =& CreateObject('etemplate.etemplate','calendar.import');
|
||||
|
||||
|
||||
$etpl->exec('calendar.uiforms.import',$content);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
/* $Id$ */
|
||||
|
||||
$setup_info['calendar']['name'] = 'calendar';
|
||||
$setup_info['calendar']['version'] = '1.5';
|
||||
$setup_info['calendar']['version'] = '1.5.001';
|
||||
$setup_info['calendar']['app_order'] = 3;
|
||||
$setup_info['calendar']['enable'] = 1;
|
||||
|
||||
@ -79,3 +79,4 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -28,9 +28,7 @@
|
||||
'cal_modifier' => array('type' => 'int','precision' => '4'),
|
||||
'cal_non_blocking' => array('type' => 'int','precision' => '2','default' => '0'),
|
||||
'cal_special' => array('type' => 'int','precision' => '2','default' => '0'),
|
||||
'cal_etag' => array('type' => 'int','precision' => '4'),
|
||||
'cal_edit_user' => array('type' => 'int','precision' => '4'),
|
||||
'cal_edit_time' => array('type' => 'int','precision' => '8')
|
||||
'cal_etag' => array('type' => 'int','precision' => '4','default' => '0')
|
||||
),
|
||||
'pk' => array('cal_id'),
|
||||
'fk' => array(),
|
||||
|
@ -208,7 +208,7 @@
|
||||
'uc' => array()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->query('SELECT count(*) FROM webcal_entry',__LINE__,__FILE__);
|
||||
$GLOBALS['egw_setup']->oProc->next_record();
|
||||
if($GLOBALS['egw_setup']->oProc->f(0))
|
||||
@ -233,10 +233,10 @@
|
||||
.'VALUES('.$cal_id.",'".$cal_owner."','".$cal_group."',".$datetime.",".$moddatetime.",".$cal_duration.",".$cal_priority.",'".$cal_type."','".$cal_access."','".$cal_name."','".$cal_description."')",__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->DropTable('webcal_entry_groups');
|
||||
$GLOBALS['egw_setup']->oProc->DropTable('webcal_entry');
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->CreateTable('calendar_entry_user',
|
||||
Array(
|
||||
'fd' => array(
|
||||
@ -250,7 +250,7 @@
|
||||
'uc' => array()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->query('SELECT count(*) FROM webcal_entry_user',__LINE__,__FILE__);
|
||||
$GLOBALS['egw_setup']->oProc->next_record();
|
||||
if($GLOBALS['egw_setup']->oProc->f(0))
|
||||
@ -264,9 +264,9 @@
|
||||
$db2->query('INSERT INTO calendar_entry_user(cal_id,cal_login,cal_status) VALUES('.$cal_id.','.$cal_login.",'".$cal_status."')",__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->DropTable('webcal_entry_user');
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->CreateTable('calendar_entry_repeats',
|
||||
Array(
|
||||
'fd' => array(
|
||||
@ -283,7 +283,7 @@
|
||||
'uc' => array()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->query('SELECT count(*) FROM webcal_entry_repeats',__LINE__,__FILE__);
|
||||
$GLOBALS['egw_setup']->oProc->next_record();
|
||||
if($GLOBALS['egw_setup']->oProc->f(0))
|
||||
@ -308,10 +308,10 @@
|
||||
$db2->query('INSERT INTO calendar_entry_repeats(cal_id,cal_type,cal_use_end,cal_end,cal_frequency,cal_days) VALUES('.$cal_id.",'".$cal_type."',".$useend.",".$enddate.",".$cal_frequency.",'".$cal_days."')",__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->DropTable('webcal_entry_repeats');
|
||||
$GLOBALS['egw_setup']->oProc->query("UPDATE {$GLOBALS['egw_setup']->applications_table} SET app_tables='calendar_entry,calendar_entry_user,calendar_entry_repeats' WHERE app_name='calendar'",__LINE__,__FILE__);
|
||||
|
||||
|
||||
$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.7pre2';
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'];
|
||||
}
|
||||
@ -320,7 +320,7 @@
|
||||
function calendar_upgrade0_9_7pre2()
|
||||
{
|
||||
$db2 = $GLOBALS['egw_setup']->db;
|
||||
|
||||
|
||||
$GLOBALS['egw_setup']->oProc->RenameColumn('calendar_entry', 'cal_duration', 'cal_edatetime');
|
||||
$GLOBALS['egw_setup']->oProc->query('SELECT cal_id,cal_datetime,cal_owner,cal_edatetime,cal_mdatetime FROM calendar_entry ORDER BY cal_id',__LINE__,__FILE__);
|
||||
if($GLOBALS['egw_setup']->oProc->num_rows())
|
||||
@ -337,7 +337,7 @@
|
||||
$db2->query('UPDATE calendar_entry SET cal_datetime='.$datetime.', cal_edatetime='.$edatetime.', cal_mdatetime='.$mdatetime.' WHERE cal_id='.$cal_id,__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.7pre3';
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'];
|
||||
}
|
||||
@ -590,7 +590,7 @@
|
||||
define(RECUR_MONTHLY_MDAY,3);
|
||||
define(RECUR_MONTHLY_WDAY,4);
|
||||
define(RECUR_YEARLY,5);
|
||||
|
||||
|
||||
define(M_SUNDAY,1);
|
||||
define(M_MONDAY,2);
|
||||
define(M_TUESDAY,4);
|
||||
@ -856,7 +856,7 @@
|
||||
$GLOBALS['egw_setup']->oProc->CreateTable('phpgw_cal_alarm',
|
||||
Array(
|
||||
'fd' => array(
|
||||
'alarm_id' => array('type' => 'auto','nullable' => False),
|
||||
'alarm_id' => array('type' => 'auto','nullable' => False),
|
||||
'cal_id' => array('type' => 'int', 'precision' => 8, 'nullable' => False),
|
||||
'cal_owner' => array('type' => 'int', 'precision' => 8, 'nullable' => False),
|
||||
'cal_time' => array('type' => 'int', 'precision' => 8, 'nullable' => False),
|
||||
@ -900,7 +900,7 @@
|
||||
@reset($calendar_data);
|
||||
while($calendar_data && list($cal_id,$category) = each($calendar_data))
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->query("UPDATE phpgw_cal SET category='".$category."' WHERE cal_id=".$cal_id,__LINE__,__FILE__);
|
||||
$GLOBALS['egw_setup']->oProc->query("UPDATE phpgw_cal SET category='".$category."' WHERE cal_id=".$cal_id,__LINE__,__FILE__);
|
||||
}
|
||||
$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.13.006';
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'];
|
||||
@ -1061,14 +1061,14 @@
|
||||
// re-run the update as very old entries only have an empty uid
|
||||
return calendar_upgrade0_9_16_005();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$test[] = '0.9.16.007';
|
||||
function calendar_upgrade0_9_16_007()
|
||||
{
|
||||
// update the sequenzes for refreshed tables (postgres only)
|
||||
$GLOBALS['egw_setup']->oProc->UpdateSequence('phpgw_cal_holidays','hol_id');
|
||||
|
||||
|
||||
$GLOBALS['setup_info']['calendar']['currentver'] = '1.0.0';
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'];
|
||||
}
|
||||
@ -1498,14 +1498,14 @@
|
||||
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.2';
|
||||
}
|
||||
|
||||
|
||||
|
||||
$test[] = '1.2';
|
||||
function calendar_upgrade1_2()
|
||||
{
|
||||
// get old alarms (saved before 1.2) working again
|
||||
$GLOBALS['egw_setup']->db->query("UPDATE egw_async SET async_method ='calendar.bocalupdate.send_alarm' WHERE async_method ='calendar.bocalendar.send_alarm'",__LINE__,__FILE__);
|
||||
|
||||
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.2.001';
|
||||
}
|
||||
|
||||
@ -1532,17 +1532,71 @@
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->AddColumn('egw_cal','cal_etag',array(
|
||||
'type' => 'int',
|
||||
'precision' => '4'
|
||||
));
|
||||
$GLOBALS['egw_setup']->oProc->AddColumn('egw_cal','cal_edit_user',array(
|
||||
'type' => 'int',
|
||||
'precision' => '4'
|
||||
));
|
||||
$GLOBALS['egw_setup']->oProc->AddColumn('egw_cal','cal_edit_time',array(
|
||||
'type' => 'int',
|
||||
'precision' => '8'
|
||||
'precision' => '4',
|
||||
'default' => '0'
|
||||
));
|
||||
// as we no longer create cal_edit_time|user and already set default 0 for cal_etag, we skip the 1.5 update
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.5.001';
|
||||
}
|
||||
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.5';
|
||||
|
||||
$test[] = '1.5';
|
||||
function calendar_upgrade1_5()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->DropColumn('egw_cal',array(
|
||||
'fd' => array(
|
||||
'cal_id' => array('type' => 'auto','nullable' => False),
|
||||
'cal_uid' => array('type' => 'varchar','precision' => '255','nullable' => False),
|
||||
'cal_owner' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'cal_category' => array('type' => 'varchar','precision' => '30'),
|
||||
'cal_modified' => array('type' => 'int','precision' => '8'),
|
||||
'cal_priority' => array('type' => 'int','precision' => '2','nullable' => False,'default' => '2'),
|
||||
'cal_public' => array('type' => 'int','precision' => '2','nullable' => False,'default' => '1'),
|
||||
'cal_title' => array('type' => 'varchar','precision' => '255','nullable' => False,'default' => '1'),
|
||||
'cal_description' => array('type' => 'text'),
|
||||
'cal_location' => array('type' => 'varchar','precision' => '255'),
|
||||
'cal_reference' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'),
|
||||
'cal_modifier' => array('type' => 'int','precision' => '4'),
|
||||
'cal_non_blocking' => array('type' => 'int','precision' => '2','default' => '0'),
|
||||
'cal_special' => array('type' => 'int','precision' => '2','default' => '0'),
|
||||
'cal_etag' => array('type' => 'int','precision' => '4'),
|
||||
'cal_edit_time' => array('type' => 'int','precision' => '8')
|
||||
),
|
||||
'pk' => array('cal_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array(),
|
||||
'uc' => array()
|
||||
),'cal_edit_user');
|
||||
$GLOBALS['egw_setup']->oProc->DropColumn('egw_cal',array(
|
||||
'fd' => array(
|
||||
'cal_id' => array('type' => 'auto','nullable' => False),
|
||||
'cal_uid' => array('type' => 'varchar','precision' => '255','nullable' => False),
|
||||
'cal_owner' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'cal_category' => array('type' => 'varchar','precision' => '30'),
|
||||
'cal_modified' => array('type' => 'int','precision' => '8'),
|
||||
'cal_priority' => array('type' => 'int','precision' => '2','nullable' => False,'default' => '2'),
|
||||
'cal_public' => array('type' => 'int','precision' => '2','nullable' => False,'default' => '1'),
|
||||
'cal_title' => array('type' => 'varchar','precision' => '255','nullable' => False,'default' => '1'),
|
||||
'cal_description' => array('type' => 'text'),
|
||||
'cal_location' => array('type' => 'varchar','precision' => '255'),
|
||||
'cal_reference' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'),
|
||||
'cal_modifier' => array('type' => 'int','precision' => '4'),
|
||||
'cal_non_blocking' => array('type' => 'int','precision' => '2','default' => '0'),
|
||||
'cal_special' => array('type' => 'int','precision' => '2','default' => '0'),
|
||||
'cal_etag' => array('type' => 'int','precision' => '4')
|
||||
),
|
||||
'pk' => array('cal_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array(),
|
||||
'uc' => array()
|
||||
),'cal_edit_time');
|
||||
$GLOBALS['egw_setup']->oProc->AlterColumn('egw_cal','cal_etag',array(
|
||||
'type' => 'int',
|
||||
'precision' => '4',
|
||||
'default' => '0'
|
||||
));
|
||||
$GLOBALS['egw_setup']->db->query('UPDATE egw_cal SET cal_etag=0 WHERE cal_etag IS NULL',__LINE__,__FILE__);
|
||||
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.5.001';
|
||||
}
|
||||
?>
|
||||
|
Loading…
Reference in New Issue
Block a user