Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/royal-elementor-addons/admin/mega-menu.php
+++ b/royal-elementor-addons/admin/mega-menu.php
@@ -1,6 +1,10 @@
<?php
use WprAddonsPlugin;
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
// Register Post Type
function register_mega_menu_cpt() {
$args = array(
--- a/royal-elementor-addons/admin/metabox/wpr-secondary-image.php
+++ b/royal-elementor-addons/admin/metabox/wpr-secondary-image.php
@@ -21,7 +21,7 @@
global $content_width, $_wp_additional_image_sizes;
$image_id = get_post_meta( $post->ID, 'wpr_secondary_image_id', true );
- $content = '';
+ $content = '';
$old_content_width = $content_width;
$content_width = 254;
@@ -49,7 +49,7 @@
}
- echo wp_kses_post( $content );
+ echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Admin metabox markup: wp_get_attachment_image() core output and escaped literals; wp_kses_post() strips required hidden input.
}
add_action( 'save_post', 'secondary_image_save', 10, 1 );
--- a/royal-elementor-addons/admin/plugin-options.php
+++ b/royal-elementor-addons/admin/plugin-options.php
@@ -58,6 +58,13 @@
register_setting ('wpr-settings', 'wpr_hide_banners');
register_setting ('wpr-settings', 'wpr_hide_head_foot_on_maintenenace');
+ // Bundled ACF (Expert / Pro)
+ $bundled_acf_args = [ 'default' => 'on' ];
+ if ( function_exists( 'wpr_sanitize_bundled_acf_option' ) ) {
+ $bundled_acf_args['sanitize_callback'] = 'wpr_sanitize_bundled_acf_option';
+ }
+ register_setting( 'wpr-settings', 'wpr-bundled-acf', $bundled_acf_args );
+
// WooCommerce
register_setting( 'wpr-settings', 'wpr_override_woo_templates' );
register_setting( 'wpr-settings', 'wpr_override_woo_cart' );
@@ -506,6 +513,17 @@
<input type="checkbox" name="wpr_hide_head_foot_on_maintenenace" id="wpr_hide_head_foot_on_maintenenace" <?php echo checked( get_option('wpr_hide_head_foot_on_maintenenace', 'on'), 'on', true ); ?>>
<label for="wpr_hide_head_foot_on_maintenenace"></label>
</div>
+
+ <?php if ( defined( 'WPR_ADDONS_PRO_VERSION' ) && function_exists( 'wpr_fs' ) && wpr_fs()->is_plan( 'expert' ) ) : ?>
+ <div class="wpr-woo-template-info">
+ <div class="wpr-woo-template-title">
+ <h4><?php esc_html_e( 'Bundled ACF', 'wpr-addons' ); ?></h4>
+ <span><?php esc_html_e( 'Load bundled Advanced Custom Fields from Royal Addons Pro. Disable when using a standalone ACF / ACF Pro plugin.', 'wpr-addons' ); ?></span>
+ </div>
+ <input type="checkbox" name="wpr-bundled-acf" id="wpr-bundled-acf" value="on" <?php echo checked( get_option( 'wpr-bundled-acf', 'on' ), 'on', false ); ?>>
+ <label for="wpr-bundled-acf"></label>
+ </div>
+ <?php endif; ?>
</div>
<div class="wpr-settings-group wpr-settings-group-optimizers">
--- a/royal-elementor-addons/admin/templates-kit.php
+++ b/royal-elementor-addons/admin/templates-kit.php
@@ -70,16 +70,6 @@
</ul>
</div>
- <div class="wpr-templates-kit-filters">
- <div>Filter: All</div>
- <ul>
- <li data-filter="all">Blog</li>
- <li data-filter="blog">Blog</li>
- <li data-filter="business">Business</li>
- <li data-filter="ecommerce">eCommerce</li>
- <li data-filter="beauty">Beauty</li>
- </ul>
- </div>
</header>
<div class="wpr-templates-kit-page-title">
@@ -93,6 +83,30 @@
</p>
</div>
+ <?php
+ $kit_category_filters = [
+ [ 'all', '', __( 'All Templates', 'wpr-addons' ) ],
+ [ 'shop', 'shop,woocommerce,estore,ecommerce', __( 'Shop', 'wpr-addons' ) ],
+ [ 'portfolio', 'portfolio', __( 'Portfolio', 'wpr-addons' ) ],
+ [ 'news-magazine', 'magazine,newspaper,news magazine', __( 'News/Magazine', 'wpr-addons' ) ],
+ [ 'landing-page', 'landing page,landingpage,onepage,one page', __( 'Landing Page', 'wpr-addons' ) ],
+ [ 'dynamic', 'dynamic,acf', __( 'Dynamic', 'wpr-addons' ) ],
+ [ 'digital-agency', 'digital agency', __( 'Digital Agency', 'wpr-addons' ) ],
+ [ 'business', 'business,corporate', __( 'Business', 'wpr-addons' ) ],
+ [ 'blog', 'blog,blogger', __( 'Blog', 'wpr-addons' ) ],
+ [ 'ai', 'artificial intelligence,ai website,ai templates,ai agency,ai saas,chatgpt,chat gpt,ai automation', __( 'AI', 'wpr-addons' ) ],
+ ];
+ ?>
+ <ul class="wpr-templates-kit-category-filters">
+ <?php foreach ( $kit_category_filters as $index => $filter ) : ?>
+ <li
+ data-filter="<?php echo esc_attr( $filter[0] ); ?>"
+ <?php echo '' !== $filter[1] ? 'data-filter-tags="' . esc_attr( $filter[1] ) . '"' : ''; ?>
+ <?php echo 0 === $index ? 'class="wpr-active-filter"' : ''; ?>
+ ><?php echo esc_html( $filter[2] ); ?></li>
+ <?php endforeach; ?>
+ </ul>
+
<div class="wpr-templates-kit-grid main-grid" data-theme-status="<?php echo esc_attr(get_theme_status()); ?>">
<?php
$kits = WPR_Templates_Data::get_available_kits();
--- a/royal-elementor-addons/admin/templates/library/wpr-templates-data.php
+++ b/royal-elementor-addons/admin/templates/library/wpr-templates-data.php
@@ -7,8 +7,8 @@
class WPR_Templates_Data {
public static function get_available_kits() {
- $is_pro_active = defined('WPR_ADDONS_PRO_VERSION') && wpr_fs()->can_use_premium_code();
- $is_expert = $is_pro_active && wpr_fs()->is_plan( 'expert' );
+ $is_pro_active = false;
+ $is_expert = false;
$is_cf7_active = is_plugin_active('contact-form-7/wp-contact-form-7.php') ? 'true' : 'false';
$is_mla_active = is_plugin_active('media-library-assistant/index.php') ? 'true' : 'false';
$is_woo_active = is_plugin_active('woocommerce/woocommerce.php') ? 'true' : 'false';
@@ -709,6 +709,18 @@
'label' => 'new',
'priority' => 3,
],
+ 'v3' => [
+ 'name' => 'Woo Shop V3',
+ 'pages' => 'home,shop,single-product,cart,checkout,about,contact,',
+ 'plugins' => '{"woocommerce":'. $is_woo_active .'}',
+ 'tags' => 'free shop shopping woo-commerce woocommerce estore ecommerce shop ecommerce product online shop online store boutique clothes eshopping fashion designer market reseller digital purchases e commerce black friday',
+ 'theme-builder' => true,
+ 'woo-builder' => true,
+ 'off-canvas' => false,
+ 'price' => $is_pro_active ? 'free' : 'free',
+ 'label' => 'new',
+ 'priority' => 3,
+ ],
],
'shop-wooshop' => [
'v2' => [
@@ -724,6 +736,20 @@
'priority' => 4,
],
],
+ 'product-showcase' => [
+ 'v1' => [
+ 'name' => 'Product Showcase V1',
+ 'pages' => 'home,overview,features,technology,design,review,pricing',
+ 'plugins' => '{}',
+ 'tags' => 'single page landing page one page onepage landingpage products product showcase modern catalog features attributes reviews rating testimonial technology woocommerce shop woo shopping headphones parallax',
+ 'theme-builder' => true,
+ 'woo-builder' => false,
+ 'off-canvas' => true,
+ 'price' => $is_pro_active ? 'free' : 'pro',
+ 'label' => 'new',
+ 'priority' => 50,
+ ],
+ ],
'cosmetic' => [
'v1' => [
'name' => 'Cosmetic Shop V1',
@@ -854,6 +880,18 @@
'label' => 'new',
'priority' => 20,
],
+ 'v3' => [
+ 'name' => 'Hotel V3',
+ 'pages' => 'home,about,rooms-1,rooms-2,room-single,services,spa-wellness,restaurant,gallery,faq,blog,single-blog,contact,',
+ 'plugins' => '{}',
+ 'tags' => 'hotel rooms apartment resort bnb accommodation tourism luxury hotel booking reservation travel vacation rent trip suites hospitality guest service wellness spa ',
+ 'theme-builder' => true,
+ 'woo-builder' => false,
+ 'off-canvas' => true,
+ 'price' => $is_pro_active ? 'free' : 'pro',
+ 'label' => 'new',
+ 'priority' => 19,
+ ],
],
'fitness-gym' => [
'v1' => [
@@ -1151,6 +1189,18 @@
'label' => 'new',
'priority' => 2,
],
+ 'v5' => [
+ 'name' => 'Digital Marketing Agency v5',
+ 'pages' => 'home,about,services,single-project,work-process,team,faq,blog,single-blog,contact,',
+ 'plugins' => '{}',
+ 'tags' => 'digital agency portfolio creative branding business company corporate digital services office agency web digital marketing content seo social media branding',
+ 'theme-builder' => true,
+ 'woo-builder' => false,
+ 'off-canvas' => true,
+ 'price' => $is_pro_active ? 'free' : 'pro',
+ 'label' => 'new',
+ 'priority' => 2,
+ ],
],
'digital-seo-marketing-agency' => [
'v1' => [
@@ -1373,7 +1423,7 @@
'name' => 'Car Rent',
'pages' => 'home,cars,car-details,about,contact,',
'plugins' => '{"woocommerce":'. $is_woo_active .'}',
- 'tags' => 'expert car rental service driver rent car delivery jorney luxary airport transfer car booking car hire',
+ 'tags' => 'expert car rental service driver rent car delivery jorney luxary journey luxury airport transfer car booking car hire',
'theme-builder' => true,
'woo-builder' => true,
'off-canvas' => false,
@@ -2324,6 +2374,12 @@
'preview' => ['home','about','services','service-details','team','portfolio','faq','blog','contact'],
'price' => $is_pro_active ? 'free' : 'pro',
],
+ 'digital-marketing-agency-v5' => [
+ 'name' => 'Digital Marketing Agency v5',
+ 'pages' => ['home','about','services','single-project','work-process','team','faq','blog','contact'],
+ 'preview' => ['home','about','services','single-project','work-process','team','faq','blog','contact'],
+ 'price' => $is_pro_active ? 'free' : 'pro',
+ ],
'fashion-v2' => [
'name' => 'Fashion',
'pages' => ['home','home-v2','home-v3','shop-v1','shop-v2','shop-v3','blog','about-v1','about-v2','contact-v1','contact-v2','contact-v3',],
@@ -2642,6 +2698,12 @@
'preview' => ['home','shop','cart','blog','about','contact'],
'price' => $is_pro_active ? 'free' : 'free',
],
+ 'wooshop-v3' => [
+ 'name' => 'Woo Shop V3',
+ 'pages' => ['home','shop','cart','checkout','about','contact'],
+ 'preview' => ['home','shop','cart','checkout','about','contact'],
+ 'price' => $is_pro_active ? 'free' : 'free',
+ ],
'fashion-v1' => [
'name' => 'Fashion',
'pages' => ['home','shop-v1','shop-v2','blog','about','faq','contact'],
@@ -2894,6 +2956,12 @@
'preview' => ['home','about','rooms','single-room','services','events','blog','contact'],
'price' => $is_pro_active ? 'free' : 'pro',
],
+ 'hotel-v3' => [
+ 'name' => 'Hotel V3',
+ 'pages' => ['home','about','rooms-1','rooms-2','room-single','services','spa-wellness','restaurant','gallery','faq','blog','contact'],
+ 'preview' => ['home','about','rooms-1','rooms-2','room-single','services','spa-wellness','restaurant','gallery','faq','blog','contact'],
+ 'price' => $is_pro_active ? 'free' : 'pro',
+ ],
'digital-seo-marketing-agency-v1' => [
'name' => 'Digital SEO Agency v1',
'pages' => ['home','about','services','team','projects','details','pricing','blog','faq','contact'],
--- a/royal-elementor-addons/classes/modules/forms/wpr-send-webhook.php
+++ b/royal-elementor-addons/classes/modules/forms/wpr-send-webhook.php
@@ -1,7 +1,6 @@
<?php
namespace WprAddonsClassesModulesForms;
-use ElementorUtils;
use WprAddonsClassesUtilities;
if ( ! defined( 'ABSPATH' ) ) {
@@ -13,67 +12,140 @@
*
* @since 3.4.6
*/
+class WPR_Send_Webhook {
- class WPR_Send_Webhook {
+ public function __construct() {
+ add_action( 'wp_ajax_wpr_form_builder_webhook', [ $this, 'send_webhook' ] );
+ add_action( 'wp_ajax_nopriv_wpr_form_builder_webhook', [ $this, 'send_webhook' ] );
+ add_action( 'elementor/editor/after_save', [ $this, 'persist_webhook_urls_on_save' ], 10, 2 );
+ }
+
+ /**
+ * Persist validated webhook URLs when an Elementor document is saved.
+ *
+ * Avoids relying solely on widget render() (which runs on draft preview).
+ *
+ * @param int $post_id Post ID.
+ * @param array $data Elementor document data.
+ */
+ public function persist_webhook_urls_on_save( $post_id, $data ) {
+ if ( ! current_user_can( 'publish_posts' ) ) {
+ return;
+ }
+
+ if ( ! is_array( $data ) ) {
+ return;
+ }
+
+ $this->walk_elements_for_webhook( $data );
+ }
+
+ /**
+ * Recursively find Form Builder widgets and store safe webhook URLs.
+ *
+ * @param array $elements Elementor elements tree.
+ */
+ protected function walk_elements_for_webhook( $elements ) {
+ foreach ( $elements as $element ) {
+ if ( ! is_array( $element ) ) {
+ continue;
+ }
+
+ $widget_type = isset( $element['widgetType'] ) ? $element['widgetType'] : '';
+ if ( 'wpr-form-builder' === $widget_type && ! empty( $element['id'] ) ) {
+ $settings = isset( $element['settings'] ) && is_array( $element['settings'] ) ? $element['settings'] : [];
+ $webhook_url = isset( $settings['webhook_url'] ) ? $settings['webhook_url'] : '';
+ $validated = Utilities::wpr_validate_webhook_url( $webhook_url );
- public function __construct() {
- add_action('wp_ajax_wpr_form_builder_webhook' , [$this, 'send_webhook']);
- add_action('wp_ajax_nopriv_wpr_form_builder_webhook',[$this, 'send_webhook']);
- }
-
- public function send_webhook() {
- $nonce = $_POST['nonce'];
-
- if ( !wp_verify_nonce( $nonce, 'wpr-addons-js' ) ) {
- return; // Get out of here, the nonce is rotten!
- }
-
- $message_body = [];
-
- foreach ( $_POST['form_content'] as $key => $value ) {
- if ( is_array($value[1]) ) {
- if ( empty($value[2]) ) {
- $message_body[trim($key)] = implode("n", $value[1]);
+ if ( is_wp_error( $validated ) ) {
+ update_option( 'wpr_webhook_url_' . $element['id'], '' );
} else {
- $message_body[trim($value[2])] = implode("n", $value[1]);
+ update_option( 'wpr_webhook_url_' . $element['id'], $validated );
}
- } else {
- if ( empty($value2) ) {
- $message_body[trim($key)] = $value[1];
- } else {
- $message_body[trim($value[2])] = $value[1];
- }
- }
- }
+ }
- $message_body['form_id'] = $_POST['wpr_form_id'];
- $message_body['form_name'] = $_POST['form_name'];
+ if ( ! empty( $element['elements'] ) && is_array( $element['elements'] ) ) {
+ $this->walk_elements_for_webhook( $element['elements'] );
+ }
+ }
+ }
+
+ public function send_webhook() {
+ $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
+
+ if ( ! wp_verify_nonce( $nonce, 'wpr-addons-js' ) ) {
+ return; // Get out of here, the nonce is rotten!
+ }
+
+ $form_id = isset( $_POST['wpr_form_id'] ) ? sanitize_text_field( wp_unslash( $_POST['wpr_form_id'] ) ) : '';
+ if ( '' === $form_id || ! preg_match( '/^[A-Za-z0-9_-]+$/', $form_id ) ) {
+ wp_send_json_error( [
+ 'action' => 'wpr_form_builder_webhook',
+ 'message' => esc_html__( 'Invalid form ID.', 'wpr-addons' ),
+ 'status' => 'error',
+ ] );
+ }
+
+ $webhook_url = get_option( 'wpr_webhook_url_' . $form_id, '' );
+ $webhook_url = Utilities::wpr_validate_webhook_url( $webhook_url );
+
+ if ( is_wp_error( $webhook_url ) || '' === $webhook_url ) {
+ wp_send_json_error( [
+ 'action' => 'wpr_form_builder_webhook',
+ 'message' => esc_html__( 'Webhook error', 'wpr-addons' ),
+ 'status' => 'error',
+ 'details' => is_wp_error( $webhook_url ) ? $webhook_url->get_error_message() : esc_html__( 'Webhook URL is missing or invalid.', 'wpr-addons' ),
+ ] );
+ }
+
+ $message_body = [];
+ $form_content = isset( $_POST['form_content'] ) && is_array( $_POST['form_content'] ) ? wp_unslash( $_POST['form_content'] ) : []; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized per-field below.
+
+ foreach ( $form_content as $key => $value ) {
+ if ( ! is_array( $value ) ) {
+ continue;
+ }
+
+ $field_key = isset( $value[2] ) && '' !== $value[2] ? sanitize_text_field( $value[2] ) : sanitize_text_field( (string) $key );
+ $field_value = isset( $value[1] ) ? $value[1] : '';
+
+ if ( is_array( $field_value ) ) {
+ $message_body[ $field_key ] = implode( "n", array_map( 'sanitize_text_field', $field_value ) );
+ } else {
+ $message_body[ $field_key ] = sanitize_text_field( $field_value );
+ }
+ }
+
+ $message_body['form_id'] = $form_id;
+ $message_body['form_name'] = isset( $_POST['form_name'] ) ? sanitize_text_field( wp_unslash( $_POST['form_name'] ) ) : '';
$args = [
- 'body' => $message_body,
+ 'body' => $message_body,
+ 'timeout' => 15,
+ 'redirection' => 3,
];
- $response = wp_remote_post( trim(get_option('wpr_webhook_url_' . $_POST['wpr_form_id'])), $args );
+ // wp_safe_remote_post rejects unsafe/private URLs and re-validates redirects.
+ $response = wp_safe_remote_post( $webhook_url, $args );
$response_code = (int) wp_remote_retrieve_response_code( $response );
- $is_success = ! is_wp_error( $response ) && $response_code >= 200 && $response_code < 300;
+ $is_success = ! is_wp_error( $response ) && $response_code >= 200 && $response_code < 300;
if ( ! $is_success ) {
- wp_send_json_error([
- 'action' => 'wpr_form_builder_webhook',
- 'message' => esc_html__('Webhook error', 'wpr-addons'),
- 'status' => 'error',
- 'details' => json_encode($message_body)
- ]);
- // throw new Exception( 'Webhook error.' );
- } else {
- wp_send_json_success([
- 'action' => 'wpr_form_builder_webhook',
- 'message' => esc_html__('Webhook success', 'wpr-addons'),
- 'status' => 'success',
- 'details' => json_encode($message_body)
- ]);
- }
- }
- }
+ wp_send_json_error( [
+ 'action' => 'wpr_form_builder_webhook',
+ 'message' => esc_html__( 'Webhook error', 'wpr-addons' ),
+ 'status' => 'error',
+ 'details' => wp_json_encode( $message_body ),
+ ] );
+ }
+
+ wp_send_json_success( [
+ 'action' => 'wpr_form_builder_webhook',
+ 'message' => esc_html__( 'Webhook success', 'wpr-addons' ),
+ 'status' => 'success',
+ 'details' => wp_json_encode( $message_body ),
+ ] );
+ }
+}
- new WPR_Send_Webhook();
No newline at end of file
+new WPR_Send_Webhook();
--- a/royal-elementor-addons/classes/modules/wpr-ajax-search.php
+++ b/royal-elementor-addons/classes/modules/wpr-ajax-search.php
@@ -23,6 +23,37 @@
add_action('wp_ajax_nopriv_wpr_data_fetch',[$this, 'data_fetch']);
}
+ /**
+ * Sanitize meta keys for ajax search. Rejects empty and underscore-prefixed (private) keys.
+ *
+ * @param string|array $raw_keys Comma-separated string or array of meta keys.
+ * @return string[]
+ */
+ private static function sanitize_search_meta_keys( $raw_keys ) {
+ if ( is_string( $raw_keys ) ) {
+ $raw_keys = preg_split( '/s*,s*/', $raw_keys, -1, PREG_SPLIT_NO_EMPTY );
+ }
+
+ if ( ! is_array( $raw_keys ) ) {
+ return [];
+ }
+
+ $keys = [];
+
+ foreach ( $raw_keys as $key ) {
+ $key = sanitize_text_field( (string) $key );
+
+ // Allow only safe public meta key characters; reject private (_*) keys.
+ if ( '' === $key || '_' === $key[0] || ! preg_match( '/^[A-Za-z0-9_-]+$/', $key ) ) {
+ continue;
+ }
+
+ $keys[] = $key;
+ }
+
+ return array_values( array_unique( $keys ) );
+ }
+
public function data_fetch() {
$nonce = $_POST['nonce'];
@@ -112,7 +143,6 @@
}
}
- $keyword = sanitize_text_field( $_POST['wpr_keyword'] );
$can_view_protected_posts = current_user_can('read_private_posts');
$meta_query = [];
@@ -149,19 +179,37 @@
$the_query = new WP_Query( $args );
- if ( !$the_query->have_posts() && $keyword !== '' && 'yes' === sanitize_text_field( $_POST['wpr_meta_query'] ) ) {
- $fallback_args = $args;
- $fallback_args['s'] = ''; // disable default search
- $fallback_args['meta_query'] = [
- [
- 'value' => $keyword,
- 'compare' => 'LIKE'
- ]
- ];
+ // Fallback: search selected public meta keys only (never key-less / never _* keys).
+ if ( ! $the_query->have_posts() && 'yes' === sanitize_text_field( wp_unslash( $_POST['wpr_meta_query'] ?? '' ) ) ) {
+ $keyword = sanitize_text_field( wp_unslash( $_POST['wpr_keyword'] ?? '' ) );
+ $meta_keys = self::sanitize_search_meta_keys( wp_unslash( $_POST['wpr_meta_keys'] ?? '' ) );
+
+ if ( '' !== $keyword && mb_strlen( $keyword ) >= 3 && ! empty( $meta_keys ) ) {
+ $meta_query_or = [ 'relation' => 'OR' ];
+
+ foreach ( $meta_keys as $meta_key ) {
+ $meta_query_or[] = [
+ 'key' => $meta_key,
+ 'value' => $keyword,
+ 'compare' => 'LIKE',
+ ];
+ }
+
+ if ( 'yes' === sanitize_text_field( wp_unslash( $_POST['wpr_exclude_without_thumb'] ?? '' ) ) ) {
+ $meta_query_or = [
+ 'relation' => 'AND',
+ [ 'key' => '_thumbnail_id' ],
+ $meta_query_or,
+ ];
+ }
+
+ $args['s'] = '';
+ $args['meta_query'] = $meta_query_or;
- $the_query = new WP_Query($fallback_args);
+ $the_query = new WP_Query( $args );
+ }
}
-
+
if( $the_query->have_posts() ) :
$number_of_queried_posts = $the_query->found_posts;
$post_count = 0;
--- a/royal-elementor-addons/classes/modules/wpr-filter-grid-media.php
+++ b/royal-elementor-addons/classes/modules/wpr-filter-grid-media.php
@@ -1,926 +0,0 @@
-<?php
-namespace WprAddonsClassesModules;
-
-use ElementorUtils;
-use ElementorGroup_Control_Image_Size;
-use WprAddonsClassesUtilities;
-
-
-if ( ! defined( 'ABSPATH' ) ) {
- exit; // Exit if accessed directly.
-}
-
-/**
- * WPR_Filter_Grid_Media setup
- *
- * @since 3.4.6
- */
-
- class WPR_Filter_Grid_Media {
-
- public function __construct() {
- add_action('wp_ajax_wpr_filter_grid_media', [$this, 'wpr_filter_grid_media']);
- add_action('wp_ajax_nopriv_wpr_filter_grid_media', [$this, 'wpr_filter_grid_media']);
- add_action('wp_ajax_wpr_get_media_filtered_count', [$this, 'wpr_get_media_filtered_count']);
- add_action('wp_ajax_nopriv_wpr_get_media_filtered_count', [$this, 'wpr_get_media_filtered_count']);
- }
-
- // Get Taxonomies Related to Post Type
- public function get_related_taxonomies() {
- $relations = [];
- $post_types = Utilities::get_custom_types_of( 'post', false );
-
- foreach ( $post_types as $slug => $title ) {
- $relations[$slug] = [];
-
- foreach ( get_object_taxonomies( $slug ) as $tax ) {
- array_push( $relations[$slug], $tax );
- }
- }
-
- return json_encode( $relations );
- }
-
- // Get Max Pages
- public function get_max_num_pages( $settings ) {
- $query = new WP_Query( $this->get_main_query_args() );
- $max_num_pages = intval( ceil( $query->max_num_pages ) );
-
- $adjustedTotalPosts = max(0, $query->found_posts - $query->query_vars['offset']); // Ensuring it doesn't go below 0
- $numberOfPages = ceil($adjustedTotalPosts / $query->query_vars['posts_per_page']);
-
- wp_send_json_success([
- 'page_count' => $numberOfPages,
- 'max_num_pages' => $max_num_pages,
- 'query_found' => $query->found_posts,
- 'query_offset' => $query->query_vars['offset'],
- 'query_num' => $query->query_vars['posts_per_page']
- ]);
-
- // Reset
- wp_reset_postdata();
-
- // $max_num_pages
- return $max_num_pages;
- }
-
- // Main Query Args
- public function get_main_query_args() {
- $settings = $_POST['grid_settings'];
- $taxonomy = $_POST['wpr_taxonomy'];
- $term = $_POST['wpr_filter'];
- $tax_query = [];
-
- $author = ! empty( $settings[ 'query_author' ] ) ? implode( ',', $settings[ 'query_author' ] ) : '';
-
- // Get Paged
- if ( get_query_var( 'paged' ) ) {
- $paged = get_query_var( 'paged' );
- } elseif ( get_query_var( 'page' ) ) {
- $paged = get_query_var( 'page' );
- } else {
- $paged = 1;
- }
-
- if ( empty($settings['query_offset']) ) {
- $settings[ 'query_offset' ] = 0;
- }
-
- $offset = ( $paged - 1 ) * $settings['query_posts_per_page'] + $settings[ 'query_offset' ];
-
- if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
- $settings[ 'query_randomize' ] = '';
- $settings['order_posts'] = 'date';
- }
-
- $query_order_by = '' != $settings['query_randomize'] ? $settings['query_randomize'] : $settings['order_posts'];
-
- if ( 'manual' === $settings[ 'query_selection' ] ) {
- $query_order_by = 'post__in';
- }
-
- // Dynamic
- $args = [
- 'post_type' => 'attachment',
- 'post_status' => 'inherit',
- 'post_mime_type' => 'image',
- 'tax_query' => $this->get_tax_query_args(),
- 'post__not_in' => $settings[ 'query_exclude_attachment' ],
- 'posts_per_page' => $settings['query_posts_per_page'],
- 'orderby' => $query_order_by,
- 'author' => $author,
- 'paged' => $paged,
- 'offset' => $offset
- ];
-
- // Manual
- if ( 'manual' === $settings[ 'query_selection' ] ) {
- $post_ids = [''];
-
- $attachments = $settings['query_manual_attachment'];
-
- $attachments_count = 0;
-
- if (!empty($attachments) ) {
- $attachments_count = count($attachments);
- }
-
- for ( $i = 0; $i < $attachments_count; $i++ ) {
- array_push( $post_ids, $settings['query_manual_attachment'][$i]['id'] );
- }
-
- $orderby = '' === $settings[ 'query_randomize' ] ? 'post__in' : 'rand';
-
- $args = [
- 'post_type' => 'attachment',
- 'post_status' => 'inherit',
- 'post__in' => $post_ids,
- 'orderby' => $orderby,
- 'paged' => $paged,
- 'posts_per_page' => $settings['query_posts_per_page'],
- 'paged' => $paged,
- ];
-
- if ( isset($_POST['wpr_offset']) ) {
- $args['offset'] = $_POST['wpr_offset'];
- }
-
- $tax_query = $this->get_tax_query_args();
-
- if ( ! empty( $tax_query ) ) {
- $args['tax_query'] = $tax_query;
- }
- }
-
- if ( isset($_POST['wpr_offset']) ) {
- $args['offset'] = $_POST['wpr_offset'];
- }
-
- if ( 'rand' !== $query_order_by && 'manual' !== $settings['query_selection'] ) {
- $args['order'] = $settings['order_direction'];
- }
-
- return $args;
- }
-
- // Taxonomy Query Args
- public function get_tax_query_args() {
- $settings = $_POST['grid_settings'];
- $tax_query = [];
-
- // Add filter for selected taxonomy and term if they exist
- if (!empty($_POST['wpr_taxonomy']) && !empty($_POST['wpr_filter']) && $_POST['wpr_filter'] !== 'all' && $_POST['wpr_taxonomy'] !== '*') {
- $tax_query[] = [
- 'taxonomy' => sanitize_text_field($_POST['wpr_taxonomy']),
- 'field' => 'slug', // Use slug instead of ID for attachments
- 'terms' => sanitize_text_field($_POST['wpr_filter']),
- ];
-
- return $tax_query; // Return early with just the selected filter
- }
-
- // Otherwise, use the default taxonomies from settings
- $media_taxonomies = get_taxonomies(['object_type' => ['attachment']], 'names'); // Get custom attachment taxonomies
-
- foreach ($media_taxonomies as $tax) {
- if (!empty($settings['query_taxonomy_' . $tax])) {
- $tax_query[] = [
- 'taxonomy' => $tax,
- 'field' => 'slug', // Ensure it's using slug
- 'terms' => $settings['query_taxonomy_' . $tax],
- ];
- }
- }
-
- return $tax_query;
- }
-
- // Get Animation Class
- public function get_animation_class( $data, $object ) {
- $class = '';
-
- // Animation Class
- if ( 'none' !== $data[ $object .'_animation'] ) {
- $class .= ' wpr-'. $object .'-'. $data[ $object .'_animation'];
- $class .= ' wpr-anim-size-'. $data[ $object .'_animation_size'];
- $class .= ' wpr-anim-timing-'. $data[ $object .'_animation_timing'];
-
- if ( 'yes' === $data[ $object .'_animation_tr'] ) {
- $class .= ' wpr-anim-transparency';
- }
- }
-
- return $class;
- }
-
- // Get Image Effect Class
- public function get_image_effect_class( $settings ) {
- $class = '';
-
- if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
- if ( 'pro-zi' == $settings['image_effects'] || 'pro-zo' == $settings['image_effects'] || 'pro-go' == $settings['image_effects'] || 'pro-bo' == $settings['image_effects'] ) {
- $settings['image_effects'] = 'none';
- }
- }
-
- // Animation Class
- if ( 'none' !== $settings['image_effects'] ) {
- $class .= ' wpr-'. $settings['image_effects'];
- }
-
- // Slide Effect
- if ( 'slide' !== $settings['image_effects'] ) {
- $class .= ' wpr-effect-size-'. $settings['image_effects_size'];
- } else {
- $class .= ' wpr-effect-dir-'. $settings['image_effects_direction'];
- }
-
- return $class;
- }
-
- // Render Post Thumbnail
- public function render_post_thumbnail( $settings ) {
- $id = get_the_ID();
- $src = Group_Control_Image_Size::get_attachment_image_src( $id, 'layout_image_crop', $settings );
- $alt = '' === wp_get_attachment_caption( $id ) ? get_the_title() : wp_get_attachment_caption( $id );
-
- echo '<div class="wpr-grid-image-wrap" data-src="'. esc_url( wp_get_attachment_url( $id ) ) .'">';
- echo '<img src="'. esc_url( $src ) .'" alt="'. wp_kses_post( $alt ) .'" class="wpr-anim-timing-'. esc_html($settings[ 'image_effects_animation_timing']) .'">';
- echo '</div>';
- }
-
- // Render Media Overlay
- public function render_media_overlay( $settings ) {
- echo '<div class="wpr-grid-media-hover-bg '. esc_attr($this->get_animation_class( $settings, 'overlay' )) .'" data-url="'. esc_url( get_the_permalink( get_the_ID() ) ) .'">';
-
- if ( defined('WPR_ADDONS_PRO_VERSION') && wpr_fs()->can_use_premium_code() ) {
- if ( '' !== $settings['overlay_image']['url'] ) {
- echo '<img src="'. esc_url( $settings['overlay_image']['url'] ) .'">';
- }
- }
-
- echo '</div>';
- }
-
- // Render Post Title
- public function render_post_title( $settings, $class ) {
- $title_pointer = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'none' : $_POST['grid_settings']['title_pointer'];
- $title_pointer_animation = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'fade' : $_POST['grid_settings']['title_pointer_animation'];
- $pointer_item_class = ( isset( $_POST['grid_settings']['title_pointer'] ) && 'none' !== $_POST['grid_settings']['title_pointer'] ) ? 'wpr-pointer-item' : '';
-
- $class .= ' wpr-pointer-'. $title_pointer;
- $class .= ' wpr-pointer-line-fx wpr-pointer-fx-'. $title_pointer_animation;
-
- $tags_whitelist = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p'];
- $element_title_tag = Utilities::validate_html_tags_wl( $settings['element_title_tag'], 'h2', $tags_whitelist );
-
- echo '<'. esc_attr($element_title_tag) .' class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- if ( 'yes' === $settings['element_disable_link'] ) {
- echo '<span class="' . esc_attr( $pointer_item_class ) . '">';
- echo esc_html(wp_trim_words( get_the_title(), $settings['element_word_count'] ));
- echo '</span>';
- } else {
- echo '<a class="' . esc_attr( $pointer_item_class ) . '" href="' . esc_url( get_the_permalink() ) . '">';
- echo esc_html(wp_trim_words( get_the_title(), $settings['element_word_count'] ));
- echo '</a>';
- }
- echo '</div>';
- echo '</'. esc_attr($element_title_tag) .'>';
- }
-
- // Render Post Content
- public function render_post_content( $settings, $class ) {
- $dropcap_class = 'yes' === $settings['element_dropcap'] ? ' wpr-enable-dropcap' : '';
- $class .= $dropcap_class;
-
- if ( '' === get_the_content() ) {
- return;
- }
-
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- echo wp_kses_post(get_the_content());
- echo '</div>';
- echo '</div>';
- }
-
- // Render Post Excerpt
- public function render_post_excerpt( $settings, $class ) {
- $dropcap_class = 'yes' === $settings['element_dropcap'] ? ' wpr-enable-dropcap' : '';
- $class .= $dropcap_class;
-
- if ( '' === get_the_excerpt() ) {
- return;
- }
-
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- echo '<p>'. esc_html(wp_trim_words( get_the_excerpt(), $settings['element_word_count'] )) .'</p>';
- echo '</div>';
- echo '</div>';
- }
-
- // Render Post Date
- public function render_post_date( $settings, $class ) {
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- echo '<span>';
- // Text: Before
- if ( 'before' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- // Icon: Before
- if ( 'before' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-left">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
-
- // Date
- echo esc_html(apply_filters( 'the_date', get_the_date( '' ), get_option( 'date_format' ), '', '' ));
-
- // Icon: After
- if ( 'after' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-right">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
- // Text: After
- if ( 'after' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- echo '</span>';
- echo '</div>';
- echo '</div>';
- }
-
- // Render Post Time
- public function render_post_time( $settings, $class ) {
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- echo '<span>';
- // Text: Before
- if ( 'before' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- // Icon: Before
- if ( 'before' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-left">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
-
- // Time
- echo esc_html(get_the_time(''));
-
- // Icon: After
- if ( 'after' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-right">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
- // Text: After
- if ( 'after' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- echo '</span>';
- echo '</div>';
- echo '</div>';
- }
-
- // Render Post Author
- public function render_post_author( $settings, $class ) {
- $author_id = get_post_field( 'post_author' );
-
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- // Text: Before
- if ( 'before' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
-
- // Author
- echo '<a href="'. esc_url( get_author_posts_url( $author_id ) ) .'">';
-
- // Icon: Before
- if ( 'before' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-left">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
- if ( 'yes' === $settings['element_show_avatar'] ) {
- echo get_avatar( $author_id, $settings['element_avatar_size'] );
- }
-
- echo '<span>'. esc_html(get_the_author_meta( 'display_name', $author_id )) .'</span>';
-
- // Icon: After
- if ( 'after' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-right">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
- echo '</a>';
-
- // Text: After
- if ( 'after' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- echo '</div>';
- echo '</div>';
- }
-
- public function render_post_likes( $settings, $class, $post_id ) {
- $post_likes = new WPR_Post_Likes();
-
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- // Text: Before
- if ( 'before' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
-
- echo wp_kses_post( $post_likes->get_button( $post_id, $settings ) );
-
- // Text: After
- if ( 'after' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- echo '</div>';
- echo '</div>';
- }
-
- // Render Post Sharing
- public function render_post_sharing_icons( $settings, $class ) {
- $args = [
- 'icons' => 'yes',
- 'tooltip' => $settings['element_sharing_tooltip'],
- 'url' => esc_url( get_permalink( get_queried_object_id() ) ),
- 'title' => esc_html( get_the_title() ),
- 'text' => esc_html( get_the_excerpt() ),
- 'image' => esc_url( get_the_post_thumbnail_url() ),
- ];
-
- $hidden_class = '';
-
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- // Text: Before
- if ( 'before' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
-
- echo '<span class="wpr-post-sharing">';
-
- if ( 'yes' === $settings['element_sharing_trigger'] ) {
- $hidden_class = ' wpr-sharing-hidden';
- $attributes = ' data-action="'. esc_attr( $settings['element_sharing_trigger_action'] ) .'"';
- $attributes .= ' data-direction="'. esc_attr( $settings['element_sharing_trigger_direction'] ) .'"';
-
- echo '<a class="wpr-sharing-trigger wpr-sharing-icon"'. $attributes .'>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
- if ( 'yes' === $settings['element_sharing_tooltip'] ) {
- echo '<span class="wpr-sharing-tooltip wpr-tooltip">'. esc_html__( 'Share', 'wpr-addons' ) .'</span>';
- }
-
- echo wp_kses_post( Utilities::get_wpr_icon( $settings['element_sharing_trigger_icon'], '' ) );
- echo '</a>';
- }
-
-
- echo '<span class="wpr-post-sharing-inner' . esc_attr( $hidden_class ) . '">';
-
- for ( $i = 1; $i < 7; $i++ ) {
- $args['network'] = $settings['element_sharing_icon_'. $i];
-
- echo wp_kses_post( Utilities::get_post_sharing_icon( $args ) );
- }
-
- echo '</span>';
-
- echo '</span>';
-
- // Text: After
- if ( 'after' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- echo '</div>';
- echo '</div>';
- }
-
- // Render Post Lightbox
- public function render_post_lightbox( $settings, $class, $post_id ) {
- echo '<div class="'. esc_attr($class) .'">';
- echo '<div class="inner-block">';
- $lightbox_source = get_the_post_thumbnail_url( $post_id );
-
- // Audio Post Type
- if ( 'audio' === get_post_format() ) {
- // Load Meta Value
- if ( 'meta' === $settings['element_lightbox_pfa_select'] ) {
- $utilities = new Utilities();
- $meta_value = get_post_meta( $post_id, $settings['element_lightbox_pfa_meta'], true );
-
- // URL
- if ( false === strpos( $meta_value, '<iframe ' ) ) {
- add_filter( 'oembed_result', [ $utilities, 'filter_oembed_results' ], 50, 3 );
- $track_url = wp_oembed_get( $meta_value );
- remove_filter( 'oembed_result', [ $utilities, 'filter_oembed_results' ], 50 );
-
- // Iframe
- } else {
- $track_url = Utilities::filter_oembed_results( $meta_value );
- }
-
- $lightbox_source = $track_url;
- }
-
- // Video Post Type
- } elseif ( 'video' === get_post_format() ) {
- // Load Meta Value
- if ( 'meta' === $settings['element_lightbox_pfv_select'] ) {
- $meta_value = get_post_meta( $post_id, $settings['element_lightbox_pfv_meta'], true );
-
- // URL
- if ( false === strpos( $meta_value, '<iframe ' ) ) {
- $video = ElementorEmbed::get_video_properties( $meta_value );
-
- // Iframe
- } else {
- $video = ElementorEmbed::get_video_properties( Utilities::filter_oembed_results($meta_value) );
- }
-
- // Provider URL
- if ( 'youtube' === $video['provider'] ) {
- $video_url = '//www.youtube.com/embed/'. $video['video_id'] .'?feature=oembed&autoplay=1&controls=1';
- } elseif ( 'vimeo' === $video['provider'] ) {
- $video_url = 'https://player.vimeo.com/video/'. $video['video_id'] .'?autoplay=1#t=0';
- }
-
- // Add Lightbox Attributes
- if ( isset( $video_url ) ) {
- $lightbox_source = $video_url;
- }
- }
- }
-
- if ( $lightbox_source == false ) {
- $lightbox_source = wp_get_attachment_url( $post_id );
- }
-
- // Lightbox Button
- echo '<span data-src="'. esc_url( $lightbox_source ) .'">';
-
- // Text: Before
- if ( 'before' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
-
- // Lightbox Icon
- echo '<i class="'. esc_attr( $settings['element_extra_icon']['value'] ) .'"></i>';
-
- // Text: After
- if ( 'after' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
-
- echo '</span>';
-
- // Media Overlay
- if ( 'yes' === $settings['element_lightbox_overlay'] ) {
- echo '<div class="wpr-grid-lightbox-overlay"></div>';
- }
- echo '</div>';
- echo '</div>';
- }
-
- // Render Post Element Separator
- public function render_post_element_separator( $settings, $class ) {
- echo '<div class="'. esc_attr($class .' '. $settings['element_separator_style']) .'">';
- echo '<div class="inner-block"><span></span></div>';
- echo '</div>';
- }
-
- // Render Post Taxonomies
- public function render_post_taxonomies( $settings, $class, $post_id ) {
- $terms = wp_get_post_terms( $post_id, $settings['element_select'] );
- $count = 0;
-
- $tax1_pointer = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'none' : $_POST['grid_settings']['tax1_pointer'];
- $tax1_pointer_animation = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'fade' : $_POST['grid_settings']['tax1_pointer_animation'];
- $tax2_pointer = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'none' : $_POST['grid_settings']['tax2_pointer'];
- $tax2_pointer_animation = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'fade' : $_POST['grid_settings']['tax2_pointer_animation'];
- $pointer_item_class = (isset($_POST['grid_settings']['tax1_pointer']) && 'none' !== $_POST['grid_settings']['tax1_pointer']) || (isset($_POST['grid_settings']['tax2_pointer']) && 'none' !== $_POST['grid_settings']['tax2_pointer']) ? 'wpr-pointer-item' : '';
-
- // Pointer Class
- if ( 'wpr-grid-tax-style-1' === $settings['element_tax_style'] ) {
- $class .= ' wpr-pointer-'. $tax1_pointer;
- $class .= ' wpr-pointer-line-fx wpr-pointer-fx-'. $tax1_pointer_animation;
- } else {
- $class .= ' wpr-pointer-'. $tax2_pointer;
- $class .= ' wpr-pointer-line-fx wpr-pointer-fx-'. $tax2_pointer_animation;
- }
-
- echo '<div class="'. esc_attr($class .' '. $settings['element_tax_style']) .'">';
- echo '<div class="inner-block">';
- // Text: Before
- if ( 'before' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- // Icon: Before
- if ( 'before' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-left">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
-
- // Taxonomies
- foreach ( $terms as $term ) {
-
- // Custom Colors
- $enable_custom_colors = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? '' : $_POST['grid_settings']['tax1_custom_color_switcher'];
-
- if ( 'yes' === $enable_custom_colors ) {
- $custom_tax_styles = '';
- $cfc_text = get_term_meta($term->term_id, $_POST['grid_settings']['tax1_custom_color_field_text'], true);
- $cfc_bg = get_term_meta($term->term_id, $_POST['grid_settings']['tax1_custom_color_field_bg'], true);
- $color_styles = 'color:'. $cfc_text .'; background-color:'. $cfc_bg .'; border-color:'. $cfc_bg .';';
- $css_selector = '.elementor-element'. $this->get_unique_selector() .' .wpr-grid-tax-style-1 .inner-block a.wpr-tax-id-'. esc_attr($term->term_id);
- $custom_tax_styles .= $css_selector .'{'. $color_styles .'}';
- echo '<style>'. esc_html($custom_tax_styles) .'</style>'; // TODO: take out of loop if possible
- }
-
- echo '<a class="' . esc_attr( trim( $pointer_item_class . ' wpr-tax-id-' . $term->term_id ) ) . '" href="' . esc_url( get_term_link( $term->term_id ) ) . '">' . esc_html( $term->name );
- if ( ++$count !== count( $terms ) ) {
- echo '<span class="tax-sep">'. esc_html($settings['element_tax_sep']) .'</span>';
- }
- echo '</a>';
- }
-
- // Icon: After
- if ( 'after' === $settings['element_extra_icon_pos'] ) {
- ob_start();
- ElementorIcons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
- $extra_icon = ob_get_clean();
-
- echo '<span class="wpr-grid-extra-icon-right">';
- echo wp_kses_post( $extra_icon );
- echo '</span>';
- }
- // Text: After
- if ( 'after' === $settings['element_extra_text_pos'] ) {
- echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
- }
- echo '</div>';
- echo '</div>';
- }
-
-
- // Get Elements
- public function get_elements( $type, $settings, $class, $post_id ) {
- if ( 'pro-lk' == $type || 'pro-shr' == $type ) {
- $type = 'title';
- }
-
- switch ( $type ) {
- case 'title':
- $this->render_post_title( $settings, $class );
- break;
-
- case 'caption':
- $this->render_post_excerpt( $settings, $class );
- break;
-
- case 'date':
- $this->render_post_date( $settings, $class );
- break;
-
- case 'time':
- $this->render_post_time( $settings, $class );
- break;
-
- case 'author':
- $this->render_post_author( $settings, $class );
- break;
-
- case 'likes':
- $this->render_post_likes( $settings, $class, $post_id );
- break;
-
- case 'sharing':
- $this->render_post_sharing_icons( $settings, $class );
- break;
-
- case 'lightbox':
- $this->render_post_lightbox( $settings, $class, $post_id );
- break;
-
- case 'separator':
- $this->render_post_element_separator( $settings, $class );
- break;
-
- default:
- $this->render_post_taxonomies( $settings, $class, $post_id );
- break;
- }
-
- }
-
- // Get Elements by Location
- public function get_elements_by_location( $location, $settings, $post_id ) {
- $locations = [];
-
- foreach ( $settings['grid_elements'] as $data ) {
- $place = $data['element_location'];
- $align_vr = $data['element_align_vr'];
-
- if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
- $align_vr = 'middle';
- }
-
- if ( ! isset($locations[$place]) ) {
- $locations[$place] = [];
- }
-
- if ( 'over' === $place ) {
- if ( ! isset($locations[$place][$align_vr]) ) {
- $locations[$place][$align_vr] = [];
- }
-
- array_push( $locations[$place][$align_vr], $data );
- } else {
- array_push( $locations[$place], $data );
- }
- }
-
- if ( ! empty( $locations[$location] ) ) {
-
- if ( 'over' === $location ) {
- foreach ( $locations[$location] as $align => $elements ) {
-
- if ( 'middle' === $align ) {
- echo '<div class="wpr-cv-container"><div class="wpr-cv-outer"><div class="wpr-cv-inner">';
- }
-
- echo '<div class="wpr-grid-media-hover-'. esc_attr($align) .' elementor-clearfix">';
- foreach ( $elements as $data ) {
-
- // Get Class
- $class = 'wpr-grid-item-'. $data['element_select'];
- $class .= ' elementor-repeater-item-'. $data['_id'];
- $class .= ' wpr-grid-item-display-'. $data['element_display'];
- $class .= ' wpr-grid-item-align-'. $data['element_align_hr'];
- $class .= $this->get_animation_class( $data, 'element' );
-
- // Element
- $this->get_elements( $data['element_select'], $data, $class, $post_id );
- }
- echo '</div>';
-
- if ( 'middle' === $align ) {
- echo '</div></div></div>';
- }
- }
- } else {
- echo '<div class="wpr-grid-item-'. esc_attr($location) .'-content elementor-clearfix">';
- foreach ( $locations[$location] as $data ) {
-
- // Get Class
- $class = 'wpr-grid-item-'. $data['element_select'];
- $class .= ' elementor-repeater-item-'. $data['_id'];
- $class .= ' wpr-grid-item-display-'. $data['element_display'];
- $class .= ' wpr-grid-item-align-'. $data['element_align_hr'];
-
- // Element
- $this->get_elements( $data['element_select'], $data, $class, $post_id );
- }
- echo '</div>';
- }
-
- }
- }
-
- public function wpr_get_media_filtered_count() {
- $nonce = $_POST['nonce'];
-
- if (!isset($nonce) || !wp_verify_nonce($nonce, 'wpr-addons-js')) {
- wp_send_json_error(array(
- 'message' => esc_html__('Security check failed.', 'wpr-addons'),
- ));
- }
-
- $settings = $_POST['grid_settings'];
- $page_count = $this->get_max_num_pages( $settings );
-
- wp_send_json_success([
- 'page_count' => $page_count,
- ]);
-
- wp_die();
- }
-
- public function wpr_filter_grid_media() {
- $nonce = $_POST['nonce'];
-
- if (!isset($nonce) || !wp_verify_nonce($nonce, 'wpr-addons-js')) {
- wp_send_json_error(array(
- 'message' => esc_html__('Security check failed.', 'wpr-addons'),
- ));
- }
-
- // Get Settings
- $settings = $_POST['grid_settings'];
- // Get Posts
- $posts = new WP_Query( $this->get_main_query_args() );
-
- // Loop: Start
- if ( $posts->have_posts() ) :
-
- while ( $posts->have_posts() ) : $posts->the_post();
-
- // $post_index++;
- // if ( Utilities::is_new_free_user() && $post_index > 12 ) {
- // return;
- // }
-
- if ( ! wp_attachment_is( 'image', get_the_ID() ) ) {
- continue;
- }
-
- // Post Class
- $post_class = implode( ' ', get_post_class( 'wpr-grid-item elementor-clearfix', get_the_ID() ) );
-
- // Grid Item
- echo '<article class="'. esc_attr( $post_class ) .'">';
-
- // Inner Wrapper
- echo '<div class="wpr-grid-item-inner">';
-
- // Content: Above Media
- $this->get_elements_by_location( 'above', $settings, get_the_ID() );
-
- // Media
- echo '<div class="wpr-grid-media-wrap'. esc_attr($this->get_image_effect_class( $settings )) .' ">';
- // Post Thumbnail
- $this->render_post_thumbnail( $settings, get_the_ID() );
-
- // Media Hover
- echo '<div class="wpr-grid-media-hover wpr-animation-wrap">';
- // Media Overlay
- $this->render_media_overlay( $settings );
-
- // Content: Over Media
- $this->get_elements_by_location( 'over', $settings, get_the_ID() );
-
- echo '</div>';
- echo '</div>';
-
- // Content: Below Media
- $this->get_elements_by_location( 'below', $settings, get_the_ID() );
-
- echo '</div>'; // End .wpr-grid-item-inner
-
- echo '</article>'; // End .wpr-grid-item
-
- endwhile;
-
- // reset
- wp_reset_postdata();
-
- // Loop: End
- endif;
-
- die();
- }
-
-}
-
-new WPR_Filter_Grid_Media();
No newline at end of file
--- a/royal-elementor-addons/classes/modules/wpr-load-more-instagram-posts.php
+++ b/royal-elementor-addons/classes/modules/wpr-load-more-instagram-posts.php
@@ -97,7 +97,10 @@
}
// Icon: Before
if ( 'before' === $settings['element_extra_icon_pos'] ) {
- echo '<i class="wpr-insta-feed-extra-icon-left '. esc_attr( $settings['element_extra_icon']['value'] ) .'"></i>';
+ ElementorIcons_Manager::render_icon( $settings['element_extra_icon'], [
+ 'aria-hidden' => 'true',
+ 'class' => 'wpr-insta-feed-extra-icon-left',
+ ] );
}
// Date
@@ -109,7 +112,10 @@
// Icon: After
if ( 'after' === $settings['element_extra_icon_pos'] ) {
- echo '<i class="wpr-insta-feed-extra-icon-right '. esc_attr( $settings['element_extra_icon']['value'] ) .'"></i>';
+ ElementorIcons_Manager::render_icon( $settings['element_extra_icon'], [
+ 'aria-hidden' => 'true',
+ 'class' => 'wpr-insta-feed-extra-icon-right',
+ ] );
}
// Text: After
if ( 'after' === $settings['element_extra_text_pos'] ) {
@@ -151,7 +157,7 @@
}
// Lightbox Icon
- echo '<i class="'. esc_attr( $settings['element_extra_icon']['value'] ) .'"></i>';
+ ElementorIcons_Manager::render_icon( $settings['element_extra_icon'], [ 'aria-hidden' => 'true' ] );
// Text: After
if ( 'after' === $settings['element_extra_text_pos'] ) {
@@ -199,17 +205,17 @@
echo '<span class="wpr-sharing-tooltip wpr-tooltip">'. esc_html__( 'Share', 'wpr-addons' ) .'</span>';
}
- echo Utilities::get_wpr_icon( $settings['element_sharing_trigger_icon'], '' );
+ echo Utilities::get_wpr_icon( $settings['element_sharing_trigger_icon'], '' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '</a>';
}
- echo '<span class="wpr-post-sharing-inner'. $hidden_class .'">';
+ echo '<span class="wpr-post-sharing-inner' . esc_attr( $hidden_class ) . '">';
for ( $i = 1; $i < 7; $i++ ) {
$args['network'] = $settings['element_sharing_icon_'. $i];
- echo Utilities::get_post_sharing_icon( $args );
+ echo Utilities::get_post_sharing_icon( $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
echo '</span>';
@@ -443,8 +449,8 @@
<div class="wpr-insta-feed-content-wrap wpr-insta-col-12">
<figure>
<?php
- // Content: Below Media
- echo $this->get_elements_by_location( 'above', $settings, $result );
+ // Content: Above Media
+ $this->get_elements_by_location( 'above', $settings, $result );
?>
<div class="wpr-insta-feed-media-wrap <?php echo esc_attr($this->get_image_effect_class( $settings )) ?>" data-overlay-link="<?php echo esc_attr( $settings['overlay_post_link'] ) ?>">
<?php if ( 'CAROUSEL_ALBUM' == $result->media_type || 'IMAGE' == $result->media_type ) : ?>
@@ -468,7 +474,7 @@
</div>
<?php
// Content: Below Media
- echo $this->get_elements_by_location( 'below', $settings, $result );
+ $this->get_elements_by_location( 'below', $settings, $result );
?>
</figure>
</div>
--- a/royal-elementor-addons/classes/modules/wpr-media-grid-helpers.php
+++ b/royal-elementor-addons/classes/modules/wpr-media-grid-helpers.php
@@ -0,0 +1,1020 @@
+<?php
+namespace WprAddonsClassesModules;
+
+use ElementorGroup_Control_Image_Size;
+use WprAddonsClassesUtilities;
+use WprAddonsClassesModulesWPR_Post_Likes;
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
+
+/**
+ * WPR_Media_Grid_Helpers setup
+ *
+ * @since 3.4.6
+ */
+class WPR_Media_Grid_Helpers {
+
+ public function __construct() {
+ add_action( 'wp_ajax_wpr_filter_grid_media', [ $this, 'wpr_filter_grid_media' ] );
+ add_action( 'wp_ajax_nopriv_wpr_filter_grid_media', [ $this, 'wpr_filter_grid_media' ] );
+ add_action( 'wp_ajax_wpr_get_media_filtered_count', [ $this, 'wpr_get_media_filtered_count' ] );
+ add_action( 'wp_ajax_nopriv_wpr_get_media_filtered_count', [ $this, 'wpr_get_media_filtered_count' ] );
+ }
+
+ // Get Max Pages
+ public static function get_max_num_pages( $settings ) {
+ if ( isset( $_POST['wpr_url_params'] ) ) {
+ $query = new WP_Query( self::get_main_query_args( $settings, [] ) );
+ $max_num_pages = intval( ceil( $query->max_num_pages ) );
+
+ wp_reset_postdata();
+
+ return $max_num_pages;
+ } elseif ( isset( $_POST['grid_settings'] ) ) {
+ $query = new WP_Query( self::get_main_query_args( $settings, [] ) );
+ $max_num_pages = intval( ceil( $query->max_num_pages ) );
+
+ $adjusted_total_posts = max( 0, $query->found_posts - $query->query_vars['offset'] );
+ $number_of_pages = ceil( $adjusted_total_posts / $query->query_vars['posts_per_page'] );
+
+ wp_send_json_success( [
+ 'page_count' => $number_of_pages,
+ 'max_num_pages' => $max_num_pages,
+ 'query_found' => $query->found_posts,
+ 'query_offset' => $query->query_vars['offset'],
+ 'query_num' => $query->query_vars['posts_per_page'],
+ ] );
+
+ wp_reset_postdata();
+
+ return $max_num_pages;
+ }
+
+ $query = new WP_Query( self::get_main_query_args( $settings, [] ) );
+ $max_num_pages = intval( ceil( $query->max_num_pages ) );
+
+ wp_reset_postdata();
+
+ return $max_num_pages;
+ }
+
+ // Main Query Args
+ public static function get_main_query_args( $settings, $params ) {
+ $author = ! empty( $settings['query_author'] ) ? implode( ',', $settings['query_author'] ) : '';
+
+ if ( get_query_var( 'paged' ) ) {
+ $paged = get_query_var( 'paged' );
+ } elseif ( get_query_var( 'page' ) ) {
+ $paged = get_query_var( 'page' );
+ } else {
+ $paged = 1;
+ }
+
+ if ( empty( $settings['query_offset'] ) ) {
+ $settings['query_offset'] = 0;
+ }
+
+ $offset = ( $paged - 1 ) * $settings['query_posts_per_page'] + $settings['query_offset'];
+
+ if ( ! defined( 'WPR_ADDONS_PRO_VERSION' ) || ! w