Uname: Linux p3plzcpnl499967.prod.phx3.secureserver.net 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
Software: Apache
PHP version: 8.2.30 [ PHP INFO ] PHP os: Linux
Server Ip: 208.109.40.231
Your Ip: 216.73.216.26
User: nayff91c5tsx (10005085) | Group: nayff91c5tsx (10005085)
Safe Mode: OFF
Disable Function:
NONE

name : class-custom-sections.php
<?php
/**
 * Custom Sections.
 *
 * @package Page Builder Framework Premium Add-On
 */

namespace WPBF;

ob_start();

/**
 * Custom Sections.
 */
class Custom_Sections {

	/**
	 * Post types which are not going to be used with Custom Sections.
	 *
	 * All these should be removed using a filter in the respective integration or plugin.
	 *
	 * @var array
	 */
	private $unused_post_types = array(
		'attachment',
		'wpbf_hooks',
		'fl-builder-template',
		'elementor_library',
		'mailpoet_page',
		'udb_admin_page',
	);

	/**
	 * Post types which are handled/ managed manually (excluded from dynamic handling).
	 *
	 * @var array
	 */
	private $static_post_types = array(
		'post',
		'page',

		/**
		 * WooCommerce's "product" & EDD's "download" are not totally static.
		 *
		 * It's static because we select & manage the taxonomies being shown
		 * in the inclusion & exclusion rules.
		 *
		 * But their post listing are called together with other dynamic post types.
		 */
		'product',
		'download',
	);

	/**
	 * Taxonomies excluded from dynamic handling.
	 *
	 * @var array
	 */
	private $excluded_taxonomies = array(
		'post_tag',
		'post_category',
		'download_category',
		'download_tag',
		'product_cat',
		'product_tag',
	);

	/**
	 * Post types which are handled dynamically.
	 *
	 * @var array
	 */
	private $dynamic_post_types = array();

	/**
	 * Setup action & filter hooks.
	 */
	public function __construct() {

		add_action( 'init', array( $this, 'register_cpt' ) );
		add_action( 'admin_menu', array( $this, 'menu_item' ), 100 );
		add_action( 'admin_head', array( $this, 'fix_current_item' ) );
		add_filter( 'manage_wpbf_hooks_posts_columns', array( $this, 'register_columns' ) );
		add_action( 'manage_wpbf_hooks_posts_custom_column', array( $this, 'add_columns' ), 10, 2 );

		add_action( 'add_meta_boxes', array( $this, 'meta_box' ) );

		add_filter( 'post_updated_messages', array( $this, 'cpt_messages' ) );

		add_action( 'save_post', array( $this, 'save_meta_box_data' ) );

		add_action( 'wp', array( $this, 'do_published_hooks' ) );
		add_action( 'wp', array( $this, 'frontend_show_hooks' ) );
		add_action( 'admin_bar_menu', array( $this, 'display_hooks' ), 999 );

		add_action( 'template_redirect', array( $this, 'cpt_redirect' ) );

		add_action( 'admin_enqueue_scripts', array( $this, 'hook_admin_scripts' ) );

	}

	/**
	 * Hook admin scripts.
	 */
	public function hook_admin_scripts() {

		wp_enqueue_style( 'wpbf-premium-hooks', WPBF_PREMIUM_URI . 'css/wpbf-premium-hooks.css', '', WPBF_PREMIUM_VERSION );

	}

	/**
	 * Check whether or not Gutenberg is active for the provided post ID.
	 *
	 * @param int $hook_id The post ID.
	 *
	 * @return boolean Whether or not Gutenberg is active.
	 */
	public function is_gutenberg_active( $hook_id ) {

		$gutenberg = true;

		if ( version_compare( $GLOBALS['wp_version'], '5.0', '<' ) ) {
			$gutenberg = false;
		}

		if ( ! function_exists( 'has_blocks' ) || ! has_blocks( $hook_id ) ) {
			$gutenberg = false;
		}

		return $gutenberg;

	}

	/**
	 * Check whether or not Brizy is active for the provided post ID.
	 *
	 * @param int $hook_id The post ID.
	 *
	 * @return boolean Where or not Brizy is active.
	 */
	public function is_brizy_active( $hook_id ) {

		if ( class_exists( '\Brizy_Editor_Post' ) ) {

			if ( ! $this->supported_in_brizy_post_types() ) {
				return false;
			}

			try {
				$post = \Brizy_Editor_Post::get( $hook_id );

				if ( is_object( $post ) && method_exists( $post, 'uses_editor' ) && $post->uses_editor() ) {
					return true;
				}
			} catch ( \Exception $e ) {
				return false;
			}
		}

		return false;

	}

	/**
	 * Check whether custom section post type is checked in Brizy settings.
	 *
	 * @see wp-content/plugins/brizy/editor.php
	 */
	public function supported_in_brizy_post_types() {

		if ( ! class_exists( '\Brizy_Editor' ) ) {
			return false;
		}

		$brizy_editor         = \Brizy_Editor::get();
		$supported_post_types = $brizy_editor->supported_post_types();

		if ( in_array( 'wpbf_hooks', $supported_post_types, true ) ) {
			return true;
		}

		return false;

	}

	/**
	 * Initialize Brizy frontend.
	 *
	 * This was taken from `is_view_page` condition inside `initialize_front_end` function
	 * in brizy/public/main.php file.
	 *
	 * What we don't use from that function:
	 * - template_include hook
	 * - preparePost private function
	 * - plugin_live_composer_fixes private function
	 * - remove `wpautop` filter from `the_content` (moved to our `render_brizy_content` function)
	 *
	 * @see wp-content/plugins/brizy/public/main.php
	 *
	 * @param int $post_id The post id.
	 */
	public function initialize_brizy_frontend( $post_id ) {

		$brizy_post   = \Brizy_Editor_Post::get( $post_id );
		$brizy_public = \Brizy_Public_Main::get( $brizy_post );

		// Insert the compiled head and content.
		add_filter( 'body_class', array( $brizy_public, 'body_class_frontend' ) );
		add_action( 'wp_head', array( $brizy_public, 'insert_page_head' ) );
		add_action( 'admin_bar_menu', array( $brizy_public, 'toolbar_link' ), 999 );
		add_action( 'wp_enqueue_scripts', array( $brizy_public, '_action_enqueue_preview_assets' ), 9999 );
		// add_filter( 'the_content', array( $brizy_public, 'insert_page_content' ), -12000 );
		// add_action( 'brizy_template_content', array( $brizy_public, 'brizy_the_content' ) );

		// $this->render_brizy_content( $post_id );
	}

	/**
	 * Render Brizy content.
	 *
	 * @see wp-content/plugins/brizy/public/main.php
	 *
	 * @param int $post_id The post id.
	 */
	public function render_brizy_content( $post_id ) {

		// @see wp-content/plugins/brizy/public/main.php
		remove_filter( 'the_content', 'wpautop' );

		$post         = \Brizy_Editor_Post::get( $post_id );
		$brizy_public = \Brizy_Public_Main::get( $post );

		$brizy_public->brizy_the_content();

		// Let's bring back the filter after rendering the content.
		add_filter( 'the_content', 'wpautop' );

	}

	/**
	 * Do published hooks.
	 */
	public function do_published_hooks() {

		if ( is_singular( 'wpbf_hooks' ) ) {
			return;
		}

		$args = array(
			'post_type'        => 'wpbf_hooks',
			'no_found_rows'    => true,
			'post_status'      => 'publish',
			'numberposts'      => 100,
			'fields'           => 'ids',
			'order'            => 'ASC',
			'suppress_filters' => false,
		);

		$hooks   = get_posts( $args );
		$options = get_post_meta( get_the_ID(), 'wpbf_options', true );
		$options = ! empty( $options ) ? $options : array();

		foreach ( $hooks as $hook_id ) {

			$location = get_post_meta( $hook_id, '_wpbf_hook_location', true );
			$action   = get_post_meta( $hook_id, '_wpbf_hook_action', true );
			$priority = get_post_meta( $hook_id, '_wpbf_hook_priority', true );
			$priority = empty( $priority ) ? 10 : $priority;

			if ( ! empty( $location ) ) {

				if ( 'header' === $location ) {
					$action = 'wpbf_header';
				} elseif ( 'footer' === $location ) {
					$action = 'wpbf_footer';
				} elseif ( '404' === $location ) {
					$action = 'wpbf_404';
				}
			}

			// Stop, and continue to next loop if $action is empty.
			if ( empty( $action ) ) {
				continue;
			}

			$matched_display_rule = $this->matched_display_rules( $hook_id );

			// If current "singular" is going to display custom section, then remove the default actions.
			if ( $matched_display_rule ) {
				switch ( $action ) {
					case 'wpbf_header':
						remove_action( 'wpbf_header', 'wpbf_do_header' );
						break;
					case 'wpbf_footer':
						remove_action( 'wpbf_before_footer', 'wpbf_custom_footer' );
						remove_action( 'wpbf_footer', 'wpbf_do_footer' );
						break;
					case 'wpbf_404':
						remove_action( 'wpbf_404', 'wpbf_do_404' );
						break;
				}
			}

			$position_disabled = false;

			if ( 'header' === $location || 'footer' === $location ) {
				if ( in_array( 'remove-' . $location, $options, true ) ) {
					$position_disabled = true;
				}
			}

			// Stop, and continue to next loop if the rule is not passed.
			if ( ! $matched_display_rule || $position_disabled ) {
				continue;
			}

			add_action(
				'template_redirect',
				function () use ( $hook_id ) {

					if ( $this->is_brizy_active( $hook_id ) ) {
						$this->initialize_brizy_frontend( $hook_id );
					}

				}
			);

			add_action(
				'wp_enqueue_scripts',
				function () use ( $hook_id ) {

					if ( ! class_exists( '\Elementor\Core\Files\CSS\Post' ) ) {
						return;
					}

					$css_file = new \Elementor\Core\Files\CSS\Post( $hook_id );
					$css_file->enqueue();

				},
				500
			);

			add_action(
				$action,
				function () use ( $hook_id, $action ) {

					$hide_on_desktop = get_post_meta( $hook_id, '_wpbf_hide_on_desktop', true );
					$hide_on_tablet  = get_post_meta( $hook_id, '_wpbf_hide_on_tablet', true );
					$hide_on_mobile  = get_post_meta( $hook_id, '_wpbf_hide_on_mobile', true );

					$wrapper_classes  = 'wpbf-custom-section-' . get_post_field( 'post_name', $hook_id );
					$wrapper_classes .= $hide_on_desktop ? ' wpbf-hidden-large' : '';
					$wrapper_classes .= $hide_on_tablet ? ' wpbf-hidden-medium' : '';
					$wrapper_classes .= $hide_on_mobile ? ' wpbf-hidden-small' : '';

					/**
					 * Remove our wrapper from WooCommerce product loop.
					 * Reason being, this used to interfere with page builders.
					 */
					// add_filter( 'wpbf_woo_product_loop_wrapper', '__return_false' );

					echo '<div class="wpbf-custom-section ' . esc_attr( $wrapper_classes ) . '">';

					if ( class_exists( '\Elementor\Plugin' ) && \Elementor\Plugin::$instance->db->is_built_with_elementor( $hook_id ) ) {
						if ( defined( 'ELEMENTOR_PRO_VERSION' ) ) {
							// Elementor PRO support.
							echo do_shortcode( sprintf( '[elementor-template id="%s"]', $hook_id ) );
						} else {
							// Elementor Free support.
							$elementor_frontend = new \Elementor\Frontend();

							echo $elementor_frontend->get_builder_content_for_display( $hook_id );
						}
					} elseif ( $this->is_brizy_active( $hook_id ) ) {
						$this->render_brizy_content( $hook_id );
					} elseif ( function_exists( 'et_pb_is_pagebuilder_used' ) && et_pb_is_pagebuilder_used( $hook_id ) ) {
						// Divi support.
						$style_suffix = et_load_unminified_styles() ? '' : '.min';

						wp_enqueue_style( 'et-builder-modules-style', ET_BUILDER_URI . '/styles/frontend-builder-plugin-style' . $style_suffix . '.css', array(), ET_BUILDER_VERSION );

						$hook_post    = get_post( $hook_id );
						$hook_content = $hook_post->post_content;
						$hook_content = et_builder_get_layout_opening_wrapper() . $hook_content . et_builder_get_layout_closing_wrapper();
						$hook_content = et_builder_get_builder_content_opening_wrapper() . $hook_content . et_builder_get_builder_content_closing_wrapper();

						echo apply_filters( 'the_content', $hook_content );
					} elseif ( class_exists( '\FLBuilderModel' ) && \FLBuilderModel::is_builder_enabled( $hook_id ) ) {
						// Beaver Builder support.
						echo do_shortcode( sprintf( '[fl_builder_insert_layout id="%s"]', $hook_id ) );
					} elseif ( $this->is_gutenberg_active( $hook_id ) ) {
						if ( class_exists( '\UAGB_Init_Blocks' ) ) {
							$uagb = \UAGB_Init_Blocks::get_instance();
							add_action( 'enqueue_block_assets', array( $uagb, 'block_assets' ) );
						}

						// Gutenberg support.
						echo do_shortcode( do_blocks( get_post_field( 'post_content', $hook_id ) ) );
					} else {
						echo do_shortcode( get_post_field( 'post_content', $hook_id ) );
					}

					echo '</div>';

					/**
					 * Bring back our wrapper to WooCommerce product loop.
					 */
					// add_filter( 'wpbf_woo_product_loop_wrapper', '__return_true' );
				},
				absint( $priority )
			);

		} // End of $hooks foreach.

	}

	/**
	 * Check if current condition matches the display rules.
	 *
	 * @param int $hook_id The post ID.
	 *
	 * @return boolean Whether or not the current condition matches the display rules.
	 */
	public function matched_display_rules( $hook_id ) {

		$restrict_access = get_post_meta( $hook_id, '_wpbf_restrict_access', true );

		if ( empty( $restrict_access ) ) {
			// Run compatibility check.
			$restrict_access = get_post_meta( $hook_id, '_wpbf_restrict_logged_users', true );
			$restrict_access = 'true' === $restrict_access ? 'logged-in' : 'all';
		}

		// If only logged-in users are allowed, then restrict guest users.
		if ( 'logged-in' === $restrict_access && ! is_user_logged_in() ) {
			return false;
		}

		// If only guest users are allowed, then restrict logged-in users.
		if ( 'logged-out' === $restrict_access && is_user_logged_in() ) {
			return false;
		}

		$db_parent_rule = get_post_meta( $hook_id, '_wpbf_display_rule_parent', true );

		if ( empty( $db_parent_rule ) || ! is_array( $db_parent_rule ) ) {
			$db_parent_rule = array( 1 => 'entire_site' );
		}

		$db_exclusion_parent_rule = get_post_meta( $hook_id, '_wpbf_exclusion_display_rule_parent', true );

		if ( empty( $db_exclusion_parent_rule ) || ! is_array( $db_exclusion_parent_rule ) ) {
			$db_exclusion_parent_rule = array( 1 => '' );
		}

		$db_child_rule = get_post_meta( $hook_id, '_wpbf_display_rule_child', true );

		if ( empty( $db_child_rule ) || ! is_array( $db_child_rule ) ) {
			$db_child_rule = array();
		}

		$db_exclusion_child_rule = get_post_meta( $hook_id, '_wpbf_exclusion_display_rule_child', true );

		if ( empty( $db_exclusion_child_rule ) || ! is_array( $db_exclusion_child_rule ) ) {
			$db_exclusion_child_rule = array();
		}

		$post_id = is_singular() || is_front_page() ? get_queried_object_id() : 0;

		if ( ! $post_id ) {
			if ( 'page' === get_option( 'show_on_front' ) ) {
				$post_id = absint( get_option( 'page_for_posts' ) );
			}
		}

		$taxonomies = $this->get_filtered_taxonomies();

		foreach ( $db_exclusion_parent_rule as $exclusion_parent_rule_index => $rule ) {
			if ( 'entire_site' === $rule ) {
				return false;
			}

			if ( 'all_archive' === $rule ) {
				if ( is_archive() ) {
					return false;
				}
			}

			if ( 'author_archive' === $rule ) {
				if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
					if ( is_author() ) {
						return false;
					}
				} else {

					$author_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

					if ( is_author( $author_id ) ) {
						return false;
					}
				}
			}

			if ( 'date_archive' === $rule ) {
				if ( is_date() ) {
					return false;
				}
			}

			if ( 'blog_page' === $rule ) {
				if ( is_home() ) {
					return false;
				}
			}

			if ( 'search' === $rule && is_search() ) {
				return false;
			}

			if ( '404' === $rule ) {
				if ( is_404() ) {
					return false;
				}
			}

			if ( 'posts' === $rule ) {
				if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
					if ( is_singular( 'post' ) ) {
						return false;
					}
				} elseif ( absint( $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) === $post_id ) {
					return false;
				}
			}

			if ( 'post_category' === $rule ) {
				if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
					if ( is_category() ) {
						return false;
					}
				} else {

					$category_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

					if ( is_category( $category_id ) ) {
						return false;
					}
				}
			}

			if ( 'post_tag' === $rule ) {
				if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
					if ( is_tag() ) {
						return false;
					}
				} else {

					$tag_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

					if ( is_tag( $tag_id ) ) {
						return false;
					}
				}
			}

			if ( 'post_archive' === $rule ) {
				if ( is_archive() && ! is_post_type_archive() ) {
					return false;
				}
			}

			$post_types = $this->get_filtered_post_types();

			// Work on Easy Digital Downlaods.
			if ( class_exists( 'Easy_Digital_Downloads' ) ) {
				unset( $post_types['download'] );
				if ( 'download' === $rule ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_singular( 'download' ) ) {
							return false;
						}
					} elseif ( absint( $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) === $post_id ) {

							return false;
					}
				}

				if ( 'download_category' === $rule ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_tax( 'download_category' ) ) {
							return false;
						}
					} else {
						$download_category_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

						if ( is_tax( 'download_category', $download_category_id ) ) {
							return false;
						}
					}
				}

				if ( 'download_tag' === $rule ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_tax( 'download_tag' ) ) {
							return false;
						}
					} else {

						$download_tag_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

						if ( is_tax( 'download_tag', $download_tag_id ) ) {
							return false;
						}
					}
				}
			} // End of Easy Digital Downloads work.

			// Work on WooCommerce.
			if ( class_exists( 'WooCommerce' ) ) {
				unset( $post_types['product'] );
				if ( 'product' === $rule ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_singular( 'product' ) ) {
							return false;
						}
					} elseif ( absint( $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) === $post_id ) {
						return false;
					}
				}

				if ( 'shop' === $rule ) {
					if ( is_shop() ) {
						return false;
					}
				}

				if ( 'product_cat' === $rule ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_tax( 'product_cat' ) ) {
							return false;
						}
					} else {

						$product_cat_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

						if ( is_tax( 'product_cat', $product_cat_id ) ) {
							return false;
						}
					}
				}

				if ( 'product_tag' === $rule ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_tax( 'product_tag' ) ) {
							return false;
						}
					} else {

						$product_tag_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

						if ( is_tax( 'product_tag', $product_tag_id ) ) {
							return false;
						}
					}
				}
			} // End of WooCommerce work.

			if ( 'pages' === $rule ) {
				if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
					if ( is_page() ) {
						return false;
					}
				} elseif ( absint( $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) === $post_id ) {

						return false;
				}
			}

			foreach ( array_keys( $post_types ) as $post_type_key ) {
				if ( $rule === $post_type_key ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_singular( $post_type_key ) ) {
							return false;
						}
					} elseif ( absint( $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) === $post_id ) {
						return false;
					}
				}

				if ( $post_type_key . '_archive' === $rule ) {
					if ( is_post_type_archive( $post_type_key ) ) {
						return false;
					}
				}
			}

			foreach ( $taxonomies as $tax_name => $tax ) {
				if ( $tax_name === $rule ) {
					if ( 'all' === $db_exclusion_child_rule[ $exclusion_parent_rule_index ] ) {
						if ( is_tax( $tax_name ) ) {
							return false;
						}
					} else {

						$term_id = $db_exclusion_child_rule[ $exclusion_parent_rule_index ];

						if ( is_tax( $tax_name, $term_id ) ) {
							return false;
						}
					}
				}
			}
		}

		foreach ( $db_parent_rule as $parent_rule_loop_index => $rule ) {
			if ( 'entire_site' === $rule ) {
				return true;
			}

			if ( 'all_archive' === $rule ) {
				if ( is_archive() ) {
					return true;
				}
			}

			if ( 'author_archive' === $rule ) {
				if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
					if ( is_author() ) {
						return true;
					}
				} else {

					$author_id = $db_child_rule[ $parent_rule_loop_index ];

					if ( is_author( $author_id ) ) {
						return true;
					}
				}
			}

			if ( 'date_archive' === $rule ) {
				if ( is_date() ) {
					return true;
				}
			}

			if ( 'blog_page' === $rule ) {
				if ( is_home() ) {
					return true;
				}
			}

			if ( 'search' === $rule && is_search() ) {
				return true;
			}

			if ( '404' === $rule ) {
				if ( is_404() ) {
					return true;
				}
			}

			if ( 'posts' === $rule ) {
				if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
					if ( is_singular( 'post' ) ) {
						return true;
					}
				} elseif ( absint( $db_child_rule[ $parent_rule_loop_index ] ) === $post_id ) {
						return true;
				}
			}

			if ( 'post_category' === $rule ) {
				if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
					if ( is_category() ) {
						return true;
					}
				} else {
					$category_id = $db_child_rule[ $parent_rule_loop_index ];

					if ( is_category( $category_id ) ) {
						return true;
					}
				}
			}

			if ( 'post_tag' === $rule ) {
				if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
					if ( is_tag() ) {
						return true;
					}
				} else {
					$tag_id = $db_child_rule[ $parent_rule_loop_index ];

					if ( is_tag( $tag_id ) ) {
						return true;
					}
				}
			}

			if ( 'post_archive' === $rule ) {
				if ( is_archive() && ! is_post_type_archive() ) {
					return true;
				}
			}

			$post_types = $this->get_filtered_post_types();

			// Easy Digital Downloads work.
			if ( class_exists( 'Easy_Digital_Downloads' ) ) {
				unset( $post_types['download'] );
				if ( 'download' === $rule ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_singular( 'download' ) ) {
							return true;
						}
					} elseif ( absint( $db_child_rule[ $parent_rule_loop_index ] ) === $post_id ) {
							return true;
					}
				}

				if ( 'download_category' === $rule ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_tax( 'download_category' ) ) {
							return true;
						}
					} else {
						$download_category_id = $db_child_rule[ $parent_rule_loop_index ];

						if ( is_tax( 'download_category', $download_category_id ) ) {
							return true;
						}
					}
				}

				if ( 'download_tag' === $rule ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_tax( 'download_tag' ) ) {
							return true;
						}
					} else {

						$download_tag_id = $db_child_rule[ $parent_rule_loop_index ];

						if ( is_tax( 'download_tag', $download_tag_id ) ) {
							return true;
						}
					}
				}
			} // End of Easy Digital Downloads work.

			// WooCommerce work.
			if ( class_exists( 'WooCommerce' ) ) {
				unset( $post_types['product'] );
				if ( 'product' === $rule ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_singular( 'product' ) ) {
							return true;
						}
					} elseif ( absint( $db_child_rule[ $parent_rule_loop_index ] ) === $post_id ) {
						return true;
					}
				}

				if ( 'shop' === $rule ) {
					if ( is_shop() ) {
						return true;
					}
				}

				if ( 'product_cat' === $rule ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_tax( 'product_cat' ) ) {
							return true;
						}
					} else {

						$product_cat_id = $db_child_rule[ $parent_rule_loop_index ];

						if ( is_tax( 'product_cat', $product_cat_id ) ) {
							return true;
						}
					}
				}

				if ( 'product_tag' === $rule ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_tax( 'product_tag' ) ) {
							return true;
						}
					} else {

						$product_tag_id = $db_child_rule[ $parent_rule_loop_index ];

						if ( is_tax( 'product_tag', $product_tag_id ) ) {
							return true;
						}
					}
				}
			} // End of WooCommerce work.

			if ( 'pages' === $rule ) {
				if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
					if ( is_page() ) {
						return true;
					}
				} elseif ( absint( $db_child_rule[ $parent_rule_loop_index ] ) === $post_id ) {
					return true;
				}
			}

			foreach ( array_keys( $post_types ) as $post_type_key ) {
				if ( $rule === $post_type_key ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_singular( $post_type_key ) ) {
							return true;
						}
					} elseif ( absint( $db_child_rule[ $parent_rule_loop_index ] ) === $post_id ) {
						return true;
					}
				}

				if ( $post_type_key . '_archive' === $rule ) {
					if ( is_post_type_archive( $post_type_key ) ) {
						return true;
					}
				}
			}

			foreach ( $taxonomies as $tax_name => $tax ) {
				if ( $tax_name === $rule ) {
					if ( 'all' === $db_child_rule[ $parent_rule_loop_index ] ) {
						if ( is_tax( $tax_name ) ) {
							return true;
						}
					} else {

						$term_id = $db_child_rule[ $parent_rule_loop_index ];

						if ( is_tax( $tax_name, $term_id ) ) {
							return true;
						}
					}
				}
			}
		}

		return false;

	}

	/**
	 * Make sure our admin menu item is highlighted.
	 */
	public function fix_current_item() {

		global $parent_file, $submenu_file, $post_type;

		if ( 'wpbf_hooks' === $post_type ) {
			$parent_file  = 'themes.php';
			$submenu_file = 'edit.php?post_type=wpbf_hooks';
		}

	}

	/**
	 * Register custom post type.
	 */
	public function register_cpt() {

		$labels = array(
			'name'          => _x( 'Custom Sections', 'Post Type General Name', 'wpbfpremium' ),
			'singular_name' => _x( 'Custom Section', 'Post Type Singular Name', 'wpbfpremium' ),
			'menu_name'     => __( 'Custom Sections', 'wpbfpremium' ),
			'all_items'     => __( 'All Custom Sections', 'wpbfpremium' ),
			'add_new_item'  => __( 'Add New Custom Section', 'wpbfpremium' ),
			'new_item'      => __( 'New Custom Section', 'wpbfpremium' ),
			'edit_item'     => __( 'Edit Custom Section', 'wpbfpremium' ),
			'update_item'   => __( 'Update Custom Section', 'wpbfpremium' ),
			'search_items'  => __( 'Search Custom Sections', 'wpbfpremium' ),
		);

		$args = array(
			'labels'              => $labels,
			'supports'            => array( 'title', 'editor' ),
			'hierarchical'        => false,
			'public'              => true,
			'show_ui'             => true,
			'show_in_menu'        => false,
			'can_export'          => true,
			'has_archive'         => false,
			'exclude_from_search' => true,
			'show_in_rest'        => true,
		);

		register_post_type( 'wpbf_hooks', $args );

	}

	/**
	 * Register custom post type columns.
	 *
	 * @param array $columns The columns.
	 *
	 * @return array The updated columns.
	 */
	public function register_columns( $columns ) {

		$columns['wpbf_hook_action'] = esc_html__( 'Location', 'wpbfpremium' );

		$new_columns = array();

		foreach ( $columns as $column_key => $column_text ) {

			if ( 'date' === $column_key ) {
				$new_columns['wpbf_hook_action'] = esc_html__( 'Location', 'wpbfpremium' );
			}

			$new_columns[ $column_key ] = $column_text;

		}

		return $new_columns;

	}

	/**
	 * Add content to custom post type columns.
	 *
	 * @param string $column The column.
	 * @param string $post_id The post ID.
	 */
	public function add_columns( $column, $post_id ) {

		if ( 'wpbf_hook_action' === $column ) {

			$location = get_post_meta( $post_id, '_wpbf_hook_location', true );
			$action   = get_post_meta( $post_id, '_wpbf_hook_action', true );

			if ( 'hooks' !== $location ) {
				echo esc_html( ucfirst( $location ) );
			} else {
				echo esc_html( $action );
			}
		}

	}

	/**
	 * CPT update messages.
	 *
	 * @param array $messages The update messages.
	 *
	 * @return array The updated wpbf_hooks update messages.
	 */
	public function cpt_messages( $messages ) {

		$post = get_post();

		$messages['wpbf_hooks'] = array(
			0  => '', // Unused. Messages start at index 1.
			1  => __( 'Section updated.', 'wpbfpremium' ),
			2  => __( 'Custom field updated.' ),
			3  => __( 'Custom field deleted.' ),
			4  => __( 'Section updated.', 'wpbfpremium' ),
			5  => isset( $_GET['revision'] ) ? sprintf( __( 'Section restored to revision from %s', 'wpbfpremium' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
			6  => __( 'Section published.', 'wpbfpremium' ),
			7  => __( 'Section saved.', 'wpbfpremium' ),
			8  => __( 'Section submitted.', 'wpbfpremium' ),
			9  => sprintf(
				__( 'Section scheduled for: <strong>%1$s</strong>.', 'wpbfpremium' ),
				date_i18n( __( 'M j, Y @ G:i', 'wpbfpremium' ), strtotime( $post->post_date ) )
			),
			10 => __( 'Section draft updated.', 'wpbfpremium' ),
		);

		return $messages;

	}

	/**
	 * Add metaboxes.
	 */
	public function meta_box() {

		add_meta_box(
			'wpbf_hooks_location',
			__( 'Location', 'wpbfpremium' ),
			array( $this, 'metabox_callback' ),
			'wpbf_hooks'
		);

		add_meta_box(
			'wpbf_hooks_display_rules',
			__( 'Display Rules', 'wpbfpremium' ),
			array( $this, 'display_rules_metabox_callback' ),
			'wpbf_hooks'
		);

		add_meta_box(
			'wpbf_hooks_breakpoint_rules',
			__( 'Responsive', 'wpbfpremium' ),
			array( $this, 'breakpoint_rules_metabox_callback' ),
			'wpbf_hooks'
		);

		add_meta_box(
			'wpbf_hooks_user_access',
			__( 'User Access', 'wpbfpremium' ),
			array( $this, 'user_access_metabox_callback' ),
			'wpbf_hooks'
		);

		add_meta_box( 'wpbf_hook_sidebar_settings', __( 'Theme Hooks', 'wpbfpremium' ), array( $this, 'sidebar_metabox_callback' ), 'wpbf_hooks', 'side', 'default' );

	}

	/**
	 * The hooks list.
	 */
	public function hook_list() {

		return apply_filters(
			'wpbf_custom_section_hooks',
			array(
				__( 'General', 'wpbfpremium' )    => array(
					'wpbf_body_open',
					'wpbf_content_open',
					'wpbf_inner_content_open',
					'wpbf_main_content_open',
					'wpbf_before_page_title',
					'wpbf_after_page_title',
					'wpbf_entry_content_open',
					'wpbf_entry_content_close',
					'wpbf_main_content_close',
					'wpbf_inner_content_close',
					'wpbf_content_close',
					'wpbf_body_close',
				),
				__( 'Pre Header', 'wpbfpremium' ) => array(
					'wpbf_before_pre_header',
					'wpbf_pre_header_open',
					'wpbf_pre_header_left_open',
					'wpbf_pre_header_left_close',
					'wpbf_pre_header_right_open',
					'wpbf_pre_header_right_close',
					'wpbf_pre_header_close',
					'wpbf_after_pre_header',
				),
				__( 'Header', 'wpbfpremium' )     => array(
					'wpbf_before_header',
					'wpbf_header_open',
					'wpbf_header_close',
					'wpbf_after_header',
				),
				__( 'Navigation', 'wpbfpremium' ) => array(
					'wpbf_before_main_navigation',
					'wpbf_before_main_menu',
					'wpbf_main_menu_open',
					'wpbf_main_menu_close',
					'wpbf_after_main_menu',
					'wpbf_before_mobile_menu',
					'wpbf_mobile_menu_open',
					'wpbf_mobile_menu_close',
					'wpbf_after_mobile_menu',
					'wpbf_after_main_navigation',
					'wpbf_before_menu_toggle',
					'wpbf_after_menu_toggle',
					'wpbf_before_mobile_toggle',
					'wpbf_after_mobile_toggle',
				),
				__( 'Logo', 'wpbfpremium' )       => array(
					'wpbf_before_logo',
					'wpbf_after_logo',
					'wpbf_before_mobile_logo',
					'wpbf_after_mobile_logo',
				),
				__( 'Archives', 'wpbfpremium' )   => array(
					'wpbf_before_loop',
					'wpbf_after_loop',
				),
				__( 'Sidebar', 'wpbfpremium' )    => array(
					'wpbf_before_sidebar',
					'wpbf_sidebar_open',
					'wpbf_after_sidebar',
					'wpbf_sidebar_close',
				),
				__( 'Footer', 'wpbfpremium' )     => array(
					'wpbf_before_footer',
					'wpbf_footer_open',
					'wpbf_footer_close',
					'wpbf_after_footer',
				),
				__( 'Post Meta', 'wpbfpremium' )  => array(
					'wpbf_before_article_meta',
					'wpbf_article_meta_open',
					'wpbf_before_author_meta',
					'wpbf_after_author_meta',
					'wpbf_before_date_meta',
					'wpbf_after_date_meta',
					'wpbf_before_comments_meta',
					'wpbf_after_comments_meta',
					'wpbf_article_meta_close',
					'wpbf_after_article_meta',
				),
				__( 'Posts', 'wpbfpremium' )      => array(
					'wpbf_before_article',
					'wpbf_article_open',
					'wpbf_before_post_links',
					'wpbf_post_links',
					'wpbf_after_post_links',
					'wpbf_article_close',
					'wpbf_after_article',
				),
				__( 'Comments', 'wpbfpremium' )   => array(
					'wpbf_before_comments',
					'wpbf_before_comment_form',
					'wpbf_after_comment_form',
					'wpbf_after_comments',
				),
			)
		);

	}

	/**
	 * Display theme hooks.
	 */
	public function frontend_show_hooks() {

		if ( ! isset( $_GET['wpbf_hooks'] ) ) {
			return;
		}

		$actions = array_reduce(
			$this->hook_list(),
			function ( $carry, $item ) {
				$carry = array_merge( $carry, $item );

				return $carry;
			},
			array()
		);

		foreach ( $actions as $action ) {

			add_action(
				$action,
				function () use ( $action ) {
					echo '<div style="display: inline-block; font-family: Helvetica, Arial, sans-serif; padding: 8px; margin: 5px; line-height: 1; border-radius: 4px; font-size: 13px; font-weight: 700; color: #000; background: #f9e880;">' . esc_html( $action ) . '</div>';
				}
			);

		}

	}

	/**
	 * Theme hooks admin bar link.
	 *
	 * @param object $wp_admin_bar The wp admin bar object.
	 */
	public function display_hooks( $wp_admin_bar ) {

		if ( apply_filters( 'wpbf_disable_hooks_guide', false ) ) {
			return;
		}

		if ( ! current_user_can( 'edit_theme_options' ) || is_admin() ) {
			return;
		}

		global $wp;
		$current_url = home_url( add_query_arg( array(), $wp->request ) );

		if ( ! isset( $_GET['wpbf_hooks'] ) ) {

			$args = array(
				'id'    => 'wpbf-hooks',
				'title' => __( 'Display Theme Hooks', 'wpbfpremium' ),
				'href'  => trailingslashit( $current_url ) . '?wpbf_hooks',
				'meta'  => array(
					'target' => '_self',
					'class'  => 'wpbf-hooks-inactive',
					'title'  => __( 'Display Theme Hooks', 'wpbfpremium' ),
				),
			);

		} else {

			$args = array(
				'id'    => 'wpbf-hooks',
				'title' => __( 'Hide Theme Hooks', 'wpbfpremium' ),
				'href'  => trailingslashit( $current_url ),
				'meta'  => array(
					'target' => '_self',
					'class'  => 'wpbf-hooks-active',
					'title'  => __( 'Hide Theme Hooks', 'wpbfpremium' ),
				),
			);

		}

		$wp_admin_bar->add_node( $args );

	}

	/**
	 * The metabox callback.
	 *
	 * @param WP_Post $post The post object.
	 */
	public function metabox_callback( $post ) {

		wp_nonce_field( 'wpbf_hook_nonce', 'wpbf_hook_nonce' );

		$location = get_post_meta( $post->ID, '_wpbf_hook_location', true );
		$action   = get_post_meta( $post->ID, '_wpbf_hook_action', true );
		$priority = get_post_meta( $post->ID, '_wpbf_hook_priority', true );

		?>

		<table class="form-table wpbf-table">
			<tbody>
				<tr>
					<th class="wpbf-th">
						<label><?php esc_attr_e( 'Location', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">
						<select id="wpbf_hook_location" name="wpbf_hook_location">
							<option value="hooks" <?php selected( 'hooks', $location ); ?>>Hooks</option>
							<option value="header" <?php selected( 'header', $location ); ?>>Header</option>
							<option value="footer" <?php selected( 'footer', $location ); ?>>Footer</option>
							<option value="404" <?php selected( '404', $location ); ?>>404 Page</option>
						</select>
					</td>
				</tr>
				<tr id="hooks-tr">
					<th class="wpbf-th">
						<label><?php esc_attr_e( 'Hooks', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">
						<select name="wpbf_hook_action">
							<?php foreach ( $this->hook_list() as $optgroup => $hooks ) : ?>
								<optgroup label="<?php echo esc_attr( $optgroup ); ?>">
									<?php foreach ( $hooks as $hook ) : ?>
										<option value="<?php echo $hook; ?>" <?php selected( $hook, $action ); ?>><?php echo esc_html( $hook ); ?></option>
									<?php endforeach; ?>
								</optgroup>
							<?php endforeach; ?>
						</select>

						<?php if ( $this->supported_in_brizy_post_types() ) : ?>
							<p class="description">
								<?php _e( 'These hooks are not available on pages that have Brizy\'s "Blank Template" selected. Please switch to the "Default Template" instead.', 'wpbfpremium' ); ?>
							</p>
						<?php endif; ?>

					</td>
				</tr>
				<tr id="hooks-priority-tr">
					<th class="wpbf-th">
						<label><?php esc_attr_e( 'Priority', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">
						<input type="text" placeholder="10" name="wpbf_hook_priority" value="<?php echo esc_attr( $priority ); ?>">
					</td>
				</tr>
			</tbody>
		</table>

		<script>
			jQuery(document).on('ready', function () {
				var contextual_display = function () {
					jQuery('#hooks-tr, #hooks-priority-tr').hide();
					if (this.value === 'hooks') {
						jQuery('#hooks-tr, #hooks-priority-tr').show();
					}
				};
				jQuery('#wpbf_hook_location').change(contextual_display).change();
			})
		</script>

		<?php

	}

	/**
	 * Get posts.
	 *
	 * @param string $post_type The post type.
	 *
	 * @return array The post type array.
	 */
	public function get_posts( $post_type = 'post' ) {

		$posts = get_posts(
			array(
				'posts_per_page' => 1000,
				'post_type'      => $post_type,
			)
		);

		$all_label = sprintf( __( 'All %s', 'wpbfpremium' ), $this->get_post_types()[ $post_type ]['label'] );

		$posts = array_reduce(
			$posts,
			function ( $carry, $item ) {
				$carry[ $item->ID ] = $item->post_title;

				return $carry;
			},
			array( 'all' => $all_label )
		);

		return $posts;

	}

	/**
	 * Get public post types.
	 *
	 * @return array The public post types.
	 */
	public function get_post_types() {

		$post_types = get_post_types( array( 'public' => true ), 'objects' );

		return array_reduce(
			$post_types,
			function ( $carry, \WP_Post_Type $item ) {
				$carry[ $item->name ] = array(
					'label'         => $item->label,
					'singular_name' => $item->labels->singular_name,
				);

				return $carry;
			}
		);

	}

	/**
	 * Get public post types.
	 *
	 * @param  string $post_type_slug The post type slug.
	 * @return array The public taxonomies.
	 */
	public function get_taxonomies( $post_type_slug = '' ) {

		if ( $post_type_slug ) {
			$taxonomies = get_object_taxonomies( $post_type_slug, 'objects' );
		} else {
			$taxonomies = get_taxonomies( array( 'public' => true ), 'objects' );
		}

		if ( empty( $taxonomies ) ) {
			return array();
		} else {
			return array_reduce(
				$taxonomies,
				function ( $carry, \WP_Taxonomy $taxonomy ) {
					$carry[ $taxonomy->name ] = array(
						'label'         => $taxonomy->label,
						'singular_name' => $taxonomy->labels->singular_name,
					);

					return $carry;
				}
			);
		}

	}

	/**
	 * Get filtered taxonomies.
	 *
	 * @param  string $post_type_slug The post type slug.
	 * @return array The filtered taxonomies.
	 */
	public function get_filtered_taxonomies( $post_type_slug = '' ) {

		$taxonomies = $this->get_taxonomies( $post_type_slug );

		foreach ( $this->excluded_taxonomies as $tax_name ) {
			if ( isset( $taxonomies[ $tax_name ] ) ) {
				unset( $taxonomies[ $tax_name ] );
			}
		}

		return $taxonomies;

	}

	/**
	 * Get filtered post types.
	 *
	 * @return array The filtered post types.
	 */
	public function get_filtered_post_types() {

		$post_types = $this->get_post_types();

		// Remove un-used post types from being displayed in the inclusion & exclusion list.
		foreach ( $this->unused_post_types as $post_type ) {
			if ( isset( $post_types[ $post_type ] ) ) {
				unset( $post_types[ $post_type ] );
			}
		}

		// Remove static post types from dynamic handling, since we manage them manually.
		foreach ( $this->static_post_types as $post_type ) {
			// WooCommerce's "product" and EDD's "download" are not totally static.
			if ( 'product' !== $post_type && 'download' !== $post_type ) {
				if ( isset( $post_types[ $post_type ] ) ) {
					unset( $post_types[ $post_type ] );
				}
			}
		}

		return $post_types;

	}

	/**
	 * Display rule's js templates.
	 */
	public function display_rules_js_templates() {

		$post_types = $this->get_filtered_post_types();

		$post_categories = get_categories(
			array(
				'hide_empty' => false,
			)
		);

		$post_tags = get_tags(
			array(
				'hide_empty' => false,
			)
		);

		$display_rules = array(
			''        => __( 'Select...', 'wpbfpremium' ),
			'General' => array(
				'entire_site'    => __( 'Entire Site', 'wpbfpremium' ),
				'blog_page'      => __( 'Blog Page', 'wpbfpremium' ),
				'all_archive'    => __( 'All Archive', 'wpbfpremium' ),
				'author_archive' => __( 'Author Archive', 'wpbfpremium' ),
				'date_archive'   => __( 'Date Archive', 'wpbfpremium' ),
				'search'         => __( 'Search Results', 'wpbfpremium' ),
				'404'            => __( '404 Page', 'wpbfpremium' ),
			),
			'Page'    => array(
				'pages' => __( 'Pages', 'wpbfpremium' ),
			),
			'Post'    => array(
				'posts'         => __( 'Posts', 'wpbfpremium' ),
				'post_category' => __( 'Post Category', 'wpbfpremium' ),
				'post_tag'      => __( 'Post Tag', 'wpbfpremium' ),
				'post_archive'  => __( 'Post Archive', 'wpbfpremium' ),
			),
		);

		$old_post_types = $post_types;

		if ( class_exists( 'Easy_Digital_Downloads' ) ) {
			unset( $post_types['download'] );

			$display_rules['Download']['download']          = __( 'Downloads', 'wpbfpremium' );
			$display_rules['Download']['download_category'] = __( 'Downloads Category', 'wpbfpremium' );
			$display_rules['Download']['download_tag']      = __( 'Downloads Tag', 'wpbfpremium' );
		}

		if ( class_exists( 'WooCommerce' ) ) {
			unset( $post_types['product'] );

			$display_rules['Product']['product']     = __( 'Products', 'wpbfpremium' );
			$display_rules['Product']['shop']        = __( 'Shop Page', 'wpbfpremium' );
			$display_rules['Product']['product_cat'] = __( 'Product Category', 'wpbfpremium' );
			$display_rules['Product']['product_tag'] = __( 'Product Tag', 'wpbfpremium' );
		}

		foreach ( $post_types as $post_type_key => $post_type ) {
			$display_rules[ $post_type['singular_name'] ][ $post_type_key ]     = $post_type['label'];
			$display_rules[ $post_type['singular_name'] ]['handle_dynamically'] = true;
		}

		// Restore old post types value.
		$post_types = $old_post_types;

		$posts = $this->get_posts();

		$pages = $this->get_posts( 'page' );

		$authors = get_users( array( 'fields' => array( 'ID', 'user_login' ) ) );

		?>

		<script type="text/html" id="tmpl-display-rule-wrapper">
			<div class="rule-wrapper {{data.kind}}" data-index="{{data.index}}">
				<div class="parent-rule-select">
					{{{ data.parent_rule_tmp }}}
				</div>
				<div class="child-rule-select">
					{{{ data.child_rule_tmp }}}
				</div>
				<div class="rule-remove">
					<i class="remove-rule dashicons dashicons-no-alt"></i>
				</div>
			</div>
		</script>

		<!-- Start of parent's include-exclude -->
		<script type="text/html" id="tmpl-display-rule-parent">
			<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_parent' : 'wpbf_display_rule_parent'; #>
			<select class="{{data.kind}}" name="{{data.kind}}[{{data.index}}]">

				<?php foreach ( $display_rules as $rule_group_name => $location_list_or_text ) : ?>
					<?php if ( is_array( $location_list_or_text ) ) : ?>

						<?php
						$handle_dynamically = isset( $location_list_or_text['handle_dynamically'] ) && is_bool( $location_list_or_text['handle_dynamically'] ) ? $location_list_or_text['handle_dynamically'] : false;
						?>

						<optgroup label="<?php echo esc_attr( $rule_group_name ); ?>">
							<?php foreach ( $location_list_or_text as $location_key => $location_text ) : ?>

								<?php
								$should_fetch_taxonomies = false;

								if ( $handle_dynamically ) {
									$should_fetch_taxonomies = true;
								} elseif ( 'general' !== strtolower( $rule_group_name ) && ! in_array( strtolower( $rule_group_name ), $this->static_post_types, true ) ) {
									$should_fetch_taxonomies = true;
								}
								?>

								<option value="<?php echo $location_key; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo esc_attr( $location_key ); ?>') { #> selected <#}#>>
									<?php echo esc_html( $location_text ); ?>
								</option>

								<?php if ( $should_fetch_taxonomies ) : ?>

									<?php
									$taxonomies = $this->get_taxonomies( $location_key );
									?>

									<?php foreach ( $taxonomies as $tax_name => $tax ) : ?>

										<option value="<?php echo esc_attr( $tax_name ); ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo esc_attr( $tax_name ); ?>') { #> selected <#}#>>
											<?php echo esc_attr( $tax['label'] ); ?>
										</option>

									<?php endforeach; ?>

									<option value="<?php echo $location_key; ?>_archive" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $location_key; ?>_archive') { #> selected <#}#>>
										<?php echo esc_attr( $rule_group_name ); ?> <?php _e( 'Archive', 'wpbfpremium' ); ?>
									</option>

								<?php endif; ?>

							<?php endforeach; ?>
						</optgroup>

					<?php else : ?>

						<option value="<?php echo $rule_group_name; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $rule_group_name; ?>') { #> selected <#}#>>
							<?php echo esc_html( $location_list_or_text ); ?>
						</option>

					<?php endif; ?>
				<?php endforeach; ?>

			</select>
		</script>
		<!-- End of parent's include-exclude -->

		<script type="text/html" id="tmpl-display-rule-posts">
			<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
			<select name="{{data.kind}}[{{data.index}}]">
				<?php foreach ( $posts as $post_loop_index => $value ) : ?>
					<option value="<?php echo $post_loop_index; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $post_loop_index; ?>') { #> selected <#}#>><?php echo $value; ?></option>
				<?php endforeach; ?>
			</select>
		</script>

		<script type="text/html" id="tmpl-display-rule-post_category">
			<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
			<select name="{{data.kind}}[{{data.index}}]">
				<option value="all"
				<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All Post Categories', 'wpbfpremium' ); ?></option>
				<?php foreach ( $post_categories as $post_category ) : ?>
					<option value="<?php echo $post_category->term_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $post_category->term_id; ?>') { #> selected <#}#>><?php echo $post_category->name; ?></option>
				<?php endforeach; ?>
			</select>
		</script>

		<script type="text/html" id="tmpl-display-rule-post_tag">
			<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
			<select name="{{data.kind}}[{{data.index}}]">
				<option value="all"
				<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All Tags', 'wpbfpremium' ); ?></option>
				<?php foreach ( $post_tags as $post_tag ) : ?>
					<option value="<?php echo $post_tag->term_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $post_tag->term_id; ?>') { #> selected <#}#>><?php echo $post_tag->name; ?></option>
				<?php endforeach; ?>
			</select>
		</script>

		<script type="text/html" id="tmpl-display-rule-pages">
			<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
			<select name="{{data.kind}}[{{data.index}}]">
				<?php foreach ( $pages as $page_loop_index => $value ) : ?>
					<option value="<?php echo $page_loop_index; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $page_loop_index; ?>') { #> selected <#}#>><?php echo $value; ?></option>
				<?php endforeach; ?>
			</select>
		</script>

		<!-- Start of custom post type's posts -->
		<?php foreach ( array_keys( $post_types ) as $post_type_key ) { ?>
			<script type="text/html" id="tmpl-display-rule-<?php echo esc_attr( $post_type_key ); ?>">
				<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>

				<select name="{{data.kind}}[{{data.index}}]">
					<?php foreach ( $this->get_posts( $post_type_key ) as $post_id => $post_title ) : ?>

						<option value="<?php echo $post_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $post_id; ?>') { #> selected <#}#>><?php echo $post_title; ?></option>

					<?php endforeach; ?>
				</select>
			</script>
		<?php } ?>
		<!-- End of custom post type's posts -->

		<?php
		$taxonomies = $this->get_filtered_taxonomies();
		?>

		<!-- Start of custom post type's terms -->
		<?php foreach ( $taxonomies as $tax_name => $tax ) : ?>
			<script type="text/html" id="tmpl-display-rule-<?php echo esc_attr( $tax_name ); ?>">
				<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
				<select name="{{data.kind}}[{{data.index}}]">
					<?php
					$terms = get_terms(
						array(
							'taxonomy'   => $tax_name,
							'hide_empty' => false,
						)
					);
					?>

					<option value="all"
					<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All', 'wpbfpremium' ); ?> <?php echo esc_attr( $tax['label'] ); ?></option>

					<?php foreach ( $terms as $term ) : ?>
						<option value="<?php echo $term->term_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $term->term_id; ?>') { #> selected <#}#>><?php echo $term->name; ?></option>
					<?php endforeach; ?>
				</select>
			</script>
		<?php endforeach; ?>
		<!-- End of custom post type's terms -->

		<script type="text/html" id="tmpl-display-rule-author_archive">
			<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
			<select name="{{data.kind}}[{{data.index}}]">
				<option value="all"
				<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All Authors', 'wpbfpremium' ); ?></option>
				<?php foreach ( $authors as $author ) : ?>
					<option value="<?php echo $author->ID; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $author->ID; ?>') { #> selected <#}#>><?php echo $author->user_login; ?></option>
				<?php endforeach; ?>
			</select>
		</script>

		<?php

		if ( class_exists( 'Easy_Digital_Downloads' ) ) {

			$edd_categories = get_terms(
				array(
					'taxonomy'   => 'download_category',
					'hide_empty' => false,
				)
			);

			$edd_tags = get_terms(
				array(
					'taxonomy'   => 'download_tag',
					'hide_empty' => false,
				)
			);

			?>

			<script type="text/html" id="tmpl-display-rule-download_category">
				<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
				<select name="{{data.kind}}[{{data.index}}]">
					<option value="all"
					<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All Downloads Categories', 'wpbfpremium' ); ?></option>
					<?php foreach ( $edd_categories as $edd_category ) : ?>
						<option value="<?php echo $edd_category->term_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $edd_category->term_id; ?>') { #> selected <#}#>><?php echo $edd_category->name; ?></option>
					<?php endforeach; ?>
				</select>
			</script>
			<script type="text/html" id="tmpl-display-rule-download_tag">
				<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
				<select name="{{data.kind}}[{{data.index}}]">
					<option value="all"
					<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All Downloads Tags', 'wpbfpremium' ); ?></option>
					<?php foreach ( $edd_tags as $edd_tag ) : ?>
						<option value="<?php echo $edd_tag->term_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $edd_tag->term_id; ?>') { #> selected <#}#>><?php echo $edd_tag->name; ?></option>
					<?php endforeach; ?>
				</select>
			</script>

			<?php

		}

		if ( class_exists( 'WooCommerce' ) ) {

			$woo_categories = get_terms(
				array(
					'taxonomy'   => 'product_cat',
					'hide_empty' => false,
				)
			);

			$woo_tags = get_terms(
				array(
					'taxonomy'   => 'product_tag',
					'hide_empty' => false,
				)
			);

			?>

			<script type="text/html" id="tmpl-display-rule-product_cat">
				<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
				<select name="{{data.kind}}[{{data.index}}]">
					<option value="all"
					<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All Product Categories', 'wpbfpremium' ); ?></option>
					<?php foreach ( $woo_categories as $woo_category ) : ?>
						<option value="<?php echo $woo_category->term_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $woo_category->term_id; ?>') { #> selected <#}#>><?php echo $woo_category->name; ?></option>
					<?php endforeach; ?>
				</select>
			</script>

			<script type="text/html" id="tmpl-display-rule-product_tag">
				<# data.kind = typeof data.kind !=='undefined' && data.kind === 'exclusion' ? 'wpbf_exclusion_display_rule_child' : 'wpbf_display_rule_child'; #>
				<select name="{{data.kind}}[{{data.index}}]">
					<option value="all"
					<# if ( typeof data !== 'undefined' && data.saved_value == 'all') { #> selected <#}#>><?php _e( 'All Post Tags', 'wpbfpremium' ); ?></option>
					<?php foreach ( $woo_tags as $woo_tag ) : ?>
						<option value="<?php echo $woo_tag->term_id; ?>" <# if ( typeof data !== 'undefined' && data.saved_value == '<?php echo $woo_tag->term_id; ?>') { #> selected <#}#>><?php echo $woo_tag->name; ?></option>
					<?php endforeach; ?>
				</select>
			</script>

			<?php

		}

	}

	/**
	 * The display rule's script.
	 *
	 * @param int $post_id The post ID.
	 */
	public function display_rules_script( $post_id ) {

		$db_parent_rule = get_post_meta( $post_id, '_wpbf_display_rule_parent', true );
		if ( empty( $db_parent_rule ) || ! is_array( $db_parent_rule ) ) {
			$db_parent_rule = array( 1 => 'entire_site' );
		}

		$db_exclusion_parent_rule = get_post_meta( $post_id, '_wpbf_exclusion_display_rule_parent', true );
		if ( empty( $db_exclusion_parent_rule ) || ! is_array( $db_exclusion_parent_rule ) ) {
			$db_exclusion_parent_rule = array( 1 => '' );
		}

		$db_child_rule = get_post_meta( $post_id, '_wpbf_display_rule_child', true );
		if ( empty( $db_child_rule ) || ! is_array( $db_child_rule ) ) {
			$db_child_rule = array();
		}

		$db_exclusion_child_rule = get_post_meta( $post_id, '_wpbf_exclusion_display_rule_child', true );
		if ( empty( $db_exclusion_child_rule ) || ! is_array( $db_exclusion_child_rule ) ) {
			$db_exclusion_child_rule = array();
		}

		$dynamic_archives = '';

		foreach ( $this->dynamic_post_types as $post_type_key => $post_type ) {
			$dynamic_archives .= ", '" . $post_type_key . "_archive'";
		}

		$no_child_rules = "'entire_site', 'search', 'all_archive', 'date_archive', 'blog_page', '404', 'post_archive', 'shop'" . $dynamic_archives;
		?>

		<script type="text/javascript">

			(function ($) {

				var db_parent_rule = JSON.parse('<?php echo wp_json_encode( $db_parent_rule ); ?>');
				var db_child_rule = JSON.parse('<?php echo wp_json_encode( $db_child_rule ); ?>');

				var db_exclusion_parent_rule = JSON.parse('<?php echo wp_json_encode( $db_exclusion_parent_rule ); ?>');
				var db_exclusion_child_rule = JSON.parse('<?php echo wp_json_encode( $db_exclusion_child_rule ); ?>');

				var create_rule_field = function (index, kind, parent_rule_saved_value, child_rule_value_saved_value) {

					parent_rule_saved_value = parent_rule_saved_value || '';
					kind = kind || 'inclusion';
					child_rule_value_saved_value = child_rule_value_saved_value || '';

					var child_rule_tmp = '',
						get_child_rule_tmp,
						parent_rule_tmp = wp.template('display-rule-parent'),
						rule_wrapper = wp.template('display-rule-wrapper');

					if (parent_rule_saved_value !== '' && _.contains([<?php echo $no_child_rules; ?>], parent_rule_saved_value) === false) {

						get_child_rule_tmp = wp.template('display-rule-' + parent_rule_saved_value);

						child_rule_tmp = get_child_rule_tmp({
							saved_value: child_rule_value_saved_value,
							kind: kind,
							index: index
						});

					}

					$('.container-' + kind).append(rule_wrapper({

						parent_rule_tmp: parent_rule_tmp({
							saved_value: parent_rule_saved_value,
							index: index,
							kind: kind
						}),
						child_rule_tmp: child_rule_tmp,
						index: index,
						kind: kind

					}));

				};

				var repeater = function () {

					$('.add-include-rule').click(function (e) {
						e.preventDefault();
						var last_index = $('.rule-wrapper.inclusion').eq(-1).data('index');
						if (typeof last_index === 'undefined') {
							last_index = 0;
						}
						create_rule_field(last_index + 1);
					});

					$('.add-exclude-rule').click(function (e) {
						e.preventDefault();
						var last_index = $('.rule-wrapper.exclusion').eq(-1).data('index');
						if (typeof last_index === 'undefined') {
							last_index = 0;
						}
						create_rule_field(last_index + 1, 'exclusion');
					});

				};

				var remove_rule_listener = function () {

					$(document).on('click', '.remove-rule', function (e) {
						e.preventDefault();
						$(this).parents('.rule-wrapper').remove();
					});

				};

				var parent_rule_change_listener = function () {

					$(document).on('change', '.wpbf_display_rule_parent, .wpbf_exclusion_display_rule_parent', function (e) {

						var template,
							rule_wrapper_obj,
							index,
							kind = 'inclusion',
							select_display_rule = this.value;

						rule_wrapper_obj = $(this).parents('.rule-wrapper');
						index = rule_wrapper_obj.data('index');

						if (e.currentTarget.className == 'wpbf_exclusion_display_rule_parent') {
							kind = 'exclusion';
						}

						template = '';
						if (_.contains([<?php echo $no_child_rules; ?>], select_display_rule) === false) {
							template = wp.template('display-rule-' + select_display_rule)({index: index, kind: kind});
						}

						rule_wrapper_obj.find('.child-rule-select').html(template);

					})

				};

				var on_load = function () {

					// inclusion
					$.each(db_parent_rule, function (index, parent_rule_saved_value) {
						create_rule_field(index, 'inclusion', parent_rule_saved_value, db_child_rule[index]);
					});

					// exclusion
					$.each(db_exclusion_parent_rule, function (index, parent_rule_saved_value) {
						create_rule_field(index, 'exclusion', parent_rule_saved_value, db_exclusion_child_rule[index]);
					});

				};

				$(function () {
					on_load();
					parent_rule_change_listener();
					repeater();
					remove_rule_listener();
				});

			})(jQuery)

		</script>

		<?php

	}

	/**
	 * Breakpoint rules metabox callback.
	 *
	 * @param WP_Post $post The post object.
	 */
	public function breakpoint_rules_metabox_callback( $post ) {

		wp_nonce_field( 'wpbf_hook_nonce', 'wpbf_hook_nonce' );

		$hide_on_desktop = get_post_meta( $post->ID, '_wpbf_hide_on_desktop', true );
		$hide_on_tablet  = get_post_meta( $post->ID, '_wpbf_hide_on_tablet', true );
		$hide_on_mobile  = get_post_meta( $post->ID, '_wpbf_hide_on_mobile', true );
		?>

		<table class="form-table wpbf-table">
			<tbody>

				<tr>
					<th class="wpbf-th">
						<label for="wpbf_hide_on_desktop"><?php esc_attr_e( 'Hide on Desktop', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">

						<div class="wpbf-setting-field">
							<label for="wpbf_hide_on_desktop" class="label checkbox-label">
								<input type="checkbox" name="wpbf_hide_on_desktop" id="wpbf_hide_on_desktop" value="1" <?php checked( $hide_on_desktop, 1 ); ?>>
								<div class="indicator"></div>
							</label>
						</div>

					</td>
				</tr>

				<tr>
					<th class="wpbf-th">
						<label for="wpbf_hide_on_tablet"><?php esc_attr_e( 'Hide on Tablet', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">

						<div class="wpbf-setting-field">
							<label for="wpbf_hide_on_tablet" class="label checkbox-label">
								<input type="checkbox" name="wpbf_hide_on_tablet" id="wpbf_hide_on_tablet" value="1" <?php checked( $hide_on_tablet, 1 ); ?>>
								<div class="indicator"></div>
							</label>
						</div>

					</td>
				</tr>

				<tr>
					<th class="wpbf-th">
						<label for="wpbf_hide_on_mobile"><?php esc_attr_e( 'Hide on Mobile', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">

						<div class="wpbf-setting-field">
							<label for="wpbf_hide_on_mobile" class="label checkbox-label">
								<input type="checkbox" name="wpbf_hide_on_mobile" id="wpbf_hide_on_mobile" value="1" <?php checked( $hide_on_mobile, 1 ); ?>>
								<div class="indicator"></div>
							</label>
						</div>

					</td>
				</tr>

			</tbody>
		</table>

		<?php

	}

	/**
	 * Display rules metabox callback.
	 *
	 * @param WP_Post $post The post object.
	 */
	public function display_rules_metabox_callback( $post ) {

		wp_nonce_field( 'wpbf_hook_nonce', 'wpbf_hook_nonce' );

		?>

		<table class="form-table wpbf-table">
			<tbody>
				<tr>
					<th class="wpbf-th">
						<label><?php esc_attr_e( 'Include', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">
						<div class="container-inclusion">
						</div>
						<button class="button add-include-rule"><?php _e( 'Add Rule', 'wpbfpremium' ); ?></button>
					</td>
				</tr>
				<tr>
					<th class="wpbf-th">
						<label><?php esc_attr_e( 'Exclude', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">
						<div class="container-exclusion">
						</div>
						<button class="button add-exclude-rule"><?php _e( 'Add Rule', 'wpbfpremium' ); ?></button>
					</td>
				</tr>
			</tbody>
		</table>

		<?php
		$this->dynamic_post_types = $this->get_filtered_post_types();

		$this->display_rules_script( $post->ID );
		$this->display_rules_js_templates();

	}

	/**
	 * Logged-in metabox callback.
	 *
	 * @param WP_Post $post The post object.
	 */
	public function user_access_metabox_callback( $post ) {

		wp_nonce_field( 'wpbf_hook_nonce', 'wpbf_hook_nonce' );

		$db_value = get_post_meta( $post->ID, '_wpbf_restrict_access', true );

		if ( empty( $db_value ) ) {
			// Run compatibility check.
			$db_value = get_post_meta( $post->ID, '_wpbf_restrict_logged_users', true );
			$db_value = 'true' === $db_value ? 'logged-in' : 'all';
		}
		?>

		<table class="form-table wpbf-table">
			<tbody>
				<tr>
					<th class="wpbf-th">
						<label for="wpbf_restrict_access"><?php esc_attr_e( 'Show to', 'wpbfpremium' ); ?></label>
					</th>
					<td class="wpbf-td">
						<div class="wpbf-field is-half">
							<select id="wpbf_restrict_access" name="wpbf_restrict_access">
								<option value="all" <?php selected( 'all', $db_value ); ?>>
									<?php esc_html_e( 'All Users', 'wpbfpremium' ); ?>
								</option>
								<option value="logged-in" <?php selected( 'logged-in', $db_value ); ?>>
									<?php esc_html_e( 'Logged-in Users', 'wpbfpremium' ); ?>
								</option>
								<option value="logged-out" <?php selected( 'logged-out', $db_value ); ?>>
									<?php esc_html_e( 'Visitors', 'wpbfpremium' ); ?>
								</option>
							</select>
						</div>
					</td>
				</tr>
			</tbody>
		</table>

		<?php

	}

	/**
	 * Sidebar metabox callback.
	 *
	 * Display a link to display theme hooks in the sidebar.
	 */
	public function sidebar_metabox_callback() {

		?>

		<p class="description">
			<?php _e( 'Display available theme hooks on the frontend of your website.', 'wpbfpremium' ); ?>
		</p>
		<a style="margin-top: 1em" target="_blank" href="<?php echo home_url( '?wpbf_hooks' ); ?>" class="button button-primary button-large">
			<?php _e( 'Display Theme Hooks', 'wpbfpremium' ); ?>
		</a>

		<?php

	}

	/**
	 * Save metabox data.
	 *
	 * @param int $post_id The post ID.
	 */
	public function save_meta_box_data( $post_id ) {

		if ( ! isset( $_POST['wpbf_hook_nonce'] ) ) {
			return;
		}

		if ( ! wp_verify_nonce( $_POST['wpbf_hook_nonce'], 'wpbf_hook_nonce' ) ) {
			return;
		}

		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}

		$this->save_hooks_metadata( $post_id );
		$this->save_breakpoint_rules( $post_id );
		$this->save_display_rules( $post_id );

		$restrict_access = sanitize_text_field( wp_unslash( $_POST['wpbf_restrict_access'] ) );

		update_post_meta( $post_id, '_wpbf_restrict_access', $restrict_access );

	}

	/**
	 * Save hook's meta data.
	 *
	 * @param int $post_id The post ID.
	 */
	public function save_hooks_metadata( $post_id ) {

		update_post_meta( $post_id, '_wpbf_hook_location', sanitize_text_field( $_POST['wpbf_hook_location'] ) );

		if ( ! isset( $_POST['wpbf_hook_action'] ) ) {
			return;
		}

		$action   = sanitize_text_field( wp_unslash( $_POST['wpbf_hook_action'] ) );
		$priority = sanitize_text_field( wp_unslash( $_POST['wpbf_hook_priority'] ) );

		update_post_meta( $post_id, '_wpbf_hook_action', $action );
		update_post_meta( $post_id, '_wpbf_hook_priority', $priority );

	}

	/**
	 * Save breakpoint rules.
	 *
	 * @param int $post_id The post ID.
	 */
	public function save_breakpoint_rules( $post_id ) {

		if ( isset( $_POST['wpbf_hide_on_desktop'] ) ) {
			update_post_meta( $post_id, '_wpbf_hide_on_desktop', 1 );
		} else {
			delete_post_meta( $post_id, '_wpbf_hide_on_desktop' );
		}

		if ( isset( $_POST['wpbf_hide_on_tablet'] ) ) {
			update_post_meta( $post_id, '_wpbf_hide_on_tablet', 1 );
		} else {
			delete_post_meta( $post_id, '_wpbf_hide_on_tablet' );
		}

		if ( isset( $_POST['wpbf_hide_on_mobile'] ) ) {
			update_post_meta( $post_id, '_wpbf_hide_on_mobile', 1 );
		} else {
			delete_post_meta( $post_id, '_wpbf_hide_on_mobile' );
		}

	}

	/**
	 * Save display rules metadata.
	 *
	 * @param int $post_id The post ID.
	 */
	public function save_display_rules( $post_id ) {

		$display_rule_parent = isset( $_POST['wpbf_display_rule_parent'] ) ? array_map( 'sanitize_text_field', $_POST['wpbf_display_rule_parent'] ) : array();
		$display_rule_child  = '';

		if ( isset( $_POST['wpbf_display_rule_child'] ) ) {
			$display_rule_child = array_map( 'sanitize_text_field', $_POST['wpbf_display_rule_child'] );
		}

		$exclusion_display_rule_parent = isset( $_POST['wpbf_exclusion_display_rule_parent'] ) ? array_map( 'sanitize_text_field', $_POST['wpbf_exclusion_display_rule_parent'] ) : array();
		$exclusion_display_rule_child  = '';

		if ( isset( $_POST['wpbf_exclusion_display_rule_child'] ) ) {
			$exclusion_display_rule_child = array_map( 'sanitize_text_field', $_POST['wpbf_exclusion_display_rule_child'] );
		}

		update_post_meta( $post_id, '_wpbf_display_rule_parent', $display_rule_parent );
		update_post_meta( $post_id, '_wpbf_display_rule_child', $display_rule_child );

		update_post_meta( $post_id, '_wpbf_exclusion_display_rule_parent', $exclusion_display_rule_parent );
		update_post_meta( $post_id, '_wpbf_exclusion_display_rule_child', $exclusion_display_rule_child );

	}

	/**
	 * Create our admin menu item.
	 */
	public function menu_item() {

		add_submenu_page(
			'themes.php',
			esc_html__( 'Custom Sections', 'wpbfpremium' ),
			esc_html__( 'Custom Sections', 'wpbfpremium' ),
			apply_filters( 'wpbf_custom_sections_capability', 'manage_options' ),
			'edit.php?post_type=wpbf_hooks'
		);

	}

	/**
	 * Get instance of this class.
	 *
	 * @return object The current class instance.
	 */
	public static function get_instance() {

		static $instance = null;

		if ( is_null( $instance ) ) {
			$instance = new self();
		}

		return $instance;
	}

	/**
	 * Redirect unallowed users.
	 */
	public function cpt_redirect() {

		if ( is_singular( 'wpbf_hooks' ) && ! current_user_can( 'edit_posts' ) ) {
			wp_safe_redirect( site_url(), 301 );
			die;
		}

	}

}
Custom_Sections::get_instance();
© 2026 GrazzMean