identifier = $identifier; $plugin_slug = Helpers::get_config_data( $this->identifier,'plugin_slug' ); $this->namespace = $plugin_slug . '/v1'; add_action( 'rest_api_init', [$this, 'register_routes'] ); } /** * Register API endpoints routes. * * @since 1.0.0 * * @return void */ public function register_routes() { register_rest_route( $this->namespace, $this->rest_base, [ [ // Create 'methods' => \WP_REST_Server::CREATABLE, 'callback' => [$this, 'create_item'], 'permission_callback' => [ $this, 'permissions_check' ], ], [ // Bulk delete 'methods' => \WP_REST_Server::DELETABLE, 'callback' => [$this, 'bulk_delete'], 'permission_callback' => [ $this, 'permissions_check' ], ], [ // show list 'methods' => \WP_REST_Server::READABLE, 'callback' => [$this, 'get_items'], 'permission_callback' => [ $this, 'permissions_check' ], ], ] ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', [ [ // Get single flow 'methods' => \WP_REST_Server::READABLE, 'callback' => [$this, 'get_item'], 'permission_callback' => [ $this, 'permissions_check' ], ], [ // Update single flow 'methods' => \WP_REST_Server::EDITABLE, 'callback' => [$this, 'update_item'], 'permission_callback' => [ $this, 'permissions_check' ], ], [ // Delete single flow 'methods' => \WP_REST_Server::DELETABLE, 'callback' => [$this, 'delete_item'], 'permission_callback' => [ $this, 'permissions_check' ], ], ] ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)' . '/clone', [ [ // Clone flow 'methods' => \WP_REST_Server::CREATABLE, 'callback' => [$this, 'clone_item'], 'permission_callback' => [ $this, 'permissions_check' ], ], ] ); } /** * Check that the current user is allowed to manage notification flows. * * Every flow route is administrative: flows control the content and * recipients of the emails the site sends out. They must never be * reachable by unauthenticated visitors. * * @since 1.0.0 * * @param \WP_REST_Request $request * * @return bool */ public function permissions_check( $request ) { $can = current_user_can( 'manage_options' ); return (bool) apply_filters( Helpers::get_hook_name( $this->identifier, 'ens_flow_permission' ), $can, $request ); } /** * Create flow * * @since 1.0.0 * * @param WP_Rest_Request $request * * @return JSON Created flow data */ public function create_item( $request ) { $response = Helpers::ens_verify_nonce( $request->get_header( 'x_wp_nonce' ), $this->identifier ); if ( $response instanceof WP_HTTP_Response ) { return $response; } return $this->save_flow( $request ); } /** * Update flow * * @since 1.0.0 * * @param WP_Rest_Request $request * * @return JSON Updated flow data */ public function update_item( $request ) { $response = Helpers::ens_verify_nonce( $request->get_header( 'x_wp_nonce' ), $this->identifier ); if ( $response instanceof WP_HTTP_Response ) { return $response; } $flow_id = (int) $request['flow_id']; $flow = new Flow( $this->identifier, $flow_id ); if ( !$flow->is_flow() ) { $response = [ 'success' => 0, 'status_code' => 422, 'message' => __( 'Invalid flow id.', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [], ]; return new WP_HTTP_Response( $response, 422 ); } return $this->save_flow( $request, $flow_id ); } /** * Get flow * * @since 1.0.0 * * @param WP_Rest_Request $request * * @return JSON Flow data */ public function get_item( $request ) { $response = Helpers::ens_verify_nonce( $request->get_header( 'x_wp_nonce' ), $this->identifier ); if ( $response instanceof WP_HTTP_Response ) { return $response; } $flow_id = (int) $request['flow_id']; $flow = new Flow( $this->identifier, $flow_id ); if ( !$flow->is_flow() ) { $data = [ 'success' => 0, 'status_code' => 422, 'message' => __( 'Invalid flow id.', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [], ]; return new WP_HTTP_Response( $data, 422 ); } $response = [ 'success' => 1, 'status_code' => 200, 'message' => __( 'Successfully retrieved flow', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => $this->prepare_item( $flow_id ), ]; return rest_ensure_response( $response, 200 ); } /** * Get all flows * * @since 1.0.0 * * @param WP_Rest_Request $request * * @return JSON */ public function get_items( $request ) { $response = Helpers::ens_verify_nonce( $request->get_header( 'x_wp_nonce' ), $this->identifier ); if ( $response instanceof WP_HTTP_Response ) { return $response; } $per_page = !empty( $request['per_page'] ) ? intval( $request['per_page'] ) : -1; $paged = !empty( $request['paged'] ) ? intval( $request['paged'] ) : -1; $trigger = !empty( $request['trigger'] ) ? sanitize_text_field( $request['trigger'] ) : ''; $status = !empty( $request['status'] ) ? sanitize_text_field( $request['status'] ) : 'any'; $search_key = !empty( $request['search_key'] ) ? sanitize_text_field( $request['search_key'] ) : ''; $flow = new Flow($this->identifier); $flows = $flow->all( [ 'posts_per_page' => $per_page, 'paged' => $paged, 'trigger' => $trigger, 'post_status' => $status, 'search_key' => $search_key, ] ); $items = []; foreach ( $flows['items'] as $item ) { $single_flow = $this->prepare_item( $item->ID ); $items[] = $single_flow; } $flow = new Flow( $this->identifier ); $status_count = $flow->total_flows_group_by_status(); $data = [ 'success' => 1, 'status_code' => 200, 'message' => __( 'Showing filtered flow list.', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [ 'total' => $flows['total'], 'status_count' => $status_count, 'items' => $items, ], ]; return rest_ensure_response( $data, 200 ); } /** * Delete flow * * @since 1.0.0 * * @param WP_Rest_Request $request * * @return JSON */ public function delete_item( $request ) { $response = Helpers::ens_verify_nonce( $request->get_header( 'x_wp_nonce' ), $this->identifier ); if ( $response instanceof WP_HTTP_Response ) { return $response; } $flow_id = (int) $request['flow_id']; $flow = new Flow( $this->identifier, $flow_id ); if ( !$flow->is_flow() ) { $data = [ 'success' => 0, 'status_code' => 422, 'message' => __( 'Invalid flow id.', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [], ]; return new WP_HTTP_Response( $data, 422 ); } $flow->delete(); $response = [ 'success' => 1, 'status_code' => 200, 'message' => __( 'Successfully deleted flow', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [], ]; return rest_ensure_response( $response, 200 ); } /** * Bulk delete flows * * @since 1.0.0 * * @param WP_Rest_Request $request * * @return JSON */ public function bulk_delete( $request ) { $response = Helpers::ens_verify_nonce( $request->get_header( 'x_wp_nonce' ), $this->identifier ); if ( $response instanceof WP_HTTP_Response ) { return $response; } $flow_ids = json_decode( $request->get_body(), true ); foreach ( $flow_ids as $flow_id ) { $flow = new Flow( $this->identifier, $flow_id ); if ( !$flow->is_flow() ) { $data = [ 'success' => 0, 'status_code' => 422, 'message' => __( 'Invalid flow id.', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [], ]; return new WP_HTTP_Response( $data, 422 ); } $flow->delete(); } return rest_ensure_response( [ 'success' => 1, 'status_code' => 200, 'message' => __( 'Successfully deleted all flows', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [ 'items' => $flow_ids, ], ], 200 ); } /** * Clone flow * * @since 1.0.0 * * @param Object $request * * @return JSON */ public function clone_item( $request ) { $response = Helpers::ens_verify_nonce( $request->get_header( 'x_wp_nonce' ), $this->identifier ); if ( $response instanceof WP_HTTP_Response ) { return $response; } $flow_id = (int) $request['flow_id']; $flow = new Flow( $this->identifier, $flow_id ); if ( !$flow->is_flow() ) { return new WP_HTTP_Response( [ 'success' => 0, 'status_code' => 422, 'message' => __( 'Invalid flow id.', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => [], ], 422 ); } $flow->clone(); $item = $this->prepare_item( $flow ); $response = [ 'success' => 1, 'status_code' => 200, 'message' => __( 'Successfully cloned requested flow', Helpers::get_config_data( $this->identifier,'text_domain' ) ), 'data' => $item, ]; return rest_ensure_response( $response, 200 ); } /** * Save flow * * @since 1.0.0 * * @param WP_Rest_Request $request * @param int $id * * @return WP_REST_Response */ public function save_flow( $request, $id = 0 ) { $flow = new Flow( $this->identifier, $id ); $request_body = $request->get_body(); $data = !is_null( $request_body ) ? json_decode( $request_body, true ) : []; // Check if the input data is empty if ( empty( $data ) ) { return rest_ensure_response( [ 'status_code' => 400, 'success' => 0, 'message' => __( 'No data provided to save the flow', Helpers::get_config_data( $this->identifier,'text_domain' ) ), ], 400 ); } $name = !empty( $data['name'] ) ? sanitize_text_field( $data['name'] ) : $flow->get_name(); $trigger = !empty( $data['trigger'] ) ? sanitize_text_field( $data['trigger'] ) : $flow->get_trigger(); $flow_config = !empty( $data['flow_config'] ) ? Helpers::ens_sanitize_recursive( $data['flow_config'] ) : $flow->get_flow_config(); $status = ( isset( $data['status'] ) && !empty( $data['status'] ) ) ? sanitize_text_field( strtolower( $data['status'] ) ) : ( $flow->get_status() ? $flow->get_status() : 'draft' ); $action = $id ? 'updated' : 'created'; // Check if the input data is empty if ( empty( $name ) || empty( $trigger ) ) { return rest_ensure_response( [ 'status_code' => 400, 'success' => 0, 'message' => __( 'Flow name & trigger is required', Helpers::get_config_data( $this->identifier,'text_domain' ) ), ], 400 ); } // preparing flow data. $flow_data = [ 'name' => $name, 'trigger' => $trigger, 'flow_config' => $flow_config, 'status' => $status, ]; $flow->set_props( $flow_data ); $flow_id = $flow->save(); // Prepare response data. $item = $this->prepare_item( $flow_id ); $response = [ 'status_code' => 200, 'success' => 1, // translators: %s is the name of the action 'message' => esc_html( sprintf( __( 'Successfully %s notification flow', Helpers::get_config_data( $this->identifier,'text_domain' ) ), $action ) ), 'data' => $item, ]; return rest_ensure_response( $response, 200 ); } /** * Prepare item for response * * @since 1.0.0 * * @param integer $flow_id * * @return array */ public function prepare_item( $flow_id ) { $flow = new Flow( $this->identifier, $flow_id ); $data = [ 'id' => $flow->get_id(), 'name' => $flow->get_name(), 'trigger' => $flow->get_trigger(), 'flow_config' => empty( $flow->get_flow_config() ) ? [] : $flow->get_flow_config(), 'status' => $flow->get_status(), ]; return apply_filters( Helpers::get_hook_name( $this->identifier, 'ens_flow_prepare_item' ), $data, $flow_id ); } }