1313
1414class Calendar {
1515
16+ private const CAL_EOL = "\r\n" ;
17+ private string $ timezone = "" ;
18+
1619 public function __construct ( Login $ login ) {
1720 $ this ->login = $ login ;
21+ $ this ->timezone = Config::getTimezone ()->getName ();
1822 }
1923
2024 public function generateICS (DataAccess $ da ) : string {
@@ -23,30 +27,45 @@ public function generateICS(DataAccess $da) : string {
2327 }
2428
2529 private function toICS (array $ plainData ) : string {
26- $ cal = '' ;
27- $ eol = "\r\n" ;
28-
29- $ cal .= 'BEGIN:VCALENDAR ' . $ eol ;
30- $ cal .= 'VERSION:2.0 ' . $ eol ;
31- $ cal .= 'PRODID:https://github.com/KIMB-technologies/TaskTimeTerminateServer ' . $ eol ;
32- $ cal .= 'CALSCALE:GREGORIAN ' . $ eol ;
33- $ cal .= 'METHOD:PUBLISH ' . $ eol ;
34-
35- $ tz = date_default_timezone_get ();
36-
37- foreach ($ plainData as $ dat ){
38- $ cal .= 'BEGIN:VEVENT ' . $ eol ;
39- $ cal .= 'UID: ' . uniqid () . '@ttt-server ' . $ eol ;
30+ $ cal = 'BEGIN:VCALENDAR ' . self ::CAL_EOL ;
31+ $ cal .= 'VERSION:2.0 ' . self ::CAL_EOL ;
32+ $ cal .= 'PRODID:https://github.com/KIMB-technologies/TaskTimeTerminateServer ' . self ::CAL_EOL ;
33+ $ cal .= 'CALSCALE:GREGORIAN ' . self ::CAL_EOL ;
34+ $ cal .= 'METHOD:PUBLISH ' . self ::CAL_EOL ;
4035
41- $ cal .= 'SUMMARY: ' . $ dat ['category ' ] . ' - ' . $ dat ['name ' ] . $ eol ;
42- $ cal .= 'DTSTART;TZID= ' . $ tz . ': ' . date ('Ymd ' , $ dat ['begin ' ]) .'T ' . date ('His ' , $ dat ['begin ' ]) .'Z ' . $ eol ;
43- $ cal .= 'DTEND;TZID= ' . $ tz . ': ' . date ('Ymd ' , $ dat ['end ' ]) .'T ' . date ('His ' , $ dat ['end ' ]) .'Z ' . $ eol ;
44-
45- $ cal .= 'END:VEVENT ' . $ eol ;
36+ // name, category, begin, end
37+ $ current = array ("" ,"" , 0 , 0 );
38+ foreach ( $ plainData as $ dat ){ // will be in order current to past (sees sorting in TTTStats::printDataset())
39+ if (
40+ $ dat ['name ' ] === $ current [0 ] && $ dat ['category ' ] === $ current [1 ] &&
41+ abs ( $ current [2 ] - $ dat ['end ' ] ) < 120
42+ ){ // group to one "event"?
43+ $ current [2 ] = $ dat ['begin ' ];
44+ continue ;
45+ }
46+ if (!empty ($ current [0 ]) && !empty ($ current [1 ])){
47+ $ cal .= $ this ->calEvent (...$ current );
48+ }
49+ $ current = array ($ dat ['name ' ], $ dat ['category ' ], $ dat ['begin ' ], $ dat ['end ' ]);
50+ }
51+ if (!empty ($ current [0 ]) && !empty ($ current [1 ])){
52+ $ cal .= $ this ->calEvent (...$ current );
4653 }
4754
48- $ cal .= 'END:VCALENDAR ' . $ eol ;
49- return $ cal ;
55+ return $ cal . 'END:VCALENDAR ' . self ::CAL_EOL ;
56+ }
57+
58+ private function calEvent (string $ name , string $ category , int $ begin , int $ end ) : string {
59+ return 'BEGIN:VEVENT ' . self ::CAL_EOL
60+ . 'UID: ' . sha1 ($ name . $ category . $ begin . $ end ) . '@ttt-server ' . self ::CAL_EOL
61+ . 'SUMMARY: ' . mb_strcut ($ name . ' - ' . $ category , 0 , 75 - 8 ) . self ::CAL_EOL // maximal 75 octets per line
62+ . $ this ->calTimeRow ($ begin , 'DTSTART ' )
63+ . $ this ->calTimeRow ($ end , 'DTEND ' )
64+ .'END:VEVENT ' . self ::CAL_EOL ;
65+ }
66+
67+ private function calTimeRow (int $ time , string $ rowname ) : string {
68+ return $ rowname . ';TZID= ' . $ this ->timezone . ': ' . date ('Ymd\THis ' , $ time ) .'Z ' . self ::CAL_EOL ;
5069 }
5170
5271 public function getLink (DataAccess $ da ) : string {
0 commit comments