2004-08-01 17:36:04 +02:00
< ? php
2007-03-09 12:39:47 +01:00
/**
* eGroupWare - Calendar ' s shared base - class of all UI classes
*
* @ link http :// www . egroupware . org
* @ package calendar
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de >
2015-01-19 20:32:26 +01:00
* @ copyright ( c ) 2004 - 15 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-08-01 17:36:04 +02:00
/**
2005-11-09 00:15:14 +01:00
* Shared base - class of all calendar UserInterface classes
2004-08-01 17:36:04 +02:00
*
* It manages eg . the state of the controls in the UI and generated the calendar navigation ( sidebox - menu )
*
2005-11-09 00:15:14 +01:00
* 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
*
* All permanent debug messages of the calendar - code should done via the debug - message method of the bocal class ! ! !
2004-08-01 17:36:04 +02:00
*/
2008-06-07 19:45:33 +02:00
class calendar_ui
2004-08-01 17:36:04 +02:00
{
/**
* @ var $debug mixed integer level or string function - name
*/
2005-11-09 00:15:14 +01:00
var $debug = false ;
2004-08-01 17:36:04 +02:00
/**
2006-08-22 18:50:45 +02:00
* instance of the bocal or bocalupdate class
2008-05-08 17:02:35 +02:00
*
2008-06-07 19:45:33 +02:00
* @ var calendar_boupdate
2004-08-01 17:36:04 +02:00
*/
2006-08-22 18:50:45 +02:00
var $bo ;
/**
* instance of jscalendar
*
* @ var jscalendar
*/
var $jscal ;
/**
* Reference to global datetime class
*
2011-01-05 22:49:55 +01:00
* @ var egw_datetime
2006-08-22 18:50:45 +02:00
*/
var $datetime ;
/**
2009-11-25 13:58:09 +01:00
* Instance of categories class
2006-08-22 18:50:45 +02:00
*
* @ var categories
*/
2009-11-25 13:58:09 +01:00
var $categories ;
2006-08-22 18:50:45 +02:00
/**
* Reference to global uiaccountsel class
*
* @ var uiaccountsel
*/
var $accountsel ;
2005-11-09 00:15:14 +01:00
/**
* @ var array $common_prefs reference to $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ]
*/
var $common_prefs ;
/**
* @ var array $cal_prefs reference to $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'calendar' ]
*/
var $cal_prefs ;
/**
* @ var int $wd_start user pref . workday start
*/
var $wd_start ;
/**
* @ var int $wd_start user pref . workday end
*/
var $wd_end ;
/**
* @ var int $interval_m user pref . interval
*/
var $interval_m ;
/**
* @ var int $user account_id of loged in user
*/
var $user ;
/**
* @ var string $date session - state : date ( Ymd ) of shown view
*/
var $date ;
/**
* @ var int $cat_it session - state : selected category
*/
var $cat_id ;
/**
2015-12-16 20:54:22 +01:00
* @ var int $status_filter session - state : selected filter , at the moment all or hideprivate
2005-11-09 00:15:14 +01:00
*/
2015-12-16 20:54:22 +01:00
var $status_filter ;
2005-11-09 00:15:14 +01:00
/**
* @ var int / array $owner session - state : selected owner ( s ) of shown calendar ( s )
*/
var $owner ;
/**
* @ var string $sortby session - state : filter of planner : 'category' or 'user'
*/
var $sortby ;
/**
* @ var string $view session - state : selected view
*/
var $view ;
/**
* @ var string $view menuaction of the selected view
*/
var $view_menuaction ;
2015-01-19 20:32:26 +01:00
/**
* @ var boolean test checkbox checked
*/
var $test ;
2008-05-08 17:02:35 +02:00
2005-11-09 00:15:14 +01:00
/**
* @ var int $first first day of the shown view
*/
var $first ;
/**
* @ var int $last last day of the shown view
*/
var $last ;
2009-04-20 17:44:24 +02:00
2008-10-07 10:57:09 +02:00
/**
* @ var array $states_to_save all states that will be saved to the user prefs
*/
2015-12-16 20:54:22 +01:00
var $states_to_save = array ( 'owner' , 'status_filter' , 'filter' , 'cat_id' , 'view' , 'sortby' , 'planner_days' , 'weekend' );
2004-08-01 17:36:04 +02:00
/**
* Constructor
2005-11-09 00:15:14 +01:00
*
2008-06-07 19:45:33 +02:00
* @ param boolean $use_boupdate use bocalupdate as parenent instead of bocal
2014-05-23 12:24:05 +02:00
* @ param array $set_states to manualy set / change one of the states , default NULL = use $_REQUEST
2004-08-01 17:36:04 +02:00
*/
2008-06-07 19:45:33 +02:00
function __construct ( $use_boupdate = false , $set_states = NULL )
2004-08-01 17:36:04 +02:00
{
2008-06-07 19:45:33 +02:00
if ( $use_boupdate )
{
$this -> bo = new calendar_boupdate ();
}
else
{
$this -> bo = new calendar_bo ();
}
2008-03-21 21:30:19 +01:00
$this -> jscal = $GLOBALS [ 'egw' ] -> jscalendar ;
$this -> datetime = $GLOBALS [ 'egw' ] -> datetime ;
$this -> accountsel = $GLOBALS [ 'egw' ] -> uiaccountsel ;
2009-11-25 13:58:09 +01:00
$this -> categories = new categories ( $this -> user , 'calendar' );
2010-02-17 14:29:28 +01:00
2005-11-09 00:15:14 +01:00
$this -> common_prefs = & $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ];
$this -> cal_prefs = & $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'calendar' ];
2007-04-26 17:29:15 +02:00
$this -> bo -> check_set_default_prefs ();
2005-11-09 00:15:14 +01:00
$this -> wd_start = 60 * $this -> cal_prefs [ 'workdaystarts' ];
$this -> wd_end = 60 * $this -> cal_prefs [ 'workdayends' ];
$this -> interval_m = $this -> cal_prefs [ 'interval' ];
2004-08-01 17:36:04 +02:00
2005-11-09 00:15:14 +01:00
$this -> user = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2004-08-01 17:36:04 +02:00
2005-11-09 00:15:14 +01:00
$this -> manage_states ( $set_states );
2004-08-01 17:36:04 +02:00
$GLOBALS [ 'uical' ] = & $this ; // make us available for ExecMethod, else it creates a new instance
2008-05-08 17:02:35 +02:00
2004-08-01 17:36:04 +02:00
// calendar does not work with hidden sidebox atm.
2005-11-09 00:15:14 +01:00
unset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'auto_hide_sidebox' ]);
2011-09-14 15:09:13 +02:00
2011-09-15 16:46:56 +02:00
// make sure the hook for export_limit is registered
2011-09-15 18:53:20 +02:00
if ( ! $GLOBALS [ 'egw' ] -> hooks -> hook_exists ( 'export_limit' , 'calendar' )) $GLOBALS [ 'egw' ] -> hooks -> register_single_app_hook ( 'calendar' , 'export_limit' );
2004-08-01 17:36:04 +02:00
}
2008-05-08 17:02:35 +02:00
2006-03-03 19:51:46 +01:00
/**
2006-03-04 10:54:31 +01:00
* Checks and terminates ( or returns for home ) with a message if $this -> owner include a user / resource we have no read - access to
*
* If currentapp == 'home' we return the error instead of terminating with it !!!
*
* @ return boolean / string false if there ' s no error or string with error - message
2006-03-03 19:51:46 +01:00
*/
2015-11-11 00:31:55 +01:00
function check_owners_access ( $users = null , & $no_access = array ())
2006-03-03 19:51:46 +01:00
{
2006-03-04 10:54:31 +01:00
$no_access = $no_access_group = array ();
2015-11-11 00:31:55 +01:00
$owner_array = $users ? $users : explode ( ',' , $this -> owner );
2015-09-09 23:35:26 +02:00
foreach ( $owner_array as $idx => $owner )
2006-03-03 19:51:46 +01:00
{
2009-12-04 11:22:33 +01:00
$owner = trim ( $owner );
2006-03-04 10:54:31 +01:00
if ( is_numeric ( $owner ) && $GLOBALS [ 'egw' ] -> accounts -> get_type ( $owner ) == 'g' )
{
foreach ( $GLOBALS [ 'egw' ] -> accounts -> member ( $owner ) as $member )
{
$member = $member [ 'account_id' ];
2009-06-09 14:16:15 +02:00
if ( ! $this -> bo -> check_perms ( EGW_ACL_READ | EGW_ACL_READ_FOR_PARTICIPANTS | EGW_ACL_FREEBUSY , 0 , $member ))
2006-03-04 10:54:31 +01:00
{
$no_access_group [ $member ] = $this -> bo -> participant_name ( $member );
2008-05-08 17:02:35 +02:00
}
2006-03-04 10:54:31 +01:00
}
}
2009-06-09 14:16:15 +02:00
elseif ( ! $this -> bo -> check_perms ( EGW_ACL_READ | EGW_ACL_READ_FOR_PARTICIPANTS | EGW_ACL_FREEBUSY , 0 , $owner ))
2006-03-03 19:51:46 +01:00
{
$no_access [ $owner ] = $this -> bo -> participant_name ( $owner );
2015-09-09 23:35:26 +02:00
unset ( $owner_array [ $idx ]);
2006-03-03 19:51:46 +01:00
}
}
if ( count ( $no_access ))
{
2015-11-11 00:31:55 +01:00
$message = lang ( 'Access denied to the calendar of %1 !!!' , implode ( ', ' , $no_access ));
egw_framework :: message ( $message , 'error' );
2015-09-09 23:35:26 +02:00
$this -> owner = implode ( ',' , $owner_array );
2015-11-11 00:31:55 +01:00
return $message ;
2006-03-03 19:51:46 +01:00
}
2006-03-04 10:54:31 +01:00
if ( count ( $no_access_group ))
{
2011-06-14 20:33:26 +02:00
$this -> bo -> warnings [ 'groupmembers' ] = lang ( 'Groupmember(s) %1 not included, because you have no access.' , implode ( ', ' , $no_access_group ));
2006-03-04 10:54:31 +01:00
}
return false ;
}
2008-05-08 17:02:35 +02:00
2006-03-04 10:54:31 +01:00
/**
2014-01-21 16:01:06 +01:00
* show the egw - framework plus evtl . $this -> group_warning from check_owner_access
2006-03-04 10:54:31 +01:00
*/
function do_header ()
{
2013-11-05 19:08:07 +01:00
// Include the jQuery-UI CSS - many more complex widgets use it
$theme = 'redmond' ;
egw_framework :: includeCSS ( " /phpgwapi/js/jquery/jquery-ui/ $theme /jquery-ui-1.10.3.custom.css " );
// Load our CSS after jQuery-UI, so we can override it
egw_framework :: includeCSS ( '/etemplate/templates/default/etemplate2.css' );
// load etemplate2
egw_framework :: validate_file ( '/etemplate/js/etemplate2.js' );
// load our app.js file
egw_framework :: validate_file ( '/calendar/js/app.js' );
2011-06-14 20:33:26 +02:00
common :: egw_header ();
2008-05-08 17:02:35 +02:00
2014-07-16 14:18:04 +02:00
if ( $this -> bo -> warnings ) echo '<pre class="message" align="center">' . html :: htmlspecialchars ( implode ( " \n " , $this -> bo -> warnings )) . " </pre> \n " ;
2006-03-03 19:51:46 +01:00
}
2004-08-01 17:36:04 +02:00
/**
* Manages the states of certain controls in the UI : date shown , category selected , ...
*
* The state of all these controls is updated if they are set in $_REQUEST or $set_states and saved in the session .
* The following states are used :
* - date or year , month , day : the actual date of the period displayed
* - cat_id : the selected category
* - owner : the owner of the displayed calendar
* - save_owner : the overriden owner of the planner
2015-12-16 20:54:22 +01:00
* - status_filter : the used filter : all or hideprivate
2004-08-01 17:36:04 +02:00
* - sortby : category or user of planner
2005-11-09 00:15:14 +01:00
* - view : the actual view , where dialogs should return to or which they refresh
2009-08-04 19:14:16 +02:00
* @ param array $set_states array to manualy set / change one of the states , default NULL = use $_REQUEST
2004-08-01 17:36:04 +02:00
*/
function manage_states ( $set_states = NULL )
{
2008-10-07 10:57:09 +02:00
// retrieve saved states from prefs
2015-09-09 22:59:23 +02:00
$states = is_array ( $this -> bo -> cal_prefs [ 'saved_states' ]) ?
$this -> bo -> cal_prefs [ 'saved_states' ] : unserialize ( $this -> bo -> cal_prefs [ 'saved_states' ]);
2015-10-05 11:38:25 +02:00
2009-04-20 17:44:24 +02:00
// only look at _REQUEST, if we are in the calendar (prefs and admin show our sidebox menu too!)
2004-08-01 17:36:04 +02:00
if ( is_null ( $set_states ))
{
2013-12-12 04:42:08 +01:00
// ajax-exec call has get-parameter in some json
if ( isset ( $_REQUEST [ 'json_data' ]) && ( $json_data = json_decode ( $_REQUEST [ 'json_data' ], true )) &&
! empty ( $json_data [ 'request' ][ 'parameters' ][ 0 ]))
{
2014-03-20 17:10:52 +01:00
if ( is_array ( $json_data [ 'request' ][ 'parameters' ][ 0 ]))
{
//error_log(__METHOD__.__LINE__.array2string($json_data['request']['parameters'][0]));
$set_states = $json_data [ 'request' ][ 'parameters' ][ 0 ];
}
else
{
parse_str ( substr ( $json_data [ 'request' ][ 'parameters' ][ 0 ], 10 ), $set_states ); // cut off "/index.php?"
}
2013-12-12 04:42:08 +01:00
}
else
{
$set_states = substr ( $_GET [ 'menuaction' ], 0 , 9 ) == 'calendar.' ? $_REQUEST : array ();
}
2004-08-01 17:36:04 +02:00
}
if ( ! $states [ 'date' ] && $states [ 'year' ] && $states [ 'month' ] && $states [ 'day' ])
{
$states [ 'date' ] = $this -> bo -> date2string ( $states );
}
foreach ( array (
'date' => $this -> bo -> date2string ( $this -> bo -> now_su ),
'cat_id' => 0 ,
2015-12-16 20:54:22 +01:00
'status_filter' => 'default' ,
2004-08-01 17:36:04 +02:00
'owner' => $this -> user ,
'save_owner' => 0 ,
'sortby' => 'category' ,
2005-11-09 00:15:14 +01:00
'planner_days' => 0 , // full month
2010-10-12 11:49:17 +02:00
'view' => ( $this -> bo -> cal_prefs [ 'defaultcalendar' ] ? $this -> bo -> cal_prefs [ 'defaultcalendar' ] : 'day' ), // use pref, if exists else use the dayview
2007-03-09 12:39:47 +01:00
'listview_days' => '' , // no range
2015-01-19 20:32:26 +01:00
'test' => 'false' ,
2004-08-01 17:36:04 +02:00
) as $state => $default )
{
if ( isset ( $set_states [ $state ]))
{
2006-03-06 08:11:39 +01:00
if ( $state == 'owner' )
{
// only change the owners of the same resource-type as given in set_state[owner]
2015-11-23 19:01:21 +01:00
$set_owners = is_array ( $set_states [ 'owner' ]) ? $set_states [ 'owner' ] : explode ( ',' , $set_states [ 'owner' ]);
2006-09-25 10:50:02 +02:00
if (( string ) $set_owners [ 0 ] === '0' ) // set exactly the specified owners (without the 0)
2006-03-06 08:11:39 +01:00
{
2012-01-07 23:21:48 +01:00
if ( $set_states [ 'owner' ] === '0,r0' ) // small fix for resources
{
$set_states [ 'owner' ] = $default ; // --> set default, instead of none
}
else
{
$set_states [ 'owner' ] = substr ( $set_states [ 'owner' ], 2 );
}
2006-03-06 08:11:39 +01:00
}
2006-09-25 10:50:02 +02:00
else // change only the owners of the given type
2006-03-06 08:11:39 +01:00
{
2008-05-08 17:02:35 +02:00
$res_type = is_numeric ( $set_owners [ 0 ]) ? false : $set_owners [ 0 ][ 0 ];
2015-10-06 01:45:51 +02:00
$owners = $states [ 'owner' ] ? $states [ 'owner' ] : $default ;
if ( ! is_array ( $owners ))
{
$owners = explode ( ',' , $owners );
}
2006-09-25 10:50:02 +02:00
foreach ( $owners as $key => $owner )
{
2008-05-08 17:02:35 +02:00
if ( ! $res_type && is_numeric ( $owner ) || $res_type && $owner [ 0 ] == $res_type )
2006-09-25 10:50:02 +02:00
{
unset ( $owners [ $key ]);
}
}
if ( ! $res_type || ! in_array ( $res_type . '0' , $set_owners ))
{
$owners = array_merge ( $owners , $set_owners );
}
$set_states [ 'owner' ] = implode ( ',' , $owners );
2006-03-06 08:11:39 +01:00
}
}
2006-03-16 19:17:18 +01:00
// for the uiforms class (eg. edit), dont store the (new) owner, as it might change the view
2009-07-09 11:50:47 +02:00
if ( substr ( $_GET [ 'menuaction' ], 0 , 25 ) == 'calendar.calendar_uiforms' )
2006-03-16 19:17:18 +01:00
{
$this -> owner = $set_states [ $state ];
continue ;
}
2004-08-01 17:36:04 +02:00
$states [ $state ] = $set_states [ $state ];
}
elseif ( ! is_array ( $states ) || ! isset ( $states [ $state ]))
{
$states [ $state ] = $default ;
}
if ( $state == 'date' )
{
$date_arr = $this -> bo -> date2array ( $states [ 'date' ]);
foreach ( array ( 'year' , 'month' , 'day' ) as $name )
{
$this -> $name = $states [ $name ] = $date_arr [ $name ];
}
}
$this -> $state = $states [ $state ];
}
2012-01-05 05:12:13 +01:00
// remove a given calendar from the view
if ( isset ( $_GET [ 'close' ]) && ( $k = array_search ( $_GET [ 'close' ], $owners = explode ( ',' , $this -> owner ))) !== false )
{
unset ( $owners [ $k ]);
$this -> owner = $states [ 'owner' ] = implode ( ',' , $owners );
}
2015-09-09 22:59:23 +02:00
if ( is_array ( $this -> owner ))
{
$this -> owner = implode ( ',' , $this -> owner );
}
2005-11-09 00:15:14 +01:00
if ( substr ( $this -> view , 0 , 8 ) == 'planner_' )
{
$states [ 'sortby' ] = $this -> sortby = $this -> view == 'planner_cat' ? 'category' : 'user' ;
$states [ 'view' ] = $this -> view = 'planner' ;
}
2004-08-01 17:36:04 +02:00
// set the actual view as return_to
2009-04-20 17:44:24 +02:00
if ( isset ( $_GET [ 'menuaction' ]))
2006-03-03 19:51:46 +01:00
{
2014-01-30 12:03:16 +01:00
list (, $class , $func ) = explode ( '.' , $_GET [ 'menuaction' ]);
2008-06-12 10:25:57 +02:00
if ( $func == 'index' )
{
$func = $this -> view ; $this -> view = 'index' ; // switch to the default view
}
2006-03-03 19:51:46 +01:00
}
else // eg. calendar/index.php
{
$func = $this -> view ;
2008-06-12 10:25:57 +02:00
$class = $this -> view == 'listview' ? 'calendar_uilist' : 'calendar_uiviews' ;
2006-03-03 19:51:46 +01:00
}
2008-06-12 10:25:57 +02:00
if ( $class == 'calendar_uiviews' || $class == 'calendar_uilist' )
2004-08-01 17:36:04 +02:00
{
2005-11-09 00:15:14 +01:00
$this -> view = $states [ 'view' ] = $func ;
2004-08-01 17:36:04 +02:00
}
2015-07-01 00:26:59 +02:00
$this -> view_menuaction = $this -> view == 'listview' ? 'calendar.calendar_uilist.listview' : 'calendar.calendar_uiviews.index' ;
2005-11-23 15:21:20 +01:00
2007-03-09 12:39:47 +01:00
if ( $this -> debug > 0 || $this -> debug == 'manage_states' ) $this -> bo -> debug_message ( 'uical::manage_states(%1) session was %2, states now %3' , True , $set_states , $states_session , $states );
2010-07-16 11:00:49 +02:00
// save the states in the session only when we are in calendar
if ( $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] == 'calendar' )
2008-10-07 10:57:09 +02:00
{
2010-07-16 11:00:49 +02:00
// save defined states into the user-prefs
if ( ! empty ( $states ) && is_array ( $states ))
2009-10-12 11:34:56 +02:00
{
2015-11-06 01:37:23 +01:00
$saved_states = array_intersect_key ( $states , array_flip ( $this -> states_to_save ));
2010-07-16 11:00:49 +02:00
if ( $saved_states != $this -> cal_prefs [ 'saved_states' ])
{
$GLOBALS [ 'egw' ] -> preferences -> add ( 'calendar' , 'saved_states' , $saved_states );
$GLOBALS [ 'egw' ] -> preferences -> save_repository ( false , 'user' , true );
}
2009-10-12 11:34:56 +02:00
}
2008-10-07 10:57:09 +02:00
}
2004-08-01 17:36:04 +02:00
}
/**
* gets the icons displayed for a given event
*
2009-08-04 19:14:16 +02:00
* @ param array $event
2004-08-01 17:36:04 +02:00
* @ return array of 'img' / 'title' pairs
*/
function event_icons ( $event )
{
2005-11-09 00:15:14 +01:00
$is_private = ! $event [ 'public' ] && ! $this -> bo -> check_perms ( EGW_ACL_READ , $event );
2004-08-01 17:36:04 +02:00
2012-06-24 08:04:44 +02:00
$icons = array ();
2004-08-01 17:36:04 +02:00
if ( ! $is_private )
{
if ( $event [ 'priority' ] == 3 )
{
2008-03-21 21:30:19 +01:00
$icons [] = html :: image ( 'calendar' , 'high' , lang ( 'high priority' ));
2004-08-01 17:36:04 +02:00
}
2005-11-09 00:15:14 +01:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE )
2004-08-01 17:36:04 +02:00
{
2008-03-21 21:30:19 +01:00
$icons [] = html :: image ( 'calendar' , 'recur' , lang ( 'recurring event' ));
2004-08-01 17:36:04 +02:00
}
2006-03-06 08:11:39 +01:00
// icons for single user, multiple users or group(s) and resources
2014-01-30 12:03:16 +01:00
foreach ( array_keys ( $event [ 'participants' ]) as $uid )
2006-03-06 08:11:39 +01:00
{
2008-05-08 17:02:35 +02:00
if ( is_numeric ( $uid ) || ! isset ( $this -> bo -> resources [ $uid [ 0 ]][ 'icon' ]))
2006-03-06 08:11:39 +01:00
{
if ( isset ( $icons [ 'single' ]) || $GLOBALS [ 'egw' ] -> accounts -> get_type ( $uid ) == 'g' )
{
unset ( $icons [ 'single' ]);
2008-03-21 21:30:19 +01:00
$icons [ 'multiple' ] = html :: image ( 'calendar' , 'users' );
2006-03-06 08:11:39 +01:00
}
elseif ( ! isset ( $icons [ 'multiple' ]))
{
2008-03-21 21:30:19 +01:00
$icons [ 'single' ] = html :: image ( 'calendar' , 'single' );
2006-03-06 08:11:39 +01:00
}
2008-05-08 17:02:35 +02:00
}
elseif ( ! isset ( $icons [ $uid [ 0 ]]) && isset ( $this -> bo -> resources [ $uid [ 0 ]]) && isset ( $this -> bo -> resources [ $uid [ 0 ]][ 'icon' ]))
2006-03-06 08:11:39 +01:00
{
2008-05-08 17:02:35 +02:00
$icons [ $uid [ 0 ]] = html :: image ( $this -> bo -> resources [ $uid [ 0 ]][ 'app' ],
( $this -> bo -> resources [ $uid [ 0 ]][ 'icon' ] ? $this -> bo -> resources [ $uid [ 0 ]][ 'icon' ] : 'navbar' ),
lang ( $this -> bo -> resources [ $uid [ 0 ]][ 'app' ]),
2006-03-06 08:11:39 +01:00
'width="16px" height="16px"' );
}
}
2004-08-01 17:36:04 +02:00
}
2006-03-16 19:17:18 +01:00
if ( $event [ 'non_blocking' ])
{
2008-03-21 21:30:19 +01:00
$icons [] = html :: image ( 'calendar' , 'nonblocking' , lang ( 'non blocking' ));
2006-03-16 19:17:18 +01:00
}
2004-08-01 17:36:04 +02:00
if ( $event [ 'public' ] == 0 )
{
2008-03-21 21:30:19 +01:00
$icons [] = html :: image ( 'calendar' , 'private' , lang ( 'private' ));
2004-08-01 17:36:04 +02:00
}
if ( isset ( $event [ 'alarm' ]) && count ( $event [ 'alarm' ]) >= 1 && ! $is_private )
{
2008-03-21 21:30:19 +01:00
$icons [] = html :: image ( 'calendar' , 'alarm' , lang ( 'alarm' ));
2004-08-01 17:36:04 +02:00
}
2009-11-18 14:58:01 +01:00
if ( $event [ 'participants' ][ $this -> user ][ 0 ] == 'U' )
{
2015-10-07 14:05:12 +02:00
$icons [] = html :: image ( 'calendar' , 'needs-action' , lang ( 'Needs action' ));
2009-11-18 14:58:01 +01:00
}
2004-08-01 17:36:04 +02:00
return $icons ;
}
/**
* Create a select - box item in the sidebox - menu
* @ privat used only by sidebox_menu !
*/
2014-03-05 14:24:27 +01:00
function _select_box ( $title , $name , $options , $width = '99%' )
2004-08-01 17:36:04 +02:00
{
2014-03-05 14:24:27 +01:00
$select = " <select style= \" width: $width ; \" name= \" " . $name . '" id="calendar_' . $name . '" title="' .
2004-08-01 17:36:04 +02:00
lang ( 'Select a %1' , lang ( $title )) . '">' .
$options . " </select> \n " ;
return array (
'text' => $select ,
'no_lang' => True ,
2013-12-12 05:19:59 +01:00
'link' => False ,
'icon' => false ,
2004-08-01 17:36:04 +02:00
);
}
2005-11-09 00:15:14 +01:00
/**
* Generate a link to add an event , incl . the necessary popup
*
* @ param string $content content of the link
2014-05-23 12:24:05 +02:00
* @ param string $date which date should be used as start - and end - date , default null = $this -> date
* @ param int $hour which hour should be used for the start , default null = $this -> hour
* @ param int $minute start - minute
* @ param array $vars
2005-11-09 00:15:14 +01:00
* @ return string the link incl . content
*/
2009-11-25 21:16:41 +01:00
function add_link ( $content , $date = null , $hour = null , $minute = 0 , array $vars = null )
2005-11-09 00:15:14 +01:00
{
2009-11-25 21:16:41 +01:00
$vars [ 'menuaction' ] = 'calendar.calendar_uiforms.edit' ;
$vars [ 'date' ] = $date ? $date : $this -> date ;
2005-11-09 00:15:14 +01:00
if ( ! is_null ( $hour ))
{
$vars [ 'hour' ] = $hour ;
$vars [ 'minute' ] = $minute ;
}
2014-02-24 10:48:22 +01:00
return html :: a_href ( $content , '' , $vars , ' data-date="' . $vars [ 'date' ] . '|' . $vars [ 'hour' ] . '|' . $vars [ 'minute' ]
. '" title="' . html :: htmlspecialchars ( lang ( 'Add' )) . '"' );
2005-11-09 00:15:14 +01:00
}
2008-05-08 17:02:35 +02:00
2005-11-09 00:15:14 +01:00
/**
* returns javascript to open a popup window : window . open ( ... )
*
* @ param string $link link or this . href
2014-05-23 12:24:05 +02:00
* @ param string $target name of target or this . target
* @ param int $width width of the window
* @ param int $height height of the window
2005-11-09 00:15:14 +01:00
* @ return string javascript ( using single quotes )
*/
2010-04-15 20:23:02 +02:00
function popup ( $link , $target = '_blank' , $width = 750 , $height = 410 )
2008-02-07 14:59:34 +01:00
{
2009-08-04 19:14:16 +02:00
return 'egw_openWindowCentered2(' . ( $link == 'this.href' ? $link : " ' " . $link . " ' " ) . ',' .
2010-06-10 19:54:03 +02:00
( $target == 'this.target' ? $target : " ' " . $target . " ' " ) . " , $width , $height ,'yes') " ;
2008-02-07 14:59:34 +01:00
}
2005-11-09 00:15:14 +01:00
2004-08-01 17:36:04 +02:00
/**
* creates the content for the sidebox - menu , called as hook
*/
function sidebox_menu ()
{
2014-01-24 12:24:14 +01:00
$link_vars = array ();
2015-06-10 23:51:28 +02:00
// Magic etemplate2 favorites menu (from framework)
2014-02-12 22:51:25 +01:00
display_sidebox ( 'calendar' , lang ( 'Favorites' ), egw_framework :: favorite_list ( 'calendar' ));
2013-12-12 04:42:08 +01:00
2014-01-30 12:03:16 +01:00
$file = array ( 'menuOpened' => true ); // menu open by default
2004-08-01 17:36:04 +02:00
2015-06-10 23:51:28 +02:00
// Target for etemplate
$file [] = array (
'no_lang' => true ,
'text' => '<span id="calendar-et2_target" />' ,
'link' => false ,
'icon' => false
);
// Merge print placeholders (selectbox in etemplate)
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'calendar' ][ 'document_dir' ])
2015-10-05 11:38:25 +02:00
{
2015-06-10 23:51:28 +02:00
$file [ 'Placeholders' ] = egw :: link ( '/index.php' , 'menuaction=calendar.calendar_merge.show_replacements' );
}
$appname = 'calendar' ;
$menu_title = lang ( 'Calendar Menu' );
display_sidebox ( $appname , $menu_title , $file );
2015-06-15 23:38:03 +02:00
$this -> sidebox_etemplate ();
2015-06-10 23:51:28 +02:00
// resources menu hooks
foreach ( $this -> bo -> resources as $resource )
2005-11-09 00:15:14 +01:00
{
2015-06-10 23:51:28 +02:00
if ( ! is_array ( $resource [ 'cal_sidebox' ])) continue ;
$menu_title = $resource [ 'cal_sidebox' ][ 'menu_title' ] ? $resource [ 'cal_sidebox' ][ 'menu_title' ] : lang ( $resource [ 'app' ]);
$file = ExecMethod ( $resource [ 'cal_sidebox' ][ 'file' ], array (
'menuaction' => $this -> view_menuaction ,
'owner' => $this -> owner ,
));
display_sidebox ( $appname , $menu_title , $file );
2005-11-09 00:15:14 +01:00
}
2015-06-10 23:51:28 +02:00
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ])
{
$file = Array (
'Configuration' => egw :: link ( '/index.php' , 'menuaction=admin.uiconfig.index&appname=calendar' ),
'Custom Fields' => egw :: link ( '/index.php' , 'menuaction=admin.customfields.index&appname=calendar' ),
'Holiday Management' => egw :: link ( '/index.php' , 'menuaction=calendar.uiholiday.admin' ),
'Global Categories' => egw :: link ( '/index.php' , 'menuaction=admin.admin_categories.index&appname=calendar' ),
);
$GLOBALS [ 'egw' ] -> framework -> sidebox ( $appname , lang ( 'Admin' ), $file , 'admin' );
2004-08-01 17:36:04 +02:00
}
2015-06-10 23:51:28 +02:00
}
2005-11-09 00:15:14 +01:00
2015-06-10 23:51:28 +02:00
/**
* Makes the sidebox content with etemplate , after hook is processed
*/
function sidebox_etemplate ( $content = array ())
{
if ( $content [ 'merge' ])
2009-11-19 19:56:04 +01:00
{
2015-06-15 23:38:03 +02:00
// View from sidebox is JSON encoded
$this -> manage_states ( array_merge ( $content , json_decode ( $content [ 'view' ], true )));
if ( $content [ 'first' ])
{
$this -> first = egw_time :: to ( $content [ 'first' ], 'ts' );
}
if ( $content [ 'last' ])
{
2015-12-02 18:34:06 +01:00
$this -> last = new egw_time ( $content [ 'last' ]);
2015-12-15 17:36:54 +01:00
$this -> last -> setTime ( 23 , 59 , 59 );
$this -> last = $this -> last -> format ( 'ts' );
2015-06-15 23:38:03 +02:00
}
2015-12-10 00:12:12 +01:00
2015-06-10 23:51:28 +02:00
$_GET [ 'merge' ] = $content [ 'merge' ];
$this -> merge ();
return ;
2009-11-19 19:56:04 +01:00
}
2015-06-10 23:51:28 +02:00
$sidebox = new etemplate_new ( 'calendar.sidebox' );
2009-11-19 19:56:04 +01:00
2015-11-06 01:37:23 +01:00
$content = $this -> cal_prefs [ 'saved_states' ];
2015-06-10 23:51:28 +02:00
$content [ 'view' ] = $this -> view ? $this -> view : 'week' ;
$content [ 'date' ] = $this -> date ? $this -> date : egw_time ();
$owners = $this -> owner ? is_array ( $this -> owner ) ? array ( $this -> owner ) : explode ( ',' , $this -> owner ) : array ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]);
2015-12-08 01:57:45 +01:00
$sel_options = array ();
// Add external owners that a select account widget will not find
2016-01-06 21:37:29 +01:00
$linked_owners = array ();
2015-06-10 23:51:28 +02:00
foreach ( $owners as $owner )
{
2016-01-06 21:37:29 +01:00
if ( ! is_numeric ( $owner ))
2015-06-10 23:51:28 +02:00
{
2015-12-08 23:29:56 +01:00
$resource = $this -> bo -> resources [ substr ( $owner , 0 , 1 )];
2016-01-06 21:37:29 +01:00
$label = egw_link :: title ( $resource [ 'app' ], substr ( $owner , 1 ));
$linked_owners [ $resource [ 'app' ]][ substr ( $owner , 1 )] = $label ;
$sel_options [ 'owner' ][] = array ( 'value' => $owner , 'label' => $label );
2015-06-10 23:51:28 +02:00
}
}
2016-01-06 21:37:29 +01:00
if ( $linked_owners )
{
// Send them to link registry too
egw_json_response :: get () -> call ( 'egw.link_title_callback' , $linked_owners );
}
2015-12-08 01:57:45 +01:00
2015-06-10 23:51:28 +02:00
$readonlys = array ();
2015-12-16 20:54:22 +01:00
$sel_options [ 'status_filter' ] = array (
2015-06-10 23:51:28 +02:00
array ( 'value' => 'default' , 'label' => lang ( 'Not rejected' ), 'title' => lang ( 'Show all status, but rejected' )),
array ( 'value' => 'accepted' , 'label' => lang ( 'Accepted' ), 'title' => lang ( 'Show only accepted events' )),
array ( 'value' => 'unknown' , 'label' => lang ( 'Invitations' ), 'title' => lang ( 'Show only invitations, not yet accepted or rejected' )),
array ( 'value' => 'tentative' , 'label' => lang ( 'Tentative' ), 'title' => lang ( 'Show only tentative accepted events' )),
array ( 'value' => 'delegated' , 'label' => lang ( 'Delegated' ), 'title' => lang ( 'Show only delegated events' )),
array ( 'value' => 'rejected' , 'label' => lang ( 'Rejected' ), 'title' => lang ( 'Show only rejected events' )),
array ( 'value' => 'owner' , 'label' => lang ( 'Owner too' ), 'title' => lang ( 'Show also events just owned by selected user' )),
array ( 'value' => 'all' , 'label' => lang ( 'All incl. rejected' ), 'title' => lang ( 'Show all status incl. rejected events' )),
array ( 'value' => 'hideprivate' , 'label' => lang ( 'Hide private infos' ), 'title' => lang ( 'Show all events, as if they were private' )),
array ( 'value' => 'showonlypublic' , 'label' => lang ( 'Hide private events' ), 'title' => lang ( 'Show only events flagged as public, (not checked as private)' )),
array ( 'value' => 'no-enum-groups' , 'label' => lang ( 'only group-events' ), 'title' => lang ( 'Do not include events of group members' )),
array ( 'value' => 'not-unknown' , 'label' => lang ( 'No meeting requests' ), 'title' => lang ( 'Show all status, but unknown' )),
);
2015-11-11 17:44:11 +01:00
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'calendar_delete_history' ])
{
2015-12-16 20:54:22 +01:00
$sel_options [ 'status_filter' ][] = array ( 'value' => 'deleted' , 'label' => lang ( 'Deleted' ), 'title' => lang ( 'Show events that have been deleted' ));
2015-11-11 17:44:11 +01:00
}
2014-01-10 18:31:24 +01:00
2015-06-10 23:51:28 +02:00
// Merge print
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'calendar' ][ 'document_dir' ])
2014-01-10 18:31:24 +01:00
{
2015-06-10 23:51:28 +02:00
$sel_options [ 'merge' ] = calendar_merge :: get_documents ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'calendar' ][ 'document_dir' ], '' , null , 'calendar' );
}
else
{
$readonlys [ 'merge' ] = true ;
2014-01-10 18:31:24 +01:00
}
2011-06-13 21:52:55 +02:00
2015-06-10 23:51:28 +02:00
// Sidebox?
$sidebox -> exec ( 'calendar.calendar_ui.sidebox_etemplate' , $content , $sel_options , $readonlys );
}
2014-07-01 17:26:05 +02:00
2016-01-20 21:58:14 +01:00
/**
* Send updated event information to the client via ajax
*
* This allows to pass only changed information for a single ( recurring ) event
* and update the UI without a refreshing any more than needed . If adding ,
* a notification via egw_framework :: refresh_opener () is still needed but
* edits , updates and deletes will be automatic .
* If the event is recurring , we send the next month ' s worth of recurrences
* for lack of a better way to determine how much to send .
*
* @ param int $event_id
* @ param egw_time $recurrence_date
*/
public function update_client ( $event_id , egw_time $recurrence_date = null )
{
// Directly update stored data.
// Make sure we have the whole event
$event = $this -> bo -> read ( $event_id , $recurrence_date );
$response = egw_json_response :: get ();
if ( ! $event )
{
// Sending null will trigger a removal
$response -> call ( 'egw.dataStoreUID' , 'calendar::' . $event_id , null );
return false ;
}
if ( ! $event [ 'recur_type' ] || $recurrence_date )
{
$this -> to_client ( $event );
$response -> call ( 'egw.dataStoreUID' , 'calendar::' . $event [ 'row_id' ], $event );
}
// If it's recurring, try to send the next month or so
else if ( $event [ 'recur_type' ] )
{
$this_month = new egw_time ( 'next month' );
$rrule = calendar_rrule :: event2rrule ( $event , true );
$rrule -> rewind ();
do
{
$occurrence = $rrule -> current ();
$converted = $this -> bo -> read ( $event [ 'id' ], $occurrence );
$this -> to_client ( $converted );
$response -> call ( 'egw.dataStoreUID' , 'calendar::' . $converted [ 'row_id' ], $converted );
$rrule -> next ();
}
while ( $rrule -> valid () && $occurrence <= $this_month );
}
}
2015-06-10 23:51:28 +02:00
/**
* Prepare an array of event information for sending to the client
*
2016-01-20 21:58:14 +01:00
* This involves changing timestamps into strings with timezone so javascript
* does not change them , and making sure we have everything the client needs
* for proper display .
2015-06-10 23:51:28 +02:00
*
* @ param type $event
*/
2015-11-05 21:56:13 +01:00
public function to_client ( & $event )
2015-06-10 23:51:28 +02:00
{
if ( ! $this -> bo -> check_perms ( EGW_ACL_EDIT , $event ))
{
$event [ 'class' ] .= 'rowNoEdit ' ;
}
2011-06-13 21:52:55 +02:00
2015-06-10 23:51:28 +02:00
// Delete disabled for other applications
if ( ! $this -> bo -> check_perms ( EGW_ACL_DELETE , $event ) || ! is_numeric ( $event [ 'id' ]))
{
$event [ 'class' ] .= 'rowNoDelete ' ;
}
2011-06-13 21:52:55 +02:00
2015-06-10 23:51:28 +02:00
// mark deleted events
if ( $event [ 'deleted' ])
2004-08-01 17:36:04 +02:00
{
2015-06-10 23:51:28 +02:00
$event [ 'class' ] .= 'rowDeleted ' ;
2004-08-01 17:36:04 +02:00
}
2011-02-15 21:35:46 +01:00
2015-06-10 23:51:28 +02:00
$event [ 'recure' ] = $this -> bo -> recure2string ( $event );
2014-03-05 14:24:27 +01:00
2015-06-10 23:51:28 +02:00
if ( empty ( $event [ 'description' ])) $event [ 'description' ] = ' ' ; // no description screws the titles horz. alignment
if ( empty ( $event [ 'location' ])) $event [ 'location' ] = ' ' ; // no location screws the owner horz. alignment
// respect category permissions
if ( ! empty ( $event [ 'category' ]))
2011-06-14 20:33:26 +02:00
{
2015-06-10 23:51:28 +02:00
$event [ 'category' ] = $this -> categories -> check_list ( EGW_ACL_READ , $event [ 'category' ]);
}
2015-10-05 11:38:25 +02:00
$event [ 'non_blocking' ] = ( bool ) $event [ 'non_blocking' ];
2014-07-01 17:26:05 +02:00
2015-06-10 23:51:28 +02:00
if ( ! ( int ) $event [ 'id' ] && preg_match ( '/^([a-z_-]+)([0-9]+)$/i' , $event [ 'id' ], $matches ))
{
$app = $matches [ 1 ];
$app_id = $matches [ 2 ];
$icons = array ();
2015-07-01 18:02:20 +02:00
if ( ! ( $is_private = calendar_bo :: integration_get_private ( $app , $app_id , $event )))
2015-06-10 23:51:28 +02:00
{
$icons = calendar_uiviews :: integration_get_icons ( $app , $app_id , $event );
2011-02-15 21:35:46 +01:00
}
2015-12-01 23:02:47 +01:00
$event [ 'app' ] = $app ;
$event [ 'app_id' ] = $app_id ;
2015-06-10 23:51:28 +02:00
}
else
{
$is_private = ! $this -> bo -> check_perms ( EGW_ACL_READ , $event );
}
if ( $is_private )
{
$event [ 'is_private' ] = true ;
$event [ 'class' ] .= 'rowNoView ' ;
2008-05-08 17:02:35 +02:00
}
2011-02-15 21:35:46 +01:00
2015-12-01 23:02:47 +01:00
if ( ! $event [ 'app' ])
{
$event [ 'app' ] = 'calendar' ;
}
if ( ! $event [ 'app_id' ])
{
$event [ 'app_id' ] = $event [ 'id' ];
}
2008-05-08 17:02:35 +02:00
2015-06-10 23:51:28 +02:00
if ( $event [ 'recur_type' ] != MCAL_RECUR_NONE )
2005-11-09 00:15:14 +01:00
{
2015-12-16 01:28:56 +01:00
$event [ 'app_id' ] .= ':' . egw_time :: to ( $event [ 'recur_date' ] ? $event [ 'recur_date' ] : $event [ 'start' ], 'ts' );
2005-11-09 00:15:14 +01:00
}
2016-01-05 21:43:19 +01:00
// set id for grid
$event [ 'row_id' ] = $event [ 'id' ] . ( $event [ 'recur_type' ] ? ':' . egw_time :: to ( $event [ 'recur_date' ] ? $event [ 'recur_date' ] : $event [ 'start' ], 'ts' ) : '' );
2015-10-27 21:10:53 +01:00
$event [ 'parts' ] = implode ( " , \n " , $this -> bo -> participants ( $event , false ));
2015-07-22 01:45:38 +02:00
$event [ 'date' ] = $this -> bo -> date2string ( $event [ 'start' ]);
2005-11-09 00:15:14 +01:00
2015-06-10 23:51:28 +02:00
// Change dates
foreach ( calendar_egw_record :: $types [ 'date-time' ] as $field )
2004-08-01 17:36:04 +02:00
{
2015-06-10 23:51:28 +02:00
if ( is_int ( $event [ $field ]))
{
2015-08-12 00:30:50 +02:00
$event [ $field ] = egw_time :: to ( $event [ $field ], egw_time :: ET2 );
2015-06-10 23:51:28 +02:00
}
2004-08-01 17:36:04 +02:00
}
}
2015-10-05 11:38:25 +02:00
2011-02-15 21:35:46 +01:00
public function merge ( $timespan = array ())
{
// Merge print
if ( $_GET [ 'merge' ])
{
if ( ! $timespan )
{
2015-12-10 00:12:12 +01:00
// Try to make time span into appropriate ranges to match
if ( stripos ( $_GET [ 'merge' ], 'month' ) !== false || stripos ( $_GET [ 'merge' ], lang ( 'month' )) !== false ) $template = 'month' ;
if ( stripos ( $_GET [ 'merge' ], 'week' ) !== false || stripos ( $_GET [ 'merge' ], lang ( 'week' )) !== false ) $template = 'week' ;
//error_log("Detected template $template");
switch ( $template )
{
case 'month' :
// Trim to _only_ the month, do not pad to week start / end
$time = new egw_time ( $this -> date );
$timespan = array ( array (
'start' => egw_time :: to ( $time -> format ( 'Y-m-01 00:00:00' ), 'ts' ),
'end' => egw_time :: to ( $time -> format ( 'Y-m-t 23:59:59' ), 'ts' )
));
break ;
case 'week' :
$timespan = array ();
$start = new egw_time ( $this -> first );
$t = clone $start ;
$t -> modify ( '+1 week' ) -> modify ( '-1 second' );
if ( $t -> format ( 'ts' ) < egw_time :: to ( $this -> last , 'ts' ))
{
do
{
$timespan [] = array (
'start' => $start -> format ( 'ts' ),
'end' => $t -> format ( 'ts' )
);
$start -> modify ( '+1 week' );
$t -> modify ( '+1 week' );
} while ( $start -> format ( 'ts' ) < $this -> last );
break ;
}
// Fall through
default :
$timespan = array ( array (
'start' => is_array ( $this -> first ) ? $this -> bo -> date2ts ( $this -> first ) : $this -> first ,
'end' => is_array ( $this -> last ) ? $this -> bo -> date2ts ( $this -> last ) : $this -> last
));
}
2011-02-15 21:35:46 +01:00
}
2011-06-17 15:27:45 +02:00
$merge = new calendar_merge ();
2015-12-11 20:38:52 +01:00
//error_log($_GET['merge'] . ' Timespan: ');foreach($timespan as $t) error_log(egw_time::to($t['start']) . ' - ' . egw_time::to($t['end']));
2015-10-09 21:48:28 +02:00
$error = $merge -> download ( $_GET [ 'merge' ], $timespan , '' , $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'calendar' ][ 'document_dir' ]);
// Here? Doesn't actually give the message
egw_framework :: refresh_opener ( $error , 'calendar' );
2011-02-15 21:35:46 +01:00
}
2015-10-09 21:48:28 +02:00
unset ( $_GET [ 'merge' ]);
2015-10-14 20:10:39 +02:00
if ( $error )
{
// This doesn't give message either, but at least it doesn't give a blank screen
egw_framework :: redirect_link ( '/index.php' , array (
'msg' => $error ,
'cd' => 'yes'
));
}
2011-02-15 21:35:46 +01:00
}
2004-08-01 17:36:04 +02:00
}