PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.1.3
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.1.3
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
cartflows / modules / flow / classes / class-cartflows-step-post-type.php

class-cartflows-step-post-type.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.1.3, at modules/flow/classes/class-cartflows-step-post-type.php

532 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Step post type.
4 *
5 * @package CartFlows
6 */
7
8 // Exit if accessed directly.
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12 /**
13 * Initialization
14 *
15 * @since 1.0.0
16 */
17 class Cartflows_Step_Post_Type {
18
19
20 /**
21 * Member Variable
22 *
23 * @var instance
24 */
25 private static $instance;
26
27 /**
28 * Member Variable
29 *
30 * @var body_classes
31 */
32 private $body_classes = array();
33
34 /**
35 * Initiator
36 */
37 public static function get_instance() {
38 if ( ! isset( self::$instance ) ) {
39 self::$instance = new self();
40 }
41 return self::$instance;
42 }
43
44 /**
45 * Constructor
46 */
47 public function __construct() {
48
49 add_action( 'init', array( $this, 'step_post_type' ) );
50 add_action( 'init', array( $this, 'add_wp_templates_support' ) );
51 add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );
52
53 add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );
54
55 add_filter( 'template_include', array( $this, 'load_page_template' ), 90 );
56 add_action( 'template_redirect', array( $this, 'query_fix' ), 3 );
57
58 add_action( 'admin_init', array( $this, 'disallowed_admin_all_steps_view' ) );
59 }
60
61 /**
62 * Trys to load page.php for a header, footer or part theme layout.
63 *
64 * @since 1.0.0
65 * @param string $template The current template to be loaded.
66 * @return string
67 */
68 public function load_page_template( $template ) {
69
70 global $post;
71
72 if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
73
74 /**
75 * Remove Next/Prev Navigation
76 * add_filter('next_post_link', '__return_empty_string');
77 * add_filter('previous_post_link', '__return_empty_string');
78 *
79 * $page = locate_template( array( 'page.php' ) );
80 *
81 * if ( ! empty( $page ) ) {
82 * return $page;
83 * }
84 */
85
86 /* Remove Next / Previous Rel Link */
87 remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
88 add_filter( 'next_post_rel_link', '__return_empty_string' );
89 add_filter( 'previous_post_rel_link', '__return_empty_string' );
90
91 $page_template = Cartflows_Helper::get_current_page_template();
92
93 $file = '';
94
95 switch ( $page_template ) {
96
97 case 'cartflows-default':
98 $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
99 $this->body_classes[] = $page_template;
100 break;
101 case 'cartflows-canvas':
102 $file = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
103 $this->body_classes[] = $page_template;
104 break;
105 default:
106 /**
107 * Remove Next/Prev Navigation
108 */
109 add_filter( 'next_post_link', '__return_empty_string' );
110 add_filter( 'previous_post_link', '__return_empty_string' );
111
112 $page = locate_template( array( 'page.php' ) );
113
114 if ( ! empty( $page ) ) {
115 $file = $page;
116 }
117
118 break;
119
120 /**
121 * Default:
122 * $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
123 * $this->body_classes[] = 'cartflows-default';
124 * break;
125 */
126 }
127
128 $file = apply_filters( 'cartflows_page_template_file', $file );
129 $this->body_classes = apply_filters( 'cartflows_page_template_body_classes', $this->body_classes );
130
131
132 // Just to be safe, we check if the file exist first.
133 if ( file_exists( $file ) ) {
134
135 /* Add Body Class */
136 add_filter( 'body_class', array( $this, 'body_class' ) );
137
138 if ( apply_filters( 'cartflows_allow_to_change_page_template', true ) ) {
139 $template = $file;
140 }
141 return $template;
142 } else {
143 // File path intentionally not disclosed for security.
144 return $template;
145 }
146 }
147
148 return $template;
149 }
150
151 /**
152 * Body classes.
153 *
154 * @since 1.0.0
155 * @param array $classes Body classes.
156 * @return array
157 */
158 public function body_class( $classes = array() ) {
159
160 $classes = array_merge( $classes, $this->body_classes );
161
162 return $classes;
163 }
164
165 /**
166 * Create custom post type
167 */
168 public function step_post_type() {
169
170 $labels = array(
171 'name' => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
172 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
173 'search_items' => esc_html__( 'Search Steps', 'cartflows' ),
174 'all_items' => esc_html__( 'All Steps', 'cartflows' ),
175 'edit_item' => esc_html__( 'Edit Step', 'cartflows' ),
176 'view_item' => esc_html__( 'View Step', 'cartflows' ),
177 'add_new' => esc_html__( 'Add New', 'cartflows' ),
178 'update_item' => esc_html__( 'Update Step', 'cartflows' ),
179 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
180 'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
181 );
182
183 $permalink_settings = Cartflows_Helper::get_permalink_settings();
184
185 $args = array(
186 'labels' => $labels,
187 'public' => true,
188 'query_var' => true,
189 'can_export' => true,
190 'exclude_from_search' => true,
191 'show_ui' => true,
192 'show_in_menu' => false,
193 'show_in_admin_bar' => true,
194 'show_in_rest' => current_user_can( 'edit_posts' ),
195 'supports' => array( 'title', 'editor', 'elementor', 'revisions' ),
196 'capability_type' => 'post',
197 'capabilities' => array(
198 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
199 ),
200 'map_meta_cap' => true,
201 );
202
203 if ( isset( $permalink_settings['permalink_structure'] ) && ! empty( $permalink_settings['permalink_structure'] ) ) {
204 $args['rewrite'] = array(
205 'slug' => $permalink_settings['permalink_structure'],
206 'with_front' => false,
207 );
208
209 } elseif ( isset( $permalink_settings['permalink'] ) && ! empty( $permalink_settings['permalink'] ) ) {
210
211 $args['rewrite'] = array(
212 'slug' => $permalink_settings['permalink'],
213 'with_front' => false,
214 );
215 }
216
217 register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );
218
219 // Step Type.
220 $args = array(
221 'label' => __( 'Step Type', 'cartflows' ),
222 'public' => false,
223 'rewrite' => false,
224 'hierarchical' => false,
225 );
226
227 register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );
228
229 // Step Flow.
230 $args = array(
231 'label' => __( 'Step Flow', 'cartflows' ),
232 'public' => false,
233 'rewrite' => false,
234 'hierarchical' => false,
235 );
236
237 register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );
238
239 if ( is_admin() ) {
240 /**
241 * Register 'Elementor' & 'Beaver Builder' site types.
242 *
243 * @see self::add_terms();
244 */
245 $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
246
247 $terms = array(
248 array(
249 'name' => __( 'Landing', 'cartflows' ),
250 'slug' => 'landing',
251 'args' => array(
252 'slug' => 'landing',
253 ),
254 ),
255 array(
256 'name' => __( 'Optin', 'cartflows' ),
257 'slug' => 'optin',
258 'args' => array(
259 'slug' => 'optin',
260 ),
261 ),
262 array(
263 'name' => __( 'Checkout', 'cartflows' ),
264 'slug' => 'checkout',
265 'args' => array(
266 'slug' => 'checkout',
267 ),
268 ),
269 array(
270 'name' => __( 'Thank You', 'cartflows' ),
271 'slug' => 'thankyou',
272 'args' => array(
273 'slug' => 'thankyou',
274 ),
275 ),
276 array(
277 'name' => __( 'Upsell', 'cartflows' ),
278 'slug' => 'upsell',
279 'args' => array(
280 'slug' => 'upsell',
281 ),
282 ),
283 array(
284 'name' => __( 'Downsell', 'cartflows' ),
285 'slug' => 'downsell',
286 'args' => array(
287 'slug' => 'downsell',
288 ),
289 ),
290 );
291
292 $this->add_terms( $taxonomy, $terms );
293
294 }
295 }
296
297 /**
298 * Add WordPress templates.
299 *
300 * Adds Cartflows templates to steps
301 *
302 * @since 1.0.0
303 * @access public
304 */
305 public function add_wp_templates_support() {
306 add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
307 }
308
309 /**
310 * Add page templates.
311 *
312 * @since 1.0.0
313 * @access public
314 *
315 * @param array $page_templates Array of page templates.
316 *
317 * @param object $wp_theme wp theme.
318 * @param object $post post.
319 *
320 * @return array Page templates.
321 */
322 public function add_page_templates( $page_templates, $wp_theme, $post ) {
323
324 $cartflows_templates = array(
325 'cartflows-default' => _x( 'CartFlows — Boxed', 'cartflows' ),
326 'cartflows-canvas' => _x( 'Template for Page Builders', 'cartflows' ),
327 );
328
329 if ( apply_filters( 'cartflows_show_all_page_templates', false ) ) {
330 $cartflows_templates = array_merge( $cartflows_templates, $page_templates );
331 }
332
333 return $cartflows_templates;
334 }
335
336 /**
337 * Query fixe throwing error on 404 page due our post type changes.
338 * We are setting post_type as empty array to fix the issue.
339 * Ther error was throwing due to redirect_canonical function
340 * This fix is apply for 404 page only.
341 *
342 * Also redirects disabled steps to the next enabled step in the flow.
343 */
344 public function query_fix() {
345
346 global $wp_query, $post;
347
348 if ( $wp_query->is_404() ) {
349 $wp_query->set( 'post_type', array() );
350 } elseif ( ! empty( $post->ID ) && CARTFLOWS_STEP_POST_TYPE == $post->post_type && wcf()->utils->is_step_disabled( $post->ID ) ) {
351 $flow_id = (int) wcf()->utils->get_flow_id_from_step_id( $post->ID );
352 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
353 $next_step_url = '';
354 if ( is_array( $steps ) && ! empty( $steps ) ) {
355
356 // Find the next enabled step.
357 foreach ( $steps as $step ) {
358 if ( isset( $step['id'] ) && $post->ID !== $step['id'] && ! wcf()->utils->is_step_disabled( $step['id'] ) ) {
359 $next_step_url = get_permalink( $step['id'] );
360 break;
361 }
362 }
363 }
364
365 if ( $next_step_url ) {
366 wp_safe_redirect( $next_step_url );
367 exit;
368 }
369 }
370 }
371
372 /**
373 * Prevent slug duplicated
374 *
375 * @param string $slug post slug.
376 * @param int $post_ID post id.
377 * @param string $post_status post status.
378 * @param string $post_type post type.
379 * @param int $post_parent post parent id.
380 * @param string $original_slug original slug.
381 * @return string
382 */
383 public function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
384
385 $check_post_types = array(
386 'post',
387 'page',
388 CARTFLOWS_STEP_POST_TYPE,
389 );
390
391 if ( ! in_array( $post_type, $check_post_types, true ) ) {
392 return $slug;
393 }
394
395 if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
396 // Saving a post, check for duplicates in POST or PAGE post types.
397 $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
398 $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
399
400 if ( $post_match || $page_match ) {
401 $slug .= '-2';
402 }
403 } else {
404
405 // Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
406 $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );
407
408 if ( $custom_post_type_match ) {
409 $slug .= '-2';
410 }
411 }
412
413 return $slug;
414 }
415
416 /**
417 * Add Update messages for any custom post type
418 *
419 * @param array $messages Array of default messages.
420 */
421 public function post_update_messages( $messages ) {
422
423 $custom_post_type = get_post_type( get_the_ID() );
424
425 if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {
426
427 $obj = get_post_type_object( $custom_post_type );
428 $singular_name = $obj->labels->singular_name;
429 $messages[ $custom_post_type ] = array(
430 0 => '', // Unused. Messages start at index 1.
431 /* translators: %s: singular custom post type name */
432 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
433 /* translators: %s: singular custom post type name */
434 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
435 /* translators: %s: singular custom post type name */
436 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
437 /* translators: %s: singular custom post type name */
438 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
439 /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
440 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore WordPress.Security.NonceVerification.Recommended
441 /* translators: %s: singular custom post type name */
442 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
443 /* translators: %s: singular custom post type name */
444 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
445 /* translators: %s: singular custom post type name */
446 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
447 /* translators: %s: singular custom post type name */
448 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
449 /* translators: %s: singular custom post type name */
450 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
451 );
452 }
453
454 return $messages;
455 }
456
457 /**
458 * Add Terms for Taxonomy.
459 *
460 * => Example.
461 *
462 * $taxonomy = '{taxonomy}';
463 * $terms = array(
464 * array(
465 * 'name' => 'Landing',
466 * 'slug' => 'landing',
467 * ),
468 * array(
469 * 'name' => 'Checkout',
470 * 'slug' => 'checkout',
471 * ),
472 * );
473 *
474 * self::add_terms( $taxonomy, $terms );
475 *
476 * @since 1.0.0
477 * @param string $taxonomy Taxonomy Name.
478 * @param array $terms Terms list.
479 * @return void
480 */
481 public function add_terms( $taxonomy = '', $terms = array() ) {
482
483 foreach ( $terms as $key => $term ) {
484
485 $term_exist = term_exists( $term['slug'], $taxonomy );
486
487 if ( empty( $term_exist ) ) {
488
489 /**
490 * Add additional args if passed from request.
491 *
492 * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
493 */
494 if ( array_key_exists( 'args', $term ) ) {
495 wp_insert_term( $term['name'], $taxonomy, $term['args'] );
496 } else {
497
498 $term['args'] = array( $term['slug'] );
499
500 wp_insert_term( $term['name'], $taxonomy, $term['args'] );
501 }
502 }
503 }
504 }
505
506 /**
507 * Redirect admin pages.
508 *
509 * @return void
510 */
511 public function disallowed_admin_all_steps_view() {
512
513 global $pagenow;
514
515 // Check current admin page. If step post type view redirect it to flow.
516 if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && CARTFLOWS_STEP_POST_TYPE === $_GET['post_type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
517
518 if ( isset( $_GET['debug'] ) && 'true' === sanitize_text_field( $_GET['debug'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
519 return;
520 }
521
522 wp_safe_redirect( admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE ) );
523 exit;
524 }
525 }
526 }
527
528 /**
529 * Kicking this off by calling 'get_instance()' method
530 */
531 Cartflows_Step_Post_Type::get_instance();
532