diff --git a/README.txt b/README.txt index 2f846d3..b81bb26 100755 --- a/README.txt +++ b/README.txt @@ -5,7 +5,7 @@ Tags: infinite scroll, load more, ajax, lazy load, endless scroll, infinite scro Requires at least: 4.4 Requires PHP: 5.6 Tested up to: 6.1 -Stable tag: 5.6.0 +Stable tag: 5.6.0.1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -263,6 +263,12 @@ How to install Ajax Load More. == Changelog == += 5.6.0.1 - February 16, 2023 = +* FIX: Added security fix for missing escaping on various shortcode params. +* FIX: Added fix for new alm object parameter. +* UPDATE: HTML data-attribute clean up on rendered shortcode parameters. + + = 5.6.0 - February 14, 2023 = * NEW: Added new ajaxloadmore.click() public JS function to manually trigger an Ajax Load More load action from any element on the screen. * NEW: Added support for new Filter facets in Filters add-on version 2.0. diff --git a/ajax-load-more.php b/ajax-load-more.php index 45d69af..167b823 100755 --- a/ajax-load-more.php +++ b/ajax-load-more.php @@ -7,15 +7,15 @@ * Author: Darren Cooney * Twitter: @KaptonKaos * Author URI: https://connekthq.com - * Version: 5.6.0 + * Version: 5.6.0.1 * License: GPL * Copyright: Darren Cooney & Connekt Media * * @package AjaxLoadMore */ -define( 'ALM_VERSION', '5.6.0' ); -define( 'ALM_RELEASE', 'February 14, 2023' ); +define( 'ALM_VERSION', '5.6.0.1' ); +define( 'ALM_RELEASE', 'February 16, 2023' ); define( 'ALM_STORE_URL', 'https://connekthq.com' ); // Plugin installation helpers. diff --git a/core/classes/class-alm-noscript.php b/core/classes/class-alm-noscript.php index da32127..6257a50 100755 --- a/core/classes/class-alm-noscript.php +++ b/core/classes/class-alm-noscript.php @@ -172,7 +172,7 @@ public static function build_noscript_paging( $query = [], $filters = false, $pe * @return HTMLElement */ public static function render( $output, $container, $paging, $css_classes, $transition_container_classes ) { - return ( ! empty( $output ) ) ? '<' . self::$element . '><' . $container . ' class="alm-listing alm-noscript' . $css_classes . '">
' . $output . '
' . $paging . '' : ''; + return ( ! empty( $output ) ) ? '<' . esc_attr( self::$element ) . '><' . esc_attr( $container ) . ' class="alm-listing alm-noscript' . esc_attr( $css_classes ) . '">
' . $output . '
' . $paging . '' : ''; } /** diff --git a/core/classes/class-alm-shortcode.php b/core/classes/class-alm-shortcode.php index 9f62f90..9bc3efd 100755 --- a/core/classes/class-alm-shortcode.php +++ b/core/classes/class-alm-shortcode.php @@ -197,7 +197,7 @@ public static function alm_render_shortcode( $atts ) { 'scroll_container' => '', 'scroll_direction' => '', 'max_pages' => '0', - 'pause_override' => 'false', + 'pause_override' => '', 'pause' => 'false', 'destroy_after' => '', 'transition' => 'fade', @@ -533,9 +533,8 @@ public static function alm_render_shortcode( $atts ) { // Master ID - Manual or generated ALM ID. $master_id = empty( $id ) ? $div_id : $id; - // Unique ALM ID and object variable. - $unique_id = ! empty( $id ) ? 'data-id="' . $id . '"' : ''; - $alm_object_var = ! empty( $id ) ? 'data-alm-object="ajax_load_more_' . $id . '"' : ''; + // Unique ALM ID. + $unique_id = ! empty( $id ) ? 'data-id="' . $id . '"' : ''; // Search atts - Used with SEO. $is_search = is_search() ? 'data-search="true"' : ''; @@ -562,7 +561,7 @@ public static function alm_render_shortcode( $atts ) { } // Start $ajaxloadmore element. - $ajaxloadmore .= '
'; + $ajaxloadmore .= '
'; // Masonry Hook (Before). $ajaxloadmore .= apply_filters( 'alm_masonry_before', $transition ); @@ -584,7 +583,7 @@ public static function alm_render_shortcode( $atts ) { /** * WooCommerce hook to filter columns, per_page, classes etc * - * @return $config; + * @return array */ $woo_config = apply_filters( 'alm_woo_config', $woo_config ); @@ -636,9 +635,9 @@ public static function alm_render_shortcode( $atts ) { if ( ! empty( $custom_options ) ) { foreach ( $custom_options as $option ) { if ( isset( $option['name'] ) && $option['name'] === $woo_orderby_value ) { - $meta_key = ( isset( $option['meta_key'] ) ) ? wc_clean( $option['meta_key'] ) : $meta_key; - $orderby = ( isset( $option['orderby'] ) ) ? wc_clean( $option['orderby'] ) : $orderby; - $order = ( isset( $option['order'] ) ) ? wc_clean( $option['order'] ) : $order; + $meta_key = isset( $option['meta_key'] ) ? wc_clean( $option['meta_key'] ) : $meta_key; + $orderby = isset( $option['orderby'] ) ? wc_clean( $option['orderby'] ) : $orderby; + $order = isset( $option['order'] ) ? wc_clean( $option['order'] ) : $order; } } } @@ -844,7 +843,7 @@ public static function alm_render_shortcode( $atts ) { $post_id, $acf_parent_field_name ); - $ajaxloadmore .= $acf_return; + $ajaxloadmore .= wp_kses_post( $acf_return ); } // Cache Add-on. @@ -967,7 +966,6 @@ public static function alm_render_shortcode( $atts ) { // Preloaded Add-on. if ( has_action( 'alm_preload_installed' ) && $preloaded === 'true' ) { - $preloaded = $seo === 'true' && (int) $query_args['paged'] < 1 && $paging !== 'true' ? 'true' : esc_attr( $preloaded ); // SEO page 1. // SEO > page 1. @@ -1126,97 +1124,93 @@ public static function alm_render_shortcode( $atts ) { $ajaxloadmore .= $sticky_posts === 'true' ? ' data-sticky-posts="' . esc_attr( $sticky_posts ) . '"' : ''; // Post Format. - $ajaxloadmore .= ! empty( $post_format ) ? ' data-post-format="' . esc_attr( $post_format ) . '"' : ''; + $ajaxloadmore .= $post_format ? ' data-post-format="' . esc_attr( $post_format ) . '"' : ''; // Category. - $ajaxloadmore .= ! empty( $category ) ? ' data-category="' . esc_attr( $category ) . '"' : ''; - $ajaxloadmore .= ! empty( $category__and ) ? ' data-category-and="' . esc_attr( $category__and ) . '"' : ''; - $ajaxloadmore .= ! empty( $category__not_in ) ? ' data-category-not-in="' . esc_attr( $category__not_in ) . '"' : ''; + $ajaxloadmore .= $category ? ' data-category="' . esc_attr( $category ) . '"' : ''; + $ajaxloadmore .= $category__and ? ' data-category-and="' . esc_attr( $category__and ) . '"' : ''; + $ajaxloadmore .= $category__not_in ? ' data-category-not-in="' . esc_attr( $category__not_in ) . '"' : ''; // Tag. - $ajaxloadmore .= ! empty( $tag ) ? ' data-tag="' . esc_attr( $tag ) . '"' : ''; - $ajaxloadmore .= ! empty( $tag__and ) ? ' data-tag-and="' . esc_attr( $tag__and ) . '"' : ''; - $ajaxloadmore .= ! empty( $tag__not_in ) ? ' data-tag-not-in="' . esc_attr( $tag__not_in ) . '"' : ''; + $ajaxloadmore .= $tag ? ' data-tag="' . esc_attr( $tag ) . '"' : ''; + $ajaxloadmore .= $tag__and ? ' data-tag-and="' . esc_attr( $tag__and ) . '"' : ''; + $ajaxloadmore .= $tag__not_in ? ' data-tag-not-in="' . esc_attr( $tag__not_in ) . '"' : ''; // Taxonomy. - $ajaxloadmore .= ! empty( $taxonomy ) ? ' data-taxonomy="' . esc_attr( $taxonomy ) . '"' : ''; - $ajaxloadmore .= ! empty( $taxonomy_terms ) ? ' data-taxonomy-terms="' . esc_attr( $taxonomy_terms ) . '"' : ''; - $ajaxloadmore .= ! empty( $taxonomy_operator ) ? ' data-taxonomy-operator="' . esc_attr( $taxonomy_operator ) . '"' : ''; - $ajaxloadmore .= ! empty( $taxonomy_include_children ) ? ' data-taxonomy-include-children="' . esc_attr( $taxonomy_include_children ) . '"' : ''; - $ajaxloadmore .= ! empty( $taxonomy_relation ) ? ' data-taxonomy-relation="' . esc_attr( $taxonomy_relation ) . '"' : ''; + $ajaxloadmore .= $taxonomy ? ' data-taxonomy="' . esc_attr( $taxonomy ) . '"' : ''; + $ajaxloadmore .= $taxonomy_terms ? ' data-taxonomy-terms="' . esc_attr( $taxonomy_terms ) . '"' : ''; + $ajaxloadmore .= $taxonomy_operator ? ' data-taxonomy-operator="' . esc_attr( $taxonomy_operator ) . '"' : ''; + $ajaxloadmore .= $taxonomy_include_children ? ' data-taxonomy-include-children="' . esc_attr( $taxonomy_include_children ) . '"' : ''; + $ajaxloadmore .= $taxonomy_relation ? ' data-taxonomy-relation="' . esc_attr( $taxonomy_relation ) . '"' : ''; // Meta Query. - $ajaxloadmore .= ! empty( $meta_key ) ? ' data-meta-key="' . esc_attr( $meta_key ) . '"' : ''; - $ajaxloadmore .= ! empty( $meta_value || $meta_value === '0' ) ? ' data-meta-value="' . esc_attr( $meta_value ) . '"' : ''; - $ajaxloadmore .= ! empty( $meta_compare ) ? ' data-meta-compare="' . esc_attr( $meta_compare ) . '"' : ''; - $ajaxloadmore .= ! empty( $meta_relation ) ? ' data-meta-relation="' . esc_attr( $meta_relation ) . '"' : ''; - $ajaxloadmore .= ! empty( $meta_type ) ? ' data-meta-type="' . esc_attr( $meta_type ) . '"' : ''; + $ajaxloadmore .= $meta_key ? ' data-meta-key="' . esc_attr( $meta_key ) . '"' : ''; + $ajaxloadmore .= $meta_value || $meta_value === '0' ? ' data-meta-value="' . esc_attr( $meta_value ) . '"' : ''; + $ajaxloadmore .= $meta_compare ? ' data-meta-compare="' . esc_attr( $meta_compare ) . '"' : ''; + $ajaxloadmore .= $meta_relation ? ' data-meta-relation="' . esc_attr( $meta_relation ) . '"' : ''; + $ajaxloadmore .= $meta_type ? ' data-meta-type="' . esc_attr( $meta_type ) . '"' : ''; // Dates. - $ajaxloadmore .= ! empty( $year ) ? ' data-year="' . esc_attr( $year ) . '"' : ''; - $ajaxloadmore .= ! empty( $month ) ? ' data-month="' . esc_attr( $month ) . '"' : ''; - $ajaxloadmore .= ! empty( $day ) ? ' data-day="' . esc_attr( $day ) . '"' : ''; + $ajaxloadmore .= $year ? ' data-year="' . esc_attr( $year ) . '"' : ''; + $ajaxloadmore .= $month ? ' data-month="' . esc_attr( $month ) . '"' : ''; + $ajaxloadmore .= $day ? ' data-day="' . esc_attr( $day ) . '"' : ''; // Author. - $ajaxloadmore .= ! empty( $author ) ? ' data-author="' . esc_attr( $author ) . '"' : ''; + $ajaxloadmore .= $author ? ' data-author="' . esc_attr( $author ) . '"' : ''; // Post Parameters. - $ajaxloadmore .= ! empty( $post__in ) ? ' data-post-in="' . esc_attr( $post__in ) . '"' : ''; - $ajaxloadmore .= ! empty( $post__not_in ) ? ' data-post-not-in="' . esc_attr( $post__not_in ) . '"' : ''; - $ajaxloadmore .= ! empty( $exclude ) ? ' data-exclude="' . esc_attr( $exclude ) . '"' : ''; + $ajaxloadmore .= $post__in ? ' data-post-in="' . esc_attr( $post__in ) . '"' : ''; + $ajaxloadmore .= $post__not_in ? ' data-post-not-in="' . esc_attr( $post__not_in ) . '"' : ''; + $ajaxloadmore .= $exclude ? ' data-exclude="' . esc_attr( $exclude ) . '"' : ''; // Search. - $ajaxloadmore .= ! empty( $search ) ? ' data-search="' . esc_attr( $search ) . '"' : ''; + $ajaxloadmore .= $search ? ' data-search="' . esc_attr( $search ) . '"' : ''; // Custom Args. - $ajaxloadmore .= ! empty( $custom_args ) ? ' data-custom-args="' . esc_attr( $custom_args ) . '"' : ''; + $ajaxloadmore .= $custom_args ? ' data-custom-args="' . esc_attr( $custom_args ) . '"' : ''; // Vars. - $ajaxloadmore .= ! empty( $vars ) ? ' data-vars="' . esc_attr( $vars ) . '"' : ''; + $ajaxloadmore .= $vars ? ' data-vars="' . esc_attr( $vars ) . '"' : ''; // Status. - $ajaxloadmore .= ! empty( $post_status ) ? ' data-post-status="' . esc_attr( $post_status ) . '"' : ''; + $ajaxloadmore .= $post_status ? ' data-post-status="' . esc_attr( $post_status ) . '"' : ''; // Order. - $ajaxloadmore .= ' data-order="' . esc_attr( $order ) . '"'; - $ajaxloadmore .= ' data-orderby="' . esc_attr( $orderby ) . '"'; - - // Offset. - $ajaxloadmore .= ' data-offset="' . esc_attr( $offset ) . '"'; - - // Posts Per Page. - $ajaxloadmore .= ' data-posts-per-page="' . esc_attr( $posts_per_page ) . '"'; + $ajaxloadmore .= ' data-order="' . esc_attr( $order ) . '"'; // Order. + $ajaxloadmore .= ' data-orderby="' . esc_attr( $orderby ) . '"'; // Orderby. + $ajaxloadmore .= ' data-offset="' . esc_attr( $offset ) . '"'; // Offset. + $ajaxloadmore .= ' data-posts-per-page="' . esc_attr( $posts_per_page ) . '"'; // Posts Per Page. // Lang. - $ajaxloadmore .= ! empty( $lang ) ? ' data-lang="' . esc_attr( $lang ) . '"' : ''; + $ajaxloadmore .= $lang ? ' data-lang="' . esc_attr( $lang ) . '"' : ''; // Scroll. if ( $paging !== 'true' ) { - $ajaxloadmore .= ' data-scroll="' . esc_attr( $scroll ) . '"'; + $ajaxloadmore .= $scroll === 'false' ? ' data-scroll="false"' : ''; if ( $scroll === 'true' ) { $ajaxloadmore .= ' data-scroll-distance="' . esc_attr( $scroll_distance ) . '"'; - $ajaxloadmore .= ! empty( $scroll_container ) ? ' data-scroll-container="' . esc_attr( $scroll_container ) . '"' : ''; - $ajaxloadmore .= ! empty( $scroll_direction ) ? ' data-scroll-direction="' . esc_attr( $scroll_direction ) . '"' : ''; - $ajaxloadmore .= ' data-max-pages="' . $max_pages . '"'; - $ajaxloadmore .= ! empty( $pause_override ) ? ' data-pause-override="' . esc_attr( $pause_override ) . '"' : ''; + $ajaxloadmore .= $scroll_container ? ' data-scroll-container="' . esc_attr( $scroll_container ) . '"' : ''; + $ajaxloadmore .= $scroll_direction ? ' data-scroll-direction="' . esc_attr( $scroll_direction ) . '"' : ''; + $ajaxloadmore .= $max_pages && $max_pages !== '0' ? ' data-max-pages="' . esc_attr( $max_pages ) . '"' : ''; + $ajaxloadmore .= $pause_override ? ' data-pause-override="' . esc_attr( $pause_override ) . '"' : ''; } } // Pause. - $ajaxloadmore .= ' data-pause="' . esc_attr( $pause ) . '"'; + $ajaxloadmore .= $pause === 'true' ? ' data-pause="true"' : ''; // Button. $ajaxloadmore .= ' data-button-label="' . wp_kses_post( $button_label ) . '"'; - $ajaxloadmore .= ! empty( $button_loading_label ) ? ' data-button-loading-label="' . wp_kses_post( $button_loading_label ) . '"' : ''; - $ajaxloadmore .= ! empty( $button_done_label ) ? ' data-button-done-label="' . wp_kses_post( $button_done_label ) . '"' : ''; + $ajaxloadmore .= $button_loading_label ? ' data-button-loading-label="' . wp_kses_post( $button_loading_label ) . '"' : ''; + $ajaxloadmore .= $button_done_label ? ' data-button-done-label="' . wp_kses_post( $button_done_label ) . '"' : ''; // Destroy After. - $ajaxloadmore .= ! empty( $destroy_after ) ? ' data-destroy-after="' . esc_attr( $destroy_after ) . '"' : ''; + $ajaxloadmore .= $destroy_after ? ' data-destroy-after="' . esc_attr( $destroy_after ) . '"' : ''; // Transition. $ajaxloadmore .= $transition !== 'fade' ? ' data-transition="' . esc_attr( $transition ) . '"' : ''; $ajaxloadmore .= $transition_container === 'false' ? ' data-transition-container="' . esc_attr( $transition_container ) . '"' : ''; - $ajaxloadmore .= ! empty( $transition_container_classes ) ? ' data-transition-container-classes="' . esc_attr( $transition_container_classes ) . '"' : ''; + $ajaxloadmore .= $transition_container_classes ? ' data-transition-container-classes="' . esc_attr( $transition_container_classes ) . '"' : ''; // Masonry. if ( 'masonry' === $transition ) { @@ -1252,16 +1246,13 @@ public static function alm_render_shortcode( $atts ) { include ALM_PATH . 'core/classes/includes/preloaded.php'; } - // Single Post + // Single Post. // Get first post and append to alm object. if ( has_action( 'alm_single_post_installed' ) && $single_post ) { - $repeater_type = preg_split( '/(?=\d)/', $repeater, 2 ); // split $repeater at number to retrieve type. - $repeater_type = $repeater_type[0]; // default / repeater / template_{x} . + $repeater_type = $repeater_type[0]; // default / repeater / template_{x}. + $repeater_type = $theme_repeater !== 'null' && has_filter( 'alm_get_theme_repeater' ) ? null : $repeater_type; - if ( $theme_repeater !== 'null' && has_filter( 'alm_get_theme_repeater' ) ) { - $repeater_type = null; - } // Get current permalink - (including querystring). $single_post_permanlink = $_SERVER['QUERY_STRING'] ? get_permalink( $single_post_id ) . '?' . esc_attr( $_SERVER['QUERY_STRING'] ) : get_permalink( $single_post_id ); @@ -1280,7 +1271,6 @@ public static function alm_render_shortcode( $atts ) { $single_post_output .= '
'; $ajaxloadmore .= $single_post_output; // Append $single_post_output data to $ajaxloadmore. - } // Next Page Add-on. @@ -1296,14 +1286,13 @@ public static function alm_render_shortcode( $atts ) { $nextpage_is_paged = apply_filters( 'alm_nextpage_paged', $nextpage_is_paged ); $ajaxloadmore .= apply_filters( 'alm_init_nextpage', $nextpage_post_id, $nextpage_start, $nextpage_is_paged, $paging, $div_id, $id, $nested ); - } // Masonry Hook (After). $ajaxloadmore .= apply_filters( 'alm_masonry_after', $transition ); // Close ALM container element. - $ajaxloadmore .= ''; + $ajaxloadmore .= ''; // Create Placeholder. $ajaxloadmore .= self::alm_render_placeholder( $placeholder, $paging ); @@ -1344,7 +1333,7 @@ public static function alm_render_shortcode( $atts ) { // No results text. if ( $no_results_text !== '' && ! empty( $no_results_text ) ) { - $ajaxloadmore .= ''; + $ajaxloadmore .= ''; } // Render