| @@ -10,11 +10,130 @@ | ||
| 10 | 10 | * Class Calendar |
| 11 | 11 | */ |
| 12 | 12 | class Calendar { |
| 13 | 13 | const TIMETICS_TIMEZONE_URI = 'https://www.googleapis.com/calendar/v3/users/me/settings/timezone'; |
| 14 | - const TIMETICS_CALENDAR_EVENT = 'https://www.googleapis.com/calendar/v3/calendars/primary/events/'; | |
| 14 | + const TIMETICS_CALENDAR_EVENT = 'https://www.googleapis.com/calendar/v3/calendars/primary/events'; | |
| 15 | 15 | |
| 16 | + | |
| 16 | 17 | /** |
| 18 | + * Get events from the calendar for the last 3 months. | |
| 19 | + * | |
| 20 | + * @param int $user_id Team member ID. | |
| 21 | + * @param array $api_filters Additional API filters for google calendar API | |
| 22 | + * | |
| 23 | + * @return array List of calendar events. | |
| 24 | + */ | |
| 25 | + public function get_events( $user_id, $api_filters = array() ) { | |
| 26 | + $access_token = timetics_get_google_access_token($user_id); | |
| 27 | + | |
| 28 | + if ( ! $access_token ) { | |
| 29 | + return ['error' => 'Access token not found or expired.']; | |
| 30 | + } | |
| 31 | + | |
| 32 | + // Define the time range for the last 3 months | |
| 33 | + $three_months_ago = date('c', strtotime('-3 months')); | |
| 34 | + $three_months_ahead = date('c', strtotime('+3 months')); // 3 months ahead date-time in RFC3339 format | |
| 35 | + | |
| 36 | + $filters = array( | |
| 37 | + 'timeMin' => rawurlencode($three_months_ago), | |
| 38 | + 'timeMax' => rawurlencode($three_months_ahead), | |
| 39 | + 'orderBy' => 'startTime', | |
| 40 | + 'singleEvents' => 'true', | |
| 41 | + ); | |
| 42 | + | |
| 43 | + // add additional api filters if needed | |
| 44 | + $filters = array_merge( $filters, $api_filters ); | |
| 45 | + | |
| 46 | + // API URL with time range filter | |
| 47 | + $api_url = add_query_arg( $filters, self::TIMETICS_CALENDAR_EVENT); | |
| 48 | + | |
| 49 | + // Set headers | |
| 50 | + $args = [ | |
| 51 | + 'headers' => [ | |
| 52 | + 'Authorization' => 'Bearer ' . $access_token, | |
| 53 | + 'Content-Type' => 'application/json', | |
| 54 | + ], | |
| 55 | + ]; | |
| 56 | + | |
| 57 | + // Fetch data from Google Calendar API | |
| 58 | + $response = wp_remote_get( $api_url, $args ); | |
| 59 | + if ( is_wp_error( $response ) ) { | |
| 60 | + return []; | |
| 61 | + } | |
| 62 | + | |
| 63 | + $body = wp_remote_retrieve_body( $response ); | |
| 64 | + $events = json_decode($body, true); | |
| 65 | + | |
| 66 | + if ( empty( $events['items'] ) ) { | |
| 67 | + return []; | |
| 68 | + } | |
| 69 | + | |
| 70 | + // Filter required fields | |
| 71 | + $filtered_events = []; | |
| 72 | + foreach ( $events['items'] as $event ) { | |
| 73 | + if ( empty( $event['start'] ) ) { | |
| 74 | + continue; | |
| 75 | + } | |
| 76 | + | |
| 77 | + $start = ! empty($event['start']['dateTime']) ? $event['start']['dateTime'] : $event['start']['date']; | |
| 78 | + $end = ! empty($event['end']['dateTime']) ? $event['end']['dateTime'] : $event['end']['date']; | |
| 79 | + | |
| 80 | + $timezone = $event['start']['timeZone'] ?? wp_timezone_string(); | |
| 81 | + $timezone = new \DateTimeZone( $timezone ); | |
| 82 | + | |
| 83 | + $start_dt = new \DateTime( $start ); | |
| 84 | + $start_dt->setTimezone( $timezone ); | |
| 85 | + | |
| 86 | + $end_dt = new \DateTime( $end ); | |
| 87 | + $end_dt->setTimezone( $timezone ); | |
| 88 | + | |
| 89 | + $filtered_events[] = [ | |
| 90 | + 'id' => $event['id'] ?? '', | |
| 91 | + 'start_date' => $start_dt->format( 'Y-m-d' ), | |
| 92 | + 'start_time' => $start_dt->format( 'H:i:s' ), | |
| 93 | + 'end_date' => $end_dt->format( 'Y-m-d' ), | |
| 94 | + 'end_time' => $end_dt->format( 'H:i:s' ), | |
| 95 | + 'summary' => $event['summary'] ?? '', | |
| 96 | + 'description'=> $event['description'] ?? '', | |
| 97 | + ]; | |
| 98 | + } | |
| 99 | + | |
| 100 | + return $filtered_events; | |
| 101 | + } | |
| 102 | + | |
| 103 | + /** | |
| 104 | + * Get event by ID | |
| 105 | + * | |
| 106 | + * @param string $event_id | |
| 107 | + * | |
| 108 | + * @return JSON | WP_Error | |
| 109 | + */ | |
| 110 | + public function get_event( $event_id , $user_id = null ) { | |
| 111 | + if ( ! $user_id ) { | |
| 112 | + $user_id = get_current_user_id(); | |
| 113 | + } | |
| 114 | + | |
| 115 | + $access_token = timetics_get_google_access_token( $user_id ); | |
| 116 | + | |
| 117 | + $data = [ | |
| 118 | + 'headers' => [ | |
| 119 | + 'Authorization' => 'Bearer ' . $access_token, | |
| 120 | + ], | |
| 121 | + ]; | |
| 122 | + | |
| 123 | + $response = wp_remote_get(self::TIMETICS_CALENDAR_EVENT . '/' . $event_id, $data); | |
| 124 | + | |
| 125 | + if ( is_wp_error( $response ) ) { | |
| 126 | + return ['error' => $response->get_error_message()]; | |
| 127 | + } | |
| 128 | + | |
| 129 | + $body = wp_remote_retrieve_body( $response ); | |
| 130 | + $event = json_decode($body, true); | |
| 131 | + | |
| 132 | + return $event; | |
| 133 | + } | |
| 134 | + | |
| 135 | + /** | |
| 17 | 136 | * Create event |
| 18 | 137 | * |
| 19 | 138 | * @param array $args Event data |
| 20 | 139 | * |
| @@ -31,8 +150,10 @@ | ||
| 31 | 150 | 'google_meet' => true, |
| 32 | 151 | 'access_token' => '', |
| 33 | 152 | ]; |
| 34 | 153 | |
| 154 | + $args = apply_filters( 'timetics/booking/create/google-event', $args); | |
| 155 | + | |
| 35 | 156 | $args = wp_parse_args( $args, $defaults ); |
| 36 | 157 | $data = $this->prepare_request_data( $args ); |
| 37 | 158 | |
| 38 | 159 | $query_params = build_query( [ |
| @@ -85,9 +206,9 @@ | ||
| 85 | 206 | |
| 86 | 207 | $data = $this->prepare_request_data( $args ); |
| 87 | 208 | $data['method'] = 'PUT'; |
| 88 | 209 | |
| 89 | - $response = wp_remote_post( self::TIMETICS_CALENDAR_EVENT . $event_id . '?' . $query_params, $data ); | |
| 210 | + $response = wp_remote_post( self::TIMETICS_CALENDAR_EVENT . '/' . $event_id . '?' . $query_params, $data ); | |
| 90 | 211 | |
| 91 | 212 | if ( is_wp_error( $response ) ) { |
| 92 | 213 | return false; |
| 93 | 214 | } |
| @@ -137,9 +258,9 @@ | ||
| 137 | 258 | 'conferenceDataVersion' => '1', |
| 138 | 259 | 'sendUpdates' => 'all', |
| 139 | 260 | ] ); |
| 140 | 261 | |
| 141 | - $response = wp_remote_post( self::TIMETICS_CALENDAR_EVENT . $event_id . '?' . $query_params, [ | |
| 262 | + $response = wp_remote_post( self::TIMETICS_CALENDAR_EVENT . '/' . $event_id . '?' . $query_params, [ | |
| 142 | 263 | 'headers' => [ |
| 143 | 264 | 'Authorization' => 'Bearer ' . $access_token, |
| 144 | 265 | 'Content-Type' => 'application/json; charset=utf-8', |
| 145 | 266 | ], |
| @@ -184,13 +305,13 @@ | ||
| 184 | 305 | * |
| 185 | 306 | * @return array |
| 186 | 307 | */ |
| 187 | 308 | private function prepare_time( $data, $access_token ) { |
| 188 | - $start_date = isset( $data['start']['date'] ) ? $data['start']['date'] : gmdate( 'Y-m-d' ); | |
| 189 | - $start_time = isset( $data['start']['time'] ) ? $data['start']['time'] : gmdate( 'H:i:s' ); | |
| 190 | - $end_date = isset( $data['end']['date'] ) ? $data['end']['date'] : gmdate( 'Y-m-d' ); | |
| 191 | - $end_time = isset( $data['end']['time'] ) ? $data['end']['time'] : gmdate( 'H:i:s' ); | |
| 192 | - $timezone = $this->get_timezone( $access_token ); | |
| 309 | + $start_date = isset( $data['start']['date'] ) ? $data['start']['date'] : gmdate( 'Y-m-d' ); | |
| 310 | + $start_time = isset( $data['start']['time'] ) ? $data['start']['time'] : gmdate( 'H:i:s' ); | |
| 311 | + $end_date = isset( $data['end']['date'] ) ? $data['end']['date'] : gmdate( 'Y-m-d' ); | |
| 312 | + $end_time = isset( $data['end']['time'] ) ? $data['end']['time'] : gmdate( 'H:i:s' ); | |
| 313 | + $timezone = isset( $data['timezone'] ) ? $data['timezone'] : 'Asia/Dhaka'; | |
| 193 | 314 | $timezone_offset = $this->get_timezone_offset( $timezone ); |
| 194 | 315 | |
| 195 | 316 | $start_date_time = $start_date . 'T' . $this->convertTo24HourFormat( $start_time ) . $timezone_offset; |
| 196 | 317 | $end_date_time = $end_date . 'T' . $this->convertTo24HourFormat( $end_time ) . $timezone_offset; |
| @@ -216,22 +337,9 @@ | ||
| 216 | 337 | * |
| 217 | 338 | * @return string |
| 218 | 339 | */ |
| 219 | 340 | public function convertTo24HourFormat( $time ) { |
| 220 | - $hours = intval( substr( $time, 0, 2 ) ); | |
| 221 | - $minutes = intval( substr( $time, 3, 2 ) ); | |
| 222 | - $seconds = intval( substr( $time, 6, 2 ) ); | |
| 223 | - $ampm = substr( $time, 9 ); | |
| 224 | - | |
| 225 | - if ( strtolower( $ampm ) == 'pm' && $hours < 12 ) { | |
| 226 | - $hours += 12; | |
| 227 | - } | |
| 228 | - | |
| 229 | - if ( strtolower( $ampm ) == "am" && $hours == 12 ) { | |
| 230 | - $hours = 0; | |
| 231 | - } | |
| 232 | - | |
| 233 | - return sprintf( "%02d:%02d:%02d", $hours, $minutes, $seconds ); | |
| 341 | + return date('H:i:s', strtotime( $time ) ); | |
| 234 | 342 | } |
| 235 | 343 | |
| 236 | 344 | /** |
| 237 | 345 | * Prepare event create requested data |
| @@ -243,10 +351,11 @@ | ||
| 243 | 351 | private function prepare_request_data( $args = [] ) { |
| 244 | 352 | $access_token = $args['access_token']; |
| 245 | 353 | $date = $this->prepare_time( |
| 246 | 354 | [ |
| 247 | - 'start' => $args['start'], | |
| 248 | - 'end' => $args['end'], | |
| 355 | + 'start' => $args['start'], | |
| 356 | + 'end' => $args['end'], | |
| 357 | + 'timezone' => $args['timezone'], | |
| 249 | 358 | ], |
| 250 | 359 | $access_token |
| 251 | 360 | ); |
| 252 | 361 | |