Zoom_Helpers

Class Zoom_Helpers

Contents

  • Methods

  • Source Source

    File: src/integrations/zoom/helpers/zoom-helpers.php

    class Zoom_Helpers {
    
    	/**
    	 * @var Zoom_Helpers
    	 */
    	public $options;
    	/**
    	 * @var Zoom_Helpers
    	 */
    	public $pro;
    	/**
    	 * @var Zoom_Helpers
    	 */
    	public $setting_tab;
    
    	/**
    	 * @var bool
    	 */
    	public $load_options;
    
    	/**
    	 * Zoom_Helpers constructor.
    	 */
    	public function __construct() {
    
    		$this->load_options = Automator()->helpers->recipe->maybe_load_trigger_options( __CLASS__ );
    
    		$this->setting_tab   = 'zoom_api';
    		$this->automator_api = AUTOMATOR_API_URL . 'v2/zoom';
    
    		add_filter( 'uap_settings_tabs', array( $this, 'add_zoom_api_settings' ), 15 );
    		add_action( 'init', array( $this, 'zoom_oauth_save' ), 200 );
    
    		// Disconnect wp-ajax action.
    		add_action( 'wp_ajax_uap_automator_zoom_api_disconnect', array( $this, 'disconnect' ), 10 );
    	}
    
    	/**
    	 * @param Zoom_Helpers $options
    	 */
    	public function setOptions( Zoom_Helpers $options ) {
    		$this->options = $options;
    	}
    
    	/**
    	 * @param Zoom_Pro_Helpers $pro
    	 */
    	public function setPro( Zoom_Pro_Helpers $pro ) {
    		$this->pro = $pro;
    	}
    
    
    	/**
    	 * @param string $label
    	 * @param string $option_code
    	 * @param array $args
    	 *
    	 * @return mixed
    	 */
    	public function get_meetings( $label = null, $option_code = 'ZOOMMEETINGS', $args = array() ) {
    
    		if ( ! $this->load_options ) {
    			return Automator()->helpers->recipe->build_default_options_array( $label, $option_code );
    		}
    
    		if ( ! $label ) {
    			$label = __( 'Meeting', 'uncanny-automator' );
    		}
    
    		$args = wp_parse_args(
    			$args,
    			array(
    				'uo_include_any' => false,
    				'uo_any_label'   => __( 'Any Meeting', 'uncanny-automator' ),
    			)
    		);
    
    		$token        = key_exists( 'token', $args ) ? $args['token'] : true;
    		$is_ajax      = key_exists( 'is_ajax', $args ) ? $args['is_ajax'] : false;
    		$target_field = key_exists( 'target_field', $args ) ? $args['target_field'] : '';
    		$end_point    = key_exists( 'endpoint', $args ) ? $args['endpoint'] : '';
    		$options      = array();
    
    		if ( Automator()->helpers->recipe->load_helpers ) {
    
    			$client = $this->get_client();
    			
    			if ( ! $client || empty( $client['access_token'] ) ) {
    				return Automator()->helpers->recipe->build_default_options_array( $label, $option_code );
    			}
    
    			// API register call
    			$response = wp_remote_post(
    				$this->automator_api,
    				array(
    					'body' =>
    						array(
    							'action'       => 'get_meetings',
    							'access_token' => $client['access_token'],
    							'page_number'  => 1,
    							'page_size'    => 1000,
    							'type'         => 'upcoming',
    						),
    				)
    			);
    
    			$response_code = wp_remote_retrieve_response_code( $response );
    
    			// prepare meeting lists
    			if ( $response_code === 200 ) {
    
    				$response_body = json_decode( wp_remote_retrieve_body( $response ), true );
    
    				if ( count( $response_body['data']['meetings'] ) > 0 ) {
    
    					foreach ( $response_body['data']['meetings'] as $meeting ) {
    						$meeting_key                            = (string) $meeting['id'];
    						$options[ $meeting_key . '-objectkey' ] = $meeting['topic'];
    					}
    				}
    			}
    		}
    
    		$option = array(
    			'option_code'     => $option_code,
    			'label'           => $label,
    			'input_type'      => 'select',
    			'required'        => true,
    			'supports_tokens' => $token,
    			'is_ajax'         => $is_ajax,
    			'fill_values_in'  => $target_field,
    			'endpoint'        => $end_point,
    			'options'         => $options,
    		);
    
    		return apply_filters( 'uap_option_zoom_get_meetings', $option );
    	}
    
    	/**
    	 * For registering user to meeting action method.
    	 *
    	 * @param string $user_id
    	 * @param string $meeting_key
    	 *
    	 * @return array
    	 */
    	public function register_user( $user_id, $meeting_key ) {
    
    		$user = get_userdata( $user_id );
    
    		if ( is_wp_error( $user ) ) {
    			return array(
    				'result'  => false,
    				'message' => __( 'Zoom user not found.', 'uncanny-automator' ),
    			);
    		}
    
    		$customer_first_name = $user->first_name;
    		$customer_last_name  = $user->last_name;
    		$customer_email      = $user->user_email;
    
    		if ( ! empty( $customer_email ) ) {
    			$customer_email_parts = explode( '@', $customer_email );
    			$customer_first_name  = empty( $customer_first_name ) ? $customer_email_parts[0] : $customer_first_name;
    			$customer_last_name   = empty( $customer_last_name ) ? $customer_email_parts[0] : $customer_last_name;
    		}
    
    		$client = $this->get_client();
    
    		if ( ! $client || empty( $client['access_token'] ) ) {
    			return array(
    				'result'  => false,
    				'message' => __( 'Zoom credentials have expired.', 'uncanny-automator' ),
    			);
    		}
    
    		$response = wp_remote_post(
    			$this->automator_api,
    			array(
    				'body' =>
    					array(
    						'action'       => 'register_meeting_user',
    						'access_token' => $client['access_token'],
    						'meeting_key'  => $meeting_key,
    						'first_name'   => $customer_first_name,
    						'last_name'    => $customer_last_name,
    						'email'        => $customer_email,
    					),
    			)
    		);
    
    		if ( ! is_wp_error( $response ) ) {
    
    			$body = json_decode( wp_remote_retrieve_body( $response ), true );
    
    			if ( 201 === wp_remote_retrieve_response_code( $response ) ) {
    
    				if ( isset( $body['data']['join_url'] ) ) {
    					return array(
    						'result'  => true,
    						'message' => __( 'Successfully registered', 'uncanny-automator' ),
    					);
    				}
    			} else {
    
    				$error = '';
    
    				if ( isset( $body['data']['message'] ) ) {
    					$error = $body['data']['message'];
    				} elseif ( isset( $body['error']['description'] ) ) {
    					$error = $body['error']['description'];
    				}
    
    				return array(
    					'result'  => false,
    					'message' => __( $error, 'uncanny-automator' ),
    				);
    			}
    		}
    
    		return array(
    			'result'  => false,
    			'message' => __( 'WordPress was not able to communicate with Zoom API.', 'uncanny-automator' ),
    		);
    	}
    
    	/**
    	 * For registering a user to meeting action method.
    	 *
    	 * @param string $user
    	 * @param string $meeting_key
    	 *
    	 * @return array
    	 */
    	public function register_userless( $user, $meeting_key ) {
    
    		$customer_email       = $user['EMAIL'];
    		$customer_email_parts = explode( '@', $customer_email );
    
    		$customer_first_name = empty( $user['FIRSTNAME'] ) ? $customer_email_parts[0] : $user['FIRSTNAME'];
    		$customer_last_name  = empty( $user['LASTNAME'] ) ? $customer_email_parts[0] : $user['LASTNAME'];
    
    		$client = $this->get_client();
    
    		if ( ! $client || empty( $client['access_token'] ) ) {
    			return array(
    				'result'  => false,
    				'message' => __( 'Zoom credentials have expired.', 'uncanny-automator' ),
    			);
    		}
    
    		$response = wp_remote_post(
    			$this->automator_api,
    			array(
    				'body' =>
    					array(
    						'action'       => 'register_meeting_user',
    						'access_token' => $client['access_token'],
    						'meeting_key'  => $meeting_key,
    						'first_name'   => $customer_first_name,
    						'last_name'    => $customer_last_name,
    						'email'        => $customer_email,
    					),
    			)
    		);
    
    		if ( ! is_wp_error( $response ) ) {
    
    			$body = json_decode( wp_remote_retrieve_body( $response ), true );
    
    			if ( 201 === wp_remote_retrieve_response_code( $response ) ) {
    
    				if ( isset( $body['data']['join_url'] ) ) {
    
    					return array(
    						'result'  => true,
    						'message' => __( 'Successfully registered', 'uncanny-automator' ),
    					);
    				}
    			} else {
    
    				$error = '';
    
    				if ( isset( $body['data']['message'] ) ) {
    					$error = $body['data']['message'];
    				} elseif ( isset( $body['error']['description'] ) ) {
    					$error = $body['error']['description'];
    				}
    
    				return array(
    					'result'  => false,
    					'message' => __( $error, 'uncanny-automator' ),
    				);
    			}
    		}
    
    		return array(
    			'result'  => false,
    			'message' => __( 'WordPress was not able to communicate with Zoom API.', 'uncanny-automator' ),
    		);
    	}
    
    	/**
    	 * For un-registering user to meeting action method.
    	 *
    	 * @param string $user_id
    	 * @param string $meeting_key
    	 *
    	 * @return array
    	 */
    	public function unregister_user( $email, $meeting_key ) {
    
    		$client = $this->get_client();
    
    		if ( ! $client || empty( $client['access_token'] ) ) {
    			return array(
    				'result'  => false,
    				'message' => __( 'Zoom credentails have expired.', 'uncanny-automator' ),
    			);
    		}
    
    		$response = wp_remote_post(
    			$this->automator_api,
    			array(
    				'body' =>
    					array(
    						'action'       => 'unregister_meeting_user',
    						'access_token' => $client['access_token'],
    						'meeting_key'  => $meeting_key,
    						'email'        => $email,
    					),
    			)
    		);
    
    		if ( ! is_wp_error( $response ) ) {
    
    			if ( 201 === wp_remote_retrieve_response_code( $response ) || 204 === wp_remote_retrieve_response_code( $response ) ) {
    
    				return array(
    					'result'  => true,
    					'message' => __( 'Successfully unregistered', 'uncanny-automator' ),
    				);
    
    			} else {
    
    				$body = json_decode( wp_remote_retrieve_body( $response ), true );
    
    				$error = '';
    
    				if ( isset( $body['data']['message'] ) ) {
    					$error = $body['data']['message'];
    				} elseif ( isset( $body['error']['description'] ) ) {
    					$error = $body['error']['description'];
    				}
    
    				return array(
    					'result'  => false,
    					'message' => __( $error, 'uncanny-automator' ),
    				);
    			}
    		}
    
    		return array(
    			'result'  => false,
    			'message' => __( 'WordPress was not able to communicate with Zoom API.', 'uncanny-automator' ),
    		);
    	}
    
    	/**
    	 * Check if the settings tab should display.
    	 *
    	 * @return boolean.
    	 */
    	public function display_settings_tab() {
    
    		if ( Automator()->utilities->has_valid_license() ) {
    			return true;
    		}
    
    		if ( Automator()->utilities->is_from_modal_action() ) {
    			return true;
    		}
    
    		return ! empty( $this->get_client() );
    	}
    
    	/**
    	 * @param $tabs
    	 *
    	 * @return mixed
    	 */
    	public function add_zoom_api_settings( $tabs ) {
    
    		if ( ! $this->display_settings_tab() ) {
    			return $tabs;
    		}
    
    		$tab_url = admin_url( 'edit.php' ) . '?post_type=uo-recipe&page=uncanny-automator-settings&tab=' . $this->setting_tab;
    
    		$tabs[ $this->setting_tab ] = array(
    			'name'           => __( 'Zoom Meeting', 'uncanny-automator' ),
    			'title'          => __( 'Zoom Meeting API settings', 'uncanny-automator' ),
    			'description'    => sprintf(
    				'<p>%1$s</p>',
    				sprintf(
    					__( "Connecting to Zoom requires setting up a JWT application and getting 2 values from inside your account. It's really easy, we promise! Visit %1\$s for simple instructions.", 'uncanny-automator' ),
    					'<a href="' . automator_utm_parameters( 'https://automatorplugin.com/knowledge-base/zoom/', 'settings', 'zoom_meeting-kb_article' ) . '" target="_blank">https://automatorplugin.com/knowledge-base/zoom/</a>'
    				)
    			) . $this->get_user_info(),
    			'is_pro'         => false,
    			'is_expired'     => false,
    			'settings_field' => 'uap_automator_zoom_api_settings',
    			'wp_nonce_field' => 'uap_automator_zoom_api_nonce',
    			'save_btn_name'  => 'uap_automator_zoom_api_save',
    			'save_btn_title' => __( 'Save API details', 'uncanny-automator' ),
    			'fields'         => array(
    				'uap_automator_zoom_api_consumer_key'    => array(
    					'title'       => __( 'API key:', 'uncanny-automator' ),
    					'type'        => 'text',
    					'css_classes' => '',
    					'placeholder' => '',
    					'default'     => '',
    					'required'    => true,
    					'custom_atts' => array( 'autocomplete' => 'off' ),
    				),
    				'uap_automator_zoom_api_consumer_secret' => array(
    					'title'       => __( 'API secret:', 'uncanny-automator' ),
    					'type'        => 'password',
    					'css_classes' => '',
    					'placeholder' => '',
    					'default'     => '',
    					'required'    => true,
    					'custom_atts' => array( 'autocomplete' => 'off' ),
    				),
    			),
    		);
    
    		return $tabs;
    	}
    
    	/**
    	 * Action when settings added, it will redirect user to 3rd party for OAuth connect.
    	 */
    	public function zoom_oauth_save() {
    
    		if ( isset( $_POST['uap_automator_zoom_api_nonce'] ) && wp_verify_nonce( $_POST['uap_automator_zoom_api_nonce'], 'uap_automator_zoom_api_nonce' ) ) {
    
    			if ( isset( $_POST['uap_automator_zoom_api_consumer_key'] ) && ! empty( $_POST['uap_automator_zoom_api_consumer_key'] ) && isset( $_POST['uap_automator_zoom_api_consumer_secret'] ) && ! empty( $_POST['uap_automator_zoom_api_consumer_secret'] ) ) {
    
    				update_option( 'uap_automator_zoom_api_consumer_key', $_POST['uap_automator_zoom_api_consumer_key'] );
    				update_option( 'uap_automator_zoom_api_consumer_secret', $_POST['uap_automator_zoom_api_consumer_secret'] );
    				delete_transient( 'uap_automator_zoom_api_user_info' );
    
    				$client = $this->refresh_token();
    
    				// Check if token is working fine or not.
    				$response = wp_remote_post(
    					$this->automator_api,
    					array(
    						'body' =>
    							array(
    								'action'       => 'get_meetings',
    								'access_token' => $client['access_token'],
    								'page_number'  => 1,
    								'page_size'    => 300,
    								'type'         => 'upcoming',
    							),
    					)
    				);
    
    				$status_code = wp_remote_retrieve_response_code( $response );
    
    				// Check for a meeting API call if not 200 then its wrong pair.
    				if ( $status_code !== 200 ) {
    
    					$body = json_decode( wp_remote_retrieve_body( $response ), true );
    
    					delete_option( '_uncannyowl_zoom_settings' );
    
    					$error_status = $body['data']['message'] ? $body['data']['message'] : '2';
    
    					wp_safe_redirect( admin_url( 'edit.php?post_type=uo-recipe&page=uncanny-automator-settings&tab=' . $this->setting_tab . '&connect=' . $error_status ) );
    
    				} else {
    
    					wp_safe_redirect( admin_url( 'edit.php?post_type=uo-recipe&page=uncanny-automator-settings&tab=' . $this->setting_tab . '&connect=1' ) );
    
    				}
    
    				die;
    
    			}
    		}
    	}
    
    	/**
    	 * Get the connected user from Zoom API.
    	 *
    	 * @return string The HTML of the user.
    	 */
    	public function get_user_info() {
    
    		ob_start();
    
    		$zoom_user = $this->api_get_user_info();
    
    		// Bail out if zoom user if empty.
    		if ( false === $zoom_user ) {
    			return;
    		}
    		?>
    
    		<?php $this->get_inline_style(); ?>
    
    		<p>
    			<div class="uo-zoom-user-info">
    
    				<div class="uo-zoom-user-info__avatar">
    					<?php if ( ! isset( $zoom_user->pic_url ) ) : ?>
    						<div class="uo-zoom-user-info-placeholder-avatar">
    							<span class="dashicons dashicons-admin-users"></span>
    						</div>
    					<?php else : ?>
    						<img width="32" src="<?php echo esc_url( $zoom_user->pic_url ); ?>" alt="<?php esc_attr_e( 'Profile Pic', 'uncanny-automator' ); ?>" />
    					<?php endif; ?>
    				</div>
    
    				<div class="uo-zoom-user-info__email">
    					<?php echo esc_html( $zoom_user->email ); ?>
    				</div>
    
    				<div class="uo-zoom-user-info__name">
    
    					<?php echo esc_html( sprintf( '(%s %s)', ! empty( $zoom_user->first_name ) ? $zoom_user->first_name : '', ! empty( $zoom_user->last_name ) ? $zoom_user->last_name : '' ) ); ?>
    				</div>
    
    			</div><!--.uo-zoom-user-info-->
    		</p>
    		<p>
    			<?php
    			$disconnect_uri = add_query_arg(
    				array(
    					'action' => 'uap_automator_zoom_api_disconnect',
    					'nonce'  => wp_create_nonce( 'uap_automator_zoom_api_disconnect' ),
    				),
    				admin_url( 'admin-ajax.php' )
    			);
    			?>
    			<a class="uo-settings-btn uo-settings-btn--error" href="<?php echo esc_url( $disconnect_uri ); ?>" title="<?php esc_attr_e( 'Disconnect', 'uncanny-automator' ); ?>">
    				<?php esc_html_e( 'Disconnect', 'uncanny-automator' ); ?>
    			</a>
    			<br/>
    		</p>
    		<?php
    
    		return ob_get_clean();
    	}
    
    	/**
    	 * Returns the zoom user from transient or from zoom api.
    	 *
    	 * @return mixed The zoom user if tokens are available. Otherwise, false.
    	 */
    	public function api_get_user_info() {
    
    		$transient_key = 'uap_automator_zoom_api_user_info';
    
    		$saved_user_info = get_transient( $transient_key );
    
    		if ( false !== $saved_user_info ) {
    			return $saved_user_info;
    		}
    
    		$client = $this->get_client();
    
    		if ( ! $client || empty( $client['access_token'] ) ) {
    			return false;
    		}
    
    		$response = wp_remote_post(
    			$this->automator_api,
    			array(
    				'body' =>
    					array(
    						'action'       => 'get_user',
    						'access_token' => $client['access_token'],
    					),
    			)
    		);
    
    		$status_code = wp_remote_retrieve_response_code( $response );
    
    		if ( 200 === $status_code ) {
    			$response_body = json_decode( wp_remote_retrieve_body( $response ) );
    			set_transient( $transient_key, $response_body->data, WEEK_IN_SECONDS );
    			return $response_body->data;
    		}
    
    		return false;
    
    	}
    
    	/**
    	 * Outputs inline style to format the html return of user info.
    	 *
    	 * @return void.
    	 */
    	public function get_inline_style() {
    		?>
    		<style>
    		.uo-settings-content-description a.uo-settings-btn--error {
    			color: #e94b35;
    		}
    		.uo-settings-content-description a.uo-settings-btn--error:focus,
    		.uo-settings-content-description a.uo-settings-btn--error:active,
    		.uo-settings-content-description a.uo-settings-btn--error:hover {
    			color: #fff;
    		}
    		.uo-zoom-user-info {
    			display: flex;
    			align-items: center;
    			margin: 20px 0 0;
    		}
    		.uo-zoom-user-info__avatar {
    			background: #fff;
    			box-shadow: 0 2px 5px 0 rgb(0 0 0 / 10%);
    			border-radius: 32px;
    			height: 32px;
    			overflow: hidden;
    			width: 32px;
    			text-align: center;
    			display: inline-flex;
    			align-items: center;
    			justify-content: center;
    			color: #2D8CFF;
    			margin-right: 5px;
    		}
    		.uo-zoom-user-info__avatar img {
    			border-radius:32px;
    		}
    		.uo-zoom-user-info__name {
    			opacity: 0.75;
    			margin-left: 5px;
    		}
    		</style>
    		<?php
    	}
    
    	/**
    	 * get_client
    	 *
    	 * @return void
    	 */
    	public function get_client() {
    
    		$client = get_option( '_uncannyowl_zoom_settings' );
    
    		if ( ! $client || empty( $client['access_token'] ) ) {
    			return false;
    		}
    
    		if ( empty( $client['expires'] ) || $client['expires'] < time() ) {
    			return $this->refresh_token();
    		}
    
    		return $client;
    
    	}
    
    	/**
    	 * refresh_token
    	 *
    	 * @param  array $client
    	 * @return void
    	 */
    	public function refresh_token() {
    
    		$client = array();
    
    		// Get the API key and secret
    		$consumer_key    = trim( get_option( 'uap_automator_zoom_api_consumer_key', '' ) );
    		$consumer_secret = trim( get_option( 'uap_automator_zoom_api_consumer_secret', '' ) );
    
    		if ( empty( $consumer_key ) || empty( $consumer_secret ) ) {
    			return false;
    		}
    
    		// Set the token expiration to 1 minute as recommended in the docuemntation
    		$client['expires'] = time() + 60;
    
    		$payload = array(
    			'iss' => $consumer_key,
    			'exp' => $client['expires'],
    		);
    
    		// Generate the access token using the JWT library
    		$token = JWT::encode( $payload, $consumer_secret );
    
    		$client['access_token'] = $token;
    		$client['refresh_token'] = $token;
    
    		// Cache it in settings
    		update_option( '_uncannyowl_zoom_settings', $client );
    
    		return $client;
    	}
    
    	/**
    	 * Disconnect the user from the Zoom API.
    	 *
    	 * @return void.
    	 */
    	public function disconnect() {
    
    		if ( wp_verify_nonce( filter_input( INPUT_GET, 'nonce', FILTER_DEFAULT ), 'uap_automator_zoom_api_disconnect' ) ) {
    
    			delete_option( 'uap_automator_zoom_api_consumer_key' );
    			delete_option( 'uap_automator_zoom_api_consumer_secret' );
    
    			delete_option( '_uncannyowl_zoom_settings_version' );
    			delete_option( '_uncannyowl_zoom_settings' );
    
    			delete_transient( '_uncannyowl_zoom_settings' );
    			delete_transient( 'uap_automator_zoom_api_user_info' );
    
    		}
    
    		$return_uri = add_query_arg(
    			array(
    				'post_type' => 'uo-recipe',
    				'page'      => 'uncanny-automator-settings',
    				'tab'       => 'zoom_api',
    			),
    			admin_url( 'edit.php' )
    		);
    
    		wp_safe_redirect( $return_uri );
    
    		exit;
    
    	}
    }
    

    Methods Methods