# wpfunnels/2.8.16/includes/core/rest-api/Controllers/class-step-controller.php

WPFunnels – Funnel Builder for WooCommerce with Checkout &amp; One Click Upsell, version 2.8.16. 435 lines.

- Page: https://pluginprobe.com/plugins/wpfunnels/2.8.16/code/includes/core/rest-api/Controllers/class-step-controller.php
- Raw: https://pluginprobe.com/plugins/wpfunnels/2.8.16/raw/includes/core/rest-api/Controllers/class-step-controller.php
- Modified: 2023-06-20T08:39:50+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/wpfunnels/2.8.16/code/includes/core/rest-api/Controllers/class-step-controller.php#L10-L20`.

```php
<?php
/**
 * Step controller
 * 
 * @package WPFunnels\Rest\Controllers
 */
namespace WPFunnels\Rest\Controllers;

use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WPFunnels\Wpfnl;
use WPFunnels\Wpfnl_functions;
use WPFunnels\TemplateLibrary\Manager;

class StepController extends Wpfnl_REST_Controller
{

	/**
	 * Endpoint namespace.
	 *
	 * @var string
	 */
	protected $namespace = 'wpfunnels/v1';

	/**
	 * Route base.
	 *
	 * @var string
	 */
	protected $rest_base = 'steps';

	/**
	 * Check if user has valid permission
	 *
	 * @param $request
	 * 
	 * @return bool|WP_Error
	 * @since  1.0.0
	 */
	public function update_items_permissions_check($request)
	{
		if (!Wpfnl_functions::wpfnl_rest_check_manager_permissions( 'steps', 'edit' )) {
			return new WP_Error('wpfunnels_rest_cannot_edit', __('Sorry, you cannot edit this resource.', 'wpfnl'), ['status' => 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<step_id>[\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);
    }

}

```
