diff --git a/api/v3/class-wpgh-api-v3-broadcasts.php b/api/v3/class-wpgh-api-v3-broadcasts.php new file mode 100644 index 000000000..b5e971b4d --- /dev/null +++ b/api/v3/class-wpgh-api-v3-broadcasts.php @@ -0,0 +1,283 @@ +get_auth_callback(); + + register_rest_route(self::NAME_SPACE, '/broadcasts', [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_broadcast' ], + 'permission_callback' => $auth_callback, + ] + ] ); + + register_rest_route(self::NAME_SPACE, '/broadcasts/schedule' ,array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'schedule_broadcast' ], + 'permission_callback' => $auth_callback, +// 'args'=> array( +// 'id_or_email' => [ +// 'required' => true, +// 'description' => _x('The ID or email of the contact you want to send email to.','api','groundhogg'), +// ], +// 'by_user_id' => [ +// 'required' => false, +// 'description' => _x( 'Search using the user ID.', 'api', 'groundhogg' ), +// ], +// 'email_id' => [ +// 'required' => true, +// 'description' => _x( 'Email ID which you want to send.', 'api', 'groundhogg' ), +// ] +// ) + )); + + } + + /** + * Get a list of broadcast. + * + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function get_broadcast( WP_REST_Request $request ) + { +// if ( ! current_user_can( 'edit_emails' ) ){ +// return self::ERROR_INVALID_PERMISSIONS(); +// } +// +// $query = $request->get_param( 'query' ) ? (array) $request->get_param( 'query' ) : []; +// +// $search = $request->get_param( 'q' ) ? $request->get_param( 'q' ) : $request->get_param( 'search' ) ; +// $search = sanitize_text_field( stripslashes( $search ) ); +// +// if ( ! key_exists( 'search', $query ) && ! empty( $search ) ){ +// $query[ 'search' ] = $search; +// } +// +// $is_for_select = filter_var( $request->get_param( 'select' ), FILTER_VALIDATE_BOOLEAN ); +// $is_for_select2 = filter_var( $request->get_param( 'select2' ), FILTER_VALIDATE_BOOLEAN ); +// +// $emails = WPGH()->emails->get_emails( $query ); +// +// if ( $is_for_select2 ){ +// $json = array(); +// +// foreach ( $emails as $i => $email ) { +// +// $json[] = array( +// 'id' => $email->ID, +// 'text' => $email->subject . ' (' . $email->status . ')' +// ); +// +// } +// +// $results = array( 'results' => $json, 'more' => false ); +// +// return rest_ensure_response( $results ); +// } +// +// if ( $is_for_select ){ +// +// $response_emails = []; +// +// foreach ( $emails as $i => $email ) { +// $response_emails[ $email->ID ] = $email->subject; +// } +// +// $emails = $response_emails; +// +// } + + $broadcasts = WPGH()->broadcasts->get_broadcasts(); + $response_broadcast = []; + foreach ( $broadcasts as $broadcast ){ + + if ( $broadcast->status == 'sent' && $broadcast->object_type == 'email') { + + $total = WPGH()->events->count( array( + 'funnel_id' => WPGH_BROADCAST, + 'step_id' => $broadcast->ID + ) ); + + $opens = WPGH()->activity->count( array( + 'funnel_id' => WPGH_BROADCAST, + 'step_id' => $broadcast->ID, + 'activity_type' => 'email_opened' + ) ); + + $clicks = WPGH()->activity->count( array( + 'funnel_id' => WPGH_BROADCAST, + 'step_id' => $broadcast->ID, + 'activity_type' => 'email_link_click' + ) ); + + $stats = [ + 'total' => $total, + 'opens' => $opens, + 'clicks'=> $clicks + ]; + + $broadcast->stats = $stats; + } + + if ($broadcast->object_type === 'email') { + + $email = WPGH()->emails->get_email($broadcast->object_id); + + $broadcast->object_name = $email->subject; + } + + + if ($broadcast->object_type === 'sms') { + + $sms = WPGH()->sms->get_sms($broadcast->object_id); + + $broadcast->object_name = $sms->title; + } + + + + $p_time = intval( $broadcast->send_time ) + ( wpgh_get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); + + $broadcast->send_time = date_i18n( 'jS F, Y \@ h:i A', intval( $p_time ) ); + + $response_broadcast[] = $broadcast; + } + return self::SUCCESS_RESPONSE( [ 'broadcasts' => $broadcasts ] ); + } + + /** + * Schedule broadcast for provided tags. + * + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function schedule_broadcast( WP_REST_Request $request ) + { + if (!current_user_can('schedule_broadcasts')) { + return self::ERROR_INVALID_PERMISSIONS(); + } + + $config = []; + + $object_id = intval( $request->get_param( 'email_or_sms_id' ) ); + $tags = wp_parse_id_list( $request->get_param('tags' ) ); + $exclude_tags = wp_parse_id_list( $request->get_param('exclude_tags' ) ); + $date = $request->get_param('date'); + $time = $request->get_param('time'); + $send_now = $request->get_param('send_now'); + $send_in_timezone = $request->get_param('local_time' ); + $type = $request->get_param('type'); + + /* Set the object */ + $config['object_id'] = $object_id; + $config['object_type'] = $type; + + if ( $config[ 'object_type' ] === 'email' ){ + $email = new WPGH_Email( $object_id ); + if ( $email->is_draft() ){ + return self::ERROR_400('email_in_draft_mode', sprintf( _x( 'You cannot schedule an email while it is in draft mode.', 'api', 'groundhogg' ) ) ); + } + } + + $contact_sum = 0; + + foreach ($tags as $tag) { + $tag = WPGH()->tags->get_tag(intval($tag)); + if ($tag) { + $contact_sum += $tag->contact_count; + } + } + + if ( $contact_sum === 0 ) { + return self::ERROR_400('no_contacts', sprintf( _x( 'Please select a tag with at least 1 contact.', 'api', 'groundhogg' ) ) ); + } + + if($date) { + $send_date = $date; + } else { + $send_date = date('Y/m/d', strtotime('tomorrow')); + } + + if ($time){ + $send_time = $time; + } else { + $send_time = '9:30'; + } + + $time_string = $send_date . ' ' . $send_time; + + /* convert to UTC */ + $send_time = wpgh_convert_to_utc_0(strtotime($time_string)); + + if ($send_now) { + $config['send_now'] = true; + $send_time = time() + 10; + } + + if ($send_time < time()) { + return self::ERROR_400('invalid_date', _x( 'Please select a time in the future', 'api', 'groundhogg' ) ); + } + + /* Set the email */ + $config['send_time'] = $send_time; + + $args = array( + 'object_id' => $object_id, + 'object_type' => $config[ 'object_type' ], + 'tags' => $tags, + 'send_time' => $send_time, + 'scheduled_by' => get_current_user_id(), + 'status' => 'scheduled', + ); + + $broadcast_id = WPGH()->broadcasts->add($args); + + if (!$broadcast_id) { + return self::ERROR_UNKNOWN(); + } + + $config['broadcast_id'] = $broadcast_id; + + $query = array( + 'tags_include' => $tags, + 'tags_exclude' => $exclude_tags + ); + + $config['contact_query'] = $query; + + if (isset($_POST['send_in_timezone'])) { + $config['send_in_local_time'] = true; + } + + set_transient('gh_get_broadcast_config', $config, HOUR_IN_SECONDS); + + return self::SUCCESS_RESPONSE( [], _x( 'Broadcast scheduled successfully.', 'api', 'groundhogg' ) ); + } +} \ No newline at end of file diff --git a/api/v3/class-wpgh-api-v3-bulk-job-listener.php b/api/v3/class-wpgh-api-v3-bulk-job-listener.php new file mode 100644 index 000000000..67c8f3bad --- /dev/null +++ b/api/v3/class-wpgh-api-v3-bulk-job-listener.php @@ -0,0 +1,145 @@ +broadcast_bulk_job = new WPGH_Broadcast_Bulk_Job(); + + parent::__construct(); + } + + public function register_routes() + { + + $auth_callback = $this->get_auth_callback(); + + register_rest_route('gh/v3', '/bulk-jobs', [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_init_data' ], + 'permission_callback' => $auth_callback, + 'args' => [ + 'bulk_action' => [ + 'required' => true + ] + ] + ], + [ + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'ajax' ], + 'permission_callback' => $auth_callback, + 'args' => [ + 'bulk_action' => [ + 'required' => true + ], + 'items' => [ + 'required' => true + ] + ] + ], + ] ); + } + + /** + * @return null|string|string[]|WP_Error + */ + private function get_bulk_action( ) + { + // Sanitize the bulk action + // Permitted Characters 0-9, A-z, _, -, / to keep inline with the Groundhogg Action Structure. No spaces. + $bulk_action = preg_replace( '/[^0-9A-z_\-\/]/', '', $_GET[ 'bulk_action' ] ); + + if ( ! $bulk_action ){ + return self::ERROR_403( 'invalid_action', 'Invalid bulk action provided.' ); + } + + return $bulk_action; + } + + public function query( WP_REST_Request $request ) + { + $items = apply_filters( "groundhogg/bulk_job/{$this->get_bulk_action()}/query", [] ); + return self::SUCCESS_RESPONSE( [ 'items' => $items ] ); + } + + public function max_items( WP_REST_Request $request ) + { + $items = apply_filters( "groundhogg/bulk_job/{$this->get_bulk_action()}/query", [] ); + $max_items = apply_filters( "groundhogg/bulk_job/{$this->get_bulk_action()}/max_items", 25, $items ); + return self::SUCCESS_RESPONSE( [ 'max_items' => $max_items ] ); + } + + public function get_init_data( WP_REST_Request $request ) + { + $items = apply_filters( "groundhogg/bulk_job/{$this->get_bulk_action()}/query", [] ); + $max_items = apply_filters( "groundhogg/bulk_job/{$this->get_bulk_action()}/max_items", 25, $items ); + return self::SUCCESS_RESPONSE( [ 'items' => $items, 'max_items' => $max_items, 'config' => get_transient( 'gh_get_broadcast_config' ) ] ); + } + + /** + * Get a list of broadcast. + * + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function ajax( WP_REST_Request $request ) + { + if ( ! current_user_can( 'perform_bulk_actions' ) ){ + return self::ERROR_INVALID_PERMISSIONS(); + } + + // Normalize required global args from JSON body. + $_GET[ 'bulk_action' ] = $request->get_param('bulk_action' ); + $_POST[ 'items' ] = $request->get_param('items' ); + $_POST[ 'the_end' ] = $request->get_param('the_end' ); + + //Double check and that everything is okay. + $action = $this->get_bulk_action(); + +// wp_send_json( [ 'action' => $action ] ); + + if ( is_wp_error( $action ) ){ + return $action; + } + + $action = sanitize_text_field( "groundhogg/bulk_job/{$action}/ajax" ); + + do_action( $action ); + + return self::ERROR_403( 'invalid_action', 'Invalid bulk action provided.' ); + + } + +} \ No newline at end of file diff --git a/api/v3/class-wpgh-api-v3.php b/api/v3/class-wpgh-api-v3.php index 3ea742c5c..a961db85c 100644 --- a/api/v3/class-wpgh-api-v3.php +++ b/api/v3/class-wpgh-api-v3.php @@ -38,6 +38,8 @@ public function declare_base_endpoints() $this->emails = new WPGH_API_V3_EMAILS(); $this->sms = new WPGH_API_V3_SMS(); $this->elements = new WPGH_API_V3_ELEMENTS(); + $this->broadcasts = new WPGH_API_V3_BROADCASTS(); + $this->bulk_job_listener = new WPGH_API_V3_BULK_JOB_LISTENER(); } /** @@ -84,6 +86,8 @@ private function includes() include_once dirname(__FILE__) . '/class-wpgh-api-v3-emails.php'; include_once dirname(__FILE__) . '/class-wpgh-api-v3-sms.php'; include_once dirname(__FILE__) . '/class-wpgh-api-v3-elements.php'; + include_once dirname(__FILE__) . '/class-wpgh-api-v3-broadcasts.php'; + include_once dirname(__FILE__) . '/class-wpgh-api-v3-bulk-job-listener.php'; do_action( 'groundhogg/api/v3/includes', $this ); diff --git a/includes/admin/broadcasts/class-wpgh-broadcast-bulk-job.php b/includes/admin/broadcasts/class-wpgh-broadcast-bulk-job.php index 58686061c..7f984c80e 100644 --- a/includes/admin/broadcasts/class-wpgh-broadcast-bulk-job.php +++ b/includes/admin/broadcasts/class-wpgh-broadcast-bulk-job.php @@ -43,7 +43,13 @@ public function query($items) } $query = new WPGH_Contact_Query(); - $args = $_GET; + + $config = get_transient( 'gh_get_broadcast_config' ); + if ( ! $config ){ + return $items; + } + + $args = $config[ 'contact_query' ]; $contacts = $query->query( $args ); $ids = wp_list_pluck( $contacts, 'ID' );