rest_authorization_required_code()]); } return true; } /** * Makes sure the current user has access to READ the settings APIs. * * @param WP_REST_Request $request Full data about the request. * * @return WP_Error|boolean * @since 3.0.0 */ public function get_items_permissions_check($request) { if (!Wpfnl_functions::wpfnl_rest_check_manager_permissions('settings')) { return new WP_Error('wpfunnels_rest_cannot_view', __('Sorry, you cannot list resources.', 'wpfnl'), ['status' => rest_authorization_required_code()]); } return true; } /** * Register rest routes * * @since 1.0.0 */ public function register_routes() { register_rest_route($this->namespace, '/' . $this->rest_base, array( 'args' => array( 'funnel_id' => array( 'description' => __('Funnel ID.', 'wpfnl'), 'type' => 'string', ), 'step_id' => array( 'description' => __('Step ID.', 'wpfnl'), 'type' => 'string', ) ), array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => [ $this, 'update_step_meta' ], 'permission_callback' => [ $this, 'update_items_permissions_check' ] , ) )); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d\.]+)/delete-step', array( 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_step', ), 'permission_callback' => array( $this, 'update_items_permissions_check', ), ), ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/create-step', array( array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'create_step', ), 'permission_callback' => array( $this, 'update_items_permissions_check', ), ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/wpfunnel-import-step', array( array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'import_step', ), 'permission_callback' => array( $this, 'update_items_permissions_check', ), ), ) ); } /** * Responsible to create a single step of funnels * * @param WP_REST_Request $payload Data from request. * * @return array * @since 1.0.0 */ public function create_step( $payload ) { if ( ! isset( $payload['funnel_id'] , $payload['step_type'] ) ){ return $this->prepare_wp_error_response( 'rest_invalid_request', __( 'Invalid rest request.', 'wpfnl' ), array( 'status' => 400 ) ); } $funnel_id = $payload['funnel_id']; $step_type = $payload['step_type']; $step_name = isset( $payload['step_name'] ) ? $payload['step_name'] : $step_type; $funnel = Wpfnl::get_instance()->funnel_store; $step = Wpfnl::get_instance()->step_store; $step_id = $step->create_step( $funnel_id, $step_name, $step_type ); $step->set_id( $step_id ); if ( ! $step_id || is_wp_error( $step_id ) ) { return $this->prepare_wp_error_response( 'rest_step_create_failed', __( 'Failed to create a step', 'wpfnl' ), array( 'status' => 400 ) ); } $funnel->set_id( $funnel_id ); $step_edit_link = get_edit_post_link( $step_id ); $step_view_link = get_post_permalink( $step_id ); /** * Fires to update _wpfnl_ab_testing_start_settings meta * * @since 2.7.0 * * @param int $step_id The ID of the order. */ do_action( 'wpfunnels/update_ab_testing_start_settings', $step_id ); //phpcs:ignore $response = array( 'success' => true, 'step_id' => $step_id, 'step_edit_link' => $step_edit_link, 'step_view_link' => rtrim( $step_view_link, '/' ), 'step_title' => $step->get_title(), 'conversion' => 0, 'visit' => 0, 'shouldShowAnalytics' => false, 'abTestingSettingsData' => Wpfnl::get_instance()->get_default_start_setting( $step_id ), ); return rest_ensure_response( $response ); } /** * Update step meta * * @param WP_REST_Request $request * * @return \WP_REST_Response * * @since 2.0.5 */ public function update_step_meta( WP_REST_Request $request ) { $step_id = $request['step_id'] ? $request['step_id'] : ''; $funnel_id = $request['funnel_id'] ? $request['funnel_id'] : ''; $slug = $request['slug'] ? $request['slug'] : ''; $settings = $request->get_params(); if( is_plugin_active( 'wpfunnels-pro/wpfnl-pro.php' ) && Wpfnl_functions::is_pro_license_activated() ){ do_action( 'wpfunnels/before_update_step_meta', $step_id, $funnel_id, $settings ); $parent_step_id = get_post_meta( $step_id, '_parent_step_id', true ); $step_id = $parent_step_id ? $parent_step_id : $step_id; }else{ if( isset($settings['funnel_id'], $settings['step_id'], $settings['title'], $settings['slug']) ){ $steps = Wpfnl_functions::get_steps($settings['funnel_id']); foreach($steps as $key=>$step){ if($step['id'] == $settings['step_id']){ $steps[$key]['name'] = $settings['title']; } } update_post_meta( $settings['funnel_id'], '_steps_order',$steps); wp_update_post([ "ID" => $step_id, "post_title" => wp_strip_all_tags( $settings['title'] ), "post_name" => sanitize_title($settings['slug']), ]); } } $response = array( 'success' => true, 'post_title' => htmlspecialchars_decode(get_the_title($step_id)), 'permalink' => rtrim( get_the_permalink($step_id), '/' ), 'slug' => sanitize_title($slug), ); return $this->prepare_item_for_response( $response, $request ); } /** * Common function to update step meta * * @param WP_REST_Request $request * * @return \WP_REST_Response * * @since 2.7.10 */ public static function update_step_meta_on_funnel_name_change( $funnel_id, $step_id, $settings ){ if( is_plugin_active( 'wpfunnels-pro/wpfnl-pro.php' ) && Wpfnl_functions::is_pro_license_activated() ){ /** * Fires to update step slug on ab testing variation on funnel name change * * @since 2.7.0 * * @param int $step_id The ID of the step. * @param int $funnel_id The ID of the funnel to which the step belongs. * @param array $settings An array of settings containing the title and slug for the step. */ do_action( 'wpfunnels/before_update_step_meta_on_funnel_name_change', $step_id, $funnel_id, $settings ); }else{ if( isset($settings['funnel_id'], $settings['step_id'], $settings['title'], $settings['slug']) ){ $steps = Wpfnl_functions::get_steps($settings['funnel_id']); if ( !empty( $steps ) ){ foreach($steps as $key=>$step){ if($step['id'] == $settings['step_id']){ $steps[$key]['name'] = $settings['title']; } } } update_post_meta( $settings['funnel_id'], '_steps_order', $steps); wp_update_post([ "ID" => $step_id, "post_title" => wp_strip_all_tags( $settings['title'] ), "post_name" => sanitize_title($settings['slug']), ]); } } } /** * Delete step and all its data * * @param WP_REST_Request $payload Data from request. * * @return array * * @since 2.7.9 */ public function delete_step( $payload ) { if ( ! isset ( $payload['step_id'] )){ return $this->prepare_wp_error_response( 'rest_invalid_stepID', __( 'Invalid Step ID.', 'wpfnl' ), array( 'status' => 404 ) ); } $step_id = sanitize_text_field( $payload['step_id'] ); $step_type = get_post_meta( $step_id, '_step_type', true ); /** * Delete the automation data linked with the step * * @since 2.7.0 * * @param int $step_id Step ID. */ do_action( 'wpfunnels/before_delete_step', $step_id ); //phpcs:ignore $response = $this->prepare_wp_error_response( 'rest_invalid_stepID', __( 'Invalid Step ID.', 'wpfnl' ), array( 'status' => 404 ) ); if ( $step_type ) { $response = $this->delete_regular_step($step_id); } else if ( $step_id ){ // For conditional step. $response = $this->conditional_step_response($step_id); } return $response; } /** * Delete a regular step and all its data. * * @param int $step_id The ID of the regular step to be deleted. * * @return array The response containing the success status and message. * * @since 2.7.9 */ private function delete_regular_step( $step_id ) { if ( !$step_id ){ return $this->prepare_wp_error_response( 'rest_invalid_stepID', __( 'Invalid Step ID.', 'wpfnl' ), array( 'status' => 404 ) ); } $step = new Wpfnl::$instance->step_store(); $step->read( $step_id ); $funnel_id = $step->get_funnel_id(); $delete_result = $step->delete( $step_id ); $funnel = Wpfnl::$instance->funnel_store; $funnel->read($funnel_id); if ( $delete_result ) { return $this->prepare_wp_success_response( 'Step deleted successfully', 200 ); } $response = $this->prepare_wp_error_response( 'rest_delete_failure', __( 'Failed to delete step.', 'wpfnl' ), array( 'status' => 500 ) ); return $response ; } /** * Response for deleting a conditional step. * * @param int $step_id The ID of the conditional step to be deleted. * * @return array The response indicating the success of the deletion. * * @since 2.7.9 */ private function conditional_step_response( $step_id ) { if ( !$step_id ){ return $this->prepare_wp_error_response( 'rest_invalid_stepID', __( 'Invalid Step ID.', 'wpfnl' ), array( 'status' => 404 ) ); } return $this->prepare_wp_success_response( 'Conditional step deleted successfully',200 ); } /** * Prepare a single setting object for response. * * @param object $item Setting object. * @param WP_REST_Request $request Request object. * * @return \WP_REST_Response $response Response data. * @since 1.0.0 */ public function prepare_item_for_response($item, $request) { $data = $this->add_additional_fields_to_object($item, $request); return rest_ensure_response( $data ); } /** * Import wp funnel steps from remote servers. * * @param array $payload * * @return array * @since 1.0.0 */ public function import_step( $payload ) { $manager_class = new Manager(); $source = $manager_class->get_source(!empty( $payload['source'] ) ? $payload['source'] : 'remote' ); return $source->import_step($payload); } }