· 5 years ago · Jul 14, 2020, 04:36 PM
1<?php
2/**
3 * BuddyBoss Groups Zoom.
4 *
5 * @package BuddyBoss\Groups\Zoom
6 * @since 1.0.0
7 */
8
9// Exit if accessed directly.
10defined( 'ABSPATH' ) || exit;
11
12/**
13 * Class BP_Group_Zoom
14 */
15class BP_Zoom_Group {
16 /**
17 * Your __construct() method will contain configuration options for
18 * your extension.
19 *
20 * @since 1.0.0
21 */
22 function __construct() {
23 if ( ! bbp_pro_is_license_valid() || ! bp_is_active( 'groups' ) || ! bp_zoom_is_zoom_enabled() || ! bp_zoom_is_zoom_groups_enabled() ) {
24 return false;
25 }
26
27 $this->setup_filters();
28 $this->setup_actions();
29 }
30
31 /**
32 * Setup the group zoom class filters
33 *
34 * @since 1.0.0
35 */
36 private function setup_filters() {
37 add_filter( 'bp_nouveau_customizer_group_nav_items', array( $this, 'customizer_group_nav_items' ), 10 ,2 );
38 }
39
40 /**
41 * setup actions.
42 *
43 * @since 1.0.0
44 */
45 public function setup_actions() {
46 add_action( 'bp_setup_nav', array( $this, 'setup_nav' ), 100 );
47 add_filter( 'document_title_parts', array( $this, 'bp_nouveau_group_zoom_set_page_title' ) );
48 add_filter( 'pre_get_document_title', array( $this, 'bp_nouveau_group_zoom_set_title_tag' ), 999, 1 );
49
50 add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
51
52 // Adds a zoom metabox to the new BuddyBoss Group Admin UI
53 add_action( 'bp_groups_admin_meta_boxes', array( $this, 'group_admin_ui_edit_screen' ) );
54
55 // Saves the zoom options if they come from the BuddyBoss Group Admin UI
56 add_action( 'bp_group_admin_edit_after', array( $this, 'edit_screen_save' ) );
57
58 add_action( 'bp_zoom_meeting_add', array( $this, 'create_activity' ), 10, 2 );
59 add_action( 'bp_zoom_meeting_add', array( $this, 'groups_notification_meeting_created' ), 20, 2 );
60 add_action( 'bp_groups_zoom_meeting_created_notification', array(
61 $this,
62 'groups_format_create_meeting_notification'
63 ), 10, 5 );
64 add_action( 'bp_get_request', array( $this, 'zoom_meeting_mark_notifications' ), 1 );
65 add_action( 'bp_zoom_meeting_deleted_meetings', array( $this, 'delete_meeting_notifications' ) );
66
67 add_action( 'bp_activity_entry_content', array( $this, 'embed_meeting' ), 10 );
68 // Register the activity stream actions
69 add_action( 'bp_register_activity_actions', array( $this, 'register_activity_actions' ) );
70
71 add_action( 'bp_init', array( $this, 'zoom_webhook' ), 10 );
72
73 add_action( 'groups_delete_group', array( $this, 'delete_group_delete_all_meetings' ), 10 );
74 }
75
76 /**
77 * Setup navigation for group zoom tabs.
78 *
79 * @since 1.0.0
80 */
81 public function setup_nav() {
82 // return if no group.
83 if ( ! bp_is_group() ) {
84 return;
85 }
86
87 $current_group = groups_get_current_group();
88 $group_link = bp_get_group_permalink( $current_group );
89 $sub_nav = array();
90
91 // if current group has zoom enable then return.
92 if ( bp_zoom_is_group_setup( $current_group->id ) ) {
93 $sub_nav[] = array(
94 'name' => __( 'Zoom', 'buddyboss-pro' ),
95 'slug' => 'zoom',
96 'parent_url' => $group_link,
97 'parent_slug' => $current_group->slug,
98 'screen_function' => array( $this, 'zoom_page' ),
99 'item_css_id' => 'zoom',
100 'position' => 100,
101 'user_has_access' => $current_group->user_has_access,
102 'no_access_url' => $group_link,
103 );
104
105 $default_args = array(
106 'parent_url' => trailingslashit( $group_link . 'zoom' ),
107 'parent_slug' => $current_group->slug . '_zoom',
108 'screen_function' => array( $this, 'zoom_page' ),
109 'user_has_access' => $current_group->user_has_access,
110 'no_access_url' => $group_link,
111 );
112
113 $sub_nav[] = array_merge(
114 array(
115 'name' => __( 'Upcoming Meetings', 'buddyboss-pro' ),
116 'slug' => 'meetings',
117 'position' => 10,
118 ),
119 $default_args
120 );
121
122 $sub_nav[] = array_merge(
123 array(
124 'name' => __( 'Past Meetings', 'buddyboss-pro' ),
125 'slug' => 'past-meetings',
126 'position' => 20,
127 ),
128 $default_args
129 );
130
131 if ( bp_zoom_groups_can_user_manage_zoom( bp_loggedin_user_id(), $current_group->id ) ) {
132 $sub_nav[] = array_merge(
133 array(
134 'name' => __( 'Create Meeting', 'buddyboss-pro' ),
135 'slug' => 'create-meeting',
136 'position' => 30,
137 ),
138 $default_args
139 );
140 }
141 }
142
143 // If the user is a group admin, then show the group admin nav item.
144 if ( bp_is_item_admin() ) {
145 $admin_link = trailingslashit( $group_link . 'admin' );
146
147 $sub_nav[] = array(
148 'name' => __( 'Zoom', 'buddyboss-pro' ),
149 'slug' => 'zoom',
150 'position' => 100,
151 'parent_url' => $admin_link,
152 'parent_slug' => $current_group->slug . '_manage',
153 'screen_function' => 'groups_screen_group_admin',
154 'user_has_access' => bp_is_item_admin(),
155 'show_in_admin_bar' => true,
156 );
157 }
158
159 foreach ( $sub_nav as $nav ) {
160 bp_core_new_subnav_item( $nav, 'groups' );
161 }
162
163 // save edit screen options.
164 if ( bp_is_groups_component() && bp_is_current_action( 'admin' ) && bp_is_action_variable( 'zoom', 0 ) ) {
165 $this->edit_screen_save( $current_group->id );
166
167 // Load zoom admin page.
168 add_action( 'bp_screens', array( $this, 'zoom_admin_page' ) );
169 }
170 }
171
172 /**
173 * Zoom page callback
174 *
175 * @since 1.0.0
176 */
177 public function zoom_page() {
178 // when sync completes.
179 if ( isset( $_REQUEST['sync_meeting_done'] ) ) {
180 bp_core_add_message( __( 'Group meetings were successfully synced with Zoom.', 'buddyboss-pro' ), 'success' );
181 }
182
183 // if single meeting page and meeting does not exists return 404.
184 if ( bp_zoom_is_single_meeting() && false === bp_zoom_get_current_meeting() ) {
185 bp_do_404();
186
187 return;
188 }
189
190 $group_id = bp_is_group() ? bp_get_current_group_id() : false;
191
192 // if edit meeting page and meeting does not exists return 404.
193 if (
194 ( bp_zoom_is_edit_meeting() && false === bp_zoom_get_edit_meeting() )
195 || ( ! bp_zoom_groups_can_user_manage_zoom( bp_loggedin_user_id(), $group_id ) && bp_zoom_is_create_meeting() )
196 ) {
197 bp_do_404();
198 return;
199 }
200
201 if ( ! bp_zoom_is_create_meeting() ) {
202 $param = array(
203 'per_page' => 1
204 );
205
206 if ( 'past-meetings' === bp_action_variable( 0 ) ) {
207 $param['from'] = wp_date( 'Y-m-d H:i:s', null, new DateTimeZone( 'UTC' ) );
208 $param['since'] = false;
209 $param['sort'] = 'DESC';
210 }
211
212 if ( bp_zoom_is_groups_zoom() && ! bp_zoom_is_single_meeting() && bp_has_zoom_meetings( $param ) ) {
213 while ( bp_zoom_meeting() ) {
214 bp_the_zoom_meeting();
215
216 $group_link = bp_get_group_permalink( groups_get_group( bp_get_zoom_meeting_group_id() ) );
217 $redirect_url = trailingslashit( $group_link . 'zoom/meetings/' . bp_get_zoom_meeting_id() );
218 wp_safe_redirect( $redirect_url );
219 exit;
220 }
221 }
222 }
223
224 add_action( 'bp_template_content', array( $this, 'zoom_page_content' ) );
225 bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'groups/single/home' ) );
226 }
227
228 /**
229 * Zoom admin page callback
230 *
231 * @since 1.0.0
232 */
233 public function zoom_admin_page() {
234 if ( 'zoom' !== bp_get_group_current_admin_tab() ) {
235 return false;
236 }
237
238 if ( ! bp_is_item_admin() && ! bp_current_user_can( 'bp_moderate' ) ) {
239 return false;
240 }
241 add_action( 'groups_custom_edit_steps', array( $this, 'edit_screen' ) );
242 bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'groups/single/home' ) );
243 }
244
245 /**
246 * Display zoom page content.
247 *
248 * @since 1.0.0
249 */
250 function zoom_page_content() {
251 do_action( 'template_notices' );
252 bp_get_template_part( 'groups/single/zoom' );
253 }
254
255 /**
256 * Enqueue scripts for zoom meeting pages.
257 *
258 * @since 1.0.0
259 */
260 public function enqueue_scripts() {
261 if ( ! bp_zoom_is_groups_zoom() ) {
262 return;
263 }
264 wp_enqueue_style( 'jquery-datetimepicker' );
265 wp_enqueue_script( 'jquery-datetimepicker' );
266 wp_enqueue_script( 'bp-select2' );
267 if ( wp_script_is( 'bp-select2-local', 'registered' ) ) {
268 wp_enqueue_script( 'bp-select2-local' );
269 }
270 wp_enqueue_style( 'bp-select2' );
271 }
272
273 /**
274 * Adds a zoom metabox to BuddyBoss Group Admin UI
275 *
276 * @since 1.0.0
277 *
278 * @uses add_meta_box
279 */
280 public function group_admin_ui_edit_screen() {
281 add_meta_box(
282 'bp_zoom_group_admin_ui_meta_box',
283 __( 'Zoom Conference', 'buddyboss-pro' ),
284 array( $this, 'group_admin_ui_display_metabox' ),
285 get_current_screen()->id,
286 'advanced',
287 'high'
288 );
289 }
290
291 /**
292 * Displays the zoom metabox in BuddyBoss Group Admin UI
293 *
294 * @param object $item (group object)
295 *
296 * @since 1.0.0
297 *
298 */
299 public function group_admin_ui_display_metabox( $item ) {
300 $this->edit_screen( $item );
301 }
302
303 /**
304 * Show zoom option form when editing a group
305 *
306 * @param object $group (the group to edit if in Group Admin UI)
307 *
308 * @since 1.0.0
309 * @uses is_admin() To check if we're in the Group Admin UI
310 */
311 public function edit_screen( $group = false ) {
312 $group_id = empty( $group->id ) ? bp_get_new_group_id() : $group->id;
313
314 if ( empty( $group->id ) ) {
315 $group_id = bp_get_new_group_id();
316 }
317
318 if ( empty( $group_id ) ) {
319 $group_id = bp_get_group_id();
320 }
321
322 if ( empty( $group_id ) ) {
323 $group_id = $group->id;
324 }
325
326 $min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
327 wp_enqueue_script( 'bp-zoom-meeting-common', bp_zoom_integration_url( '/assets/js/bp-zoom-meeting-common' . $min . '.js' ), array( 'jquery' ), bb_platform_pro()->version, true );
328 wp_localize_script(
329 'bp-zoom-meeting-common',
330 'bpZoomMeetingCommonVars',
331 array(
332 'ajax_url' => admin_url( 'admin-ajax.php' ),
333 )
334 );
335
336 // Should box be checked already?
337 $checked = bp_zoom_group_is_zoom_enabled( $group_id );
338 $api_key = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-key', true );
339 $api_secret = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-secret', true );
340 $api_email = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-email', true );
341 $webhook_token = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-webhook-token', true );
342 ?>
343
344 <div class="bb-group-zoom-settings-container">
345
346 <h4 class="bb-section-title"><?php esc_html_e( 'Group Zoom Settings', 'buddyboss-pro' ); ?></h4>
347
348 <fieldset>
349 <legend class="screen-reader-text"><?php esc_html_e( 'Group Zoom Settings', 'buddyboss-pro' ); ?></legend>
350 <?php if ( ! is_admin() ) : ?>
351 <p class="bb-section-info"><?php esc_html_e( 'Connect this group to a Zoom account, to allow meetings to be scheduled from this group and synced with Zoom. Once enabled, enter your Zoom API Credentials below, using the "Setup Wizard" button to guide you step by step.', 'buddyboss-pro' ); ?></p>
352 <?php else: ?>
353 <p class="bb-section-info"><?php esc_html_e( 'Connect this group to a Zoom account, to allow meetings to be scheduled from this group and synced with Zoom. Once enabled, enter your Zoom API Credentials below.', 'buddyboss-pro' ); ?></p>
354 <?php endif; ?>
355
356 <div class="field-group">
357 <p class="checkbox bp-checkbox-wrap bp-group-option-enable">
358 <input type="checkbox" name="bp-edit-group-zoom" id="bp-edit-group-zoom" class="bs-styled-checkbox" value="1"<?php checked( $checked ); ?> />
359 <label for="bp-edit-group-zoom"><span><?php esc_html_e( 'Yes, I want to connect this group to Zoom.', 'buddyboss-pro' ); ?></span></label>
360 </p>
361 </div>
362
363 </fieldset>
364
365 <div id="bp-group-zoom-settings-additional" class="group-settings-selections <?php echo ! $checked ? 'bp-hide' : ''; ?>">
366
367 <hr class="bb-sep-line" />
368 <h4 class="bb-section-title"><?php esc_html_e( 'Group Permissions', 'buddyboss-pro' ); ?></h4>
369
370 <fieldset class="radio group-media">
371 <legend class="screen-reader-text"><?php esc_html_e( 'Group Permissions', 'buddyboss-pro' ); ?></legend>
372 <p class="group-setting-label" tabindex="0"><?php esc_html_e( 'Which members of this group are allowed to create, edit and delete Zoom meetings? The "Zoom Account Email" (below) will be assigned as the default host for every meeting in this group, regardless of who created the meeting.', 'buddyboss-pro' ); ?></p>
373
374 <div class="bp-radio-wrap">
375 <input type="radio" name="bp-group-zoom-manager" id="group-zoom-manager-members" class="bs-styled-radio" value="members"<?php bp_zoom_group_show_manager_setting( 'members', $group ); ?> />
376 <label for="group-zoom-manager-members"><?php esc_html_e( 'All group members', 'buddyboss-pro' ); ?></label>
377 </div>
378
379 <div class="bp-radio-wrap">
380 <input type="radio" name="bp-group-zoom-manager" id="group-zoom-manager-mods" class="bs-styled-radio" value="mods"<?php bp_zoom_group_show_manager_setting( 'mods', $group ); ?> />
381 <label for="group-zoom-manager-mods"><?php esc_html_e( 'Organizers and Moderators only', 'buddyboss-pro' ); ?></label>
382 </div>
383
384 <div class="bp-radio-wrap">
385 <input type="radio" name="bp-group-zoom-manager" id="group-zoom-manager-admins" class="bs-styled-radio" value="admins"<?php bp_zoom_group_show_manager_setting( 'admins', $group ); ?> />
386 <label for="group-zoom-manager-admins"><?php esc_html_e( 'Organizers only', 'buddyboss-pro' ); ?></label>
387 </div>
388 </fieldset>
389
390 <hr class="bb-sep-line" />
391 </div>
392
393 <div id="bp-group-zoom-settings" class="bp-group-zoom-settings <?php echo ! $checked ? 'bp-hide' : ''; ?>">
394
395 <h4 class="bb-section-title"><?php esc_html_e( 'Zoom API Credentials', 'buddyboss-pro' ); ?></h4>
396 <legend class="screen-reader-text"><?php esc_html_e( 'Zoom API Credentials', 'buddyboss-pro' ); ?></legend>
397 <div class="bb-field-wrap">
398 <label for="bp-group-zoom-api-key" class="group-setting-label"><?php esc_html_e( 'API Key', 'buddyboss-pro' ); ?>*</label>
399
400 <div class="bp-input-wrap">
401 <input <?php echo ! is_admin() ? 'required' : ''; ?> type="text" name="bp-group-zoom-api-key" id="bp-group-zoom-api-key" class="zoom-group-instructions-main-input" value="<?php echo $api_key; ?>"/>
402 </div>
403 </div>
404
405 <div class="bb-field-wrap">
406 <label for="bp-group-zoom-api-secret" class="group-setting-label"><?php esc_html_e( 'API Secret', 'buddyboss-pro' ); ?>*</label>
407
408 <div class="bp-input-wrap">
409 <input <?php echo ! is_admin() ? 'required' : ''; ?> type="text" name="bp-group-zoom-api-secret" id="bp-group-zoom-api-secret" class="zoom-group-instructions-main-input" value="<?php echo $api_secret; ?>"/>
410 </div>
411 </div>
412
413 <div class="bb-field-wrap">
414 <label for="bp-group-zoom-api-email" class="group-setting-label"><?php esc_html_e( 'Zoom Account Email', 'buddyboss-pro' ); ?>*</label>
415
416 <div class="bp-input-wrap">
417 <input <?php echo ! is_admin() ? 'required' : ''; ?> type="text" name="bp-group-zoom-api-email" id="bp-group-zoom-api-email" class="zoom-group-instructions-main-input" value="<?php echo $api_email; ?>"/>
418 </div>
419 </div>
420
421 <div class="bb-field-wrap">
422 <label for="bp-group-zoom-api-webhook-token" class="group-setting-label"><?php esc_html_e( 'Verification Token', 'buddyboss-pro' ); ?></label>
423
424 <div class="bp-input-wrap">
425 <input type="text" name="bp-group-zoom-api-webhook-token" id="bp-group-zoom-api-webhook-token" class="zoom-group-instructions-main-input" value="<?php echo $webhook_token; ?>"/>
426 <div class="bb-description-info">
427 <span class="bb-url-text"><?php echo esc_url( bp_get_groups_directory_permalink() . '?zoom_webhook=1&group_id=' . $group_id ); ?></span>
428 <a href="#" id="copy-webhook-link" class="copy-webhook-link" data-balloon-pos="down" data-balloon="<?php esc_html_e( 'Copy', 'buddyboss-pro' ); ?>" data-copied="<?php esc_html_e( 'Copied', 'buddyboss-pro' ); ?>" data-webhook-link="<?php echo esc_url( bp_get_groups_directory_permalink() . '?zoom_webhook=1&group_id=' . $group_id ); ?>">
429 <span class="bb-icon-copy"></span>
430 </a>
431 </div>
432 </div>
433 </div>
434 <hr class="bb-sep-line" />
435 </div>
436
437
438 <div class="bp-zoom-group-button-wrap">
439 <?php if ( ! empty( $checked ) && ! empty( $api_key ) && ! empty( $api_secret ) && ! empty( $api_email ) ) { ?>
440 <a class="bp-zoom-group-check-connection" href="#" id="bp-zoom-group-check-connection">
441 <i class="bb-icon-radio"></i>
442 <span><?php _e( 'Check Connection', 'buddyboss-pro' ); ?></span>
443 </a>
444 <?php } ?>
445
446 <?php if ( ! is_admin() ) : ?>
447 <a href="#bp-zoom-group-show-instructions-popup-<?php echo $group_id; ?>" id="bp-zoom-group-show-instructions" class="button outline show-zoom-instructions <?php if ( empty( $checked ) ) { echo 'bp-hide'; }?> ">
448 <?php _e( 'Setup Wizard', 'buddyboss-pro' ); ?>
449 </a>
450 <div id="bp-zoom-group-show-instructions-popup-<?php echo $group_id; ?>" class="bzm-white-popup bp-zoom-group-show-instructions mfp-hide">
451 <header class="bb-zm-model-header"><?php _e( 'Connect a Zoom Account', 'buddyboss-pro' ); ?></header>
452
453 <div class="bp-step-nav-main">
454
455 <div class="bp-step-nav">
456 <ul>
457 <li class="selected"><a href="#step-1"><?php _e('Zoom Login', 'buddyboss-pro' ); ?></a></li>
458 <li><a href="#step-2"><?php _e('Create App', 'buddyboss-pro' ); ?></a></li>
459 <li><a href="#step-3"><?php _e('App Credentials', 'buddyboss-pro' ); ?></a></li>
460 <li><a href="#step-4"><?php _e('Verification Token', 'buddyboss-pro' ); ?></a></li>
461 <li><a href="#step-5"><?php _e('Finish', 'buddyboss-pro' ); ?></a></li>
462 </ul>
463 </div> <!-- .bp-step-nav -->
464
465 <div class="bp-step-blocks">
466
467 <div class="bp-step-block selected" id="step-1">
468 <div id="zoom-instruction-container">
469 <p><?php _e('To use Zoom, we will need you to create an "app" in your Zoom account and connect it to this group so we can sync meeting data with Zoom. This should only take a few minutes if you already have a Zoom account. Note that cloud recordings and alternate hosts will only work if you have a "Pro" or "Business" Zoom account.', 'buddyboss-pro' ); ?></p>
470 <p><?php _e('Start by going to the <a href="https://marketplace.zoom.us/" target="_blank">Zoom App Marketplace</a> and clicking the "Sign In" link in the titlebar. You can sign in using your existing Zoom credentials. If you do not yet have a Zoom account, just click the "Sign Up" link in the titlebar. Once you have successfully signed into Zoom App Marketplace you can move to the next step.', 'buddyboss-pro' ); ?></p>
471 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-sign_in.png' ); ?>" />
472 </div>
473 </div>
474
475 <div class="bp-step-block" id="step-2">
476 <div id="zoom-instruction-container">
477 <p><?php _e('Once you are signed into Zoom App Marketplace, you need to <a href="https://marketplace.zoom.us/develop/create" target="_blank">build an app</a>. You can always find the Build App link by going to "Develop" → "Build App" from the titlebar.', 'buddyboss-pro' ); ?></p>
478 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-build_app.png' ); ?>" />
479 <p><?php _e('On the next page, select the first option "JWT" as the app type and click the "Create" button. If you see the message "Your account already has JWT credentials" you can use the existing app. In that case, click the "View here" link to modify the existing JWT app.', 'buddyboss-pro' ); ?></p>
480 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-app_type.png' ); ?>" />
481 <p><?php _e('After clicking "Create App" you will get a popup asking you to enter an App Name. Enter any name that will remind you the app is being used for this website. Then click the "Create" button.', 'buddyboss-pro' ); ?></p>
482 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-app_name.png' ); ?>" />
483 <p><?php _e( 'After clicking "Create" you will be redirected to a form asking for some basic personal information. Fill out all required fields and click the "Continue" button. Once you see "App Credentials" move to the next step.', 'buddyboss-pro' ); ?></p>
484 </div>
485 </div>
486
487 <div class="bp-step-block" id="step-3">
488 <div id="zoom-instruction-container">
489 <p><?php _e( 'Once you get to the "App Credentials" page, copy the <strong>API Key</strong> and <strong>API Secret</strong> and paste them into the fields in the form below. Then you will need to decide which of the Zoom users in your account should be the default host for all meetings in this group. Enter their email address into the <strong>Zoom Account Email</strong> field below. The email must exist as a Host in your Zoom account.', 'buddyboss-pro' ); ?></p>
490 <div class="bb-group-zoom-settings-container">
491 <div class="bb-field-wrap">
492 <label for="bp-group-zoom-api-key-popup" class="group-setting-label"><?php _e( 'API Key', 'buddyboss-pro' ); ?>*</label>
493 <div class="bp-input-wrap">
494 <input required="" type="text" name="bp-group-zoom-api-key-popup" class="zoom-group-instructions-cloned-input" value="<?php echo $api_key; ?>" />
495 </div>
496 </div>
497
498 <div class="bb-field-wrap">
499 <label for="bp-group-zoom-api-secret-popup" class="group-setting-label"><?php _e( 'API Secret', 'buddyboss-pro' ); ?>*</label>
500 <div class="bp-input-wrap">
501 <input required="" type="text" name="bp-group-zoom-api-secret-popup" class="zoom-group-instructions-cloned-input" value="<?php echo $api_secret; ?>" />
502 </div>
503 </div>
504
505 <div class="bb-field-wrap">
506 <label for="bp-group-zoom-api-email-popup" class="group-setting-label"><?php _e( 'Zoom Account Email', 'buddyboss-pro' ); ?>*</label>
507 <div class="bp-input-wrap">
508 <input required="" type="text" name="bp-group-zoom-api-email-popup" class="zoom-group-instructions-cloned-input" value="<?php echo $api_email; ?>" />
509 </div>
510 </div>
511
512 </div><!-- .bb-group-zoom-settings-container -->
513
514 </div>
515 </div>
516
517 <div class="bp-step-block" id="step-4">
518 <div id="zoom-instruction-container">
519 <p><?php _e( 'Once you have entered the API Key, API Secret, and Zoom Account Email, continue to the "Feature" tab. Enable "Event Subscriptions" and then click "Add new event subscription". This step is necessary to allow meeting updates from Zoom to automatically sync back into your group. Note that within the group on this site, you can also click the "Sync" button at any time to force a manual sync.', 'buddyboss-pro' ); ?></p>
520 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-event_subscription.png' ); ?>" />
521 <p><?php _e( 'For "Subscription Name" you can again enter any name you want. Click the
522 <span class="bb-icon-copy"></span> Copy Link button below to copy a special link, and then paste that link back into Zoom in the field titled "Event notification endpoint URL".', 'buddyboss-pro' ); ?></p>
523 <p><a href="#" class="copy-webhook-link button small outline" data-text="<?php _e( 'Copy Link', 'buddyboss-pro' ); ?>" data-copied="<?php _e( 'Copied', 'buddyboss-pro' ); ?>" data-webhook-link="<?php echo esc_url( bp_get_groups_directory_permalink() . '?zoom_webhook=1&group_id=' . $group_id ); ?>">
524 <span class="bb-icon-copy"></span> <?php _e( 'Copy Link', 'buddyboss-pro' ); ?>
525 </a></p>
526 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-event_notification.png' ); ?>" />
527 <p><?php _e( 'Next, click the "Add events" button. In the popup, make sure to check the following options: <strong>Start Meeting, End Meeting, Meeting has been updated, Meeting has been deleted, All Recordings have completed.</strong>', 'buddyboss-pro' ); ?></p>
528 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-events_1.png' ); ?>" />
529 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-events_2.png' ); ?>" />
530 <p><?php _e( 'Click "Done" to close the popup. In the "Event Subscriptions" box, click "Save".', 'buddyboss-pro' ); ?></p>
531 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-event_save.png' ); ?>" />
532 <p><?php _e( 'You should now see a "Verification Token" created at the top of the page. Click "Copy" and then paste the token into the Verification Token field at the bottom of this form. You\'re almost done!', 'buddyboss-pro' ); ?></p>
533 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-token.png' ); ?>" />
534
535 <div class="bb-group-zoom-settings-container">
536 <div class="bb-field-wrap">
537 <label for="bp-group-zoom-api-webhook-token-popup" class="group-setting-label"><?php _e( 'Verification Token', 'buddyboss-pro' ); ?></label>
538 <div class="bp-input-wrap">
539 <input type="text" name="bp-group-zoom-api-webhook-token-popup" class="zoom-group-instructions-cloned-input" value="<?php echo $webhook_token; ?>">
540 </div>
541 </div>
542 </div>
543 </div>
544 </div>
545
546 <div class="bp-step-block" id="step-5">
547 <div id="zoom-instruction-container">
548 <p><?php _e( 'Now you can click "Continue" back at Zoom. You should see a message that "Your app is activated on the account". At this point we are done with the Zoom website.', 'buddyboss-pro' ); ?></p>
549 <img src="<?php echo bp_zoom_integration_url( '/assets/images/wizard-activated.png' ); ?>" />
550 <p><?php _e( 'Make sure to click the "Save" button on this tab to save the data you entered. Then click the "Check Connection" button on the page to confirm the API was successfully connected. If everything worked you should see a new "Zoom" tab in your group, where you can start scheduling meetings! ', 'buddyboss-pro' ); ?></p>
551 </div>
552 </div>
553
554 </div> <!-- .bp-step-blocks -->
555
556 <div class="bp-step-actions">
557 <span class="bp-step-prev button small outline" style="display: none;"><i class="bb-icon-arrow-left"></i> <?php _e('Previous', 'buddyboss-pro' ); ?></span>
558 <span class="bp-step-next button small outline"><i class="bb-icon-arrow-right"></i> <?php _e('Next', 'buddyboss-pro' ); ?></span>
559
560 <span class="save-settings button small"><?php _e('Save', 'buddyboss-pro' ); ?></span>
561
562 </div> <!-- .bp-step-actions -->
563
564 </div> <!-- .bp-step-nav-main -->
565
566 </div>
567
568 <button type="submit" class="bb-save-settings"><?php esc_attr_e( 'Save Settings', 'buddyboss-pro' ); ?></button>
569 <?php else: ?>
570 <p>
571 <a class="button" href="
572 <?php
573 echo bp_get_admin_url(
574 add_query_arg(
575 array(
576 'page' => 'bp-help',
577 'article' => 88334,
578 ),
579 'admin.php'
580 )
581 );
582 ?>"><?php _e( 'View Tutorial', 'buddyboss-pro' ); ?></a>
583 </p>
584 <?php endif; ?>
585 </div>
586
587 <?php
588
589 // Verify intent
590 if ( is_admin() ) {
591 ?><input type="hidden" id="bp-zoom-group-id" value="<?php echo $group_id; ?>" /><?php
592 wp_nonce_field( 'groups_edit_save_zoom', 'zoom_group_admin_ui' );
593 } else {
594 wp_nonce_field( 'groups_edit_save_zoom' );
595 } ?>
596 </div>
597 <?php
598 }
599
600 /**
601 * Save the Group Zoom data on edit
602 *
603 * @param int $group_id (to handle Group Admin UI hook bp_group_admin_edit_after )
604 *
605 * @since 1.0.0
606 */
607 public function edit_screen_save( $group_id = 0 ) {
608
609 // Bail if not a POST action
610 if ( ! bp_is_post_request() ) {
611 return;
612 }
613
614 // Admin Nonce check
615 if ( is_admin() ) {
616 check_admin_referer( 'groups_edit_save_zoom', 'zoom_group_admin_ui' );
617
618 // Theme-side Nonce check
619 } elseif ( empty( $_REQUEST['_wpnonce'] ) || ( ! empty( $_REQUEST['_wpnonce'] ) && ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'groups_edit_save_zoom' ) ) ) {
620 return;
621 }
622
623 global $wpdb, $bp;
624
625
626 $edit_zoom = ! empty( $_POST['bp-edit-group-zoom'] ) ? true : false;
627 $manager = ! empty( $_POST['bp-group-zoom-manager'] ) ? $_POST['bp-group-zoom-manager'] : bp_zoom_group_get_manager( $group_id );
628 $api_key = ! empty( $_POST['bp-group-zoom-api-key'] ) ? $_POST['bp-group-zoom-api-key'] : '';
629 $api_secret = ! empty( $_POST['bp-group-zoom-api-secret'] ) ? $_POST['bp-group-zoom-api-secret'] : '';
630 $api_email = ! empty( $_POST['bp-group-zoom-api-email'] ) ? $_POST['bp-group-zoom-api-email'] : '';
631 $webhook_token = ! empty( $_POST['bp-group-zoom-api-webhook-token'] ) ? $_POST['bp-group-zoom-api-webhook-token'] : '';
632 $group_id = ! empty( $group_id ) ? $group_id : bp_get_current_group_id();
633
634 groups_update_groupmeta( $group_id, 'bp-group-zoom', $edit_zoom );
635 groups_update_groupmeta( $group_id, 'bp-group-zoom-manager', $manager );
636
637 $api_email = filter_var( $api_email, FILTER_VALIDATE_EMAIL );
638
639 $old_api_email = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-email', true );
640
641 if ( $edit_zoom ) {
642 if ( $api_email ) {
643 bp_zoom_conference()->zoom_api_key = $api_key;
644 bp_zoom_conference()->zoom_api_secret = $api_secret;
645
646 $user_info = bp_zoom_conference()->get_user_info( $api_email );
647
648 if ( 200 === $user_info['code'] && ! empty( $user_info['response'] ) ) {
649 if ( ! empty( $api_email ) ) {
650 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-email', $api_email );
651 }
652
653 if ( ! empty( $api_key ) ) {
654 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-key', $api_key );
655 }
656
657 if ( ! empty( $api_secret ) ) {
658 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-secret', $api_secret );
659 }
660
661 if ( ! empty( $webhook_token ) ) {
662 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-webhook-token', $webhook_token );
663 }
664
665 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-host', $user_info['response']->id );
666 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-host-type', $user_info['response']->type );
667 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-host-user', json_encode( $user_info['response'] ) );
668
669 if ( $old_api_email !== $api_email ) {
670 // Hide old host meetings.
671 $q_hide = $wpdb->prepare( "UPDATE {$bp->table_prefix}bp_zoom_meetings SET hide_sitewide = %d WHERE group_id = %d AND host_id = %s", '1', $group_id, $old_api_email );
672 $wpdb->query( $q_hide );
673
674 // Un-hide current host meetings.
675 $q_un_hide = $wpdb->prepare( "UPDATE {$bp->table_prefix}bp_zoom_meetings SET hide_sitewide = %d WHERE group_id = %d AND host_id = %s", '0', $group_id, $api_email );
676 $wpdb->query( $q_un_hide );
677
678 }
679
680 bp_core_add_message( __( 'Group Zoom settings were successfully updated.', 'buddyboss-pro' ), 'success' );
681
682 } else {
683
684 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-email', $api_email );
685 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-key', $api_key );
686 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-secret', $api_secret );
687 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-webhook-token', $webhook_token );
688 groups_delete_groupmeta( $group_id, 'bp-group-zoom-api-host' );
689 groups_delete_groupmeta( $group_id, 'bp-group-zoom-api-host-type' );
690 groups_delete_groupmeta( $group_id, 'bp-group-zoom-api-host-user' );
691
692 bp_core_add_message( __( 'Invalid Credentials. Please enter valid key, secret key or account email.', 'buddyboss-pro' ), 'error' );
693 }
694 } else {
695
696 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-email', $api_email );
697 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-key', $api_key );
698 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-secret', $api_secret );
699 groups_update_groupmeta( $group_id, 'bp-group-zoom-api-webhook-token', $webhook_token );
700 groups_delete_groupmeta( $group_id, 'bp-group-zoom-api-host' );
701 groups_delete_groupmeta( $group_id, 'bp-group-zoom-api-host-type' );
702 groups_delete_groupmeta( $group_id, 'bp-group-zoom-api-host-user' );
703
704 bp_core_add_message( __( 'There was an error updating group Zoom API settings. Please try again.', 'buddyboss-pro' ), 'error' );
705 }
706 } else {
707 bp_core_add_message( __( 'Group Zoom settings were successfully updated.', 'buddyboss-pro' ), 'success' );
708 }
709
710 /**
711 * Add action that fire before user redirect
712 *
713 * @Since 1.0.0
714 *
715 * @param int $group_id Current group id
716 */
717 do_action( 'bp_group_admin_after_edit_screen_save', $group_id );
718
719 // Redirect after save when not in admin
720 if ( ! is_admin() ) {
721 bp_core_redirect( trailingslashit( bp_get_group_permalink( buddypress()->groups->current_group ) . '/admin/zoom' ) );
722 }
723 }
724
725 /**
726 * Register our activity actions with BuddyBoss
727 *
728 * @since 1.0.0
729 * @uses bp_activity_set_action()
730 */
731 public function register_activity_actions() {
732 // Group activity stream items
733 bp_activity_set_action( buddypress()->groups->id, 'zoom_meeting_create', esc_html__( 'New Zoom meeting', 'buddyboss-pro' ), array(
734 $this,
735 'meeting_activity_action_callback'
736 ) );
737 }
738
739 /**
740 * Zoom meeting activity action.
741 *
742 * @param $action
743 * @param $activity
744 *
745 * @return string
746 * @since 1.0.0
747 */
748 public function meeting_activity_action_callback( $action, $activity ) {
749 if ( 'zoom_meeting_create' === $activity->type && buddypress()->groups->id === $activity->component && ! bp_zoom_is_group_setup( $activity->item_id ) ) {
750 return $action;
751 }
752
753 $user_id = $activity->user_id;
754 $group_id = $activity->item_id;
755 $meeting_id = $activity->secondary_item_id;
756
757 $meeting = new BP_Zoom_Meeting( $meeting_id );
758
759 if ( empty( $meeting->id ) ) {
760 return $action;
761 }
762
763 // User
764 $user_link = bp_core_get_userlink( $user_id );
765
766 // Meeting
767 $meeting_permalink = bp_get_zoom_meeting_url( $group_id, $meeting_id );
768 $meeting_title = $meeting->title;
769 $meeting_link = '<a href="' . $meeting_permalink . '">' . $meeting_title . '</a>';
770
771 $group = groups_get_group( $group_id );
772 $group_link = bp_get_group_link( $group );
773
774 return sprintf(
775 esc_html__( '%1$s scheduled a Zoom meeting %2$s in the group %3$s', 'buddyboss-pro' ),
776 $user_link,
777 $meeting_link,
778 $group_link
779 );
780 }
781
782 /**
783 * Create activity for meeting.
784 *
785 * @param $meeting
786 * @param $args
787 *
788 * @since 1.0.0
789 */
790 public function create_activity( $meeting, $args ) {
791 if ( ! empty( $meeting ) && ! empty( $meeting->group_id ) && empty( $args['id'] ) ) {
792
793 $group = groups_get_group( $meeting->group_id );
794
795 if ( ! empty( $group->id ) ) {
796 $action = sprintf( __( '%1$s scheduled a Zoom meeting in the group %2$s', 'buddyboss-pro' ), bp_core_get_userlink( $meeting->user_id ), '<a href="' . bp_get_group_permalink( $group ) . '">' . esc_attr( $group->name ) . '</a>' );
797
798 $activity_id = groups_record_activity(
799 array(
800 'user_id' => $meeting->user_id,
801 'action' => $action,
802 'content' => '',
803 'type' => 'zoom_meeting_create',
804 'item_id' => $meeting->group_id,
805 'secondary_item_id' => $meeting->id,
806 )
807 );
808
809 if ( $activity_id ) {
810
811 // save activity id in meeting
812 $meeting->activity_id = $activity_id;
813 $meeting->save();
814
815 // update activity meta
816 bp_activity_update_meta( $activity_id, 'bp_meeting_id', $meeting->id );
817
818 groups_update_groupmeta( $meeting->group_id, 'last_activity', bp_core_current_time() );
819 }
820 }
821 }
822 }
823
824 /**
825 * Return activity meeting embed HTML
826 *
827 * @return false|string|void
828 * @since 1.0.0
829 *
830 */
831 public function embed_meeting() {
832 if ( 'zoom_meeting_create' === bp_get_activity_type() &&
833 buddypress()->groups->id === bp_get_activity_object_name() &&
834 ! bp_zoom_is_group_setup( bp_get_activity_item_id() ) ) {
835 return;
836 }
837
838 $meeting_id = bp_activity_get_meta( bp_get_activity_id(), 'bp_meeting_id', true );
839
840 if ( empty( $meeting_id ) ) {
841 return;
842 }
843
844 if ( bp_has_zoom_meetings(
845 array(
846 'include' => $meeting_id,
847 'from' => false,
848 'since' => false,
849 )
850 ) ) {
851 while ( bp_zoom_meeting() ) {
852 bp_the_zoom_meeting();
853
854 bp_get_template_part( 'zoom/activity-meeting-entry' );
855 }
856 }
857 }
858
859 /**
860 * Notify all group members when a meeting is created.
861 *
862 * @param $meeting
863 * @param $args
864 *
865 * @since 1.0.0
866 *
867 */
868 public function groups_notification_meeting_created( $meeting, $args ) {
869 if ( ! bp_is_active( 'notifications' ) || empty( $meeting ) || empty( $meeting->group_id ) || ! empty( $args['id'] ) ) {
870 return;
871 }
872
873 $group = groups_get_group( $meeting->group_id );
874
875 $user_ids = BP_Groups_Member::get_group_member_ids( $group->id );
876 foreach ( (array) $user_ids as $user_id ) {
877
878 // do not add notification for current user.
879 if ( (int) $user_id === bp_loggedin_user_id() ) {
880 continue;
881 }
882
883 // Trigger a BuddyPress Notification.
884 bp_notifications_add_notification(
885 array(
886 'user_id' => $user_id,
887 'item_id' => $meeting->group_id,
888 'secondary_item_id' => $meeting->id,
889 'component_name' => buddypress()->groups->id,
890 'component_action' => 'zoom_meeting_created',
891 )
892 );
893 }
894 }
895
896 /**
897 * Create meeting notification for groups.
898 *
899 * @param $action
900 * @param $item_id
901 * @param $secondary_item_id
902 * @param $total_items
903 * @param $format
904 *
905 * @return mixed|void
906 * @since 1.0.0
907 */
908 public function groups_format_create_meeting_notification( $action, $item_id, $secondary_item_id, $total_items, $format ) {
909 $group_id = $item_id;
910
911 $group = groups_get_group( $group_id );
912 $group_link = bp_get_group_permalink( $group );
913 $meeting = new BP_Zoom_Meeting( $secondary_item_id );
914 $amount = 'single';
915
916 if ( (int) $total_items > 1 ) {
917 $text = sprintf(
918 /* translators: total number of groups. */
919 __( 'You have %1$d new Zoom meetings in groups', 'buddyboss-pro' ),
920 (int) $total_items
921 );
922 $amount = 'multiple';
923 $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
924
925 if ( 'string' === $format ) {
926 /**
927 * Filters multiple promoted to group mod notification for string format.
928 * Complete filter - bp_groups_multiple_member_promoted_to_mod_notification.
929 *
930 * @param string $string HTML anchor tag for notification.
931 * @param int $total_items Total number of rejected requests.
932 * @param string $text Notification content.
933 * @param string $notification_link The permalink for notification.
934 *
935 * @since 1.0.0
936 *
937 */
938 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $text, $notification_link );
939 } else {
940 /**
941 * Filters multiple promoted to group mod notification for non-string format.
942 * Complete filter - bp_groups_multiple_member_promoted_to_mod_notification.
943 *
944 * @param array $array Array holding permalink and content for notification.
945 * @param int $total_items Total number of rejected requests.
946 * @param string $text Notification content.
947 * @param string $notification_link The permalink for notification.
948 *
949 * @since 1.0.0
950 *
951 */
952 return apply_filters(
953 'bp_groups_' . $amount . '_' . $action . '_notification',
954 array(
955 'link' => $notification_link,
956 'text' => $text,
957 ),
958 $total_items,
959 $text,
960 $notification_link
961 );
962 }
963 } else {
964 $text = sprintf(
965 /* translators: 1 Meeting title. 2 Group Title. */
966 __( 'Zoom meeting "%1$s" created in the group "%2$s"', 'buddyboss-pro' ),
967 $meeting->title,
968 $group->name
969 );
970 $notification_link = wp_nonce_url(
971 add_query_arg(
972 array(
973 'action' => 'bp_mark_read',
974 'group_id' => $item_id,
975 'meeting_id' => $secondary_item_id,
976 ),
977 $group_link . 'zoom/meetings/' . $secondary_item_id
978 ),
979 'bp_mark_meeting_' . $item_id
980 );
981
982 if ( 'string' === $format ) {
983 /**
984 * Filters single promoted to group mod notification for string format.
985 * Complete filter - bp_groups_single_zoom_meeting_created_notification.
986 *
987 * @param string $string HTML anchor tag for notification.
988 * @param int $group_link The permalink for the group.
989 * @param string $group ->name Name of the group.
990 * @param string $text Notification content.
991 * @param string $notification_link The permalink for notification.
992 *
993 * @since 1.0.0
994 *
995 */
996 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link );
997 } else {
998 /**
999 * Filters single promoted to group admin notification for non-string format.
1000 * Complete filter - bp_groups_single_member_promoted_to_mod_notification.
1001 *
1002 * @param array $array Array holding permalink and content for notification.
1003 * @param int $group_link The permalink for the group.
1004 * @param string $group ->name Name of the group.
1005 * @param string $text Notification content.
1006 * @param string $notification_link The permalink for notification.
1007 *
1008 * @since 1.0.0
1009 *
1010 */
1011 return apply_filters(
1012 'bp_groups_' . $amount . '_' . $action . '_notification',
1013 array(
1014 'link' => $notification_link,
1015 'text' => $text,
1016 ),
1017 $group_link,
1018 $group->name,
1019 $text,
1020 $notification_link
1021 );
1022 }
1023 }
1024 }
1025
1026 /**
1027 * Mark zoom meeting notifications.
1028 *
1029 * @param string $action
1030 *
1031 * @since 1.0.0
1032 */
1033 public function zoom_meeting_mark_notifications( $action = '' ) {
1034 // Bail if no group ID is passed
1035 if ( empty( $_GET['group_id'] ) ) {
1036 return;
1037 }
1038
1039 // Bail if action is not for this function
1040 if ( 'bp_mark_read' !== $action ) {
1041 return;
1042 }
1043
1044 // Get required data
1045 $user_id = bp_loggedin_user_id();
1046 $meeting_id = intval( $_GET['meeting_id'] );
1047 $group_id = intval( $_GET['group_id'] );
1048
1049 // Check nonce
1050 if ( ! bp_verify_nonce_request( 'bp_mark_meeting_' . $group_id ) ) {
1051 return;
1052
1053 // Check current user's ability to edit the user
1054 } elseif ( ! current_user_can( 'edit_user', $user_id ) ) {
1055 return;
1056 }
1057
1058 if ( ! empty( $meeting_id ) ) {
1059 // Attempt to clear notifications for the current user from this meeting
1060 $success = bp_notifications_mark_notifications_by_item_id( $user_id, intval( $_GET['group_id'] ), buddypress()->groups->id, 'zoom_meeting_created', intval( $_GET['meeting_id'] ) );
1061 } else {
1062 // Attempt to clear notifications for the current user from this topic
1063 $success = bp_notifications_mark_notifications_by_item_id( $user_id, $group_id, buddypress()->groups->id, 'zoom_meeting_created' );
1064 }
1065
1066 // Do additional subscriptions actions
1067 do_action( 'bp_zoom_meeting_mark_notifications_handler', $success, $user_id, $group_id, $action, $meeting_id );
1068 }
1069
1070 /**
1071 * Delete create meeting notifications.
1072 *
1073 * @param $meeting_ids
1074 *
1075 * @since 1.0.0
1076 */
1077 public function delete_meeting_notifications( $meeting_ids ) {
1078 if ( ! bp_is_active( 'notifications' ) ) {
1079 return;
1080 }
1081
1082 if ( ! empty( $meeting_ids ) ) {
1083 foreach ( $meeting_ids as $meeting_id ) {
1084 $meeting = new BP_Zoom_Meeting( $meeting_id );
1085
1086 if ( ! empty( $meeting->id ) && ! empty( $meeting->group_id ) && ! empty( $meeting->user ) ) {
1087 bp_notifications_delete_notifications_by_item_id( $meeting->user, $meeting->group_id, buddypress()->groups->id, 'zoom_meeting_created', $meeting_id );
1088 }
1089 }
1090 }
1091 }
1092
1093 /**
1094 * Customizer group nav items.
1095 *
1096 * @param array $nav_items
1097 * @param object $group
1098 *
1099 * @since 1.0.0
1100 */
1101 public function customizer_group_nav_items( $nav_items, $group ) {
1102 $nav_items['zoom'] = array(
1103 'name' => __( 'Zoom', 'buddyboss-pro' ),
1104 'slug' => 'zoom',
1105 'parent_slug' => $group->slug,
1106 'position' => 90,
1107 );
1108
1109 return $nav_items;
1110 }
1111
1112 /**
1113 * Zoom webhook handler
1114 *
1115 * @since 1.0.0
1116 */
1117 public function zoom_webhook() {
1118 $zoom_webhook = filter_input( INPUT_GET, 'zoom_webhook', FILTER_VALIDATE_INT );
1119
1120 if ( ! empty( $zoom_webhook ) && 1 === $zoom_webhook ) {
1121
1122 $group_id = filter_input( INPUT_GET, 'group_id', FILTER_VALIDATE_INT );
1123 if ( ! empty( $group_id ) && 0 < $group_id && bp_zoom_is_group_setup( $group_id ) && ! empty( groups_get_group( $group_id ) ) ) {
1124 $content = file_get_contents( "php://input" );
1125 $json = json_decode( $content, true );
1126 $token = false;
1127
1128 foreach ( getallheaders() as $header_name => $header_value ) {
1129 if ( 'Authorization' === $header_name ) {
1130 $token = $header_value;
1131 break;
1132 }
1133 }
1134
1135 $group_token = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-webhook-token', true );
1136
1137 if ( empty( trim( $group_token ) ) || trim( $group_token ) !== trim( $token ) ) {
1138 $this->forbid('No token detected' );
1139 exit;
1140 }
1141
1142 if ( ! empty( $json['event'] ) && ! empty( $json['payload']['object'] ) ) {
1143 $event = $json['event'];
1144 $object = $json['payload']['object'];
1145 $zoom_meeting_id = ! empty( $object['id'] ) ? $object['id'] : false;
1146 $meeting_response = bp_zoom_meeting_get_specific( array( 'meeting_id' => $zoom_meeting_id ) );
1147 $meeting = false;
1148
1149 if ( ! empty( $meeting_response['meetings'][0] ) ) {
1150 $meeting = new BP_Zoom_Meeting( $meeting_response['meetings'][0]->id );
1151
1152 if ( empty( $meeting->id ) ) {
1153 $this->forbid('No token detected' );
1154 exit;
1155 }
1156 }
1157
1158 if ( empty( $meeting ) ) {
1159 $this->forbid('No token detected' );
1160 exit;
1161 }
1162
1163 switch( $event ) {
1164 case 'meeting.started' :
1165 bp_zoom_meeting_update_meta( $meeting->id, 'meeting_status', 'started' );
1166 break;
1167
1168 case 'meeting.ended' :
1169 bp_zoom_meeting_update_meta( $meeting->id, 'meeting_status', 'ended' );
1170 break;
1171
1172 case 'meeting.deleted' :
1173 bp_zoom_meeting_delete( array( 'id' => $meeting->id ) );
1174 break;
1175
1176 case 'meeting.updated' :
1177 if ( isset( $object['topic'] ) ) {
1178 $meeting->title = $object['topic'];
1179 }
1180
1181 // todo: we are not supporting other meeting types now, future enhancement.
1182 if ( isset( $object['type'] ) && ( 8 === $object['type'] || 3 === $object['type'] || 4 === $object['type'] ) ) {
1183 $meeting->hide_sitewide = true;
1184 } else if ( isset( $object['type'] ) ) {
1185 $meeting->hide_sitewide = false;
1186 }
1187
1188 if ( isset( $object['timezone'] ) ) {
1189 $meeting->timezone = $object['timezone'];
1190 }
1191
1192 if ( isset( $object['start_time'] ) ) {
1193 $meeting->start_date_utc = $object['start_time'];
1194 $meeting->start_date = wp_date( 'Y-m-d\TH:i:s', strtotime( $meeting->start_date_utc ), new DateTimeZone( $meeting->timezone ) );
1195 }
1196
1197 if ( isset( $object['duration'] ) ) {
1198 $meeting->duration = (int) $object['duration'];
1199 }
1200
1201 if ( isset( $object['agenda'] ) ) {
1202 $meeting->description = $object['agenda'];
1203 }
1204
1205 if ( isset( $object['start_url'] ) ) {
1206 groups_update_groupmeta( $group_id, 'zoom_start_url', $object['start_url'] );
1207 }
1208
1209 if ( isset( $object['join_url'] ) ) {
1210 groups_update_groupmeta( $group_id, 'zoom_join_url', $object['join_url'] );
1211 }
1212
1213 if ( isset( $object['password'] ) ) {
1214 $meeting->password = $object['password'];
1215 }
1216
1217 if ( isset( $object['settings'] ) ) {
1218 $settings = $object['settings'];
1219
1220 if ( isset( $settings['host_video'] ) ) {
1221 $meeting->host_video = (bool) $settings['host_video'];
1222 }
1223
1224 if ( isset( $settings['participant_video'] ) ) {
1225 $meeting->participants_video = (bool) $settings['participant_video'];
1226 }
1227
1228 if ( isset( $settings['join_before_host'] ) ) {
1229 $meeting->join_before_host = (bool) $settings['join_before_host'];
1230 }
1231
1232 if ( isset( $settings['mute_upon_entry'] ) ) {
1233 $meeting->mute_participants = (bool) $settings['mute_upon_entry'];
1234 }
1235
1236 if ( isset( $settings['approval_type'] ) ) {
1237 $approval_type = (int) $settings['approval_type'];
1238
1239 if ( in_array( $approval_type, array( 0, 1 ) ) ) {
1240 $api_key = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-key', true );
1241 $api_secret = groups_get_groupmeta( $group_id, 'bp-group-zoom-api-secret', true );
1242 bp_zoom_conference()->zoom_api_key = ! empty( $api_key ) ? $api_key : '';
1243 bp_zoom_conference()->zoom_api_secret = ! empty( $api_secret ) ? $api_secret : '';
1244 $zoom_meeting = bp_zoom_conference()->get_meeting_info( $zoom_meeting_id );
1245 if ( isset( $zoom_meeting['response']->registration_url ) && ! empty( $zoom_meeting['response']->registration_url ) ) {
1246 bp_zoom_meeting_update_meta( $meeting->id, 'zoom_registration_url', $zoom_meeting['response']->registration_url );
1247 }
1248 } else {
1249 bp_zoom_meeting_delete_meta( $meeting->id, 'zoom_registration_url' );
1250 }
1251 }
1252
1253 if ( isset( $settings['auto_recording'] ) ) {
1254 $meeting->auto_recording = $settings['auto_recording'];
1255 }
1256
1257 if ( isset( $settings['alternative_hosts'] ) ) {
1258 $meeting->alternative_host_ids = $settings['alternative_hosts'];
1259 }
1260
1261 if ( isset( $settings['waiting_room'] ) ) {
1262 $meeting->waiting_room = (bool) $settings['waiting_room'];
1263 }
1264
1265 if ( isset( $settings['meeting_authentication'] ) ) {
1266 $meeting->meeting_authentication = (bool) $settings['meeting_authentication'];
1267 }
1268 }
1269
1270 $meeting->save();
1271 break;
1272 case 'recording.completed':
1273 if ( ! bp_zoom_is_zoom_recordings_enabled() ) {
1274 break;
1275 }
1276 $password = ! empty( $object['password'] ) ? $object['password'] : '';
1277 $recording_files = ! empty( $object['recording_files'] ) ? $object['recording_files'] : array();
1278 $start_time = ! empty( $object['start_time'] ) ? $object['start_time'] : '';
1279 if ( ! empty( $recording_files ) ) {
1280 foreach ( $recording_files as $recording_file ) {
1281 $recording_id = ( isset( $recording_file['id'] ) ? $recording_file['id'] : '' );
1282 if ( ! empty( $recording_id ) && empty( bp_zoom_recording_get( array(), array( 'recording_id' => $recording_id ) ) ) ) {
1283 bp_zoom_recording_add( array(
1284 'recording_id' => $recording_id,
1285 'meeting_id' => $zoom_meeting_id,
1286 'uuid' => $object['uuid'],
1287 'details' => $recording_file,
1288 'password' => $password,
1289 'file_type' => $recording_file['file_type'],
1290 'start_time' => $start_time,
1291 ) );
1292 } elseif ( empty( $recording_id ) && empty( bp_zoom_recording_get( array(), array(
1293 'meeting_id' => $zoom_meeting_id,
1294 'uuid' => $object['uuid'],
1295 'file_type' => 'TIMELINE',
1296 ) ) ) ) {
1297 bp_zoom_recording_add( array(
1298 'recording_id' => $recording_id,
1299 'meeting_id' => $zoom_meeting_id,
1300 'uuid' => $object['uuid'],
1301 'details' => $recording_file,
1302 'password' => $password,
1303 'file_type' => $recording_file['file_type'],
1304 'start_time' => $start_time,
1305 ) );
1306 }
1307 }
1308
1309 $count = bp_zoom_recording_get( array(), array(
1310 'meeting_id' => $zoom_meeting_id,
1311 ) );
1312
1313 bp_zoom_meeting_update_meta($meeting->id, 'zoom_recording_count', (int)count($count));
1314 }
1315 break;
1316 }
1317 }
1318 }
1319 }
1320 }
1321
1322 /**
1323 * Forbid zoom webhook.
1324 *
1325 * @since 1.0.0
1326 *
1327 * @param $reason
1328 */
1329 public function forbid( $reason ) {
1330 // format the error
1331 $error = "=== ERROR: " . $reason . " ===\n*** ACCESS DENIED ***\n";
1332
1333 // forbid
1334 http_response_code( 403 );
1335
1336 echo $error;
1337
1338 // stop executing
1339 exit;
1340 }
1341
1342 /**
1343 * Setup page title for the zoom.
1344 *
1345 * @param $title
1346 *
1347 * @return mixed
1348 * @since 1.0.0
1349 */
1350 public function bp_nouveau_group_zoom_set_page_title( $title ) {
1351
1352 global $bp, $bp_zoom_current_meeting;
1353 $new_title = '';
1354
1355 if ( bp_zoom_is_single_meeting() ) {
1356 $new_title = $bp_zoom_current_meeting->title;
1357 }
1358
1359 if ( empty( $new_title ) && 'past-meetings' === bp_zoom_group_current_meeting_tab() ) {
1360 $new_title = esc_html__( 'Past Meetings', 'buddyboss-pro' );
1361 }
1362
1363 if ( empty( $new_title ) && 'meetings' === bp_zoom_group_current_meeting_tab() ) {
1364 $new_title = esc_html__( 'Upcoming Meetings', 'buddyboss-pro' );
1365 }
1366
1367 if ( empty( $new_title ) && 'create-meeting' === bp_zoom_group_current_meeting_tab() ) {
1368 $new_title = esc_html__( 'Create Meeting', 'buddyboss-pro' );
1369 }
1370
1371 if ( strlen( $new_title ) > 0 ) {
1372 $title['title'] = $new_title;
1373 }
1374
1375 return $title;
1376 }
1377
1378 /**
1379 * Setup title tag for the page.
1380 *
1381 * @param $title
1382 *
1383 * @return mixed
1384 * @since 1.0.0
1385 */
1386 function bp_nouveau_group_zoom_set_title_tag( $title ) {
1387
1388 global $bp, $bp_zoom_current_meeting;
1389 $new_title = "";
1390
1391 if ( bp_zoom_is_single_meeting() ) {
1392 $new_title = $bp_zoom_current_meeting->title;
1393 }
1394
1395 if ( empty( $new_title ) && 'past-meetings' === bp_zoom_group_current_meeting_tab() ) {
1396 $new_title = esc_html__( 'Past Meetings', 'buddyboss-pro' );
1397 }
1398
1399 if ( empty( $new_title ) && 'meetings' === bp_zoom_group_current_meeting_tab() ) {
1400 $new_title = esc_html__( 'Upcoming Meetings', 'buddyboss-pro' );
1401 }
1402
1403 if ( empty( $new_title ) && 'create-meeting' === bp_zoom_group_current_meeting_tab() ) {
1404 $new_title = esc_html__( 'Create Meeting', 'buddyboss-pro' );
1405 }
1406
1407 if ( in_array( bp_zoom_group_current_meeting_tab(), array( 'meetings', 'past-meetings', 'create-meeting' ) ) || bp_zoom_is_single_meeting() ) {
1408 $sep = apply_filters( 'document_title_separator', '-' );
1409 $get_current_group = bp_get_current_group_name();
1410
1411 $new_title = $new_title . ' ' . $sep . ' ' . $get_current_group . ' ' . $sep . ' ' . bp_get_site_name();
1412 }
1413
1414 //Combine the new title with the old (separator and tagline)
1415 if ( strlen( $new_title ) > 0 ) {
1416 $title = $new_title . " " . $title;
1417 }
1418
1419 return $title;
1420 }
1421
1422 /**
1423 * Remove all meetings belonging to a specific group.
1424 *
1425 * @since 1.0.0
1426 *
1427 * @param int $group_id ID of the group.
1428 */
1429 public function delete_group_delete_all_meetings( $group_id ) {
1430 bp_zoom_meeting_delete( array( 'group_id' => $group_id ) );
1431 }
1432}