2011-02-09 16:58:06 +01:00
< ? php
/**
2016-05-01 19:47:59 +02:00
* EGroupware Calendar - document merge
2011-02-09 16:58:06 +01:00
*
* @ link http :// www . egroupware . org
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de >
* @ author Nathan Gray
* @ package calendar
2016-05-01 19:47:59 +02:00
* @ copyright ( c ) 2007 - 16 by Ralf Becker < RalfBecker - AT - outdoor - training . de >
2011-02-09 16:58:06 +01:00
* @ copyright 2011 Nathan Gray
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ version $Id $
*/
2016-05-01 19:47:59 +02:00
use EGroupware\Api ;
2011-02-09 16:58:06 +01:00
/**
* Calendar - document merge object
*/
2016-05-01 19:47:59 +02:00
class calendar_merge extends Api\Storage\Merge
2011-02-09 16:58:06 +01:00
{
/**
* Functions that can be called via menuaction
*
* @ var array
*/
var $public_functions = array (
2012-09-29 12:16:39 +02:00
'download_by_request' => true ,
'show_replacements' => true ,
2011-02-09 16:58:06 +01:00
);
// Object for getting calendar info
protected $bo ;
// Object used for getting resource info
protected static $resources ;
2011-02-15 21:35:46 +01:00
/**
* Recognised relative days - used as a day table , like day_ < n >
*/
protected static $relative = array (
'today' ,
'tomorrow' ,
'yesterday' ,
2012-02-16 17:55:42 +01:00
'selected' ,
2011-02-15 21:35:46 +01:00
);
/**
* If you use a range , these extra tags are available
*/
protected static $range_tags = array (
'start' => 'Y-m-d' ,
'end' => 'Y-m-d' ,
2011-02-22 19:45:33 +01:00
'month' => 'F' ,
2011-02-15 21:35:46 +01:00
'year' => 'Y'
);
2011-02-16 18:19:19 +01:00
/**
* Base query for all event searches
*/
protected $query = array ();
2011-06-22 19:23:04 +02:00
/**
* Stored IDs , if user passed in ID / events instead of date range
*/
protected $ids = array ();
2011-02-09 16:58:06 +01:00
/**
* Constructor
*/
function __construct ()
{
parent :: __construct ();
2011-09-13 11:05:33 +02:00
// overwrite global export-limit, if one is set for calendar/appointments
2016-05-01 19:47:59 +02:00
$this -> export_limit = Api\Storage\Merge :: getExportLimit ( 'calendar' );
2011-09-13 11:05:33 +02:00
2016-05-01 19:47:59 +02:00
// switch of handling of Api\Html formated content, if Api\Html is not used
$this -> parse_html_styles = Api\Storage\Customfields :: use_html ( 'calendar' );
2011-02-09 16:58:06 +01:00
$this -> bo = new calendar_boupdate ();
2011-02-17 17:50:46 +01:00
self :: $range_tags [ 'start' ] = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ];
self :: $range_tags [ 'end' ] = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ];
2011-02-15 21:35:46 +01:00
2011-02-09 16:58:06 +01:00
// Register table plugins
$this -> table_plugins [ 'participant' ] = 'participant' ;
for ( $i = 0 ; $i < 7 ; $i ++ )
{
$this -> table_plugins [ date ( 'l' , strtotime ( " + $i days " ))] = 'day_plugin' ;
}
2011-02-15 21:35:46 +01:00
for ( $i = 1 ; $i <= 31 ; $i ++ ) {
$this -> table_plugins [ 'day_' . $i ] = 'day' ; // Numerically by day number (1-31)
}
foreach ( self :: $relative as $day ) {
$this -> table_plugins [ $day ] = 'day' ; // Current day
}
2015-10-09 21:48:28 +02:00
$this -> query = is_array ( $this -> bo -> cal_prefs [ 'saved_states' ]) ?
$this -> bo -> cal_prefs [ 'saved_states' ] : unserialize ( $this -> bo -> cal_prefs [ 'saved_states' ]);
$this -> query [ 'users' ] = is_array ( $this -> query [ 'owner' ]) ? $this -> query [ 'owner' ] : explode ( ',' , $this -> query [ 'owner' ]);
2011-02-18 17:09:42 +01:00
$this -> query [ 'num_rows' ] = - 1 ;
2011-02-09 16:58:06 +01:00
}
2015-10-09 21:48:28 +02:00
/**
* Merges a given document with contact data
*
* Overridden from parent to be able to change a list of events into a range ,
* if the target document has no pagerepeat tag . Otherwise , parent :: merge_string ()
* would fail because we ' re trying to merge multiple records with no pagerepeat tag .
*
*
* @ param string $content
* @ param array $ids array with contact id ( s )
* @ param string & $err error - message on error
* @ param string $mimetype mimetype of complete document , eg . text /* , application / vnd . oasis . opendocument . text , application / rtf
* @ param array $fix = null regular expression => replacement pairs eg . to fix garbled placeholders
* @ param string $charset = null charset to override default set by mimetype or export charset
* @ return string | boolean merged document or false on error
*/
function merge_string ( $content , $ids , $err , $mimetype , $fix )
{
2015-12-10 00:12:12 +01:00
//error_log(__METHOD__ . ' IDs: ' . array2string($ids));
2015-10-09 21:48:28 +02:00
// Handle merging a list of events into a document with range instead of pagerepeat
2015-12-10 00:12:12 +01:00
if (( strpos ( $content , '$$range' ) !== false || strpos ( $content , '{{range' ) !== false ) && is_array ( $ids ))
2015-10-09 21:48:28 +02:00
{
2015-12-10 00:12:12 +01:00
//error_log(__METHOD__ . ' Got list of events(?), no pagerepeat tag');
2015-10-09 21:48:28 +02:00
// Merging more than one something will fail without pagerepeat
if ( is_array ( $ids ) && $ids [ 0 ][ 'id' ])
{
// Passed an array of events, to be handled like a date range
$events = $ids ;
$ids = array ( 'start' => PHP_INT_MAX , 'end' => 0 );
$this -> ids = array ();
foreach ( $events as $event ) {
2016-05-01 19:47:59 +02:00
if ( $event [ 'start' ] && Api\DateTime :: to ( $event [ 'start' ], 'ts' ) < $ids [ 'start' ]) $ids [ 'start' ] = Api\DateTime :: to ( $event [ 'start' ], 'ts' );
if ( $event [ 'end' ] && Api\DateTime :: to ( $event [ 'end' ], 'ts' ) > $ids [ 'end' ]) $ids [ 'end' ] = Api\DateTime :: to ( $event [ 'end' ], 'ts' );
2015-10-09 21:48:28 +02:00
// Keep ids for future use
$this -> ids [] = $event [ 'id' ];
}
$ids = array ( $ids );
}
}
2015-12-02 18:34:06 +01:00
// Handle merging a range of events into a document with pagerepeat instead of range
2015-12-10 00:12:12 +01:00
else if (( strpos ( $content , '$$pagerepeat' ) !== false || strpos ( $content , '{{pagerepeat' ) !== false )
&& (( strpos ( $content , '$$range' ) === false && strpos ( $content , '{{range' ) === false ))
&& is_array ( $ids ) && $ids [ 0 ] && ! $ids [ 0 ][ 'id' ])
2015-12-02 18:34:06 +01:00
{
2015-12-10 00:12:12 +01:00
//error_log(__METHOD__ . ' Got range(?), but pagerepeat instead of range tag');
2015-12-02 18:34:06 +01:00
// Passed a range, needs to be expanded
$events = $this -> bo -> search ( $this -> query + $ids [ 0 ] + array (
'offset' => 0 ,
'enum_recuring' => true ,
'order' => 'cal_start' ,
2016-05-01 19:47:59 +02:00
'cfs' => strpos ( $content , '#' ) !== false ? array_keys ( Api\Storage\Customfields :: get ( 'calendar' )) : null
2015-12-02 18:34:06 +01:00
));
$ids = array ();
foreach ( $events as $event ) {
$ids [] = $event ;
}
}
2015-12-04 21:58:37 +01:00
2015-10-09 21:48:28 +02:00
return parent :: merge_string ( $content , $ids , $err , $mimetype , $fix );
}
2011-02-09 16:58:06 +01:00
/**
* Get replacements
*
* @ param int | array $id event - id array with id , recur_date , or array with search parameters
* @ param string & $content = null content to create some replacements only if they are used
* @ return array | boolean
*/
protected function get_replacements ( $id , & $content = null )
{
$prefix = '' ;
// List events ?
2011-06-22 19:23:04 +02:00
if ( is_array ( $id ) && ! $id [ 'id' ] && ! $id [ 0 ][ 'id' ])
2011-02-09 16:58:06 +01:00
{
2011-02-16 18:19:19 +01:00
$events = $this -> bo -> search ( $this -> query + $id + array (
2011-02-09 16:58:06 +01:00
'offset' => 0 ,
'order' => 'cal_start' ,
2016-05-01 19:47:59 +02:00
'cfs' => strpos ( $content , '#' ) !== false ? array_keys ( Api\Storage\Customfields :: get ( 'calendar' )) : null
2011-02-09 16:58:06 +01:00
));
2011-02-16 18:19:19 +01:00
if ( strpos ( $content , '$$calendar/' ) !== false || strpos ( $content , '$$table/day' ) !== false )
{
array_unshift ( $events , false ); unset ( $events [ 0 ]); // renumber the array to start with key 1, instead of 0
$prefix = 'calendar/%d' ;
}
2011-02-09 16:58:06 +01:00
}
2012-04-16 21:19:44 +02:00
elseif ( is_array ( $id ) && $id [ 0 ][ 'id' ])
2011-06-22 19:23:04 +02:00
{
// Passed an array of events, to be handled like a date range
$events = $id ;
$id = array ( 'start' => PHP_INT_MAX , 'end' => 0 );
$this -> ids = array ();
foreach ( $events as $event ) {
2011-07-04 23:22:57 +02:00
if ( $event [ 'start' ] && $event [ 'start' ] < $id [ 'start' ]) $id [ 'start' ] = $event [ 'start' ];
if ( $event [ 'end' ] && $event [ 'end' ] > $id [ 'end' ]) $id [ 'end' ] = $event [ 'end' ];
2011-06-22 19:23:04 +02:00
// Keep ids for future use
$this -> ids [] = $event [ 'id' ];
}
2015-10-09 21:48:28 +02:00
$id = array ( $id );
2011-06-22 19:23:04 +02:00
}
2011-02-09 16:58:06 +01:00
else
{
$events = array ( $id );
2011-06-22 19:23:04 +02:00
$this -> ids = $events ;
2011-02-09 16:58:06 +01:00
}
2011-09-13 17:41:31 +02:00
// as this function allows to pass query- parameters, we need to check the result of the query against export_limit restrictions
2016-05-01 19:47:59 +02:00
if ( Api\Storage\Merge :: hasExportLimit ( $this -> export_limit ) && ! Api\Storage\Merge :: is_export_limit_excepted () && count ( $events ) > ( int ) $this -> export_limit )
2011-09-13 17:41:31 +02:00
{
2011-09-14 12:27:53 +02:00
$err = lang ( 'No rights to export more than %1 entries!' ,( int ) $this -> export_limit );
2016-05-01 19:47:59 +02:00
throw new Api\Exception\WrongUserinput ( $err );
2011-09-13 17:41:31 +02:00
}
2011-02-09 16:58:06 +01:00
$replacements = array ();
2011-02-10 20:17:26 +01:00
$n = 0 ;
foreach ( $events as $event )
2011-02-09 16:58:06 +01:00
{
2012-04-11 22:03:11 +02:00
$values = $this -> calendar_replacements ( $event , sprintf ( $prefix , ++ $n ), $content );
2011-02-15 21:35:46 +01:00
if ( is_array ( $id ) && $id [ 'start' ])
{
foreach ( self :: $range_tags as $key => $format )
{
2011-02-22 19:45:33 +01:00
$value = date ( $format , $key == 'end' ? $id [ 'end' ] : $id [ 'start' ]);
if ( $key == 'month' ) $value = lang ( $value );
$values [ " $\ $range / $key $ $ " ] = $value ;
2011-02-15 21:35:46 +01:00
}
}
2011-02-09 16:58:06 +01:00
$replacements += $values ;
}
return $replacements ;
}
/**
* Return replacements for the calendar
*
* @ param int | array $id event - id or array with id / recur_date , or array with event info
* @ param boolean $last_event_too = false also include information about the last event
* @ return array
*/
2012-04-11 22:03:11 +02:00
public function calendar_replacements ( $id , $prefix = '' , & $content = '' )
2011-02-09 16:58:06 +01:00
{
$replacements = array ();
if ( ! is_array ( $id ) || ! $id [ 'start' ]) {
$event = $this -> bo -> read ( is_array ( $id ) ? $id [ 'id' ] : $id , is_array ( $id ) ? $id [ 'recur_date' ] : null );
} else {
$event = $id ;
}
2016-05-17 01:26:15 +02:00
$record = new calendar_egw_record ( $event [ 'id' ]);
// Convert to human friendly values
$types = calendar_egw_record :: $types ;
importexport_export_csv :: convert ( $record , $types , 'calendar' );
$array = $record -> get_record_array ();
foreach ( $array as $key => $value )
{
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . $key . '$$' ] = $value ;
}
2011-04-07 01:18:08 +02:00
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . 'calendar_id' . '$$' ] = $event [ 'id' ];
2011-02-09 16:58:06 +01:00
foreach ( $this -> bo -> event2array ( $event ) as $name => $data )
{
if ( substr ( $name , - 4 ) == 'date' ) $name = substr ( $name , 0 , - 4 );
2011-02-10 20:17:26 +01:00
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . 'calendar_' . $name . '$$' ] = is_array ( $data [ 'data' ]) ? implode ( ', ' , $data [ 'data' ]) : $data [ 'data' ];
2011-02-09 16:58:06 +01:00
}
2015-07-10 17:27:06 +02:00
// Add seperate lists of participants by type
if ( strpos ( $content , 'calendar_participants/' ) !== false )
{
$types = array ();
foreach ( $this -> bo -> resources as $resource )
{
$types [ $resource [ 'app' ]] = array ();
}
foreach ( $event [ 'participants' ] as $uid => $status )
{
$type = $this -> bo -> resources [ $uid [ 0 ]][ 'app' ];
2016-05-01 11:57:48 +02:00
if ( $type == 'api-accounts' )
2015-07-10 17:27:06 +02:00
{
$type = ( $GLOBALS [ 'egw' ] -> accounts -> get_type ( $uid ) == 'g' ? 'group' : 'account' );
}
$types [ $type ][] = $this -> bo -> participant_name ( $uid );
}
foreach ( $types as $t_id => $type )
{
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . " calendar_participants/ { $t_id } $ $ " ] = implode ( ', ' , $type );
}
}
2011-03-15 00:25:51 +01:00
if ( ! $replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . 'calendar_recur_type$$' ])
{
// Need to set it to '' if not set or previous record may be used
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . 'calendar_recur_type$$' ] = '' ;
}
2011-02-09 16:58:06 +01:00
foreach ( array ( 'start' , 'end' ) as $what )
{
foreach ( array (
'date' => $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ],
'day' => 'l' ,
2011-03-28 18:24:36 +02:00
'time' => ( date ( 'Ymd' , $event [ 'start' ]) != date ( 'Ymd' , $event [ 'end' ]) ? $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ] . ' ' : '' ) . ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'timeformat' ] == 12 ? 'h:i a' : 'H:i' ),
2011-02-09 16:58:06 +01:00
) as $name => $format )
{
2016-05-01 19:47:59 +02:00
$value = Api\DateTime :: to ( $event [ $what ], $format );
2011-02-09 16:58:06 +01:00
if ( $format == 'l' ) $value = lang ( $value );
2011-02-10 20:17:26 +01:00
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . 'calendar_' . $what . $name . '$$' ] = $value ;
2011-02-09 16:58:06 +01:00
}
}
$duration = ( $event [ 'end' ] - $event [ 'start' ]) / 60 ;
2011-02-10 20:17:26 +01:00
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . 'calendar_duration$$' ] = floor ( $duration / 60 ) . lang ( 'h' ) . ( $duration % 60 ? $duration % 60 : '' );
2011-02-09 16:58:06 +01:00
2014-07-08 21:05:09 +02:00
// Add in contact stuff for owner
if ( strpos ( $content , '$$calendar_owner/' ) !== null && ( $user = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $event [ 'owner' ], 'person_id' )))
{
$replacements += $this -> contact_replacements ( $user ,( $prefix ? $prefix . '/' : '' ) . 'calendar_owner' );
$replacements [ '$$' . ( $prefix ? $prefix . '/' : '' ) . 'calendar_owner/primary_group$$' ] = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $GLOBALS [ 'egw' ] -> accounts -> id2name ( $event [ 'owner' ], 'account_primary_group' ));
}
2016-05-18 23:41:20 +02:00
if ( $content && strpos ( $content , '$$#' ) !== FALSE )
2012-04-11 22:03:11 +02:00
{
$this -> cf_link_to_expand ( $event , $content , $replacements );
}
2011-10-26 18:45:38 +02:00
// Links
2013-02-07 10:36:07 +01:00
$replacements += $this -> get_all_links ( 'calendar' , $event [ 'id' ], $prefix , $content );
2011-10-26 18:45:38 +02:00
2011-02-09 16:58:06 +01:00
return $replacements ;
}
/**
* Table plugin for event
* Lists events for a certain day of the week . Only works for one week at a time , so for multiple weeks ,
* use multiple date ranges .
*
* Use :
* $$table / Monday $ $ $$starttime $ $ $$title $ $ $$endtable $ $
* The day of the week may be language specific ( date ( 'l' )) .
*
* @ param string $plugin ( Monday - Sunday )
* @ param int / array date or date range
2011-02-17 19:18:06 +01:00
* @ param int $n Row number
2011-02-09 16:58:06 +01:00
* @ param string $repeat Text being repeated for each entry
* @ return array
*/
public function day_plugin ( $plugin , $date , $n , $repeat )
{
2014-11-19 13:20:59 +01:00
static $days = null ;
2011-02-09 16:58:06 +01:00
if ( is_array ( $date ) && ! $date [ 'start' ]) {
2011-06-22 19:23:04 +02:00
// List of IDs
if ( $date [ 0 ][ 'start' ]) {
$id = array ( 'start' => PHP_INT_MAX , 'end' => 0 );
foreach ( $date as $event ) {
2011-07-04 23:22:57 +02:00
if ( $event [ 'start' ] && $event [ 'start' ] < $id [ 'start' ]) $id [ 'start' ] = $event [ 'start' ];
if ( $event [ 'end' ] && $event [ 'end' ] > $id [ 'end' ]) $id [ 'end' ] = $event [ 'end' ];
2011-06-22 19:23:04 +02:00
}
$date = $id ;
} else {
$event = $this -> bo -> read ( is_array ( $date ) ? $date [ 'id' ] : $date , is_array ( $date ) ? $date [ 'recur_date' ] : null );
if ( date ( 'l' , $event [ 'start' ]) != $plugin ) return array ();
$date = $event [ 'start' ];
}
2011-02-09 16:58:06 +01:00
}
$_date = $date [ 'start' ] ? $date [ 'start' ] : $date ;
if ( $days [ date ( 'Ymd' , $_date )][ $plugin ]) return $days [ date ( 'Ymd' , $_date )][ $plugin ][ $n ];
2011-02-16 18:19:19 +01:00
$events = $this -> bo -> search ( $this -> query + array (
2011-02-09 16:58:06 +01:00
'start' => $date [ 'end' ] ? $date [ 'start' ] : mktime ( 0 , 0 , 0 , date ( 'm' , $_date ), date ( 'd' , $_date ), date ( 'Y' , $_date )),
'end' => $date [ 'end' ] ? $date [ 'end' ] : mktime ( 23 , 59 , 59 , date ( 'm' , $_date ), date ( 'd' , $_date ), date ( 'Y' , $_date )),
'offset' => 0 ,
'num_rows' => 20 ,
'order' => 'cal_start' ,
2014-10-15 21:08:26 +02:00
'daywise' => true ,
'cfs' => array (), // read all custom-fields
2011-02-09 16:58:06 +01:00
));
2011-06-22 19:23:04 +02:00
2014-11-19 13:20:59 +01:00
if ( true ) $days = array ();
2011-02-09 16:58:06 +01:00
$replacements = array ();
2011-03-28 18:55:24 +02:00
$time_format = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'timeformat' ] == 12 ? 'h:i a' : 'H:i' ;
2012-04-11 22:03:11 +02:00
foreach ( $events as $day => $list )
2011-02-09 16:58:06 +01:00
{
2014-11-19 13:20:59 +01:00
foreach ( $list as $event )
2011-02-09 16:58:06 +01:00
{
2011-06-22 19:23:04 +02:00
if ( $this -> ids && ! in_array ( $event [ 'id' ], $this -> ids )) continue ;
2016-05-01 19:47:59 +02:00
$start = Api\DateTime :: to ( $event [ 'start' ], 'array' );
$end = Api\DateTime :: to ( $event [ 'end' ], 'array' );
2011-03-28 18:55:24 +02:00
$replacements = $this -> calendar_replacements ( $event );
2011-02-18 17:09:42 +01:00
if ( $start [ 'year' ] == $end [ 'year' ] && $start [ 'month' ] == $end [ 'month' ] && $start [ 'day' ] == $end [ 'day' ]) {
$dow = date ( 'l' , $event [ 'start' ]);
} else {
$dow = date ( 'l' , strtotime ( $day ));
2011-03-28 18:55:24 +02:00
// Fancy date+time formatting for multi-day events
2011-03-29 17:10:55 +02:00
$replacements [ '$$calendar_starttime$$' ] = date ( $time_format , $day == date ( 'Ymd' , $event [ 'start' ]) ? $event [ 'start' ] : mktime ( 0 , 0 , 0 , 0 , 0 , 1 ));
$replacements [ '$$calendar_endtime$$' ] = date ( $time_format , $day == date ( 'Ymd' , $event [ 'end' ]) ? $event [ 'end' ] : mktime ( 23 , 59 , 59 , 0 , 0 , 0 ));
2011-02-18 17:09:42 +01:00
}
2012-05-15 15:23:11 +02:00
2011-03-28 18:55:24 +02:00
$days [ date ( 'Ymd' , $_date )][ $dow ][] = $replacements ;
2011-02-09 16:58:06 +01:00
}
2011-02-23 22:02:22 +01:00
if ( strpos ( $repeat , 'day/date' ) !== false || strpos ( $repeat , 'day/name' ) !== false ) {
2011-02-22 19:45:33 +01:00
$date_marker = array (
'$$day/date$$' => date ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ], strtotime ( $day )),
'$$day/name$$' => lang ( date ( 'l' , strtotime ( $day )))
);
2011-02-17 19:18:06 +01:00
if ( ! is_array ( $days [ date ( 'Ymd' , $_date )][ date ( 'l' , strtotime ( $day ))])) {
2011-02-18 16:30:21 +01:00
$blank = $this -> calendar_replacements ( array ());
2014-11-19 13:20:59 +01:00
foreach ( $blank as & $value )
{
$value = '' ;
}
2011-02-18 16:30:21 +01:00
$days [ date ( 'Ymd' , $_date )][ date ( 'l' , strtotime ( $day ))][] = $blank ;
2011-02-17 19:18:06 +01:00
}
2011-02-18 16:30:21 +01:00
$days [ date ( 'Ymd' , $_date )][ date ( 'l' , strtotime ( $day ))][ 0 ] += $date_marker ;
2011-02-17 19:18:06 +01:00
}
2017-07-27 22:41:16 +02:00
// Add in birthdays
if ( strpos ( $repeat , 'day/birthdays' ) !== false )
{
$days [ date ( 'Ymd' , $_date )][ date ( 'l' , strtotime ( $day ))][ 0 ][ '$$day/birthdays$$' ] = $this -> get_birthdays ( $day );
}
2011-02-09 16:58:06 +01:00
}
return $days [ date ( 'Ymd' , $_date )][ $plugin ][ 0 ];
}
2011-02-15 21:35:46 +01:00
/**
* Table plugin for a certain date
*
* Can be either a particular date ( 2011 - 02 - 15 ) or a day of the month ( 15 )
*
* @ param string $plugin
2011-02-17 19:18:06 +01:00
* @ param int $id ID for this record
* @ param int $n Repeated row number
* @ param string $repeat Text being repeated for each entry
2011-02-15 21:35:46 +01:00
* @ return array
*/
2011-02-17 19:18:06 +01:00
public function day ( $plugin , $id , $n , $repeat )
2011-02-15 21:35:46 +01:00
{
2014-11-19 13:20:59 +01:00
static $days = null ;
2011-02-15 21:35:46 +01:00
// Figure out which day
list ( $type , $which ) = explode ( '_' , $plugin );
if ( $type == 'day' && $which )
{
2011-06-22 19:23:04 +02:00
if ( $id [ 0 ][ 'start' ])
{
$dates = array ( 'start' => PHP_INT_MAX , 'end' => 0 );
foreach ( $id as $event ) {
2011-07-04 23:22:57 +02:00
if ( $event [ 'start' ] && $event [ 'start' ] < $dates [ 'start' ]) $dates [ 'start' ] = $event [ 'start' ];
if ( $event [ 'end' ] && $event [ 'end' ] > $dates [ 'end' ]) $dates [ 'end' ] = $event [ 'end' ];
2011-06-22 19:23:04 +02:00
}
$id = $dates ;
}
2014-11-19 13:20:59 +01:00
$arr = $this -> bo -> date2array ( $id [ 'start' ]);
$arr [ 'day' ] = $which ;
$date = $this -> bo -> date2ts ( $arr );
2011-02-15 21:35:46 +01:00
if ( is_array ( $id ) && $id [ 'start' ] && ( $date < $id [ 'start' ] || $date > $id [ 'end' ])) return array ();
}
2012-02-16 17:55:42 +01:00
elseif ( $plugin == 'selected' )
{
$date = $id [ 'start' ];
}
2011-02-15 21:35:46 +01:00
else
{
$date = strtotime ( $plugin );
}
if ( $type == 'day' && is_array ( $id ) && ! $id [ 'start' ]) {
$event = $this -> bo -> read ( is_array ( $id ) ? $id [ 'id' ] : $id , is_array ( $id ) ? $id [ 'recur_date' ] : null );
if ( $which && date ( 'd' , $event [ 'start' ]) != $which ) return array ();
if ( date ( 'Ymd' , $date ) != date ( 'Ymd' , $event [ 'start' ])) return array ();
return $n == 0 ? $this -> calendar_replacements ( $event ) : array ();
}
2012-05-15 15:23:11 +02:00
2011-02-15 21:35:46 +01:00
// Use start for cache, in case of multiple months
$_date = $id [ 'start' ] ? $id [ 'start' ] : $date ;
if ( $days [ date ( 'Ymd' , $_date )][ $plugin ]) return $days [ date ( 'Ymd' , $_date )][ $plugin ][ $n ];
2011-02-16 18:19:19 +01:00
$events = $this -> bo -> search ( $this -> query + array (
2011-02-15 21:35:46 +01:00
'start' => $date ,
'end' => mktime ( 23 , 59 , 59 , date ( 'm' , $date ), date ( 'd' , $date ), date ( 'Y' , $date )),
'offset' => 0 ,
'num_rows' => 20 ,
'order' => 'cal_start' ,
2014-10-15 21:08:26 +02:00
'daywise' => true ,
'cfs' => array (), // read all custom-fields
2011-02-15 21:35:46 +01:00
));
$replacements = array ();
2014-11-19 13:20:59 +01:00
if ( true ) $days = array ();
2011-03-29 17:10:55 +02:00
$time_format = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'timeformat' ] == 12 ? 'h:i a' : 'H:i' ;
2012-04-11 22:03:11 +02:00
foreach ( $events as $day => $list )
2011-02-15 21:35:46 +01:00
{
2014-11-19 13:20:59 +01:00
foreach ( $list as $event )
2011-02-15 21:35:46 +01:00
{
2011-06-22 19:23:04 +02:00
if ( $this -> ids && ! in_array ( $event [ 'id' ], $this -> ids )) continue ;
2016-05-01 19:47:59 +02:00
$start = Api\DateTime :: to ( $event [ 'start' ], 'array' );
$end = Api\DateTime :: to ( $event [ 'end' ], 'array' );
2011-03-28 18:55:24 +02:00
$replacements = $this -> calendar_replacements ( $event );
if ( $start [ 'year' ] == $end [ 'year' ] && $start [ 'month' ] == $end [ 'month' ] && $start [ 'day' ] == $end [ 'day' ]) {
2014-11-19 13:20:59 +01:00
//$dow = date('l',$event['start']);
2011-03-28 18:55:24 +02:00
} else {
// Fancy date+time formatting for multi-day events
2011-03-29 17:10:55 +02:00
$replacements [ '$$calendar_starttime$$' ] = date ( $time_format , $day == date ( 'Ymd' , $event [ 'start' ]) ? $event [ 'start' ] : mktime ( 0 , 0 , 0 , 0 , 0 , 1 ));
$replacements [ '$$calendar_endtime$$' ] = date ( $time_format , $day == date ( 'Ymd' , $event [ 'end' ]) ? $event [ 'end' ] : mktime ( 23 , 59 , 59 , 0 , 0 , 0 ));
2011-03-28 18:55:24 +02:00
}
$days [ date ( 'Ymd' , $_date )][ $plugin ][] = $replacements ;
2011-02-15 21:35:46 +01:00
}
2011-02-23 22:02:22 +01:00
if ( strpos ( $repeat , 'day/date' ) !== false || strpos ( $repeat , 'day/name' ) !== false ) {
2011-02-22 19:45:33 +01:00
$date_marker = array (
'$$day/date$$' => date ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ], strtotime ( $day )),
'$$day/name$$' => lang ( date ( 'l' , strtotime ( $day )))
);
2011-02-17 19:18:06 +01:00
if ( ! is_array ( $days [ date ( 'Ymd' , $_date )][ $plugin ])) {
2011-02-18 16:30:21 +01:00
$blank = $this -> calendar_replacements ( array ());
2014-11-19 13:20:59 +01:00
foreach ( $blank as & $value )
{
$value = '' ;
}
2011-02-18 16:30:21 +01:00
$days [ date ( 'Ymd' , $_date )][ $plugin ][] = $blank ;
2011-02-17 19:18:06 +01:00
}
2011-02-18 16:30:21 +01:00
$days [ date ( 'Ymd' , $_date )][ $plugin ][ 0 ] += $date_marker ;
2011-02-17 19:18:06 +01:00
}
2017-07-27 22:41:16 +02:00
// Add in birthdays
if ( strpos ( $repeat , 'day/birthdays' ) !== false )
{
$days [ date ( 'Ymd' , $_date )][ date ( 'l' , strtotime ( $day ))][ 0 ][ '$$day/birthdays$$' ] = $this -> get_birthdays ( $day );
}
2011-02-15 21:35:46 +01:00
}
return $days [ date ( 'Ymd' , $_date )][ $plugin ][ 0 ];
}
2011-02-09 16:58:06 +01:00
/**
* Table plugin for participants
*
* Copied from eventmgr resources
*
* @ param string $plugin
* @ param int $id
* @ param int $n
* @ return array
*/
public function participant ( $plugin , $id , $n )
{
2014-11-19 13:20:59 +01:00
unset ( $plugin ); // not used, but required by function signature
2011-02-09 16:58:06 +01:00
if ( ! is_array ( $id ) || ! $id [ 'start' ]) {
$event = $this -> bo -> read ( is_array ( $id ) ? $id [ 'id' ] : $id , is_array ( $id ) ? $id [ 'recur_date' ] : null );
} else {
$event = $id ;
}
if ( ! is_array ( $event [ 'participants' ]) || $n >= count ( $event [ 'participants' ])) return array ();
$participant = null ;
$status = null ;
$i = - 1 ;
foreach ( $event [ 'participants' ] as $participant => $status ) {
if ( ++ $i == $n ) break ;
}
if ( ! $participant ) return array ();
// Add some common information
2014-11-19 13:20:59 +01:00
$quantity = $role = null ;
2011-02-09 16:58:06 +01:00
calendar_so :: split_status ( $status , $quantity , $role );
if ( $role != 'REQ-PARTICIPANT' )
{
if ( isset ( $this -> bo -> roles [ $role ]))
{
$role = lang ( $this -> bo -> roles [ $role ]);
}
// allow to use cats as roles (beside regular iCal ones)
elseif ( substr ( $role , 0 , 6 ) == 'X-CAT-' && ( $cat_id = ( int ) substr ( $role , 6 )) > 0 )
{
$role = $GLOBALS [ 'egw' ] -> categories -> id2name ( $cat_id );
}
else
{
$role = lang ( str_replace ( 'X-' , '' , $role ));
}
}
$info = array (
'name' => $this -> bo -> participant_name ( $participant ),
2012-05-15 15:23:11 +02:00
'status' => lang ( $this -> bo -> verbose_status [ $status ]),
2011-02-09 16:58:06 +01:00
'quantity' => $quantity ,
'role' => $role
);
2012-05-15 15:23:11 +02:00
2011-02-09 16:58:06 +01:00
switch ( $participant [ 0 ])
{
case 'c' :
$replacements = $this -> contact_replacements ( substr ( $participant , 1 ), '' );
break ;
case 'r' :
2016-07-26 09:03:02 +02:00
if ( is_null ( self :: $resources )) self :: $resources = new resources_bo ();
2011-02-09 16:58:06 +01:00
if (( $resource = self :: $resources -> read ( substr ( $participant , 1 ))))
{
foreach ( $resource as $name => $value )
{
$replacements [ '$$' . $name . '$$' ] = $value ;
}
}
break ;
default :
if ( is_numeric ( $participant ) && ( $contact = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $participant , 'person_id' )))
{
$replacements = $this -> contact_replacements ( $contact , '' );
}
break ;
}
foreach ( $info as $name => $value )
{
$replacements [ '$$' . $name . '$$' ] = $value ;
}
return $replacements ;
}
2017-07-27 22:41:16 +02:00
/**
* Get replacement for birthdays placeholder
* @ param String $day Date in Ymd format
*/
protected function get_birthdays ( $day )
{
$contacts = new Api\Contacts ();
$birthdays = Array ();
foreach ( $contacts -> get_addressbooks () as $owner => $name )
{
$birthdays += $contacts -> read_birthdays ( $owner , substr ( $day , 0 , 4 ));
}
return $birthdays [ $day ] ? implode ( ', ' , array_column ( $birthdays [ $day ], 'name' )) : '' ;
}
2011-02-09 16:58:06 +01:00
/**
* Generate table with replacements for the preferences
*
*/
public function show_replacements ()
{
2016-05-01 19:47:59 +02:00
Api\Translation :: add_app ( 'calendar' );
2011-02-09 16:58:06 +01:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'calendar' ) . ' - ' . lang ( 'Replacements for inserting events into documents' );
2015-07-15 18:29:10 +02:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'nonavbar' ] = true ;
2016-05-14 21:26:36 +02:00
echo $GLOBALS [ 'egw' ] -> framework -> header ();
2011-02-09 16:58:06 +01:00
echo " <table width='90%' align='center'> \n " ;
echo '<tr><td colspan="4"><h3>' . lang ( 'Calendar fields:' ) . " </h3></td></tr> " ;
2014-11-19 13:20:59 +01:00
$n = 0 ;
2011-02-09 16:58:06 +01:00
foreach ( array (
2011-04-07 01:18:08 +02:00
'calendar_id' => lang ( 'Calendar ID' ),
2011-02-10 20:17:26 +01:00
'calendar_title' => lang ( 'Title' ),
'calendar_description' => lang ( 'Description' ),
'calendar_participants' => lang ( 'Participants' ),
'calendar_location' => lang ( 'Location' ),
'calendar_start' => lang ( 'Start' ) . ': ' . lang ( 'Date' ) . '+' . lang ( 'Time' ),
'calendar_startday' => lang ( 'Start' ) . ': ' . lang ( 'Weekday' ),
'calendar_startdate' => lang ( 'Start' ) . ': ' . lang ( 'Date' ),
'calendar_starttime' => lang ( 'Start' ) . ': ' . lang ( 'Time' ),
'calendar_end' => lang ( 'End' ) . ': ' . lang ( 'Date' ) . '+' . lang ( 'Time' ),
'calendar_endday' => lang ( 'End' ) . ': ' . lang ( 'Weekday' ),
'calendar_enddate' => lang ( 'End' ) . ': ' . lang ( 'Date' ),
'calendar_endtime' => lang ( 'End' ) . ': ' . lang ( 'Time' ),
'calendar_duration' => lang ( 'Duration' ),
'calendar_category' => lang ( 'Category' ),
'calendar_priority' => lang ( 'Priority' ),
'calendar_updated' => lang ( 'Updated' ),
'calendar_recur_type' => lang ( 'Repetition' ),
'calendar_access' => lang ( 'Access' ) . ': ' . lang ( 'public' ) . ', ' . lang ( 'private' ),
'calendar_owner' => lang ( 'Owner' ),
2011-02-09 16:58:06 +01:00
) as $name => $label )
{
if ( in_array ( $name , array ( 'start' , 'end' )) && $n & 1 ) // main values, which should be in the first column
{
echo " </tr> \n " ;
$n ++ ;
}
if ( ! ( $n & 1 )) echo '<tr>' ;
2011-02-18 18:02:14 +01:00
echo '<td>{{' . $name . '}}</td><td>' . $label . '</td>' ;
2011-02-09 16:58:06 +01:00
if ( $n & 1 ) echo " </tr> \n " ;
$n ++ ;
}
2011-02-15 21:35:46 +01:00
echo '<tr><td colspan="4"><h3>' . lang ( 'Range fields' ) . " :</h3></td></tr> " ;
echo '<tr><td colspan="4">' . lang ( 'If you select a range (month, week, etc) instead of a list of entries, these extra fields are available' ) . '</td></tr>' ;
2014-11-19 13:20:59 +01:00
foreach ( array_keys ( self :: $range_tags ) as $name )
2011-02-15 21:35:46 +01:00
{
2011-02-18 18:02:14 +01:00
echo '<tr><td>{{range/' . $name . '}}</td><td>' . lang ( $name ) . " </td></tr> \n " ;
2011-02-15 21:35:46 +01:00
}
2011-02-09 16:58:06 +01:00
echo '<tr><td colspan="4"><h3>' . lang ( 'Custom fields' ) . " :</h3></td></tr> " ;
2016-05-01 19:47:59 +02:00
$custom = Api\Storage\Customfields :: get ( 'calendar' );
2011-02-09 16:58:06 +01:00
foreach ( $custom as $name => $field )
{
2011-02-18 18:02:14 +01:00
echo '<tr><td>{{#' . $name . '}}</td><td colspan="3">' . $field [ 'label' ] . " </td></tr> \n " ;
2011-02-09 16:58:06 +01:00
}
2015-07-10 17:27:06 +02:00
echo '<tr><td colspan="4"><h3>' . lang ( 'Participants' ) . " :</h3></td></tr> " ;
echo '<tr><td>{{calendar_participants/account}}</td><td colspan="3">' . lang ( 'Accounts' ) . " </td></tr> \n " ;
echo '<tr><td>{{calendar_participants/group}}</td><td colspan="3">' . lang ( 'Groups' ) . " </td></tr> \n " ;
foreach ( $this -> bo -> resources as $resource )
{
if ( $resource [ 'type' ])
{
echo '<tr><td>{{calendar_participants/' . $resource [ 'app' ] . '}}</td><td colspan="3">' . lang ( $resource [ 'app' ]) . " </td></tr> \n " ;
}
}
2011-02-09 16:58:06 +01:00
echo '<tr><td colspan="4"><h3>' . lang ( 'Participant table' ) . " :</h3></td></tr> " ;
2011-02-18 18:02:14 +01:00
echo '<tr><td colspan="4">{{table/participant}} ... </td></tr>' ;
echo '<tr><td>{{name}}</td><td>' . lang ( 'name' ) . '</td></tr>' ;
echo '<tr><td>{{role}}</td><td>' . lang ( 'role' ) . '</td></tr>' ;
echo '<tr><td>{{quantity}}</td><td>' . lang ( 'quantity' ) . '</td></tr>' ;
echo '<tr><td>{{status}}</td><td>' . lang ( 'status' ) . '</td></tr>' ;
echo '<tr><td colspan="4">{{endtable}}</td></tr>' ;
2012-05-15 15:23:11 +02:00
2011-02-15 21:35:46 +01:00
echo '<tr style="vertical-align:top"><td colspan="2"><table >' ;
echo '<tr><td><h3>' . lang ( 'Day of week tables' ) . " :</h3></td></tr> " ;
2011-02-09 16:58:06 +01:00
$days = array ();
for ( $i = 0 ; $i < 7 ; $i ++ )
{
$days [ date ( 'N' , strtotime ( " + $i days " ))] = date ( 'l' , strtotime ( " + $i days " ));
}
ksort ( $days );
foreach ( $days as $day )
{
2011-02-18 18:02:14 +01:00
echo '<tr><td>{{table/' . $day . '}} ... {{endtable}}</td></tr>' ;
2011-02-15 21:35:46 +01:00
}
2011-02-17 19:18:06 +01:00
echo '</table></td><td colspan="2"><table >' ;
2011-02-15 21:35:46 +01:00
echo '<tr><td><h3>' . lang ( 'Daily tables' ) . " :</h3></td></tr> " ;
2014-11-19 13:20:59 +01:00
foreach ( self :: $relative as $value ) {
2011-02-18 18:02:14 +01:00
echo '<tr><td>{{table/' . $value . '}} ... {{endtable}}</td></tr>' ;
2011-02-09 16:58:06 +01:00
}
2011-02-18 18:02:14 +01:00
echo '<tr><td>{{table/day_n}} ... {{endtable}}</td><td>1 <= n <= 31</td></tr>' ;
2011-02-15 21:35:46 +01:00
echo '</table></td></tr>' ;
2017-07-27 22:41:16 +02:00
echo '<tr><td colspan="2">Available for the first entry inside each day of week or daily table inside the selected range:</td></tr>' ;
echo '<tr><td>{{day/date}}</td><td colspan="3">' . lang ( 'Date for the day of the week' ) . '</td></tr>' ;
echo '<tr><td>{{day/name}}</td><td colspan="3">' . lang ( 'Name of the week (ex: Monday)' ) . '</td></tr>' ;
echo '<tr><td>{{day/birthdays}}</td><td colspan="3">' . lang ( 'Birthdays' ) . '</td></tr>' ;
2011-02-09 16:58:06 +01:00
echo '<tr><td colspan="4"><h3>' . lang ( 'General fields:' ) . " </h3></td></tr> " ;
foreach ( array (
2013-03-20 15:51:09 +01:00
'link' => lang ( 'HTML link to the current record' ),
2011-10-26 18:45:38 +02:00
'links' => lang ( 'Titles of any entries linked to the current record, excluding attached files' ),
'attachments' => lang ( 'List of files linked to the current record' ),
'links_attachments' => lang ( 'Links and attached files' ),
2012-01-06 19:35:34 +01:00
'links/[appname]' => lang ( 'Links to specified application. Example: {{links/infolog}}' ),
2011-02-09 16:58:06 +01:00
'date' => lang ( 'Date' ),
'user/n_fn' => lang ( 'Name of current user, all other contact fields are valid too' ),
'user/account_lid' => lang ( 'Username' ),
'pagerepeat' => lang ( 'For serial letter use this tag. Put the content, you want to repeat between two Tags.' ),
'label' => lang ( 'Use this tag for addresslabels. Put the content, you want to repeat, between two tags.' ),
'labelplacement' => lang ( 'Tag to mark positions for address labels' ),
2011-02-18 18:02:14 +01:00
'IF fieldname' => lang ( 'Example {{IF n_prefix~Mr~Hello Mr.~Hello Ms.}} - search the field "n_prefix", for "Mr", if found, write Hello Mr., else write Hello Ms.' ),
'NELF' => lang ( 'Example {{NELF role}} - if field role is not empty, you will get a new line with the value of field role' ),
2017-02-10 10:41:43 +01:00
'NENVLF' => lang ( 'Example {{NENVLF role}} - if field role is not empty, set a LF without any value of the field' ),
2011-02-18 18:02:14 +01:00
'LETTERPREFIX' => lang ( 'Example {{LETTERPREFIX}} - Gives a letter prefix without double spaces, if the title is emty for example' ),
'LETTERPREFIXCUSTOM' => lang ( 'Example {{LETTERPREFIXCUSTOM n_prefix title n_family}} - Example: Mr Dr. James Miller' ),
2011-02-09 16:58:06 +01:00
) as $name => $label )
{
2011-02-18 18:02:14 +01:00
echo '<tr><td>{{' . $name . '}}</td><td colspan="3">' . $label . " </td></tr> \n " ;
2011-02-09 16:58:06 +01:00
}
echo " </table> \n " ;
2016-05-14 21:26:36 +02:00
echo $GLOBALS [ 'egw' ] -> framework -> footer ();
2011-02-09 16:58:06 +01:00
}
}