--- a/happy-elementor-addons/classes/clone-handler.php
+++ b/happy-elementor-addons/classes/clone-handler.php
@@ -7,234 +7,237 @@
class Clone_Handler {
- /**
- * Request and nonce action name
- */
- const ACTION = 'ha_duplicate_thing';
-
- /**
- * Check if current user can clone
- *
- * @return bool
- */
- public static function can_clone() {
- return current_user_can( 'edit_posts' );
- }
-
- /**
- * Check if current user and post author are same
- *
- * @param int $post_id
- * @return boolean
- */
- public static function is_the_same_author($post_id) {
- $author_id = get_post_field( 'post_author', $post_id );
- return ( get_current_user_id() == $author_id );
- }
-
- /**
- * Add clone link in row actions
- *
- * @param array $actions
- * @param WP_Post $post
- * @return array
- */
- public static function add_row_actions( $actions, $post ) {
- if ( current_user_can( 'edit_post', $post->ID ) && post_type_supports( $post->post_type, 'elementor' ) ) {
- $actions[ self::ACTION ] = sprintf(
- '<a href="%1$s" title="%2$s"><span class="screen-reader-text">%2$s</span>%3$s</a>',
- esc_url( self::get_url( $post->ID, 'list' ) ),
- sprintf( esc_attr__( 'Clone - %s', 'happy-elementor-addons' ), esc_attr( $post->post_title ) ),
- esc_html__( 'Happy Clone', 'happy-elementor-addons' )
- );
- }
-
- return $actions;
- }
-
- /**
- * Duplicate requested post
- *
- * @return void
- */
- public static function duplicate_thing() {
- if ( ! self::can_clone() ) {
- return;
- }
-
- $_uri = $_SERVER['REQUEST_URI'];
-
- // Resolve finder clone request issue
- if ( stripos( $_uri, '&' ) !== false ) {
- $_uri = html_entity_decode( $_uri );
- $_uri = parse_url( $_uri, PHP_URL_QUERY );
- $valid_args = ['_wpnonce', 'post_id', 'ref'];
- parse_str( $_uri, $args );
-
- if ( ! empty( $args ) && is_array( $args ) ) {
- foreach ( $args as $key => $val ) {
- if ( in_array( $key, $valid_args, true ) ) {
- $_GET[ $key ] = $val;
- }
- }
- }
- }
-
- $nonce = isset( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : '';
- $post_id = isset( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0;
- $ref = isset( $_GET['ref'] ) ? sanitize_text_field($_GET['ref']) : '';
-
- if ( ! wp_verify_nonce( $nonce, self::ACTION ) ) {
- return;
- }
-
- $post_status = get_post_status ( $post_id );
- $same_author = self::is_the_same_author( $post_id );
-
- if ( ('private' == $post_status || 'draft' == $post_status) && ! $same_author ) {
- wp_die( __( 'Sorry, you are not allowed to clone this item.' ) );
- }
-
- if ( post_password_required( $post_id ) && ! $same_author ) {
- wp_die( __( 'Sorry, you are not allowed to clone this item.' ) );
- }
-
- if ( is_null( ( $post = get_post( $post_id ) ) ) ) {
- return;
- }
-
- $post = sanitize_post( $post, 'db' );
- $duplicated_post_id = self::duplicate_post( $post );
- $redirect = add_query_arg( [ 'post_type' => $post->post_type ], admin_url( 'edit.php' ) );
-
- if ( ! is_wp_error( $duplicated_post_id ) ) {
- self::duplicate_taxonomies( $post, $duplicated_post_id );
- self::duplicate_meta_entries( $post, $duplicated_post_id );
-
- $css = Post_CSS::create( $duplicated_post_id );
- $css->update();
-
- if ( $ref === 'editor' ) {
- $document = ha_elementor()->documents->get( $duplicated_post_id );
- $redirect = $document->get_edit_url();
- }
- }
-
- wp_safe_redirect( $redirect );
- die();
- }
-
- /**
- * Get clone url with required query params
- *
- * @param $post_id
- * @param string $ref
- * @return string
- */
- public static function get_url( $post_id, $ref = '' ) {
- return wp_nonce_url(
- add_query_arg(
- [
- 'action' => self::ACTION,
- 'post_id' => $post_id,
- 'ref' => $ref,
- ],
- admin_url( 'admin.php' )
- ),
- self::ACTION
- );
- }
-
- /**
- * Clone post
- *
- * @param $old_post
- * @return int $dulicated post id
- */
- protected static function duplicate_post( $post ) {
- $current_user = wp_get_current_user();
-
- $duplicated_post_args = [
- 'post_status' => 'draft',
- 'to_ping' => $post->to_ping,
- 'post_type' => $post->post_type,
- 'menu_order' => $post->menu_order,
- 'post_author' => $current_user->ID,
- 'post_parent' => $post->post_parent,
- 'ping_status' => $post->ping_status,
- 'post_excerpt' => $post->post_excerpt,
- 'post_content' => $post->post_content,
- 'post_password' => $post->post_password,
- 'comment_status' => $post->comment_status,
- 'post_title' => sprintf( __( '%s - [Cloned #%d]', 'happy-elementor-addons' ), $post->post_title,
- $post->ID ),
- ];
-
- return wp_insert_post( $duplicated_post_args );
- }
-
- /**
- * Copy post taxonomies to cloned post
- *
- * @param $post
- * @param $duplicated_post_id
- */
- protected static function duplicate_taxonomies( $post, $duplicated_post_id ) {
- $taxonomies = get_object_taxonomies( $post->post_type );
- if ( ! empty( $taxonomies ) && is_array( $taxonomies ) ) {
- foreach ( $taxonomies as $taxonomy ) {
- $terms = wp_get_object_terms( $post->ID, $taxonomy, [ 'fields' => 'slugs' ] );
- wp_set_object_terms( $duplicated_post_id, $terms, $taxonomy, false );
- }
- }
- }
-
- /**
- * Copy post meta entries to cloned post
- *
- * @param $post
- * @param $duplicated_post_id
- */
- protected static function duplicate_meta_entries( $post, $duplicated_post_id ) {
- global $wpdb;
-
- $entries = $wpdb->get_results(
- $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $post->ID )
- );
-
- if ( is_array( $entries ) ) {
- // $query = "INSERT INTO {$wpdb->postmeta} ( post_id, meta_key, meta_value ) VALUES ";
- // $_records = [];
- // foreach ( $entries as $entry ) {
- // $_value = wp_slash( $entry->meta_value );
- // $_records[] = "( $duplicated_post_id, '{$entry->meta_key}', '{$_value}' )";
- // }
- // $query .= implode( ', ', $_records ) . ';';
- // $wpdb->query( $query );
-
- foreach ( $entries as $entry ) {
- $wpdb->insert(
- $wpdb->postmeta,
- [
- 'post_id' => $duplicated_post_id,
- 'meta_key' => $entry->meta_key,
- 'meta_value' => $entry->meta_value,
- ],
- [ '%d', '%s', '%s' ]
- );
- }
-
- // foreach ( $entries as $entry ) {
- // update_post_meta( $duplicated_post_id, $entry->meta_key, $entry->meta_value );
- // }
-
-
-
- // Fix Template Type Wrong issue
- $source_type = get_post_meta($post->ID, '_elementor_template_type', true);
- delete_post_meta($duplicated_post_id, '_elementor_template_type');
- update_post_meta($duplicated_post_id, '_elementor_template_type', $source_type);
- }
- }
+ /**
+ * Request and nonce action name
+ */
+ const ACTION = 'ha_duplicate_thing';
+
+ /**
+ * Check if current user can clone
+ *
+ * @return bool
+ */
+ public static function can_clone() {
+ return current_user_can( 'edit_posts' );
+ }
+
+ /**
+ * Check if current user and post author are same
+ *
+ * @param int $post_id
+ * @return boolean
+ */
+ public static function is_the_same_author( $post_id ) {
+ $author_id = get_post_field( 'post_author', $post_id );
+
+ return ( get_current_user_id() == $author_id );
+ }
+
+ /**
+ * Add clone link in row actions
+ *
+ * @param array $actions
+ * @param WP_Post $post
+ * @return array
+ */
+ public static function add_row_actions( $actions, $post ) {
+ if ( current_user_can( 'edit_post', $post->ID ) && post_type_supports( $post->post_type, 'elementor' ) ) {
+ $actions[self::ACTION] = sprintf(
+ '<a href="%1$s" title="%2$s"><span class="screen-reader-text">%2$s</span>%3$s</a>',
+ esc_url( self::get_url( $post->ID, 'list' ) ),
+ sprintf( esc_attr__( 'Clone - %s', 'happy-elementor-addons' ), esc_attr( $post->post_title ) ),
+ esc_html__( 'Happy Clone', 'happy-elementor-addons' )
+ );
+ }
+
+ return $actions;
+ }
+
+ /**
+ * Duplicate requested post
+ *
+ * @return void
+ */
+ public static function duplicate_thing() {
+ if ( !self::can_clone() ) {
+ return;
+ }
+
+ $_uri = $_SERVER['REQUEST_URI'];
+
+ // Resolve finder clone request issue
+ if ( stripos( $_uri, '&' ) !== false ) {
+ $_uri = html_entity_decode( $_uri );
+ $_uri = parse_url( $_uri, PHP_URL_QUERY );
+ $valid_args = ['_wpnonce', 'post_id', 'ref'];
+ parse_str( $_uri, $args );
+
+ if ( !empty( $args ) && is_array( $args ) ) {
+ foreach ( $args as $key => $val ) {
+ if ( in_array( $key, $valid_args, true ) ) {
+ $_GET[$key] = $val;
+ }
+ }
+ }
+ }
+
+ $nonce = isset( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : '';
+ $post_id = isset( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0;
+ $ref = isset( $_GET['ref'] ) ? sanitize_text_field( $_GET['ref'] ) : '';
+
+ if ( !$post_id || !get_post( $post_id ) ) {
+ wp_die( __( 'Invalid post.' ) );
+ }
+
+ if ( !current_user_can( 'edit_post', $post_id ) ) {
+ wp_die( __( 'Sorry, you are not allowed to clone this item.' ) );
+ }
+
+ $post_status = get_post_status( $post_id );
+ $same_author = self::is_the_same_author( $post_id );
+
+ if ( ( 'private' == $post_status || 'draft' == $post_status ) && !$same_author ) {
+ wp_die( __( 'Sorry, you are not allowed to clone this item.' ) );
+ }
+
+ if ( post_password_required( $post_id ) && !$same_author ) {
+ wp_die( __( 'Sorry, you are not allowed to clone this item.' ) );
+ }
+
+ if ( null === ( ( $post = get_post( $post_id ) ) ) ) {
+ return;
+ }
+
+ $post = sanitize_post( $post, 'db' );
+ $duplicated_post_id = self::duplicate_post( $post );
+ $redirect = add_query_arg( ['post_type' => $post->post_type], admin_url( 'edit.php' ) );
+
+ if ( !is_wp_error( $duplicated_post_id ) ) {
+ self::duplicate_taxonomies( $post, $duplicated_post_id );
+ self::duplicate_meta_entries( $post, $duplicated_post_id );
+
+ $css = Post_CSS::create( $duplicated_post_id );
+ $css->update();
+
+ if ( $ref === 'editor' ) {
+ $document = ha_elementor()->documents->get( $duplicated_post_id );
+ $redirect = $document->get_edit_url();
+ }
+ }
+
+ wp_safe_redirect( $redirect );
+ die();
+ }
+
+ /**
+ * Get clone url with required query params
+ *
+ * @param $post_id
+ * @param string $ref
+ * @return string
+ */
+ public static function get_url( $post_id, $ref = '' ) {
+ return wp_nonce_url(
+ add_query_arg(
+ [
+ 'action' => self::ACTION,
+ 'post_id' => $post_id,
+ 'ref' => $ref
+ ],
+ admin_url( 'admin.php' )
+ ),
+ self::ACTION
+ );
+ }
+
+ /**
+ * Clone post
+ *
+ * @param $old_post
+ * @return int $dulicated post id
+ */
+ protected static function duplicate_post( $post ) {
+ $current_user = wp_get_current_user();
+
+ $duplicated_post_args = [
+ 'post_status' => 'draft',
+ 'to_ping' => $post->to_ping,
+ 'post_type' => $post->post_type,
+ 'menu_order' => $post->menu_order,
+ 'post_author' => $current_user->ID,
+ 'post_parent' => $post->post_parent,
+ 'ping_status' => $post->ping_status,
+ 'post_excerpt' => $post->post_excerpt,
+ 'post_content' => $post->post_content,
+ 'post_password' => $post->post_password,
+ 'comment_status' => $post->comment_status,
+ 'post_title' => sprintf( __( '%s - [Cloned #%d]', 'happy-elementor-addons' ), $post->post_title,
+ $post->ID )
+ ];
+
+ return wp_insert_post( $duplicated_post_args );
+ }
+
+ /**
+ * Copy post taxonomies to cloned post
+ *
+ * @param $post
+ * @param $duplicated_post_id
+ */
+ protected static function duplicate_taxonomies( $post, $duplicated_post_id ) {
+ $taxonomies = get_object_taxonomies( $post->post_type );
+ if ( !empty( $taxonomies ) && is_array( $taxonomies ) ) {
+ foreach ( $taxonomies as $taxonomy ) {
+ $terms = wp_get_object_terms( $post->ID, $taxonomy, ['fields' => 'slugs'] );
+ wp_set_object_terms( $duplicated_post_id, $terms, $taxonomy, false );
+ }
+ }
+ }
+
+ /**
+ * Copy post meta entries to cloned post
+ *
+ * @param $post
+ * @param $duplicated_post_id
+ */
+ protected static function duplicate_meta_entries( $post, $duplicated_post_id ) {
+ global $wpdb;
+
+ $entries = $wpdb->get_results(
+ $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $post->ID )
+ );
+
+ if ( is_array( $entries ) ) {
+ // $query = "INSERT INTO {$wpdb->postmeta} ( post_id, meta_key, meta_value ) VALUES ";
+ // $_records = [];
+ // foreach ( $entries as $entry ) {
+ // $_value = wp_slash( $entry->meta_value );
+ // $_records[] = "( $duplicated_post_id, '{$entry->meta_key}', '{$_value}' )";
+ // }
+ // $query .= implode( ', ', $_records ) . ';';
+ // $wpdb->query( $query );
+
+ foreach ( $entries as $entry ) {
+ $wpdb->insert(
+ $wpdb->postmeta,
+ [
+ 'post_id' => $duplicated_post_id,
+ 'meta_key' => $entry->meta_key,
+ 'meta_value' => $entry->meta_value
+ ],
+ ['%d', '%s', '%s']
+ );
+ }
+
+ // foreach ( $entries as $entry ) {
+ // update_post_meta( $duplicated_post_id, $entry->meta_key, $entry->meta_value );
+ // }
+
+ // Fix Template Type Wrong issue
+ $source_type = get_post_meta( $post->ID, '_elementor_template_type', true );
+ delete_post_meta( $duplicated_post_id, '_elementor_template_type' );
+ update_post_meta( $duplicated_post_id, '_elementor_template_type', $source_type );
+ }
+ }
}
--- a/happy-elementor-addons/classes/condition-manager.php
+++ b/happy-elementor-addons/classes/condition-manager.php
@@ -101,8 +101,6 @@
return apply_filters('happyaddons/conditions/archive', $conditions);
}
-
-
private function singular_conditions() {
$conditions = [
'all' => [
@@ -226,7 +224,55 @@
return $keys;
}
- protected function validate_reqeust() {
+
+ /**
+ * Validate a general AJAX request that does NOT operate on a specific template.
+ *
+ * This method verifies:
+ * - The request nonce for CSRF protection.
+ * - The current user's capability to access the editor context.
+ *
+ * Intended for endpoints that return global/shared data
+ * (e.g., condition autocomplete results) and do not require
+ * object-level authorization.
+ *
+ * @version 1.0.0
+ *
+ * @throws Exception If the nonce is invalid or the user lacks permission.
+ * @return void
+ */
+ protected function validate_general_request() {
+
+ $nonce = $_REQUEST['nonce'] ?? '';
+
+ if ( !wp_verify_nonce( $nonce, 'ha_editor_nonce' ) ) {
+ throw new Exception( 'Invalid request' );
+ }
+
+ if ( !current_user_can( 'edit_posts' ) ) {
+ throw new Exception( 'Unauthorized request' );
+ }
+ }
+
+ /**
+ * Validate a template-specific AJAX request.
+ *
+ * This method performs full object-level authorization and ensures:
+ * - The request nonce is valid (CSRF protection).
+ * - A valid template ID is provided.
+ * - The template exists and belongs to the expected post type.
+ * - The current user has permission to edit the specific template
+ * via WordPress meta capability mapping (edit_post).
+ *
+ * This protects against IDOR (Insecure Direct Object Reference)
+ * and unauthorized access to template data.
+ *
+ * @version 1.0.1
+ *
+ * @throws Exception If validation fails at any step.
+ * @return void
+ */
+ protected function validate_template_request() {
$nonce = !empty($_REQUEST['nonce']) ? $_REQUEST['nonce'] : '';
$template_id = isset( $_REQUEST['template_id'] ) ? absint( $_REQUEST['template_id'] ) : null;
@@ -234,7 +280,7 @@
throw new Exception('Invalid request');
}
- if (!current_user_can('edit_posts', $template_id)) {
+ if (!current_user_can('edit_post', $template_id)) {
throw new Exception('Unauthorized request');
}
@@ -252,7 +298,7 @@
public function ha_get_template_type() {
try {
- //$this->validate_reqeust();
+ //$this->validate_template_request();
$id = isset($_REQUEST['post_id']) ? absint($_REQUEST['post_id']) : null;
if ($id) {
$tpl_type = get_post_meta($id, '_ha_library_type', true);
@@ -269,7 +315,7 @@
// update template conditions
public function process_condition_update() {
try {
- $this->validate_reqeust();
+ $this->validate_template_request();
$templateID = isset($_REQUEST['template_id']) ? absint($_REQUEST['template_id']) : null;
$requestConditions = isset($_REQUEST['conds']) ? ha_sanitize_array_recursively($_REQUEST['conds']) : [];
@@ -359,7 +405,7 @@
public function process_condition_update_old() {
try {
- $this->validate_reqeust();
+ $this->validate_template_request();
$templateID = isset($_REQUEST['template_id']) ? $_REQUEST['template_id'] : null;
$conditions = isset($_REQUEST['conds']) ? $_REQUEST['conds'] : [];
@@ -454,7 +500,7 @@
public function ha_get_current_condition() {
try {
- // $this->validate_reqeust();
+ $this->validate_template_request();
$templateID = isset($_REQUEST['template_id']) ? absint($_REQUEST['template_id']) : null;
// wp_send_json_success($templateID);
if ($templateID) {
@@ -486,9 +532,9 @@
$sub_name = $parsed_condition['sub_name'];
$sub_id = $parsed_condition['sub_id'];
- $sub_name_html = ($sub_name) ? '<option value="' . $sub_name . '" selected="selected">' . $this->all_conds_list[$sub_name]['title'] . '</option>' : '';
+ $sub_name_html = ($sub_name) ? '<option value="' . esc_attr($sub_name) . '" selected="selected">' . esc_html($this->all_conds_list[$sub_name]['title']) . '</option>' : '';
- $sub_id_html = ($sub_id) ? '<option value="' . $sub_id . '" selected="selected">' . get_the_title($sub_id) . '</option>' : '';
+ $sub_id_html = ($sub_id) ? '<option value="' . esc_attr($sub_id) . '" selected="selected">' . esc_html(get_the_title($sub_id)) . '</option>' : '';
$uuid = uniqid();
$if = function ($condition, $true, $false) {
@@ -517,12 +563,12 @@
</select>
</div>
<div class="ha-tce-sub_name" $sub_name_visibility>
- <select data-id="sub_name-$uuid" data-parent="$uuid" data-setting="sub_name" data-selected="$sub_name">
+ <select data-id="sub_name-$uuid" data-parent="$uuid" data-setting="sub_name" data-selected="esc_attr($sub_name)">
$sub_name_html
</select>
</div>
<div class="ha-tce-sub_id" $sub_id_visibility>
- <select data-id="sub_id-$uuid" data-parent="$uuid" data-setting="sub_id" data-selected="$sub_id">
+ <select data-id="sub_id-$uuid" data-parent="$uuid" data-setting="sub_id" data-selected="esc_attr($sub_id)">
$sub_id_html
</select>
</div>
@@ -539,7 +585,7 @@
public function process_autocomplete() {
try {
- $this->validate_reqeust();
+ $this->validate_general_request();
$object_type = !empty($_REQUEST['object_type']) ? trim(sanitize_text_field($_REQUEST['object_type'])) : '';
--- a/happy-elementor-addons/classes/theme-builder.php
+++ b/happy-elementor-addons/classes/theme-builder.php
@@ -1,204 +1,205 @@
<?php
- namespace Happy_AddonsElementorClasses;
+ namespace Happy_AddonsElementorClasses;
- defined( 'ABSPATH' ) || die();
+ defined( 'ABSPATH' ) || die();
- use Happy_AddonsElementorClassesConditions_Cache;
+ use Happy_AddonsElementorClassesConditions_Cache;
- class Theme_Builder {
- public static $instance = null;
+ class Theme_Builder {
+ public static $instance = null;
- protected $templates;
- protected $current_theme;
- protected $current_template;
- protected $current_location;
-
- private $cache;
- private $location_cache;
-
- const CPT = 'ha_library';
- const TAB_BASE = 'edit.php?post_type=ha_library';
-
- public $header_template;
- public $footer_template;
- public $singular_template;
-
- public function __construct() {
- add_action( 'wp', [ $this, 'hooks' ] );
- // $this->cache = new Conditions_Cache();
- $this->cache = Conditions_Cache::instance();
-
- add_filter( 'query_vars', [$this, 'add_query_vars_filter'] );
- add_filter( 'views_edit-' . self::CPT, [$this, 'admin_print_tabs'] );
- add_action( 'init', [$this, 'create_themebuilder_cpt'], 0 );
- add_action( 'admin_menu', [$this, 'modify_menu'], 90 );
- add_action( 'pre_get_posts', [$this, 'add_role_filter_to_posts_query'] );
-
- // Only for evementor v2
- add_action( 'elementor/editor/v2/scripts/enqueue', [$this, 'ha_template_element_scripts'] );
-
- // Theme builder scripts
- add_action( 'elementor/editor/after_enqueue_scripts', [$this, 'ha_template_element_scripts'] );
- add_action( 'elementor/editor/after_enqueue_scripts', [$this, 'edit_template_condition_modal'], 10, 2 );
-
- add_filter( 'elementor/document/config', [$this, 'ha_template_document_title'], 10, 2 );
-
- // Admin Actions
- add_action( 'admin_action_ha_library_new_post', [$this, 'admin_action_new_post'] );
-
- add_action( 'current_screen', function () {
- $current_screen = get_current_screen();
- if ( ! $current_screen || ! strstr( $current_screen->post_type, 'ha_library' ) ) {
- return;
- }
- add_action( 'in_admin_header', function () {
- $this->render_admin_top_bar();
- } );
- // add_action('admin_head', [$this, 'add_new_template_template']);
- add_action( 'in_admin_footer', [$this, 'add_new_template_template'], 10, 2 );
- } );
-
- add_action( 'manage_' . self::CPT . '_posts_columns', [__CLASS__, 'admin_columns_headers'] );
- add_action( 'manage_' . self::CPT . '_posts_custom_column', [$this, 'admin_columns_content'], 10, 2 );
-
- //Override Single Post Template
- add_filter( 'template_include', [$this, 'ha_theme_builder_content'], 999 );
- add_action( 'happyaddons_theme_builder_render', [ $this, 'single_blog_content_elementor' ], 999 );
-
- add_action( 'elementor/elements/categories_registered', [$this, 'add_elementor_widget_categories'] );
-
- // Register Ajax Handles
- // add_action( 'wp_ajax_ha_cond_template_type', [$this, 'ha_get_template_type'] );
- }
-
- public function add_elementor_widget_categories( $elements_manager ) {
- if ( self::CPT == get_post_type() ) {
- $elements_manager->add_category(
- 'happy_addons_theme_builder',
- [
- 'title' => esc_html__( 'Happy Theme Builder', 'happy-elementor-addons' ),
- 'icon' => 'fa fa-plug'
- ]
- );
- }
- }
-
- public static function get_template_types() {
- $template_types = [
- 'header' => esc_html__( 'Header', 'happy-elementor-addons' ),
- 'footer' => esc_html__( 'Footer', 'happy-elementor-addons' ),
- 'single' => esc_html__( 'Single', 'happy-elementor-addons' ),
- 'archive' => esc_html__( 'Archive', 'happy-elementor-addons' )
- ];
-
- // return apply_filters('happyaddons_theme_builder_template_types', $template_types);
-
- return apply_filters( 'happyaddons/theme-builder/template-types', $template_types );
- }
-
- public function add_query_vars_filter( $vars ) {
- $vars[] = 'ha_library_type';
-
- return $vars;
- }
-
- // Register Custom Post Type Theme Builder
- public function create_themebuilder_cpt() {
-
- $labels = [
- 'name' => _x( 'Theme Builder', 'Post Type General Name', 'happy-elementor-addons' ),
- 'singular_name' => _x( 'Theme Builder', 'Post Type Singular Name', 'happy-elementor-addons' ),
- 'menu_name' => _x( 'Theme Builder', 'Admin Menu text', 'happy-elementor-addons' ),
- 'name_admin_bar' => _x( 'Theme Builder', 'Add New on Toolbar', 'happy-elementor-addons' ),
- 'archives' => __( 'Theme Builder Archives', 'happy-elementor-addons' ),
- 'attributes' => __( 'Theme Builder Attributes', 'happy-elementor-addons' ),
- 'parent_item_colon' => __( 'Parent Theme Builder:', 'happy-elementor-addons' ),
- 'all_items' => __( 'All Theme Builder', 'happy-elementor-addons' ),
- 'add_new_item' => __( 'Add New Theme Builder', 'happy-elementor-addons' ),
- 'add_new' => __( 'Add New', 'happy-elementor-addons' ),
- 'new_item' => __( 'New Theme Builder', 'happy-elementor-addons' ),
- 'edit_item' => __( 'Edit Theme Builder', 'happy-elementor-addons' ),
- 'update_item' => __( 'Update Theme Builder', 'happy-elementor-addons' ),
- 'view_item' => __( 'View Theme Builder', 'happy-elementor-addons' ),
- 'view_items' => __( 'View Theme Builder', 'happy-elementor-addons' ),
- 'search_items' => __( 'Search Theme Builder', 'happy-elementor-addons' ),
- 'not_found' => __( 'Not found', 'happy-elementor-addons' ),
- 'not_found_in_trash' => __( 'Not found in Trash', 'happy-elementor-addons' ),
- 'featured_image' => __( 'Featured Image', 'happy-elementor-addons' ),
- 'set_featured_image' => __( 'Set featured image', 'happy-elementor-addons' ),
- 'remove_featured_image' => __( 'Remove featured image', 'happy-elementor-addons' ),
- 'use_featured_image' => __( 'Use as featured image', 'happy-elementor-addons' ),
- 'insert_into_item' => __( 'Insert into Theme Builder', 'happy-elementor-addons' ),
- 'uploaded_to_this_item' => __( 'Uploaded to this Theme Builder', 'happy-elementor-addons' ),
- 'items_list' => __( 'Theme Builder list', 'happy-elementor-addons' ),
- 'items_list_navigation' => __( 'Theme Builder list navigation', 'happy-elementor-addons' ),
- 'filter_items_list' => __( 'Filter Theme Builder list', 'happy-elementor-addons' )
- ];
- $args = [
- 'label' => __( 'Theme Builder', 'happy-elementor-addons' ),
- 'description' => __( '', 'happy-elementor-addons' ),
- 'labels' => $labels,
- 'supports' => [ 'title', 'elementor' ],
- 'taxonomies' => [],
- 'public' => true,
- 'show_ui' => true,
- 'show_in_menu' => '',
- 'show_in_admin_bar' => false,
- 'show_in_nav_menus' => false,
- 'can_export' => true,
- 'has_archive' => false,
- 'hierarchical' => false,
- 'exclude_from_search' => true,
- 'capability_type' => 'page'
- ];
- register_post_type( 'ha_library', $args );
- }
-
- public function modify_menu() {
- add_submenu_page(
- Dashboard::PAGE_SLUG, // Parent slug
- __( 'Theme Builder', 'happy-elementor-addons' ), // Page title
- __( 'Theme Builder', 'happy-elementor-addons' ), // Menu title
- 'manage_options', // Capability
- 'edit.php?post_type=ha_library', // Slug
- false// Function
- );
- }
-
- public function add_role_filter_to_posts_query( $query ) {
- /**
- * No use on front
- * pre get posts runs everywhere
- * even if you test $pagenow after, bail as soon as possible
- */
- if ( ! is_admin() ) {
- return;
- }
-
- global $pagenow;
-
- /**
- * use $query parameter instead of global $post_type
- */
- if ( 'edit.php' === $pagenow && self::CPT === $query->query['post_type'] ) {
-
- if ( isset( $_GET['ha_library_type'] ) ) {
- $meta_query = [
- [
- 'key' => '_ha_library_type',
- 'value' => sanitize_text_field( $_GET['ha_library_type'] ),
- 'compare' => '=='
- ]
- ];
- $query->set( 'meta_query', $meta_query );
- $query->set( 'meta_key', '_ha_library_type' );
- }
- }
- }
+ protected $templates;
+ protected $current_theme;
+ protected $current_template;
+ protected $current_location;
+
+ private $cache;
+ private $location_cache;
+
+ const CPT = 'ha_library';
+ const TAB_BASE = 'edit.php?post_type=ha_library';
+
+ public $header_template;
+ public $footer_template;
+ public $singular_template;
+
+ public function __construct() {
+ add_action( 'wp', [$this, 'hooks'] );
+ // $this->cache = new Conditions_Cache();
+ $this->cache = Conditions_Cache::instance();
+
+ add_filter( 'query_vars', [$this, 'add_query_vars_filter'] );
+ add_filter( 'views_edit-' . self::CPT, [$this, 'admin_print_tabs'] );
+ add_action( 'init', [$this, 'create_themebuilder_cpt'], 0 );
+ add_action( 'admin_menu', [$this, 'modify_menu'], 90 );
+ add_action( 'pre_get_posts', [$this, 'add_role_filter_to_posts_query'] );
+
+ // Only for evementor v2
+ add_action( 'elementor/editor/v2/scripts/enqueue', [$this, 'ha_template_element_scripts'] );
+
+ // Theme builder scripts
+ add_action( 'elementor/editor/after_enqueue_scripts', [$this, 'ha_template_element_scripts'] );
+ add_action( 'elementor/editor/after_enqueue_scripts', [$this, 'edit_template_condition_modal'], 10, 2 );
+
+ add_filter( 'elementor/document/config', [$this, 'ha_template_document_title'], 10, 2 );
+
+ // Admin Actions
+ add_action( 'admin_action_ha_library_new_post', [$this, 'admin_action_new_post'] );
+
+ add_action( 'current_screen', function () {
+ $current_screen = get_current_screen();
+ if ( !$current_screen || !strstr( $current_screen->post_type, 'ha_library' ) ) {
+ return;
+ }
+ add_action( 'in_admin_header', function () {
+ $this->render_admin_top_bar();
+ } );
+ // add_action('admin_head', [$this, 'add_new_template_template']);
+ add_action( 'in_admin_footer', [$this, 'add_new_template_template'], 10, 2 );
+ } );
+
+ add_action( 'manage_' . self::CPT . '_posts_columns', [__CLASS__, 'admin_columns_headers'] );
+ add_action( 'manage_' . self::CPT . '_posts_custom_column', [$this, 'admin_columns_content'], 10, 2 );
+
+ //Override Single Post Template
+ add_filter( 'template_include', [$this, 'ha_theme_builder_content'], 999 );
+ add_action( 'happyaddons_theme_builder_render', [$this, 'single_blog_content_elementor'], 999 );
+
+ add_action( 'elementor/elements/categories_registered', [$this, 'add_elementor_widget_categories'] );
+
+ // Register Ajax Handles
+ // add_action( 'wp_ajax_ha_cond_template_type', [$this, 'ha_get_template_type'] );
+ }
+
+ public function add_elementor_widget_categories( $elements_manager ) {
+ if ( self::CPT == get_post_type() ) {
+ $elements_manager->add_category(
+ 'happy_addons_theme_builder',
+ [
+ 'title' => esc_html__( 'Happy Theme Builder', 'happy-elementor-addons' ),
+ 'icon' => 'fa fa-plug'
+ ]
+ );
+ }
+ }
+
+ public static function get_template_types() {
+ $template_types = [
+ 'header' => esc_html__( 'Header', 'happy-elementor-addons' ),
+ 'footer' => esc_html__( 'Footer', 'happy-elementor-addons' ),
+ 'single' => esc_html__( 'Single', 'happy-elementor-addons' ),
+ 'archive' => esc_html__( 'Archive', 'happy-elementor-addons' )
+ ];
+
+ // return apply_filters('happyaddons_theme_builder_template_types', $template_types);
+
+ return apply_filters( 'happyaddons/theme-builder/template-types', $template_types );
+ }
+
+ public function add_query_vars_filter( $vars ) {
+ $vars[] = 'ha_library_type';
+
+ return $vars;
+ }
+
+ // Register Custom Post Type Theme Builder
+ public function create_themebuilder_cpt() {
+
+ $labels = [
+ 'name' => _x( 'Theme Builder', 'Post Type General Name', 'happy-elementor-addons' ),
+ 'singular_name' => _x( 'Theme Builder', 'Post Type Singular Name', 'happy-elementor-addons' ),
+ 'menu_name' => _x( 'Theme Builder', 'Admin Menu text', 'happy-elementor-addons' ),
+ 'name_admin_bar' => _x( 'Theme Builder', 'Add New on Toolbar', 'happy-elementor-addons' ),
+ 'archives' => __( 'Theme Builder Archives', 'happy-elementor-addons' ),
+ 'attributes' => __( 'Theme Builder Attributes', 'happy-elementor-addons' ),
+ 'parent_item_colon' => __( 'Parent Theme Builder:', 'happy-elementor-addons' ),
+ 'all_items' => __( 'All Theme Builder', 'happy-elementor-addons' ),
+ 'add_new_item' => __( 'Add New Theme Builder', 'happy-elementor-addons' ),
+ 'add_new' => __( 'Add New', 'happy-elementor-addons' ),
+ 'new_item' => __( 'New Theme Builder', 'happy-elementor-addons' ),
+ 'edit_item' => __( 'Edit Theme Builder', 'happy-elementor-addons' ),
+ 'update_item' => __( 'Update Theme Builder', 'happy-elementor-addons' ),
+ 'view_item' => __( 'View Theme Builder', 'happy-elementor-addons' ),
+ 'view_items' => __( 'View Theme Builder', 'happy-elementor-addons' ),
+ 'search_items' => __( 'Search Theme Builder', 'happy-elementor-addons' ),
+ 'not_found' => __( 'Not found', 'happy-elementor-addons' ),
+ 'not_found_in_trash' => __( 'Not found in Trash', 'happy-elementor-addons' ),
+ 'featured_image' => __( 'Featured Image', 'happy-elementor-addons' ),
+ 'set_featured_image' => __( 'Set featured image', 'happy-elementor-addons' ),
+ 'remove_featured_image' => __( 'Remove featured image', 'happy-elementor-addons' ),
+ 'use_featured_image' => __( 'Use as featured image', 'happy-elementor-addons' ),
+ 'insert_into_item' => __( 'Insert into Theme Builder', 'happy-elementor-addons' ),
+ 'uploaded_to_this_item' => __( 'Uploaded to this Theme Builder', 'happy-elementor-addons' ),
+ 'items_list' => __( 'Theme Builder list', 'happy-elementor-addons' ),
+ 'items_list_navigation' => __( 'Theme Builder list navigation', 'happy-elementor-addons' ),
+ 'filter_items_list' => __( 'Filter Theme Builder list', 'happy-elementor-addons' )
+ ];
+ $args = [
+ 'label' => __( 'Theme Builder', 'happy-elementor-addons' ),
+ 'description' => __( '', 'happy-elementor-addons' ),
+ 'labels' => $labels,
+ 'supports' => ['title', 'elementor'],
+ 'taxonomies' => [],
+ 'public' => true,
+ 'show_ui' => true,
+ 'show_in_menu' => '',
+ 'show_in_admin_bar' => false,
+ 'show_in_nav_menus' => false,
+ 'can_export' => true,
+ 'has_archive' => false,
+ 'hierarchical' => false,
+ 'exclude_from_search' => true,
+ 'capability_type' => 'page',
+ 'map_meta_cap' => true,
+ ];
+ register_post_type( 'ha_library', $args );
+ }
+
+ public function modify_menu() {
+ add_submenu_page(
+ Dashboard::PAGE_SLUG, // Parent slug
+ __( 'Theme Builder', 'happy-elementor-addons' ), // Page title
+ __( 'Theme Builder', 'happy-elementor-addons' ), // Menu title
+ 'manage_options', // Capability
+ 'edit.php?post_type=ha_library', // Slug
+ false // Function
+ );
+ }
+
+ public function add_role_filter_to_posts_query( $query ) {
+ /**
+ * No use on front
+ * pre get posts runs everywhere
+ * even if you test $pagenow after, bail as soon as possible
+ */
+ if ( !is_admin() ) {
+ return;
+ }
+
+ global $pagenow;
+
+ /**
+ * use $query parameter instead of global $post_type
+ */
+ if ( 'edit.php' === $pagenow && self::CPT === $query->query['post_type'] ) {
+
+ if ( isset( $_GET['ha_library_type'] ) ) {
+ $meta_query = [
+ [
+ 'key' => '_ha_library_type',
+ 'value' => sanitize_text_field( $_GET['ha_library_type'] ),
+ 'compare' => '=='
+ ]
+ ];
+ $query->set( 'meta_query', $meta_query );
+ $query->set( 'meta_key', '_ha_library_type' );
+ }
+ }
+ }
- private function render_admin_top_bar() {
- ?>
+ private function render_admin_top_bar() {
+ ?>
<div id="ha-admin-top-bar-root">
<div class="ha-admin-top-bar">
<div class="ha-admin-top-bar__main-area">
@@ -230,782 +231,781 @@
</div>
</div>
<?php
- }
+ }
- public static function admin_columns_headers( $posts_columns ) {
- $offset = 2;
+ public static function admin_columns_headers( $posts_columns ) {
+ $offset = 2;
- $posts_columns = array_slice( $posts_columns, 0, $offset, true ) + [
- 'type' => __( 'Type', 'happy-elementor-addons' ),
- 'condition' => __( 'Conditions', 'happy-elementor-addons' )
- ] + array_slice( $posts_columns, $offset, null, true );
+ $posts_columns = array_slice( $posts_columns, 0, $offset, true ) + [
+ 'type' => __( 'Type', 'happy-elementor-addons' ),
+ 'condition' => __( 'Conditions', 'happy-elementor-addons' )
+ ] + array_slice( $posts_columns, $offset, null, true );
- return $posts_columns;
- }
+ return $posts_columns;
+ }
- public function admin_columns_content( $column_name, $post_id ) {
+ public function admin_columns_content( $column_name, $post_id ) {
- // $instance = self::instance();
+ // $instance = self::instance();
- if ( 'type' === $column_name ) {
+ if ( 'type' === $column_name ) {
- $type = get_post_meta( $post_id, '_ha_library_type', true );
- $isActive = get_post_meta( $post_id, '_ha_template_active', true );
+ $type = get_post_meta( $post_id, '_ha_library_type', true );
+ $isActive = get_post_meta( $post_id, '_ha_template_active', true );
- echo ucwords( str_replace( '-', ' ', $type ) );
+ echo ucwords( str_replace( '-', ' ', $type ) );
- echo "<span id='htlt-", $post_id, "'>";
+ echo "<span id='htlt-", $post_id, "'>";
- if ( $isActive ) {
+ if ( $isActive ) {
- echo ' - <b>Active</b>';
+ echo ' - <b>Active</b>';
- }
+ }
- echo '</span>';
- }
+ echo '</span>';
+ }
- if ( 'condition' === $column_name ) {
+ if ( 'condition' === $column_name ) {
- $type = get_post_meta( $post_id, '_ha_library_type', true );
+ $type = get_post_meta( $post_id, '_ha_library_type', true );
- if ( 'loop-template' != $type ) {
- // generate display condition from document conditions
- $includeConditions = [];
- $excludeConditions = [];
+ if ( 'loop-template' != $type ) {
+ // generate display condition from document conditions
+ $includeConditions = [];
+ $excludeConditions = [];
- // get doc conditions
- $documentConditions = $this->get_document_conditions( $post_id );
+ // get doc conditions
+ $documentConditions = $this->get_document_conditions( $post_id );
- if ( ! empty( $documentConditions ) ) {
- foreach ( $documentConditions as $key => $condition ) {
- if ( 'include' === $condition['type'] ) {
- $sub_page_id = ! empty( $condition['sub_id'] ) ? '#' . get_the_title( $condition['sub_id'] ) : '';
- $con_label = ! empty( $condition['sub_name'] ) && 'all' !== $condition['sub_name'] ? Condition_Manager::instance()->get_name( $condition['sub_name'] ) . $sub_page_id : Condition_Manager::instance()->get_all_name( $condition['name'] );
- $includeConditions[] = $con_label;
- } else if ( 'exclude' === $condition['type'] ) {
- $sub_page_id = ! empty( $condition['sub_id'] ) ? '#' . get_the_title( $condition['sub_id'] ) : '';
- $con_label = ! empty( $condition['sub_name'] ) && 'all' !== $condition['sub_name'] ? Condition_Manager::instance()->get_name( $condition['sub_name'] ) . $sub_page_id : Condition_Manager::instance()->get_all_name( $condition['name'] );
- $excludeConditions[] = $con_label;
- } else {
- // not use this..
- }
+ if ( !empty( $documentConditions ) ) {
+ foreach ( $documentConditions as $key => $condition ) {
+ if ( 'include' === $condition['type'] ) {
+ $sub_page_id = !empty( $condition['sub_id'] ) ? '#' . get_the_title( $condition['sub_id'] ) : '';
+ $con_label = !empty( $condition['sub_name'] ) && 'all' !== $condition['sub_name'] ? Condition_Manager::instance()->get_name( $condition['sub_name'] ) . $sub_page_id : Condition_Manager::instance()->get_all_name( $condition['name'] );
+ $includeConditions[] = $con_label;
+ } else if ( 'exclude' === $condition['type'] ) {
+ $sub_page_id = !empty( $condition['sub_id'] ) ? '#' . get_the_title( $condition['sub_id'] ) : '';
+ $con_label = !empty( $condition['sub_name'] ) && 'all' !== $condition['sub_name'] ? Condition_Manager::instance()->get_name( $condition['sub_name'] ) . $sub_page_id : Condition_Manager::instance()->get_all_name( $condition['name'] );
+ $excludeConditions[] = $con_label;
+ } else {
+ // not use this..
+ }
- }
- }
+ }
+ }
- echo '<b>Include : </b> ' . implode( ', ', $includeConditions ) . '<br/>' . '<b>Exclude : </b> ' . implode( ', ', $excludeConditions );
- } else {
- echo '<b>Not Applicable</b>';
- }
- }
- }
+ echo '<b>Include : </b> ' . implode( ', ', $includeConditions ) . '<br/>' . '<b>Exclude : </b> ' . implode( ', ', $excludeConditions );
+ } else {
+ echo '<b>Not Applicable</b>';
+ }
+ }
+ }
- public function admin_print_tabs( $views ) {
- $getActive = get_query_var( 'ha_library_type' );
- // var_dump($getActive);
- ?>
+ public function admin_print_tabs( $views ) {
+ $getActive = get_query_var( 'ha_library_type' );
+ // var_dump($getActive);
+ ?>
<div id="happyaddon-template-library-tabs-wrapper" class="nav-tab-wrapper">
- <a class="nav-tab <?=! ( $getActive ) ? 'nav-tab-active' : '';?>" href="<?=admin_url( self::TAB_BASE )?>">All</a>
+ <a class="nav-tab <?=! ( $getActive ) ? 'nav-tab-active' : '';?>" href="<?=admin_url( self::TAB_BASE )?>">All</a>
<?php
- foreach ( self::get_template_types() as $key => $value ) {
- $active = ( $getActive == $key ) ? 'nav-tab-active' : '';
- $admin_filter_url = admin_url( self::TAB_BASE . '&ha_library_type=' . $key );
- echo '<a class="nav-tab ' . $active . '" href="' . $admin_filter_url . '">' . $value . '</a>';
- }
- ?>
+ foreach ( self::get_template_types() as $key => $value ) {
+ $active = ( $getActive == $key ) ? 'nav-tab-active' : '';
+ $admin_filter_url = admin_url( self::TAB_BASE . '&ha_library_type=' . $key );
+ echo '<a class="nav-tab ' . $active . '" href="' . $admin_filter_url . '">' . $value . '</a>';
+ }
+ ?>
</div>
<br>
<?php
- return $views;
- }
+ return $views;
+ }
- /**
- * @since 2.3.0
- * @access public
- */
- public function add_new_template_template() {
- ob_start();
- include HAPPY_ADDONS_DIR_PATH . 'templates/admin/new-template.php';
- $template = ob_get_clean();
- echo $template;
- }
-
- // public function edit_template_template() {
- // ob_start();
- // include(HAPPY_ADDONS_DIR_PATH . 'templates/admin/edit-template.php');
- // $template = ob_get_clean();
- // echo $template;
- // }
-
- public function edit_template_condition_modal() {
- if ( self::CPT === get_post_type() ) {
- ob_start();
- include HAPPY_ADDONS_DIR_PATH . 'templates/admin/edit-template-condition.php';
- $template = ob_get_clean();
- echo $template;
- }
- }
-
- /**
- * Admin action new post.
- *
- * When a new post action is fired the title is set to 'Elementor' and the post ID.
- *
- * Fired by `admin_action_elementor_new_post` action.
- *
- * @since 1.9.0
- * @access public
- */
- public function admin_action_new_post() {
-
- // echo '<pre>';
- // var_dump($_REQUEST);
- // echo '</pre>';
-
- // die();
-
- check_admin_referer( 'ha_library_new_post_action' );
-
- if ( empty( $_GET['post_type'] ) ) {
- $post_type = 'post';
- } else {
- $post_type = sanitize_text_field( $_GET['post_type'] );
- }
-
- $post_type_object = get_post_type_object( $post_type );
-
- if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) {
- return;
- }
-
- if ( empty( $_GET['template_type'] ) ) {
- $type = 'post';
- } else {
- $type = sanitize_text_field( $_GET['template_type'] );
- }
-
- $post_data = isset( $_GET['post_data'] ) ? ha_sanitize_array_recursively( $_GET['post_data'] ) : [];
-
- // $template_display_type = isset($_GET['template_display_type']) ? $_GET['template_display_type'] : '';
- // $template_display_type_singular = isset($_GET['template_display_type_singular']) ? $_GET['template_display_type_singular'] : '';
- // $template_display_type_selected = isset($_GET['template_display_type_selected']) ? $_GET['template_display_type_selected'] : [];
-
- $conditions = [];
-
- // if (!empty($template_display_type)) {
- // $conditions .= $template_display_type;
- // if ($template_display_type == 'singular') {
- // $conditions .= '/' . $template_display_type_singular;
- // if ($template_display_type_singular == 'selective') {
- // $vals = implode(',', $template_display_type_selected);
- // $conditions .= '/' . $vals;
- // }
- // }
- // }
-
- $meta = [];
-
- /**
- * Create new post meta data.
- *
- * Filters the meta data of any new post created.
- *
- * @since 2.0.0
- *
- * @param array $meta Post meta data.
- */
- // $meta = apply_filters( 'elementor/admin/create_new_post/meta', $meta );
-
- $meta['display_conditions'] = $conditions;
- $post_data['post_type'] = $post_type;
-
- $document = $this->create_template_document( $type, $post_data, $meta );
-
- if ( is_wp_error( $document ) ) {
- wp_die( $document ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
- }
-
- wp_redirect( $this->get_edit_url( $document ) );
-
- die;
- }
-
- protected function create_template_document( $type, $post_data, $meta ) {
- if ( empty( $post_data['post_title'] ) ) {
- $post_data['post_title'] = esc_html__( 'Elementor', 'happy-elementor-addons' );
- $update_title = true;
- }
-
- $meta_data['_elementor_edit_mode'] = 'builder';
-
- // Save the type as-is for plugins that hooked at `wp_insert_post`.
- $meta_data['_ha_library_type'] = $type;
- $meta_data['_ha_display_cond'] = $meta['display_conditions'];
- $meta_data['_wp_page_template'] = 'elementor_canvas';
-
- $post_data['meta_input'] = $meta_data;
-
- $post_id = wp_insert_post( $post_data );
-
- if ( ! empty( $update_title ) ) {
- $post_data['ID'] = $post_id;
- $post_data['post_title'] .= ' #' . $post_id;
-
- // The meta doesn't need update.
- unset( $post_data['meta_input'] );
-
- wp_update_post( $post_data );
- }
-
- return $post_id;
- }
-
- public function get_edit_url( $id ) {
- $url = add_query_arg(
- [
- 'post' => $id,
- 'action' => 'elementor'
- ],
- admin_url( 'post.php' )
- );
-
- return $url;
- }
-
- public function hooks() {
- $this->current_template = basename( get_page_template_slug() );
- if ( 'elementor_canvas' == $this->current_template ) {
- return;
- }
-
- $this->current_theme = get_template();
-
- switch ( $this->current_theme ) {
- case 'astra':
- new Happy_AddonsElementorClassesBuilder_CompatibilityAstra( self::template_ids() );
- break;
-
- case 'generatepress':
- case 'generatepress-child':
- new Happy_AddonsElementorClassesBuilder_CompatibilityGeneratepress( self::template_ids() );
- break;
-
- case 'oceanwp':
- case 'oceanwp-child':
- new Happy_AddonsElementorClassesBuilder_CompatibilityOceanwp( self::template_ids() );
- break;
-
- case 'bb-theme':
- case 'bb-theme-child':
- new Happy_AddonsElementorClassesBuilder_CompatibilityBbtheme( self::template_ids() );
- break;
-
- case 'genesis':
- case 'genesis-child':
- new Happy_AddonsElementorClassesBuilder_CompatibilityGenesis( self::template_ids() );
- break;
-
- case 'twentynineteen':
- new Happy_AddonsElementorClassesBuilder_CompatibilityTwentyNineteen( self::template_ids() );
- break;
-
- case 'my-listing':
- case 'my-listing-child':
- new Happy_AddonsElementorClassesBuilder_CompatibilityMy_Listing( self::template_ids() );
- break;
-
- default:
- new Happy_AddonsElementorClassesBuilder_CompatibilityTheme_Support();
- break;
- }
- }
-
- public static function template_ids() {
- $cached = wp_cache_get( 'ha_template_ids' );
- if ( false !== $cached ) {
- return $cached;
- }
-
- $instance = self::instance();
- $instance->the_filter();
-
- $ids = [
- $instance->header_template,
- $instance->footer_template,
- $instance->singular_template
- ];
-
- if ( null != $instance->header_template ) {
- if ( class_exists( 'ElementorCoreFilesCSSPost' ) ) {
- $css_file = new ElementorCoreFilesCSSPost( $instance->header_template );
- $css_file->enqueue();
- }
- }
-
- if ( null != $instance->footer_template ) {
- if ( class_exists( 'ElementorCoreFilesCSSPost' ) ) {
- $css_file = new ElementorCoreFilesCSSPost( $instance->footer_template );
- $css_file->enqueue();
- }
- }
-
- wp_cache_set( 'ha_template_ids', $ids );
-
- return $ids;
- }
-
- public function get_document_instances( $post_id ) {
-
- $summary = [];
-
- $document_conditions = $this->get_document_conditions( $post_id );
-
- $summary = [];
-
- if ( ! empty( $document_conditions ) ) {
- foreach ( $document_conditions as $document_condition ) {
- if ( 'exclude' === $document_condition['type'] ) {
- // continue;
- }
-
- // print_r($document_condition);
-
- $condition_name = ! empty( $document_condition['sub_name'] ) ? $document_condition['sub_name'] : $document_condition['name'];
-
- // $condition = $this->get_condition($condition_name);
- // if (!$condition) {
- // continue;
- // }
-
- if ( ! empty( $document_condition['sub_id'] ) ) {
- $instance_label = Condition_Manager::instance()->get_name( $condition_name ) . " #{$document_condition['sub_id']}";
- } else {
- // $instance_label = $condition_name->get_all_label();
- $instance_label = Condition_Manager::instance()->get_all_name( $condition_name );
- }
-
- $summary[$condition_name] = $instance_label;
- }
- }
-
- return $summary;
- }
-
- /**
- * @param Theme_Document $document
- *
- * @return array
- */
- public function get_document_conditions( $post_id ) {
- $saved_conditions = get_post_meta( $post_id, '_ha_display_cond', true );
-
- $conditions = [];
-
- if ( is_array( $saved_conditions ) ) {
- foreach ( $saved_conditions as $condition ) {
- $conditions[] = $this->parse_condition( $condition );
- }
- }
-
- return $conditions;
- }
-
- private function get_template_by_location( $location ) {
- $templates = $this->cache->get_by_location( $location );
-
- return $templates;
- }
-
- protected function the_filter() {
- $arg = [
- 'posts_per_page' => -1,
- 'orderby' => 'id',
- 'order' => 'DESC',
- 'post_status' => 'publish',
- 'post_type' => self::CPT
- ];
-
- $this->templates = get_posts( $arg );
-
- $this->templates = null;
-
- // more conditions can be triggered at once
- // don't use switch case
- // may impliment and callable by dynamic class in future
-
- // entire site
- if ( ! is_admin() ) {
- $filters = [[
- 'key' => 'condition_a',
- 'value' => 'general'
- ]];
- $this->load_template_element( $filters );
- }
-
- // all pages, all posts, 404 page
- if ( is_page() ) {
- $filters = [
- [
- 'key' => 'condition_a',
- 'value' => 'singular'
- ],
- [
- 'key' => 'condition_singular',
- 'value' => 'all_pages'
- ]
- ];
- $this->load_template_element( $filters );
- } else if ( is_single() ) {
- $filters = [
- [
- 'key' => 'condition_a',
- 'value' => 'posts'
- ]
- ];
- $this->load_template_element( $filters );
- } else if ( is_404() ) {
- $filters = [
- [
- 'key' => 'condition_a',
- 'value' => 'singular'
- ],
- [
- 'key' => 'condition_singular',
- 'value' => '404page'
- ]
- ];
- $this->load_template_element( $filters );
- }
- }
-
- private function check_elementor_content( $post_id ) {
- $elContent = get_post_meta( $post_id, '_elementor_data', true );
-
- if ( $elContent ) {
- return true;
- }
-
- return false;
- }
-
- public function get_public_post_types() {
- $post_type_args = [
- // Default is the value $public.
- 'show_in_nav_menus' => true
- ];
-
- // Keep for backwards compatibility
- if ( ! empty( $args['post_type'] ) ) {
- $post_type_args['name'] = $args['post_type'];
- unset( $args['post_type'] );
- }
-
- $post_type_args = wp_parse_args( $post_type_args );
-
- $_post_types = get_post_types( $post_type_args, 'objects' );
-
- $post_types = [];
-
- foreach ( $_post_types as $post_type => $object ) {
- $post_types[$post_type] = $object->label;
- }
-
- return $post_types;
- }
-
- public function ha_theme_builder_content( $template ) {
- $location = '';
-
- if ( is_singular( array_keys( $this->get_public_post_types() ) ) || is_404() ) {
- $location = 'single';
-
- $isBuiltWithElementor = $this->check_elementor_content( get_the_ID() );
-
- if ( $isBuiltWithElementor ) {
- return $template;
- }
- } else if ( function_exists( 'is_shop' ) && is_shop() ) {
- $location = 'archive';
- } else if ( is_archive() || is_tax() || is_home() || is_search() ) {
- $location = 'archive';
- }
-
- if ( class_exists( "ElementorProPlugin" ) ) {
- $document = ElementorProPlugin::elementor()->documents->get_doc_for_frontend( get_the_ID() );
- $page_templates_module = ElementorProPlugin::elementor()->modules_manager->get_modules( 'page-templates' );
-
- if ( $document && $document instanceof ElementorProModulesThemeBuilderDocumentsTheme_Document ) {
- // For editor preview iframe.
- $location = $document->get_location();
-
- if ( 'header' === $location || 'footer' === $location ) {
- $page_template = $page_templates_module::TEMPLATE_HEADER_FOOTER;
- $template_path = $page_templates_module->get_template_path( $page_template );
- $page_templates_module->set_print_callback( function () use ( $location ) {
- ElementorProModulesThemeBuilderModule::instance()->get_locations_manager()->do_location( $location );
- } );
- $template = $template_path;
-
- return $template;
- }
- }
- }
- if ( $location ) {
- $location_documents = Condition_Manager::instance()->get_documents_for_location( $location );
-
- if ( empty( $location_documents ) ) {
- return $template;
- }
-
- if ( 'single' === $location || 'archive' === $location ) {
-
- $first_key = key( $location_documents );
- $theme_document = $location_documents[$first_key];
-
- $templateType = get_post_meta( $theme_document, '_wp_page_template', true );
-
- $this->singular_template = $theme_document;
-
- if ( $theme_document ) {
- switch ( $templateType ) {
- case 'elementor_canvas':
- $template = HAPPY_ADDONS_DIR_PATH . 'templates/builder/singular/canvas.php';
- break;
- case 'elementor_header_footer':
- $template = HAPPY_ADDONS_DIR_PATH . 'templates/builder/singular/fullwidth.php';
- break;
- default:
- // $template = $template;
- $template = HAPPY_ADDONS_DIR_PATH . 'templates/builder/singular/fullwidth.php';
- break;
- }
- }
- }
- }
-
- return $template;
- }
-
- /*
- * Render Elementor single blog content
- */
- public function single_blog_content_elementor( $post ) {
- $templat