PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.35
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.35
51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 All 39 releases
king-addons / includes / extensions / Header_Footer_Builder / Header_Footer_Builder.php

Header_Footer_Builder.php in King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder 51.1.35, at includes/extensions/Header_Footer_Builder/Header_Footer_Builder.php

1,797 lines 72.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /** @noinspection PhpMissingFieldTypeInspection, DuplicatedCode */
2
3 namespace King_Addons;
4
5 use Elementor;
6 use WP_Query;
7
8 if (!defined('ABSPATH')) {
9 exit;
10 }
11
12 final class Header_Footer_Builder
13 {
14 private static ?Header_Footer_Builder $instance = null;
15 private static ?string $current_page_type = null;
16 private static array $current_page_data = array();
17 private static $location_selection;
18 private static $user_selection;
19 private static $elementor_instance;
20
21 public static function instance(): ?Header_Footer_Builder
22 {
23 if (is_null(self::$instance)) {
24 self::$instance = new self();
25 }
26 return self::$instance;
27 }
28
29 public function __construct()
30 {
31 add_action('init', [$this, 'addPostType']);
32 add_action('admin_notices', [$this, 'renderNoticeZeroPosts']);
33 add_action('in_admin_header', [$this, 'renderAdminCustomHeader']);
34 add_action('add_meta_boxes', [$this, 'registerMetabox']);
35 add_action('save_post', [$this, 'saveMetaboxData']);
36 add_action('template_redirect', [$this, 'checkUserCanEdit']);
37 add_filter('screen_options_show_screen', [$this, 'disableScreenOptions'], 10, 2);
38
39 require_once(KING_ADDONS_PATH . 'includes/extensions/Header_Footer_Builder/ELHF_Render_On_Canvas.php');
40 add_filter('single_template', [$this, 'loadElementorCanvasTemplate']);
41
42 self::setCompatibility();
43 add_action('admin_enqueue_scripts', array($this, 'enqueueScripts'));
44 add_action('admin_action_edit', array($this, 'initialize_options'));
45 add_action('wp_ajax_king_addons_el_hf_get_posts_by_query', array($this, 'king_addons_el_hf_get_posts_by_query'));
46
47 if (is_admin()) {
48 add_action('manage_king-addons-el-hf_posts_custom_column', [$this, 'columnContent'], 10, 2);
49 add_filter('manage_king-addons-el-hf_posts_columns', [$this, 'columnHeadings']);
50 }
51 }
52
53 /**
54 * Show an admin notice when there are zero "king-addons-el-hf" posts
55 */
56 function renderNoticeZeroPosts()
57 {
58 global $pagenow, $post_type;
59
60 // Check if we are on the "All posts" page for the custom post type
61 if ('edit.php' === $pagenow && 'edit-king-addons-el-hf' === $post_type) {
62
63 // Count published posts of this CPT
64 $count_posts = wp_count_posts('king-addons-el-hf');
65 if ($count_posts->publish == 0) {
66 echo '<div class="notice notice-info is-dismissible">';
67 echo '<p>';
68 echo esc_html__("Create the first header or footer by clicking the 'Create New' button above.", 'king addons');
69 echo '</p>';
70 echo '</div>';
71 }
72 }
73 }
74
75 public function disableScreenOptions($show_screen, $screen)
76 {
77 if ($screen->id === 'edit-king-addons-el-hf') {
78 return false;
79 }
80 return $show_screen;
81 }
82
83 function king_addons_el_hf_get_posts_by_query()
84 {
85 // Security fix: Add authorization check
86 if (!current_user_can('edit_posts')) {
87 wp_send_json_error('Insufficient permissions');
88 return;
89 }
90
91 check_ajax_referer('king-addons-el-hf-get-posts-by-query', 'nonce');
92
93 $search_string = isset($_POST['q']) ? sanitize_text_field($_POST['q']) : '';
94 $result = array();
95
96 $args = array(
97 'public' => true,
98 '_builtin' => false,
99 );
100
101 $output = 'names';
102 $operator = 'and';
103 $post_types = get_post_types($args, $output, $operator);
104
105 unset($post_types['elementor-hf']);
106
107 $post_types['Posts'] = 'post';
108 $post_types['Pages'] = 'page';
109
110 foreach ($post_types as $key => $post_type) {
111 $data = array();
112
113 add_filter('posts_search', array($this, 'search_only_titles'), 10, 2);
114
115 $query = new WP_Query(
116 array(
117 's' => $search_string,
118 'post_type' => $post_type,
119 'posts_per_page' => -1,
120 )
121 );
122
123 if ($query->have_posts()) {
124 while ($query->have_posts()) {
125 $query->the_post();
126 $title = get_the_title();
127 $title .= (0 != $query->post->post_parent) ? ' (' . get_the_title($query->post->post_parent) . ')' : '';
128 $id = get_the_id();
129 $data[] = array(
130 'id' => 'post-' . $id,
131 'text' => $title,
132 );
133 }
134 }
135
136 if (is_array($data) && !empty($data)) {
137 $result[] = array(
138 'text' => $key,
139 'children' => $data,
140 );
141 }
142 }
143
144 wp_reset_postdata();
145
146 $args = array(
147 'public' => true,
148 );
149
150 $output = 'objects';
151 $taxonomies = get_taxonomies($args, $output, $operator);
152
153 foreach ($taxonomies as $taxonomy) {
154 $terms = get_terms(
155 $taxonomy->name,
156 array(
157 'orderby' => 'count',
158 'hide_empty' => 0,
159 'name__like' => $search_string,
160 )
161 );
162
163 $data = array();
164
165 $label = ucwords($taxonomy->label);
166
167 if (!empty($terms)) {
168 foreach ($terms as $term) {
169
170 $data[] = array(
171 'id' => 'tax-' . $term->term_id,
172 'text' => $term->name . ' archive page',
173 );
174
175 $data[] = array(
176 'id' => 'tax-' . $term->term_id . '-single-' . $taxonomy->name,
177 'text' => 'All singulars from ' . $term->name,
178 );
179 }
180 }
181
182 if (is_array($data) && !empty($data)) {
183 $result[] = array(
184 'text' => $label,
185 'children' => $data,
186 );
187 }
188 }
189
190 wp_send_json($result);
191 }
192
193 public function initialize_options()
194 {
195 self::$user_selection = self::get_user_selections();
196 self::$location_selection = self::getLocationSelections();
197 }
198
199 public function renderAdminCustomHeader()
200 {
201 $current_screen = get_current_screen()->id;
202 if ($current_screen !== 'edit-king-addons-el-hf'
203 && $current_screen !== 'header-footer_page_king-addons-el-hf-settings') {
204 return;
205 }
206
207 ?>
208 <div class="king-addons-pb-settings-page-header">
209 <h1><?php esc_html_e('Elementor Header & Footer Builder', 'king-addons'); ?></h1>
210 <p>
211 <?php esc_html_e('Create fully customizable headers and footers with display conditions to control where they appear', 'king-addons'); ?>
212 </p>
213 <div class="king-addons-pb-preview-buttons">
214 <a href="<?php echo admin_url('post-new.php?post_type=king-addons-el-hf'); ?>">
215 <div class="king-addons-pb-user-template">
216 <span><?php esc_html_e('Create New', 'king-addons'); ?></span>
217 <span class="plus-icon">+</span>
218 </div>
219 </a>
220 <?php if (!king_addons_freemius()->can_use_premium_code__premium_only()): ?>
221 <div class="kng-promo-btn-wrap">
222 <a href="https://kingaddons.com/pricing/?rel=king-addons-hf-builder" target="_blank">
223 <div class="kng-promo-btn-txt">
224 <?php esc_html_e('Unlock Premium Features & 650+ Templates Today!', 'king-addons'); ?>
225 </div>
226 <img width="16px"
227 src="<?php echo esc_url(KING_ADDONS_URL) . 'includes/admin/img/share-v2.svg'; ?>"
228 alt="<?php echo esc_html__('Open link in the new tab', 'king-addons'); ?>">
229 </a>
230 </div>
231 <?php endif; ?>
232 </div>
233 </div>
234 <?php
235
236 $counts = wp_count_posts('king-addons-el-hf');
237 $total = (int)$counts->publish + (int)$counts->draft;
238
239 if (0 === $total) {
240 echo '<div class="notice notice-info">';
241 echo '<p>';
242 echo esc_html__("Create the first header or footer by clicking the 'Create New' button above.", 'king addons');
243 echo '</p>';
244 echo '</div>';
245 }
246
247 }
248
249 function addPostType(): void
250 {
251 if (!current_user_can('manage_options')) {
252 return;
253 }
254
255 $labels = [
256 'name' => esc_html__('Elementor Header & Footer Builder', 'king-addons'),
257 'singular_name' => esc_html__('Elementor Header & Footer Builder', 'king-addons'),
258 'menu_name' => esc_html__('Elementor Header & Footer Builder', 'king-addons'),
259 'name_admin_bar' => esc_html__('Elementor Header & Footer Builder', 'king-addons'),
260 'add_new' => esc_html__('Add New', 'king-addons'),
261 'add_new_item' => esc_html__('Add New', 'king-addons'),
262 'new_item' => esc_html__('New Template', 'king-addons'),
263 'edit_item' => esc_html__('Edit Template', 'king-addons'),
264 'view_item' => esc_html__('View Template', 'king-addons'),
265 'all_items' => esc_html__('All Templates', 'king-addons'),
266 'search_items' => esc_html__('Search Templates', 'king-addons'),
267 'parent_item_colon' => esc_html__('Parent Templates:', 'king-addons'),
268 'not_found' => esc_html__('No Templates found.', 'king-addons'),
269 'not_found_in_trash' => esc_html__('No Templates found in Trash.', 'king-addons'),
270 ];
271
272 $args = [
273 'labels' => $labels,
274 'public' => true,
275 'show_ui' => true,
276 'show_in_menu' => false,
277 'show_in_nav_menus' => false,
278 'exclude_from_search' => true,
279 'capability_type' => 'post',
280 'hierarchical' => false,
281 'menu_icon' => 'dashicons-editor-kitchensink',
282 'supports' => ['title', 'thumbnail', 'elementor'],
283 'show_in_rest' => true,
284 ];
285
286 register_post_type('king-addons-el-hf', $args);
287
288 if (false === get_option('king_addons_HFB_flushed_rewrite_rules')) {
289 add_option('king_addons_HFB_flushed_rewrite_rules', true);
290 flush_rewrite_rules();
291 }
292 }
293
294 function registerMetabox()
295 {
296 add_meta_box(
297 'king-addons-el-hf-meta-box',
298 esc_html__('Elementor Header & Footer Builder Options', 'king-addons'),
299 [$this, 'renderMetabox'],
300 'king-addons-el-hf',
301 'normal',
302 'high'
303 );
304 }
305
306 function renderMetabox($post)
307 {
308 $values = get_post_custom($post->ID);
309 $template_type = isset($values['king_addons_el_hf_template_type']) ? esc_attr(sanitize_text_field($values['king_addons_el_hf_template_type'][0])) : '';
310 $display_on_canvas = isset($values['king-addons-el-hf-display-on-canvas']);
311
312 wp_nonce_field('king_addons_el_hf_meta_nounce', 'king_addons_el_hf_meta_nounce');
313 ?>
314 <table class="king-addons-el-hf-options-table widefat">
315 <tbody>
316 <tr class="king-addons-el-hf-options-row type-of-template">
317 <td class="king-addons-el-hf-options-row-heading">
318 <label for="king_addons_el_hf_template_type"><strong><?php esc_html_e('Type of Template', 'king-addons'); ?></strong></label>
319 </td>
320 <td class="king-addons-el-hf-options-row-content">
321 <select name="king_addons_el_hf_template_type" id="king_addons_el_hf_template_type">
322 <option value="king_addons_el_hf_not_selected" <?php selected($template_type, ''); ?>><?php esc_html_e('Select Option', 'king-addons'); ?></option>
323 <option value="king_addons_el_hf_type_header" <?php selected($template_type, 'king_addons_el_hf_type_header'); ?>><?php esc_html_e('Header', 'king-addons'); ?></option>
324 <option value="king_addons_el_hf_type_footer" <?php selected($template_type, 'king_addons_el_hf_type_footer'); ?>><?php esc_html_e('Footer', 'king-addons'); ?></option>
325 </select>
326 </td>
327 </tr>
328 <?php
329 $this->display_rules_tab();
330
331 ?>
332 <tr class="king-addons-el-hf-options-row enable-for-canvas">
333 <td class="king-addons-el-hf-options-row-heading">
334 <label for="king-addons-el-hf-display-on-canvas">
335 <strong><?php esc_html_e('Enable Layout for Elementor Canvas Template?', 'king-addons'); ?></strong>
336 </label>
337 <p><?php esc_html_e('Enabling this option will display this layout on pages using Elementor Canvas Template', 'king-addons'); ?></p>
338 </td>
339 <td class="king-addons-el-hf-options-row-content">
340 <input type="checkbox" id="king-addons-el-hf-display-on-canvas"
341 name="king-addons-el-hf-display-on-canvas"
342 value="1" <?php checked($display_on_canvas); ?> />
343 </td>
344 </tr>
345 </tbody>
346 </table>
347 <?php
348 }
349
350
351 public function admin_styles()
352 {
353 wp_enqueue_script('king-addons-el-hf-select2', KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/select2.js', array('jquery'), KING_ADDONS_VERSION, true);
354
355 wp_register_script(
356 'king-addons-el-hf-target-rule',
357 KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/conditions-target.js',
358 array(
359 'jquery',
360 'king-addons-el-hf-select2',
361 ),
362 KING_ADDONS_VERSION,
363 true
364 );
365
366 wp_enqueue_script('king-addons-el-hf-target-rule');
367
368 wp_register_script(
369 'king-addons-el-hf-user-role',
370 KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/conditions-user.js',
371 array(
372 'jquery',
373 ),
374 KING_ADDONS_VERSION,
375 true
376 );
377
378 wp_enqueue_script('king-addons-el-hf-user-role');
379
380 wp_register_style('king-addons-el-hf-select2', KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/select2.css', '', KING_ADDONS_VERSION);
381 wp_enqueue_style('king-addons-el-hf-select2');
382 wp_register_style('king-addons-el-hf-target-rule', KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/conditions.css', '', KING_ADDONS_VERSION);
383 wp_enqueue_style('king-addons-el-hf-target-rule');
384 wp_enqueue_script('king-addons-el-hf-script', KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/admin.js', array('jquery'), KING_ADDONS_VERSION);
385
386 $localize_vars = array(
387 'please_enter' => __('Please enter', 'king-addons'),
388 'please_delete' => __('Please delete', 'king-addons'),
389 'more_char' => __('or more characters', 'king-addons'),
390 'character' => __('character', 'king-addons'),
391 'loading' => __('Loading more results…', 'king-addons'),
392 'only_select' => __('You can only select', 'king-addons'),
393 'item' => __('item', 'king-addons'),
394 'char_s' => __('s', 'king-addons'),
395 'no_result' => __('No results found', 'king-addons'),
396 'searching' => __('Searching…', 'king-addons'),
397 'not_loader' => __('The results could not be loaded.', 'king-addons'),
398 'search' => __('Search pages / post / categories', 'king-addons'),
399 'ajax_nonce' => wp_create_nonce('king-addons-el-hf-get-posts-by-query'),
400 );
401 wp_localize_script('king-addons-el-hf-select2', 'kngRules', $localize_vars);
402
403 }
404
405 public function display_rules_tab()
406 {
407 $this->admin_styles();
408 $include_locations = get_post_meta(get_the_id(), 'king_addons_el_hf_target_include_locations', true);
409 $exclude_locations = get_post_meta(get_the_id(), 'king_addons_el_hf_target_exclude_locations', true);
410 $users = get_post_meta(get_the_id(), 'king_addons_el_hf_target_user_roles', true);
411 ?>
412 <tr class="king-addons-el-hf-target-rules-row king-addons-el-hf-options-row">
413 <td class="king-addons-el-hf-target-rules-row-heading king-addons-el-hf-options-row-heading">
414 <label><strong><?php esc_html_e('Display On', 'king-addons'); ?></strong></label>
415 <p><?php esc_html_e('Add locations for where this template should appear', 'king-addons'); ?></p>
416 </td>
417 <td class="king-addons-el-hf-target-rules-row-content king-addons-el-hf-options-row-content">
418 <?php
419 self::target_rule_settings_field(
420 'king-addons-el-hf-target-rules-location',
421 [
422 'title' => __('Display Rules', 'king-addons'),
423 'value' => '[{"type":"basic-global","specific":null}]',
424 'tags' => 'site,enable,target,pages',
425 'rule_type' => 'display',
426 'add_rule_label' => __('Add Display Rule', 'king-addons'),
427 ],
428 $include_locations
429 );
430 ?>
431 </td>
432 </tr>
433 <tr class="king-addons-el-hf-target-rules-row king-addons-el-hf-options-row">
434 <td class="king-addons-el-hf-target-rules-row-heading king-addons-el-hf-options-row-heading">
435 <label><strong><?php esc_html_e('Do Not Display On', 'king-addons'); ?></strong></label>
436 <p><?php esc_html_e('Add locations for where this template should not appear', 'king-addons'); ?></p>
437 </td>
438 <td class="king-addons-el-hf-target-rules-row-content king-addons-el-hf-options-row-content">
439 <?php
440 self::target_rule_settings_field(
441 'king-addons-el-hf-target-rules-exclusion',
442 [
443 'title' => __('Exclude On', 'king-addons'),
444 'value' => '[]',
445 'tags' => 'site,enable,target,pages',
446 'add_rule_label' => __('Add Exclusion Rule', 'king-addons'),
447 'rule_type' => 'exclude',
448 ],
449 $exclude_locations
450 );
451 ?>
452 </td>
453 </tr>
454 <tr class="king-addons-el-hf-target-rules-row king-addons-el-hf-options-row">
455 <td class="king-addons-el-hf-target-rules-row-heading king-addons-el-hf-options-row-heading">
456 <label><strong><?php esc_html_e('User Roles', 'king-addons'); ?></strong></label>
457 <p><?php esc_html_e('Display custom template based on user role', 'king-addons'); ?></p>
458 </td>
459 <td class="king-addons-el-hf-target-rules-row-content king-addons-el-hf-options-row-content">
460 <?php
461 self::target_user_role_settings_field(
462 'king-addons-el-hf-target-rules-users',
463 [
464 'title' => __('Users', 'king-addons'),
465 'value' => '[]',
466 'tags' => 'site,enable,target,pages',
467 'add_rule_label' => __('Add User Rule', 'king-addons'),
468 ],
469 $users
470 );
471 ?>
472 </td>
473 </tr>
474 <?php
475 }
476
477 public static function get_user_selections()
478 {
479 $selection_options = array(
480 'basic' => array(
481 'label' => __('Basic', 'king-addons'),
482 'value' => array(
483 'all' => __('All', 'king-addons'),
484 'logged-in' => __('Logged In', 'king-addons'),
485 'logged-out' => __('Logged Out', 'king-addons'),
486 ),
487 ),
488
489 'advanced' => array(
490 'label' => __('Advanced', 'king-addons'),
491 'value' => array(),
492 ),
493 );
494
495 /* User roles */
496 $roles = get_editable_roles();
497
498 foreach ($roles as $slug => $data) {
499 $selection_options['advanced']['value'][$slug] = $data['name'];
500 }
501
502 /**
503 * Filter options displayed in the user select field of Display conditions.
504 *
505 * @since 1.5.0
506 */
507 return apply_filters('king-addons-el-hf_user_roles_list', $selection_options);
508 }
509
510 public static function target_user_role_settings_field($name, $settings, $value)
511 {
512 $input_name = $name;
513 $add_rule_label = $settings['add_rule_label'] ?? __('Add Rule', 'king-addons');
514 $saved_values = $value;
515 $output = '';
516
517 if (!isset(self::$user_selection) || empty(self::$user_selection)) {
518 self::$user_selection = self::get_user_selections();
519 }
520 $selection_options = self::$user_selection;
521
522 $output .= '<script type="text/html" id="tmpl-king-addons-el-hf-user-role-condition">';
523 $output .= '<div class="king-addons-el-hf-user-role-condition king-addons-el-hf-user-role-{{data.id}}" data-rule="{{data.id}}" >';
524 $output .= '<span class="user_role-condition-delete dashicons dashicons-dismiss"></span>';
525
526 $output .= '<div class="user_role-condition-wrap" >';
527 $output .= '<select name="' . esc_attr($input_name) . '[{{data.id}}]" class="user_role-condition form-control king-addons-el-hf-input">';
528 $output .= '<option value="">' . __('Select', 'king-addons') . '</option>';
529
530 foreach ($selection_options as $group_data) {
531 $output .= '<optgroup label="' . $group_data['label'] . '">';
532 foreach ($group_data['value'] as $opt_key => $opt_value) {
533 $output .= '<option value="' . $opt_key . '">' . $opt_value . '</option>';
534 }
535 $output .= '</optgroup>';
536 }
537 $output .= '</select>';
538 $output .= '</div>';
539 $output .= '</div> <!-- king-addons-el-hf-user-role-condition -->';
540 $output .= '</script>';
541
542 /** @noinspection PhpConditionAlreadyCheckedInspection */
543 if (!is_array($saved_values) || (is_array($saved_values) && empty($saved_values))) {
544 $saved_values = array();
545 $saved_values[0] = '';
546 }
547
548 $index = 0;
549
550 $output .= '<div class="king-addons-el-hf-user-role-wrapper king-addons-el-hf-user-role-display-on-wrap" data-type="display">';
551 $output .= '<div class="king-addons-el-hf-user-role-selector-wrapper king-addons-el-hf-user-role-display-on">';
552 $output .= '<div class="user_role-builder-wrap">';
553 foreach ($saved_values as $index => $data) {
554 $output .= '<div class="king-addons-el-hf-user-role-condition king-addons-el-hf-user-role-' . $index . '" data-rule="' . $index . '" >';
555 $output .= '<span class="user_role-condition-delete dashicons dashicons-dismiss"></span>';
556 /* Condition Selection */
557 $output .= '<div class="user_role-condition-wrap" >';
558 $output .= '<select name="' . esc_attr($input_name) . '[' . $index . ']" class="user_role-condition form-control king-addons-el-hf-input">';
559 $output .= '<option value="">' . __('Select', 'king-addons') . '</option>';
560
561 foreach ($selection_options as $group_data) {
562 $output .= '<optgroup label="' . $group_data['label'] . '">';
563 foreach ($group_data['value'] as $opt_key => $opt_value) {
564 $output .= '<option value="' . $opt_key . '" ' . selected($data, $opt_key, false) . '>' . $opt_value . '</option>';
565 }
566 $output .= '</optgroup>';
567 }
568 $output .= '</select>';
569 $output .= '</div>';
570 $output .= '</div> <!-- king-addons-el-hf-user-role-condition -->';
571 }
572 $output .= '</div>';
573 /* Add new rule */
574 $output .= '<div class="user_role-add-rule-wrap">';
575 $output .= '<a href="#" class="button" data-rule-id="' . absint($index) . '">' . $add_rule_label . '</a>';
576 $output .= '</div>';
577 $output .= '</div>';
578 $output .= '</div>';
579
580 echo $output;
581 }
582
583 public static function target_rule_settings_field($name, $settings, $value)
584 {
585 $input_name = $name;
586 $rule_type = $settings['rule_type'] ?? 'target_rule';
587 $add_rule_label = $settings['add_rule_label'] ?? __('Add Rule', 'king-addons');
588 $saved_values = $value;
589 $output = '';
590
591 if (isset(self::$location_selection) || empty(self::$location_selection)) {
592 self::$location_selection = self::getLocationSelections();
593 }
594 $selection_options = self::$location_selection;
595
596 $output .= '<script type="text/html" id="tmpl-king-addons-el-hf-target-rule-' . $rule_type . '-condition">';
597
598 $output .= '<div class="king-addons-el-hf-target-rule-condition king-addons-el-hf-target-rule-{{data.id}}" data-rule="{{data.id}}" >';
599 $output .= '<span class="target_rule-condition-delete dashicons dashicons-dismiss"></span>';
600 $output .= '<div class="target_rule-condition-wrap" >';
601
602 $output .= '<select name="' . esc_attr($input_name) . '[rule][{{data.id}}]" class="target_rule-condition form-control king-addons-el-hf-input">';
603 $output .= '<option value="">' . __('Select', 'king-addons') . '</option>';
604
605 foreach ($selection_options as $group_data) {
606 $output .= '<optgroup label="' . $group_data['label'] . '">';
607 foreach ($group_data['value'] as $opt_key => $opt_value) {
608 $output .= '<option value="' . $opt_key . '">' . $opt_value . '</option>';
609 }
610 $output .= '</optgroup>';
611 }
612 $output .= '</select>';
613
614 $output .= '</div>';
615 $output .= '</div> <!-- king-addons-el-hf-target-rule-condition -->';
616
617 $output .= '<div class="target_rule-specific-page-wrap" style="display:none">';
618 $output .= '<select name="' . esc_attr($input_name) . '[specific][]" class="target-rule-select2 target_rule-specific-page form-control king-addons-el-hf-input " multiple="multiple">';
619 $output .= '</select>';
620 $output .= '</div>';
621
622 $output .= '</script>';
623
624 $output .= '<div class="king-addons-el-hf-target-rule-wrapper king-addons-el-hf-target-rule-' . $rule_type . '-on-wrap" data-type="' . $rule_type . '">';
625 $output .= '<div class="king-addons-el-hf-target-rule-selector-wrapper king-addons-el-hf-target-rule-' . $rule_type . '-on">';
626 $output .= self::generate_target_rule_selector($rule_type, $selection_options, $input_name, $saved_values, $add_rule_label);
627 $output .= '</div>';
628 $output .= '</div>';
629
630 echo $output;
631 }
632
633 public static function generate_target_rule_selector($type, $selection_options, $input_name, $saved_values, $add_rule_label)
634 {
635 $output = '<div class="target_rule-builder-wrap">';
636
637 /** @noinspection PhpConditionAlreadyCheckedInspection */
638 if (!is_array($saved_values) || (is_array($saved_values) && empty($saved_values))) {
639 $saved_values = array();
640 $saved_values['rule'][0] = '';
641 $saved_values['specific'][0] = '';
642 }
643
644 $index = 0;
645 if (is_array($saved_values) && is_array($saved_values['rule'])) {
646 foreach ($saved_values['rule'] as $index => $data) {
647 $output .= '<div class="king-addons-el-hf-target-rule-condition king-addons-el-hf-target-rule-' . $index . '" data-rule="' . $index . '" >';
648
649 $output .= '<span class="target_rule-condition-delete dashicons dashicons-dismiss"></span>';
650 $output .= '<div class="target_rule-condition-wrap" >';
651 $output .= '<select name="' . esc_attr($input_name) . '[rule][' . $index . ']" class="target_rule-condition form-control king-addons-el-hf-input">';
652 $output .= '<option value="">' . __('Select', 'king-addons') . '</option>';
653
654 foreach ($selection_options as $group_data) {
655 $output .= '<optgroup label="' . $group_data['label'] . '">';
656 foreach ($group_data['value'] as $opt_key => $opt_value) {
657
658 $selected = '';
659
660 if ($data == $opt_key) {
661 $selected = 'selected="selected"';
662 }
663
664 $output .= '<option value="' . $opt_key . '" ' . $selected . '>' . $opt_value . '</option>';
665 }
666 $output .= '</optgroup>';
667 }
668 $output .= '</select>';
669 $output .= '</div>';
670
671 $output .= '</div>';
672
673 $output .= '<div class="target_rule-specific-page-wrap" style="display:none">';
674 $output .= '<select name="' . esc_attr($input_name) . '[specific][]" class="target-rule-select2 target_rule-specific-page form-control king-addons-el-hf-input " multiple="multiple">';
675
676 if ('specifics' == $data && isset($saved_values['specific']) && null != $saved_values['specific'] && is_array($saved_values['specific'])) {
677 foreach ($saved_values['specific'] as $sel_value) {
678
679 if (strpos($sel_value, 'post-') !== false) {
680 $post_id = (int)str_replace('post-', '', $sel_value);
681 $post_title = get_the_title($post_id);
682 $output .= '<option value="post-' . $post_id . '" selected="selected" >' . $post_title . '</option>';
683 }
684
685 if (strpos($sel_value, 'tax-') !== false) {
686 $tax_data = explode('-', $sel_value);
687
688 $tax_id = (int)str_replace('tax-', '', $sel_value);
689 $term = get_term($tax_id);
690 $term_name = '';
691
692 if (!is_wp_error($term)) {
693 $term_taxonomy = ucfirst(str_replace('_', ' ', $term->taxonomy));
694
695 if (isset($tax_data[2]) && 'single' === $tax_data[2]) {
696 $term_name = 'All singulars from ' . $term->name;
697 } else {
698 $term_name = $term->name . ' - ' . $term_taxonomy;
699 }
700 }
701
702 $output .= '<option value="' . $sel_value . '" selected="selected" >' . $term_name . '</option>';
703 }
704 }
705 }
706 $output .= '</select>';
707 $output .= '</div>';
708 }
709 }
710
711 $output .= '</div>';
712
713 $output .= '<div class="target_rule-add-rule-wrap">';
714 $output .= '<a href="#" class="button" data-rule-id="' . absint($index) . '" data-rule-type="' . $type . '">' . $add_rule_label . '</a>';
715 $output .= '</div>';
716
717 if ('display' == $type) {
718 $output .= '<div class="target_rule-add-exclusion-rule">';
719 $output .= '<a href="#" class="button">' . __('Add Exclusion Rule', 'king-addons') . '</a>';
720 $output .= '</div>';
721 }
722
723 return $output;
724 }
725
726 function saveMetaboxData($post_id)
727 {
728 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
729 return;
730 }
731
732 if (!isset($_POST['king_addons_el_hf_meta_nounce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['king_addons_el_hf_meta_nounce'])), 'king_addons_el_hf_meta_nounce')) {
733 return;
734 }
735
736 if (!current_user_can('edit_posts')) {
737 return;
738 }
739
740 if (!isset($_POST['king-addons-el-hf-target-rules-location'])) {
741 $target_locations = array(
742 'rule' => array('basic-global'),
743 'specific' => array(),
744 );
745 } else {
746 $target_locations = self::getFormatRuleValue($_POST, 'king-addons-el-hf-target-rules-location');
747 if (empty($target_locations)) {
748 $target_locations = array(
749 'rule' => array('basic-global'),
750 'specific' => array(),
751 );
752 }
753 }
754
755 $target_exclusion = self::getFormatRuleValue($_POST, 'king-addons-el-hf-target-rules-exclusion');
756 $target_users = [];
757
758 if (isset($_POST['king-addons-el-hf-target-rules-users'])) {
759 $target_users = array_map('sanitize_text_field', wp_unslash($_POST['king-addons-el-hf-target-rules-users']));
760 }
761
762 update_post_meta($post_id, 'king_addons_el_hf_target_include_locations', $target_locations);
763 update_post_meta($post_id, 'king_addons_el_hf_target_exclude_locations', $target_exclusion);
764 update_post_meta($post_id, 'king_addons_el_hf_target_user_roles', $target_users);
765
766 if (isset($_POST['king_addons_el_hf_template_type'])) {
767 update_post_meta($post_id, 'king_addons_el_hf_template_type', sanitize_text_field(wp_unslash($_POST['king_addons_el_hf_template_type'])));
768 }
769
770 if (isset($_POST['king-addons-el-hf-display-on-canvas'])) {
771 update_post_meta($post_id, 'king-addons-el-hf-display-on-canvas', sanitize_text_field(wp_unslash($_POST['king-addons-el-hf-display-on-canvas'])));
772 } else {
773 delete_post_meta($post_id, 'king-addons-el-hf-display-on-canvas');
774 }
775 }
776
777 function setCompatibility()
778 {
779 $template = get_template();
780 $is_elementor_callable = defined('ELEMENTOR_VERSION') && is_callable('Elementor\Plugin::instance');
781
782 if ($is_elementor_callable) {
783 self::$elementor_instance = Elementor\Plugin::instance();
784
785 // TODO: Add popular themes
786 switch ($template) {
787 case 'hello-elementor':
788 require_once(KING_ADDONS_PATH . 'includes/extensions/Header_Footer_Builder/themes/hello-elementor/ELHF_Hello_Elementor.php');
789 break;
790 default:
791 add_action('init', [$this, 'setupSettingsPage']);
792 add_filter('king_addons_el_hf_settings_tabs', [$this, 'setupUnsupportedTheme']);
793 add_action('init', [$this, 'setupFallbackSupport']);
794 break;
795 }
796 }
797 }
798
799 public function setupUnsupportedTheme($settings_tabs = [])
800 {
801 if (!current_theme_supports('king-addons-elementor-header-footer')) {
802 $settings_tabs['king_addons_el_hf_settings'] = [
803 'name' => esc_html__('Display Settings', 'king-addons'),
804 'url' => admin_url('edit.php?post_type=king-addons-el-hf&page=king-addons-el-hf-settings'),
805 ];
806 }
807 return $settings_tabs;
808 }
809
810 public function setupFallbackSupport()
811 {
812 if (!current_theme_supports('king-addons-elementor-header-footer')) {
813 $compatibility_option = get_option('king_addons_el_hf_compatibility_option', '1');
814
815 if ('1' === $compatibility_option) {
816 if (!class_exists('ELHF_Default_Method_1')) {
817 require_once(KING_ADDONS_PATH . 'includes/extensions/Header_Footer_Builder/themes/default/ELHF_Default_Method_1.php');
818 }
819 } elseif ('2' === $compatibility_option) {
820 if (!class_exists('ELHF_Default_Method_2')) {
821 require_once(KING_ADDONS_PATH . 'includes/extensions/Header_Footer_Builder/themes/default/ELHF_Default_Method_2.php');
822 }
823 }
824 }
825 }
826
827 function setupSettingsPage()
828 {
829 require_once(KING_ADDONS_PATH . 'includes/extensions/Header_Footer_Builder/ELHF_Settings_Page.php');
830 }
831
832 public static function renderHeader()
833 {
834 /** @noinspection SpellCheckingInspection */
835 echo '<header id="masthead" itemscope="itemscope" itemtype="https://schema.org/WPHeader">';
836 ?><p class="main-title" style="display: none;" itemprop="headline"><a
837 href="<?php echo esc_url(get_bloginfo('url')); ?>"
838 title="<?php echo esc_attr(get_bloginfo('name', 'display')); ?>"
839 rel="home"><?php echo esc_html(get_bloginfo('name')); ?></a></p><?php
840 self::getHeaderContent();
841 echo '</header>';
842 }
843
844 public static function renderFooter()
845 {
846 /** @noinspection SpellCheckingInspection */
847 echo '<footer id="colophon" itemscope="itemscope" itemtype="https://schema.org/WPFooter" role="contentinfo">';
848 self::getFooterContent();
849 echo '</footer>';
850 }
851
852 public static function getHeaderContent()
853 {
854 $header_id = self::getHeaderID();
855 if ($header_id) {
856 echo self::$elementor_instance->frontend->get_builder_content_for_display($header_id); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
857 }
858 }
859
860 public static function getFooterContent()
861 {
862 $footer_id = self::getFooterID();
863 if ($footer_id) {
864 echo '<div style="width: 100%;">';
865 echo self::$elementor_instance->frontend->get_builder_content_for_display($footer_id); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
866 echo '</div>';
867 }
868 }
869
870 public static function getHeaderID()
871 {
872 $header_id = self::getSettings('king_addons_el_hf_type_header');
873
874 if ('' === $header_id) {
875 $header_id = false;
876 }
877
878 return apply_filters('king_addons_el_hf_get_header_id', $header_id);
879 }
880
881 public static function isHeaderEnabled()
882 {
883 $header_id = self::getSettings('king_addons_el_hf_type_header');
884 $status = false;
885
886 if ('' !== $header_id) {
887 $status = true;
888 }
889
890 return apply_filters('king_addons_el_hf_header_enabled', $status);
891 }
892
893 public static function isFooterEnabled()
894 {
895 $footer_id = self::getSettings('king_addons_el_hf_type_footer');
896 $status = false;
897
898 if ('' !== $footer_id) {
899 $status = true;
900 }
901
902 return apply_filters('king_addons_el_hf_footer_enabled', $status);
903 }
904
905 public static function getFooterID()
906 {
907 $footer_id = self::getSettings('king_addons_el_hf_type_footer');
908
909 if ('' === $footer_id) {
910 $footer_id = false;
911 }
912
913 return apply_filters('king_addons_el_hf_get_footer_id', $footer_id);
914 }
915
916
917 public static function getSettings($setting = '')
918 {
919 if ('king_addons_el_hf_type_header' == $setting || 'king_addons_el_hf_type_footer' == $setting) {
920 $templates = self::getTemplateID($setting);
921 $template = !is_array($templates) ? $templates : $templates[0];
922 return apply_filters("king_addons_el_hf_get_settings_$setting", $template);
923 }
924
925 return null;
926 }
927
928 public static function getTemplateID($type)
929 {
930 $option = [
931 'location' => 'king_addons_el_hf_target_include_locations',
932 'exclusion' => 'king_addons_el_hf_target_exclude_locations',
933 'users' => 'king_addons_el_hf_target_user_roles',
934 ];
935
936 $templates = self::getPostsByConditions('king-addons-el-hf', $option);
937
938 foreach ($templates as $template) {
939 if (get_post_meta(absint($template['id']), 'king_addons_el_hf_template_type', true) === $type) {
940 // Polylang check - https://polylang.pro/doc/function-reference/
941 if (function_exists('pll_current_language')) {
942 if (pll_current_language('slug') == pll_get_post_language($template['id'], 'slug')) {
943 return $template['id'];
944 }
945 } else {
946 return $template['id'];
947 }
948 }
949 }
950
951 return '';
952 }
953
954 public static function getPostsByConditions($post_type, $option)
955 {
956 global $wpdb;
957 global $post;
958
959 // Security fix: Validate and sanitize post_type
960 $post_type = $post_type ? sanitize_key($post_type) : sanitize_key($post->post_type);
961 if (empty($post_type)) {
962 return [];
963 }
964
965 if (is_array(self::$current_page_data) && isset(self::$current_page_data[$post_type])) {
966 return apply_filters('king_addons_el_hf_get_display_posts_by_conditions', self::$current_page_data[$post_type], $post_type);
967 }
968
969 $current_page_type = self::getCurrentPageType();
970
971 self::$current_page_data[$post_type] = array();
972
973 $option['current_post_id'] = self::$current_page_data['ID'];
974 $meta_header = self::getMetaOptionPost($post_type, $option);
975
976 if (false === $meta_header) {
977 $current_post_type = sanitize_key(get_post_type());
978 $current_post_id = false;
979 $q_obj = get_queried_object();
980
981 $current_id = absint(get_the_id());
982
983 // Check if WPML is active. Find WPML Object ID for current page.
984 /** @noinspection SpellCheckingInspection */
985 if (defined('ICL_SITEPRESS_VERSION')) {
986 $default_lang = apply_filters('wpml_default_language', '');
987 $current_lang = apply_filters('wpml_current_language', '');
988
989 if ($default_lang !== $current_lang) {
990 $current_post_type = get_post_type($current_id);
991 $current_id = apply_filters('wpml_object_id', $current_id, $current_post_type, true, $default_lang);
992 }
993 }
994
995 // Security fix: Sanitize location parameter
996 $location = isset($option['location']) ? sanitize_key($option['location']) : '';
997 if (empty($location)) {
998 return [];
999 }
1000
1001 // Security fix: Use prepared statement to prevent SQL injection
1002 $query = $wpdb->prepare(
1003 "SELECT p.ID, pm.meta_value FROM {$wpdb->postmeta} as pm
1004 INNER JOIN {$wpdb->posts} as p ON pm.post_id = p.ID
1005 WHERE pm.meta_key = %s
1006 AND p.post_type = %s
1007 AND p.post_status = 'publish'",
1008 $location,
1009 $post_type
1010 );
1011
1012 $orderby = ' ORDER BY p.post_date DESC';
1013
1014 // Security fix: Build meta_args using safe placeholders and prepared statements
1015 $meta_conditions = ["pm.meta_value LIKE %s"];
1016 $meta_values = ['%"basic-global"%'];
1017
1018 switch ($current_page_type) {
1019 case 'is_404':
1020 $meta_conditions[] = "pm.meta_value LIKE %s";
1021 $meta_values[] = '%"special-404"%';
1022 break;
1023 case 'is_search':
1024 $meta_conditions[] = "pm.meta_value LIKE %s";
1025 $meta_values[] = '%"special-search"%';
1026 break;
1027 case 'is_archive':
1028 case 'is_tax':
1029 case 'is_date':
1030 case 'is_author':
1031 $meta_conditions[] = "pm.meta_value LIKE %s";
1032 $meta_values[] = '%"basic-archives"%';
1033 $meta_conditions[] = "pm.meta_value LIKE %s";
1034 $meta_values[] = '%"' . sanitize_key($current_post_type) . '|all|archive"%';
1035
1036 if ('is_tax' == $current_page_type && (is_category() || is_tag() || is_tax())) {
1037 if (is_object($q_obj) && isset($q_obj->taxonomy) && isset($q_obj->term_id)) {
1038 $meta_conditions[] = "pm.meta_value LIKE %s";
1039 $meta_values[] = '%"' . sanitize_key($current_post_type) . '|all|taxarchive|' . sanitize_key($q_obj->taxonomy) . '"%';
1040 $meta_conditions[] = "pm.meta_value LIKE %s";
1041 $meta_values[] = '%"tax-' . absint($q_obj->term_id) . '"%';
1042 }
1043 } elseif ('is_date' == $current_page_type) {
1044 $meta_conditions[] = "pm.meta_value LIKE %s";
1045 $meta_values[] = '%"special-date"%';
1046 } elseif ('is_author' == $current_page_type) {
1047 $meta_conditions[] = "pm.meta_value LIKE %s";
1048 $meta_values[] = '%"special-author"%';
1049 }
1050 break;
1051 case 'is_home':
1052 $meta_conditions[] = "pm.meta_value LIKE %s";
1053 $meta_values[] = '%"special-blog"%';
1054 break;
1055 case 'is_front_page':
1056 $current_post_id = $current_id;
1057 $meta_conditions[] = "pm.meta_value LIKE %s";
1058 $meta_values[] = '%"special-front"%';
1059 $meta_conditions[] = "pm.meta_value LIKE %s";
1060 $meta_values[] = '%"' . sanitize_key($current_post_type) . '|all"%';
1061 $meta_conditions[] = "pm.meta_value LIKE %s";
1062 $meta_values[] = '%"post-' . absint($current_id) . '"%';
1063 break;
1064 case 'is_singular':
1065 $current_post_id = $current_id;
1066 $meta_conditions[] = "pm.meta_value LIKE %s";
1067 $meta_values[] = '%"basic-singulars"%';
1068 $meta_conditions[] = "pm.meta_value LIKE %s";
1069 $meta_values[] = '%"' . sanitize_key($current_post_type) . '|all"%';
1070 $meta_conditions[] = "pm.meta_value LIKE %s";
1071 $meta_values[] = '%"post-' . absint($current_id) . '"%';
1072
1073 if (is_object($q_obj) && isset($q_obj->post_type) && isset($q_obj->ID)) {
1074 $taxonomies = get_object_taxonomies($q_obj->post_type);
1075 $terms = wp_get_post_terms($q_obj->ID, $taxonomies);
1076 foreach ($terms as $term) {
1077 if (isset($term->term_id) && isset($term->taxonomy)) {
1078 $meta_conditions[] = "pm.meta_value LIKE %s";
1079 $meta_values[] = '%"tax-' . absint($term->term_id) . '-single-' . sanitize_key($term->taxonomy) . '"%';
1080 }
1081 }
1082 }
1083 break;
1084 case 'is_woo_shop_page':
1085 if (function_exists('is_shop')) {
1086 $meta_conditions[] = "pm.meta_value LIKE %s";
1087 $meta_values[] = '%"special-woocommerce-shop"%';
1088 }
1089 break;
1090 case '':
1091 $current_post_id = $current_id;
1092 break;
1093 }
1094
1095 // Build the final meta_args string using prepare
1096 $meta_args = '(' . implode(' OR ', $meta_conditions) . ')';
1097
1098 // Security fix: Use prepared statement for the complete query
1099 $full_query = $wpdb->prepare(
1100 $query . ' AND ' . $meta_args . $orderby,
1101 ...$meta_values
1102 );
1103
1104 $posts = $wpdb->get_results($full_query);
1105
1106 foreach ($posts as $local_post) {
1107 $unserialized_location = maybe_unserialize($local_post->meta_value);
1108 if ($unserialized_location !== false) {
1109 self::$current_page_data[$post_type][$local_post->ID] = array(
1110 'id' => $local_post->ID,
1111 'location' => $unserialized_location,
1112 );
1113 }
1114 }
1115
1116 $option['current_post_id'] = $current_post_id;
1117
1118 self::removeExclusionRulePosts($post_type, $option);
1119 self::removeUserRulePosts($post_type, $option);
1120 }
1121
1122 return apply_filters('king_addons_el_hf_get_display_posts_by_conditions', self::$current_page_data[$post_type], $post_type);
1123 }
1124
1125 public static function getCurrentPageType(): ?string
1126 {
1127 if (null === self::$current_page_type) {
1128 $page_type = '';
1129 $current_id = false;
1130
1131 if (is_404()) {
1132 $page_type = 'is_404';
1133 } elseif (is_search()) {
1134 $page_type = 'is_search';
1135 } elseif (is_archive()) {
1136 $page_type = 'is_archive';
1137 if (is_category() || is_tag() || is_tax()) {
1138 $page_type = 'is_tax';
1139 } elseif (is_date()) {
1140 $page_type = 'is_date';
1141 } elseif (is_author()) {
1142 $page_type = 'is_author';
1143 } elseif (function_exists('is_shop')) {
1144 /** @noinspection PhpUndefinedFunctionInspection */
1145 if (is_shop()) {
1146 $page_type = 'is_woo_shop_page';
1147 }
1148 }
1149 } elseif (is_home()) {
1150 $page_type = 'is_home';
1151 } elseif (is_front_page()) {
1152 $page_type = 'is_front_page';
1153 $current_id = get_the_id();
1154 } elseif (is_singular()) {
1155 $page_type = 'is_singular';
1156 $current_id = get_the_id();
1157 } else {
1158 $current_id = get_the_id();
1159 }
1160
1161 self::$current_page_data['ID'] = $current_id;
1162 self::$current_page_type = $page_type;
1163 }
1164
1165 return self::$current_page_type;
1166 }
1167
1168 public static function getMetaOptionPost($post_type, $option)
1169 {
1170 $page_meta = (isset($option['page_meta']) && '' != $option['page_meta']) ? $option['page_meta'] : false;
1171
1172 if (false !== $page_meta) {
1173 $current_post_id = $option['current_post_id'] ?? false;
1174 $meta_id = get_post_meta($current_post_id, $option['page_meta'], true);
1175
1176 if (false !== $meta_id && '' != $meta_id) {
1177 self::$current_page_data[$post_type][$meta_id] = array(
1178 'id' => $meta_id,
1179 'location' => '',
1180 );
1181
1182 return self::$current_page_data[$post_type];
1183 }
1184 }
1185
1186 return false;
1187 }
1188
1189 public static function removeExclusionRulePosts($post_type, $option)
1190 {
1191 $exclusion = $option['exclusion'] ?? '';
1192 $current_post_id = $option['current_post_id'] ?? false;
1193 foreach (self::$current_page_data[$post_type] as $c_post_id => $c_data) {
1194 $exclusion_rules = get_post_meta($c_post_id, $exclusion, true);
1195 $is_exclude = self::parseLayoutDisplayCondition($current_post_id, $exclusion_rules);
1196 if ($is_exclude) {
1197 unset(self::$current_page_data[$post_type][$c_post_id]);
1198 }
1199 }
1200 }
1201
1202 public static function removeUserRulePosts($post_type, $option)
1203 {
1204 $users = $option['users'] ?? '';
1205
1206 foreach (self::$current_page_data[$post_type] as $c_post_id => $c_data) {
1207 $user_rules = get_post_meta($c_post_id, $users, true);
1208 $is_user = self::parseUserRoleCondition($user_rules);
1209
1210 if (!$is_user) {
1211 unset(self::$current_page_data[$post_type][$c_post_id]);
1212 }
1213 }
1214 }
1215
1216 public static function parseLayoutDisplayCondition($post_id, $rules): bool
1217 {
1218 $display = false;
1219
1220 /** @noinspection PhpConditionCheckedByNextConditionInspection */
1221 if (isset($rules['rule']) && is_array($rules['rule']) && !empty($rules['rule'])) {
1222 foreach ($rules['rule'] as $rule) {
1223 if (strrpos($rule, 'all') !== false) {
1224 $rule_case = 'all';
1225 } else {
1226 $rule_case = $rule;
1227 }
1228
1229 switch ($rule_case) {
1230 case 'basic-global':
1231 $display = true;
1232 break;
1233
1234 case 'basic-singulars':
1235 if (is_singular()) {
1236 $display = true;
1237 }
1238 break;
1239
1240 case 'basic-archives':
1241 if (is_archive()) {
1242 $display = true;
1243 }
1244 break;
1245
1246 case 'special-404':
1247 if (is_404()) {
1248 $display = true;
1249 }
1250 break;
1251
1252 case 'special-search':
1253 if (is_search()) {
1254 $display = true;
1255 }
1256 break;
1257
1258 case 'special-blog':
1259 if (is_home()) {
1260 $display = true;
1261 }
1262 break;
1263
1264 case 'special-front':
1265 if (is_front_page()) {
1266 $display = true;
1267 }
1268 break;
1269
1270 case 'special-date':
1271 if (is_date()) {
1272 $display = true;
1273 }
1274 break;
1275
1276 case 'special-author':
1277 if (is_author()) {
1278 $display = true;
1279 }
1280 break;
1281
1282 case 'special-woocommerce-shop':
1283 if (function_exists('is_shop')) {
1284 if (is_shop()) {
1285 $display = true;
1286 }
1287 }
1288 break;
1289
1290 case 'all':
1291 $rule_data = explode('|', $rule);
1292
1293 $post_type = $rule_data[0] ?? false;
1294 $archive_type = $rule_data[2] ?? false;
1295 $taxonomy = $rule_data[3] ?? false;
1296 if (false === $archive_type) {
1297 $current_post_type = get_post_type($post_id);
1298 if (false !== $post_id && $current_post_type == $post_type) {
1299 $display = true;
1300 }
1301 } else {
1302 if (is_archive()) {
1303 $current_post_type = get_post_type();
1304 if ($current_post_type == $post_type) {
1305 if ('archive' == $archive_type) {
1306 $display = true;
1307 } elseif ('taxarchive' == $archive_type) {
1308 $obj = get_queried_object();
1309 $current_taxonomy = '';
1310 if ('' !== $obj && null !== $obj) {
1311 $current_taxonomy = $obj->taxonomy;
1312 }
1313
1314 if ($current_taxonomy == $taxonomy) {
1315 $display = true;
1316 }
1317 }
1318 }
1319 }
1320 }
1321 break;
1322
1323 case 'specifics':
1324 if (isset($rules['specific']) && is_array($rules['specific'])) {
1325 foreach ($rules['specific'] as $specific_page) {
1326 $specific_data = explode('-', $specific_page);
1327 $specific_post_type = $specific_data[0] ?? false;
1328 $specific_post_id = $specific_data[1] ?? false;
1329 if ('post' == $specific_post_type) {
1330 if ($specific_post_id == $post_id) {
1331 $display = true;
1332 }
1333 } elseif (isset($specific_data[2]) && ('single' == $specific_data[2]) && 'tax' == $specific_post_type) {
1334 if (is_singular()) {
1335 $term_details = get_term($specific_post_id);
1336
1337 if (isset($term_details->taxonomy)) {
1338 $has_term = has_term((int)$specific_post_id, $term_details->taxonomy, $post_id);
1339
1340 if ($has_term) {
1341 $display = true;
1342 }
1343 }
1344 }
1345 } elseif ('tax' == $specific_post_type) {
1346 $tax_id = get_queried_object_id();
1347 if ($specific_post_id == $tax_id) {
1348 $display = true;
1349 }
1350 }
1351 }
1352 }
1353 break;
1354
1355 default:
1356 break;
1357 }
1358
1359 if ($display) {
1360 break;
1361 }
1362 }
1363 }
1364
1365 return $display;
1366 }
1367
1368 public static function parseUserRoleCondition($rules): bool
1369 {
1370 $show_popup = true;
1371
1372 if (is_array($rules) && !empty($rules)) {
1373 $show_popup = false;
1374
1375 foreach ($rules as $rule) {
1376 switch ($rule) {
1377 case '':
1378 case 'all':
1379 $show_popup = true;
1380 break;
1381
1382 case 'logged-in':
1383 if (is_user_logged_in()) {
1384 $show_popup = true;
1385 }
1386 break;
1387
1388 case 'logged-out':
1389 if (!is_user_logged_in()) {
1390 $show_popup = true;
1391 }
1392 break;
1393
1394 default:
1395 if (is_user_logged_in()) {
1396 $current_user = wp_get_current_user();
1397
1398 if (isset($current_user->roles)
1399 && is_array($current_user->roles)
1400 && in_array($rule, $current_user->roles)
1401 ) {
1402 $show_popup = true;
1403 }
1404 }
1405 break;
1406 }
1407
1408 if ($show_popup) {
1409 break;
1410 }
1411 }
1412 }
1413
1414 return $show_popup;
1415 }
1416
1417 public static function checkUserCanEdit()
1418 {
1419 if (is_singular('king-addons-el-hf') && !current_user_can('edit_posts')) {
1420 wp_redirect(site_url(), 301);
1421 die;
1422 }
1423 }
1424
1425 public static function loadElementorCanvasTemplate($single_template)
1426 {
1427 global $post;
1428
1429 if ('king-addons-el-hf' == $post->post_type) {
1430 if (defined('ELEMENTOR_VERSION')) {
1431 $elementor_2_0_canvas = ELEMENTOR_PATH . '/modules/page-templates/templates/canvas.php';
1432
1433 if (file_exists($elementor_2_0_canvas)) {
1434 return $elementor_2_0_canvas;
1435 } else {
1436 return ELEMENTOR_PATH . '/includes/page-templates/canvas.php';
1437 }
1438 }
1439 }
1440
1441 return $single_template;
1442 }
1443
1444 public static function enqueueScripts(): void
1445 {
1446 $screen = get_current_screen();
1447 if ($screen->id === 'edit-king-addons-el-hf') {
1448 // todo - styles
1449 // wp_enqueue_style('king-addons-el-hf-style', KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/header-footer-builder.css', '', KING_ADDONS_VERSION);
1450 wp_enqueue_style('king-addons-el-hf-style', KING_ADDONS_URL . 'includes/extensions/Header_Footer_Builder/admin.css', '', KING_ADDONS_VERSION);
1451 }
1452 }
1453
1454 public static function columnHeadings($columns)
1455 {
1456 unset($columns['date']);
1457 $columns['king_addons_el_hf_edit_template'] = esc_html__('Edit Template', 'king-addons');
1458 $columns['king_addons_el_hf_type_of_template'] = esc_html__('Type of Template', 'king-addons');
1459 $columns['king_addons_el_hf_display_rules'] = esc_html__('Display Rules', 'king-addons');
1460 $columns['date'] = esc_html__('Date', 'king-addons');
1461 return $columns;
1462 }
1463
1464 public static function columnContent($column, $post_id)
1465 {
1466 // Edit Template
1467 if ('king_addons_el_hf_edit_template' === $column) {
1468 echo '<a class="king-addons-el-hf-edit-template-btn" href="';
1469 echo './post.php?post=' . esc_attr($post_id) . '&action=edit';
1470 echo '">' . esc_html__('Edit Template', 'king-addons') . '</a>';
1471 }
1472
1473 // Display Rules
1474 if ('king_addons_el_hf_display_rules' === $column) {
1475
1476 $locations = get_post_meta($post_id, 'king_addons_el_hf_target_include_locations', true);
1477 if (!empty($locations)) {
1478 echo '<div style="margin-bottom: 5px;">';
1479 echo '<strong>';
1480 echo esc_html__('Display: ', 'king-addons');
1481 echo '</strong>';
1482 self::columnDisplayLocation($locations);
1483 echo '</div>';
1484 }
1485
1486 $locations = get_post_meta($post_id, 'king_addons_el_hf_target_exclude_locations', true);
1487 if (!empty($locations)) {
1488 echo '<div style="margin-bottom: 5px;">';
1489 echo '<strong>';
1490 echo esc_html__('Exclusion: ', 'king-addons');
1491 echo '</strong>';
1492 self::columnDisplayLocation($locations);
1493 echo '</div>';
1494 }
1495
1496 $users = get_post_meta($post_id, 'king_addons_el_hf_target_user_roles', true);
1497 if (isset($users) && is_array($users)) {
1498 if (!empty($users[0])) {
1499 $user_label = [];
1500 foreach ($users as $user) {
1501 $user_label[] = self::get_user_by_key($user);
1502 }
1503 echo '<div>';
1504 echo '<strong>Users: </strong>';
1505 echo esc_html(join(', ', $user_label));
1506 echo '</div>';
1507 }
1508 }
1509
1510 }
1511
1512 // Type of Template
1513 if ('king_addons_el_hf_type_of_template' === $column) {
1514 $template_type = get_post_meta($post_id, 'king_addons_el_hf_template_type', true);
1515 if (!empty($template_type)) {
1516 echo '<div style="margin-bottom: 5px;">';
1517 echo '<strong>';
1518 switch ($template_type) {
1519 case 'king_addons_el_hf_type_header':
1520 echo esc_html__('Header', 'king-addons');
1521 break;
1522 case 'king_addons_el_hf_type_footer':
1523 echo esc_html__('Footer', 'king-addons');
1524 break;
1525 default:
1526 echo esc_html__('Not selected', 'king-addons');
1527 break;
1528 }
1529 echo '</strong>';
1530 echo '</div>';
1531 }
1532 }
1533 }
1534
1535 public static function get_user_by_key($key)
1536 {
1537 if (!isset(self::$user_selection) || empty(self::$user_selection)) {
1538 self::$user_selection = self::get_user_selections();
1539 }
1540 $user_selection = self::$user_selection;
1541
1542 if (isset($user_selection['basic']['value'][$key])) {
1543 return $user_selection['basic']['value'][$key];
1544 } elseif ($user_selection['advanced']['value'][$key]) {
1545 return $user_selection['advanced']['value'][$key];
1546 }
1547 return $key;
1548 }
1549
1550 public static function columnDisplayLocation($locations)
1551 {
1552 $location_label = [];
1553 /** @noinspection PhpConditionAlreadyCheckedInspection */
1554 if (is_array($locations) && is_array($locations['rule']) && isset($locations['rule'])) {
1555 /** @noinspection PhpArraySearchInBooleanContextInspection */
1556 $index = array_search('specifics', $locations['rule']);
1557 /** @noinspection PhpConditionCheckedByNextConditionInspection */
1558 if (false !== $index && !empty($index)) {
1559 unset($locations['rule'][$index]);
1560 }
1561 }
1562
1563 if (isset($locations['rule']) && is_array($locations['rule'])) {
1564 foreach ($locations['rule'] as $location) {
1565 $location_label[] = self::getLocation($location);
1566 }
1567 }
1568
1569 if (isset($locations['specific']) && is_array($locations['specific'])) {
1570 foreach ($locations['specific'] as $location) {
1571 $location_label[] = self::getLocation($location);
1572 }
1573 }
1574
1575 echo esc_html(join(', ', $location_label));
1576 }
1577
1578 public static function getLocation($key)
1579 {
1580 if (!isset(self::$location_selection) || empty(self::$location_selection)) {
1581 self::$location_selection = self::getLocationSelections();
1582 }
1583
1584 $location_selection = self::$location_selection;
1585
1586 foreach ($location_selection as $location_grp) {
1587 if (isset($location_grp['value'][$key])) {
1588 return $location_grp['value'][$key];
1589 }
1590 }
1591
1592 if (strpos($key, 'post-') !== false) {
1593 $post_id = (int)str_replace('post-', '', $key);
1594 return get_the_title($post_id);
1595 }
1596
1597 if (strpos($key, 'tax-') !== false) {
1598 $tax_id = (int)str_replace('tax-', '', $key);
1599 $term = get_term($tax_id);
1600
1601 if (!is_wp_error($term)) {
1602 $term_taxonomy = ucfirst(str_replace('_', ' ', $term->taxonomy));
1603 return $term->name . ' - ' . $term_taxonomy;
1604 } else {
1605 return '';
1606 }
1607 }
1608
1609 return $key;
1610 }
1611
1612 public static function getLocationSelections()
1613 {
1614 $args = array(
1615 'public' => true,
1616 '_builtin' => true,
1617 );
1618
1619 $post_types = get_post_types($args, 'objects');
1620 unset($post_types['attachment']);
1621
1622 $args['_builtin'] = false;
1623 $custom_post_type = get_post_types($args, 'objects');
1624
1625 $post_types = apply_filters('king_addons_el_hf_location_rule_post_types', array_merge($post_types, $custom_post_type));
1626
1627 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
1628 $special_pages = array(
1629 'special-404-none' => esc_html__('404 Page (Available in PRO)', 'king-addons'),
1630 'special-search' => esc_html__('Search Page', 'king-addons'),
1631 'special-blog-none' => esc_html__('Blog / Posts Page (Available in PRO)', 'king-addons'),
1632 'special-front' => esc_html__('Front Page', 'king-addons'),
1633 'special-date' => esc_html__('Date Archive', 'king-addons'),
1634 'special-author' => esc_html__('Author Archive', 'king-addons'),
1635 );
1636 } else {
1637 $special_pages = array(
1638 'special-404' => esc_html__('404 Page', 'king-addons'),
1639 'special-search' => esc_html__('Search Page', 'king-addons'),
1640 'special-blog' => esc_html__('Blog / Posts Page', 'king-addons'),
1641 'special-front' => esc_html__('Front Page', 'king-addons'),
1642 'special-date' => esc_html__('Date Archive', 'king-addons'),
1643 'special-author' => esc_html__('Author Archive', 'king-addons'),
1644 );
1645 }
1646
1647 if (class_exists('WooCommerce')) {
1648 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
1649 $special_pages['special-woocommerce-shop-none'] = esc_html__('WooCommerce Shop Page (Available in PRO)', 'king-addons');
1650 } else {
1651 $special_pages['special-woocommerce-shop'] = esc_html__('WooCommerce Shop Page', 'king-addons');
1652 }
1653 }
1654
1655 $selection_options = array(
1656 'basic' => array(
1657 'label' => esc_html__('Basic', 'king-addons'),
1658 'value' => array(
1659 'basic-global' => esc_html__('Entire Website', 'king-addons'),
1660 'basic-singulars' => esc_html__('All Singulars', 'king-addons'),
1661 'basic-archives' => esc_html__('All Archives', 'king-addons'),
1662 ),
1663 ),
1664
1665 'special-pages' => array(
1666 'label' => esc_html__('Special Pages', 'king-addons'),
1667 'value' => $special_pages,
1668 ),
1669 );
1670
1671 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
1672 $selection_options['specific-target'] = array(
1673 'label' => esc_html__('Specific Target', 'king-addons'),
1674 'value' => array(
1675 'specifics-none' => esc_html__('Specific Pages / Posts / Taxonomies, etc. (Available in PRO)', 'king-addons'),
1676 ),
1677 );
1678 } else {
1679 $selection_options['specific-target'] = array(
1680 'label' => esc_html__('Specific Target', 'king-addons'),
1681 'value' => array(
1682 'specifics' => esc_html__('Specific Pages / Posts / Taxonomies, etc.', 'king-addons'),
1683 ),
1684 );
1685 }
1686
1687 $args = array(
1688 'public' => true,
1689 );
1690
1691 $taxonomies = get_taxonomies($args, 'objects');
1692
1693 if (!empty($taxonomies)) {
1694 foreach ($taxonomies as $taxonomy) {
1695
1696 if ('post_format' == $taxonomy->name) {
1697 continue;
1698 }
1699
1700 foreach ($post_types as $post_type) {
1701 $post_opt = self::getPostTargetRuleOptions($post_type, $taxonomy);
1702
1703 if (isset($selection_options[$post_opt['post_key']])) {
1704 if (!empty($post_opt['value']) && is_array($post_opt['value'])) {
1705 foreach ($post_opt['value'] as $key => $value) {
1706 if (!in_array($value, $selection_options[$post_opt['post_key']]['value'])) {
1707 $selection_options[$post_opt['post_key']]['value'][$key] = $value;
1708 }
1709 }
1710 }
1711 } else {
1712 $selection_options[$post_opt['post_key']] = array(
1713 'label' => $post_opt['label'],
1714 'value' => $post_opt['value'],
1715 );
1716 }
1717 }
1718 }
1719 }
1720
1721 return apply_filters('king_addons_el_hf_display_on_list', $selection_options);
1722 }
1723
1724 public static function getPostTargetRuleOptions($post_type, $taxonomy): array
1725 {
1726 $post_key = str_replace(' ', '-', strtolower($post_type->label));
1727 $post_label = ucwords($post_type->label);
1728 $post_name = $post_type->name;
1729 $post_option = array();
1730
1731 /* translators: %s is post label */
1732 $all_posts = sprintf(esc_html__('All %s', 'king-addons'), $post_label);
1733 $post_option[$post_name . '|all'] = $all_posts;
1734
1735 if ('pages' != $post_key) {
1736 /* translators: %s is post label */
1737 $all_archive = sprintf(esc_html__('All %s Archive', 'king-addons'), $post_label);
1738 $post_option[$post_name . '|all|archive'] = $all_archive;
1739 }
1740
1741 if (in_array($post_type->name, $taxonomy->object_type)) {
1742 $tax_label = ucwords($taxonomy->label);
1743 $tax_name = $taxonomy->name;
1744
1745 /* translators: %s is taxonomy label */
1746 $tax_archive = sprintf(esc_html__('All %s Archive', 'king-addons'), $tax_label);
1747
1748 $post_option[$post_name . '|all|taxarchive|' . $tax_name] = $tax_archive;
1749 }
1750
1751 $post_output['post_key'] = $post_key;
1752 $post_output['label'] = $post_label;
1753 $post_output['value'] = $post_option;
1754
1755 return $post_output;
1756 }
1757
1758 public static function getFormatRuleValue($save_data, $key): array
1759 {
1760 $meta_value = array();
1761
1762 if (isset($save_data[$key]['rule'])) {
1763 $save_data[$key]['rule'] = array_unique($save_data[$key]['rule']);
1764 if (isset($save_data[$key]['specific'])) {
1765 $save_data[$key]['specific'] = array_unique($save_data[$key]['specific']);
1766 }
1767
1768 $index = array_search('', $save_data[$key]['rule']);
1769 if (false !== $index) {
1770 unset($save_data[$key]['rule'][$index]);
1771 }
1772 $index = array_search('specifics', $save_data[$key]['rule']);
1773 if (false !== $index) {
1774 unset($save_data[$key]['rule'][$index]);
1775
1776 if (isset($save_data[$key]['specific']) && is_array($save_data[$key]['specific'])) {
1777 $save_data[$key]['rule'][] = 'specifics';
1778 }
1779 }
1780
1781 foreach ($save_data[$key] as $meta_key => $value) {
1782 if (!empty($value)) {
1783 $meta_value[$meta_key] = array_map('esc_attr', $value);
1784 }
1785 }
1786 if (!isset($meta_value['rule']) || !in_array('specifics', $meta_value['rule'])) {
1787 $meta_value['specific'] = array();
1788 }
1789
1790 if (empty($meta_value['rule'])) {
1791 $meta_value = array();
1792 }
1793 }
1794
1795 return $meta_value;
1796 }
1797 }