From ed45cbea66640d710cb7deea4538949d2b08e7da Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 6 Aug 2021 11:17:33 +0300 Subject: [PATCH 01/24] - changed readme; --- readme.txt | 11 ++++++++++- ultimate-member.php | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index 79bfb992..f179abf2 100644 --- a/readme.txt +++ b/readme.txt @@ -155,11 +155,20 @@ The plugin works with popular caching plugins by automatically excluding Ultimat * To learn more about version 2.1 please see this [docs](https://docs.ultimatemember.com/article/1512-upgrade-2-1-0) * UM2.1+ is a significant update to the Member Directories' code base from 2.0.x. Please make sure you take a full-site backup with restore point before updating the plugin -= 2.2.3: August 4, 2021 = += 2.2.3: August 11, 2021 = + +* Enhancements: + + - Added: 'um_ignore_restricted_title' hook for workaround show post title of the restricted post * Bugfixes: - Fixed: `pre_get_terms` callback to avoid the conflicts with other terms queries + - Fixed: Terms query and global access settings on PHP8 installations + - Fixed: Member directory dropdown filters where options contain `&` symbol + - Fixed: Displaying 404 error for the restricted Media + - Fixed: Displaying 'Login as this user' action on the user profile + - Fixed: Sanitizing of the social links fields (e.g. Twitter, Facebook, etc.) = 2.2.2: August 3, 2021 = diff --git a/ultimate-member.php b/ultimate-member.php index 6abe8418..b6f88f91 100644 --- a/ultimate-member.php +++ b/ultimate-member.php @@ -3,7 +3,7 @@ Plugin Name: Ultimate Member Plugin URI: http://ultimatemember.com/ Description: The easiest way to create powerful online communities and beautiful user profiles with WordPress -Version: 2.2.3-beta +Version: 2.2.3-beta2 Author: Ultimate Member Author URI: http://ultimatemember.com/ Text Domain: ultimate-member From f2244a7383dbcc41f9495b0a5144e668651538dd Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 6 Aug 2021 14:25:05 +0300 Subject: [PATCH 02/24] - avoid restriction for the post author; --- includes/core/class-access.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 43f7ac18..2b265a57 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -946,6 +946,11 @@ if ( ! class_exists( 'um\core\Access' ) ) { $original_post = $post; + if ( is_user_logged_in() && isset( $post->post_author ) && $post->post_author == get_current_user_id() ) { + $filtered_posts[] = $post; + continue; + } + //Woocommerce AJAX fixes....remove filtration on wc-ajax which goes to Front Page if ( ! empty( $_GET['wc-ajax'] ) && defined( 'WC_DOING_AJAX' ) && WC_DOING_AJAX ) { $filtered_posts[] = $post; @@ -1643,6 +1648,12 @@ if ( ! class_exists( 'um\core\Access' ) ) { return false; } + $post = get_post( $post_id ); + if ( is_user_logged_in() && isset( $post->post_author ) && $post->post_author == get_current_user_id() ) { + $cache[ $post_id ] = false; + return false; + } + $restricted = true; $restriction = $this->get_post_privacy_settings( $post_id ); From 967566157b9b8eae5e8ac735753cb037b4f7900e Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 6 Aug 2021 14:38:48 +0300 Subject: [PATCH 03/24] - fixed post title for restricted post in the User Profile > Posts tab; --- templates/profile/posts-single.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/profile/posts-single.php b/templates/profile/posts-single.php index 114cc3e1..1ad20541 100644 --- a/templates/profile/posts-single.php +++ b/templates/profile/posts-single.php @@ -3,7 +3,7 @@
ID ) ) { @@ -39,4 +39,4 @@
- \ No newline at end of file + From 3c0e4d458de1458a0239b9532958b497912c3f5c Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Fri, 6 Aug 2021 14:52:50 +0300 Subject: [PATCH 04/24] - fixed search query and restricted posts. Avoid parsing posts via the search query --- includes/core/class-access.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 2b265a57..2108de7d 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -1423,7 +1423,8 @@ if ( ! class_exists( 'um\core\Access' ) ) { */ function exclude_posts( $query ) { if ( $query->is_main_query() ) { - $exclude_posts = $this->exclude_posts_array( is_admin() ); + $force = is_search() || is_admin(); + $exclude_posts = $this->exclude_posts_array( $force ); if ( ! empty( $exclude_posts ) ) { $post__not_in = $query->get( 'post__not_in', array() ); $query->set( 'post__not_in', array_merge( wp_parse_id_list( $post__not_in ), $exclude_posts ) ); From a61ee881e102aafc687b8bc0ff244fcd680cc6da Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Mon, 9 Aug 2021 14:38:21 +0300 Subject: [PATCH 05/24] - added filters for extending restricted posts/terms IDs; --- includes/core/class-access.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 2108de7d..bd90d46d 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -181,6 +181,8 @@ if ( ! class_exists( 'um\core\Access' ) ) { } } + $exclude = apply_filters( 'um_exclude_restricted_terms_ids', $exclude ); + $cache = $exclude; return $exclude; } @@ -1411,6 +1413,8 @@ if ( ! class_exists( 'um\core\Access' ) ) { } } + $exclude_posts = apply_filters( 'um_exclude_restricted_posts_ids', $exclude_posts, $force ); + $cache[ $cache_key ] = $exclude_posts; return $exclude_posts; } From 0a15e221e168d62f273548110c44269b734c65f3 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Mon, 9 Aug 2021 14:43:13 +0300 Subject: [PATCH 06/24] - added hooks for individual checking post/term if it's restricted; --- includes/core/class-access.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index bd90d46d..82d97361 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -1693,6 +1693,8 @@ if ( ! class_exists( 'um\core\Access' ) ) { } } + $restricted = apply_filters( 'um_is_restricted_post', $restricted, $post_id ); + $cache[ $post_id ] = $restricted; return $restricted; @@ -1782,6 +1784,8 @@ if ( ! class_exists( 'um\core\Access' ) ) { } } + $restricted = apply_filters( 'um_is_restricted_term', $restricted, $term_id, $on_term_page ); + $cache[ $term_id ] = $restricted; return $restricted; } From 15f8f7578076d74dedb0a6ba16cf4a5d5851b7f8 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Tue, 10 Aug 2021 15:34:45 +0300 Subject: [PATCH 07/24] - fixed visibility of a restricted taxonomy page in the nav menu; --- includes/core/class-access.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 82d97361..055a30b0 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -1855,15 +1855,22 @@ if ( ! class_exists( 'um\core\Access' ) ) { //other filter foreach ( $menu_items as $menu_item ) { if ( ! empty( $menu_item->object_id ) && ! empty( $menu_item->object ) ) { - if ( ! $this->is_restricted( $menu_item->object_id ) ) { - $filtered_items[] = $menu_item; - continue; - } else { - $restriction_settings = $this->get_post_privacy_settings( $menu_item->object_id ); - if ( empty( $restriction_settings['_um_access_hide_from_queries'] ) ) { + if ( isset( $menu_item->type ) && 'taxonomy' === $menu_item->type ) { + if ( ! $this->is_restricted_term( $menu_item->object_id ) ) { $filtered_items[] = $menu_item; continue; } + } elseif ( isset( $menu_item->type ) && 'post_type' === $menu_item->type ) { + if ( ! $this->is_restricted( $menu_item->object_id ) ) { + $filtered_items[] = $menu_item; + continue; + } else { + $restriction_settings = $this->get_post_privacy_settings( $menu_item->object_id ); + if ( empty( $restriction_settings['_um_access_hide_from_queries'] ) ) { + $filtered_items[] = $menu_item; + continue; + } + } } } else { //add all other posts From 6fc7ed76869c11366dd2d804889f31260cb7a563 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Tue, 10 Aug 2021 16:20:14 +0300 Subject: [PATCH 08/24] - fixed sanitizing key for the drag&drop action; --- includes/admin/core/class-admin-dragdrop.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/core/class-admin-dragdrop.php b/includes/admin/core/class-admin-dragdrop.php index 60dab8fd..02f68e9e 100644 --- a/includes/admin/core/class-admin-dragdrop.php +++ b/includes/admin/core/class-admin-dragdrop.php @@ -60,7 +60,7 @@ if ( ! class_exists( 'um\admin\core\Admin_DragDrop' ) ) { foreach ( $_POST as $key => $value ) { - $key = sanitize_key( $key ); + $key = sanitize_text_field( $key ); // adding rows if ( 0 === strpos( $key, '_um_row_' ) ) { From 6a3f55b8a70141e8151cbff5bb93357b5d8bea6c Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Wed, 11 Aug 2021 13:17:48 +0300 Subject: [PATCH 09/24] - fixed sanitizing the description field with allowed HTML inside; --- includes/admin/core/class-admin-dragdrop.php | 2 +- includes/core/class-form.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/core/class-admin-dragdrop.php b/includes/admin/core/class-admin-dragdrop.php index 02f68e9e..18504e58 100644 --- a/includes/admin/core/class-admin-dragdrop.php +++ b/includes/admin/core/class-admin-dragdrop.php @@ -59,7 +59,7 @@ if ( ! class_exists( 'um\admin\core\Admin_DragDrop' ) ) { } foreach ( $_POST as $key => $value ) { - + // don't use sanitize_key here because of a key can be in Uppercase $key = sanitize_text_field( $key ); // adding rows diff --git a/includes/core/class-form.php b/includes/core/class-form.php index 0f8081ce..e8aa6c02 100644 --- a/includes/core/class-form.php +++ b/includes/core/class-form.php @@ -579,7 +579,7 @@ if ( ! class_exists( 'um\core\Form' ) ) { $form[ $k ] = (int) $form[ $k ]; break; case 'textarea': - if ( ! empty( $field['html'] ) ) { + if ( ! empty( $field['html'] ) || ( UM()->profile()->get_show_bio_key( $form ) === $k && UM()->options()->get( 'profile_show_html_bio' ) ) ) { $form[ $k ] = wp_kses_post( $form[ $k ] ); } else { $form[ $k ] = sanitize_textarea_field( $form[ $k ] ); From 519beefacec7686297b5a1ce354b34705dfaa9b6 Mon Sep 17 00:00:00 2001 From: ashubawork <43743394+ashubawork@users.noreply.github.com> Date: Thu, 12 Aug 2021 12:04:37 +0300 Subject: [PATCH 10/24] - fixed the "Assignment to constant variable" JS error on some sites --- assets/js/um-modal.js | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/js/um-modal.js b/assets/js/um-modal.js index 96f376f6..01e6fb4b 100644 --- a/assets/js/um-modal.js +++ b/assets/js/um-modal.js @@ -102,6 +102,7 @@ jQuery(document).ready(function() { user_id = jQuery(this).parents('#um_upload_single').data('user_id'); } + var d; var form_id = 0; var mode = ''; if ( jQuery('div.um-field-image[data-key="' + key + '"]').length === 1 ) { From 9d1414f4884897da2a66785d2cc3206a4e5011da Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Thu, 12 Aug 2021 12:53:30 +0300 Subject: [PATCH 11/24] - fixed restricted posts/terms query; --- includes/core/class-access.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 055a30b0..f29797b5 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -151,8 +151,9 @@ if ( ! class_exists( 'um\core\Access' ) ) { $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); if ( empty( $restricted_taxonomies ) ) { - $cache = array(); - return array(); + $exclude = apply_filters( 'um_exclude_restricted_terms_ids', array() ); + $cache = $exclude; + return $exclude; } $this->ignore_terms_exclude = true; @@ -170,8 +171,9 @@ if ( ! class_exists( 'um\core\Access' ) ) { $this->ignore_terms_exclude = false; if ( empty( $term_ids ) || is_wp_error( $term_ids ) ) { - $cache = array(); - return array(); + $exclude = apply_filters( 'um_exclude_restricted_terms_ids', array() ); + $cache = $exclude; + return $exclude; } $exclude = array(); @@ -1283,6 +1285,10 @@ if ( ! class_exists( 'um\core\Access' ) ) { * @return array */ function exclude_posts_array( $force = false ) { + if ( $this->ignore_exclude ) { + return array(); + } + static $cache = array( 'force' => false, 'default' => false, @@ -1295,7 +1301,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { } $exclude_posts = array(); - if ( current_user_can( 'administrator' ) || $this->ignore_exclude ) { + if ( current_user_can( 'administrator' ) ) { $cache[ $cache_key ] = $exclude_posts; return $exclude_posts; } From 057d46400f124cda8bfc2705976ec0ec784c178a Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Thu, 12 Aug 2021 12:59:58 +0300 Subject: [PATCH 12/24] - minified script; --- assets/js/um-modal.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/um-modal.min.js b/assets/js/um-modal.min.js index 980083c0..049c896f 100644 --- a/assets/js/um-modal.min.js +++ b/assets/js/um-modal.min.js @@ -1 +1 @@ -jQuery(document).ready(function(){jQuery(document).on("click",".um-popup-overlay",function(){remove_Modal()}),jQuery(document).on("click",'.um-modal-overlay, a[data-action="um_remove_modal"]',function(){um_remove_modal()}),jQuery(document).on("click",'a[data-modal^="um_"], span[data-modal^="um_"], .um-modal:not(:has(.um-form)) a',function(e){return e.preventDefault(),!1}),jQuery(document).on("click",".um-modal .um-single-file-preview a.cancel",function(e){e.preventDefault();var a=jQuery(this).parents(".um-modal-body"),t=jQuery(this).parents(".um-modal-body").find(".um-single-fileinfo a").attr("href"),i=a.find(".um-single-file-upload").data("set_mode");return jQuery.ajax({url:wp.ajax.settings.url,type:"post",data:{action:"um_remove_file",src:t,mode:i,nonce:um_scripts.nonce},success:function(){a.find(".um-single-file-preview").hide(),a.find(".ajax-upload-dragdrop").show(),a.find(".um-modal-btn.um-finish-upload").addClass("disabled"),um_modal_responsive()}}),!1}),jQuery(document).on("click",".um-modal .um-single-image-preview a.cancel",function(e){e.preventDefault();var a=jQuery(this).parents(".um-modal-body"),t=jQuery(this).parents(".um-modal-body").find(".um-single-image-preview img").attr("src"),i=a.find(".um-single-image-upload").data("set_mode");return jQuery.ajax({url:wp.ajax.settings.url,type:"post",data:{action:"um_remove_file",src:t,mode:i,nonce:um_scripts.nonce},success:function(){jQuery("img.cropper-hidden").cropper("destroy"),a.find(".um-single-image-preview img").attr("src",""),a.find(".um-single-image-preview").hide(),a.find(".ajax-upload-dragdrop").show(),a.find(".um-modal-btn.um-finish-upload").addClass("disabled"),um_modal_responsive()}}),!1}),jQuery(document).on("click",".um-finish-upload.file:not(.disabled)",function(){var e=jQuery(this).attr("data-key"),a=jQuery(this).parents(".um-modal-body").find(".um-single-file-preview").html();um_remove_modal(),jQuery(".um-single-file-preview[data-key="+e+"]").fadeIn().html(a);var t=jQuery(".um-field[data-key="+e+"]").find(".um-single-fileinfo a").data("file");jQuery(".um-single-file-preview[data-key="+e+"]").parents(".um-field").find(".um-btn-auto-width").html(jQuery(this).attr("data-change")),jQuery(".um-single-file-preview[data-key="+e+"]").parents(".um-field").find('input[type="hidden"]').val(t)}),jQuery(document).on("click",".um-finish-upload.image:not(.disabled)",function(){var a=jQuery(this),t=jQuery(this).attr("data-key"),e=jQuery(this).parents(".um-modal-body").find(".um-single-image-preview"),i=e.find("img").attr("src"),r=e.attr("data-coord"),u=e.find("img").data("file"),m=0;jQuery(this).parents("#um_upload_single").data("user_id")&&(m=jQuery(this).parents("#um_upload_single").data("user_id"));var n=0,o="";if(1===jQuery('div.um-field-image[data-key="'+t+'"]').length){var s=jQuery('div.um-field-image[data-key="'+t+'"]').closest(".um-form");n=s.find('input[name="form_id"]').val(),o=s.attr("data-mode")}r?(jQuery(this).html(jQuery(this).attr("data-processing")).addClass("disabled"),jQuery.ajax({url:wp.ajax.settings.url,type:"POST",dataType:"json",data:{action:"um_resize_image",src:i,coord:r,user_id:m,key:t,set_id:n,set_mode:o,nonce:um_scripts.nonce},success:function(e){e.success&&(d=new Date,"profile_photo"===t?jQuery(".um-profile-photo-img img").attr("src",e.data.image.source_url+"?"+d.getTime()):"cover_photo"===t&&(jQuery(".um-cover-e").empty().html(''),jQuery(".um").hasClass("um-editing")&&jQuery(".um-cover-overlay").show()),jQuery(".um-single-image-preview[data-key="+t+"]").fadeIn().find("img").attr("src",e.data.image.source_url+"?"+d.getTime()),um_remove_modal(),jQuery("img.cropper-invisible").remove(),jQuery(".um-single-image-preview[data-key="+t+"]").parents(".um-field").find(".um-btn-auto-width").html(a.attr("data-change")),jQuery(".um-single-image-preview[data-key="+t+"]").parents(".um-field").find('input[type="hidden"]').val(e.data.image.filename))}})):(d=new Date,jQuery(".um-single-image-preview[data-key="+t+"]").fadeIn().find("img").attr("src",i+"?"+d.getTime()),um_remove_modal(),jQuery(".um-single-image-preview[data-key="+t+"]").parents(".um-field").find(".um-btn-auto-width").html(a.attr("data-change")),jQuery(".um-single-image-preview[data-key="+t+"]").parents(".um-field").find("input[type=hidden]").val(u))}),jQuery(document.body).on("click",'a[data-modal^="um_"], span[data-modal^="um_"]',function(e){var a=jQuery(this).attr("data-modal"),t="normal";jQuery(this).data("modal-size")&&(t=jQuery(this).data("modal-size")),jQuery(this).data("modal-copy")&&(jQuery("#"+a).html(jQuery(this).parents(".um-field").find(".um-modal-hidden-content").html()),jQuery(this).parents(".um-profile-photo").attr("data-user_id")&&jQuery("#"+a).attr("data-user_id",jQuery(this).parents(".um-profile-photo").attr("data-user_id")),jQuery(this).parents(".um-cover").attr("data-ratio")&&jQuery("#"+a).attr("data-ratio",jQuery(this).parents(".um-cover").attr("data-ratio")),jQuery(this).parents(".um-cover").attr("data-user_id")&&jQuery("#"+a).attr("data-user_id",jQuery(this).parents(".um-cover").attr("data-user_id")),0'),jQuery(".um").hasClass("um-editing")&&jQuery(".um-cover-overlay").show()),jQuery(".um-single-image-preview[data-key="+i+"]").fadeIn().find("img").attr("src",e.data.image.source_url+"?"+a.getTime()),um_remove_modal(),jQuery("img.cropper-invisible").remove(),jQuery(".um-single-image-preview[data-key="+i+"]").parents(".um-field").find(".um-btn-auto-width").html(t.attr("data-change")),jQuery(".um-single-image-preview[data-key="+i+"]").parents(".um-field").find('input[type="hidden"]').val(e.data.image.filename))}})):(a=new Date,jQuery(".um-single-image-preview[data-key="+i+"]").fadeIn().find("img").attr("src",r+"?"+a.getTime()),um_remove_modal(),jQuery(".um-single-image-preview[data-key="+i+"]").parents(".um-field").find(".um-btn-auto-width").html(t.attr("data-change")),jQuery(".um-single-image-preview[data-key="+i+"]").parents(".um-field").find("input[type=hidden]").val(d))}),jQuery(document.body).on("click",'a[data-modal^="um_"], span[data-modal^="um_"]',function(e){var a=jQuery(this).attr("data-modal"),t="normal";jQuery(this).data("modal-size")&&(t=jQuery(this).data("modal-size")),jQuery(this).data("modal-copy")&&(jQuery("#"+a).html(jQuery(this).parents(".um-field").find(".um-modal-hidden-content").html()),jQuery(this).parents(".um-profile-photo").attr("data-user_id")&&jQuery("#"+a).attr("data-user_id",jQuery(this).parents(".um-profile-photo").attr("data-user_id")),jQuery(this).parents(".um-cover").attr("data-ratio")&&jQuery("#"+a).attr("data-ratio",jQuery(this).parents(".um-cover").attr("data-ratio")),jQuery(this).parents(".um-cover").attr("data-user_id")&&jQuery("#"+a).attr("data-user_id",jQuery(this).parents(".um-cover").attr("data-user_id")),0 Date: Thu, 12 Aug 2021 14:39:50 +0300 Subject: [PATCH 13/24] - fixed stripping tags in the biography field; --- includes/core/class-fields.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/core/class-fields.php b/includes/core/class-fields.php index aa10f02e..d2f4f505 100644 --- a/includes/core/class-fields.php +++ b/includes/core/class-fields.php @@ -2591,7 +2591,8 @@ if ( ! class_exists( 'um\core\Fields' ) ) { $output .= ob_get_clean(); $output .= '
' . $placeholder . ''; } else { - $output .= ''; + $textarea_field_value = ! empty( $data['html'] ) ? $field_value : strip_tags( $field_value ); + $output .= ''; } $output .= ''; From c8a09caef48440445fd92c22e121198621a0ad04 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Thu, 12 Aug 2021 15:57:21 +0300 Subject: [PATCH 14/24] - fixed posts query in the User Profile; --- includes/core/class-access.php | 2 +- includes/core/class-user-posts.php | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index f29797b5..b9819cdc 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -1432,7 +1432,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { * @param \WP_Query $query */ function exclude_posts( $query ) { - if ( $query->is_main_query() ) { + if ( $query->is_main_query() || ! empty( $query->query_vars['um_main_query'] ) ) { $force = is_search() || is_admin(); $exclude_posts = $this->exclude_posts_array( $force ); if ( ! empty( $exclude_posts ) ) { diff --git a/includes/core/class-user-posts.php b/includes/core/class-user-posts.php index 33fb2374..afd50a03 100644 --- a/includes/core/class-user-posts.php +++ b/includes/core/class-user-posts.php @@ -29,11 +29,12 @@ if ( ! class_exists( 'um\core\User_posts' ) ) { */ function add_posts() { $args = array( - 'post_type' => 'post', - 'posts_per_page' => 10, - 'offset' => 0, - 'author' => um_get_requested_user(), - 'post_status' => array( 'publish' ) + 'post_type' => 'post', + 'posts_per_page' => 10, + 'offset' => 0, + 'author' => um_get_requested_user(), + 'post_status' => array( 'publish' ), + 'um_main_query' => true, ); /** @@ -107,11 +108,12 @@ if ( ! class_exists( 'um\core\User_posts' ) ) { $page = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 0; $args = array( - 'post_type' => 'post', - 'posts_per_page' => 10, - 'offset' => ( $page - 1 ) * 10, - 'author' => $author, - 'post_status' => array( 'publish' ) + 'post_type' => 'post', + 'posts_per_page' => 10, + 'offset' => ( $page - 1 ) * 10, + 'author' => $author, + 'post_status' => array( 'publish' ), + 'um_main_query' => true, ); /** From 8805d1fd6ff6ea2f37d7cc16997f27dc278a562f Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Thu, 12 Aug 2021 16:38:56 +0300 Subject: [PATCH 15/24] - fixed Invalid taxonomy issue in query; --- includes/core/class-access.php | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index b9819cdc..95817ef1 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -150,6 +150,16 @@ if ( ! class_exists( 'um\core\Access' ) ) { } $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); + if ( ! empty( $restricted_taxonomies ) ) { + $restricted_taxonomies = array_keys( $restricted_taxonomies ); + foreach ( $restricted_taxonomies as $k => $taxonomy ) { + if ( ! taxonomy_exists( $taxonomy ) ) { + unset( $restricted_taxonomies[ $k ] ); + } + } + $restricted_taxonomies = array_values( $restricted_taxonomies ); + } + if ( empty( $restricted_taxonomies ) ) { $exclude = apply_filters( 'um_exclude_restricted_terms_ids', array() ); $cache = $exclude; @@ -159,7 +169,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { $this->ignore_terms_exclude = true; $term_ids = get_terms( array( - 'taxonomy' => array_keys( $restricted_taxonomies ), + 'taxonomy' => $restricted_taxonomies, 'hide_empty' => false, 'fields' => 'ids', 'meta_query' => array( @@ -168,6 +178,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { ), ) ); + $this->ignore_terms_exclude = false; if ( empty( $term_ids ) || is_wp_error( $term_ids ) ) { @@ -1337,13 +1348,24 @@ if ( ! class_exists( 'um\core\Access' ) ) { $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); if ( ! empty( $restricted_taxonomies ) ) { + $restricted_taxonomies = array_keys( $restricted_taxonomies ); + foreach ( $restricted_taxonomies as $k => $taxonomy ) { + if ( ! taxonomy_exists( $taxonomy ) ) { + unset( $restricted_taxonomies[ $k ] ); + } + } + $restricted_taxonomies = array_values( $restricted_taxonomies ); + } + + if ( ! empty( $restricted_taxonomies ) ) { + $terms = $wpdb->get_results( "SELECT tm.term_id AS term_id, tt.taxonomy AS taxonomy FROM {$wpdb->termmeta} tm LEFT JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = tm.term_id WHERE tm.meta_key = 'um_content_restriction' AND - tt.taxonomy IN('" . implode( "','", array_keys( $restricted_taxonomies ) ) . "')", + tt.taxonomy IN('" . implode( "','", $restricted_taxonomies ) . "')", ARRAY_A ); From d970f54c8e96883d5ea38682be4c59bdc086166d Mon Sep 17 00:00:00 2001 From: yuriinalivaiko Date: Sun, 15 Aug 2021 17:29:44 +0300 Subject: [PATCH 16/24] Keep description formatting in a view mode. --- includes/core/class-fields.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/includes/core/class-fields.php b/includes/core/class-fields.php index d2f4f505..80e24674 100644 --- a/includes/core/class-fields.php +++ b/includes/core/class-fields.php @@ -2416,10 +2416,10 @@ if ( ! class_exists( 'um\core\Fields' ) ) { } elseif( isset( $data['label'] ) ) { $placeholder = sprintf( __( 'Confirm %s', 'ultimate-member' ), $data['label'] ); } - + $output .= ''; - + $output .= ''; @@ -2622,7 +2622,7 @@ if ( ! class_exists( 'um\core\Fields' ) ) { $output .= '
'; $output .= ''; - + if ( $this->is_error( $key ) ) { $output .= $this->field_error( $this->show_error( $key ) ); } elseif ( $this->is_notice( $key ) ) { @@ -4123,6 +4123,9 @@ if ( ! class_exists( 'um\core\Fields' ) ) { if ( ! empty( $res ) ) { $res = stripslashes( $res ); } + if ( 'description' === $data['metakey'] ) { + $res = nl2br( $res ); + } $data['is_view_field'] = true; /** From 41deba974adeb38fcb594149936711d61896e72b Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Wed, 18 Aug 2021 14:04:21 +0300 Subject: [PATCH 17/24] - optimized restriction handlers; --- includes/core/class-access.php | 2373 ++++++++--------- includes/core/class-external-integrations.php | 27 +- 2 files changed, 1206 insertions(+), 1194 deletions(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 95817ef1..9594e258 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -35,14 +35,6 @@ if ( ! class_exists( 'um\core\Access' ) ) { private $allow_access; - /** - * @var \WP_Post - */ - private $current_single_post; - - - private $ignore_terms_exclude = false; - private $ignore_exclude = false; @@ -55,62 +47,389 @@ if ( ! class_exists( 'um\core\Access' ) ) { $this->redirect_handler = false; $this->allow_access = false; - // callbacks for changing posts query - add_action( 'pre_get_posts', array( &$this, 'exclude_posts' ), 99, 1 ); - - add_filter( 'posts_where', array( &$this, 'exclude_posts_where' ), 10, 2 ); - - add_filter( 'get_next_post_where', array( &$this, 'exclude_navigation_posts' ), 99, 5 ); - add_filter( 'get_previous_post_where', array( &$this, 'exclude_navigation_posts' ), 99, 5 ); - add_filter( 'widget_posts_args', array( &$this, 'exclude_restricted_posts_widget' ), 99, 1 ); - - add_filter( 'wp_count_posts', array( &$this, 'custom_count_posts_handler' ), 99, 3 ); - add_filter( 'getarchives_where', array( &$this, 'exclude_restricted_posts_archives_widget' ), 99, 2 ); + // NEW HOOKS // callbacks for changing terms query add_action( 'pre_get_terms', array( &$this, 'exclude_hidden_terms_query' ), 99, 1 ); - // callbacks for changing comments query - add_action( 'pre_get_comments', array( &$this, 'exclude_posts_comments' ), 99, 1 ); - add_filter( 'comment_feed_where', array( &$this, 'exclude_posts_comments_feed' ), 99, 2 ); - add_filter( 'wp_count_comments', array( &$this, 'custom_comments_count_handler' ), 99, 2 ); - /* Disable comments if user has not permission to access current post */ - add_filter( 'comments_open', array( $this, 'disable_comments_open' ), 99, 2 ); - add_filter( 'get_comments_number', array( $this, 'disable_comments_open_number' ), 99, 2 ); + // Change recent posts widget query + add_filter( 'widget_posts_args', array( &$this, 'exclude_restricted_posts_widget' ), 99, 1 ); + // Exclude pages displayed by wp_list_pages function + add_filter( 'wp_list_pages_excludes', array( &$this, 'exclude_restricted_pages' ), 10, 1 ); + // Archives list change where based on restricted posts + add_filter( 'getarchives_where', array( &$this, 'exclude_restricted_posts_archives_widget' ), 99, 2 ); - //there is posts (Posts/Page/CPT) filtration if site is accessible - //there also will be redirects if they need - //protect posts types - add_filter( 'the_posts', array( &$this, 'filter_protected_posts' ), 99, 2 ); - //protect pages for wp_list_pages func - add_filter( 'get_pages', array( &$this, 'filter_protected_posts' ), 99, 2 ); + // Navigation line below the post content, change query to exclude restricted + add_filter( 'get_next_post_where', array( &$this, 'exclude_navigation_posts' ), 99, 5 ); + add_filter( 'get_previous_post_where', array( &$this, 'exclude_navigation_posts' ), 99, 5 ); + // callbacks for changing posts query + add_action( 'pre_get_posts', array( &$this, 'exclude_posts' ), 99, 1 ); + add_filter( 'posts_where', array( &$this, 'exclude_posts_where' ), 10, 2 ); + add_filter( 'wp_count_posts', array( &$this, 'custom_count_posts_handler' ), 99, 3 ); + + // change the title of the post add_filter( 'the_title', array( &$this, 'filter_restricted_post_title' ), 10, 2 ); + // change the content of the restricted post + add_filter( 'the_content', array( &$this, 'filter_restricted_post_content' ), 999999, 1 ); + // change the excerpt of the restricted post + add_filter( 'get_the_excerpt', array( &$this, 'filter_restricted_post_excerpt' ), 999999, 2 ); - //filter menu items - add_filter( 'wp_nav_menu_objects', array( &$this, 'filter_menu' ), 99, 2 ); - // blocks restrictions - add_filter( 'render_block', array( $this, 'restrict_blocks' ), 10, 2 ); - - //filter attachment + // filter attachment add_filter( 'wp_get_attachment_url', array( &$this, 'filter_attachment' ), 99, 2 ); add_filter( 'has_post_thumbnail', array( &$this, 'filter_post_thumbnail' ), 99, 3 ); - // turn on/off content replacement on the filter 'the_content' - add_action( 'get_header', array( &$this, 'replace_post_content_on' ), 12 ); - add_action( 'get_footer', array( &$this, 'replace_post_content_off' ), 8 ); - // turn on/off content replacement on the filter 'the_content' with the theme "Avada" - add_action( 'avada_before_body_content', array( &$this, 'replace_post_content_off' ), 8 ); - add_action( 'avada_before_main_container', array( &$this, 'replace_post_content_on' ), 12 ); - add_action( 'avada_after_main_content', array( &$this, 'replace_post_content_off' ), 8 ); + // comments queries + add_action( 'pre_get_comments', array( &$this, 'exclude_posts_comments' ), 99, 1 ); + add_filter( 'wp_count_comments', array( &$this, 'custom_comments_count_handler' ), 99, 2 ); + // comments RSS + add_filter( 'comment_feed_where', array( &$this, 'exclude_posts_comments_feed' ), 99, 2 ); + // Disable comments if user has not permission to access current post + add_filter( 'comments_open', array( $this, 'disable_comments_open' ), 99, 2 ); + add_filter( 'get_comments_number', array( $this, 'disable_comments_open_number' ), 99, 2 ); - //check the site's accessible more priority have Individual Post/Term Restriction settings + // filter menu items + add_filter( 'wp_nav_menu_objects', array( &$this, 'filter_menu' ), 99, 2 ); + + // Gutenberg blocks restrictions + add_filter( 'render_block', array( $this, 'restrict_blocks' ), 10, 2 ); + + // there is posts (Posts/Page/CPT) filtration if site is accessible + // there also will be redirects if they need + // protect posts types + add_filter( 'the_posts', array( &$this, 'filter_protected_posts' ), 99, 2 ); + // protect pages for wp_list_pages func + add_filter( 'get_pages', array( &$this, 'filter_protected_posts' ), 99, 2 ); + + // check the site's accessible more priority have Individual Post/Term Restriction settings add_action( 'template_redirect', array( &$this, 'template_redirect' ), 1000 ); add_action( 'um_access_check_individual_term_settings', array( &$this, 'um_access_check_individual_term_settings' ) ); add_action( 'um_access_check_global_settings', array( &$this, 'um_access_check_global_settings' ) ); } + /** + * Get array with restricted posts + * + * @param bool $force + * @param bool|array|string $post_types + * + * @return array + */ + function exclude_posts_array( $force = false, $post_types = false ) { + if ( $this->ignore_exclude ) { + return array(); + } + + static $cache = array(); + + $cache_key = $force ? 'force' : 'default'; + + // `force` cache contains all restricted post IDs we can get them all from cache instead new queries + $force_cache_key = ''; + if ( 'default' === $cache_key ) { + $force_cache_key = 'force'; + } + + // make $post_types as array if string + if ( ! empty( $post_types ) ) { + $post_types = is_array( $post_types ) ? $post_types : array( $post_types ); + $cache_key .= md5( serialize( $post_types ) ); + if ( ! empty( $force_cache_key ) ) { + $force_cache_key .= md5( serialize( $post_types ) ); + } + } + + if ( array_key_exists( $cache_key, $cache ) ) { + return $cache[ $cache_key ]; + } + + $exclude_posts = array(); + if ( current_user_can( 'administrator' ) ) { + $cache[ $cache_key ] = $exclude_posts; + return $exclude_posts; + } + + // @todo using Object Cache `wp_cache_get()` `wp_cache_set()` functions + + // `force` cache contains all restricted post IDs we can get them all from cache instead new queries + if ( ! empty( $force_cache_key ) && array_key_exists( $force_cache_key, $cache ) ) { + $post_ids = $cache[ $force_cache_key ]; + + if ( ! empty( $post_ids ) ) { + foreach ( $post_ids as $post_id ) { + $content_restriction = $this->get_post_privacy_settings( $post_id ); + if ( ! empty( $content_restriction['_um_access_hide_from_queries'] ) ) { + array_push( $exclude_posts, $post_id ); + } + } + } + } else { + $restricted_posts = UM()->options()->get( 'restricted_access_post_metabox' ); + $restricted_posts = array_keys( $restricted_posts ); + if ( ! empty( $post_types ) ) { + $restricted_posts = array_intersect( $post_types, $restricted_posts ); + } + + if ( ! empty( $restricted_posts ) ) { + $this->ignore_exclude = true; + // exclude all posts assigned to current term without individual restriction settings + $post_ids = get_posts( + array( + 'fields' => 'ids', + 'post_status' => 'any', + 'post_type' => $restricted_posts, + 'numberposts' => -1, + 'meta_query' => array( + array( + 'key' => 'um_content_restriction', + 'compare' => 'EXISTS', + ), + ), + ) + ); + + $this->ignore_exclude = false; + } + + $post_ids = empty( $post_ids ) ? array() : $post_ids; + + $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); + + if ( ! empty( $restricted_taxonomies ) ) { + $restricted_taxonomies = array_keys( $restricted_taxonomies ); + foreach ( $restricted_taxonomies as $k => $taxonomy ) { + if ( ! taxonomy_exists( $taxonomy ) ) { + unset( $restricted_taxonomies[ $k ] ); + } + } + $restricted_taxonomies = array_values( $restricted_taxonomies ); + } + + if ( ! empty( $post_types ) ) { + $taxonomies = array(); + foreach ( $post_types as $p_t ) { + $taxonomies = array_merge( $taxonomies, get_object_taxonomies( $p_t ) ); + } + $restricted_taxonomies = array_intersect( $taxonomies, $restricted_taxonomies ); + } + + if ( ! empty( $restricted_taxonomies ) ) { + global $wpdb; + + $terms = $wpdb->get_results( + "SELECT tm.term_id AS term_id, + tt.taxonomy AS taxonomy + FROM {$wpdb->termmeta} tm + LEFT JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = tm.term_id + WHERE tm.meta_key = 'um_content_restriction' AND + tt.taxonomy IN('" . implode( "','", $restricted_taxonomies ) . "')", + ARRAY_A + ); + + if ( ! empty( $terms ) ) { + foreach ( $terms as $term ) { + if ( ! $this->is_restricted_term( $term['term_id'] ) ) { + continue; + } + + $this->ignore_exclude = true; + // exclude all posts assigned to current term without individual restriction settings + $posts = get_posts( + array( + 'fields' => 'ids', + 'post_status' => 'any', + 'numberposts' => -1, + 'tax_query' => array( + array( + 'taxonomy' => $term['taxonomy'], + 'field' => 'id', + 'terms' => $term['term_id'], + ), + ), + 'meta_query' => array( + 'relation' => 'OR', + array( + 'relation' => 'AND', + array( + 'key' => 'um_content_restriction', + 'value' => 's:26:"_um_custom_access_settings";s:1:"1"', + 'compare' => 'NOT LIKE', + ), + array( + 'key' => 'um_content_restriction', + 'value' => 's:26:"_um_custom_access_settings";b:1', + 'compare' => 'NOT LIKE', + ), + ), + array( + 'key' => 'um_content_restriction', + 'compare' => 'NOT EXISTS', + ), + ), + ) + ); + $this->ignore_exclude = false; + + if ( empty( $posts ) ) { + continue; + } + + $post_ids = array_merge( $post_ids, $posts ); + } + } + } + + if ( ! empty( $post_ids ) ) { + $post_ids = array_unique( $post_ids ); + + foreach ( $post_ids as $post_id ) { + // handle every post privacy setting based on post type maybe it's inactive for now + // if individual restriction is enabled then get post terms restriction settings + if ( $this->is_restricted( $post_id ) ) { + if ( true === $force ) { + array_push( $exclude_posts, $post_id ); + } else { + $content_restriction = $this->get_post_privacy_settings( $post_id ); + if ( ! empty( $content_restriction['_um_access_hide_from_queries'] ) ) { + array_push( $exclude_posts, $post_id ); + } + } + } + } + } + } + + $exclude_posts = apply_filters( 'um_exclude_restricted_posts_ids', $exclude_posts, $force ); + + $cache[ $cache_key ] = $exclude_posts; + return $exclude_posts; + } + + + + /** + * Get array with restricted terms + * + * @param \WP_Term_Query $query + * + * @return array + */ + function exclude_terms_array( $query ) { + $exclude = array(); + + $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); + if ( ! empty( $restricted_taxonomies ) ) { + $restricted_taxonomies = array_keys( $restricted_taxonomies ); + foreach ( $restricted_taxonomies as $k => $taxonomy ) { + if ( ! taxonomy_exists( $taxonomy ) ) { + unset( $restricted_taxonomies[ $k ] ); + } + } + $restricted_taxonomies = array_values( $restricted_taxonomies ); + } + + $restricted_taxonomies = array_intersect( $query->query_vars['taxonomy'], $restricted_taxonomies ); + + if ( empty( $restricted_taxonomies ) ) { + return $exclude; + } + + $cache_key = md5( serialize( $restricted_taxonomies ) ); + + static $cache = array(); + + if ( array_key_exists( $cache_key, $cache ) ) { + return $cache[ $cache_key ]; + } + + $term_ids = get_terms( + array( + 'taxonomy' => $restricted_taxonomies, + 'hide_empty' => false, + 'fields' => 'ids', + 'meta_query' => array( + 'key' => 'um_content_restriction', + 'compare' => 'EXISTS', + ), + 'um_ignore_exclude' => true, + ) + ); + + if ( empty( $term_ids ) || is_wp_error( $term_ids ) ) { + $cache[ $cache_key ] = $exclude; + return $exclude; + } + + foreach ( $term_ids as $term_id ) { + if ( $this->is_restricted_term( $term_id ) ) { + $exclude[] = $term_id; + } + } + + $exclude = apply_filters( 'um_exclude_restricted_terms_ids', $exclude ); + $cache[ $cache_key ] = $exclude; + return $exclude; + } + + + /** + * @param \WP_Term_Query $query + */ + function exclude_hidden_terms_query( $query ) { + if ( current_user_can( 'administrator' ) || ! empty( $query->query_vars['um_ignore_exclude'] ) ) { + return; + } + + $exclude = $this->exclude_terms_array( $query ); + if ( ! empty( $exclude ) ) { + $query->query_vars['exclude'] = ! empty( $query->query_vars['exclude'] ) ? wp_parse_id_list( $query->query_vars['exclude'] ) : $exclude; + } + } + + + /** + * @param \WP_Query $query + */ + function exclude_posts( $query ) { + if ( current_user_can( 'administrator' ) ) { + return; + } + + // use these functions is_search() || is_admin() for getting force hide all posts + // don't handle `hide from WP_Query` and show 404 option for searching and wp-admin query + if ( $query->is_main_query() || ! empty( $query->query_vars['um_main_query'] ) ) { + $force = is_feed() || is_search() || is_admin(); + + if ( is_object( $query ) ) { + $is_singular = $query->is_singular(); + } else { + $is_singular = ! empty( $query->is_singular ) ? true : false; + } + + if ( ! $is_singular ) { + // need to know what post type is here + $q_values = ! empty( $query->query_vars['post_type'] ) ? $query->query_vars['post_type'] : array(); + if ( ! is_array( $q_values ) ) { + $q_values = explode( ',', $query->query_vars['post_type'] ); + } + + // 'any' will cause the query var to be ignored. + if ( in_array( 'any', $q_values, true ) || empty( $q_values ) ) { + $exclude_posts = $this->exclude_posts_array( $force ); + } else { + $exclude_posts = $this->exclude_posts_array( $force, $q_values ); + } + + if ( ! empty( $exclude_posts ) ) { + $post__not_in = $query->get( 'post__not_in', array() ); + $query->set( 'post__not_in', array_merge( wp_parse_id_list( $post__not_in ), $exclude_posts ) ); + } + } + } + } + + /** * Exclude restricted post from query if there is a single query that exclude post_not_in by default in \WP_Query * @@ -120,6 +439,10 @@ if ( ! class_exists( 'um\core\Access' ) ) { * @return mixed */ function exclude_posts_where( $where, $query ) { + if ( current_user_can( 'administrator' ) ) { + return $where; + } + if ( ! $query->is_main_query() ) { return $where; } @@ -138,90 +461,37 @@ if ( ! class_exists( 'um\core\Access' ) ) { /** - * Get array with restricted terms + * Change the posts count based on restriction settings * - * @return array + * @param object $counts Post counts + * @param string $type Post type + * @param string $perm The permission to determine if the posts are 'readable' + * by the current user. + * + * @return object */ - function exclude_terms_array() { - static $cache = false; - - if ( false !== $cache ) { - return $cache; - } - - $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); - if ( ! empty( $restricted_taxonomies ) ) { - $restricted_taxonomies = array_keys( $restricted_taxonomies ); - foreach ( $restricted_taxonomies as $k => $taxonomy ) { - if ( ! taxonomy_exists( $taxonomy ) ) { - unset( $restricted_taxonomies[ $k ] ); - } - } - $restricted_taxonomies = array_values( $restricted_taxonomies ); - } - - if ( empty( $restricted_taxonomies ) ) { - $exclude = apply_filters( 'um_exclude_restricted_terms_ids', array() ); - $cache = $exclude; - return $exclude; - } - - $this->ignore_terms_exclude = true; - $term_ids = get_terms( - array( - 'taxonomy' => $restricted_taxonomies, - 'hide_empty' => false, - 'fields' => 'ids', - 'meta_query' => array( - 'key' => 'um_content_restriction', - 'compare' => 'EXISTS', - ), - ) - ); - - $this->ignore_terms_exclude = false; - - if ( empty( $term_ids ) || is_wp_error( $term_ids ) ) { - $exclude = apply_filters( 'um_exclude_restricted_terms_ids', array() ); - $cache = $exclude; - return $exclude; - } - - $exclude = array(); - foreach ( $term_ids as $term_id ) { - if ( $this->is_restricted_term( $term_id ) ) { - $exclude[] = $term_id; - } - } - - $exclude = apply_filters( 'um_exclude_restricted_terms_ids', $exclude ); - - $cache = $exclude; - return $exclude; - } - - - function exclude_hidden_terms_query( $query ) { - if ( current_user_can( 'administrator' ) || $this->ignore_terms_exclude ) { - return; - } - - $exclude = $this->exclude_terms_array(); - if ( ! empty( $exclude ) ) { - $query->query_vars['exclude'] = ! empty( $query->query_vars['exclude'] ) ? wp_parse_id_list( $query->query_vars['exclude'] ) : $exclude; - } - } - - function custom_count_posts_handler( $counts, $type, $perm ) { - global $wpdb; - - $exclude_posts = $this->exclude_posts_array( is_admin() ); - if ( empty( $exclude_posts ) ) { + if ( current_user_can( 'administrator' ) ) { return $counts; } - $cache_key = _count_posts_cache_key( $type, $perm ); + global $wpdb; + + static $cache = array(); + + $cache_key = _count_posts_cache_key( $type, $perm ); + $force = is_feed() || is_search() || is_admin(); + $cache_key .= $force ? 'force' : ''; + + if ( array_key_exists( $cache_key, $cache ) ) { + return $cache[ $cache_key ]; + } + + $exclude_posts = $this->exclude_posts_array( $force, array( $type ) ); + if ( empty( $exclude_posts ) ) { + $cache[ $cache_key ] = $counts; + return $counts; + } $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s"; @@ -247,21 +517,364 @@ if ( ! class_exists( 'um\core\Access' ) ) { } $counts = (object) $counts; - wp_cache_set( $cache_key, $counts, 'counts' ); + $cache[ $cache_key ] = $counts; return $counts; } + /** + * Exclude restricted posts in Recent Posts widget + * + * @param array $array Query args + * + * @return array + */ + function exclude_restricted_posts_widget( $array ) { + if ( current_user_can( 'administrator' ) ) { + return $array; + } + + $exclude_posts = $this->exclude_posts_array( false, 'post' ); + if ( ! empty( $exclude_posts ) ) { + $post__not_in = ! empty( $array['post__not_in'] ) ? $array['post__not_in'] : array(); + $array['post__not_in'] = array_merge( wp_parse_id_list( $post__not_in ), $exclude_posts ); + } + + return $array; + } + + + /** + * Exclude restricted posts in Recent Posts widget + * + * @param array $array Query args + * + * @return array + */ + function exclude_restricted_pages( $array ) { + if ( current_user_can( 'administrator' ) ) { + return $array; + } + + $exclude_posts = $this->exclude_posts_array( false, 'page' ); + if ( ! empty( $exclude_posts ) ) { + $array = array_merge( $array, $exclude_posts ); + } + + return $array; + } + + + /** + * Exclude restricted posts in widgets + * + * @param string $sql_where + * @param array $parsed_args + * + * @return string + */ + function exclude_restricted_posts_archives_widget( $sql_where, $parsed_args ) { + if ( current_user_can( 'administrator' ) ) { + return $sql_where; + } + + $exclude_posts = $this->exclude_posts_array( false, $parsed_args['post_type'] ); + if ( ! empty( $exclude_posts ) ) { + $exclude_string = implode( ',', $exclude_posts ); + $sql_where .= ' AND ID NOT IN ( ' . $exclude_string . ' )'; + } + + return $sql_where; + } + + + /** + * Exclude posts from next, previous navigation + * + * @param string $where + * @param bool $in_same_term + * @param array $excluded_terms + * @param string $taxonomy. + * @param \WP_Post $post + * + * @return string + */ + function exclude_navigation_posts( $where, $in_same_term, $excluded_terms, $taxonomy, $post ) { + if ( current_user_can( 'administrator' ) ) { + return $where; + } + + $exclude_posts = $this->exclude_posts_array( false, $post->post_type ); + if ( ! empty( $exclude_posts ) ) { + $exclude_string = implode( ',', $exclude_posts ); + $where .= ' AND ID NOT IN ( ' . $exclude_string . ' )'; + } + + return $where; + } + + + /** + * Replace titles of restricted posts + * + * @param string $title + * @param int|null $id + * + * @return string + */ + function filter_restricted_post_title( $title, $id = null ) { + if ( current_user_can( 'administrator' ) ) { + return $title; + } + + if ( ! isset( $id ) ) { + return $title; + } + + if ( ! is_numeric( $id ) ) { + $id = absint( $id ); + } + + $ignore = apply_filters( 'um_ignore_restricted_title', false, $id ); + if ( $ignore ) { + return $title; + } + + if ( $this->is_restricted( $id ) ) { + $restricted_global_title = UM()->options()->get( 'restricted_access_post_title' ); + $title = stripslashes( $restricted_global_title ); + } + + return $title; + } + + + /** + * Replace content of restricted posts + * + * @param string $content + * + * @return string + */ + function filter_restricted_post_content( $content ) { + if ( current_user_can( 'administrator' ) ) { + return $content; + } + + $id = get_the_ID(); + if ( ! $id || is_admin() ) { + return $content; + } + + $ignore = apply_filters( 'um_ignore_restricted_content', false, $id ); + if ( $ignore ) { + return $content; + } + + if ( $this->is_restricted( $id ) ) { + $restriction = $this->get_post_privacy_settings( $id ); + + if ( ! isset( $restriction['_um_restrict_by_custom_message'] ) || '0' == $restriction['_um_restrict_by_custom_message'] ) { + $content = stripslashes( UM()->options()->get( 'restricted_access_message' ) ); + } elseif ( '1' == $restriction['_um_restrict_by_custom_message'] ) { + $content = ! empty( $restriction['_um_restrict_custom_message'] ) ? stripslashes( $restriction['_um_restrict_custom_message'] ) : ''; + } + } + + return $content; + } + + + /** + * Replace excerpt of restricted posts + * + * @param string $post_excerpt + * @param \WP_Post $post + * + * @return string + */ + function filter_restricted_post_excerpt( $post_excerpt, $post ) { + if ( current_user_can( 'administrator' ) || is_admin() ) { + return $post_excerpt; + } + + $ignore = apply_filters( 'um_ignore_restricted_excerpt', false, $post->ID ); + if ( $ignore ) { + return $post_excerpt; + } + + if ( $this->is_restricted( $post->ID ) ) { + $post_excerpt = ''; + } + + return $post_excerpt; + } + + + /** + * Hide attachment if the post is restricted + * + * @param string $url + * @param int $attachment_id + * + * @return boolean|string + */ + function filter_attachment( $url, $attachment_id ) { + if ( current_user_can( 'administrator' ) ) { + return $url; + } + + return ( $attachment_id && $this->is_restricted( $attachment_id ) ) ? false : $url; + } + + + /** + * Hide attachment if the post is restricted + * + * @param $has_thumbnail + * @param $post + * @param $thumbnail_id + * + * @return bool + */ + function filter_post_thumbnail( $has_thumbnail, $post, $thumbnail_id ) { + if ( current_user_can( 'administrator' ) ) { + return $has_thumbnail; + } + + if ( $this->is_restricted( $thumbnail_id ) ) { + $has_thumbnail = false; + } elseif ( ! empty( $post ) && ! empty( $post->ID ) ) { + if ( $this->is_restricted( $post->ID ) ) { + $has_thumbnail = false; + } + } else { + $post_id = get_the_ID(); + if ( $this->is_restricted( $post_id ) ) { + $has_thumbnail = false; + } + } + + $has_thumbnail = apply_filters( 'um_restrict_post_thumbnail', $has_thumbnail, $post, $thumbnail_id ); + + return $has_thumbnail; + } + + + + /** + * Exclude comments from restricted posts in widgets + * + * @param \WP_Comment_Query $query + */ + function exclude_posts_comments( $query ) { + if ( current_user_can( 'administrator' ) ) { + return; + } + + if ( ! empty( $query->query_vars['post_id'] ) ) { + $exclude_posts = array(); + if ( $this->is_restricted( $query->query_vars['post_id'] ) ) { + $exclude_posts[] = $query->query_vars['post_id']; + } + } else { + $q_values = ! empty( $query->query_vars['post_type'] ) ? $query->query_vars['post_type'] : array(); + if ( ! is_array( $q_values ) ) { + $q_values = explode( ',', $query->query_vars['post_type'] ); + } + + // 'any' will cause the query var to be ignored. + if ( in_array( 'any', $q_values, true ) || empty( $q_values ) ) { + $exclude_posts = $this->exclude_posts_array( true, $this->get_available_comments_post_types() ); + } else { + $exclude_posts = $this->exclude_posts_array( true, $q_values ); + } + } + + if ( ! empty( $exclude_posts ) ) { + $post__not_in = ! empty( $query->query_vars['post__not_in'] ) ? $query->query_vars['post__not_in'] : array(); + $query->query_vars['post__not_in'] = array_merge( wp_parse_id_list( $post__not_in ), $exclude_posts ); + } + } + + + /** + * @return array + */ + function get_available_comments_post_types() { + global $wp_taxonomies; + + $restricted_posts = UM()->options()->get( 'restricted_access_post_metabox' ); + $restricted_posts = array_keys( $restricted_posts ); + + $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); + if ( ! empty( $restricted_taxonomies ) ) { + $restricted_taxonomies = array_keys( $restricted_taxonomies ); + foreach ( $restricted_taxonomies as $k => $taxonomy ) { + if ( taxonomy_exists( $taxonomy ) ) { + $restricted_posts = array_merge( $restricted_posts, $wp_taxonomies[ $taxonomy ]->object_type ); + } + } + } + + $restricted_posts = array_unique( $restricted_posts ); + foreach ( $restricted_posts as $k => $post_type ) { + if ( 'closed' === get_default_comment_status( $post_type ) ) { + unset( $restricted_posts[ $k ] ); + } + } + + $restricted_posts = array_values( $restricted_posts ); + + return $restricted_posts; + } + + + /** + * Exclude comments from comments feed + * + * @param string $where + * @param \WP_Query $query + * + * @return string + */ + function exclude_posts_comments_feed( $where, $query ) { + if ( current_user_can( 'administrator' ) ) { + return $where; + } + + $exclude_posts = $this->exclude_posts_array( true, $this->get_available_comments_post_types() ); + if ( ! empty( $exclude_posts ) ) { + $exclude_string = implode( ',', $exclude_posts ); + $where .= ' AND comment_post_ID NOT IN ( ' . $exclude_string . ' )'; + } + + return $where; + } + + + /** + * @param object $stats + * @param int $post_id Post ID. Can be 0 for the whole website + * + * @return object + */ function custom_comments_count_handler( $stats, $post_id ) { - if ( ! empty( $stats ) ) { + if ( ! empty( $stats ) || current_user_can( 'administrator' ) ) { return $stats; } - $exclude_posts = $this->exclude_posts_array( true ); - - if ( empty( $exclude_posts ) ) { - return $stats; + if ( $post_id === 0 ) { + $exclude_posts = $this->exclude_posts_array( true, $this->get_available_comments_post_types() ); + if ( empty( $exclude_posts ) ) { + return $stats; + } + } else { + $exclude_posts = array(); + if ( $this->is_restricted( $post_id ) ) { + $exclude_posts[] = $post_id; + } } $stats = $this->get_comment_count( $post_id, $exclude_posts ); @@ -274,6 +887,12 @@ if ( ! class_exists( 'um\core\Access' ) ) { } + /** + * @param int $post_id + * @param array $exclude_posts + * + * @return array + */ function get_comment_count( $post_id = 0, $exclude_posts = array() ) { static $cache = array(); @@ -350,33 +969,400 @@ if ( ! class_exists( 'um\core\Access' ) ) { /** - * @param array $restriction + * Disable comments if user has not permission to access this post * - * @return bool + * @param mixed $open + * @param int $post_id + * @return boolean */ - function um_custom_restriction( $restriction ) { + function disable_comments_open( $open, $post_id ) { + if ( current_user_can( 'administrator' ) ) { + return $open; + } + + static $cache = array(); + + if ( isset( $cache[ $post_id ] ) ) { + return $cache[ $post_id ] ? $open : false; + } + + if ( ! $this->is_restricted( $post_id ) ) { + $cache[ $post_id ] = $open; + return $open; + } + + $open = false; + + $cache[ $post_id ] = $open; + return $open; + } + + + /** + * Disable comments if user has not permission to access this post + * + * @param int $count + * @param int $post_id + * @return boolean + */ + function disable_comments_open_number( $count, $post_id ) { + if ( current_user_can( 'administrator' ) ) { + return $count; + } + + static $cache_number = array(); + + if ( isset( $cache_number[ $post_id ] ) ) { + return $cache_number[ $post_id ]; + } + + if ( ! $this->is_restricted( $post_id ) ) { + $cache_number[ $post_id ] = $count; + return $count; + } + + $count = 0; + + $cache_number[ $post_id ] = $count; + return $count; + } + + + /** + * Protect Post Types in menu query + * Restrict content new logic + * @param $menu_items + * @param $args + * @return array + */ + function filter_menu( $menu_items, $args ) { + //if empty + if ( empty( $menu_items ) ) { + return $menu_items; + } + + if ( current_user_can( 'administrator' ) ) { + return $menu_items; + } + + $filtered_items = array(); + + //other filter + foreach ( $menu_items as $menu_item ) { + if ( ! empty( $menu_item->object_id ) && ! empty( $menu_item->object ) ) { + if ( isset( $menu_item->type ) && 'taxonomy' === $menu_item->type ) { + if ( ! $this->is_restricted_term( $menu_item->object_id ) ) { + $filtered_items[] = $menu_item; + continue; + } + } elseif ( isset( $menu_item->type ) && 'post_type' === $menu_item->type ) { + if ( ! $this->is_restricted( $menu_item->object_id ) ) { + $filtered_items[] = $menu_item; + continue; + } else { + $restriction_settings = $this->get_post_privacy_settings( $menu_item->object_id ); + if ( empty( $restriction_settings['_um_access_hide_from_queries'] ) ) { + $filtered_items[] = $menu_item; + continue; + } + } + } + } else { + //add all other posts + $filtered_items[] = $menu_item; + } + } + + return $filtered_items; + } + + + /** + * @param $block_content + * @param $block + * + * @return string + */ + function restrict_blocks( $block_content, $block ) { + if ( is_admin() ) { + return $block_content; + } + + $restricted_blocks = UM()->options()->get( 'restricted_blocks' ); + if ( empty( $restricted_blocks ) ) { + return $block_content; + } + + if ( is_user_logged_in() && current_user_can( 'administrator' ) ) { + return $block_content; + } + + if ( ! isset( $block['attrs']['um_is_restrict'] ) || $block['attrs']['um_is_restrict'] !== true ) { + return $block_content; + } + + if ( empty( $block['attrs']['um_who_access'] ) ) { + return $block_content; + } + + $default_message = UM()->options()->get( 'restricted_block_message' ); + switch ( $block['attrs']['um_who_access'] ) { + case '1': { + if ( ! is_user_logged_in() ) { + $block_content = ''; + if ( isset( $block['attrs']['um_message_type'] ) ) { + if ( $block['attrs']['um_message_type'] == '1' ) { + $block_content = $default_message; + } elseif ( $block['attrs']['um_message_type'] == '2' ) { + $block_content = $block['attrs']['um_message_content']; + } + } + } else { + $display = true; + + // What roles can access this content? + if ( ! empty( $block['attrs']['um_roles_access'] ) ) { + $display = false; + foreach ( $block['attrs']['um_roles_access'] as $role ) { + if ( current_user_can( $role ) ) { + $display = true; + } + } + } + + $display = apply_filters( 'um_loggedin_block_restriction', $display, $block ); + + if ( ! $display ) { + $block_content = ''; + if ( isset( $block['attrs']['um_message_type'] ) ) { + if ( $block['attrs']['um_message_type'] == '1' ) { + $block_content = $default_message; + } elseif ( $block['attrs']['um_message_type'] == '2' ) { + $block_content = $block['attrs']['um_message_content']; + } + } + } + } + break; + } + case '2': { + if ( is_user_logged_in() ) { + $block_content = ''; + if ( isset( $block['attrs']['um_message_type'] ) ) { + if ( $block['attrs']['um_message_type'] == '1' ) { + $block_content = $default_message; + } elseif ( $block['attrs']['um_message_type'] == '2' ) { + $block_content = $block['attrs']['um_message_content']; + } + } + } + break; + } + } + + return $block_content; + } + + + /** + * Protect Post Types in query + * Restrict content new logic + * + * @param $posts + * @param \WP_Query $query + * @return array + */ + function filter_protected_posts( $posts, $query ) { + if ( current_user_can( 'administrator' ) ) { + return $posts; + } + + //Woocommerce AJAX fixes....remove filtration on wc-ajax which goes to Front Page + if ( ! empty( $_GET['wc-ajax'] ) && defined( 'WC_DOING_AJAX' ) && WC_DOING_AJAX ) { + return $posts; + } + + //if empty + if ( empty( $posts ) || is_admin() ) { + return $posts; + } + + if ( is_object( $query ) ) { + $is_singular = $query->is_singular(); + } else { + $is_singular = ! empty( $query->is_singular ) ? true : false; + } + + if ( $query->is_main_query() || ! empty( $query->query_vars['um_main_query'] ) ) { + if ( $is_singular ) { + if ( $this->is_restricted( $posts[0]->ID ) ) { + $content_restriction = $this->get_post_privacy_settings( $posts[0]->ID ); + if ( ! empty( $content_restriction['_um_access_hide_from_queries'] ) ) { + unset( $posts[0] ); + return $posts; + } + } + } + } + + $filtered_posts = array(); + + //other filter + foreach ( $posts as $post ) { + if ( is_user_logged_in() && isset( $post->post_author ) && $post->post_author == get_current_user_id() ) { + $filtered_posts[] = $post; + continue; + } + + $restriction = $this->get_post_privacy_settings( $post ); + if ( ! $restriction ) { + $filtered_posts[] = $post; + continue; + } + + if ( $is_singular ) { + $this->singular_page = true; + } + + if ( ! $this->is_restricted( $post->ID ) ) { + $filtered_posts[] = $post; + continue; + } else { + if ( $is_singular ) { + if ( ! isset( $restriction['_um_noaccess_action'] ) || '0' == $restriction['_um_noaccess_action'] ) { + if ( empty( $restriction['_um_access_hide_from_queries'] ) ) { + /** + * UM hook + * + * @type action + * @title um_access_fix_external_post_content + * @description Hook for 3-d party content filtration + * @change_log + * ["Since: 2.0"] + * @usage add_action( 'um_access_fix_external_post_content', 'function_name', 10 ); + * @example + * + */ + do_action( 'um_access_fix_external_post_content' ); + + $filtered_posts[] = $post; + continue; + } + } elseif ( '1' == $restriction['_um_noaccess_action'] ) { + $curr = UM()->permalinks()->get_current_url(); + + if ( ! isset( $restriction['_um_access_redirect'] ) || '0' == $restriction['_um_access_redirect'] ) { + + exit( wp_redirect( esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ) ) ); + + } elseif ( '1' == $restriction['_um_access_redirect'] ) { + + if ( ! empty( $restriction['_um_access_redirect_url'] ) ) { + $redirect = $restriction['_um_access_redirect_url']; + } else { + $redirect = esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ); + } + + exit( wp_redirect( $redirect ) ); + } + } + } else { + if ( empty( $restriction['_um_access_hide_from_queries'] ) ) { + $filtered_posts[] = $post; + continue; + } + } + } + } + + return $filtered_posts; + } + + + /** + * Set custom access actions and redirection + * + * Old global restrict content logic + */ + function template_redirect() { + global $post, $wp_query; + + //if we logged by administrator it can access to all content + if ( current_user_can( 'administrator' ) ) { + return; + } + + if ( is_object( $wp_query ) ) { + $is_singular = $wp_query->is_singular(); + } else { + $is_singular = ! empty( $wp_query->is_singular ) ? true : false; + } + + //if we use individual restrict content options skip this function + if ( $is_singular && $this->singular_page ) { + return; + } + + //also skip if we currently at wp-admin or 404 page + if ( is_admin() || is_404() ) { + return; + } + + //also skip if we currently at UM Register|Login|Reset Password pages + if ( um_is_core_post( $post, 'register' ) || + um_is_core_post( $post, 'password-reset' ) || + um_is_core_post( $post, 'login' ) ) { + return; + } + /** * UM hook * - * @type filter - * @title um_custom_restriction - * @description Extend Sort Types for Member Directory - * @input_vars - * [{"var":"$custom_restriction","type":"bool","desc":"Custom Restriction"}, - * {"var":"$restriction","type":"array","desc":"Restriction settings"}] + * @type action + * @title um_roles_add_meta_boxes_um_role_meta + * @description Check terms individual restrict options * @change_log * ["Since: 2.0"] - * @usage add_filter( 'um_custom_restriction', 'function_name', 10, 2 ); + * @usage add_action( 'um_access_check_individual_term_settings', 'function_name', 10 ); * @example * */ - return apply_filters( 'um_custom_restriction', true, $restriction ); + do_action( 'um_access_check_individual_term_settings' ); + //exit from function if term page is accessible + if ( $this->check_access() ) { + return; + } + + /** + * UM hook + * + * @type action + * @title um_access_check_global_settings + * @description Check global restrict content options + * @change_log + * ["Since: 2.0"] + * @usage add_action( 'um_access_check_global_settings', 'function_name', 10 ); + * @example + * + */ + do_action( 'um_access_check_global_settings' ); + + $this->check_access(); } @@ -408,11 +1394,6 @@ if ( ! class_exists( 'um\core\Access' ) ) { } if ( $this->is_restricted_term( $term_id, true ) ) { - add_filter( 'tag_template', array( &$this, 'taxonomy_message' ), 10, 3 ); - add_filter( 'archive_template', array( &$this, 'taxonomy_message' ), 10, 3 ); - add_filter( 'category_template', array( &$this, 'taxonomy_message' ), 10, 3 ); - add_filter( 'taxonomy_template', array( &$this, 'taxonomy_message' ), 10, 3 ); - $restriction = get_term_meta( $term_id, 'um_content_restriction', true ); if ( '1' == $restriction['_um_noaccess_action'] ) { $curr = UM()->permalinks()->get_current_url(); @@ -432,6 +1413,11 @@ if ( ! class_exists( 'um\core\Access' ) ) { $this->redirect_handler = $this->set_referer( $redirect, 'individual_term' ); } + } else { + add_filter( 'tag_template', array( &$this, 'taxonomy_message' ), 10, 3 ); + add_filter( 'archive_template', array( &$this, 'taxonomy_message' ), 10, 3 ); + add_filter( 'category_template', array( &$this, 'taxonomy_message' ), 10, 3 ); + add_filter( 'taxonomy_template', array( &$this, 'taxonomy_message' ), 10, 3 ); } } } @@ -456,7 +1442,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { global $post; $curr = UM()->permalinks()->get_current_url(); - $ms_empty_role_access = is_multisite() && is_user_logged_in() && !UM()->roles()->get_priority_user_role( um_user('ID') ); + $ms_empty_role_access = is_multisite() && is_user_logged_in() && ! UM()->roles()->get_priority_user_role( um_user( 'ID' ) ); if ( is_front_page() ) { if ( is_user_logged_in() && ! $ms_empty_role_access ) { @@ -491,7 +1477,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { */ $redirect_homepage = apply_filters( 'um_custom_homepage_redirect_url', $redirect_homepage, um_user( 'ID' ) ); $redirect_to = ! empty( $redirect_homepage ) ? $redirect_homepage : um_get_core_page( 'user' ); - $this->redirect_handler = $this->set_referer( esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), $redirect_to ) ), "custom_homepage" ); + $this->redirect_handler = $this->set_referer( esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), $redirect_to ) ), 'custom_homepage' ); } else { $access = UM()->options()->get( 'accessible' ); @@ -575,88 +1561,6 @@ if ( ! class_exists( 'um\core\Access' ) ) { } - /** - * Set custom access actions and redirection - * - * Old global restrict content logic - */ - function template_redirect() { - global $post, $wp_query; - - //if we logged by administrator it can access to all content - if ( current_user_can( 'administrator' ) ) { - return; - } - - if ( is_object( $wp_query ) ) { - $is_singular = $wp_query->is_singular(); - } else { - $is_singular = ! empty( $wp_query->is_singular ) ? true : false; - } - - //if we use individual restrict content options skip this function - if ( $is_singular && $this->singular_page ) { - return; - } - - //also skip if we currently at wp-admin or 404 page - if ( is_admin() || is_404() ) { - return; - } - - //also skip if we currently at UM Register|Login|Reset Password pages - if ( um_is_core_post( $post, 'register' ) || - um_is_core_post( $post, 'password-reset' ) || - um_is_core_post( $post, 'login' ) ) { - return; - } - - /** - * UM hook - * - * @type action - * @title um_roles_add_meta_boxes_um_role_meta - * @description Check terms individual restrict options - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_access_check_individual_term_settings', 'function_name', 10 ); - * @example - * - */ - do_action( 'um_access_check_individual_term_settings' ); - //exit from function if term page is accessible - if ( $this->check_access() ) { - return; - } - - /** - * UM hook - * - * @type action - * @title um_access_check_global_settings - * @description Check global restrict content options - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_access_check_global_settings', 'function_name', 10 ); - * @example - * - */ - do_action( 'um_access_check_global_settings' ); - - $this->check_access(); - } - - /** * Check access * @@ -668,7 +1572,8 @@ if ( ! class_exists( 'um\core\Access' ) ) { } if ( $this->redirect_handler ) { - wp_redirect( $this->redirect_handler ); exit; + wp_redirect( $this->redirect_handler ); + exit; } return false; @@ -715,30 +1620,6 @@ if ( ! class_exists( 'um\core\Access' ) ) { } - /** - * User can some of the roles array - * Restrict content new logic - * - * @param $user_id - * @param $roles - * @return bool - */ - function user_can( $user_id, $roles ) { - $user_can = false; - - if ( ! empty( $roles ) ) { - foreach ( $roles as $key => $value ) { - if ( ! empty( $value ) && user_can( $user_id, $key ) ) { - $user_can = true; - break; - } - } - } - - return $user_can; - } - - /** * Get privacy settings for post * return false if post is not private @@ -802,9 +1683,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { continue; } - $this->ignore_terms_exclude = true; - $terms = array_merge( $terms, wp_get_post_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) ) ); - $this->ignore_terms_exclude = false; + $terms = array_merge( $terms, wp_get_post_terms( $post->ID, $taxonomy, array( 'fields' => 'ids', 'um_ignore_exclude' => true, ) ) ); } } @@ -870,9 +1749,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { continue; } - $this->ignore_terms_exclude = true; - $terms = array_merge( $terms, wp_get_post_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) ) ); - $this->ignore_terms_exclude = false; + $terms = array_merge( $terms, wp_get_post_terms( $post->ID, $taxonomy, array( 'fields' => 'ids', 'um_ignore_exclude' => true, ) ) ); } } @@ -897,769 +1774,58 @@ if ( ! class_exists( 'um\core\Access' ) ) { /** - * Replace titles of restricted posts + * Helper for checking if the user can some of the roles array * - * @param string $title - * @param int|null $id - * - * @return string + * @param $user_id + * @param $roles + * @return bool */ - function filter_restricted_post_title( $title, $id = null ) { - if ( ! isset( $id ) ) { - return $title; - } - - if ( ! is_numeric( $id ) ) { - $id = absint( $id ); - } - - if ( $this->is_restricted( $id ) ) { - $ignore = apply_filters( 'um_ignore_restricted_title', false, $id ); - if ( $ignore ) { - return $title; - } - - $restricted_global_title = UM()->options()->get( 'restricted_access_post_title' ); - $title = stripslashes( $restricted_global_title ); - } - - return $title; - } - - - /** - * Protect Post Types in query - * Restrict content new logic - * - * @param $posts - * @param \WP_Query $query - * @return array - */ - function filter_protected_posts( $posts, $query ) { - $filtered_posts = array(); - - //if empty - if ( empty( $posts ) || is_admin() ) { - return $posts; - } - - if ( current_user_can( 'administrator' ) ) { - return $posts; - } - - $restricted_global_message = UM()->options()->get( 'restricted_access_message' ); - $restricted_global_title = UM()->options()->get( 'restricted_access_post_title' ); - - if ( is_object( $query ) ) { - $is_singular = $query->is_singular(); - } else { - $is_singular = ! empty( $query->is_singular ) ? true : false; - } - - //other filter - foreach ( $posts as $post ) { - - $original_post = $post; - - if ( is_user_logged_in() && isset( $post->post_author ) && $post->post_author == get_current_user_id() ) { - $filtered_posts[] = $post; - continue; - } - - //Woocommerce AJAX fixes....remove filtration on wc-ajax which goes to Front Page - if ( ! empty( $_GET['wc-ajax'] ) && defined( 'WC_DOING_AJAX' ) && WC_DOING_AJAX ) { - $filtered_posts[] = $post; - continue; - } - - $restriction = $this->get_post_privacy_settings( $post ); - - if ( ! $restriction ) { - $filtered_posts[] = $post; - continue; - } - - //post is private - if ( '0' == $restriction['_um_accessible'] ) { - $this->singular_page = true; - $filtered_posts[] = $post; - continue; - } elseif ( '1' == $restriction['_um_accessible'] ) { - //if post for not logged in users and user is not logged in - if ( ! is_user_logged_in() ) { - $this->singular_page = true; - - $filtered_posts[] = $post; - continue; - } else { - - if ( empty( $is_singular ) ) { - //if not single query when exclude if set _um_access_hide_from_queries - if ( empty( $restriction['_um_access_hide_from_queries'] ) ) { - - if ( ! isset( $restriction['_um_restrict_by_custom_message'] ) || '0' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = stripslashes( $restricted_global_message ); - $post->post_title = stripslashes( $restricted_global_title ); - $post->post_excerpt = ''; - } elseif ( '1' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = ! empty( $restriction['_um_restrict_custom_message'] ) ? stripslashes( $restriction['_um_restrict_custom_message'] ) : ''; - $post->post_title = stripslashes( $restricted_global_title ); - $post->post_excerpt = ''; - } - - $post = apply_filters( 'um_restricted_archive_post', $post, $restriction, $original_post ); - $filtered_posts[] = $post; - continue; - } - } else { - $this->singular_page = true; - - //if single post query - if ( ! isset( $restriction['_um_noaccess_action'] ) || '0' == $restriction['_um_noaccess_action'] ) { - - if ( ! isset( $restriction['_um_restrict_by_custom_message'] ) || '0' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = stripslashes( $restricted_global_message ); - $post->post_title = stripslashes( $restricted_global_title ); - } elseif ( '1' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = ! empty( $restriction['_um_restrict_custom_message'] ) ? stripslashes( $restriction['_um_restrict_custom_message'] ) : ''; - $post->post_title = stripslashes( $restricted_global_title ); - } - - $post = apply_filters( 'um_restricted_singular_post', $post, $restriction, $original_post ); - - $this->current_single_post = $post; - - /** - * UM hook - * - * @type action - * @title um_access_fix_external_post_content - * @description Hook for 3-d party content filtration - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_access_fix_external_post_content', 'function_name', 10 ); - * @example - * - */ - do_action( 'um_access_fix_external_post_content' ); - - add_filter( 'single_template', array( &$this, 'woocommerce_template' ), 9999999, 1 ); - - $filtered_posts[] = $post; - continue; - } elseif ( '1' == $restriction['_um_noaccess_action'] ) { - $curr = UM()->permalinks()->get_current_url(); - - if ( ! isset( $restriction['_um_access_redirect'] ) || '0' == $restriction['_um_access_redirect'] ) { - - exit( wp_redirect( esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ) ) ); - - } elseif ( '1' == $restriction['_um_access_redirect'] ) { - - if ( ! empty( $restriction['_um_access_redirect_url'] ) ) { - $redirect = $restriction['_um_access_redirect_url']; - } else { - $redirect = esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ); - } - - exit( wp_redirect( $redirect ) ); - } - - } - } - } - } elseif ( '2' == $restriction['_um_accessible'] ) { - //if post for logged in users and user is not logged in - if ( is_user_logged_in() ) { - - $custom_restrict = $this->um_custom_restriction( $restriction ); - - if ( empty( $restriction['_um_access_roles'] ) || false === array_search( '1', $restriction['_um_access_roles'] ) ) { - if ( $custom_restrict ) { - $this->singular_page = true; - - $filtered_posts[] = $post; - continue; - } - } else { - $user_can = $this->user_can( get_current_user_id(), $restriction['_um_access_roles'] ); - - if ( isset( $user_can ) && $user_can && $custom_restrict ) { - $this->singular_page = true; - - $filtered_posts[] = $post; - continue; - } - } - - if ( empty( $is_singular ) ) { - //if not single query when exclude if set _um_access_hide_from_queries - if ( empty( $restriction['_um_access_hide_from_queries'] ) ) { - - if ( ! isset( $restriction['_um_restrict_by_custom_message'] ) || '0' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = stripslashes( $restricted_global_message ); - $post->post_title = stripslashes( $restricted_global_title ); - $post->post_excerpt = ''; - } elseif ( '1' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = ! empty( $restriction['_um_restrict_custom_message'] ) ? stripslashes( $restriction['_um_restrict_custom_message'] ) : ''; - $post->post_title = stripslashes( $restricted_global_title ); - $post->post_excerpt = ''; - } - - $post = apply_filters( 'um_restricted_archive_post', $post, $restriction, $original_post ); - - $filtered_posts[] = $post; - continue; - } - } else { - $this->singular_page = true; - - //if single post query - if ( ! isset( $restriction['_um_noaccess_action'] ) || '0' == $restriction['_um_noaccess_action'] ) { - - if ( ! isset( $restriction['_um_restrict_by_custom_message'] ) || '0' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = stripslashes( $restricted_global_message ); - $post->post_title = stripslashes( $restricted_global_title ); - - $this->current_single_post = $post; - - if ( 'attachment' == $post->post_type ) { - remove_filter( 'the_content', 'prepend_attachment' ); - } - } elseif ( '1' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = ! empty( $restriction['_um_restrict_custom_message'] ) ? stripslashes( $restriction['_um_restrict_custom_message'] ) : ''; - $post->post_title = stripslashes( $restricted_global_title ); - - $this->current_single_post = $post; - - if ( 'attachment' == $post->post_type ) { - remove_filter( 'the_content', 'prepend_attachment' ); - } - } - - $post = apply_filters( 'um_restricted_singular_post', $post, $restriction, $original_post ); - - /** - * UM hook - * - * @type action - * @title um_access_fix_external_post_content - * @description Hook for 3-d party content filtration - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_access_fix_external_post_content', 'function_name', 10 ); - * @example - * - */ - do_action( 'um_access_fix_external_post_content' ); - - add_filter( 'single_template', array( &$this, 'woocommerce_template' ), 9999999, 1 ); - - $filtered_posts[] = $post; - continue; - } elseif ( '1' == $restriction['_um_noaccess_action'] ) { - - $curr = UM()->permalinks()->get_current_url(); - - if ( ! isset( $restriction['_um_access_redirect'] ) || '0' == $restriction['_um_access_redirect'] ) { - - exit( wp_redirect( esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ) ) ); - - } elseif ( '1' == $restriction['_um_access_redirect'] ) { - - if ( ! empty( $restriction['_um_access_redirect_url'] ) ) { - $redirect = $restriction['_um_access_redirect_url']; - } else { - $redirect = esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ); - } - - exit( wp_redirect( $redirect ) ); - } - - } - } - - } else { - - if ( empty( $is_singular ) ) { - if ( empty( $restriction['_um_access_hide_from_queries'] ) ) { - - if ( ! isset( $restriction['_um_restrict_by_custom_message'] ) || '0' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = stripslashes( $restricted_global_message ); - $post->post_title = stripslashes( $restricted_global_title ); - $post->post_excerpt = ''; - } elseif ( '1' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = ! empty( $restriction['_um_restrict_custom_message'] ) ? stripslashes( $restriction['_um_restrict_custom_message'] ) : ''; - $post->post_title = stripslashes( $restricted_global_title ); - $post->post_excerpt = ''; - } - - $post = apply_filters( 'um_restricted_archive_post', $post, $restriction, $original_post ); - - $filtered_posts[] = $post; - continue; - } - } else { - $this->singular_page = true; - - //if single post query - if ( ! isset( $restriction['_um_noaccess_action'] ) || '0' == $restriction['_um_noaccess_action'] ) { - - if ( ! isset( $restriction['_um_restrict_by_custom_message'] ) || '0' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = stripslashes( $restricted_global_message ); - $post->post_title = stripslashes( $restricted_global_title ); - - $this->current_single_post = $post; - - if ( 'attachment' == $post->post_type ) { - remove_filter( 'the_content', 'prepend_attachment' ); - } - } elseif ( '1' == $restriction['_um_restrict_by_custom_message'] ) { - $post->post_content = ! empty( $restriction['_um_restrict_custom_message'] ) ? stripslashes( $restriction['_um_restrict_custom_message'] ) : ''; - $post->post_title = stripslashes( $restricted_global_title ); - - $this->current_single_post = $post; - - if ( 'attachment' == $post->post_type ) { - remove_filter( 'the_content', 'prepend_attachment' ); - } - } - - $post = apply_filters( 'um_restricted_singular_post', $post, $restriction, $original_post ); - - /** - * UM hook - * - * @type action - * @title um_access_fix_external_post_content - * @description Hook for 3-d party content filtration - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_access_fix_external_post_content', 'function_name', 10 ); - * @example - * - */ - do_action( 'um_access_fix_external_post_content' ); - - add_filter( 'single_template', array( &$this, 'woocommerce_template' ), 9999999, 1 ); - - $filtered_posts[] = $post; - continue; - } elseif ( '1' == $restriction['_um_noaccess_action'] ) { - - $curr = UM()->permalinks()->get_current_url(); - - if ( ! isset( $restriction['_um_access_redirect'] ) || '0' == $restriction['_um_access_redirect'] ) { - - exit( wp_redirect( esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ) ) ); - - } elseif ( '1' == $restriction['_um_access_redirect'] ) { - - if ( ! empty( $restriction['_um_access_redirect_url'] ) ) { - $redirect = $restriction['_um_access_redirect_url']; - } else { - $redirect = esc_url( add_query_arg( 'redirect_to', urlencode_deep( $curr ), um_get_core_page( 'login' ) ) ); - } - - exit( wp_redirect( $redirect ) ); - } - } - } + function user_can( $user_id, $roles ) { + $user_can = false; + + if ( ! empty( $roles ) ) { + foreach ( $roles as $key => $value ) { + if ( ! empty( $value ) && user_can( $user_id, $key ) ) { + $user_can = true; + break; } } } - return $filtered_posts; + return $user_can; } /** - * Get array with restricted posts + * Helper for 3rd-party integrations with content restriction settings * - * @param bool $force + * @param array $restriction * - * @return array + * @return bool */ - function exclude_posts_array( $force = false ) { - if ( $this->ignore_exclude ) { - return array(); - } - - static $cache = array( - 'force' => false, - 'default' => false, - ); - - $cache_key = $force ? 'force' : 'default'; - - if ( false !== $cache[ $cache_key ] ) { - return $cache[ $cache_key ]; - } - - $exclude_posts = array(); - if ( current_user_can( 'administrator' ) ) { - $cache[ $cache_key ] = $exclude_posts; - return $exclude_posts; - } - - // @todo using Object Cache `wp_cache_get()` `wp_cache_set()` functions - - global $wpdb; - - $restricted_posts = UM()->options()->get( 'restricted_access_post_metabox' ); - if ( ! empty( $restricted_posts ) ) { - $this->ignore_exclude = true; - // exclude all posts assigned to current term without individual restriction settings - $post_ids = get_posts( - array( - 'fields' => 'ids', - 'post_status' => 'any', - 'post_type' => array_keys( $restricted_posts ), - 'numberposts' => -1, - 'meta_query' => array( - array( - 'key' => 'um_content_restriction', - 'compare' => 'EXISTS', - ), - ), - ) - ); - - $this->ignore_exclude = false; - } - - $post_ids = empty( $post_ids ) ? array() : $post_ids; - - $restricted_taxonomies = UM()->options()->get( 'restricted_access_taxonomy_metabox' ); - - if ( ! empty( $restricted_taxonomies ) ) { - $restricted_taxonomies = array_keys( $restricted_taxonomies ); - foreach ( $restricted_taxonomies as $k => $taxonomy ) { - if ( ! taxonomy_exists( $taxonomy ) ) { - unset( $restricted_taxonomies[ $k ] ); - } - } - $restricted_taxonomies = array_values( $restricted_taxonomies ); - } - - if ( ! empty( $restricted_taxonomies ) ) { - - $terms = $wpdb->get_results( - "SELECT tm.term_id AS term_id, - tt.taxonomy AS taxonomy - FROM {$wpdb->termmeta} tm - LEFT JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = tm.term_id - WHERE tm.meta_key = 'um_content_restriction' AND - tt.taxonomy IN('" . implode( "','", $restricted_taxonomies ) . "')", - ARRAY_A - ); - - if ( ! empty( $terms ) ) { - foreach ( $terms as $term ) { - if ( ! $this->is_restricted_term( $term['term_id'] ) ) { - continue; - } - - $this->ignore_exclude = true; - // exclude all posts assigned to current term without individual restriction settings - $posts = get_posts( - array( - 'fields' => 'ids', - 'post_status' => 'any', - 'numberposts' => -1, - 'tax_query' => array( - array( - 'taxonomy' => $term['taxonomy'], - 'field' => 'id', - 'terms' => $term['term_id'], - ), - ), - 'meta_query' => array( - 'relation' => 'OR', - array( - 'relation' => 'AND', - array( - 'key' => 'um_content_restriction', - 'value' => 's:26:"_um_custom_access_settings";s:1:"1"', - 'compare' => 'NOT LIKE', - ), - array( - 'key' => 'um_content_restriction', - 'value' => 's:26:"_um_custom_access_settings";b:1', - 'compare' => 'NOT LIKE', - ), - ), - array( - 'key' => 'um_content_restriction', - 'compare' => 'NOT EXISTS', - ), - ), - ) - ); - $this->ignore_exclude = false; - - if ( empty( $posts ) ) { - continue; - } - - $post_ids = array_merge( $post_ids, $posts ); - } - } - } - - if ( ! empty( $post_ids ) ) { - $post_ids = array_unique( $post_ids ); - - foreach ( $post_ids as $post_id ) { - // handle every post privacy setting based on post type maybe it's inactive for now - // if individual restriction is enabled then get post terms restriction settings - if ( $this->is_restricted( $post_id ) ) { - if ( true === $force ) { - array_push( $exclude_posts, $post_id ); - } else { - $content_restriction = $this->get_post_privacy_settings( $post_id ); - if ( ! empty( $content_restriction['_um_access_hide_from_queries'] ) ) { - array_push( $exclude_posts, $post_id ); - } - } - } - } - } - - $exclude_posts = apply_filters( 'um_exclude_restricted_posts_ids', $exclude_posts, $force ); - - $cache[ $cache_key ] = $exclude_posts; - return $exclude_posts; - } - - - /** - * Exclude posts from query - * - * @param \WP_Query $query - */ - function exclude_posts( $query ) { - if ( $query->is_main_query() || ! empty( $query->query_vars['um_main_query'] ) ) { - $force = is_search() || is_admin(); - $exclude_posts = $this->exclude_posts_array( $force ); - if ( ! empty( $exclude_posts ) ) { - $post__not_in = $query->get( 'post__not_in', array() ); - $query->set( 'post__not_in', array_merge( wp_parse_id_list( $post__not_in ), $exclude_posts ) ); - } - } - } - - - /** - * Exclude comments from restricted posts in widgets - * - * @param \WP_Comment_Query $query - */ - function exclude_posts_comments( $query ) { - $exclude_posts = $this->exclude_posts_array( true ); - if ( ! empty( $exclude_posts ) ) { - $post__not_in = ! empty( $query->query_vars['post__not_in'] ) ? $query->query_vars['post__not_in'] : array(); - $query->query_vars['post__not_in'] = array_merge( wp_parse_id_list( $post__not_in ), $exclude_posts ); - } - } - - - /** - * Exclude comments from comments feed - * - * @param string $where - * @param \WP_Query $query - * - * @return string - */ - function exclude_posts_comments_feed( $where, $query ) { - $exclude_posts = $this->exclude_posts_array( true ); - if ( ! empty( $exclude_posts ) ) { - $exclude_string = implode( ',', $exclude_posts ); - $where .= ' AND comment_post_ID NOT IN ( ' . $exclude_string . ' )'; - } - - return $where; - } - - - /** - * Exclude posts from next, previous navigation - * - * @param string $where - * @param bool $in_same_term - * @param array $excluded_terms - * @param string $taxonomy. - * @param \WP_Post $post - * - * @return string - */ - function exclude_navigation_posts( $where, $in_same_term, $excluded_terms, $taxonomy, $post ) { - $exclude_posts = $this->exclude_posts_array(); - if ( ! empty( $exclude_posts ) ) { - $exclude_string = implode( ',', $exclude_posts ); - $where .= ' AND ID NOT IN ( ' . $exclude_string . ' )'; - } - - return $where; - } - - - /** - * Exclude restricted posts in widgets - * - * @param array $array - * - * @return array - */ - function exclude_restricted_posts_widget( $array ) { - $exclude_posts = $this->exclude_posts_array(); - if ( ! empty( $exclude_posts ) ) { - $post__not_in = ! empty( $array['post__not_in'] ) ? $array['post__not_in'] : array(); - $array['post__not_in'] = array_merge( wp_parse_id_list( $post__not_in ), $exclude_posts ); - } - - return $array; - } - - - /** - * Exclude restricted posts in widgets - * - * @param string $sql_where - * @param array $parsed_args - * - * @return string - */ - function exclude_restricted_posts_archives_widget( $sql_where, $parsed_args ) { - $exclude_posts = $this->exclude_posts_array(); - if ( ! empty( $exclude_posts ) ) { - $exclude_string = implode( ',', $exclude_posts ); - $sql_where .= ' AND ID NOT IN ( ' . $exclude_string . ' )'; - } - - return $sql_where; - } - - - /** - * @param string $single_template - * - * @return string - */ - function woocommerce_template( $single_template ) { - if ( ! UM()->dependencies()->woocommerce_active_check() ) { - return $single_template; - } - - if ( is_product() ) { - remove_filter( 'template_include', array( 'WC_Template_Loader', 'template_loader' ) ); - } - - return $single_template; - } - - - /** - * Replace the content on the filter 'the_content' - * - * @param $content - * @return string - */ - function replace_post_content( $content ) { - if ( ! empty( $this->current_single_post ) ) { - $content = $this->current_single_post->post_content; - } - return $content; - } - - - /** - * Turn on the content replacement on the filter 'the_content' - * - * @hooked get_header 12 - * @since 2.1.17 - */ - public function replace_post_content_on() { - add_filter( 'the_content', array( $this, 'replace_post_content' ), 9999, 1 ); - } - - - /** - * Turn off the content replacement on the filter 'the_content' - * - * @hooked get_footer - * @since 2.1.17 - */ - public function replace_post_content_off() { - remove_filter( 'the_content', array( $this, 'replace_post_content' ), 9999 ); - } - - - /** - * Disable comments if user has not permission to access this post - * - * @param mixed $open - * @param int $post_id - * @return boolean - */ - function disable_comments_open( $open, $post_id ) { - static $cache = array(); - - if ( isset( $cache[ $post_id ] ) ) { - return $cache[ $post_id ] ? $open : false; - } - - if ( ! $this->is_restricted( $post_id ) ) { - $cache[ $post_id ] = $open; - return $open; - } - - $open = false; - - $cache[ $post_id ] = $open; - return $open; - } - - - /** - * Disable comments if user has not permission to access this post - * - * @param int $count - * @param int $post_id - * @return boolean - */ - function disable_comments_open_number( $count, $post_id ) { - static $cache_number = array(); - - if ( isset( $cache_number[ $post_id ] ) ) { - return $cache_number[ $post_id ]; - } - - if ( ! $this->is_restricted( $post_id ) ) { - $cache_number[ $post_id ] = $count; - return $count; - } - - $count = 0; - - $cache_number[ $post_id ] = $count; - return $count; + function um_custom_restriction( $restriction ) { + /** + * UM hook + * + * @type filter + * @title um_custom_restriction + * @description Extend Sort Types for Member Directory + * @input_vars + * [{"var":"$custom_restriction","type":"bool","desc":"Custom Restriction"}, + * {"var":"$restriction","type":"array","desc":"Restriction settings"}] + * @change_log + * ["Since: 2.0"] + * @usage add_filter( 'um_custom_restriction', 'function_name', 10, 2 ); + * @example + * + */ + return apply_filters( 'um_custom_restriction', true, $restriction ); } @@ -1817,184 +1983,5 @@ if ( ! class_exists( 'um\core\Access' ) ) { $cache[ $term_id ] = $restricted; return $restricted; } - - - /** - * Hide attachment if the post is restricted - * - * @param string $url - * @param int $attachment_id - * - * @return boolean|string - */ - function filter_attachment( $url, $attachment_id ) { - return ( $attachment_id && $this->is_restricted( $attachment_id ) ) ? false : $url; - } - - - /** - * Hide attachment if the post is restricted - * - * @param $has_thumbnail - * @param $post - * @param $thumbnail_id - * - * @return bool - */ - function filter_post_thumbnail( $has_thumbnail, $post, $thumbnail_id ) { - if ( $this->is_restricted( $thumbnail_id ) ) { - $has_thumbnail = false; - } elseif ( ! empty( $post ) && ! empty( $post->ID ) ) { - if ( $this->is_restricted( $post->ID ) ) { - $has_thumbnail = false; - } - } else { - $post_id = get_the_ID(); - if ( $this->is_restricted( $post_id ) ) { - $has_thumbnail = false; - } - } - - $has_thumbnail = apply_filters( 'um_restrict_post_thumbnail', $has_thumbnail, $post, $thumbnail_id ); - - return $has_thumbnail; - } - - - /** - * Protect Post Types in menu query - * Restrict content new logic - * @param $menu_items - * @param $args - * @return array - */ - function filter_menu( $menu_items, $args ) { - //if empty - if ( empty( $menu_items ) ) { - return $menu_items; - } - - if ( current_user_can( 'administrator' ) ) { - return $menu_items; - } - - $filtered_items = array(); - - //other filter - foreach ( $menu_items as $menu_item ) { - if ( ! empty( $menu_item->object_id ) && ! empty( $menu_item->object ) ) { - if ( isset( $menu_item->type ) && 'taxonomy' === $menu_item->type ) { - if ( ! $this->is_restricted_term( $menu_item->object_id ) ) { - $filtered_items[] = $menu_item; - continue; - } - } elseif ( isset( $menu_item->type ) && 'post_type' === $menu_item->type ) { - if ( ! $this->is_restricted( $menu_item->object_id ) ) { - $filtered_items[] = $menu_item; - continue; - } else { - $restriction_settings = $this->get_post_privacy_settings( $menu_item->object_id ); - if ( empty( $restriction_settings['_um_access_hide_from_queries'] ) ) { - $filtered_items[] = $menu_item; - continue; - } - } - } - } else { - //add all other posts - $filtered_items[] = $menu_item; - } - } - - return $filtered_items; - } - - - /** - * @param $block_content - * @param $block - * - * @return string - */ - function restrict_blocks( $block_content, $block ) { - if ( is_admin() ) { - return $block_content; - } - - $restricted_blocks = UM()->options()->get( 'restricted_blocks' ); - if ( empty( $restricted_blocks ) ) { - return $block_content; - } - - if ( is_user_logged_in() && current_user_can( 'administrator' ) ) { - return $block_content; - } - - if ( ! isset( $block['attrs']['um_is_restrict'] ) || $block['attrs']['um_is_restrict'] !== true ) { - return $block_content; - } - - if ( empty( $block['attrs']['um_who_access'] ) ) { - return $block_content; - } - - $default_message = UM()->options()->get( 'restricted_block_message' ); - switch ( $block['attrs']['um_who_access'] ) { - case '1': { - if ( ! is_user_logged_in() ) { - $block_content = ''; - if ( isset( $block['attrs']['um_message_type'] ) ) { - if ( $block['attrs']['um_message_type'] == '1' ) { - $block_content = $default_message; - } elseif ( $block['attrs']['um_message_type'] == '2' ) { - $block_content = $block['attrs']['um_message_content']; - } - } - } else { - $display = true; - - // What roles can access this content? - if ( ! empty( $block['attrs']['um_roles_access'] ) ) { - $display = false; - foreach ( $block['attrs']['um_roles_access'] as $role ) { - if ( current_user_can( $role ) ) { - $display = true; - } - } - } - - $display = apply_filters( 'um_loggedin_block_restriction', $display, $block ); - - if ( ! $display ) { - $block_content = ''; - if ( isset( $block['attrs']['um_message_type'] ) ) { - if ( $block['attrs']['um_message_type'] == '1' ) { - $block_content = $default_message; - } elseif ( $block['attrs']['um_message_type'] == '2' ) { - $block_content = $block['attrs']['um_message_content']; - } - } - } - } - break; - } - case '2': { - if ( is_user_logged_in() ) { - $block_content = ''; - if ( isset( $block['attrs']['um_message_type'] ) ) { - if ( $block['attrs']['um_message_type'] == '1' ) { - $block_content = $default_message; - } elseif ( $block['attrs']['um_message_type'] == '2' ) { - $block_content = $block['attrs']['um_message_content']; - } - } - } - break; - } - } - - return $block_content; - } - } } diff --git a/includes/core/class-external-integrations.php b/includes/core/class-external-integrations.php index db6c1698..2d33de79 100644 --- a/includes/core/class-external-integrations.php +++ b/includes/core/class-external-integrations.php @@ -29,6 +29,7 @@ if ( ! class_exists( 'um\core\External_Integrations' ) ) { add_action( 'um_access_fix_external_post_content', array( &$this, 'bbpress_no_access_message_fix' ), 10 ); add_action( 'um_access_fix_external_post_content', array( &$this, 'forumwp_fix' ), 11 ); + add_action( 'um_access_fix_external_post_content', array( &$this, 'woocommerce_fix' ), 12 ); add_filter( 'um_localize_permalink_filter', array( &$this, 'um_localize_permalink_filter' ), 10, 2 ); add_filter( 'icl_ls_languages', array( &$this, 'um_core_page_wpml_permalink' ), 10, 1 ); @@ -151,6 +152,30 @@ if ( ! class_exists( 'um\core\External_Integrations' ) ) { } + /** + * Fixed Woocommerce access to Products message + */ + function woocommerce_fix() { + if ( UM()->dependencies()->woocommerce_active_check() ) { + add_filter( 'single_template', array( &$this, 'woocommerce_template' ), 9999999, 1 ); + } + } + + + /** + * @param string $single_template + * + * @return string + */ + function woocommerce_template( $single_template ) { + if ( is_product() ) { + remove_filter( 'template_include', array( 'WC_Template_Loader', 'template_loader' ) ); + } + + return $single_template; + } + + /** * @param $profile_url * @param $page_id @@ -558,4 +583,4 @@ if ( ! class_exists( 'um\core\External_Integrations' ) ) { } -} \ No newline at end of file +} From 733969c84e0792c07ee35deb09d69f4e919b86ce Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Thu, 19 Aug 2021 01:50:13 +0300 Subject: [PATCH 18/24] - added fixes for incorrect posts; --- includes/core/class-access.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 9594e258..1246b581 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -695,6 +695,10 @@ if ( ! class_exists( 'um\core\Access' ) ) { * @return string */ function filter_restricted_post_excerpt( $post_excerpt, $post ) { + if ( empty( $post ) ) { + return $post_excerpt; + } + if ( current_user_can( 'administrator' ) || is_admin() ) { return $post_excerpt; } @@ -751,7 +755,7 @@ if ( ! class_exists( 'um\core\Access' ) ) { } } else { $post_id = get_the_ID(); - if ( $this->is_restricted( $post_id ) ) { + if ( false !== $post_id && $this->is_restricted( $post_id ) ) { $has_thumbnail = false; } } @@ -1629,6 +1633,11 @@ if ( ! class_exists( 'um\core\Access' ) ) { * @return bool|array */ function get_post_privacy_settings( $post ) { + // break for incorrect post + if ( empty( $post ) ) { + return false; + } + static $cache = array(); $cache_key = is_numeric( $post ) ? $post : $post->ID; @@ -1836,6 +1845,11 @@ if ( ! class_exists( 'um\core\Access' ) ) { * @return bool */ function is_restricted( $post_id ) { + // break for incorrect post + if ( empty( $post_id ) ) { + return false; + } + static $cache = array(); if ( isset( $cache[ $post_id ] ) ) { From 81eb7591130584518171e75ecae3ecb651a050ab Mon Sep 17 00:00:00 2001 From: ashubawork <43743394+ashubawork@users.noreply.github.com> Date: Thu, 19 Aug 2021 11:38:23 +0300 Subject: [PATCH 19/24] - fixed a visibility of custom link in a nav menu --- includes/core/class-access.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 1246b581..b37194e4 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -1070,6 +1070,9 @@ if ( ! class_exists( 'um\core\Access' ) ) { continue; } } + } elseif ( isset( $menu_item->type ) && 'custom' === $menu_item->type ) { + $filtered_items[] = $menu_item; + continue; } } else { //add all other posts From 5d773256b9dd3b314b2b03721f1d715ffda67382 Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Thu, 19 Aug 2021 12:58:13 +0300 Subject: [PATCH 20/24] - fixed profile form nonce; - fixed profile form getting ID and data; - fixed class-access.php when restricted taxonomies are disabled; --- includes/core/class-access.php | 18 ++++++++++-------- includes/core/class-fields.php | 11 +++++++++++ includes/core/class-form.php | 13 ++++++++++--- includes/core/um-actions-profile.php | 2 +- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 1246b581..a33b28e6 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -204,14 +204,14 @@ if ( ! class_exists( 'um\core\Access' ) ) { } } $restricted_taxonomies = array_values( $restricted_taxonomies ); - } - if ( ! empty( $post_types ) ) { - $taxonomies = array(); - foreach ( $post_types as $p_t ) { - $taxonomies = array_merge( $taxonomies, get_object_taxonomies( $p_t ) ); + if ( ! empty( $post_types ) ) { + $taxonomies = array(); + foreach ( $post_types as $p_t ) { + $taxonomies = array_merge( $taxonomies, get_object_taxonomies( $p_t ) ); + } + $restricted_taxonomies = array_intersect( $taxonomies, $restricted_taxonomies ); } - $restricted_taxonomies = array_intersect( $taxonomies, $restricted_taxonomies ); } if ( ! empty( $restricted_taxonomies ) ) { @@ -327,9 +327,11 @@ if ( ! class_exists( 'um\core\Access' ) ) { } } $restricted_taxonomies = array_values( $restricted_taxonomies ); - } - $restricted_taxonomies = array_intersect( $query->query_vars['taxonomy'], $restricted_taxonomies ); + if ( ! empty( $restricted_taxonomies ) ) { + $restricted_taxonomies = array_intersect( $query->query_vars['taxonomy'], $restricted_taxonomies ); + } + } if ( empty( $restricted_taxonomies ) ) { return $exclude; diff --git a/includes/core/class-fields.php b/includes/core/class-fields.php index 80e24674..c3be45e0 100644 --- a/includes/core/class-fields.php +++ b/includes/core/class-fields.php @@ -709,6 +709,12 @@ if ( ! class_exists( 'um\core\Fields' ) ) { return ''; } + if ( 'profile' === $this->set_mode ) { + if ( ! isset( UM()->form()->post_form['profile_nonce'] ) || UM()->form()->post_form['profile_nonce'] !== UM()->form()->nonce ) { + return ''; + } + } + return stripslashes_deep( UM()->form()->post_form[ $key ] ); } elseif ( um_user( $key ) && $this->editing == true ) { @@ -3879,6 +3885,11 @@ if ( ! class_exists( 'um\core\Fields' ) ) { UM()->form()->form_suffix = '-' . $this->global_args['form_id']; $this->set_mode = $mode; + + if ( 'profile' === $mode ) { + UM()->form()->nonce = wp_create_nonce( 'um-profile-nonce' . UM()->user()->target_id ); + } + $this->set_id = $this->global_args['form_id']; $this->field_icons = ( isset( $this->global_args['icons'] ) ) ? $this->global_args['icons'] : 'label'; diff --git a/includes/core/class-form.php b/includes/core/class-form.php index e8aa6c02..e601be2a 100644 --- a/includes/core/class-form.php +++ b/includes/core/class-form.php @@ -32,6 +32,9 @@ if ( ! class_exists( 'um\core\Form' ) ) { var $post_form = null; + var $nonce = null; + + /** * Form constructor. */ @@ -331,14 +334,18 @@ if ( ! class_exists( 'um\core\Form' ) ) { if ( $http_post && ! is_admin() && isset( $_POST['form_id'] ) && is_numeric( $_POST['form_id'] ) ) { - $this->form_id = absint( $_POST['form_id'] ); - $this->form_status = get_post_status( $this->form_id ); - $this->form_data = UM()->query()->post_data( $this->form_id ); + $this->form_id = absint( $_POST['form_id'] ); + if ( 'um_form' !== get_post_type( $this->form_id ) ) { + return; + } + $this->form_status = get_post_status( $this->form_id ); if ( 'publish' !== $this->form_status ) { return; } + $this->form_data = UM()->query()->post_data( $this->form_id ); + /** * UM hook * diff --git a/includes/core/um-actions-profile.php b/includes/core/um-actions-profile.php index 0233e127..92ccf3e5 100644 --- a/includes/core/um-actions-profile.php +++ b/includes/core/um-actions-profile.php @@ -629,7 +629,7 @@ function um_editing_user_id_input( $args ) { if ( UM()->fields()->editing == 1 && UM()->fields()->set_mode == 'profile' && UM()->user()->target_id ) { ?> - + Date: Thu, 19 Aug 2021 14:09:57 +0300 Subject: [PATCH 21/24] - fixed PHP fatal error on the page list widget displaying; --- includes/core/class-access.php | 3 ++- includes/core/class-fields.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index da490b6c..48e34561 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -1202,7 +1202,8 @@ if ( ! class_exists( 'um\core\Access' ) ) { $is_singular = ! empty( $query->is_singular ) ? true : false; } - if ( $query->is_main_query() || ! empty( $query->query_vars['um_main_query'] ) ) { + if ( is_object( $query ) && is_a( $query, '\WP_Query' ) && + ( $query->is_main_query() || ! empty( $query->query_vars['um_main_query'] ) ) ) { if ( $is_singular ) { if ( $this->is_restricted( $posts[0]->ID ) ) { $content_restriction = $this->get_post_privacy_settings( $posts[0]->ID ); diff --git a/includes/core/class-fields.php b/includes/core/class-fields.php index c3be45e0..8ecc9915 100644 --- a/includes/core/class-fields.php +++ b/includes/core/class-fields.php @@ -710,7 +710,7 @@ if ( ! class_exists( 'um\core\Fields' ) ) { } if ( 'profile' === $this->set_mode ) { - if ( ! isset( UM()->form()->post_form['profile_nonce'] ) || UM()->form()->post_form['profile_nonce'] !== UM()->form()->nonce ) { + if ( ! isset( UM()->form()->post_form['profile_nonce'] ) || false === wp_verify_nonce( UM()->form()->post_form['profile_nonce'], 'um-profile-nonce' . UM()->user()->target_id ) ) { return ''; } } From 05f4d5fda4cf09c32b485a31bb1aca8a7cf8cc3e Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Mon, 23 Aug 2021 10:29:02 +0300 Subject: [PATCH 22/24] - removed admin notice with make review info; --- includes/admin/core/class-admin-notices.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/admin/core/class-admin-notices.php b/includes/admin/core/class-admin-notices.php index 61a32bcd..50d7fe51 100644 --- a/includes/admin/core/class-admin-notices.php +++ b/includes/admin/core/class-admin-notices.php @@ -48,7 +48,8 @@ if ( ! class_exists( 'um\admin\core\Admin_Notices' ) ) { $this->need_upgrade(); $this->check_wrong_licenses(); - $this->reviews_notice(); + // removed for now to avoid the bad reviews + //$this->reviews_notice(); //$this->future_changed(); From f96e384b35a3b0954a78a824baa0e556fe2593bc Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Mon, 23 Aug 2021 16:12:55 +0300 Subject: [PATCH 23/24] - fixed nav-menu visibility; --- includes/core/class-access.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/core/class-access.php b/includes/core/class-access.php index 48e34561..5073d5bb 100644 --- a/includes/core/class-access.php +++ b/includes/core/class-access.php @@ -1075,6 +1075,9 @@ if ( ! class_exists( 'um\core\Access' ) ) { } elseif ( isset( $menu_item->type ) && 'custom' === $menu_item->type ) { $filtered_items[] = $menu_item; continue; + } else { + $filtered_items[] = $menu_item; + continue; } } else { //add all other posts From 59fc508532847f79465218d06353721756f36a1a Mon Sep 17 00:00:00 2001 From: Nikita Sinelnikov Date: Mon, 23 Aug 2021 16:24:43 +0300 Subject: [PATCH 24/24] - updated readme; - prepared to the release; --- readme.txt | 11 +++++++++-- ultimate-member.php | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/readme.txt b/readme.txt index f179abf2..1fe0148f 100644 --- a/readme.txt +++ b/readme.txt @@ -7,7 +7,7 @@ Tags: community, member, membership, user-profile, user-registration Requires PHP: 5.6 Requires at least: 5.0 Tested up to: 5.8 -Stable tag: 2.2.2 +Stable tag: 2.2.3 License: GNU Version 2 or Any Later Version License URI: http://www.gnu.org/licenses/gpl-3.0.txt @@ -155,7 +155,7 @@ The plugin works with popular caching plugins by automatically excluding Ultimat * To learn more about version 2.1 please see this [docs](https://docs.ultimatemember.com/article/1512-upgrade-2-1-0) * UM2.1+ is a significant update to the Member Directories' code base from 2.0.x. Please make sure you take a full-site backup with restore point before updating the plugin -= 2.2.3: August 11, 2021 = += 2.2.3: August 25, 2021 = * Enhancements: @@ -169,6 +169,13 @@ The plugin works with popular caching plugins by automatically excluding Ultimat - Fixed: Displaying 404 error for the restricted Media - Fixed: Displaying 'Login as this user' action on the user profile - Fixed: Sanitizing of the social links fields (e.g. Twitter, Facebook, etc.) + - Fixed: Visibility of a restricted taxonomy page in the nav menu + - Fixed: Sanitizing key for the drag&drop action + - Fixed: Sanitizing the description field with allowed HTML inside + - Fixed: The "Assignment to constant variable" JS error on some sites + - Fixed: Keep description formatting in a view mode + - Fixed: Profile form nonce handling, security enhancement + - Optimized: Restriction content handlers, avoid queries duplicates or unnecessary queries = 2.2.2: August 3, 2021 = diff --git a/ultimate-member.php b/ultimate-member.php index b6f88f91..8a630fee 100644 --- a/ultimate-member.php +++ b/ultimate-member.php @@ -3,7 +3,7 @@ Plugin Name: Ultimate Member Plugin URI: http://ultimatemember.com/ Description: The easiest way to create powerful online communities and beautiful user profiles with WordPress -Version: 2.2.3-beta2 +Version: 2.2.3 Author: Ultimate Member Author URI: http://ultimatemember.com/ Text Domain: ultimate-member