2004-10-08 00:11:18 +02:00
< ? php
2007-03-09 12:39:47 +01:00
/**
2011-04-07 09:28:46 +02:00
* EGroupware - Calendar ' s forms of the UserInterface
2007-03-09 12:39:47 +01:00
*
* @ link http :// www . egroupware . org
* @ package calendar
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de >
2011-04-07 09:28:46 +02:00
* @ copyright ( c ) 2004 - 11 by RalfBecker - At - outdoor - training . de
2007-03-09 12:39:47 +01:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ version $Id $
*/
2004-10-08 00:11:18 +02:00
/**
2005-11-09 00:15:14 +01:00
* calendar UserInterface forms : view and edit events , freetime search
*
* The new UI , BO and SO classes have a strikt definition , in which time - zone they operate :
* UI only operates in user - time , so there have to be no conversation at all !!!
* BO ' s functions take and return user - time only ( ! ), they convert internaly everything to servertime , because
* SO operates only on server - time
*
* The state of the UI elements is managed in the uical class , which all UI classes extend .
*
* All permanent debug messages of the calendar - code should done via the debug - message method of the bocal class ! ! !
2004-10-08 00:11:18 +02:00
*/
2008-06-07 19:45:33 +02:00
class calendar_uiforms extends calendar_ui
2004-10-08 00:11:18 +02:00
{
var $public_functions = array (
'freetimesearch' => True ,
2005-11-09 00:15:14 +01:00
'edit' => true ,
2010-02-05 04:34:17 +01:00
'process_edit' => true ,
2005-11-09 00:15:14 +01:00
'export' => true ,
'import' => true ,
2009-12-03 19:24:19 +01:00
'cat_acl' => true ,
2011-05-27 22:32:46 +02:00
'meeting' => true ,
2004-10-08 00:11:18 +02:00
);
2008-05-08 00:12:25 +02:00
2006-06-03 01:36:43 +02:00
/**
* Standard durations used in edit and freetime search
*
* @ var array
*/
var $durations = array ();
2008-05-08 00:12:25 +02:00
2008-01-15 09:21:25 +01:00
/**
2009-10-18 14:59:12 +02:00
* default locking time for entries , that are opened by another user
2008-01-15 09:21:25 +01:00
*
2009-10-18 14:59:12 +02:00
* @ var locktime in seconds
2008-01-15 09:21:25 +01:00
*/
var $locktime_default = 1 ;
2004-10-08 00:11:18 +02:00
/**
* Constructor
*/
2008-06-07 19:45:33 +02:00
function __construct ()
2004-10-08 00:11:18 +02:00
{
2008-06-07 19:45:33 +02:00
parent :: __construct ( true ); // call the parent's constructor
2008-05-08 00:12:25 +02:00
2006-06-03 01:36:43 +02:00
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 );
}
2005-11-09 00:15:14 +01:00
}
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
/**
* Create a default event ( adding a new event ) by evaluating certain _GET vars
*
* @ return array event - array
2008-05-08 00:12:25 +02:00
*/
2005-11-09 00:15:14 +01:00
function & default_add_event ()
{
2005-11-23 15:21:20 +01:00
$extra_participants = $_GET [ 'participants' ] ? explode ( ',' , $_GET [ 'participants' ]) : array ();
2006-03-03 19:56:01 +01:00
if ( isset ( $_GET [ 'owner' ]))
{
$owner = $_GET [ 'owner' ];
}
// dont set the planner start group as owner/participants if called from planner
elseif ( $this -> view != 'planner' || $this -> owner != $this -> cal_prefs [ 'planner_start_with_group' ])
{
$owner = $this -> owner ;
}
2008-11-12 10:22:45 +01:00
2008-05-08 00:12:25 +02:00
if ( ! $owner || ! is_numeric ( $owner ) || $GLOBALS [ 'egw' ] -> accounts -> get_type ( $owner ) != 'u' ||
2005-11-23 15:21:20 +01:00
! $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
{
2008-11-12 10:22:45 +01:00
// if we come from ressources we don't need any users selected in calendar
if ( ! isset ( $_GET [ 'participants' ]) || $_GET [ 'participants' ][ 0 ] != 'r' )
2008-10-25 08:43:15 +02:00
{
2008-11-12 10:22:45 +01:00
foreach ( explode ( ',' , $owner ) as $uid )
{
// only add users or a single ressource, not all ressources displayed by a category
if ( is_numeric ( $uid ) || $owner == $uid )
{
$extra_participants [] = $uid ;
}
}
2008-10-25 08:43:15 +02:00
}
2005-11-23 15:21:20 +01:00
}
$owner = $this -> user ;
}
2006-03-03 19:56:01 +01:00
//echo "<p>this->owner=$this->owner, _GET[owner]=$_GET[owner], user=$this->user => owner=$owner, extra_participants=".implode(',',$extra_participants)."</p>\n";
2005-11-09 00:15:14 +01:00
2005-11-23 15:21:20 +01:00
// by default include the owner as participant (the user can remove him)
$extra_participants [] = $owner ;
2005-11-09 00:15:14 +01:00
$start = $this -> bo -> date2ts ( array (
'full' => isset ( $_GET [ 'date' ]) && ( int ) $_GET [ 'date' ] ? ( int ) $_GET [ 'date' ] : $this -> date ,
'hour' => ( int ) ( isset ( $_GET [ 'hour' ]) && ( int ) $_GET [ 'hour' ] ? $_GET [ 'hour' ] : $this -> bo -> cal_prefs [ 'workdaystarts' ]),
'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";
2008-05-08 00:12:25 +02:00
2005-11-23 15:21:20 +01:00
$participant_types [ 'u' ] = $participant_types = $participants = array ();
foreach ( $extra_participants as $uid )
2005-11-09 00:15:14 +01:00
{
2005-11-23 15:21:20 +01:00
if ( isset ( $participants [ $uid ])) continue ; // already included
2009-11-19 19:56:04 +01:00
if ( ! $this -> bo -> check_acl_invite ( $uid )) continue ; // no right to invite --> ignored
2005-11-23 15:21:20 +01:00
if ( is_numeric ( $uid ))
2005-11-09 00:15:14 +01:00
{
2009-10-13 11:00:01 +02:00
$participants [ $uid ] = $participant_types [ 'u' ][ $uid ] =
2009-11-27 09:04:29 +01:00
calendar_so :: combine_status ( $uid == $this -> user ? 'A' : 'U' , 1 ,
( $uid == $this -> user || ( $uid == $owner && $this -> bo -> check_perms ( EGW_ACL_ADD , 0 , $owner ))) ? 'CHAIR' : 'REQ-PARTICIPANT' );
2005-11-23 15:21:20 +01:00
}
2008-05-08 17:02:35 +02:00
elseif ( is_array ( $this -> bo -> resources [ $uid [ 0 ]]))
2005-11-23 15:21:20 +01:00
{
2011-02-15 12:34:36 +01:00
// if contact is a user, use the user instead (as the GUI)
if ( $uid [ 0 ] == 'c' && ( $account_id = $GLOBALS [ 'egw' ] -> accounts -> name2id ( substr ( $uid , 1 ), 'person_id' )))
{
$uid = $account_id ;
$participants [ $uid ] = $participant_types [ 'u' ][ $uid ] =
calendar_so :: combine_status ( $uid == $this -> user ? 'A' : 'U' , 1 ,
( $uid == $this -> user || ( $uid == $owner && $this -> bo -> check_perms ( EGW_ACL_ADD , 0 , $owner ))) ? 'CHAIR' : 'REQ-PARTICIPANT' );
continue ;
}
2008-05-08 17:02:35 +02:00
$res_data = $this -> bo -> resources [ $uid [ 0 ]];
2005-11-23 15:21:20 +01:00
list ( $id , $quantity ) = explode ( ':' , substr ( $uid , 1 ));
2009-10-12 21:16:42 +02:00
if (( $status = $res_data [ 'new_status' ] ? ExecMethod ( $res_data [ 'new_status' ], $id ) : 'U' ))
2005-11-09 00:15:14 +01:00
{
2009-10-13 11:00:01 +02:00
$participants [ $uid ] = $participant_types [ $uid [ 0 ]][ $id ] =
calendar_so :: combine_status ( $status , $quantity , 'REQ-PARTICIPANT' );
2005-11-09 00:15:14 +01:00
}
}
}
2009-11-19 19:56:04 +01:00
if ( ! $participants ) // if all participants got removed, include current user
{
2009-11-26 19:36:19 +01:00
$participants [ $this -> user ] = $participant_types [ 'u' ][ $this -> user ] = calendar_so :: combine_status ( 'A' , 1 , 'CHAIR' );
2009-11-19 19:56:04 +01:00
}
2005-11-09 00:15:14 +01:00
return array (
'participant_types' => $participant_types ,
'participants' => $participants ,
'owner' => $owner ,
'start' => $start ,
'end' => $start + ( int ) $this -> bo -> cal_prefs [ 'defaultlength' ] * 60 ,
2009-11-04 08:56:00 +01:00
'tzid' => $this -> bo -> common_prefs [ 'tz' ],
2005-11-09 00:15:14 +01:00
'priority' => 2 , // normal
'public' => $this -> cal_prefs [ 'default_private' ] ? 0 : 1 ,
'alarm' => array (),
);
}
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
/**
* Process the edited event and evtl . call edit to redisplay it
*
* @ param array $content posted eTemplate content
2010-11-11 14:29:37 +01:00
* @ ToDo add conflict check / available quantity of resources when adding participants
2005-11-09 00:15:14 +01:00
*/
function process_edit ( $content )
{
2010-02-05 04:34:17 +01:00
if ( ! is_array ( $content )) // redirect from etemplate, if POST empty
{
return $this -> edit ( null , null , strip_tags ( $_GET [ 'msg' ]));
}
2010-05-12 13:15:45 +02:00
$messages = null ;
$msg_permission_denied_added = false ;
2005-11-09 00:15:14 +01:00
list ( $button ) = @ each ( $content [ 'button' ]);
2006-12-22 20:51:56 +01:00
if ( ! $button && $content [ 'action' ]) $button = $content [ 'action' ]; // action selectbox
unset ( $content [ 'button' ]); unset ( $content [ 'action' ]);
2005-11-09 00:15:14 +01:00
2006-12-22 20:51:56 +01:00
$view = $content [ 'view' ];
if ( $button == 'ical' )
2005-11-09 00:15:14 +01:00
{
$msg = $this -> export ( $content [ 'id' ], true );
}
// delete a recur-exception
if ( $content [ 'recur_exception' ][ 'delete_exception' ])
{
list ( $date ) = each ( $content [ 'recur_exception' ][ 'delete_exception' ]);
unset ( $content [ 'recur_exception' ][ 'delete_exception' ]);
if (( $key = array_search ( $date , $content [ 'recur_exception' ])) !== false )
{
2010-05-19 19:41:46 +02:00
// propagate the exception to a single event
$recur_exceptions = $this -> bo -> so -> get_related ( $content [ 'uid' ]);
foreach ( $recur_exceptions as $id )
{
if ( ! ( $exception = $this -> bo -> read ( $id )) ||
$exception [ 'recurrence' ] != $content [ 'recur_exception' ][ $key ]) continue ;
$exception [ 'uid' ] = common :: generate_uid ( 'calendar' , $id );
$exception [ 'reference' ] = $exception [ 'recurrence' ] = 0 ;
2011-03-24 23:17:11 +01:00
$this -> bo -> update ( $exception , true , true , false , true , $message , $content [ 'no_notifications' ]);
2010-05-19 19:41:46 +02:00
break ;
}
2005-11-09 00:15:14 +01:00
unset ( $content [ 'recur_exception' ][ $key ]);
$content [ 'recur_exception' ] = array_values ( $content [ 'recur_exception' ]);
}
}
// delete an alarm
if ( $content [ 'alarm' ][ 'delete_alarm' ])
{
list ( $id ) = each ( $content [ 'alarm' ][ 'delete_alarm' ]);
//echo "delete alarm $id"; _debug_array($content['alarm']['delete_alarm']);
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
if ( $content [ 'id' ])
{
if ( $this -> bo -> delete_alarm ( $id ))
{
$msg = lang ( 'Alarm deleted' );
unset ( $content [ 'alarm' ][ $id ]);
2010-06-10 19:24:22 +02:00
$js = " opener.location.search += (opener.location.search?'&msg=':'?msg=')+' " .
addslashes ( $msg ) . " '; " ;
2005-11-09 00:15:14 +01:00
}
else
{
2008-05-08 00:12:25 +02:00
$msg = lang ( 'Permission denied' );
2005-11-09 00:15:14 +01:00
}
}
else
{
unset ( $content [ 'alarm' ][ $id ]);
}
}
2006-06-03 01:36:43 +02:00
if ( $content [ 'duration' ])
{
$content [ 'end' ] = $content [ 'start' ] + $content [ 'duration' ];
}
2005-11-09 00:15:14 +01:00
$event = $content ;
unset ( $event [ 'new_alarm' ]);
unset ( $event [ 'alarm' ][ 'delete_alarm' ]);
2006-09-28 06:32:38 +02:00
unset ( $event [ 'duration' ]);
2005-11-09 00:15:14 +01:00
2010-06-16 12:41:45 +02:00
if ( in_array ( $button , array ( 'ignore' , 'freetime' , 'reedit' )))
2006-03-07 21:30:29 +01:00
{
// no conversation necessary, event is already in the right format
}
2010-06-16 12:41:45 +02:00
else
2005-11-09 00:15:14 +01:00
{
2010-06-16 12:41:45 +02:00
// convert content => event
2005-11-09 00:15:14 +01:00
if ( $content [ 'whole_day' ])
{
$event [ 'start' ] = $this -> bo -> date2array ( $event [ 'start' ]);
$event [ 'start' ][ 'hour' ] = $event [ 'start' ][ 'minute' ] = 0 ; unset ( $event [ 'start' ][ 'raw' ]);
$event [ 'start' ] = $this -> bo -> date2ts ( $event [ 'start' ]);
$event [ 'end' ] = $this -> bo -> date2array ( $event [ 'end' ]);
$event [ 'end' ][ 'hour' ] = 23 ; $event [ 'end' ][ 'minute' ] = $event [ 'end' ][ 'second' ] = 59 ; unset ( $event [ 'end' ][ 'raw' ]);
$event [ 'end' ] = $this -> bo -> date2ts ( $event [ 'end' ]);
}
2010-02-24 16:05:00 +01:00
// some checks for recurrences, if you give a date, make it a weekly repeating event and visa versa
2005-11-09 00:15:14 +01:00
if ( $event [ 'recur_type' ] == MCAL_RECUR_NONE && $event [ 'recur_data' ]) $event [ 'recur_type' ] = MCAL_RECUR_WEEKLY ;
if ( $event [ 'recur_type' ] == MCAL_RECUR_WEEKLY && ! $event [ 'recur_data' ])
{
$event [ 'recur_data' ] = 1 << ( int ) date ( 'w' , $event [ 'start' ]);
}
2010-11-11 14:29:37 +01:00
if ( isset ( $content [ 'participants' ]))
2005-11-09 00:15:14 +01:00
{
2010-11-11 14:29:37 +01:00
2010-06-16 12:41:45 +02:00
$event [ 'participants' ] = $event [ 'participant_types' ] = array ();
2010-11-11 14:29:37 +01:00
2010-06-16 12:41:45 +02:00
foreach ( $content [ 'participants' ] as $key => $data )
2005-11-09 00:15:14 +01:00
{
2010-06-16 12:41:45 +02:00
switch ( $key )
{
case 'delete' : // handled in default
case 'quantity' : // handled in new_resource
case 'role' : // handled in add, account or resource
case 'cal_resources' :
case 'status_date' :
break ;
2010-11-11 14:29:37 +01:00
2010-06-16 12:41:45 +02:00
case 'add' :
// email or rfc822 addresse (eg. "Ralf Becker <ralf@domain.com>") in the search field
// ToDo: get eTemplate to return that field
if (( $email = $_POST [ 'exec' ][ 'participants' ][ 'resource' ][ 'query' ]) &&
( preg_match ( '/^(.*<)?([a-z0-9_.-]+@[a-z0-9_.-]{5,})>?$/i' , $email , $matches )))
{
$status = calendar_so :: combine_status ( 'U' , $content [ 'participants' ][ 'quantity' ], $content [ 'participants' ][ 'role' ]);
// check if email belongs to account or contact --> prefer them over just emails (if we are allowed to invite him)
if (( $data = $GLOBALS [ 'egw' ] -> accounts -> name2id ( $matches [ 2 ], 'account_email' )) && $this -> bo -> check_acl_invite ( $data ))
{
$event [ 'participants' ][ $data ] = $event [ 'participant_types' ][ 'u' ][ $data ] = $status ;
}
elseif (( list ( $data ) = ExecMethod2 ( 'addressbook.addressbook_bo.search' , array (
'email' => $matches [ 2 ],
'email_home' => $matches [ 2 ],
), true , '' , '' , '' , false , 'OR' )))
{
$event [ 'participants' ][ 'c' . $data [ 'id' ]] = $event [ 'participant_types' ][ 'c' ][ $data [ 'id' ]] = $status ;
}
else
{
$event [ 'participants' ][ 'e' . $email ] = $event [ 'participant_types' ][ 'e' ][ $email ] = $status ;
}
}
elseif ( ! $content [ 'participants' ][ 'account' ] && ! $content [ 'participants' ][ 'resource' ])
2008-05-08 17:02:35 +02:00
{
2010-06-16 12:41:45 +02:00
$msg = lang ( 'You need to select an account, contact or resource first!' );
2008-05-08 17:02:35 +02:00
}
2010-06-16 12:41:45 +02:00
break ;
2010-11-11 14:29:37 +01:00
2010-06-16 12:41:45 +02:00
case 'resource' :
2011-08-11 09:41:18 +02:00
if ( is_array ( $data )) // if $data['current'] is NOT set --> $app==''
2008-05-08 17:02:35 +02:00
{
2010-06-16 12:41:45 +02:00
list ( $app , $id ) = explode ( ':' , $data [ 'current' ]);
2008-05-08 17:02:35 +02:00
}
else
{
2010-06-16 12:41:45 +02:00
list ( $app , $id ) = explode ( ':' , $data );
2008-05-08 17:02:35 +02:00
}
2010-06-16 12:41:45 +02:00
foreach ( $this -> bo -> resources as $type => $data ) if ( $data [ 'app' ] == $app ) break ;
$uid = $this -> bo -> resources [ $type ][ 'app' ] == $app ? $type . $id : false ;
2011-09-07 16:47:51 +02:00
if ( $app == 'home-accounts' )
{
$data = $id ;
}
2010-06-16 12:41:45 +02:00
// check if new entry is no account (or contact entry of an account)
2011-09-07 16:47:51 +02:00
elseif ( $app != 'addressbook' || ! ( $data = $GLOBALS [ 'egw' ] -> accounts -> name2id ( $id , 'person_id' )) || ! $this -> bo -> check_acl_invite ( $data ))
2009-07-02 13:26:52 +02:00
{
2010-06-16 12:41:45 +02:00
if ( $uid && $id )
2009-10-12 21:16:42 +02:00
{
2010-06-16 12:41:45 +02:00
$status = isset ( $this -> bo -> resources [ $type ][ 'new_status' ]) ? ExecMethod ( $this -> bo -> resources [ $type ][ 'new_status' ], $id ) : 'U' ;
if ( $status )
{
2010-11-11 14:29:37 +01:00
$res_info = $this -> bo -> resource_info ( $uid );
// todo check real availability = maximum - already booked quantity
if ( isset ( $res_info [ 'useable' ]) && $content [ 'participants' ][ 'quantity' ] > $res_info [ 'useable' ])
{
$msg .= lang ( 'Maximum available quantity of %1 exceeded!' , $res_info [ 'useable' ]);
foreach ( array ( 'quantity' , 'resource' , 'role' ) as $n )
{
$event [ 'participants' ][ $n ] = $content [ 'participants' ][ $n ];
}
}
else
{
$event [ 'participants' ][ $uid ] = $event [ 'participant_types' ][ $type ][ $id ] =
calendar_so :: combine_status ( $status , $content [ 'participants' ][ 'quantity' ], $content [ 'participants' ][ 'role' ]);
}
2010-06-16 12:41:45 +02:00
}
elseif ( ! $msg_permission_denied_added )
{
$msg .= lang ( 'Permission denied!' );
$msg_permission_denied_added = true ;
}
2009-10-12 21:16:42 +02:00
}
2010-06-16 12:41:45 +02:00
break ;
2009-07-02 13:26:52 +02:00
}
2010-06-16 12:41:45 +02:00
// fall-through for accounts entered as contact
case 'account' :
foreach ( is_array ( $data ) ? $data : explode ( ',' , $data ) as $uid )
{
2010-11-11 14:29:37 +01:00
if ( $uid && $this -> bo -> check_acl_invite ( $uid ))
{
$event [ 'participants' ][ $uid ] = $event [ 'participant_types' ][ 'u' ][ $uid ] =
calendar_so :: combine_status ( $uid == $this -> bo -> user ? 'A' : 'U' , 1 , $content [ 'participants' ][ 'role' ]);
}
elseif ( $uid && ! $msg_permission_denied_added )
{
$msg .= lang ( 'Permission denied!' );
$msg_permission_denied_added = true ;
}
2010-06-16 12:41:45 +02:00
}
break ;
2010-11-11 14:29:37 +01:00
2010-06-16 12:41:45 +02:00
default : // existing participant row
foreach ( array ( 'uid' , 'status' , 'quantity' , 'role' ) as $name )
{
2010-11-11 14:29:37 +01:00
$$name = $data [ $name ];
2010-06-16 12:41:45 +02:00
}
2010-11-11 14:29:37 +01:00
if ( $content [ 'participants' ][ 'delete' ][ $uid ] || $content [ 'participants' ][ 'delete' ][ md5 ( $uid )])
2005-11-09 00:15:14 +01:00
{
2010-11-11 14:29:37 +01:00
$uid = false ; // entry has been deleted
2006-12-22 20:51:56 +01:00
}
2011-06-21 08:46:51 +02:00
elseif ( $uid )
2006-12-22 20:51:56 +01:00
{
2010-11-11 14:29:37 +01:00
if ( is_numeric ( $uid ))
2006-12-22 20:51:56 +01:00
{
2010-11-11 14:29:37 +01:00
$id = $uid ;
$type = 'u' ;
}
else
{
$id = substr ( $uid , 1 );
$type = $uid [ 0 ];
}
if ( $data [ 'old_status' ] != $status && ! ( ! $data [ 'old_status' ] && $status == 'G' ))
{
//echo "<p>$uid: status changed '$data[old_status]' --> '$status<'/p>\n";
$new_status = calendar_so :: combine_status ( $status , $quantity , $role );
2011-03-09 18:26:20 +01:00
if ( $this -> bo -> set_status ( $event [ 'id' ], $uid , $new_status , isset ( $content [ 'edit_single' ]) ? $content [ 'participants' ][ 'status_date' ] : 0 , false , true , $content [ 'no_notifications' ]))
2009-08-17 16:38:18 +02:00
{
2010-11-11 14:29:37 +01:00
// refreshing the calendar-view with the changed participant-status
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE )
2009-08-17 22:05:46 +02:00
{
2010-11-11 14:29:37 +01:00
$msg = lang ( 'Status for all future scheduled days changed' );
2009-08-17 22:05:46 +02:00
}
else
{
2010-11-11 14:29:37 +01:00
if ( isset ( $content [ 'edit_single' ]))
{
$msg = lang ( 'Status for this particular day changed' );
// prevent accidentally creating a real exception afterwards
$view = true ;
$hide_delete = true ;
}
else
{
$msg = lang ( 'Status changed' );
}
}
if ( ! $content [ 'no_popup' ])
{
$js = " opener.location.search += (opener.location.search?'&msg=':'?msg=')+' " .
addslashes ( $msg ) . " '; " ;
2009-08-17 22:05:46 +02:00
}
2006-12-22 20:51:56 +01:00
}
}
2010-11-11 14:29:37 +01:00
if ( $uid && $status != 'G' )
{
$event [ 'participants' ][ $uid ] = $event [ 'participant_types' ][ $type ][ $id ] =
calendar_so :: combine_status ( $status , $quantity , $role );
}
2005-11-09 00:15:14 +01:00
}
2010-11-11 14:29:37 +01:00
break ;
2010-06-16 12:41:45 +02:00
}
2005-11-09 00:15:14 +01:00
}
}
}
$preserv = array (
2009-08-17 22:05:46 +02:00
'view' => $view ,
'hide_delete' => $hide_delete ,
'edit_single' => $content [ 'edit_single' ],
'reference' => $content [ 'reference' ],
'recurrence' => $content [ 'recurrence' ],
'actual_date' => $content [ 'actual_date' ],
'no_popup' => $content [ 'no_popup' ],
2010-08-16 09:13:47 +02:00
'tabs' => $content [ 'tabs' ],
2009-11-25 21:16:41 +01:00
'template' => $content [ 'template' ],
2005-11-09 00:15:14 +01:00
);
2008-01-15 09:21:25 +01:00
$noerror = true ;
2010-11-11 14:29:37 +01:00
2010-06-08 11:52:48 +02:00
//error_log(__METHOD__.$button.'#'.array2string($content['edit_single']).'#');
2010-11-11 14:29:37 +01:00
2010-06-23 16:47:34 +02:00
$ignore_conflicts = $edit_series_confirmed = $status_reset_to_unknown = false ;
2010-11-11 14:29:37 +01:00
2010-06-09 20:00:11 +02:00
switch (( string ) $button )
{
case 'ignore' :
$ignore_conflicts = true ;
$button = $event [ 'button_was' ]; // save or apply
unset ( $event [ 'button_was' ]);
break ;
2010-11-11 14:29:37 +01:00
2010-06-09 20:00:11 +02:00
case 'confirm_edit_series' :
$edit_series_confirmed = true ;
$button = $event [ 'button_was' ]; // save or apply
2010-11-11 14:29:37 +01:00
unset ( $event [ 'button_was' ]);
2010-06-09 20:00:11 +02:00
}
2010-11-11 14:29:37 +01:00
2006-12-22 20:51:56 +01:00
switch (( string ) $button )
2005-11-09 00:15:14 +01:00
{
2005-11-23 22:39:37 +01:00
case 'exception' : // create an exception in a recuring event
2008-02-07 03:38:55 +01:00
$msg = $this -> _create_exception ( $event , $preserv );
2005-11-23 22:39:37 +01:00
break ;
2005-11-09 00:15:14 +01:00
case 'copy' : // create new event with copied content, some content need to be unset to make a "new" event
unset ( $event [ 'id' ]);
unset ( $event [ 'uid' ]);
unset ( $event [ 'alarm' ]);
unset ( $event [ 'reference' ]);
2009-07-23 18:14:22 +02:00
unset ( $event [ 'recurrence' ]);
2005-11-09 00:15:14 +01:00
unset ( $event [ 'recur_exception' ]);
unset ( $event [ 'edit_single' ]); // in case it has been set
unset ( $event [ 'modified' ]);
unset ( $event [ 'modifier' ]);
2011-04-07 09:28:46 +02:00
unset ( $event [ 'caldav_name' ]);
2005-11-09 00:15:14 +01:00
$event [ 'owner' ] = ! ( int ) $this -> owner || ! $this -> bo -> check_perms ( EGW_ACL_ADD , 0 , $this -> owner ) ? $this -> user : $this -> owner ;
2010-04-30 18:00:03 +02:00
// Clear participant stati
2010-06-16 12:41:45 +02:00
foreach ( $event [ 'participant_types' ] as $type => & $participants )
{
2010-04-30 18:00:03 +02:00
foreach ( $participants as $id => & $response )
{
if ( $type == 'u' && $id == $event [ 'owner' ]) continue ;
calendar_so :: split_status ( $status , $quantity , $role );
$response = calendar_so :: combine_status ( 'U' , $quantity , $role );
}
}
2005-11-09 00:15:14 +01:00
$preserv [ 'view' ] = $preserv [ 'edit_single' ] = false ;
$msg = lang ( 'Event copied - the copy can now be edited' );
$event [ 'title' ] = lang ( 'Copy of:' ) . ' ' . $event [ 'title' ];
break ;
2008-05-08 00:12:25 +02:00
2006-12-22 20:51:56 +01:00
case 'mail' :
2005-11-09 00:15:14 +01:00
case 'save' :
2008-12-18 15:47:21 +01:00
case 'print' :
2005-11-09 00:15:14 +01:00
case 'apply' :
2008-05-08 00:12:25 +02:00
if ( $event [ 'id' ] && ! $this -> bo -> check_perms ( EGW_ACL_EDIT , $event ))
{
2009-10-01 21:21:37 +02:00
switch ( $button )
2006-12-22 20:51:56 +01:00
{
2009-10-01 21:21:37 +02:00
case 'mail' : // just mail without edit-rights is ok
$js = $this -> custom_mail ( $event , false );
break 2 ;
case 'print' : // just print without edit-rights is ok
$js = $this -> custom_print ( $event , false );
break 2 ;
2008-12-18 15:47:21 +01:00
}
$msg = lang ( 'Permission denied' );
2009-10-01 21:16:38 +02:00
$button = '' ;
2008-12-18 15:47:21 +01:00
break ;
}
2005-11-23 15:21:20 +01:00
if ( $event [ 'start' ] > $event [ 'end' ])
{
$msg = lang ( 'Error: Starttime has to be before the endtime !!!' );
$button = '' ;
break ;
}
2009-10-01 21:16:38 +02:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE && $event [ 'recur_enddate' ] && $event [ 'start' ] > $event [ 'recur_enddate' ])
{
$msg = lang ( 'repetition' ) . ': ' . lang ( 'Error: Starttime has to be before the endtime !!!' );
$button = '' ;
break ;
}
2005-11-23 15:21:20 +01:00
if ( ! $event [ 'participants' ])
{
$msg = lang ( 'Error: no participants selected !!!' );
$button = '' ;
break ;
}
2008-10-10 12:24:31 +02:00
// if private event with ressource reservation is forbidden
if ( ! $event [ 'public' ] && $GLOBALS [ 'egw_info' ][ 'server' ][ 'no_ressources_private' ])
{
foreach ( $event [ 'participants' ] as $uid => $value )
{
if ( $uid [ 0 ] == 'r' ) //ressource detection
{
$msg = lang ( 'Error: ressources reservation in private events is not allowed!!!' );
$button = '' ;
break 2 ; //break foreach and case
}
}
}
2005-11-09 00:15:14 +01:00
if ( $content [ 'edit_single' ]) // we edited a single event from a series
{
$event [ 'reference' ] = $event [ 'id' ];
2009-07-23 18:14:22 +02:00
$event [ 'recurrence' ] = $content [ 'edit_single' ];
2005-11-09 00:15:14 +01:00
unset ( $event [ 'id' ]);
2011-11-11 13:46:34 +01:00
// modifiy alarms for the exception, unsetting alarm-id to create new alarms
foreach ( $event [ 'alarm' ] as $n => & $alarm )
{
unset ( $alarm [ 'id' ]);
}
2011-03-09 18:26:20 +01:00
$conflicts = $this -> bo -> update ( $event , $ignore_conflicts , true , false , true , $messages , $content [ 'no_notifications' ]);
2005-11-09 00:15:14 +01:00
if ( ! is_array ( $conflicts ) && $conflicts )
{
// now we need to add the original start as recur-execption to the series
$recur_event = $this -> bo -> read ( $event [ 'reference' ]);
$recur_event [ 'recur_exception' ][] = $content [ 'edit_single' ];
2005-11-23 22:39:37 +01:00
unset ( $recur_event [ 'start' ]); unset ( $recur_event [ 'end' ]); // no update necessary
2011-11-11 13:46:34 +01:00
unset ( $recur_event [ 'alarm' ]); // unsetting alarms too, as they cant be updated without start!
2005-11-09 00:15:14 +01:00
$this -> bo -> update ( $recur_event , true ); // no conflict check here
unset ( $recur_event );
unset ( $event [ 'edit_single' ]); // if we further edit it, it's just a single event
2005-11-23 22:39:37 +01:00
unset ( $preserv [ 'edit_single' ]);
2005-11-09 00:15:14 +01:00
}
else // conflict or error, we need to reset everything to the state befor we tried to save it
{
$event [ 'id' ] = $event [ 'reference' ];
unset ( $event [ 'reference' ]);
$event [ 'uid' ] = $content [ 'uid' ];
}
}
else // we edited a non-reccuring event or the whole series
{
2011-11-10 19:39:08 +01:00
if (( $old_event = $this -> bo -> read ( $event [ 'id' ])))
2010-06-09 20:00:11 +02:00
{
2010-06-23 16:47:34 +02:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE )
2010-06-09 20:00:11 +02:00
{
2010-06-23 16:47:34 +02:00
// we edit a existing series event
if ( $event [ 'start' ] != $old_event [ 'start' ] ||
$event [ 'whole_day' ] != $old_event [ 'whole_day' ])
2010-06-09 20:00:11 +02:00
{
2010-06-23 16:47:34 +02:00
if ( ! ( $next_occurrence = $this -> bo -> read ( $event [ 'id' ], $this -> bo -> now_su + 1 , true )))
{
$msg = lang ( " Error: You can't shift a series from the past! " );
$noerror = false ;
break ;
}
2011-11-10 19:39:08 +01:00
// splitting of series confirmed or first event clicked (no confirmation necessary)
if ( $edit_series_confirmed || $old_event [ 'start' ] == $event [ 'actual_date' ])
2010-06-09 20:00:11 +02:00
{
2011-11-10 19:39:08 +01:00
$edit_series_confirmed = true ;
2010-06-23 16:47:34 +02:00
$orig_event = $event ;
2010-11-11 14:29:37 +01:00
2011-11-10 19:39:08 +01:00
// calculate offset against old series start or clicked recurrance,
// depending on which is smaller
2010-06-23 16:47:34 +02:00
$offset = $event [ 'start' ] - $old_event [ 'start' ];
2011-11-10 19:39:08 +01:00
if ( abs ( $offset ) > abs ( $off2 = $event [ 'start' ] - $event [ 'actual_date' ]))
{
$offset = $off2 ;
}
// base start-date of new series on actual / clicked date
$actual_date = $event [ 'actual_date' ];
$event [ 'start' ] = $actual_date + $offset ;
if ( $content [ 'duration' ])
{
$event [ 'end' ] = $event [ 'start' ] + $content [ 'duration' ];
}
elseif ( $event [ 'end' ] < $event [ 'start' ])
{
$event [ 'end' ] = $event [ 'start' ] + $event [ 'end' ] - $actual_date ;
}
//echo "<p>".__LINE__.": event[start]=$event[start]=".egw_time::to($event['start']).", duration=$content[duration], event[end]=$event[end]=".egw_time::to($event['end']).", offset=$offset</p>\n";
2010-06-23 16:47:34 +02:00
$event [ 'participants' ] = $old_event [ 'participants' ];
foreach ( $old_event [ 'recur_exception' ] as $key => $exdate )
2010-06-09 20:00:11 +02:00
{
2011-11-10 19:39:08 +01:00
if ( $exdate > $actual_date )
2010-06-23 16:47:34 +02:00
{
unset ( $old_event [ 'recur_exception' ][ $key ]);
$event [ 'recur_exception' ][ $key ] += $offset ;
}
else
{
unset ( $event [ 'recur_exception' ][ $key ]);
}
2010-06-09 20:00:11 +02:00
}
2011-11-10 19:39:08 +01:00
$old_alarms = $old_event [ 'alarm' ];
if ( $old_event [ 'start' ] < $actual_date )
2010-06-09 20:00:11 +02:00
{
2011-11-10 19:39:08 +01:00
unset ( $orig_event );
// copy event by unsetting the id(s)
unset ( $event [ 'id' ]);
unset ( $event [ 'uid' ]);
unset ( $event [ 'caldav_name' ]);
// set enddate of existing event
2010-06-23 16:47:34 +02:00
$rriter = calendar_rrule :: event2rrule ( $old_event , true );
$rriter -> rewind ();
$last = $rriter -> current ();
do
{
$rriter -> next_no_exception ();
$occurrence = $rriter -> current ();
}
while ( $rriter -> valid () &&
2011-11-10 19:39:08 +01:00
egw_time :: to ( $occurrence , 'ts' ) < $actual_date &&
2010-06-23 16:47:34 +02:00
( $last = $occurrence ));
$last -> setTime ( 0 , 0 , 0 );
$old_event [ 'recur_enddate' ] = egw_time :: to ( $last , 'ts' );
2011-08-02 17:55:20 +02:00
if ( ! $this -> bo -> update ( $old_event , true , true , false , true , $dummy = null , $content [ 'no_notifications' ]))
2010-06-23 16:47:34 +02:00
{
$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="' .
htmlspecialchars ( egw :: link ( '/index.php' , array (
'menuaction' => 'calendar.calendar_uiforms.edit' ,
'cal_id' => $content [ 'id' ],
'referer' => $referer ,
))) . '">' , '</a>' );
$noerror = false ;
$event = $orig_event ;
break ;
}
2011-11-10 19:39:08 +01:00
$event [ 'alarm' ] = array ();
2010-06-09 20:00:11 +02:00
}
}
2010-06-11 09:32:10 +02:00
else
2010-06-09 20:00:11 +02:00
{
2010-06-23 16:47:34 +02:00
$event [ 'button_was' ] = $button ; // remember for confirm
2011-11-10 19:39:08 +01:00
$preserv [ 'duration' ] = $content [ 'duration' ];
2010-06-23 16:47:34 +02:00
return $this -> confirm_edit_series ( $event , $preserv );
2010-06-09 20:00:11 +02:00
}
}
}
else
{
2010-06-23 16:47:34 +02:00
if ( $old_event [ 'start' ] != $event [ 'start' ] ||
$old_event [ 'end' ] != $event [ 'end' ] ||
$event [ 'whole_day' ] != $old_event [ 'whole_day' ])
{
2010-11-02 12:00:41 +01:00
$sameday = ( date ( 'Ymd' , $old_event [ 'start' ]) == date ( 'Ymd' , $event [ 'start' ]));
foreach (( array ) $event [ 'participants' ] as $uid => $status )
2010-06-23 16:47:34 +02:00
{
2010-11-02 12:00:41 +01:00
calendar_so :: split_status ( $status , $q , $r );
if ( $uid [ 0 ] != 'c' && $uid [ 0 ] != 'e' && $uid != $this -> bo -> user && $status != 'U' )
{
$preferences = CreateObject ( 'phpgwapi.preferences' , $uid );
$part_prefs = $preferences -> read_repository ();
switch ( $part_prefs [ 'calendar' ][ 'reset_stati' ])
2010-06-23 16:47:34 +02:00
{
2010-11-02 12:00:41 +01:00
case 'no' :
break ;
case 'startday' :
if ( $sameday ) break ;
default :
2010-11-11 14:29:37 +01:00
$status_reset_to_unknown = true ;
2010-06-23 16:47:34 +02:00
$event [ 'participants' ][ $uid ] = calendar_so :: combine_status ( 'U' , $q , $r );
// todo: report reset status to user
}
2010-11-02 12:00:41 +01:00
}
2010-06-23 16:47:34 +02:00
}
}
2010-06-09 20:00:11 +02:00
}
}
2011-03-09 18:26:20 +01:00
$conflicts = $this -> bo -> update ( $event , $ignore_conflicts , true , false , true , $messages , $content [ 'no_notifications' ]);
2005-11-09 00:15:14 +01:00
unset ( $event [ 'ignore' ]);
}
if ( is_array ( $conflicts ))
{
$event [ 'button_was' ] = $button ; // remember for ignore
return $this -> conflicts ( $event , $conflicts , $preserv );
}
2009-12-03 19:24:19 +01:00
// check if there are messages from update, eg. removed participants or categories because of missing rights
if ( $messages )
{
$msg .= ( $msg ? ', ' : '' ) . implode ( ', ' , $messages );
}
if ( $conflicts === 0 )
2008-01-15 09:21:25 +01:00
{
$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="' .
2009-11-25 21:16:41 +01:00
htmlspecialchars ( egw :: link ( '/index.php' , array (
2008-06-07 19:45:33 +02:00
'menuaction' => 'calendar.calendar_uiforms.edit' ,
2009-12-03 19:24:19 +01:00
'cal_id' => $content [ 'id' ],
))) . '">' , '</a>' );
2010-06-09 20:00:11 +02:00
$noerror = false ;
2008-01-15 09:21:25 +01:00
}
2009-07-23 18:14:22 +02:00
elseif ( $conflicts > 0 )
2005-11-09 00:15:14 +01:00
{
2011-11-10 19:39:08 +01:00
if ( $edit_series_confirmed ) // series moved by splitting in two
2010-06-09 20:00:11 +02:00
{
2011-11-10 19:39:08 +01:00
foreach ( $old_alarms as $alarm )
2010-06-09 20:00:11 +02:00
{
2011-11-10 19:39:08 +01:00
// check if alarms still needed in old event, if not delete it
$event_time = $alarm [ 'time' ] + $alarm [ 'offset' ];
if ( $event_time >= $actual_date )
2010-06-11 09:32:10 +02:00
{
$this -> bo -> delete_alarm ( $alarm [ 'id' ]);
}
2010-06-09 20:00:11 +02:00
$alarm [ 'time' ] += $offset ;
unset ( $alarm [ 'id' ]);
2011-11-10 19:39:08 +01:00
// if alarm would be in the past (eg. event moved back) --> move to next possible recurrence
if ( $alarm [ 'time' ] < $this -> bo -> now_su )
{
if (( $next_occurrence = $this -> bo -> read ( $event [ 'id' ], $this -> bo -> now_su + $alarm [ 'offset' ], true )))
{
$alarm [ 'time' ] = $next_occurrence [ 'start' ] - $alarm [ 'offset' ];
}
else
{
$alarm = false ; // no (further) recurence found --> ignore alarm
}
}
// alarm is currently on a previous recurrence --> set for first recurrence of new series
elseif ( $event_time < $event [ 'start' ])
2010-06-09 20:00:11 +02:00
{
2011-11-10 19:39:08 +01:00
$alarm [ 'time' ] = $event [ 'start' ] - $alarm [ 'offset' ];
}
if ( $alarm )
{
$alarm [ 'id' ] = $this -> bo -> save_alarm ( $event [ 'id' ], $alarm );
$event [ 'alarm' ][ $alarm [ 'id' ]] = $alarm ;
2010-06-09 20:00:11 +02:00
}
}
// attach all future exceptions to the new series
$events =& $this -> bo -> search ( array (
'query' => array ( 'cal_uid' => $old_event [ 'uid' ]),
'filter' => 'owner' , // return all possible entries
'daywise' => false ,
'date_format' => 'ts' ,
));
foreach (( array ) $events as $exception )
{
2011-11-10 19:39:08 +01:00
if ( $exception [ 'recurrence' ] > $actual_date )
2010-06-09 20:00:11 +02:00
{
$exception [ 'recurrence' ] += $offset ;
$exception [ 'reference' ] = $event [ 'id' ];
$exception [ 'uid' ] = $event [ 'uid' ];
$exception [ 'start' ] += $offset ;
$exception [ 'end' ] += $offset ;
$exception [ 'whole_day' ] = $event [ 'whole_day' ];
$alarms = array ();
foreach ( $exception [ 'alarm' ] as $id => & $alarm )
{
$alarm [ 'time' ] = $exception [ 'start' ] - $alarm [ 'offset' ];
$alarms [] = $alarm ;
}
$event [ 'alarm' ] = $alarms ;
2011-11-10 19:39:08 +01:00
$this -> bo -> update ( $exception , true , true , true , true , $msg = null , $content [ 'no_notifications' ]);
2010-06-09 20:00:11 +02:00
}
}
}
2010-11-11 14:29:37 +01:00
2010-06-23 16:47:34 +02:00
$message = lang ( 'Event saved' );
if ( $status_reset_to_unknown )
{
foreach (( array ) $event [ 'participants' ] as $uid => $status )
{
if ( $uid [ 0 ] != 'c' && $uid [ 0 ] != 'e' && $uid != $this -> bo -> user )
{
calendar_so :: split_status ( $status , $q , $r );
$status = calendar_so :: combine_status ( 'U' , $q , $r );
2010-06-24 18:21:23 +02:00
$this -> bo -> set_status ( $event [ 'id' ], $uid , $status , 0 , true );
2010-06-23 16:47:34 +02:00
}
}
$message .= lang ( ', stati of participants reset' );
}
2010-11-11 14:29:37 +01:00
2010-06-23 16:47:34 +02:00
$msg = $message . ( $msg ? ', ' . $msg : '' );
2005-11-09 00:15:14 +01:00
// writing links for new entry, existing ones are handled by the widget itself
2008-05-08 00:12:25 +02:00
if ( ! $content [ 'id' ] && is_array ( $content [ 'link_to' ][ 'to_id' ]))
2005-11-09 00:15:14 +01:00
{
2008-03-26 13:23:26 +01:00
egw_link :: link ( 'calendar' , $event [ 'id' ], $content [ 'link_to' ][ 'to_id' ]);
2005-11-09 00:15:14 +01:00
}
2010-06-10 19:24:22 +02:00
$js = " opener.location.search += (opener.location.search?'&msg=':'?msg=')+' " .
addslashes ( $msg ) . " '; " ;
2005-11-09 00:15:14 +01:00
2008-12-18 15:47:21 +01:00
if ( $button == 'print' )
{
$js = $this -> custom_print ( $event , ! $content [ 'id' ]) . " \n " . $js ; // first open the new window and then update the view
}
2006-12-22 20:51:56 +01:00
if ( $button == 'mail' )
2005-11-09 00:15:14 +01:00
{
$js = $this -> custom_mail ( $event , ! $content [ 'id' ]) . " \n " . $js ; // first open the new window and then update the view
}
}
else
{
$msg = lang ( 'Error: saving the event !!!' );
}
break ;
2008-05-08 00:12:25 +02:00
2007-01-15 23:58:32 +01:00
case 'cancel' :
if ( $content [ 'cancel_needs_refresh' ])
{
2010-06-10 19:24:22 +02:00
$js = " opener.location.search += (opener.location.search?'&msg=':'?msg=')+' " .
addslashes ( $msg ) . " '; " ;
2007-01-15 23:58:32 +01:00
}
break ;
2010-05-20 11:19:15 +02:00
case 'delete' : // delete of regular event
case 'delete_keep_exceptions' : // series and user selected to keep the exceptions
case 'delete_exceptions' : // series and user selected to delete the exceptions too
2005-11-23 22:39:37 +01:00
if ( $this -> bo -> delete ( $event [ 'id' ],( int ) $content [ 'edit_single' ]))
2005-11-09 00:15:14 +01:00
{
2010-06-08 18:36:55 +02:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE && $content [ 'reference' ] == 0 && ! $content [ 'edit_single' ])
2010-01-22 20:49:37 +01:00
{
2010-05-12 13:15:45 +02:00
$msg = lang ( 'Series deleted' );
2010-05-20 16:43:50 +02:00
$delete_exceptions = $button == 'delete_exceptions' ;
2010-05-12 13:15:45 +02:00
$exceptions_kept = false ;
// Handle the exceptions
2010-01-22 20:49:37 +01:00
$recur_exceptions = $this -> bo -> so -> get_related ( $event [ 'uid' ]);
foreach ( $recur_exceptions as $id )
{
2010-05-20 16:43:50 +02:00
if ( $delete_exceptions )
{
$this -> bo -> delete ( $id );
}
else
2010-05-12 13:15:45 +02:00
{
if ( ! ( $exception = $this -> bo -> read ( $id ))) continue ;
$exception [ 'uid' ] = common :: generate_uid ( 'calendar' , $id );
$exception [ 'reference' ] = $exception [ 'recurrence' ] = 0 ;
2011-11-11 13:54:03 +01:00
$this -> bo -> update ( $exception , true , true , false , true , $msg = null , $content [ 'no_notifications' ]);
2010-05-12 13:15:45 +02:00
$exceptions_kept = true ;
}
2010-01-22 20:49:37 +01:00
}
2010-05-12 13:15:45 +02:00
if ( $exceptions_kept )
{
$msg .= lang ( ', exceptions preserved' );
}
}
else
{
$msg = lang ( 'Event deleted' );
2010-01-22 20:49:37 +01:00
}
2011-01-06 05:48:41 +01:00
$js = " opener.location += (opener.location.search?'&msg=':'?msg=')+' " .
2010-06-10 19:24:22 +02:00
addslashes ( $msg ) . " '; " ;
2005-11-09 00:15:14 +01:00
}
break ;
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
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 ;
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
case 'add_alarm' :
2010-06-08 18:36:55 +02:00
$time = ( $content [ 'actual_date' ] ? $content [ 'actual_date' ] : $content [ 'start' ]);
2010-06-09 20:00:11 +02:00
$offset = DAY_s * $content [ 'new_alarm' ][ 'days' ] + HOUR_s * $content [ 'new_alarm' ][ 'hours' ] + 60 * $content [ 'new_alarm' ][ 'mins' ];
2010-10-06 19:40:49 +02:00
if ( $content [ 'before_after' ]) $offset *= - 1 ;
2010-06-08 18:36:55 +02:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE &&
2010-06-09 20:00:11 +02:00
( $next_occurrence = $this -> bo -> read ( $event [ 'id' ], $this -> bo -> now_su + $offset , true )) &&
2010-06-08 18:36:55 +02:00
$time < $next_occurrence [ 'start' ])
{
$time = $next_occurrence [ 'start' ];
}
2005-11-09 00:15:14 +01:00
if ( $this -> bo -> check_perms ( EGW_ACL_EDIT , ! $content [ 'new_alarm' ][ 'owner' ] ? $event : 0 , $content [ 'new_alarm' ][ 'owner' ]))
{
$alarm = array (
'offset' => $offset ,
2010-06-08 18:36:55 +02:00
'time' => $time - $offset ,
2005-11-09 00:15:14 +01:00
'all' => ! $content [ 'new_alarm' ][ 'owner' ],
'owner' => $content [ 'new_alarm' ][ 'owner' ] ? $content [ 'new_alarm' ][ 'owner' ] : $this -> user ,
);
if ( $alarm [ 'time' ] < $this -> bo -> now_su )
{
$msg = lang ( " Can't add alarms in the past !!! " );
}
elseif ( $event [ 'id' ]) // save the alarm immediatly
{
2010-06-09 20:00:11 +02:00
if (( $alarm_id = $this -> bo -> save_alarm ( $event [ 'id' ], $alarm )))
2005-11-09 00:15:14 +01:00
{
$alarm [ 'id' ] = $alarm_id ;
$event [ 'alarm' ][ $alarm_id ] = $alarm ;
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
$msg = lang ( 'Alarm added' );
2010-06-10 19:24:22 +02:00
$js = " opener.location.search += (opener.location.search?'&msg=':'?msg=')+' " .
addslashes ( $msg ) . " '; " ;
2005-11-09 00:15:14 +01:00
}
else
{
$msg = lang ( 'Error adding the alarm' );
}
}
else
{
for ( $alarm [ 'id' ] = 1 ; isset ( $event [ 'alarm' ][ $alarm [ 'id' ]]); $alarm [ 'id' ] ++ ); // get a temporary non-conflicting, numeric id
$event [ 'alarm' ][ $alarm [ 'id' ]] = $alarm ;
}
}
else
{
$msg = lang ( 'Permission denied' );
}
break ;
}
2010-05-20 11:19:15 +02:00
if ( in_array ( $button , array ( 'cancel' , 'save' , 'delete' , 'delete_exceptions' , 'delete_keep_exceptions' )) && $noerror )
2005-11-09 00:15:14 +01:00
{
2008-05-08 00:12:25 +02:00
if ( $content [ 'lock_token' ]) // remove an existing lock
{
egw_vfs :: unlock ( egw_vfs :: app_entry_lock_path ( 'calendar' , $content [ 'id' ]), $content [ 'lock_token' ], false );
}
2005-11-09 00:15:14 +01:00
if ( $content [ 'no_popup' ])
{
2010-06-10 19:24:22 +02:00
egw :: redirect_link ( '/index.php' , array (
'menuaction' => 'calendar.calendar_uiviews.index' ,
2005-11-09 00:15:14 +01:00
'msg' => $msg ,
));
}
$js .= 'window.close();' ;
echo " <html><body onload= \" $js\ " ></ body ></ html > \n " ;
2009-10-12 21:16:42 +02:00
common :: egw_exit ();
2005-11-09 00:15:14 +01:00
}
2011-03-09 18:26:20 +01:00
unset ( $event [ 'no_notifications' ]);
2005-11-14 20:56:51 +01:00
return $this -> edit ( $event , $preserv , $msg , $js , $event [ 'id' ] ? $event [ 'id' ] : $content [ 'link_to' ][ 'to_id' ]);
2005-11-09 00:15:14 +01:00
}
2008-05-08 00:12:25 +02:00
2008-02-07 03:38:55 +01:00
/**
* Create an exception from the clicked event
2008-05-08 00:12:25 +02:00
*
2008-02-07 03:38:55 +01:00
* It ' s not stored to the DB unless the user saves it !
*
* @ param array & $event
* @ param array & $preserv
* @ return string message that exception was created
*/
function _create_exception ( & $event , & $preserv )
{
$event [ 'end' ] += $preserv [ 'actual_date' ] - $event [ 'start' ];
2009-07-23 18:14:22 +02:00
$event [ 'reference' ] = $preserv [ 'reference' ] = $event [ 'id' ];
2009-08-07 11:26:11 +02:00
$event [ 'recurrence' ] = $preserv [ 'recurrence' ] = $preserv [ 'actual_date' ];
2008-02-07 03:38:55 +01:00
$event [ 'start' ] = $preserv [ 'edit_single' ] = $preserv [ 'actual_date' ];
$event [ 'recur_type' ] = MCAL_RECUR_NONE ;
foreach ( array ( 'recur_enddate' , 'recur_interval' , 'recur_exception' , 'recur_data' ) as $name )
{
unset ( $event [ $name ]);
}
2009-07-22 17:38:58 +02:00
if ( $this -> bo -> check_perms ( EGW_ACL_EDIT , $event ))
{
2009-08-17 23:15:40 +02:00
return lang ( 'Save event as exception - Delete single occurrence - Edit status or alarms for this particular day' );
2009-07-22 17:38:58 +02:00
}
2009-08-17 23:15:40 +02:00
return lang ( 'Edit status or alarms for this particular day' );
2008-02-07 03:38:55 +01:00
}
2005-11-09 00:15:14 +01:00
/**
* return javascript to open felamimail compose window with preset content to mail all participants
*
* @ param array $event
* @ param boolean $added
* @ return string javascript window . open command
*/
function custom_mail ( $event , $added )
{
$to = array ();
2008-05-08 17:02:35 +02:00
2005-11-09 00:15:14 +01:00
foreach ( $event [ 'participants' ] as $uid => $status )
{
2009-03-05 16:18:40 +01:00
$toadd = '' ;
2006-12-22 20:51:56 +01:00
if ( $status == 'R' || $uid == $this -> user ) continue ;
2008-05-08 00:12:25 +02:00
2006-12-22 20:51:56 +01:00
if ( is_numeric ( $uid ) && $GLOBALS [ 'egw' ] -> accounts -> get_type ( $uid ) == 'u' )
2005-11-09 00:15:14 +01:00
{
2007-12-11 08:13:08 +01:00
if ( ! ( $email = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $uid , 'account_email' ))) continue ;
2005-11-09 00:15:14 +01:00
$GLOBALS [ 'egw' ] -> accounts -> get_account_name ( $uid , $lid , $firstname , $lastname );
2008-05-08 00:12:25 +02:00
2009-03-05 16:18:40 +01:00
$toadd = $firstname . ' ' . $lastname . ' <' . $email . '>' ;
if ( ! in_array ( $toadd , $to )) $to [] = $toadd ;
2007-12-11 08:13:08 +01:00
}
elseif ( $uid < 0 )
{
foreach ( $GLOBALS [ 'egw' ] -> accounts -> members ( $uid , true ) as $uid )
{
if ( ! ( $email = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $uid , 'account_email' ))) continue ;
$GLOBALS [ 'egw' ] -> accounts -> get_account_name ( $uid , $lid , $firstname , $lastname );
2008-05-08 00:12:25 +02:00
2009-03-05 16:18:40 +01:00
$toadd = $firstname . ' ' . $lastname . ' <' . $email . '>' ;
2009-03-05 16:52:57 +01:00
// dont add groupmembers if they already rejected the event, or are the current user
if ( ! in_array ( $toadd , $to ) && ( $event [ 'participants' ][ $uid ] !== 'R' && $uid != $this -> user )) $to [] = $toadd ;
2007-12-11 08:13:08 +01:00
}
2005-11-09 00:15:14 +01:00
}
2008-05-08 17:02:35 +02:00
elseif (( $info = $this -> bo -> resource_info ( $uid )))
2006-12-22 20:51:56 +01:00
{
2008-05-08 17:02:35 +02:00
$to [] = $info [ 'email' ];
2006-12-22 20:51:56 +01:00
}
2005-11-09 00:15:14 +01:00
}
list ( $subject , $body ) = $this -> bo -> get_update_message ( $event , $added ? MSG_ADDED : MSG_MODIFIED ); // update-message is in TZ of the user
2009-02-25 11:55:38 +01:00
#error_log(__METHOD__.print_r($event,true));
2008-06-12 09:33:44 +02:00
$boical = new calendar_ical ();
2008-10-05 11:22:45 +02:00
$ics = $boical -> exportVCal ( array ( $event ), '2.0' , 'request' , false );
2005-11-09 00:15:14 +01:00
$ics_file = tempnam ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ], 'ics' );
if (( $f = fopen ( $ics_file , 'w' )))
{
fwrite ( $f , $ics );
fclose ( $f );
}
$vars = array (
'menuaction' => 'felamimail.uicompose.compose' ,
2010-12-09 12:57:14 +01:00
'mimeType' => 'plain' , // force type to plain as thunderbird seems to try to be smart while parsing html messages with ics attachments
2007-05-16 09:30:58 +02:00
'preset[to]' => $to ,
2005-11-09 00:15:14 +01:00
'preset[subject]' => $subject ,
'preset[body]' => $body ,
'preset[name]' => 'event.ics' ,
'preset[file]' => $ics_file ,
'preset[type]' => 'text/calendar; method=request' ,
'preset[size]' => filesize ( $ics_file ),
);
2009-11-25 21:16:41 +01:00
return " window.open(' " . egw :: link ( '/index.php' , $vars ) . " ','_blank','width=700,height=700,scrollbars=yes,status=no'); " ;
2005-11-09 00:15:14 +01:00
}
2008-12-18 15:47:21 +01:00
/**
* return javascript to open compose window to print the event
*
* @ param array $event
* @ param boolean $added
* @ return string javascript window . open command
*/
function custom_print ( $event , $added )
{
$vars = array (
'menuaction' => 'calendar.calendar_uiforms.edit' ,
'cal_id' => $event [ 'id' ],
'print' => true ,
);
2009-11-25 21:16:41 +01:00
return " window.open(' " . egw :: link ( '/index.php' , $vars ) . " ','_blank','width=700,height=700,scrollbars=yes,status=no'); " ;
2008-12-18 15:47:21 +01:00
}
2005-11-09 00:15:14 +01:00
/**
* Edit a calendar event
*
* @ param array $event = null Event to edit , if not $_GET [ 'cal_id' ] contains the event - id
* @ param array $perserv = null following keys :
* view boolean view - mode , if no edit - access we automatic fallback to view - mode
2009-08-17 22:05:46 +02:00
* hide_delete boolean hide delete button
2005-11-09 00:15:14 +01:00
* no_popup boolean use a popup or not
* edit_single int timestamp of single event edited , unset / null otherwise
* @ param string $msg = '' msg to display
* @ param string $js = 'window.focus();' javascript to include in the page
* @ param mixed $link_to_id = '' $content from or for the link - widget
*/
function edit ( $event = null , $preserv = null , $msg = '' , $js = 'window.focus();' , $link_to_id = '' )
{
2005-11-23 15:21:20 +01:00
$sel_options = array (
2006-12-22 20:51:56 +01:00
'recur_type' => & $this -> bo -> recur_types ,
'status' => $this -> bo -> verbose_status ,
'duration' => $this -> durations ,
2009-10-12 21:16:42 +02:00
'role' => $this -> bo -> roles ,
2010-10-06 19:40:49 +02:00
'before_after' => array ( 0 => lang ( 'Before' ), 1 => lang ( 'After' )),
2006-12-22 20:51:56 +01:00
'action' => array (
'copy' => array ( 'label' => 'Copy' , 'title' => 'Copy this event' ),
'ical' => array ( 'label' => 'Export' , 'title' => 'Download this event as iCal' ),
2008-12-18 15:47:21 +01:00
'print' => array ( 'label' => 'Print' , 'title' => 'Print this event' ),
2007-05-07 11:35:05 +02:00
'mail' => array ( 'label' => 'Mail all participants' , 'title' => 'compose a mail to all participants after the event is saved' ),
2006-12-22 20:51:56 +01:00
),
2005-11-23 15:21:20 +01:00
);
2006-12-22 20:51:56 +01:00
unset ( $sel_options [ 'status' ][ 'G' ]);
2005-11-09 00:15:14 +01:00
if ( ! is_array ( $event ))
{
$preserv = array (
'no_popup' => isset ( $_GET [ 'no_popup' ]),
2009-11-25 21:16:41 +01:00
'template' => isset ( $_GET [ 'template' ]) ? $_GET [ 'template' ] : ( isset ( $_REQUEST [ 'print' ]) ? 'calendar.print' : 'calendar.edit' ),
2005-11-09 00:15:14 +01:00
);
$cal_id = ( int ) $_GET [ 'cal_id' ];
2006-12-22 20:51:56 +01:00
2011-05-26 20:28:41 +02:00
if ( ! $cal_id && empty ( $_GET [ 'ical' ]) || $cal_id && ! ( $event = $this -> bo -> read ( $cal_id )))
2005-11-09 00:15:14 +01:00
{
2008-05-08 00:12:25 +02:00
if ( $cal_id )
2005-11-09 00:15:14 +01:00
{
if ( ! $preserv [ 'no_popup' ])
{
$js = " alert(' " . lang ( 'Permission denied' ) . " '); window.close(); " ;
}
else
{
2006-12-22 20:51:56 +01:00
$GLOBALS [ 'egw' ] -> framework -> render ( '<p class="redItalic" align="center">' . lang ( 'Permission denied' ) . " </p> \n " , null , true );
2009-10-12 21:16:42 +02:00
common :: egw_exit ();
2005-11-09 00:15:14 +01:00
}
}
$event =& $this -> default_add_event ();
}
2011-05-26 20:28:41 +02:00
elseif ( ! empty ( $_GET [ 'ical' ]))
{
$ical = new calendar_ical ();
if ( ! ( $events = $ical -> icaltoegw ( $_GET [ 'ical' ], '' , 'utf-8' )) || count ( $events ) != 1 )
{
error_log ( __METHOD__ . " (' $_GET[ical] ') error parsing iCal! " );
$msg = lang ( 'Error: importing the iCal' );
$event =& $this -> default_add_event ();
}
else
{
$event = array_shift ( $events );
2011-05-26 20:40:35 +02:00
if (( $existing_event = $this -> bo -> read ( $event [ 'uid' ])))
2011-05-26 20:28:41 +02:00
{
2011-05-26 20:40:35 +02:00
$event = $existing_event ;
}
else
{
$event [ 'participant_types' ] = array ();
foreach ( $event [ 'participants' ] as $uid => $status )
{
calendar_so :: split_user ( $uid , $user_type , $user_id );
$event [ 'participant_types' ][ $user_type ][ $user_id ] = $status ;
}
2011-05-26 20:28:41 +02:00
}
//error_log(__METHOD__."(...) parsed as ".array2string($event));
}
unset ( $ical );
}
2006-12-22 20:51:56 +01:00
else
{
$preserv [ 'actual_date' ] = $event [ 'start' ]; // remember the date clicked
2010-06-08 18:36:55 +02:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE )
2006-12-22 20:51:56 +01:00
{
2010-05-03 09:52:10 +02:00
if ( empty ( $event [ 'whole_day' ]))
2008-02-07 03:38:55 +01:00
{
2010-05-03 09:52:10 +02:00
$date = $_GET [ 'date' ];
2008-02-07 03:38:55 +01:00
}
2009-08-17 16:38:18 +02:00
else
{
2010-05-03 09:52:10 +02:00
$date = new egw_time ( $_GET [ 'date' ], egw_time :: $user_timezone );
$date =& $this -> bo -> so -> startOfDay ( $date );
$date -> setUser ();
2009-08-17 16:38:18 +02:00
}
2010-05-03 09:52:10 +02:00
$event = $this -> bo -> read ( $cal_id , $date , true );
$preserv [ 'actual_date' ] = $event [ 'start' ]; // remember the date clicked
2010-06-08 18:36:55 +02:00
if ( $_GET [ 'exception' ])
{
$msg = $this -> _create_exception ( $event , $preserv );
}
else
{
$event = $this -> bo -> read ( $cal_id , null , true );
}
2006-12-22 20:51:56 +01:00
}
}
2007-01-15 23:58:32 +01:00
// set new start and end if given by $_GET
if ( isset ( $_GET [ 'start' ])) { $event [ 'start' ] = $_GET [ 'start' ]; }
if ( isset ( $_GET [ 'end' ])) { $event [ 'end' ] = $_GET [ 'end' ]; }
2005-11-09 00:15:14 +01:00
// check if the event is the whole day
$start = $this -> bo -> date2array ( $event [ 'start' ]);
$end = $this -> bo -> date2array ( $event [ 'end' ]);
$event [ 'whole_day' ] = ! $start [ 'hour' ] && ! $start [ 'minute' ] && $end [ 'hour' ] == 23 && $end [ 'minute' ] == 59 ;
$link_to_id = $event [ 'id' ];
2011-12-12 22:51:12 +01:00
if ( ! $add_link && ! $event [ 'id' ] && isset ( $_REQUEST [ 'link_app' ]) && isset ( $_REQUEST [ 'link_id' ]))
2005-11-09 00:15:14 +01:00
{
2011-12-12 22:51:12 +01:00
$link_ids = is_array ( $_REQUEST [ 'link_id' ]) ? $_REQUEST [ 'link_id' ] : array ( $_REQUEST [ 'link_id' ]);
foreach ( is_array ( $_REQUEST [ 'link_app' ]) ? $_REQUEST [ 'link_app' ] : array ( $_REQUEST [ 'link_app' ]) as $n => $link_app )
{
$link_id = $link_ids [ $n ];
$app_entry = array ();
if ( ! preg_match ( '/^[a-z_0-9-]+:[:a-z_0-9-]+$/i' , $link_app . ':' . $link_id )) // guard against XSS
{
continue ;
}
switch ( $link_app )
{
case 'infolog' :
static $infolog_bo ;
if ( ! $infolog_bo ) $infolog_bo = new infolog_bo ();
$infolog = $app_entry = $infolog_bo -> read ( $link_id );
$event = array_merge ( $event , array (
'owner' => $infolog [ 'info_owner' ],
'category' => $GLOBALS [ 'egw' ] -> categories -> check_list ( EGW_ACL_READ , $infolog [ 'info_cat' ]),
'priority' => $infolog [ 'info_priority' ] + 1 ,
'public' => $infolog [ 'info_access' ] != 'private' ,
'title' => $infolog [ 'info_subject' ],
'description' => $infolog [ 'info_des' ],
'location' => $infolog [ 'info_location' ],
'start' => $infolog [ 'info_startdate' ],
'end' => $infolog [ 'info_enddate' ]
));
2011-12-13 18:38:09 +01:00
// Only add current user, not all selected calendar users
$event [ 'participants' ] = array ( calendar_so :: combine_user ( 'u' , $event [ 'owner' ]) => 'ACHAIR' );
$event [ 'participant_types' ] = array ( 'u' => array ( $event [ 'owner' ] => 'ACHAIR' ));
2011-12-12 22:51:12 +01:00
// Add responsible as participant
foreach ( $infolog [ 'info_responsible' ] as $responsible ) {
$event [ 'participants' ][ calendar_so :: combine_user ( 'u' , $responsible )] = calendar_so :: combine_status ( 'U' );
$event [ 'participant_types' ][ 'u' ][ $responsible ] = 'U' ;
}
// Add linked contact as participant
if ( $infolog [ 'info_link' ][ 'app' ] == 'addressbook' )
{
$event [ 'participants' ][ calendar_so :: combine_user ( 'c' , $infolog [ 'info_link' ][ 'id' ])] = calendar_so :: combine_status ( 'U' );
2011-12-14 16:45:54 +01:00
$event [ 'participant_types' ][ 'c' ][ $infolog [ 'info_link' ][ 'id' ]] = 'U' ;
2011-12-12 22:51:12 +01:00
}
2011-12-14 16:45:54 +01:00
// Add infolog link to calendar entry
egw_link :: link ( 'calendar' , $link_to_id , $infolog [ 'info_link' ][ 'app' ], $infolog [ 'info_link' ][ 'id' ]);
2011-12-12 22:51:12 +01:00
break ;
default :
$event [ 'title' ] = egw_link :: title ( $link_app , $link_id );
}
2011-12-14 16:45:54 +01:00
2011-12-12 22:51:12 +01:00
// Copy same custom fields
$cal_cfs = config :: get_customfields ( 'calendar' );
$link_app_cfs = config :: get_customfields ( $link_app );
foreach ( $cal_cfs as $name => $settings )
{
if ( $link_app_cfs [ $name ]) $event [ '#' . $name ] = $app_entry [ '#' . $name ];
}
egw_link :: link ( 'calendar' , $link_to_id , $link_app , $link_id );
}
2005-11-09 00:15:14 +01:00
}
}
2009-11-25 21:16:41 +01:00
$etpl = new etemplate ();
if ( ! $etpl -> read ( $preserv [ 'template' ]))
{
$etpl -> read ( $preserv [ 'template' ] = 'calendar.edit' );
}
2005-11-09 00:15:14 +01:00
$view = $preserv [ 'view' ] = $preserv [ 'view' ] || $event [ 'id' ] && ! $this -> bo -> check_perms ( EGW_ACL_EDIT , $event );
//echo "view=$view, event="; _debug_array($event);
2008-05-08 00:12:25 +02:00
// 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' )) ?
2009-10-12 21:16:42 +02:00
common :: grab_owner_name ( $lock_uid ) : $lock [ 'owner' ]));
2008-05-08 00:12:25 +02:00
}
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 ))
{
2010-05-18 12:31:08 +02:00
// install ajax handler to unlock the entry again, if the window get's closed by the user (X of window or our [Close] button)
$GLOBALS [ 'egw' ] -> js -> set_onunload ( " if (do_onunload) xajax_doXMLHTTPsync('calendar.calendar_uiforms.ajax_unlock', $event[id] ,' $preserv[lock_token] '); " );
$GLOBALS [ 'egw' ] -> js -> set_onload ( " replace_eTemplate_onsubmit(); " );
// overwrite submit method of eTemplate form AND onSubmit event, to switch off onUnload handler for regular form submits
// selectboxes use onchange(this.form.submit()) which does not fire onSubmit event --> need to overwrite submit() method
// regular submit buttons dont call submit(), but trigger onSubmit event --> need to overwrite onSubmit event
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'java_script' ] .= '
< script >
var do_onunload = true ;
function replace_eTemplate_onsubmit ()
{
document . eTemplate . old_submit = document . eTemplate . submit ;
document . eTemplate . submit = function ()
{
do_onunload = false ;
this . old_submit ();
}
document . eTemplate . old_onsubmit = document . eTemplate . onsubmit ;
document . eTemplate . onsubmit = function ()
{
do_onunload = false ;
this . old_onsubmit ();
}
}
</ script >
' ;
2008-05-08 00:12:25 +02:00
}
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";
}
2005-11-09 00:15:14 +01:00
$content = array_merge ( $event , array (
'link_to' => array (
'to_id' => $link_to_id ,
'to_app' => 'calendar' ,
),
'edit_single' => $preserv [ 'edit_single' ], // need to be in content too, as it is used in the template
2010-08-16 09:13:47 +02:00
'tabs' => $preserv [ 'tabs' ],
2005-11-09 00:15:14 +01:00
'view' => $view ,
2008-05-08 00:12:25 +02:00
'msg' => $msg ,
2011-04-08 16:21:23 +02:00
'query_delete_exceptions' => ( int )( $event [ 'recur_type' ] && $event [ 'recur_exception' ]),
2005-11-09 00:15:14 +01:00
));
2006-06-03 01:36:43 +02:00
$content [ 'duration' ] = $content [ 'end' ] - $content [ 'start' ];
if ( isset ( $this -> durations [ $content [ 'duration' ]])) $content [ 'end' ] = '' ;
2006-12-22 20:51:56 +01:00
$row = 2 ;
$readonlys = $content [ 'participants' ] = $preserv [ 'participants' ] = array ();
2010-11-11 14:29:37 +01:00
// preserve some ui elements, if set eg. under error-conditions
foreach ( array ( 'quantity' , 'resource' , 'role' ) as $n )
{
if ( isset ( $event [ 'participants' ][ $n ])) $content [ 'participants' ][ $n ] = $event [ 'participants' ][ $n ];
}
2005-11-09 00:15:14 +01:00
foreach ( $event [ 'participant_types' ] as $type => $participants )
{
$name = 'accounts' ;
if ( isset ( $this -> bo -> resources [ $type ]))
{
$name = $this -> bo -> resources [ $type ][ 'app' ];
}
foreach ( $participants as $id => $status )
{
2006-12-22 20:51:56 +01:00
$uid = $type == 'u' ? $id : $type . $id ;
2009-10-12 21:16:42 +02:00
calendar_so :: split_status ( $status , $quantity , $role );
2006-12-22 20:51:56 +01:00
$preserv [ 'participants' ][ $row ] = $content [ 'participants' ][ $row ] = array (
'app' => $name == 'accounts' ? ( $GLOBALS [ 'egw' ] -> accounts -> get_type ( $id ) == 'g' ? 'Group' : 'User' ) : $name ,
'uid' => $uid ,
2009-10-12 21:16:42 +02:00
'status' => $status ,
'old_status' => $status ,
'quantity' => $quantity > 1 || $uid [ 0 ] == 'r' ? $quantity : '' , // only display quantity for resources or if > 1
'role' => $role ,
2006-12-22 20:51:56 +01:00
);
2009-10-12 21:16:42 +02:00
// replace iCal roles with a nicer label and remove regular REQ-PARTICIPANT
if ( isset ( $this -> bo -> roles [ $role ]))
{
2009-10-12 23:26:11 +02:00
$content [ 'participants' ][ $row ][ 'role_label' ] = lang ( $this -> bo -> roles [ $role ]);
2009-10-12 21:16:42 +02:00
}
// allow third party apps to use categories for roles
elseif ( substr ( $role , 0 , 6 ) == 'X-CAT-' )
{
2009-10-12 23:26:11 +02:00
$content [ 'participants' ][ $row ][ 'role_label' ] = $GLOBALS [ 'egw' ] -> categories -> id2name ( substr ( $role , 6 ));
2009-10-12 21:16:42 +02:00
}
else
{
2009-10-12 23:26:11 +02:00
$content [ 'participants' ][ $row ][ 'role_label' ] = lang ( str_replace ( 'X-' , '' , $role ));
2009-10-12 21:16:42 +02:00
}
2010-04-16 12:19:29 +02:00
$content [ 'participants' ][ $row ][ 'delete_id' ] = strpbrk ( $uid , '"\'<>' ) !== false ? md5 ( $uid ) : $uid ;
2009-10-12 21:16:42 +02:00
//echo "<p>$uid ($quantity): $role --> {$content['participants'][$row]['role']}</p>\n";
2009-07-22 17:38:58 +02:00
$readonlys [ $row . '[status]' ] = ! $this -> bo -> check_status_perms ( $uid , $event );
2009-08-17 22:05:46 +02:00
$readonlys [ " delete[ $uid ] " ] = $preserv [ 'hide_delete' ] || ! $this -> bo -> check_perms ( EGW_ACL_EDIT , $event );
2008-05-08 17:02:35 +02:00
// todo: make the participants available as links with email as title
if ( $name == 'accounts' )
{
2009-10-12 21:16:42 +02:00
$content [ 'participants' ][ $row ++ ][ 'title' ] = common :: grab_owner_name ( $id );
2008-05-08 17:02:35 +02:00
}
elseif (( $info = $this -> bo -> resource_info ( $uid )))
{
$content [ 'participants' ][ $row ++ ][ 'title' ] = $info [ 'name' ] ? $info [ 'name' ] : $info [ 'email' ];
}
else
{
$content [ 'participants' ][ $row ++ ][ 'title' ] = '#' . $uid ;
}
2005-11-23 15:21:20 +01:00
// enumerate group-invitations, so people can accept/reject them
2006-12-22 20:51:56 +01:00
if ( $name == 'accounts' && $GLOBALS [ 'egw' ] -> accounts -> get_type ( $id ) == 'g' &&
( $members = $GLOBALS [ 'egw' ] -> accounts -> members ( $id , true )))
2005-11-23 15:21:20 +01:00
{
2006-12-22 20:51:56 +01:00
$sel_options [ 'status' ][ 'G' ] = lang ( 'Select one' );
foreach ( $members as $member )
2005-11-23 15:21:20 +01:00
{
2009-06-18 15:21:05 +02:00
if ( ! isset ( $participants [ $member ]) && $this -> bo -> check_perms ( EGW_ACL_READ , 0 , $member ))
2005-11-23 15:21:20 +01:00
{
2009-06-18 15:21:05 +02:00
$preserv [ 'participants' ][ $row ] = $content [ 'participants' ][ $row ] = array (
'app' => 'Group invitation' ,
'uid' => $member ,
'status' => 'G' ,
);
2011-08-01 18:36:54 +02:00
$readonlys [ $row . '[quantity]' ] = $readonlys [ " delete[ $member ] " ] = true ;
2009-08-17 16:38:18 +02:00
// read access is enough to invite participants, but you need edit rights to change status
2011-08-01 18:36:54 +02:00
$readonlys [ $row . '[status]' ] = ! $this -> bo -> check_perms ( EGW_ACL_EDIT , 0 , $member );
2009-10-12 21:16:42 +02:00
$content [ 'participants' ][ $row ++ ][ 'title' ] = common :: grab_owner_name ( $member );
2005-11-23 15:21:20 +01:00
}
}
}
2005-11-09 00:15:14 +01:00
}
2006-12-22 20:51:56 +01:00
// resouces / apps we shedule, atm. resources and addressbook
$content [ 'participants' ][ 'cal_resources' ] = '' ;
2008-10-10 12:24:31 +02:00
foreach ( $this -> bo -> resources as $data )
{
$content [ 'participants' ][ 'cal_resources' ] .= ',' . $data [ 'app' ];
}
// adding extra content for the resource link-entry widget to
// * select resources or addressbook as a default selection on the app selectbox based on prefs
$content [ 'participants' ][ 'resource' ][ 'default_sel' ] = $this -> cal_prefs [ 'defaultresource_sel' ];
// * get informations from the event on the ajax callback
if ( in_array ( $content [ 'participants' ][ 'resource' ][ 'default_sel' ], array ( 'resources_conflict' , 'resources_without_conflict' )))
{
// fix real app string
$content [ 'participants' ][ 'resource' ][ 'default_sel' ] = 'resources' ;
// this will be used to get reservation information on the resource select list
$content [ 'participants' ][ 'resource' ][ 'extra' ] = " values2url(this.form,'start,end,duration,participants,recur_type,whole_day') " .
" +'&exec[event_id]= " . $content [ 'id' ] . " ' " . " +'&exec[show_conflict]= " .
(( $this -> cal_prefs [ 'defaultresource_sel' ] == 'resources_without_conflict' ) ? '0' : '1' ) . " ' " ;
}
2005-11-09 00:15:14 +01:00
}
2006-12-22 20:51:56 +01:00
$content [ 'participants' ][ 'status_date' ] = $preserv [ 'actual_date' ];
$preserv = array_merge ( $preserv , $content );
2005-11-09 00:15:14 +01:00
if ( $event [ 'alarm' ])
{
// makes keys of the alarm-array starting with 1
$content [ 'alarm' ] = array ( false );
2010-06-07 19:54:29 +02:00
if ( ! $content [ 'edit_single' ])
2005-11-09 00:15:14 +01:00
{
2010-06-07 19:54:29 +02:00
foreach ( array_values ( $event [ 'alarm' ]) as $id => $alarm )
2005-11-09 00:15:14 +01:00
{
2010-06-07 19:54:29 +02:00
if ( ! $alarm [ 'all' ] && ! $this -> bo -> check_perms ( EGW_ACL_READ , 0 , $alarm [ 'owner' ]))
{
continue ; // no read rights to the calendar of the alarm-owner, dont show the alarm
}
$alarm [ 'all' ] = ( int ) $alarm [ 'all' ];
2010-10-06 19:40:49 +02:00
$after = false ;
if ( $alarm [ 'offset' ] < 0 )
{
$after = true ;
$alarm [ 'offset' ] = - 1 * $alarm [ 'offset' ];
}
2010-06-07 19:54:29 +02:00
$days = ( int ) ( $alarm [ 'offset' ] / DAY_s );
$hours = ( int ) (( $alarm [ 'offset' ] % DAY_s ) / HOUR_s );
$minutes = ( int ) (( $alarm [ 'offset' ] % HOUR_s ) / 60 );
$label = array ();
if ( $days ) $label [] = $days . ' ' . lang ( 'days' );
if ( $hours ) $label [] = $hours . ' ' . lang ( 'hours' );
if ( $minutes ) $label [] = $minutes . ' ' . lang ( 'Minutes' );
2010-10-06 19:40:49 +02:00
$alarm [ 'offset' ] = implode ( ', ' , $label ) . ' ' . ( $after ? lang ( 'after' ) : lang ( 'before' ));
2010-06-07 19:54:29 +02:00
$content [ 'alarm' ][] = $alarm ;
2010-11-11 14:29:37 +01:00
2011-03-07 11:18:20 +01:00
$readonlys [ 'delete_alarm[' . $alarm [ 'id' ] . ']' ] = ! $this -> bo -> check_perms ( EGW_ACL_EDIT , $alarm [ 'all' ] ? $event : 0 , $alarm [ 'owner' ]);
2005-11-09 00:15:14 +01:00
}
2010-06-07 19:54:29 +02:00
}
else
{
2010-06-08 10:53:40 +02:00
// hide the alarm tab for newly created exceptions
2010-08-16 09:13:47 +02:00
$readonlys [ 'tabs' ][ 'alarms' ] = true ;
2010-11-11 14:29:37 +01:00
2010-06-08 10:53:40 +02:00
// disable the alarm tab functionality
2010-06-07 19:54:29 +02:00
$readonlys [ 'button[add_alarm]' ] = true ;
$readonlys [ 'new_alarm[days]' ] = true ;
$readonlys [ 'new_alarm[hours]' ] = true ;
$readonlys [ 'new_alarm[mins]' ] = true ;
$readonlys [ 'new_alarm[owner]' ] = true ;
2005-11-09 00:15:14 +01:00
}
2009-11-04 10:41:19 +01:00
if ( count ( $content [ 'alarm' ]) == 1 )
{
$content [ 'alarm' ] = false ; // no alarms added to content array
}
2005-11-09 00:15:14 +01:00
}
else
{
$content [ 'alarm' ] = false ;
}
$content [ 'msg' ] = $msg ;
if ( $view )
{
2011-08-01 17:57:23 +02:00
$readonlys [ '__ALL__' ] = true ; // making everything readonly, but widgets set explicitly to false
$readonlys [ 'alarm' ] = $readonlys [ 'button[cancel]' ] = $readonlys [ 'action' ] =
$readonlys [ 'before_after' ] = $readonlys [ 'button[add_alarm]' ] = $readonlys [ 'new_alarm[owner]' ] =
$readonlys [ 'new_alarm[days]' ] = $readonlys [ 'new_alarm[hours]' ] = $readonlys [ 'new_alarm[mins]' ] = false ;
2008-05-08 00:12:25 +02:00
2006-12-22 20:51:56 +01:00
$content [ 'participants' ][ 'no_add' ] = true ;
2009-11-25 21:16:41 +01:00
2009-11-26 09:28:06 +01:00
// respect category permissions
if ( ! empty ( $event [ 'category' ]))
{
$content [ 'category' ] = $this -> categories -> check_list ( EGW_ACL_READ , $event [ 'category' ]);
}
2005-11-09 00:15:14 +01:00
}
else
{
2010-04-16 15:24:58 +02:00
//Add the check_recur_type function to onload, which disables recur_data function
//if recur_type is not repeat weekly.
2010-06-08 19:45:22 +02:00
$onload = " check_recur_type('recur_type',2); " ;
2006-06-03 01:36:43 +02:00
// 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
2010-04-16 15:24:58 +02:00
$onload .= " set_style_by_class('table','end_hide','display',' " . ( $content [ 'duration' ] && isset ( $sel_options [ 'duration' ][ $content [ 'duration' ]]) ? 'none' : 'block' ) . " '); " ;
$GLOBALS [ 'egw' ] -> js -> set_onload ( $onload );
2006-06-03 01:36:43 +02:00
2010-06-09 20:00:11 +02:00
$readonlys [ 'recur_exception' ] = true ;
2010-02-24 16:05:00 +01:00
2010-01-23 11:40:44 +01:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE )
{
2010-06-09 20:00:11 +02:00
$readonlys [ 'recur_exception' ] = ! count ( $content [ 'recur_exception' ]); // otherwise we get a delete button
2010-01-23 11:40:44 +01:00
$onclick =& $etpl -> get_cell_attribute ( 'button[delete]' , 'onclick' );
$onclick = str_replace ( 'Delete this event' , 'Delete this series of recuring events' , $onclick );
}
2010-01-23 13:43:35 +01:00
elseif ( $event [ 'reference' ] != 0 )
{
$readonlys [ 'recur_type' ] = $readonlys [ 'recur_enddate' ] = true ;
$readonlys [ 'recur_interval' ] = $readonlys [ 'recur_data' ] = true ;
}
2005-11-09 00:15:14 +01:00
}
// disabling the custom fields tab, if there are none
2010-08-16 09:13:47 +02:00
$readonlys [ 'tabs' ] = array (
2006-08-22 18:50:45 +02:00
'custom' => ! count ( $this -> bo -> config [ 'customfields' ]),
'participants' => $this -> accountsel -> account_selection == 'none' ,
2005-11-09 00:15:14 +01:00
);
2006-12-22 20:51:56 +01:00
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'felamimail' ])) // no mail without mail-app
{
unset ( $sel_options [ 'action' ][ 'mail' ]);
}
if ( ! $event [ 'id' ]) // no ical export for new (not saved) events
2005-11-09 00:15:14 +01:00
{
2006-12-22 20:51:56 +01:00
$readonlys [ 'action' ] = true ;
2005-11-09 00:15:14 +01:00
}
2006-12-22 20:51:56 +01:00
if ( ! ( $readonlys [ 'button[exception]' ] = ! $this -> bo -> check_perms ( EGW_ACL_EDIT , $event ) || $event [ 'recur_type' ] == MCAL_RECUR_NONE ))
2005-11-09 00:15:14 +01:00
{
2006-12-22 20:51:56 +01:00
$content [ 'exception_label' ] = $this -> bo -> long_date ( $preserv [ 'actual_date' ]);
2005-11-09 00:15:14 +01:00
}
2009-08-17 22:05:46 +02:00
$readonlys [ 'button[delete]' ] = ! $event [ 'id' ] || $preserv [ 'hide_delete' ] || ! $this -> bo -> check_perms ( EGW_ACL_DELETE , $event );
2005-11-23 22:39:37 +01:00
2007-05-07 11:35:05 +02:00
if ( ! $event [ 'id' ] || $this -> bo -> check_perms ( EGW_ACL_EDIT , $event )) // new event or edit rights to the event ==> allow to add alarm for all users
2005-11-09 00:15:14 +01:00
{
$sel_options [ 'owner' ][ 0 ] = lang ( 'All participants' );
}
2007-05-07 11:35:05 +02:00
if ( isset ( $event [ 'participant_types' ][ 'u' ][ $this -> user ]))
{
$sel_options [ 'owner' ][ $this -> user ] = $this -> bo -> participant_name ( $this -> user );
}
2005-11-09 00:15:14 +01:00
foreach (( array ) $event [ 'participant_types' ][ 'u' ] as $uid => $status )
{
2007-05-07 11:35:05 +02:00
if ( $uid != $this -> user && $status != 'R' && $this -> bo -> check_perms ( EGW_ACL_EDIT , 0 , $uid ))
2005-11-09 00:15:14 +01:00
{
$sel_options [ 'owner' ][ $uid ] = $this -> bo -> participant_name ( $uid );
}
}
$content [ 'no_add_alarm' ] = ! count ( $sel_options [ 'owner' ]); // no rights to set any alarm
if ( ! $event [ 'id' ])
{
2008-05-08 00:12:25 +02:00
$etpl -> set_cell_attribute ( 'button[new_alarm]' , 'type' , 'checkbox' );
2005-11-09 00:15:14 +01:00
}
if ( $preserv [ 'no_popup' ])
{
$etpl -> set_cell_attribute ( 'button[cancel]' , 'onclick' , '' );
}
2010-02-12 21:18:45 +01:00
2010-06-28 13:38:28 +02:00
// Allow admins to restore deleted events
2011-04-27 18:53:06 +02:00
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'calendar_delete_history' ] && $event [ 'deleted' ] )
2010-06-28 13:38:28 +02:00
{
2010-09-09 11:11:57 +02:00
$content [ 'deleted' ] = $preserv [ 'deleted' ] = null ;
$etpl -> set_cell_attribute ( 'button[save]' , 'label' , 'Recover' );
2010-06-28 13:38:28 +02:00
$etpl -> set_cell_attribute ( 'button[apply]' , 'disabled' , true );
}
2011-03-21 17:57:11 +01:00
// Allow users to prevent notifications?
2011-04-27 18:53:06 +02:00
$etpl -> set_cell_attribute ( 'no_notifications' , 'disabled' , ! $GLOBALS [ 'egw_info' ][ 'server' ][ 'calendar_allow_no_notification' ]);
2010-06-28 13:38:28 +02:00
2010-02-12 21:18:45 +01:00
// Setup history tab
$this -> setup_history ( $content , $sel_options );
2005-11-09 00:15:14 +01:00
//echo "content="; _debug_array($content);
//echo "preserv="; _debug_array($preserv);
//echo "readonlys="; _debug_array($readonlys);
//echo "sel_options="; _debug_array($sel_options);
2009-07-22 17:38:58 +02:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'calendar' ) . ' - '
. ( ! $event [ 'id' ] ? lang ( 'Add' )
: ( $view ? ( $content [ 'edit_single' ] ? lang ( 'View exception' ) : ( $content [ 'recur_type' ] ? lang ( 'View series' ) : lang ( 'View' )))
: ( $content [ 'edit_single' ] ? lang ( 'Create exception' ) : ( $content [ 'recur_type' ] ? lang ( 'Edit series' ) : lang ( 'Edit' )))));
2010-04-16 15:24:58 +02:00
//Function for disabling the recur_data multiselect box
$js .=
" \n function check_recur_type(_id, _ind) \n { \n egw_set_checkbox_multiselect_enabled('recur_data', " .
" document.getElementById('exec['+_id+']').selectedIndex == _ind); \n } \n " ;
2005-11-09 00:15:14 +01:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'java_script' ] .= " <script> \n $js\n </script> \n " ;
2008-05-08 00:12:25 +02:00
2007-01-15 23:58:32 +01:00
$content [ 'cancel_needs_refresh' ] = ( bool ) $_GET [ 'cancel_needs_refresh' ];
2008-01-17 16:39:22 +01:00
2007-01-15 23:58:32 +01:00
// non_interactive==true from $_GET calls immediate save action without displaying the edit form
if ( isset ( $_GET [ 'non_interactive' ]) && ( bool ) $_GET [ 'non_interactive' ] === true )
{
unset ( $_GET [ 'non_interactive' ]); // prevent process_exec <--> edit loops
$content [ 'button' ][ 'save' ] = true ;
2007-01-22 19:47:59 +01:00
$this -> process_edit ( array_merge ( $content , $preserv ));
2007-01-15 23:58:32 +01:00
}
else
{
2008-06-07 19:45:33 +02:00
$etpl -> exec ( 'calendar.calendar_uiforms.process_edit' , $content , $sel_options , $readonlys , $preserv , $preserv [ 'no_popup' ] ? 0 : 2 );
2007-01-15 23:58:32 +01:00
}
2005-11-09 00:15:14 +01:00
}
2008-05-08 00:12:25 +02:00
/**
* 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 ();
}
2011-05-27 22:32:46 +02:00
/**
* Display a meeting request ( iCal ) for FMail and allow to accept , tentative or reject it
*
* @ todo Handle situation when user is NOT invited , but eg . can view that mail ...
* @ param array $event = null
* @ param string $msg = ''
*/
function meeting ( array $event = null , $msg = '' )
{
$user = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
if ( ! is_array ( $event ))
{
2011-05-31 12:12:39 +02:00
$ical_charset = 'utf-8' ;
$ical_string = $_GET [ 'ical' ];
if ( $ical_string == 'session' )
{
$session_data = egw_cache :: getSession ( 'calendar' , 'ical' );
$ical_string = $session_data [ 'attachment' ];
$ical_charset = $session_data [ 'charset' ];
unset ( $session_data );
}
2011-05-27 22:32:46 +02:00
$ical = new calendar_ical ();
2011-05-31 12:12:39 +02:00
if ( ! ( $events = $ical -> icaltoegw ( $ical_string , '' , $ical_charset )) || count ( $events ) != 1 )
2011-05-27 22:32:46 +02:00
{
error_log ( __METHOD__ . " (' $_GET[ical] ') error parsing iCal! " );
$GLOBALS [ 'egw' ] -> framework -> render ( html :: fieldset ( '<pre>' . htmlspecialchars ( $ical_string ) . '</pre>' ,
lang ( 'Error: importing the iCal' )));
return ;
}
$event = array_shift ( $events );
if (( $existing_event = $this -> bo -> read ( $event [ 'uid' ])) && ! $existing_event [ 'deleted' ])
{
$event = $existing_event ;
foreach (( array ) $event [ 'participants' ] as $uid => $status )
{
calendar_so :: split_status ( $status , $quantity , $role );
if ( $role == 'CHAIR' )
{
$event [ 'organizer' ] = $this -> bo -> participant_name ( $uid , false , true );
break ;
}
}
if ( empty ( $event [ 'organizer' ]))
{
$event [ 'organizer' ] = $this -> bo -> participant_name ( $event [ 'owner' ], false , true );
}
$msg = lang ( 'Using already existing event on server.' );
}
else
{
$event [ 'participant_types' ] = array ();
foreach ( $event [ 'participants' ] as $uid => $status )
{
calendar_so :: split_user ( $uid , $user_type , $user_id );
$event [ 'participant_types' ][ $user_type ][ $user_id ] = $status ;
}
}
//error_log(__METHOD__."(...) parsed as ".array2string($event));
$event [ 'recure' ] = $this -> bo -> recure2string ( $event );
$event [ 'all_participants' ] = implode ( " , \n " , $this -> bo -> participants ( $event , true ));
if ( ! isset ( $event [ 'participants' ][ $user ]))
{
$msg .= ( $msg ? " \n " : '' ) . lang ( 'You are not invited to that event!' );
if ( $event [ 'id' ])
{
$readonlys [ 'button[accept]' ] = $readonlys [ 'button[tentativ]' ] = $readonlys [ 'button[reject]' ] = true ;
}
}
// ignore events in the past
if ( $this -> bo -> date2ts ( $event [ 'start' ]) < $this -> bo -> now_su )
{
$msg = lang ( 'Requested meeting is in the past!' );
$readonlys [ 'button[accept]' ] = $readonlys [ 'button[tentativ]' ] = $readonlys [ 'button[reject]' ] = true ;
}
}
else
{
//_debug_array($event);
list ( $button ) = each ( $event [ 'button' ]);
unset ( $event [ 'button' ]);
switch ( $button )
{
case 'reject' :
if ( ! $event [ 'id' ])
{
// send reply to organizer
$this -> bo -> send_update ( MSG_REJECTED , array ( 'e' . $event [ 'organizer' ] => 'DCHAIR' ), $event );
break ; // no need to store rejected event
}
// fall-through
case 'accept' :
case 'tentativ' :
$status = strtoupper ( $button [ 0 ]); // A, R or T
if ( ! $event [ 'id' ])
{
// store event without notifications!
if (( $event [ 'id' ] = $this -> bo -> update ( $event , $ignore_conflicts = true , true , false , true , $msg , true )))
{
$msg = lang ( 'Event saved' );
}
else
{
$msg = lang ( 'Error: saving the event !!!' );
break ;
}
}
// set status and send notification / meeting response
if ( $this -> bo -> set_status ( $event , $user , $status ))
{
if ( ! $msg ) $msg = lang ( 'Status changed' );
}
break ;
}
}
$event [ 'msg' ] = $msg ;
$readonlys [ 'button[edit]' ] = ! $event [ 'id' ];
$tpl = new etemplate ( 'calendar.meeting' );
$tpl -> exec ( 'calendar.calendar_uiforms.meeting' , $event , $sel_options , $readonlys , $event , 2 );
}
2005-11-09 00:15:14 +01:00
/**
* displays a sheduling conflict
*
2008-05-08 00:12:25 +02:00
* @ param array $event
2005-11-09 00:15:14 +01:00
* @ 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 )
{
2009-08-04 19:14:16 +02:00
$etpl = CreateObject ( 'etemplate.etemplate' , 'calendar.conflicts' );
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
foreach ( $conflicts as $k => $conflict )
{
$is_readable = $this -> bo -> check_perms ( EGW_ACL_READ , $conflict );
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
$conflicts [ $k ] += array (
'icon_participants' => $is_readable ? ( count ( $conflict [ 'participants' ]) > 1 ? 'users' : 'single' ) : 'private' ,
'tooltip_participants' => $is_readable ? implode ( ', ' , $this -> bo -> participants ( $conflict )) : '' ,
'time' => $this -> bo -> long_date ( $conflict [ 'start' ], $conflict [ 'end' ], true ),
'conflicting_participants' => implode ( " , \n " , $this -> bo -> participants ( array (
'participants' => array_intersect_key ( $conflict [ 'participants' ], $event [ 'participants' ]),
2006-03-16 19:03:43 +01:00
), true , true )), // show group invitations too
2005-11-09 00:15:14 +01:00
'icon_recur' => $conflict [ 'recur_type' ] != MCAL_RECUR_NONE ? 'recur' : '' ,
'text_recur' => $conflict [ 'recur_type' ] != MCAL_RECUR_NONE ? lang ( 'Recurring event' ) : ' ' ,
2008-05-08 00:12:25 +02:00
);
2005-11-09 00:15:14 +01:00
}
$content = $event + array (
'conflicts' => array_values ( $conflicts ), // conflicts have id-start as key
);
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'calendar' ) . ' - ' . lang ( 'Scheduling conflict' );
2010-06-09 20:00:11 +02:00
$etpl -> exec ( 'calendar.calendar_uiforms.process_edit' , $content , false , false , array_merge ( $event , $preserv ), $preserv [ 'no_popup' ] ? 0 : 2 );
}
2010-11-11 14:29:37 +01:00
2010-06-09 20:00:11 +02:00
/**
* displays a confirmation window for changed start dates of series events
*
* @ param array $event
* @ param array $preserv data to preserv
*/
function confirm_edit_series ( $event , $preserv )
{
$etpl = CreateObject ( 'etemplate.etemplate' , 'calendar.confirm_edit_series' );
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'calendar' ) . ' - ' . lang ( 'Start of Series Event Changed' );
2008-06-07 19:45:33 +02:00
$etpl -> exec ( 'calendar.calendar_uiforms.process_edit' , $content , false , false , array_merge ( $event , $preserv ), $preserv [ 'no_popup' ] ? 0 : 2 );
2004-10-08 00:11:18 +02:00
}
2009-04-29 16:17:46 +02:00
/**
* Callback for freetimesearch button in edit
*
* It stores the data of the submitted form in the session under 'freetimesearch_args_' . $edit_content [ 'id' ],
* for later retrival of the freetimesearch method , called by the returned window . open () command .
*
* @ param array $edit_content
* @ return string with xajaxResponse
*/
function ajax_freetimesearch ( array $edit_content )
{
$response = new xajaxResponse ();
2009-04-29 16:31:58 +02:00
//$response->addAlert(__METHOD__.'('.array2string($edit_content).')');
2009-04-29 16:17:46 +02:00
if ( $edit_content [ 'duration' ])
{
$edit_content [ 'end' ] = $edit_content [ 'start' ] + $edit_content [ 'duration' ];
}
if ( $edit_content [ 'whole_day' ])
{
$arr = $this -> bo -> date2array ( $edit_content [ 'start' ]);
$arr [ 'hour' ] = $arr [ 'minute' ] = $arr [ 'second' ] = 0 ; unset ( $arr [ 'raw' ]);
$edit_content [ 'start' ] = $this -> bo -> date2ts ( $arr );
$arr = $this -> bo -> date2array ( $edit_content [ 'end' ]);
$arr [ 'hour' ] = 23 ; $arr [ 'minute' ] = $arr [ 'second' ] = 59 ; unset ( $arr [ 'raw' ]);
$edit_content [ 'end' ] = $this -> bo -> date2ts ( $arr );
}
$content = array (
'start' => $edit_content [ 'start' ],
'duration' => $edit_content [ 'end' ] - $edit_content [ 'start' ],
'end' => $edit_content [ 'end' ],
'cal_id' => $edit_content [ 'id' ],
'recur_type' => $edit_content [ 'recur_type' ],
'participants' => array (),
);
foreach ( $edit_content [ 'participants' ] as $key => $data )
{
2010-04-16 12:19:29 +02:00
if ( is_numeric ( $key ) && ! $edit_content [ 'participants' ][ 'delete' ][ $data [ 'uid' ]] &&
! $edit_content [ 'participants' ][ 'delete' ][ md5 ( $data [ 'uid' ])])
2009-04-29 16:17:46 +02:00
{
$content [ 'participants' ][] = $data [ 'uid' ];
}
elseif ( $key == 'account' && ! is_array ( $data ) && $data )
{
$content [ 'participants' ][] = $data ;
}
}
// default search parameters
$content [ 'start_time' ] = $edit_content [ 'whole_day' ] ? 0 : $this -> cal_prefs [ 'workdaystarts' ];
$content [ 'end_time' ] = $this -> cal_prefs [ 'workdayends' ];
if ( $this -> cal_prefs [ 'workdayends' ] * HOUR_s < $this -> cal_prefs [ 'workdaystarts' ] * HOUR_s + $content [ 'duration' ])
{
$content [ 'end_time' ] = 0 ; // no end-time limit, as duration would never fit
}
$content [ 'weekdays' ] = MCAL_M_WEEKDAYS ;
$content [ 'search_window' ] = 7 * DAY_s ;
// store content in session
2009-04-29 16:31:58 +02:00
egw_cache :: setSession ( 'calendar' , 'freetimesearch_args_' . ( int ) $edit_content [ 'id' ], $content );
2009-04-29 16:17:46 +02:00
//menuaction=calendar.calendar_uiforms.freetimesearch&values2url('start,end,duration,participants,recur_type,whole_day'),ft_search,700,500
$link = egw :: link ( '/index.php' , array (
'menuaction' => 'calendar.calendar_uiforms.freetimesearch' ,
'cal_id' => $edit_content [ 'id' ],
));
$response -> addScriptCall ( 'egw_openWindowCentered2' , $link , 'ft_search' , 700 , 500 );
return $response -> getXML ();
}
2004-10-08 00:11:18 +02:00
/**
* Freetime search
*
* As the function is called in a popup via javascript , parametes get initialy transfered via the url
2005-11-09 00:15:14 +01:00
* @ param array $content = null array with parameters or false ( default ) to use the get - params
* @ param string start [ str ] start - date
* @ param string start [ hour ] start - hour
* @ param string start [ min ] start - minutes
* @ param string end [ str ] end - date
* @ param string end [ hour ] end - hour
* @ param string end [ min ] end - minutes
* @ param string participants ':' delimited string of user - id ' s
2004-10-08 00:11:18 +02:00
*/
2005-11-09 00:15:14 +01:00
function freetimesearch ( $content = null )
2004-10-08 00:11:18 +02:00
{
2009-04-29 16:17:46 +02:00
$etpl = new etemplate ( 'calendar.freetimesearch' );
2005-11-09 00:15:14 +01:00
2004-12-12 13:31:41 +01:00
$sel_options [ 'search_window' ] = array (
7 * DAY_s => lang ( 'one week' ),
14 * DAY_s => lang ( 'two weeks' ),
31 * DAY_s => lang ( 'one month' ),
92 * DAY_s => lang ( 'three month' ),
365 * DAY_s => lang ( 'one year' ),
);
2004-10-08 00:11:18 +02:00
if ( ! is_array ( $content ))
{
2009-04-29 16:17:46 +02:00
// get content from session (and delete it immediatly)
$content = egw_cache :: getSession ( 'calendar' , 'freetimesearch_args_' . ( int ) $_GET [ 'cal_id' ]);
egw_cache :: unsetSession ( 'calendar' , 'freetimesearch_args_' . ( int ) $_GET [ 'cal_id' ]);
2008-05-08 00:12:25 +02:00
2004-12-12 13:31:41 +01:00
// 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 )
{
2008-05-08 00:12:25 +02:00
if ( $window > $content [ 'duration' ])
2004-12-12 13:31:41 +01:00
{
$content [ 'search_window' ] = $window ;
break ;
}
}
2004-10-08 00:11:18 +02:00
}
else
{
2008-05-08 00:12:25 +02:00
if ( ! $content [ 'duration' ]) $content [ 'duration' ] = $content [ 'end' ] - $content [ 'start' ];
2004-10-08 00:11:18 +02:00
if ( is_array ( $content [ 'freetime' ][ 'select' ]))
{
list ( $selected ) = each ( $content [ 'freetime' ][ 'select' ]);
2004-10-11 12:43:26 +02:00
//echo "$selected = ".date('D d.m.Y H:i',$content['freetime'][$selected]['start']);
2004-10-08 00:11:18 +02:00
$start = ( int ) $content [ 'freetime' ][ $selected ][ 'start' ];
2004-12-12 13:31:41 +01:00
$end = $start + $content [ 'duration' ];
2005-11-09 00:15:14 +01:00
/**
* ToDo : make this an eTemplate function to transmit content back to the opener
*/
2004-10-08 00:11:18 +02:00
$fields_to_set = array (
2005-11-09 00:15:14 +01:00
'exec[start][str]' => date ( $this -> common_prefs [ 'dateformat' ], $start ),
'exec[start][i]' => ( int ) date ( 'i' , $start ),
'exec[end][str]' => date ( $this -> common_prefs [ 'dateformat' ], $end ),
'exec[end][i]' => ( int ) date ( 'i' , $end ),
2006-06-03 01:36:43 +02:00
'exec[duration]' => $content [ 'duration' ],
2004-10-08 00:11:18 +02:00
);
if ( $this -> common_prefs [ 'timeformat' ] == 12 )
{
$fields_to_set += array (
2005-11-09 00:15:14 +01:00
'exec[start][H]' => date ( 'h' , $start ),
'exec[start][a]' => date ( 'a' , $start ),
'exec[end][H]' => date ( 'h' , $end ),
'exec[end][a]' => date ( 'a' , $end ),
2004-10-08 00:11:18 +02:00
);
}
2008-05-08 00:12:25 +02:00
else
2004-10-08 00:11:18 +02:00
{
$fields_to_set += array (
2005-11-09 00:15:14 +01:00
'exec[start][H]' => ( int ) date ( 'H' , $start ),
'exec[end][H]' => ( int ) date ( 'H' , $end ),
2004-10-08 00:11:18 +02:00
);
}
echo " <html>
< script >
var fields = Array ( '".implode("' , '",array_keys($fields_to_set))."' );
var values = Array ( '".implode("' , '",$fields_to_set)."' );
for ( i = 0 ; i < fields . length ; ++ i ) {
elements = opener . document . getElementsByName ( fields [ i ]);
if ( elements ) {
if ( elements . length == 1 )
elements [ 0 ] . value = values [ i ];
else
for ( n = 0 ; n < elements . length ; ++ n ) {
if ( elements [ n ] . value == values [ i ]) elements [ n ] . checked = true ;
}
}
}
2008-05-08 00:12:25 +02:00
window . close ();
2004-10-08 00:11:18 +02:00
</ script >
</ html > \n " ;
exit ;
}
2004-10-08 18:04:50 +02:00
}
if ( $content [ 'recur_type' ])
{
$content [ 'msg' ] .= lang ( 'Only the initial date of that recuring event is checked!' );
}
2004-12-12 13:31:41 +01:00
$content [ 'freetime' ] = $this -> freetime ( $content [ 'participants' ], $content [ 'start' ], $content [ 'start' ] + $content [ 'search_window' ], $content [ 'duration' ], $content [ 'cal_id' ]);
$content [ 'freetime' ] = $this -> split_freetime_daywise ( $content [ 'freetime' ], $content [ 'duration' ], $content [ 'weekdays' ], $content [ 'start_time' ], $content [ 'end_time' ], $sel_options );
2004-10-08 00:11:18 +02:00
//echo "<pre>".print_r($content,true)."</pre>\n";
2005-11-09 00:15:14 +01:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'calendar' ) . ' - ' . lang ( 'freetime search' );
2004-10-08 18:04:50 +02:00
// let the window popup, if its already there
2005-11-09 00:15:14 +01:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'java_script' ] .= " <script> \n window.focus(); \n </script> \n " ;
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
if ( ! is_object ( $GLOBALS [ 'egw' ] -> js ))
{
$GLOBALS [ 'egw' ] -> js = CreateObject ( 'phpgwapi.javascript' );
}
2006-06-03 01:36:43 +02:00
$sel_options [ 'duration' ] = $this -> durations ;
if ( $content [ 'duration' ] && isset ( $sel_options [ 'duration' ][ $content [ 'duration' ]])) $content [ 'end' ] = '' ;
2005-11-09 00:15:14 +01:00
// 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
2006-06-03 01:36:43 +02:00
$GLOBALS [ 'egw' ] -> js -> set_onload ( " set_style_by_class('table','end_hide','visibility',' " . ( $content [ 'duration' ] && isset ( $sel_options [ 'duration' ][ $content [ 'duration' ]]) ? 'hidden' : 'visible' ) . " '); " );
2004-10-08 00:11:18 +02:00
2008-06-07 19:45:33 +02:00
$etpl -> exec ( 'calendar.calendar_uiforms.freetimesearch' , $content , $sel_options , '' , array (
2004-10-08 00:11:18 +02:00
'participants' => $content [ 'participants' ],
2004-10-08 18:04:50 +02:00
'cal_id' => $content [ 'cal_id' ],
'recur_type' => $content [ 'recur_type' ],
2008-05-08 00:12:25 +02:00
), 2 );
2004-10-08 00:11:18 +02:00
}
2008-05-08 00:12:25 +02:00
2004-10-08 00:11:18 +02:00
/**
* calculate the freetime of given $participants in a certain time - span
*
2005-11-09 00:15:14 +01:00
* @ param array $participants user - id ' s
* @ param int $start start - time timestamp in user - time
* @ param int $end end - time timestamp in user - time
* @ param int $duration min . duration in sec , default 1
* @ param int $cal_id own id for existing events , to exclude them from being busy - time , default 0
2004-10-08 00:11:18 +02:00
* @ return array of free time - slots : array with start and end values
*/
2004-10-08 18:04:50 +02:00
function freetime ( $participants , $start , $end , $duration = 1 , $cal_id = 0 )
2004-10-08 00:11:18 +02:00
{
2004-12-12 13:31:41 +01:00
if ( $this -> debug > 2 ) $this -> bo -> debug_message ( 'uiforms::freetime(participants=%1, start=%2, end=%3, duration=%4, cal_id=%5)' , true , $participants , $start , $end , $duration , $cal_id );
2004-10-08 00:11:18 +02:00
$busy = $this -> bo -> search ( array (
'start' => $start ,
'end' => $end ,
'users' => $participants ,
2006-03-16 19:03:43 +01:00
'ignore_acl' => true , // otherwise we get only events readable by the user
2004-10-08 00:11:18 +02:00
));
$busy [] = array ( // add end-of-search-date as event, to cope with empty search and get freetime til that date
2005-11-09 00:15:14 +01:00
'start' => $end ,
'end' => $end ,
2008-05-08 00:12:25 +02:00
);
2004-10-08 00:11:18 +02:00
$ft_start = $start ;
$freetime = array ();
$n = 0 ;
foreach ( $busy as $event )
{
2004-10-08 18:04:50 +02:00
if (( int ) $cal_id && $event [ 'id' ] == ( int ) $cal_id ) continue ; // ignore our own event
2006-03-08 11:23:44 +01:00
if ( $event [ 'non_blocking' ]) continue ; // ignore non_blocking events
2004-10-08 00:11:18 +02:00
if ( $this -> debug )
{
echo " <p>ft_start= " . date ( 'D d.m.Y H:i' , $ft_start ) . " <br> \n " ;
echo " event[title]= $event[title] <br> \n " ;
2008-10-10 12:24:31 +02:00
echo " event[start]= " . date ( 'D d.m.Y H:i' , $event [ 'start' ]) . " <br> \n " ;
echo " event[end]= " . date ( 'D d.m.Y H:i' , $event [ 'end' ]) . " <br> \n " ;
2004-10-08 00:11:18 +02:00
}
// $events ends before our actual position ==> ignore it
2005-11-09 00:15:14 +01:00
if ( $event [ 'end' ] < $ft_start )
2004-10-08 00:11:18 +02:00
{
//echo "==> event ends before ft_start ==> continue<br>\n";
continue ;
}
// $events starts before our actual position ==> set start to it's end and go to next event
2005-11-09 00:15:14 +01:00
if ( $event [ 'start' ] < $ft_start )
2004-10-08 00:11:18 +02:00
{
//echo "==> event starts before ft_start ==> set ft_start to it's end & continue<br>\n";
2005-11-09 00:15:14 +01:00
$ft_start = $event [ 'end' ];
2004-10-08 00:11:18 +02:00
continue ;
}
2005-11-09 00:15:14 +01:00
$ft_end = $event [ 'start' ];
2004-10-08 00:11:18 +02:00
// only show slots equal or bigger to min_length
if ( $ft_end - $ft_start >= $duration )
{
$freetime [ ++ $n ] = array (
'start' => $ft_start ,
'end' => $ft_end ,
);
2004-12-12 13:31:41 +01:00
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 " ;
2008-05-08 00:12:25 +02:00
}
2005-11-09 00:15:14 +01:00
$ft_start = $event [ 'end' ];
2004-10-08 00:11:18 +02:00
}
2004-12-12 13:31:41 +01:00
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 );
2008-05-08 00:12:25 +02:00
2004-10-08 00:11:18 +02:00
return $freetime ;
}
2008-05-08 00:12:25 +02:00
2004-10-08 00:11:18 +02:00
/**
* split the freetime in daywise slot , taking into account weekdays , start - and stop - times
*
2004-12-12 13:31:41 +01:00
* If the duration is bigger then the difference of start - and end_time , the end_time is ignored
*
2005-11-09 00:15:14 +01:00
* @ param array $freetime free time - slots : array with start and end values
* @ param int $duration min . duration in sec
* @ param int $weekdays allowed weekdays , bitfield of MCAL_M_ ...
* @ param int $start_time minimum start - hour 0 - 23
* @ param int $end_time maximum end - hour 0 - 23 , or 0 for none
* @ param array $sel_options on return options for start - time selectbox
2004-10-08 00:11:18 +02:00
* @ return array of free time - slots : array with start and end values
*/
function split_freetime_daywise ( $freetime , $duration , $weekdays , $start_time , $end_time , & $sel_options )
{
2004-12-12 13:31:41 +01:00
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 );
2008-05-08 00:12:25 +02:00
2004-12-12 13:31:41 +01:00
$freetime_daywise = array ();
if ( ! is_array ( $sel_options )) $sel_options = array ();
2004-10-08 00:11:18 +02:00
$time_format = $this -> common_prefs [ 'timeformat' ] == 12 ? 'h:i a' : 'H:i' ;
2008-05-08 00:12:25 +02:00
2004-12-12 13:31:41 +01:00
$start_time = ( int ) $start_time ; // ignore leading zeros
$end_time = ( int ) $end_time ;
2004-10-08 00:11:18 +02:00
2004-12-12 13:31:41 +01:00
// ignore the end_time, if duration would never fit
2008-05-08 00:12:25 +02:00
if (( $end_time - $start_time ) * HOUR_s < $duration )
2004-12-12 13:31:41 +01:00
{
2008-05-08 00:12:25 +02:00
$end_time = 0 ;
2004-12-12 13:31:41 +01:00
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 );
}
2004-10-08 00:11:18 +02:00
$n = 0 ;
foreach ( $freetime as $ft )
{
$daybegin = $this -> bo -> date2array ( $ft [ 'start' ]);
$daybegin [ 'hour' ] = $daybegin [ 'minute' ] = $daybegin [ 'second' ] = 0 ;
unset ( $daybegin [ 'raw' ]);
$daybegin = $this -> bo -> date2ts ( $daybegin );
2008-05-08 00:12:25 +02:00
2004-10-08 00:11:18 +02:00
for ( $t = $daybegin ; $t < $ft [ 'end' ]; $t += DAY_s , $daybegin += DAY_s )
{
$dow = date ( 'w' , $daybegin + DAY_s / 2 ); // 0=Sun, .., 6=Sat
$mcal_dow = pow ( 2 , $dow );
if ( ! ( $weekdays & $mcal_dow ))
{
2004-12-12 13:31:41 +01:00
//echo "wrong day of week $dow<br>\n";
2004-10-08 00:11:18 +02:00
continue ; // wrong day of week
}
$start = $t < $ft [ 'start' ] ? $ft [ 'start' ] : $t ;
2008-05-08 00:12:25 +02:00
2004-10-08 00:11:18 +02:00
if ( $start - $daybegin < $start_time * HOUR_s ) // start earlier then start_time
{
$start = $daybegin + $start_time * HOUR_s ;
}
// if end_time given use it, else the original slot's end
$end = $end_time ? $daybegin + $end_time * HOUR_s : $ft [ 'end' ];
if ( $end > $ft [ 'end' ]) $end = $ft [ 'end' ];
// slot to small for duration
if ( $end - $start < $duration )
{
2004-12-12 13:31:41 +01:00
//echo "slot to small for duration=$duration<br>\n";
2004-10-08 00:11:18 +02:00
continue ;
}
$freetime_daywise [ ++ $n ] = array (
'start' => $start ,
'end' => $end ,
);
$times = array ();
2004-12-12 13:31:41 +01:00
for ( $s = $start ; $s + $duration <= $end && $s < $daybegin + DAY_s ; $s += 60 * $this -> cal_prefs [ 'interval' ])
2004-10-08 00:11:18 +02:00
{
$e = $s + $duration ;
$end_date = $e - $daybegin > DAY_s ? lang ( date ( 'l' , $e )) . ' ' . date ( $this -> common_prefs [ 'dateformat' ], $e ) . ' ' : '' ;
$times [ $s ] = date ( $time_format , $s ) . ' - ' . $end_date . date ( $time_format , $e );
}
$sel_options [ $n . '[start]' ] = $times ;
}
}
return $freetime_daywise ;
}
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
/**
* Export events as vCalendar version 2.0 files ( iCal )
*
2009-08-04 19:14:16 +02:00
* @ param int | array $content = 0 numeric cal_id or submitted content from etempalte :: exec
2005-11-09 00:15:14 +01:00
* @ param boolean $return_error = false should an error - msg be returned or a regular page with it generated ( default )
* @ return string error - msg if $return_error
*/
function export ( $content = 0 , $return_error = false )
{
2009-02-25 11:55:38 +01:00
$boical = new calendar_ical ();
#error_log(__METHOD__.print_r($content,true));
2005-11-09 00:15:14 +01:00
if ( is_numeric ( $cal_id = $content ? $content : $_REQUEST [ 'cal_id' ]))
{
2009-02-25 11:55:38 +01:00
if ( ! ( $ical =& $boical -> exportVCal ( array ( $cal_id ), '2.0' , 'PUBLISH' , false )))
2005-11-09 00:15:14 +01:00
{
$msg = lang ( 'Permission denied' );
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
if ( $return_error ) return $msg ;
}
else
{
2009-10-12 21:16:42 +02:00
html :: content_header ( 'event.ics' , 'text/calendar' , bytes ( $ical ));
2005-11-09 00:15:14 +01:00
echo $ical ;
2009-10-12 21:16:42 +02:00
common :: egw_exit ();
2005-11-09 00:15:14 +01:00
}
}
if ( is_array ( $content ))
{
$events =& $this -> bo -> search ( array (
'start' => $content [ 'start' ],
'end' => $content [ 'end' ],
'enum_recuring' => false ,
'daywise' => false ,
'owner' => $this -> owner ,
'date_format' => 'server' , // timestamp in server time for boical class
));
if ( ! $events )
{
$msg = lang ( 'No events found' );
}
else
{
2009-02-25 11:55:38 +01:00
$ical =& $boical -> exportVCal ( $events , '2.0' , 'PUBLISH' , false );
2009-10-12 21:16:42 +02:00
html :: content_header ( $content [ 'file' ] ? $content [ 'file' ] : 'event.ics' , 'text/calendar' , bytes ( $ical ));
2005-11-09 00:15:14 +01:00
echo $ical ;
2009-10-12 21:16:42 +02:00
common :: egw_exit ();
2005-11-09 00:15:14 +01:00
}
}
if ( ! is_array ( $content ))
{
$view = $GLOBALS [ 'egw' ] -> session -> appsession ( 'view' , 'calendar' );
$content = array (
'start' => $this -> bo -> date2ts ( $_REQUEST [ 'start' ] ? $_REQUEST [ 'start' ] : $this -> date ),
'end' => $this -> bo -> date2ts ( $_REQUEST [ 'end' ] ? $_REQUEST [ 'end' ] : $this -> date ),
'file' => 'event.ics' ,
'version' => '2.0' ,
);
}
$content [ 'msg' ] = $msg ;
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'calendar' ) . ' - ' . lang ( 'iCal Export' );
2009-10-12 21:16:42 +02:00
$etpl = new etemplate ( 'calendar.export' );
2008-06-07 19:45:33 +02:00
$etpl -> exec ( 'calendar.calendar_uiforms.export' , $content );
2005-11-09 00:15:14 +01:00
}
2008-05-08 00:12:25 +02:00
2005-11-09 00:15:14 +01:00
/**
* Import events as vCalendar version 2.0 files ( iCal )
*
* @ param array $content = null submitted content from etempalte :: exec
*/
function import ( $content = null )
{
if ( is_array ( $content ))
{
if ( is_array ( $content [ 'ical_file' ]) && is_uploaded_file ( $content [ 'ical_file' ][ 'tmp_name' ]))
{
2010-04-14 12:19:41 +02:00
@ set_time_limit ( 0 ); // try switching execution time limit off
$start = microtime ( true );
$calendar_ical = new calendar_ical ;
2010-05-21 08:18:52 +02:00
$calendar_ical -> setSupportedFields ( 'file' , '' );
2010-04-14 12:19:41 +02:00
if ( ! $calendar_ical -> importVCal ( $f = fopen ( $content [ 'ical_file' ][ 'tmp_name' ], 'r' )))
2005-11-09 00:15:14 +01:00
{
$msg = lang ( 'Error: importing the iCal' );
}
else
{
2010-04-14 12:19:41 +02:00
$msg = lang ( 'iCal successful imported' ) . ' ' . lang ( '(%1 events in %2 seconds)' ,
$calendar_ical -> events_imported , number_format ( microtime ( true ) - $start , 1 ));
2005-11-09 00:15:14 +01:00
}
2010-04-14 12:19:41 +02:00
if ( $f ) fclose ( $f );
2005-11-09 00:15:14 +01:00
}
else
{
$msg = lang ( 'You need to select an iCal file first' );
}
}
$content = array (
'msg' => $msg ,
);
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'calendar' ) . ' - ' . lang ( 'iCal Import' );
2010-04-14 12:19:41 +02:00
$etpl = new etemplate ( 'calendar.import' );
2008-05-08 00:12:25 +02:00
2008-06-07 19:45:33 +02:00
$etpl -> exec ( 'calendar.calendar_uiforms.import' , $content );
2005-11-09 00:15:14 +01:00
}
2009-12-03 19:24:19 +01:00
/**
* Edit category ACL ( admin only )
*
* @ param array $content = null
*/
function cat_acl ( array $content = null )
{
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ])
{
throw new egw_exception_no_permission_admin ();
}
if ( $content )
{
list ( $button ) = each ( $content [ 'button' ]);
unset ( $content [ 'button' ]);
if ( $button != 'cancel' ) // store changed acl
{
foreach ( $content [ 'rows' ] as $data )
{
if ( ! ( $cat_id = $data [ 'cat_id' ])) continue ;
foreach ( array_merge (( array ) $data [ 'add' ],( array ) $data [ 'status' ], array_keys (( array ) $data [ 'old' ])) as $account_id )
{
$rights = 0 ;
if ( in_array ( $account_id ,( array ) $data [ 'add' ])) $rights |= calendar_boupdate :: CAT_ACL_ADD ;
if ( in_array ( $account_id ,( array ) $data [ 'status' ])) $rights |= calendar_boupdate :: CAT_ACL_STATUS ;
if ( $account_id ) $this -> bo -> set_cat_rights ( $cat_id , $account_id , $rights );
}
}
}
if ( $button != 'apply' ) // end dialog
{
egw :: redirect_link ( '/index.php' , array ( 'menuaction' => $this -> view_menuaction ));
}
}
$content [ 'rows' ] = $preserv [ 'rows' ] = array ();
$n = 1 ;
foreach ( $this -> bo -> get_cat_rights () as $Lcat_id => $data )
{
$cat_id = ( int ) substr ( $Lcat_id , 1 );
$row = array (
'cat_id' => $cat_id ,
'add' => array (),
'status' => array (),
);
foreach ( $data as $account_id => $rights )
{
if ( $rights & calendar_boupdate :: CAT_ACL_ADD ) $row [ 'add' ][] = $account_id ;
if ( $rights & calendar_boupdate :: CAT_ACL_STATUS ) $row [ 'status' ][] = $account_id ;
}
$content [ 'rows' ][ $n ] = $row ;
$preserv [ 'rows' ][ $n ] = array (
'cat_id' => $cat_id ,
'old' => $data ,
);
$readonlys [ $n . '[cat_id]' ] = true ;
++ $n ;
}
// add empty row for new entries
$content [ 'rows' ][] = array ( 'cat_id' => '' );
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'Calendar' ) . ' - ' . lang ( 'Category ACL' );
$tmp = new etemplate ( 'calendar.cat_acl' );
$tmp -> exec ( 'calendar.calendar_uiforms.cat_acl' , $content , null , $readonlys , $preserv );
}
2010-02-12 21:18:45 +01:00
/**
* Set up the required fields to get the history tab
*/
2011-04-08 16:21:23 +02:00
public function setup_history ( & $content , & $sel_options )
{
2010-02-12 21:18:45 +01:00
$status = 'history_status' ;
$content [ 'history' ] = array (
'id' => $content [ 'id' ],
'app' => 'calendar' ,
2011-08-04 16:00:15 +02:00
'status-widgets' => array (
'owner' => 'select-account' ,
'creator' => 'select-account' ,
'category' => 'select-cat' ,
'non_blocking' => array ( '' => lang ( 'No' ), 1 => lang ( 'Yes' )),
'public' => array ( '' => lang ( 'No' ), 1 => lang ( 'Yes' )),
2010-02-24 16:05:00 +01:00
2011-08-04 16:00:15 +02:00
'start' => 'date-time' ,
'end' => 'date-time' ,
'tz_id' => 'select-timezone' ,
2010-02-12 21:18:45 +01:00
// Participants
'participants' => array (
'select-account' ,
$sel_options [ 'status' ],
$sel_options [ 'role' ]
),
'participants-c' => array (
'link:addressbook' ,
$sel_options [ 'status' ],
'label' ,
$sel_options [ 'role' ]
),
2011-08-04 16:00:15 +02:00
'participants-r' => array (
'link:resources' ,
$sel_options [ 'status' ],
'label' ,
$sel_options [ 'role' ]
),
2010-02-12 21:18:45 +01:00
),
);
// Get participants for only this one, if it's recurring. The date is on the end of the value.
2011-08-04 16:00:15 +02:00
if ( $content [ 'recur_type' ] || $content [ 'recurrence' ])
{
2010-02-12 21:18:45 +01:00
$content [ 'history' ][ 'filter' ] = array (
' ( history_status NOT LIKE \ ' participants % \ ' OR ( history_status LIKE \ ' participants % \ ' AND (
2010-02-24 16:05:00 +01:00
history_new_value LIKE \ '%' . bo_tracking :: ONE2N_SEPERATOR . $content [ 'recurrence' ] . ' \ ' OR
2010-02-12 21:18:45 +01:00
history_old_value LIKE \ '%' . bo_tracking :: ONE2N_SEPERATOR . $content [ 'recurrence' ] . '\')))'
);
}
2010-02-24 16:05:00 +01:00
2010-02-12 21:18:45 +01:00
// Translate labels
$tracking = new calendar_tracking ();
2011-08-04 16:00:15 +02:00
foreach ( $tracking -> field2label as $field => $label )
{
2010-02-12 21:18:45 +01:00
$sel_options [ $status ][ $field ] = lang ( $label );
}
2011-04-20 08:22:29 +02:00
// custom fields are now "understood" directly by historylog widget
2010-02-12 21:18:45 +01:00
}
2004-10-08 00:11:18 +02:00
}