PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.13.3
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.13.3
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
← All changes | includes/core/rest-api/Controllers/class-step-controller.php +1039 -374 2.8.16 → 3.13.3 View file →
@@ -1,434 +1,1099 @@
1 1 <?php
2 2 /**
3 3 * Step controller
4 - *
4 + *
5 5 * @package WPFunnels\Rest\Controllers
6 6 */
7 +
7 8 namespace WPFunnels\Rest\Controllers;
8 9
9 10 use WP_Error;
10 11 use WP_REST_Request;
11 12 use WP_REST_Response;
13 +use WPFunnels\Metas\Wpfnl_Step_Meta_keys;
12 14 use WPFunnels\Wpfnl;
13 15 use WPFunnels\Wpfnl_functions;
14 16 use WPFunnels\TemplateLibrary\Manager;
15 -
17 +use Elementor\Plugin;
16 18 class StepController extends Wpfnl_REST_Controller
17 19 {
18 20
19 - /**
20 - * Endpoint namespace.
21 - *
22 - * @var string
23 - */
24 - protected $namespace = 'wpfunnels/v1';
21 + /**
22 + * Endpoint namespace.
23 + *
24 + * @var string
25 + */
26 + protected $namespace = 'wpfunnels/v1';
25 27
26 - /**
27 - * Route base.
28 - *
29 - * @var string
30 - */
31 - protected $rest_base = 'steps';
28 + /**
29 + * Route base.
30 + *
31 + * @var string
32 + */
33 + protected $rest_base = 'steps';
32 34
33 - /**
34 - * Check if user has valid permission
35 - *
36 - * @param $request
37 - *
38 - * @return bool|WP_Error
39 - * @since 1.0.0
40 - */
41 - public function update_items_permissions_check($request)
42 - {
43 - if (!Wpfnl_functions::wpfnl_rest_check_manager_permissions( 'steps', 'edit' )) {
44 - return new WP_Error('wpfunnels_rest_cannot_edit', __('Sorry, you cannot edit this resource.', 'wpfnl'), ['status' => rest_authorization_required_code()]);
45 - }
46 - return true;
47 - }
35 + /**
36 + * Check if user has valid permission
37 + *
38 + * @param $request
39 + *
40 + * @return bool|WP_Error
41 + * @since 1.0.0
42 + */
43 + public function update_items_permissions_check($request)
44 + {
45 + if (!Wpfnl_functions::wpfnl_rest_check_manager_permissions('steps', 'edit')) {
46 + return new WP_Error('wpfunnels_rest_cannot_edit', __('Sorry, you cannot edit this resource.', 'wpfnl'), ['status' => rest_authorization_required_code()]);
47 + }
48 + return true;
49 + }
48 50
49 - /**
50 - * Makes sure the current user has access to READ the settings APIs.
51 - *
52 - * @param WP_REST_Request $request Full data about the request.
53 - *
54 - * @return WP_Error|boolean
55 - * @since 3.0.0
56 - */
57 - public function get_items_permissions_check($request)
58 - {
59 - if (!Wpfnl_functions::wpfnl_rest_check_manager_permissions('settings')) {
60 - return new WP_Error('wpfunnels_rest_cannot_view', __('Sorry, you cannot list resources.', 'wpfnl'), ['status' => rest_authorization_required_code()]);
61 - }
62 - return true;
63 - }
51 + /**
52 + * Makes sure the current user has access to READ the settings APIs.
53 + *
54 + * @param WP_REST_Request $request Full data about the request.
55 + *
56 + * @return WP_Error|boolean
57 + * @since 3.0.0
58 + */
59 + public function get_items_permissions_check($request)
60 + {
61 + if (!Wpfnl_functions::wpfnl_rest_check_manager_permissions('settings')) {
62 + return new WP_Error('wpfunnels_rest_cannot_view', __('Sorry, you cannot list resources.', 'wpfnl'), ['status' => rest_authorization_required_code()]);
63 + }
64 + return true;
65 + }
64 66
65 67
66 - /**
67 - * Register rest routes
68 - *
69 - * @since 1.0.0
70 - */
71 - public function register_routes()
72 - {
73 - register_rest_route($this->namespace, '/' . $this->rest_base, array(
74 - 'args' => array(
75 - 'funnel_id' => array(
76 - 'description' => __('Funnel ID.', 'wpfnl'),
77 - 'type' => 'string',
78 - ),
79 - 'step_id' => array(
80 - 'description' => __('Step ID.', 'wpfnl'),
81 - 'type' => 'string',
82 - )
83 - ),
84 - array(
85 - 'methods' => \WP_REST_Server::EDITABLE,
86 - 'callback' => [
87 - $this,
88 - 'update_step_meta'
89 - ],
90 - 'permission_callback' => [
91 - $this,
92 - 'update_items_permissions_check'
93 - ] ,
94 - )
95 - ));
96 - register_rest_route(
97 - $this->namespace,
98 - '/' . $this->rest_base . '/(?P<step_id>[\d\.]+)/delete-step',
99 - array(
100 - 'methods' => \WP_REST_Server::DELETABLE,
101 - 'callback' => array(
102 - $this,
103 - 'delete_step',
104 - ),
105 - 'permission_callback' => array(
106 - $this,
107 - 'update_items_permissions_check',
108 - ),
109 - ),
110 - );
111 - register_rest_route(
112 - $this->namespace,
113 - '/' . $this->rest_base . '/create-step',
114 - array(
115 - array(
116 - 'methods' => \WP_REST_Server::EDITABLE,
117 - 'callback' => array(
118 - $this,
119 - 'create_step',
120 - ),
121 - 'permission_callback' => array(
122 - $this,
123 - 'update_items_permissions_check',
124 - ),
125 - ),
126 - )
127 - );
68 + /**
69 + * Register rest routes
70 + *
71 + * @since 1.0.0
72 + */
73 + public function register_routes()
74 + {
75 + register_rest_route($this->namespace, '/' . 'funnels/(?P<funnel_id>[\d\.]+)/' . $this->rest_base . '/(?P<step_id>[\d\.]+)/metadata', array(
76 + array(
77 + 'methods' => \WP_REST_Server::EDITABLE,
78 + 'args' => array(
79 + 'funnel_id' => array(
80 + 'validate_callback' => function($param, $request, $key) {
81 + return is_numeric( $param );
82 + }
83 + ),
84 + 'step_id' => array(
85 + 'validate_callback' => function($param, $request, $key) {
86 + return is_numeric( $param );
87 + }
88 + )
89 + ),
90 + 'callback' => [
91 + $this,
92 + 'save_step_metadata'
93 + ],
94 + 'permission_callback' => [
95 + $this,
96 + 'update_items_permissions_check'
97 + ],
98 + )
99 + ));
128 100
129 - register_rest_route(
130 - $this->namespace,
131 - '/' . $this->rest_base . '/wpfunnel-import-step',
132 - array(
133 - array(
134 - 'methods' => \WP_REST_Server::EDITABLE,
135 - 'callback' => array(
136 - $this,
137 - 'import_step',
138 - ),
139 - 'permission_callback' => array(
140 - $this,
141 - 'update_items_permissions_check',
142 - ),
143 - ),
144 - )
145 - );
146 - }
101 + register_rest_route(
102 + $this->namespace,
103 + '/' . $this->rest_base . '/(?P<step_id>[\d\.]+)/delete-step',
104 + array(
105 + 'methods' => \WP_REST_Server::DELETABLE,
106 + 'callback' => array(
107 + $this,
108 + 'delete_step',
109 + ),
110 + 'permission_callback' => array(
111 + $this,
112 + 'update_items_permissions_check',
113 + ),
114 + ),
115 + );
147 116
148 - /**
149 - * Responsible to create a single step of funnels
150 - *
151 - * @param WP_REST_Request $payload Data from request.
152 - *
153 - * @return array
154 - * @since 1.0.0
155 - */
156 - public function create_step( $payload ) {
157 - if ( ! isset( $payload['funnel_id'] , $payload['step_type'] ) ){
158 - return $this->prepare_wp_error_response(
159 - 'rest_invalid_request',
160 - __( 'Invalid rest request.', 'wpfnl' ),
161 - array( 'status' => 400 )
162 - );
163 - }
117 + register_rest_route(
118 + $this->namespace,
119 + '/' . $this->rest_base . '/create-step',
120 + array(
121 + array(
122 + 'methods' => \WP_REST_Server::EDITABLE,
123 + 'callback' => array(
124 + $this,
125 + 'create_step',
126 + ),
127 + 'permission_callback' => array(
128 + $this,
129 + 'update_items_permissions_check',
130 + ),
131 + ),
132 + )
133 + );
164 134
165 - $funnel_id = $payload['funnel_id'];
166 - $step_type = $payload['step_type'];
167 - $step_name = isset( $payload['step_name'] ) ? $payload['step_name'] : $step_type;
168 - $funnel = Wpfnl::get_instance()->funnel_store;
169 - $step = Wpfnl::get_instance()->step_store;
170 - $step_id = $step->create_step( $funnel_id, $step_name, $step_type );
135 + register_rest_route(
136 + $this->namespace,
137 + '/' . $this->rest_base . '/wpfunnel-import-step',
138 + array(
139 + array(
140 + 'methods' => \WP_REST_Server::EDITABLE,
141 + 'callback' => array(
142 + $this,
143 + 'import_step',
144 + ),
145 + 'permission_callback' => array(
146 + $this,
147 + 'update_items_permissions_check',
148 + ),
149 + ),
150 + )
151 + );
171 152
172 - $step->set_id( $step_id );
153 + register_rest_route(
154 + $this->namespace, '/' . $this->rest_base . '/update-conditional-status',
155 + array(
156 + array(
157 + 'methods' => \WP_REST_Server::EDITABLE,
158 + 'callback' => array(
159 + $this,
160 + 'update_conditional_status',
161 + ),
162 + 'permission_callback' => array(
163 + $this,
164 + 'update_items_permissions_check',
165 + ),
166 + 'args' => array(
167 + 'stepId' => array(
168 + 'description' => __('Funnel step ID.', 'wpfnl'),
169 + 'type' => 'integer',
170 + 'required' => true
171 + ),
172 + 'status' => array(
173 + 'description' => __('Condition status.', 'wpfnl'),
174 + 'type' => 'string',
175 + 'required' => true
176 + ),
177 + ),
178 + ),
179 + )
180 + );
173 181
174 - if ( ! $step_id || is_wp_error( $step_id ) ) {
175 - return $this->prepare_wp_error_response(
176 - 'rest_step_create_failed',
177 - __( 'Failed to create a step', 'wpfnl' ),
178 - array( 'status' => 400 )
179 - );
180 - }
181 -
182 - $funnel->set_id( $funnel_id );
183 - $step_edit_link = get_edit_post_link( $step_id );
184 - $step_view_link = get_post_permalink( $step_id );
182 + register_rest_route(
183 + $this->namespace, '/' . $this->rest_base . '/get-conditions',
184 + array(
185 + array(
186 + 'methods' => \WP_REST_Server::READABLE,
187 + 'callback' => array(
188 + $this,
189 + 'get_conditions',
190 + ),
191 + 'permission_callback' => array(
192 + $this,
193 + 'update_items_permissions_check',
194 + ),
195 + 'args' => array(
196 + 'stepId' => array(
197 + 'description' => __('Funnel step ID.', 'wpfnl'),
198 + 'type' => 'integer',
199 + 'required' => true
200 + )
201 + ),
202 + ),
203 + )
204 + );
185 205
186 - /**
187 - * Fires to update _wpfnl_ab_testing_start_settings meta
188 - *
189 - * @since 2.7.0
190 - *
191 - * @param int $step_id The ID of the order.
192 - */
193 - do_action( 'wpfunnels/update_ab_testing_start_settings', $step_id ); //phpcs:ignore
206 + register_rest_route(
207 + $this->namespace, '/' . $this->rest_base . '/save-condition',
208 + array(
209 + array(
210 + 'methods' => \WP_REST_Server::EDITABLE,
211 + 'callback' => array(
212 + $this,
213 + 'save_condition',
214 + ),
215 + 'permission_callback' => array(
216 + $this,
217 + 'update_items_permissions_check',
218 + ),
219 + 'args' => array(
220 + 'stepId' => array(
221 + 'description' => __('Funnel step ID.', 'wpfnl'),
222 + 'type' => 'integer',
223 + 'required' => true
224 + ),
225 + 'conditions' => array(
226 + 'description' => __('Funnel step ID.', 'wpfnl'),
227 + 'type' => 'array',
228 + 'required' => true
229 + ),
230 + ),
231 + ),
232 + )
233 + );
194 234
195 - $response = array(
196 - 'success' => true,
197 - 'step_id' => $step_id,
198 - 'step_edit_link' => $step_edit_link,
199 - 'step_view_link' => rtrim( $step_view_link, '/' ),
200 - 'step_title' => $step->get_title(),
201 - 'conversion' => 0,
202 - 'visit' => 0,
203 - 'shouldShowAnalytics' => false,
204 - 'abTestingSettingsData' => Wpfnl::get_instance()->get_default_start_setting( $step_id ),
205 - );
235 + register_rest_route(
236 + $this->namespace, '/' . $this->rest_base . '/paste-step',
237 + array(
238 + array(
239 + 'methods' => \WP_REST_Server::EDITABLE,
240 + 'callback' => array(
241 + $this,
242 + 'paste_step',
243 + ),
244 + 'permission_callback' => array(
245 + $this,
246 + 'update_items_permissions_check',
247 + ),
248 + 'args' => array(
249 + 'stepId' => array(
250 + 'description' => __('Funnel step ID.', 'wpfnl'),
251 + 'type' => 'integer',
252 + 'required' => true
253 + ),
254 + 'funnelId' => array(
255 + 'description' => __('Funnel ID.', 'wpfnl'),
256 + 'type' => 'integer',
257 + 'required' => true
258 + )
259 + ),
260 + ),
261 + )
262 + );
263 + }
206 264
207 - return rest_ensure_response( $response );
208 - }
265 + /**
266 + * Responsible to create a single step of funnels
267 + *
268 + * @param WP_REST_Request $payload Data from request.
269 + *
270 + * @return array
271 + * @since 1.0.0
272 + */
273 + public function create_step($payload)
274 + {
275 + if (!isset($payload['funnel_id'], $payload['step_type'])) {
276 + return $this->prepare_wp_error_response(
277 + 'rest_invalid_request',
278 + __('Invalid rest request.', 'wpfnl'),
279 + array('status' => 400)
280 + );
281 + }
209 282
283 + $funnel_id = $payload['funnel_id'];
284 + $step_type = $payload['step_type'];
285 + $step_name = isset($payload['step_name']) ? $payload['step_name'] : $step_type;
286 + $funnel = Wpfnl::get_instance()->funnel_store;
287 + $step = Wpfnl::get_instance()->step_store;
288 + $step_id = $step->create_step($funnel_id, $step_name, $step_type);
210 289
211 - /**
212 - * Update step meta
213 - *
214 - * @param WP_REST_Request $request
215 - *
216 - * @return \WP_REST_Response
217 - *
218 - * @since 2.0.5
219 - */
220 - public function update_step_meta( WP_REST_Request $request ) {
290 + $step->set_id($step_id);
221 291
222 - $step_id = $request['step_id'] ? $request['step_id'] : '';
223 - $funnel_id = $request['funnel_id'] ? $request['funnel_id'] : '';
224 - $slug = $request['slug'] ? $request['slug'] : '';
225 - $settings = $request->get_params();
292 + if (!$step_id || is_wp_error($step_id)) {
293 + return $this->prepare_wp_error_response(
294 + 'rest_step_create_failed',
295 + __('Failed to create a step', 'wpfnl'),
296 + array('status' => 400)
297 + );
298 + }
226 299
227 - if( is_plugin_active( 'wpfunnels-pro/wpfnl-pro.php' ) && Wpfnl_functions::is_pro_license_activated() ){
228 - do_action( 'wpfunnels/before_update_step_meta', $step_id, $funnel_id, $settings );
229 - $parent_step_id = get_post_meta( $step_id, '_parent_step_id', true );
230 - $step_id = $parent_step_id ? $parent_step_id : $step_id;
231 - }else{
232 - if( isset($settings['funnel_id'], $settings['step_id'], $settings['title'], $settings['slug']) ){
233 - $steps = Wpfnl_functions::get_steps($settings['funnel_id']);
234 - foreach($steps as $key=>$step){
235 - if($step['id'] == $settings['step_id']){
236 - $steps[$key]['name'] = $settings['title'];
237 - }
238 - }
239 - update_post_meta( $settings['funnel_id'], '_steps_order',$steps);
240 - wp_update_post([
241 - "ID" => $step_id,
242 - "post_title" => wp_strip_all_tags( $settings['title'] ),
243 - "post_name" => sanitize_title($settings['slug']),
244 - ]);
245 - }
246 - }
300 + $funnel->set_id($funnel_id);
301 + $step_edit_link = get_edit_post_link($step_id);
302 + $step_view_link = get_post_permalink($step_id);
303 + $response = array(
304 + 'success' => true,
305 + 'step_id' => $step_id,
306 + 'step_edit_link' => $step_edit_link,
307 + 'step_view_link' => rtrim($step_view_link, '/'),
308 + 'step_title' => $step->get_title(),
309 + 'conversion' => 0,
310 + 'visit' => 0,
311 + 'shouldShowAnalytics' => false,
312 + 'abTestingSettingsData' => [],
313 + );
247 314
248 - $response = array(
249 - 'success' => true,
250 - 'post_title' => htmlspecialchars_decode(get_the_title($step_id)),
251 - 'permalink' => rtrim( get_the_permalink($step_id), '/' ),
252 - 'slug' => sanitize_title($slug),
253 - );
254 - return $this->prepare_item_for_response( $response, $request );
255 -
256 - }
315 + if (isset($payload['lastClickedAddStep'])) {
316 + $reconfigureSettings = get_post_meta($funnel->get_id(), '_wpfnl_reconfigurable_condition_data', true);
317 + if (is_array($reconfigureSettings) && !empty($reconfigureSettings)) {
318 + $key = array_search($payload['lastClickedAddStep'], array_column($reconfigureSettings, 'nodeId'));
319 + if (false !== $key) {
320 + $reconfigureSettings[$key]['step_id'] = $step_id;
321 + update_post_meta($funnel->get_id(), '_wpfnl_reconfigurable_condition_data', $reconfigureSettings);
322 + $response['reconfigureSettings'] = $reconfigureSettings;
323 + update_post_meta($step_id, '_wpfnl_maybe_enable_condition', $reconfigureSettings[$key]['is_enable']);
324 + }
325 + }
326 + }
257 327
258 - /**
259 - * Common function to update step meta
260 - *
261 - * @param WP_REST_Request $request
262 - *
263 - * @return \WP_REST_Response
264 - *
265 - * @since 2.7.10
266 - */
267 - public static function update_step_meta_on_funnel_name_change( $funnel_id, $step_id, $settings ){
268 - if( is_plugin_active( 'wpfunnels-pro/wpfnl-pro.php' ) && Wpfnl_functions::is_pro_license_activated() ){
269 - /**
270 - * Fires to update step slug on ab testing variation on funnel name change
271 - *
272 - * @since 2.7.0
273 - *
274 - * @param int $step_id The ID of the step.
275 - * @param int $funnel_id The ID of the funnel to which the step belongs.
276 - * @param array $settings An array of settings containing the title and slug for the step.
277 - */
278 - do_action( 'wpfunnels/before_update_step_meta_on_funnel_name_change', $step_id, $funnel_id, $settings );
279 - }else{
280 - if( isset($settings['funnel_id'], $settings['step_id'], $settings['title'], $settings['slug']) ){
281 - $steps = Wpfnl_functions::get_steps($settings['funnel_id']);
282 - if ( !empty( $steps ) ){
283 - foreach($steps as $key=>$step){
284 - if($step['id'] == $settings['step_id']){
285 - $steps[$key]['name'] = $settings['title'];
286 - }
287 - }
288 - }
289 - update_post_meta( $settings['funnel_id'], '_steps_order', $steps);
290 - wp_update_post([
291 - "ID" => $step_id,
292 - "post_title" => wp_strip_all_tags( $settings['title'] ),
293 - "post_name" => sanitize_title($settings['slug']),
294 - ]);
295 - }
296 - }
297 - }
328 + return rest_ensure_response($response);
329 + }
298 330
299 331
300 - /**
301 - * Delete step and all its data
302 - *
303 - * @param WP_REST_Request $payload Data from request.
304 - *
305 - * @return array
306 - *
307 - * @since 2.7.9
308 - */
309 - public function delete_step( $payload ) {
310 - if ( ! isset ( $payload['step_id'] )){
311 - return $this->prepare_wp_error_response(
312 - 'rest_invalid_stepID',
313 - __( 'Invalid Step ID.', 'wpfnl' ),
314 - array( 'status' => 404 )
315 - );
316 - }
332 + /**
333 + * Update step meta fields
334 + *
335 + * @param WP_REST_Request $request
336 + * @return WP_Error|\WP_HTTP_Response|WP_REST_Response
337 + * @since 3.0.14
338 + */
339 + public function save_step_metadata(\WP_REST_Request $request)
340 + {
341 + $params = $request->get_params();
342 + $funnel_id = isset($params['funnel_id']) ? intval($params['funnel_id']) : 0;
343 + $step_id = isset($params['step_id']) ? intval($params['step_id']) : 0;
317 344
318 - $step_id = sanitize_text_field( $payload['step_id'] );
319 - $step_type = get_post_meta( $step_id, '_step_type', true );
345 + if (!$funnel_id) {
346 + wp_send_json_error(array(
347 + 'success' => false,
348 + 'message' => __('Invalid funnel id is provided.', 'wpfnl')
349 + ));
350 + }
320 351
321 - /**
322 - * Delete the automation data linked with the step
323 - *
324 - * @since 2.7.0
325 - *
326 - * @param int $step_id Step ID.
327 - */
328 - do_action( 'wpfunnels/before_delete_step', $step_id ); //phpcs:ignore
352 + if (WPFNL_STEPS_POST_TYPE !== get_post_type( $step_id )) {
353 + wp_send_json_error(array(
354 + 'success' => false,
355 + 'message' => __('Invalid step id is provided.', 'wpfnl')
356 + ));
357 + }
329 358
330 - $response = $this->prepare_wp_error_response(
331 - 'rest_invalid_stepID',
332 - __( 'Invalid Step ID.', 'wpfnl' ),
333 - array( 'status' => 404 )
334 - );
359 + $is_slug_available = Wpfnl_functions::is_slug_available($params['slug'], $step_id, $params['title']);
335 360
336 - if ( $step_type ) {
337 - $response = $this->delete_regular_step($step_id);
338 - } else if ( $step_id ){ // For conditional step.
339 - $response = $this->conditional_step_response($step_id);
340 - }
341 - return $response;
342 - }
361 + if (!$is_slug_available) {
362 + wp_send_json_error(array(
363 + 'success' => false,
364 + 'message' => __('Slug must be unique', 'wpfnl')
365 + ));
366 + }
343 367
344 - /**
345 - * Delete a regular step and all its data.
346 - *
347 - * @param int $step_id The ID of the regular step to be deleted.
348 - *
349 - * @return array The response containing the success status and message.
350 - *
351 - * @since 2.7.9
352 - */
353 - private function delete_regular_step( $step_id ) {
354 - if ( !$step_id ){
355 - return $this->prepare_wp_error_response(
356 - 'rest_invalid_stepID',
357 - __( 'Invalid Step ID.', 'wpfnl' ),
358 - array( 'status' => 404 )
359 - );
360 - }
361 -
362 - $step = new Wpfnl::$instance->step_store();
363 - $step->read( $step_id );
368 + $result = $this->update_step_name( $funnel_id, $step_id, $params );
369 + $step_type = Wpfnl_functions::get_step_type($step_id);
370 + $default_meta = Wpfnl_functions::get_step_default_meta($step_type);
364 371
365 - $funnel_id = $step->get_funnel_id();
366 - $delete_result = $step->delete( $step_id );
367 - $funnel = Wpfnl::$instance->funnel_store;
368 - $funnel->read($funnel_id);
372 + Wpfnl_Step_Meta_keys::save_meta($step_id, $params, $default_meta);
369 373
370 - if ( $delete_result ) {
371 - return $this->prepare_wp_success_response( 'Step deleted successfully', 200 );
372 - }
374 + return rest_ensure_response(array(
375 + 'success' => true,
376 + 'post_title' => $result['post_title'],
377 + 'permalink' => $result['permalink'],
378 + 'funnel_main_link' => $result['funnel_main_link'],
379 + 'slug' => $result['slug'],
380 + 'message' => __('Saved Successfully', 'wpfnl')
381 + ));
382 + }
373 383
374 - $response = $this->prepare_wp_error_response(
375 - 'rest_delete_failure',
376 - __( 'Failed to delete step.', 'wpfnl' ),
377 - array( 'status' => 500 )
378 - );
379 -
380 - return $response ;
381 - }
382 384
383 - /**
384 - * Response for deleting a conditional step.
385 - *
386 - * @param int $step_id The ID of the conditional step to be deleted.
387 - *
388 - * @return array The response indicating the success of the deletion.
389 - *
390 - * @since 2.7.9
391 - */
392 - private function conditional_step_response( $step_id ) {
393 - if ( !$step_id ){
394 - return $this->prepare_wp_error_response(
395 - 'rest_invalid_stepID',
396 - __( 'Invalid Step ID.', 'wpfnl' ),
397 - array( 'status' => 404 )
398 - );
399 - }
385 + /**
386 + * Update the step name and step slug. This will also impact the drawflow data to update the step name
387 + * and slug which is saved under funnel.
388 + *
389 + * @param $funnel_id
390 + * @param $step_id
391 + * @param $metadata
392 + * @return array
393 + *
394 + * @since 3.0.14
395 + */
396 + public function update_step_name( $funnel_id, $step_id, $metadata ) {
397 + $step_title = isset( $metadata['title'] ) ? sanitize_text_field( $metadata['title'] ) : '';
398 + $step_slug = isset( $metadata['slug'] ) ? sanitize_title( $metadata['slug'] ) : '';
399 + $parent_id = get_post_meta($step_id, '_parent_step_id', true);
400 400
401 - return $this->prepare_wp_success_response( 'Conditional step deleted successfully',200 );
402 - }
401 + wp_update_post([
402 + "ID" => $step_id,
403 + "post_title" => $step_title,
404 + "post_name" => $step_slug,
405 + ]);
403 406
407 + if ( defined('WPFNL_PRO_VERSION') ) {
408 + do_action('wpfunnels/before_update_step_meta', $step_id, $funnel_id, $metadata);
409 + }
410 + else {
411 + if (isset($metadata['title'], $metadata['slug'])) {
412 + $steps = Wpfnl_functions::get_steps($funnel_id);
413 + foreach ($steps as $key => $step) {
414 + if ( $step['id'] == $step_id ) {
415 + $steps[$key]['name'] = $metadata['title'];
416 + }
417 + }
418 + update_post_meta( $funnel_id, '_steps_order', $steps );
419 + }
420 + }
404 421
405 - /**
406 - * Prepare a single setting object for response.
407 - *
408 - * @param object $item Setting object.
409 - * @param WP_REST_Request $request Request object.
410 - *
411 - * @return \WP_REST_Response $response Response data.
412 - * @since 1.0.0
413 - */
414 - public function prepare_item_for_response($item, $request)
415 - {
416 - $data = $this->add_additional_fields_to_object($item, $request);
417 - return rest_ensure_response( $data );
418 - }
422 + if ($step_id == $parent_id || !$parent_id) {
423 + $funnel_data = get_post_meta($funnel_id, '_funnel_data', true);
424 + if (isset($funnel_data['drawflow']['Home']['data']) and is_array($funnel_data['drawflow']['Home']['data'])) {
419 425
420 - /**
426 + foreach ($funnel_data['drawflow']['Home']['data'] as $key => $data) {
427 + if (isset($data['data']['step_id']) && (int)$step_id === (int)$data['data']['step_id']) {
428 + $edit_post_link = base64_encode(get_edit_post_link($step_id));
429 + $view_link = base64_encode(get_the_permalink($step_id));
430 + $funnel_data['drawflow']['Home']['data'][$key]['data']['step_view_link'] = $view_link;
431 + $funnel_data['drawflow']['Home']['data'][$key]['data']['step_edit_link'] = $edit_post_link;
432 + }
433 + }
434 + update_post_meta($funnel_id, '_funnel_data', $funnel_data);
435 + }
436 +
437 + $funnel_data = get_post_meta($funnel_id, 'funnel_data', true);
438 + if (isset($funnel_data['drawflow']['Home']['data']) and is_array($funnel_data['drawflow']['Home']['data'])) {
439 + foreach ($funnel_data['drawflow']['Home']['data'] as $key => $data) {
440 + if (isset($data['data']['step_id']) && (int)$step_id === (int)$data['data']['step_id']) {
441 + $edit_post_link = base64_encode(get_edit_post_link($step_id));
442 + $view_link = base64_encode(get_the_permalink($step_id));
443 + $funnel_data['drawflow']['Home']['data'][$key]['data']['step_view_link'] = $view_link;
444 + $funnel_data['drawflow']['Home']['data'][$key]['data']['step_edit_link'] = $edit_post_link;
445 + }
446 + }
447 + update_post_meta($funnel_id, 'funnel_data', $funnel_data);
448 + }
449 + }
450 +
451 + $first_step_id = Wpfnl_functions::get_first_step($funnel_id);
452 + $utm_settings = Wpfnl_functions::get_funnel_utm_settings($funnel_id);
453 + $view_link = get_post_permalink($first_step_id);
454 +
455 + if (!empty($utm_settings['utm_enable']) && 'on' === $utm_settings['utm_enable']) {
456 + unset($utm_settings['utm_enable']);
457 + $view_link = add_query_arg($utm_settings, $view_link);
458 + $view_link = strtolower($view_link);
459 + }
460 +
461 + return array(
462 + 'post_title' => $step_title,
463 + 'permalink' => rtrim(get_the_permalink($step_id), '/'),
464 + 'funnel_main_link' => esc_url($view_link),
465 + 'slug' => sanitize_title($step_slug),
466 + );
467 + }
468 +
469 +
470 +
471 + /**
472 + * Common function to update step meta
473 + *
474 + * @param WP_REST_Request $request
475 + *
476 + * @return \WP_REST_Response
477 + *
478 + * @since 2.7.10
479 + */
480 + public static function update_step_meta_on_funnel_name_change($funnel_id, $step_id, $settings)
481 + {
482 + if (is_plugin_active('wpfunnels-pro/wpfnl-pro.php') && Wpfnl_functions::is_pro_license_activated()) {
483 + /**
484 + * Fires to update step slug on ab testing variation on funnel name change
485 + *
486 + * @param int $step_id The ID of the step.
487 + * @param int $funnel_id The ID of the funnel to which the step belongs.
488 + * @param array $settings An array of settings containing the title and slug for the step.
489 + * @since 2.7.0
490 + *
491 + */
492 + do_action('wpfunnels/before_update_step_meta_on_funnel_name_change', $step_id, $funnel_id, $settings);
493 + } else {
494 + if (isset($settings['funnel_id'], $settings['step_id'], $settings['title'], $settings['slug'])) {
495 + $steps = Wpfnl_functions::get_steps($settings['funnel_id']);
496 + if (!empty($steps)) {
497 + foreach ($steps as $key => $step) {
498 + if ($step['id'] == $settings['step_id']) {
499 + $steps[$key]['name'] = $settings['title'];
500 + }
501 + }
502 + }
503 + update_post_meta($settings['funnel_id'], '_steps_order', $steps);
504 + wp_update_post([
505 + "ID" => $step_id,
506 + "post_title" => wp_strip_all_tags($settings['title']),
507 + "post_name" => sanitize_title($settings['slug']),
508 + ]);
509 + }
510 + }
511 + }
512 +
513 +
514 + /**
515 + * Delete step and all its data
516 + *
517 + * @param WP_REST_Request $payload Data from request.
518 + *
519 + * @return array
520 + *
521 + * @since 2.7.9
522 + */
523 + public function delete_step($payload)
524 + {
525 + if (!isset ($payload['step_id'])) {
526 + return $this->prepare_wp_error_response(
527 + 'rest_invalid_stepID',
528 + __('Invalid Step ID.', 'wpfnl'),
529 + array('status' => 404)
530 + );
531 + }
532 +
533 +
534 + $step_id = sanitize_text_field($payload['step_id']);
535 + $step_type = get_post_meta($step_id, '_step_type', true);
536 +
537 + $result = [
538 + 'success' => true,
539 + ];
540 +
541 + if (!empty($payload['nodeId'])) {
542 + $is_enable = Wpfnl_functions::maybe_enable_condition($step_id);
543 + $condiitons = Wpfnl_functions::get_conditions($step_id);
544 + $next_step = Wpfnl_functions::get_conditional_next_step($step_id);
545 + $funnel_id = Wpfnl_functions::get_funnel_id_from_step($step_id);
546 + $data = get_post_meta($funnel_id, '_wpfnl_reconfigurable_condition_data', true);
547 +
548 + if (!is_array($data) || empty($data)) {
549 + $data = [];
550 + } else {
551 + $key = array_search($payload['nodeId'], array_column($data, 'nodeId'));
552 + if (false !== $key) {
553 + unset($data[$key]);
554 + }
555 + }
556 +
557 + $is_enable_condition = get_post_meta($step_id, '_wpfnl_maybe_enable_condition', true);
558 +
559 + if (!empty($payload['stepId']) && !empty($payload['nodeType']) && 'addstep' !== $payload['nodeType']) {
560 + update_post_meta($payload['stepId'], '_wpfnl_maybe_enable_condition', $is_enable_condition);
561 + }
562 +
563 + $updatedData = [
564 + 'step_id' => !empty($payload['nodeType']) && 'addstep' !== $payload['nodeType'] && !empty($payload['stepId']) ? $payload['stepId'] : '',
565 + 'nodeId' => $payload['nodeId'],
566 + 'is_enable' => $is_enable_condition,
567 + 'conditions' => get_post_meta($step_id, '_wpfnl_step_conditions', true),
568 + 'next_step' => get_post_meta($step_id, '_wpfnl_next_step_after_condition', true),
569 + ];
570 +
571 + array_push($data, $updatedData);
572 +
573 + update_post_meta($funnel_id, '_wpfnl_reconfigurable_condition_data', $data);
574 + $result['reconfigurable_condition_data'] = $data;
575 + }
576 +
577 +
578 + /**
579 + * Delete the automation data linked with the step
580 + *
581 + * @param int $step_id Step ID.
582 + * @since 2.7.0
583 + *
584 + */
585 + do_action('wpfunnels/before_delete_step', $step_id); //phpcs:ignore
586 +
587 + $response = $this->prepare_wp_error_response(
588 + 'rest_invalid_stepID',
589 + __('Invalid Step ID.', 'wpfnl'),
590 + array('status' => 404)
591 + );
592 +
593 + if ($step_type) {
594 + $response = $this->delete_regular_step($step_id);
595 + } else if ($step_id) { // For conditional step.
596 + $response = $this->conditional_step_response($step_id);
597 + }
598 +
599 + $result['response'] = $response;
600 + return $result;
601 + }
602 +
603 + /**
604 + * Delete a regular step and all its data.
605 + *
606 + * @param int $step_id The ID of the regular step to be deleted.
607 + *
608 + * @return array The response containing the success status and message.
609 + *
610 + * @since 2.7.9
611 + */
612 + private function delete_regular_step($step_id)
613 + {
614 + if (!$step_id) {
615 + return $this->prepare_wp_error_response(
616 + 'rest_invalid_stepID',
617 + __('Invalid Step ID.', 'wpfnl'),
618 + array('status' => 404)
619 + );
620 + }
621 +
622 + $step = new Wpfnl::$instance->step_store();
623 + $step->read($step_id);
624 +
625 + $funnel_id = $step->get_funnel_id();
626 + $delete_result = $step->delete($step_id);
627 + $funnel = Wpfnl::$instance->funnel_store;
628 + $funnel->read($funnel_id);
629 +
630 + if ($delete_result) {
631 + return $this->prepare_wp_success_response('Step deleted successfully', 200);
632 + }
633 +
634 + $response = $this->prepare_wp_error_response(
635 + 'rest_delete_failure',
636 + __('Failed to delete step.', 'wpfnl'),
637 + array('status' => 500)
638 + );
639 +
640 + return $response;
641 + }
642 +
643 + /**
644 + * Response for deleting a conditional step.
645 + *
646 + * @param int $step_id The ID of the conditional step to be deleted.
647 + *
648 + * @return array The response indicating the success of the deletion.
649 + *
650 + * @since 2.7.9
651 + */
652 + private function conditional_step_response($step_id)
653 + {
654 + if (!$step_id) {
655 + return $this->prepare_wp_error_response(
656 + 'rest_invalid_stepID',
657 + __('Invalid Step ID.', 'wpfnl'),
658 + array('status' => 404)
659 + );
660 + }
661 +
662 + return $this->prepare_wp_success_response('Conditional step deleted successfully', 200);
663 + }
664 +
665 +
666 + /**
667 + * Prepare a single setting object for response.
668 + *
669 + * @param object $item Setting object.
670 + * @param WP_REST_Request $request Request object.
671 + *
672 + * @return \WP_REST_Response $response Response data.
673 + * @since 1.0.0
674 + */
675 + public function prepare_item_for_response($item, $request)
676 + {
677 + $data = $this->add_additional_fields_to_object($item, $request);
678 + return rest_ensure_response($data);
679 + }
680 +
681 + /**
421 682 * Import wp funnel steps from remote servers.
422 683 *
423 684 * @param array $payload
424 - *
685 + *
425 686 * @return array
426 687 * @since 1.0.0
427 688 */
428 - public function import_step( $payload ) {
429 - $manager_class = new Manager();
430 - $source = $manager_class->get_source(!empty( $payload['source'] ) ? $payload['source'] : 'remote' );
689 + public function import_step($payload)
690 + {
691 + $manager_class = new Manager();
692 + $source = $manager_class->get_source(!empty($payload['source']) ? $payload['source'] : 'remote');
431 693 return $source->import_step($payload);
432 694 }
433 695
696 +
697 + /**
698 + * Update conditional status for a step.
699 + *
700 + * This function updates the conditional status for a specific step based on the provided
701 + * step ID and status in the request. It checks for required parameters, sanitizes input,
702 + * and updates the corresponding post meta with the new status.
703 + *
704 + * @param WP_REST_Request $request The REST request object containing parameters.
705 + *
706 + * @return \WP_REST_Response The REST response indicating the success of the operation.
707 + * @since 2.9.0
708 + *
709 + */
710 + public function update_conditional_status($request)
711 + {
712 + $required_params = array('stepId', 'status');
713 +
714 + // Check if all required parameters are present in the request.
715 + foreach ($required_params as $param) {
716 + if (!$request->has_param($param)) {
717 + return rest_ensure_response($this->prepare_wp_error_response(
718 + __("Required parameter '$param' is missing.", 'wpfnl'), 400
719 + ));
720 + }
721 + }
722 +
723 + // Get the step ID and status from the request.
724 + $step_id = sanitize_text_field($request['stepId']);
725 + $status = sanitize_text_field($request['status']);
726 +
727 + if (!$step_id) {
728 + return rest_ensure_response($this->prepare_wp_error_response(
729 + __("Required parameter step id is empty.", 'wpfnl'), 400
730 + ));
731 + }
732 +
733 + // Update the conditional status post meta.
734 + update_post_meta($step_id, '_wpfnl_maybe_enable_condition', $status);
735 +
736 + $funnel_id = get_post_meta($step_id, '_funnel_id', true);
737 + $reconfigureSettings = get_post_meta($funnel_id, '_wpfnl_reconfigurable_condition_data', true);
738 + if (is_array($reconfigureSettings) && !empty($reconfigureSettings)) {
739 + $key = array_search($step_id, array_column($reconfigureSettings, 'step_id'));
740 + if (false !== $key) {
741 + unset($reconfigureSettings[$key]);
742 + update_post_meta($funnel_id, '_wpfnl_reconfigurable_condition_data', $reconfigureSettings);
743 + }
744 + }
745 +
746 + // Return a REST response indicating success.
747 + return rest_ensure_response(['success' => true]);
748 + }
749 +
750 +
751 + /**
752 + * Get conditional status and conditions for a step.
753 + *
754 + * This function retrieves the conditional status and associated conditions for a specific step
755 + * based on the provided step ID in the request. It checks for required parameters, sanitizes input,
756 + * and returns the conditional status, along with the array of conditions.
757 + *
758 + * @param WP_REST_Request $request The REST request object containing parameters.
759 + *
760 + * @return \WP_REST_Response The REST response containing the conditional status and conditions.
761 + * @since 2.9.0
762 + *
763 + */
764 + public function get_conditions($request)
765 + {
766 + $required_params = array('stepId');
767 +
768 + // Check if all required parameters are present in the request.
769 + foreach ($required_params as $param) {
770 + if (!isset($request[$param])) {
771 + return rest_ensure_response($this->prepare_wp_error_response(
772 + __("Required parameter '$param' is missing.", 'wpfnl'), 400
773 + ));
774 + }
775 + }
776 +
777 + // Get the step ID from the request.
778 + $step_id = sanitize_text_field($request['stepId']);
779 +
780 + if (!$step_id) {
781 + return rest_ensure_response($this->prepare_wp_error_response(
782 + __("Required parameter step id is empty.", 'wpfnl'), 400
783 + ));
784 + }
785 +
786 + // Retrieve the conditional status from the post meta.
787 + $status = get_post_meta($step_id, '_wpfnl_maybe_enable_condition', true);
788 +
789 + // Prepare the response array.
790 + $response = [
791 + 'success' => true,
792 + ];
793 +
794 + // Set default status if not available.
795 + if (!$status) {
796 + $status = 'no';
797 + }
798 + $response['status'] = $status;
799 +
800 + // Retrieve step conditions from post meta.
801 + $conditions = get_post_meta($step_id, '_wpfnl_step_conditions', true);
802 +
803 + // Ensure conditions are available as an array.
804 + if (!is_array($conditions) || !$conditions) {
805 + $conditions = [];
806 + }
807 + $response['conditions'] = $conditions;
808 +
809 +
810 + $afterCondition = get_post_meta($step_id, '_wpfnl_next_step_after_condition', true);
811 + if (!is_array($afterCondition) || !$afterCondition) {
812 + $afterCondition = [];
813 + }
814 +
815 + $response['afterCondition'] = $afterCondition;
816 +
817 + // Return a REST response with the status and conditions.
818 + return rest_ensure_response($response);
819 + }
820 +
821 +
822 + /**
823 + * Save conditional status and conditions for a step.
824 + *
825 + * This function handles the saving of conditional status and associated conditions for a specific step
826 + * based on the provided step ID in the request. It checks for required parameters, sanitizes input,
827 + * and updates the post meta with the conditions and after-condition values.
828 + *
829 + * @param WP_REST_Request $request The REST request object containing parameters.
830 + *
831 + * @return \WP_REST_Response The REST response indicating the success of the operation.
832 + * @since 2.9.0
833 + *
834 + */
835 + public function save_condition($request)
836 + {
837 + $required_params = array('stepId', 'conditions');
838 +
839 + // Check if all required parameters are present in the request.
840 + foreach ($required_params as $param) {
841 + if (!isset($request[$param])) {
842 + return rest_ensure_response($this->prepare_wp_error_response(
843 + __("Required parameter '$param' is missing.", 'wpfnl'), 400
844 + ));
845 + }
846 + }
847 +
848 + $step_id = sanitize_text_field($request['stepId']);
849 + $conditions = filter_var_array($request['conditions']);
850 +
851 + $afterCondition = filter_var_array(isset($request['afterCondition']) ? $request['afterCondition'] : []);
852 +
853 + if (!$step_id) {
854 + return rest_ensure_response($this->prepare_wp_error_response(
855 + __("Required parameter step id is empty.", 'wpfnl'), 400
856 + ));
857 + }
858 +
859 + // Update post meta with the conditions and after-condition values.
860 + update_post_meta($step_id, '_wpfnl_step_conditions', $conditions);
861 + update_post_meta($step_id, '_wpfnl_next_step_after_condition', $afterCondition);
862 +
863 + // Prepare the response array.
864 + $response = [
865 + 'success' => true,
866 + ];
867 +
868 + $funnel_id = get_post_meta($step_id, '_funnel_id', true);
869 + $reconfigureSettings = get_post_meta($funnel_id, '_wpfnl_reconfigurable_condition_data', true);
870 + if (is_array($reconfigureSettings) && !empty($reconfigureSettings)) {
871 + $key = array_search($step_id, array_column($reconfigureSettings, 'step_id'));
872 + if (false !== $key) {
873 + unset($reconfigureSettings[$key]);
874 + update_post_meta($funnel_id, '_wpfnl_reconfigurable_condition_data', $reconfigureSettings);
875 + }
876 + }
877 +
878 + // Return a REST response indicating the success of the operation.
879 + return rest_ensure_response($response);
880 + }
881 +
882 +
883 + /**
884 + * Paste a step and all its data to create a new step.
885 + * This function creates a new step by duplicating an existing step and updating the post meta with the new step information.
886 + *
887 + * @param WP_REST_Request $request The REST request object containing parameters.
888 + *
889 + * @return \WP_REST_Response The REST response indicating the success of the operation.
890 + *
891 + * @since 3.4.16
892 + */
893 + public function paste_step($request){
894 + $required_params = array('stepId','funnelId');
895 +
896 + // Check if all required parameters are present in the request.
897 + foreach ($required_params as $param) {
898 + if (!isset($request[$param])) {
899 + return rest_ensure_response(
900 + $this->prepare_wp_error_response( 400,
901 + sprintf(__("Required parameter '%s' is missing.", 'wpfnl'), $param), ''
902 + )
903 + );
904 + }
905 + }
906 + $parent_step_id = sanitize_text_field($request['stepId']);
907 + $funnel_id = sanitize_text_field($request['funnelId']);
908 + // Clone the parent step to create a new step.
909 + $response = $this->clone_parent_step( $parent_step_id, $funnel_id );
910 + if( !$response ){
911 + return rest_ensure_response($this->prepare_wp_error_response( 400,
912 + __("Failed to duplicate a step", 'wpfnl'), ''
913 + ));
914 + }
915 + $step_id = isset($response['step_id']) ? $response['step_id'] : '';
916 + $step = isset($response['step']) ? $response['step'] : '';
917 + // Duplicate step metadata for this step.
918 + $this->duplicate_all_meta( $step, $parent_step_id, $step_id, $funnel_id );
919 +
920 + $builder = Wpfnl_functions::get_builder_type();
921 + // Clear elementor cache
922 + $this->clear_elementor_cache( $step_id, $builder );
923 + // Get the step view link with UTM
924 + $view_link = $this->get_step_view_link_with_utm( $step_id, $funnel_id );
925 + /**
926 + * Fires after duplicating an A/B testing step in WP Funnels.
927 + *
928 + * @param int $step_id The ID of the duplicated step.
929 + * @param string $builder The name of the builder used for the duplication.
930 + */
931 + do_action('wpfunnels_after_ab_testing_duplicate', $step_id, $builder);
932 + /**
933 + * Fires after a step is duplicated in a funnel.
934 + *
935 + * @param int $funnel_id The ID of the funnel.
936 + * @param int $step_id The ID of the duplicated step.
937 + */
938 + do_action('wpfunnels/after_step_duplicate', $funnel_id, $step_id );
939 + $response = $this->prepare_response_for_paste_step( $step_id, $response, $view_link );
940 + if( !$response ){
941 + return rest_ensure_response($this->prepare_wp_error_response( 400,
942 + __("Failed to duplicate a step", 'wpfnl'), ''
943 + ));
944 + }
945 + return $response;
946 + }
947 +
948 + /**
949 + * Prepare API response for paste step.
950 + *
951 + * @param int $step_id The ID of the step.
952 + * @param array $response The response data.
953 + * @param string $view_link The view link of the step.
954 + *
955 + * @return array The response data.
956 + *
957 + * @throws \WPFunnels\TemplateLibrary\Wpfnl_Source_Remote
958 + *
959 + * @since 3.4.16
960 + */
961 + public function prepare_response_for_paste_step( $step_id, $response, $view_link ){
962 +
963 + if( !$step_id ){
964 + return false;
965 + }
966 +
967 + // Create an instance of remote class.
968 + $remote = new \WPFunnels\TemplateLibrary\Wpfnl_Source_Remote();
969 +
970 + return [
971 + 'success' => true,
972 + 'stepID' => $step_id,
973 + 'step_name' => isset($response['title']) ? $response['title'] : '',
974 + 'step_type' => isset($response['step_type']) ? $response['step_type'] : '',
975 + 'stepEditLink' => get_edit_post_link($step_id),
976 + 'stepViewLink' => $view_link,
977 + 'abTestingSettingsData'=> $remote->get_default_start_setting($step_id),
978 + ];
979 + }
980 +
981 + /**
982 + * Create a new step by duplicating an existing step.
983 + *
984 + * @param int $parent_step_id The ID of the parent step.
985 + * @param int $funnel_id The ID of the funnel.
986 + *
987 + * @return array The response data.
988 + *
989 + * @since 3.4.16
990 + */
991 + public function clone_parent_step( $parent_step_id, $funnel_id ) {
992 + if( !$parent_step_id || !$funnel_id ) {
993 + return false;
994 + }
995 +
996 + $title = get_the_title($parent_step_id);
997 + $page_template = get_post_meta($parent_step_id, '_wp_page_template', true);
998 + $step_type = get_post_meta($parent_step_id, '_step_type', true);
999 + $post_content = get_post_field('post_content', $parent_step_id);
1000 +
1001 + // Create an instance of the step store.
1002 + $step = new \WPFunnels\Data_Store\Wpfnl_Steps_Store_Data();
1003 +
1004 + $step_id = $step->create_step($funnel_id, $title, $step_type, $post_content, true);
1005 +
1006 + if( !$step_id ){
1007 + return false;
1008 + }
1009 + // Update the step meta data.
1010 + $step->update_meta($step_id, '_funnel_id', $funnel_id);
1011 +
1012 + return [
1013 + 'step' => $step,
1014 + 'step_id' => $step_id,
1015 + 'title' => $title,
1016 + 'step_type' => $step_type,
1017 + 'page_template' => $page_template,
1018 + ];
1019 + }
1020 +
1021 +
1022 + /**
1023 + * Duplicate all the meta data for a step.
1024 + *
1025 + * @param object $step The step object.
1026 + * @param int $parent_step_id The ID of the parent step.
1027 + * @param int $step_id The ID of the step.
1028 + * @param int $funnel_id The ID of the funnel.
1029 + *
1030 + * @since 3.4.16
1031 + */
1032 + public function duplicate_all_meta( $step, $parent_step_id, $step_id, $funnel_id ) {
1033 + if( !$parent_step_id || !$step_id || !$funnel_id ) {
1034 + return;
1035 + }
1036 +
1037 + // Create an instance of the funnel store.
1038 + $funnel = new \WPFunnels\Data_Store\Wpfnl_Funnel_Store_Data();
1039 + $funnel->duplicate_all_meta( $parent_step_id, $step_id, array('_funnel_id','_is_duplicate','wpfnl_mint_automation_id') );
1040 +
1041 + /**
1042 + * Save the new step information on funnel data and funnel identifier.
1043 + * This is required to show steps in funnel canvas
1044 + */
1045 +
1046 + $funnel->update_step_id_in_funnel_data_and_identifier($parent_step_id, $step_id, $funnel_id);
1047 + $step->update_meta($step_id, '_is_duplicate', 'yes');
1048 + }
1049 +
1050 + /**
1051 + * Clear elememtor cache and remove the cache for the step.
1052 + * This is required to clear the cache for the step when it is duplicated.
1053 + *
1054 + * @param int $step_id The ID of the step.
1055 + * @param string $builder The name of the builder.
1056 + *
1057 + * @since 3.4.16
1058 + */
1059 + public function clear_elementor_cache( $step_id, $builder ) {
1060 + if( !$step_id || 'elementor' === $builder) {
1061 + return;
1062 + }
1063 +
1064 + $step_edit_link = get_edit_post_link($step_id);
1065 +
1066 + $step_edit_link = str_replace(['&amp;', 'edit'], ['&', 'elementor'], $step_edit_link);
1067 + if ( is_plugin_active( 'elementor/elementor.php' ) && class_exists( '\Elementor\Plugin' ) ) {
1068 + Plugin::$instance->files_manager->clear_cache(); // Clearing cache of Elementor CSS.
1069 + }
1070 +
1071 + }
1072 +
1073 + /**
1074 + * Get step view link with UTM.
1075 + *
1076 + * @param int $step_id The ID of the step.
1077 + * @param int $funnel_id The ID of the funnel.
1078 + *
1079 + * @return string The view link of the step.
1080 + *
1081 + * @since 3.4.16
1082 + */
1083 + public function get_step_view_link_with_utm( $step_id, $funnel_id ) {
1084 + if( !$step_id ||!$funnel_id ) {
1085 + return '';
1086 + }
1087 +
1088 + $view_link = get_post_permalink( $step_id );
1089 + $utm_settings = Wpfnl_functions::get_funnel_utm_settings($funnel_id);
1090 +
1091 + if ( is_array($utm_settings) && isset($utm_settings[ 'utm_enable' ]) && 'on' === $utm_settings[ 'utm_enable' ] ) {
1092 + unset( $utm_settings[ 'utm_enable' ] );
1093 + $view_link = add_query_arg( $utm_settings, $view_link );
1094 + $view_link = strtolower( $view_link );
1095 + }
1096 +
1097 + return $view_link;
1098 + }
434 1099 }