From 33ce6d7ae57d39251485e4300303df73d4a841ff Mon Sep 17 00:00:00 2001 From: nikitasinelnikov Date: Fri, 20 Dec 2019 15:06:58 +0200 Subject: [PATCH] - commit with user metadata table; --- assets/js/um-members.js | 28 +- assets/js/um-members.min.js | 2 +- includes/admin/core/class-admin-settings.php | 184 ++++ includes/class-config.php | 1 + includes/class-init.php | 9 +- includes/core/class-member-directory-meta.php | 871 ++++++++++++++++++ includes/core/class-member-directory.php | 41 +- includes/core/class-roles-capabilities.php | 4 +- includes/core/class-setup.php | 25 + 9 files changed, 1141 insertions(+), 24 deletions(-) create mode 100644 includes/core/class-member-directory-meta.php diff --git a/assets/js/um-members.js b/assets/js/um-members.js index 5e80b1fb..fe5e4558 100644 --- a/assets/js/um-members.js +++ b/assets/js/um-members.js @@ -1191,20 +1191,27 @@ jQuery(document.body).ready( function() { um_set_url_from_data( directory, 'filter_' + filter_name + '_from','' ); um_set_url_from_data( directory, 'filter_' + filter_name + '_to', '' ); - jQuery( '.um-search-filter input[name="filter_' + filter_name + '_from"]' ).val(''); - jQuery( '.um-search-filter input[name="filter_' + filter_name + '_to"]' ).val(''); + var $slider = jQuery( '.um-search-filter #' + filter_name + '_min' ).siblings('.um-slider'); + var options = $slider.slider( 'option' ); + + $slider.slider( 'values', [ options.min, options.max ] ); + + jQuery( '.um-search-filter #' + filter_name + '_min' ).val(''); + jQuery( '.um-search-filter #' + filter_name + '_max' ).val(''); + + um_set_range_label( $slider ); } else if ( type === 'datepicker' ) { um_set_url_from_data( directory, 'filter_' + filter_name + '_from','' ); um_set_url_from_data( directory, 'filter_' + filter_name + '_to', '' ); - jQuery( '.um-search-filter input[name="filter_' + filter_name + '_from"]' ).val(''); - jQuery( '.um-search-filter input[name="filter_' + filter_name + '_to"]' ).val(''); + jQuery( '.um-search-filter #' + filter_name + '_from' ).val(''); + jQuery( '.um-search-filter #' + filter_name + '_to' ).val(''); } else if ( type === 'timepicker' ) { um_set_url_from_data( directory, 'filter_' + filter_name + '_from','' ); um_set_url_from_data( directory, 'filter_' + filter_name + '_to', '' ); - jQuery( '.um-search-filter input[name="filter_' + filter_name + '_from"]' ).val(''); - jQuery( '.um-search-filter input[name="filter_' + filter_name + '_to"]' ).val(''); + jQuery( '.um-search-filter #' + filter_name + '_from' ).val(''); + jQuery( '.um-search-filter #' + filter_name + '_to' ).val(''); } }); @@ -1341,6 +1348,11 @@ jQuery(document.body).ready( function() { elem.blur(); }, onSet: function( context ) { + + if ( ! context.select ) { + return; + } + var directory = elem.parents('.um-directory'); if ( um_is_directory_busy( directory ) ) { @@ -1424,6 +1436,10 @@ jQuery(document.body).ready( function() { onClose: function() { elem.blur(); }, onSet: function( context ) { + if ( ! context.select ) { + return; + } + var directory = elem.parents('.um-directory'); if ( um_is_directory_busy( directory ) ) { diff --git a/assets/js/um-members.min.js b/assets/js/um-members.min.js index ab30b5b1..cbf0e82a 100644 --- a/assets/js/um-members.min.js +++ b/assets/js/um-members.min.js @@ -1 +1 @@ -var um_members_directory_busy=[],um_member_directories=[],um_member_directory_last_data=[];function um_parse_current_url(){var t={},a=window.location.search.substring(1).split("&");return jQuery.each(a,function(e){var r=a[e].split("=");t[r[0]]=r[1]}),t}function um_get_data_for_directory(e,r){var t=um_members_get_hash(e),a={},i=um_parse_current_url();if(jQuery.each(i,function(e){-1!==e.indexOf("_"+t)&&""!==i[e]&&(a[e.replace("_"+t,"")]=i[e])}),r){if(void 0!==a[r])try{a[r]=decodeURIComponent(a[r])}catch(e){console.error(e)}return a[r]}return a}function um_set_url_from_data(e,r,t){var a=um_members_get_hash(e),i=um_get_data_for_directory(e),m={};jQuery.isArray(t)?(jQuery.each(t,function(e){t[e]=encodeURIComponent(t[e])}),t=t.join("||")):jQuery.isNumeric(t)||(t=t.split("||"),jQuery.each(t,function(e){t[e]=encodeURIComponent(t[e])}),t=t.join("||")),""!==t&&(m[r+"_"+a]=t),jQuery.each(i,function(e){r===e?""!==t&&(m[e+"_"+a]=t):m[e+"_"+a]=i[e]}),jQuery.each(um_member_directories,function(e){var r=um_member_directories[e];if(r!==a){var t=um_get_data_for_directory(jQuery('.um-directory[data-hash="'+r+'"]'));jQuery.each(t,function(e){m[e+"_"+r]=t[e]})}});var d=[];jQuery.each(m,function(e){d.push(e+"="+m[e])});var u="?"+(d=wp.hooks.applyFilters("um_member_directory_url_attrs",d)).join("&");"?"===u&&(u=""),window.history.pushState("string","UM Member Directory",window.location.origin+window.location.pathname+u)}function um_members_get_hash(e){return e.data("hash")}function um_is_directory_busy(e){var r=um_members_get_hash(e);return void 0!==um_members_directory_busy[r]&&um_members_directory_busy[r]}function um_members_show_preloader(e){um_members_directory_busy[um_members_get_hash(e)]=!0,e.find(".um-members-overlay").show()}function um_members_hide_preloader(e){um_members_directory_busy[um_members_get_hash(e)]=!1,e.find(".um-members-overlay").hide()}function um_set_range_label(e,r){var t=e.siblings(".um-slider-range").data("placeholder");t=r?t.replace("{min_range}",r.values[0]).replace("{max_range}",r.values[1]).replace("{field_label}",e.siblings(".um-slider-range").data("label")):t.replace("{min_range}",e.slider("values",0)).replace("{max_range}",e.slider("values",1)).replace("{field_label}",e.siblings(".um-slider-range").data("label")),e.siblings(".um-slider-range").html(t),e.siblings(".um_range_min").val(e.slider("values",0)),e.siblings(".um_range_max").val(e.slider("values",1))}function um_get_search(e){return e.find(".um-search-line").length?e.find(".um-search-line").val():""}function um_get_sort(e){return e.data("sorting")}function um_get_current_page(e){var r=e.data("page");return r&&void 0!==r||(r=1),r}function um_time_convert(e,r){var t=Math.floor(e/60),a=e%60;return 60<=a&&(a=0,24<=(t+=1)&&(t=0)),a<10&&(a="0"+a),t+":"+a}function um_ajax_get_members(s,t){var a=um_members_get_hash(s),e=um_get_current_page(s),r=um_get_search(s),i=um_get_sort(s),m=-(new Date).getTimezoneOffset()/60,_={directory_id:a,page:e,search:r,sorting:i,gmt_offset:m,post_refferer:s.data("base-post"),nonce:um_scripts.nonce};s.find(".um-search-filter").length&&s.find(".um-search-filter").each(function(){var e=jQuery(this);if(e.find(".um-slider").length){var r=e.find(".um-slider").data("field_name"),t=um_get_data_for_directory(s,"filter_"+r+"_from"),a=um_get_data_for_directory(s,"filter_"+r+"_to");void 0===t&&void 0===a||(_[r]=[t,a])}else if(e.find(".um-datepicker-filter").length){r=e.find(".um-datepicker-filter").data("filter_name"),t=um_get_data_for_directory(s,"filter_"+r+"_from"),a=um_get_data_for_directory(s,"filter_"+r+"_to");void 0===t&&void 0===a||(_[r]=[t,a])}else if(e.find(".um-timepicker-filter").length){r=e.find(".um-timepicker-filter").data("filter_name"),t=um_get_data_for_directory(s,"filter_"+r+"_from"),a=um_get_data_for_directory(s,"filter_"+r+"_to");if(void 0!==t)(i=1*(t=t.split(":"))[0])<10&&(i="0"+i),(d=1*t[1])<10&&(d="0"+d),t=i+":"+d+":00";if(void 0!==a){var i,m=a.split(":"),d=1*m[1];(i=1*m[0])<10&&(i="0"+i),d<10&&(d="0"+d),a=i+":"+d+":59"}void 0===t&&void 0===a||(_[r]=[t,a])}else if(e.find("select").length){r=e.find("select").attr("name");void 0!==(u=um_get_data_for_directory(s,"filter_"+r))&&(_[r]=u.split("||"))}else{var u;r=e.find('input[type="text"]').attr("name");void 0!==(u=um_get_data_for_directory(s,"filter_"+r))&&(_[r]=u)}}),_=wp.hooks.applyFilters("um_member_directory_filter_request",_),wp.ajax.send("um_get_members",{data:_,success:function(e){um_member_directory_last_data[a]=e,um_build_template(s,e);var r=wp.template("um-members-pagination");s.find(".um-members-pagination-box").html(r(e)),s.data("total_pages",e.pagination.total_pages),e.pagination.total_pages?(s.find(".um-member-directory-sorting-options").prop("disabled",!1),s.find(".um-member-directory-view-type").removeClass("um-disabled")):(s.find(".um-member-directory-sorting-options").prop("disabled",!0),s.find(".um-member-directory-view-type").addClass("um-disabled")),jQuery(document).trigger("um_members_rendered",t),um_init_new_dropdown(),um_members_hide_preloader(s)},error:function(e){console.log(e),um_members_hide_preloader(s)}})}function um_build_template(e,r){var t=e.data("view_type"),a=wp.template("um-member-"+t+"-"+um_members_get_hash(e));e.find(".um-members-grid, .um-members-list").remove(),e.find(".um-members-wrapper").prepend(a(r.users));var i=wp.template("um-members-header");e.find(".um-members-intro").remove(),void 0!==r.is_search&&r.is_search&&e.find(".um-members-wrapper").prepend(i(r)),e.addClass("um-loaded"),e.find(".um-members.um-members-grid").length&&UM_Member_Grid(e.find(".um-members.um-members-grid")),jQuery(document).trigger("um_build_template",[e,r]),jQuery(window).trigger("resize"),init_tipsy()}function UM_Member_Grid(e){e.find(".um-member").length&&e.imagesLoaded(function(){e.masonry({itemSelector:".um-member",columnWidth:".um-member",gutter:".um-gutter-sizer"}).on("layoutComplete",function(e,r){jQuery(document).trigger("um_grid_initialized",[e,r])})})}function um_get_filters_data(s){var _=[];return s.find(".um-search-filter").each(function(){var t,a,d,i=jQuery(this);if(i.find("input.um-datepicker-filter").length)d="datepicker",i.find("input.um-datepicker-filter").each(function(){if("to"!==jQuery(this).data("range")){var e=jQuery(this).data("filter_name"),r=um_get_data_for_directory(s,"filter_"+e+"_from"),t=um_get_data_for_directory(s,"filter_"+e+"_to");if(void 0!==r||void 0!==t){var a,i=jQuery(this).val(),m=s.find('input.um-datepicker-filter[data-range="to"][data-filter_name="'+e+'"]').val();i===m?a=m:""!==i&&""!==m?a=i+" - "+m:""===i?a="before "+m:""===m&&(a="since "+i),_.push({name:e,label:jQuery(this).data("filter-label"),value_label:a,value:[r,t],type:d})}}});else if(i.find("input.um-timepicker-filter").length)d="timepicker",i.find("input.um-timepicker-filter").each(function(){if("to"!==jQuery(this).data("range")){var e=jQuery(this).data("filter_name"),r=um_get_data_for_directory(s,"filter_"+e+"_from"),t=um_get_data_for_directory(s,"filter_"+e+"_to");if(void 0!==r||void 0!==t){var a,i=jQuery(this).val(),m=s.find('input.um-timepicker-filter[data-range="to"][data-filter_name="'+e+'"]').val();i===m?a=m:""!==i&&""!==m?a=i+" - "+m:""===i?a="before "+m:""===m&&(a="since "+i),_.push({name:e,label:jQuery(this).data("filter-label"),value_label:a,value:[r,t],type:d})}}});else if(i.find("select").length){d="select",t=i.find("select").attr("name"),a=i.find("select").data("placeholder"),m=void 0===(m=um_get_data_for_directory(s,"filter_"+t))?[]:m.split("||"),jQuery.each(m,function(e){var r=i.find('select option[value="'+m[e]+'"]').data("value_label");_.push({name:t,label:a,value_label:r,value:m[e],type:d})})}else if(i.find('input[type="text"]').length){var m;d="text",t=i.find('input[type="text"]').attr("name"),a=i.find('input[type="text"]').attr("placeholder"),void 0===(m=um_get_data_for_directory(s,"filter_"+t))&&(m=""),""!=m&&_.push({name:t,label:a,value_label:m,value:m,type:d})}else if(i.find("div.ui-slider").length){d="slider",t=i.find("div.ui-slider").data("field_name");var e=um_get_data_for_directory(s,"filter_"+t+"_from"),r=um_get_data_for_directory(s,"filter_"+t+"_to");if(void 0===e&&void 0===r)return;a=i.find("div.um-slider-range").data("label");var u=i.find("div.um-slider-range").data("placeholder").replace("{min_range}",e).replace("{max_range}",r).replace("{field_label}",i.find("div.um-slider-range").data("label"));_.push({name:t,label:a,value_label:u,value:[e,r],type:d})}}),_}function um_change_tag(e){var r=um_get_filters_data(e);e.find(".um-members-filter-tag").remove();var t=e.find(".um-filtered-line");if(t.length){var a=wp.template("um-members-filtered-line");t.prepend(a({filters:r})),0===e.find(".um-members-filter-remove").length?(e.find(".um-clear-filters").hide(),e.find(".um-clear-filters").parents(".um-member-directory-header-row").addClass("um-header-row-invisible")):(e.find(".um-clear-filters").show(),e.find(".um-clear-filters").parents(".um-member-directory-header-row").removeClass("um-header-row-invisible"))}}function um_run_search(e){if(!um_is_directory_busy(e)){um_members_show_preloader(e);var r=um_get_data_for_directory(e,"search");if((a=e.find(".um-search-line").val())===r||""===a&&void 0===r)um_members_hide_preloader(e);else{e.data("general_search",a),um_set_url_from_data(e,"search",a),e.data("page",1),um_set_url_from_data(e,"page","");var t=!1;if(!(t=wp.hooks.applyFilters("um_member_directory_ignore_after_search",t)))if(1===e.data("must-search")){var a=um_get_search(e);if(0===e.find(".um-members-filter-remove").length&&!a)return e.data("searched",0),e.find(".um-members-grid, .um-members-list").remove(),e.find(".um-member-directory-sorting-options").prop("disabled",!0),e.find(".um-member-directory-view-type").addClass("um-disabled"),void um_members_hide_preloader(e)}e.data("searched",1),e.find(".um-member-directory-sorting-options").prop("disabled",!1),e.find(".um-member-directory-view-type").removeClass("um-disabled"),um_ajax_get_members(e)}}}jQuery(document.body).ready(function(){jQuery(".um-directory .um-search-filter select").each(function(){1===jQuery(this).find("option:not(:disabled)").length&&jQuery(this).prop("disabled",!0),jQuery(this).select2("destroy").select2()}),jQuery(document.body).on("mouseover",".um-directory .um-member-directory-view-type",function(){if(!jQuery(this).hasClass("um-disabled")){var e=jQuery(this).find(".um-member-directory-view-type-a:visible");e.hide(),e.next().length?e.next().show().tipsy("show"):jQuery(this).find(".um-member-directory-view-type-a:first").show().tipsy("show")}}).on("mouseout",".um-directory .um-member-directory-view-type",function(){jQuery(this).hasClass("um-disabled")||(jQuery(this).find(".um-member-directory-view-type-a").hide().tipsy("hide"),jQuery(this).find('.um-member-directory-view-type-a[data-type="'+jQuery(this).parents(".um-directory").data("view_type")+'"]').show())}),jQuery(document.body).on("click",".um-directory .um-member-directory-view-type-a",function(){var e=jQuery(this).parents(".um-directory");if(um_is_directory_busy(e))return!1;var r=jQuery(this),t=r.parents(".um-member-directory-view-type");if(!t.hasClass("um-disabled")){um_members_show_preloader(e);var a=t.find(".um-member-directory-view-type-a:visible");a.hide(),a.next().length?a.next().show().tipsy("show"):t.find(".um-member-directory-view-type-a:first").show().tipsy("show");var i=um_member_directory_last_data[um_members_get_hash(e)];if(null!==i){var m=r.data("type");um_set_url_from_data(e,"view_type",m),e.data("view_type",m),um_build_template(e,i)}um_members_hide_preloader(e)}}),jQuery(document.body).on("click",".um-directory .um-do-search",function(){um_run_search(jQuery(this).parents(".um-directory"))}),jQuery(document.body).on("keypress",".um-directory .um-search-line",function(e){13===e.which&&um_run_search(jQuery(this).parents(".um-directory"))}),jQuery(document.body).on("click",".um-directory .um-member-directory-sorting-a .um-new-dropdown li a",function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)&&1!==jQuery(this).data("selected")){um_members_show_preloader(e);var r=jQuery(this).data("value");e.data("sorting",r),um_set_url_from_data(e,"sort",r),um_ajax_get_members(e),jQuery(this).parents(".um-new-dropdown").find("a").data("selected",0).prop("data-selected",0).attr("data-selected",0),jQuery(this).data("selected",1).prop("data-selected",1).attr("data-selected",1),jQuery(this).parents(".um-member-directory-sorting-a").find("> a").html(jQuery(this).html())}}),jQuery(document.body).on("click",".um-directory .pagi:not(.current)",function(){if(!jQuery(this).hasClass("disabled")){var e,r=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(r))um_members_show_preloader(r),1===(e="first"===jQuery(this).data("page")?1:"prev"===jQuery(this).data("page")?1*r.data("page")-1:"next"===jQuery(this).data("page")?1*r.data("page")+1:"last"===jQuery(this).data("page")?parseInt(r.data("total_pages")):parseInt(jQuery(this).data("page")))?(r.find('.pagi[data-page="first"], .pagi[data-page="prev"]').addClass("disabled"),r.find('.pagi[data-page="prev"], .pagi[data-page="last"]').removeClass("disabled")):(e===parseInt(r.data("total_pages"))?r.find('.pagi[data-page="prev"], .pagi[data-page="last"]').addClass("disabled"):r.find('.pagi[data-page="prev"], .pagi[data-page="last"]').removeClass("disabled"),r.find('.pagi[data-page="first"], .pagi[data-page="prev"]').removeClass("disabled")),r.find(".pagi").removeClass("current"),r.find('.pagi[data-page="'+e+'"]').addClass("current"),r.data("page",e),um_set_url_from_data(r,"page",1===e?"":e),um_ajax_get_members(r)}}),jQuery(document.body).on("change",".um-directory .um-members-pagi-dropdown",function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)){um_members_show_preloader(e);var r=jQuery(this).val();e.find(".pagi").removeClass("current"),e.find('.pagi[data-page="'+r+'"]').addClass("current"),e.data("page",r),um_set_url_from_data(e,"page",1===r?"":r),um_ajax_get_members(e)}}),jQuery(document.body).on("click",".um-directory .um-members.um-members-list .um-member-more a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member");return r.find(".um-member-more").hide(),r.find(".um-member-meta-main").slideDown(),r.find(".um-member-less").fadeIn(),!1}),jQuery(document.body).on("click",".um-directory .um-members.um-members-list .um-member-less a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member");return r.find(".um-member-less").hide(),r.find(".um-member-meta-main").slideUp(),r.find(".um-member-more").fadeIn(),!1}),jQuery(document.body).on("click",".um-directory .um-members.um-members-grid .um-member-more a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member"),t=jQuery(this).parents(".um-members");return r.find(".um-member-more").hide(),r.find(".um-member-meta").slideDown(function(){UM_Member_Grid(t)}),r.find(".um-member-less").fadeIn(),setTimeout(function(){UM_Member_Grid(t)},100),!1}),jQuery(document.body).on("click",".um-directory .um-members.um-members-grid .um-member-less a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member"),t=jQuery(this).parents(".um-members");return r.find(".um-member-less").hide(),r.find(".um-member-meta").slideUp(function(){r.find(".um-member-more").fadeIn(),UM_Member_Grid(t)}),!1}),jQuery(".um-member-directory-filters-a").click(function(){var e=jQuery(this),r=e.parents(".um-directory").find(".um-search");r.is(":visible")?r.slideUp(250,function(){e.toggleClass("um-member-directory-filters-visible"),r.parents(".um-member-directory-header-row").toggleClass("um-header-row-invisible")}):r.slideDown({duration:250,start:function(){jQuery(this).css({display:"grid"}),e.toggleClass("um-member-directory-filters-visible"),r.parents(".um-member-directory-header-row").toggleClass("um-header-row-invisible")}})}),jQuery(document.body).on("change",".um-directory .um-search-filter select",function(){if(""!==jQuery(this).val()){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)){um_members_show_preloader(e);var r=jQuery(this).prop("name"),t=um_get_data_for_directory(e,"filter_"+r);t=void 0===t?[]:t.split("||"),-1===jQuery.inArray(jQuery(this).val(),t)&&(t.push(jQuery(this).val()),um_set_url_from_data(e,"filter_"+r,t=t.join("||")),e.data("page",1),um_set_url_from_data(e,"page","")),jQuery(this).find('option[value="'+jQuery(this).val()+'"]').prop("disabled",!0).hide(),1===jQuery(this).find("option:not(:disabled)").length&&jQuery(this).prop("disabled",!0),jQuery(this).select2("destroy").select2(),jQuery(this).val("").trigger("change"),um_ajax_get_members(e),um_change_tag(e),e.data("searched",1),e.find(".um-member-directory-sorting-options").prop("disabled",!1),e.find(".um-member-directory-view-type").removeClass("um-disabled")}}}),jQuery(document.body).on("blur",'.um-directory .um-search-filter.um-text-filter-type input[type="text"]',function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)){var r=jQuery(this).val(),t=jQuery(this).prop("name"),a=um_get_data_for_directory(e,"filter_"+t);void 0===a&&(a=""),r!==a&&(um_members_show_preloader(e),um_set_url_from_data(e,"filter_"+t,r),e.data("page",1),um_set_url_from_data(e,"page",""),um_ajax_get_members(e),um_change_tag(e),e.data("searched",1),e.find(".um-member-directory-sorting-options").prop("disabled",!1),e.find(".um-member-directory-view-type").removeClass("um-disabled"))}}),jQuery(document.body).on("keypress",'.um-directory .um-search-filter.um-text-filter-type input[type="text"]',function(e){if(13===e.which){var r=jQuery(this).parents(".um-directory");if(um_is_directory_busy(r))return;var t=jQuery(this).val(),a=jQuery(this).prop("name"),i=um_get_data_for_directory(r,"filter_"+a);if(void 0===i&&(i=""),t===i)return;um_members_show_preloader(r),um_set_url_from_data(r,"filter_"+a,t),r.data("page",1),um_set_url_from_data(r,"page",""),um_ajax_get_members(r),um_change_tag(r),r.data("searched",1),r.find(".um-member-directory-sorting-options").prop("disabled",!1),r.find(".um-member-directory-view-type").removeClass("um-disabled")}}),jQuery(document.body).on("click",".um-directory .um-members-filter-remove",function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)&&e){um_members_show_preloader(e);var r=jQuery(this).data("value"),t=jQuery(this).data("name"),a=jQuery(this).data("type");if("text"===a)um_set_url_from_data(e,"filter_"+t,""),jQuery('.um-search-filter input[name="'+t+'"]').val("");else if("select"===a){var i=um_get_data_for_directory(e,"filter_"+t);i=void 0===i?[]:i.split("||"),-1!==jQuery.inArray(r.toString(),i)&&(i=jQuery.grep(i,function(e){return e!==r.toString()})),i.length||(i=""),um_set_url_from_data(e,"filter_"+t,i);var m=jQuery('.um-search-filter select[name="'+t+'"]');m.find('option[value="'+r+'"]').prop("disabled",!1).show(),1d.data("total_pages")&&(r=d.data("total_pages")),d.data("page",r).attr("data-page",r),d.find(".um-member-directory-sorting").length){var t=um_get_data_for_directory(d,"sort");void 0===t&&(t=d.find('.um-new-dropdown[data-element=".um-member-directory-sorting-a"]').find('a[data-default="1"]').data("value")),d.data("sorting",t);var a=d.find('.um-new-dropdown[data-element=".um-member-directory-sorting-a"]');a.find("a").data("selected",0).prop("data-selected",0).attr("data-selected",0),a.find('a[data-value="'+t+'"]').data("selected",1).prop("data-selected",1).attr("data-selected",1),d.find(".um-member-directory-sorting-a").find("> a").html(a.find('a[data-value="'+t+'"]').html())}if(d.find(".um-member-directory-view-type").length){var i=um_get_data_for_directory(d,"view_type");void 0===i&&(i=d.find('.um-member-directory-view-type-a[data-default="1"]').data("type")),d.data("view_type",i),d.find(".um-member-directory-view-type .um-member-directory-view-type-a").hide(),d.find('.um-member-directory-view-type .um-member-directory-view-type-a[data-type="'+i+'"]').show()}d.find(".um-datepicker-filter").each(function(){var e=jQuery(this),r=e.pickadate("picker"),t=e.data("filter_name"),a=e.data("range"),i=um_get_data_for_directory(d,"filter_"+t+"_"+a);void 0!==i?r.set("select",1e3*i):r.clear()}),d.find(".um-slider").each(function(){var e=jQuery(this),r=e.data("field_name"),t=um_get_data_for_directory(d,"filter_"+r+"_from"),a=um_get_data_for_directory(d,"filter_"+r+"_to");void 0===t&&(t=e.data("min")),t=parseInt(t),void 0===a&&(a=e.data("max")),a=parseInt(a),e.slider("values",[t,a]),um_set_range_label(e)}),d.find(".um-timepicker-filter").each(function(){var e=jQuery(this),r=e.pickatime("picker"),t=e.data("filter_name"),a=e.data("range"),i=um_get_data_for_directory(d,"filter_"+t+"_"+a);if(void 0!==i){var m=i.split(":");r.set("select",60*m[0])}else r.clear()});var m=!1;if(!(m=wp.hooks.applyFilters("um_member_directory_ignore_after_search",m))&&1===d.data("must-search")){var u=um_get_search(d);if(!um_get_filters_data(d).length&&!u)return d.data("searched",0),void um_members_hide_preloader(d);d.data("searched",1)}um_ajax_get_members(d),um_change_tag(d)})})}); \ No newline at end of file +var um_members_directory_busy=[],um_member_directories=[],um_member_directory_last_data=[];function um_parse_current_url(){var t={},a=window.location.search.substring(1).split("&");return jQuery.each(a,function(e){var r=a[e].split("=");t[r[0]]=r[1]}),t}function um_get_data_for_directory(e,r){var t=um_members_get_hash(e),a={},i=um_parse_current_url();if(jQuery.each(i,function(e){-1!==e.indexOf("_"+t)&&""!==i[e]&&(a[e.replace("_"+t,"")]=i[e])}),r){if(void 0!==a[r])try{a[r]=decodeURIComponent(a[r])}catch(e){console.error(e)}return a[r]}return a}function um_set_url_from_data(e,r,t){var a=um_members_get_hash(e),i=um_get_data_for_directory(e),m={};jQuery.isArray(t)?(jQuery.each(t,function(e){t[e]=encodeURIComponent(t[e])}),t=t.join("||")):jQuery.isNumeric(t)||(t=t.split("||"),jQuery.each(t,function(e){t[e]=encodeURIComponent(t[e])}),t=t.join("||")),""!==t&&(m[r+"_"+a]=t),jQuery.each(i,function(e){r===e?""!==t&&(m[e+"_"+a]=t):m[e+"_"+a]=i[e]}),jQuery.each(um_member_directories,function(e){var r=um_member_directories[e];if(r!==a){var t=um_get_data_for_directory(jQuery('.um-directory[data-hash="'+r+'"]'));jQuery.each(t,function(e){m[e+"_"+r]=t[e]})}});var d=[];jQuery.each(m,function(e){d.push(e+"="+m[e])});var u="?"+(d=wp.hooks.applyFilters("um_member_directory_url_attrs",d)).join("&");"?"===u&&(u=""),window.history.pushState("string","UM Member Directory",window.location.origin+window.location.pathname+u)}function um_members_get_hash(e){return e.data("hash")}function um_is_directory_busy(e){var r=um_members_get_hash(e);return void 0!==um_members_directory_busy[r]&&um_members_directory_busy[r]}function um_members_show_preloader(e){um_members_directory_busy[um_members_get_hash(e)]=!0,e.find(".um-members-overlay").show()}function um_members_hide_preloader(e){um_members_directory_busy[um_members_get_hash(e)]=!1,e.find(".um-members-overlay").hide()}function um_set_range_label(e,r){var t=e.siblings(".um-slider-range").data("placeholder");t=r?t.replace("{min_range}",r.values[0]).replace("{max_range}",r.values[1]).replace("{field_label}",e.siblings(".um-slider-range").data("label")):t.replace("{min_range}",e.slider("values",0)).replace("{max_range}",e.slider("values",1)).replace("{field_label}",e.siblings(".um-slider-range").data("label")),e.siblings(".um-slider-range").html(t),e.siblings(".um_range_min").val(e.slider("values",0)),e.siblings(".um_range_max").val(e.slider("values",1))}function um_get_search(e){return e.find(".um-search-line").length?e.find(".um-search-line").val():""}function um_get_sort(e){return e.data("sorting")}function um_get_current_page(e){var r=e.data("page");return r&&void 0!==r||(r=1),r}function um_time_convert(e,r){var t=Math.floor(e/60),a=e%60;return 60<=a&&(a=0,24<=(t+=1)&&(t=0)),a<10&&(a="0"+a),t+":"+a}function um_ajax_get_members(s,t){var a=um_members_get_hash(s),e=um_get_current_page(s),r=um_get_search(s),i=um_get_sort(s),m=-(new Date).getTimezoneOffset()/60,_={directory_id:a,page:e,search:r,sorting:i,gmt_offset:m,post_refferer:s.data("base-post"),nonce:um_scripts.nonce};s.find(".um-search-filter").length&&s.find(".um-search-filter").each(function(){var e=jQuery(this);if(e.find(".um-slider").length){var r=e.find(".um-slider").data("field_name"),t=um_get_data_for_directory(s,"filter_"+r+"_from"),a=um_get_data_for_directory(s,"filter_"+r+"_to");void 0===t&&void 0===a||(_[r]=[t,a])}else if(e.find(".um-datepicker-filter").length){r=e.find(".um-datepicker-filter").data("filter_name"),t=um_get_data_for_directory(s,"filter_"+r+"_from"),a=um_get_data_for_directory(s,"filter_"+r+"_to");void 0===t&&void 0===a||(_[r]=[t,a])}else if(e.find(".um-timepicker-filter").length){r=e.find(".um-timepicker-filter").data("filter_name"),t=um_get_data_for_directory(s,"filter_"+r+"_from"),a=um_get_data_for_directory(s,"filter_"+r+"_to");if(void 0!==t)(i=1*(t=t.split(":"))[0])<10&&(i="0"+i),(d=1*t[1])<10&&(d="0"+d),t=i+":"+d+":00";if(void 0!==a){var i,m=a.split(":"),d=1*m[1];(i=1*m[0])<10&&(i="0"+i),d<10&&(d="0"+d),a=i+":"+d+":59"}void 0===t&&void 0===a||(_[r]=[t,a])}else if(e.find("select").length){r=e.find("select").attr("name");void 0!==(u=um_get_data_for_directory(s,"filter_"+r))&&(_[r]=u.split("||"))}else{var u;r=e.find('input[type="text"]').attr("name");void 0!==(u=um_get_data_for_directory(s,"filter_"+r))&&(_[r]=u)}}),_=wp.hooks.applyFilters("um_member_directory_filter_request",_),wp.ajax.send("um_get_members",{data:_,success:function(e){um_member_directory_last_data[a]=e,um_build_template(s,e);var r=wp.template("um-members-pagination");s.find(".um-members-pagination-box").html(r(e)),s.data("total_pages",e.pagination.total_pages),e.pagination.total_pages?(s.find(".um-member-directory-sorting-options").prop("disabled",!1),s.find(".um-member-directory-view-type").removeClass("um-disabled")):(s.find(".um-member-directory-sorting-options").prop("disabled",!0),s.find(".um-member-directory-view-type").addClass("um-disabled")),jQuery(document).trigger("um_members_rendered",t),um_init_new_dropdown(),um_members_hide_preloader(s)},error:function(e){console.log(e),um_members_hide_preloader(s)}})}function um_build_template(e,r){var t=e.data("view_type"),a=wp.template("um-member-"+t+"-"+um_members_get_hash(e));e.find(".um-members-grid, .um-members-list").remove(),e.find(".um-members-wrapper").prepend(a(r.users));var i=wp.template("um-members-header");e.find(".um-members-intro").remove(),void 0!==r.is_search&&r.is_search&&e.find(".um-members-wrapper").prepend(i(r)),e.addClass("um-loaded"),e.find(".um-members.um-members-grid").length&&UM_Member_Grid(e.find(".um-members.um-members-grid")),jQuery(document).trigger("um_build_template",[e,r]),jQuery(window).trigger("resize"),init_tipsy()}function UM_Member_Grid(e){e.find(".um-member").length&&e.imagesLoaded(function(){e.masonry({itemSelector:".um-member",columnWidth:".um-member",gutter:".um-gutter-sizer"}).on("layoutComplete",function(e,r){jQuery(document).trigger("um_grid_initialized",[e,r])})})}function um_get_filters_data(s){var _=[];return s.find(".um-search-filter").each(function(){var t,a,d,i=jQuery(this);if(i.find("input.um-datepicker-filter").length)d="datepicker",i.find("input.um-datepicker-filter").each(function(){if("to"!==jQuery(this).data("range")){var e=jQuery(this).data("filter_name"),r=um_get_data_for_directory(s,"filter_"+e+"_from"),t=um_get_data_for_directory(s,"filter_"+e+"_to");if(void 0!==r||void 0!==t){var a,i=jQuery(this).val(),m=s.find('input.um-datepicker-filter[data-range="to"][data-filter_name="'+e+'"]').val();i===m?a=m:""!==i&&""!==m?a=i+" - "+m:""===i?a="before "+m:""===m&&(a="since "+i),_.push({name:e,label:jQuery(this).data("filter-label"),value_label:a,value:[r,t],type:d})}}});else if(i.find("input.um-timepicker-filter").length)d="timepicker",i.find("input.um-timepicker-filter").each(function(){if("to"!==jQuery(this).data("range")){var e=jQuery(this).data("filter_name"),r=um_get_data_for_directory(s,"filter_"+e+"_from"),t=um_get_data_for_directory(s,"filter_"+e+"_to");if(void 0!==r||void 0!==t){var a,i=jQuery(this).val(),m=s.find('input.um-timepicker-filter[data-range="to"][data-filter_name="'+e+'"]').val();i===m?a=m:""!==i&&""!==m?a=i+" - "+m:""===i?a="before "+m:""===m&&(a="since "+i),_.push({name:e,label:jQuery(this).data("filter-label"),value_label:a,value:[r,t],type:d})}}});else if(i.find("select").length){d="select",t=i.find("select").attr("name"),a=i.find("select").data("placeholder"),m=void 0===(m=um_get_data_for_directory(s,"filter_"+t))?[]:m.split("||"),jQuery.each(m,function(e){var r=i.find('select option[value="'+m[e]+'"]').data("value_label");_.push({name:t,label:a,value_label:r,value:m[e],type:d})})}else if(i.find('input[type="text"]').length){var m;d="text",t=i.find('input[type="text"]').attr("name"),a=i.find('input[type="text"]').attr("placeholder"),void 0===(m=um_get_data_for_directory(s,"filter_"+t))&&(m=""),""!=m&&_.push({name:t,label:a,value_label:m,value:m,type:d})}else if(i.find("div.ui-slider").length){d="slider",t=i.find("div.ui-slider").data("field_name");var e=um_get_data_for_directory(s,"filter_"+t+"_from"),r=um_get_data_for_directory(s,"filter_"+t+"_to");if(void 0===e&&void 0===r)return;a=i.find("div.um-slider-range").data("label");var u=i.find("div.um-slider-range").data("placeholder").replace("{min_range}",e).replace("{max_range}",r).replace("{field_label}",i.find("div.um-slider-range").data("label"));_.push({name:t,label:a,value_label:u,value:[e,r],type:d})}}),_}function um_change_tag(e){var r=um_get_filters_data(e);e.find(".um-members-filter-tag").remove();var t=e.find(".um-filtered-line");if(t.length){var a=wp.template("um-members-filtered-line");t.prepend(a({filters:r})),0===e.find(".um-members-filter-remove").length?(e.find(".um-clear-filters").hide(),e.find(".um-clear-filters").parents(".um-member-directory-header-row").addClass("um-header-row-invisible")):(e.find(".um-clear-filters").show(),e.find(".um-clear-filters").parents(".um-member-directory-header-row").removeClass("um-header-row-invisible"))}}function um_run_search(e){if(!um_is_directory_busy(e)){um_members_show_preloader(e);var r=um_get_data_for_directory(e,"search");if((a=e.find(".um-search-line").val())===r||""===a&&void 0===r)um_members_hide_preloader(e);else{e.data("general_search",a),um_set_url_from_data(e,"search",a),e.data("page",1),um_set_url_from_data(e,"page","");var t=!1;if(!(t=wp.hooks.applyFilters("um_member_directory_ignore_after_search",t)))if(1===e.data("must-search")){var a=um_get_search(e);if(0===e.find(".um-members-filter-remove").length&&!a)return e.data("searched",0),e.find(".um-members-grid, .um-members-list").remove(),e.find(".um-member-directory-sorting-options").prop("disabled",!0),e.find(".um-member-directory-view-type").addClass("um-disabled"),void um_members_hide_preloader(e)}e.data("searched",1),e.find(".um-member-directory-sorting-options").prop("disabled",!1),e.find(".um-member-directory-view-type").removeClass("um-disabled"),um_ajax_get_members(e)}}}jQuery(document.body).ready(function(){jQuery(".um-directory .um-search-filter select").each(function(){1===jQuery(this).find("option:not(:disabled)").length&&jQuery(this).prop("disabled",!0),jQuery(this).select2("destroy").select2()}),jQuery(document.body).on("mouseover",".um-directory .um-member-directory-view-type",function(){if(!jQuery(this).hasClass("um-disabled")){var e=jQuery(this).find(".um-member-directory-view-type-a:visible");e.hide(),e.next().length?e.next().show().tipsy("show"):jQuery(this).find(".um-member-directory-view-type-a:first").show().tipsy("show")}}).on("mouseout",".um-directory .um-member-directory-view-type",function(){jQuery(this).hasClass("um-disabled")||(jQuery(this).find(".um-member-directory-view-type-a").hide().tipsy("hide"),jQuery(this).find('.um-member-directory-view-type-a[data-type="'+jQuery(this).parents(".um-directory").data("view_type")+'"]').show())}),jQuery(document.body).on("click",".um-directory .um-member-directory-view-type-a",function(){var e=jQuery(this).parents(".um-directory");if(um_is_directory_busy(e))return!1;var r=jQuery(this),t=r.parents(".um-member-directory-view-type");if(!t.hasClass("um-disabled")){um_members_show_preloader(e);var a=t.find(".um-member-directory-view-type-a:visible");a.hide(),a.next().length?a.next().show().tipsy("show"):t.find(".um-member-directory-view-type-a:first").show().tipsy("show");var i=um_member_directory_last_data[um_members_get_hash(e)];if(null!==i){var m=r.data("type");um_set_url_from_data(e,"view_type",m),e.data("view_type",m),um_build_template(e,i)}um_members_hide_preloader(e)}}),jQuery(document.body).on("click",".um-directory .um-do-search",function(){um_run_search(jQuery(this).parents(".um-directory"))}),jQuery(document.body).on("keypress",".um-directory .um-search-line",function(e){13===e.which&&um_run_search(jQuery(this).parents(".um-directory"))}),jQuery(document.body).on("click",".um-directory .um-member-directory-sorting-a .um-new-dropdown li a",function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)&&1!==jQuery(this).data("selected")){um_members_show_preloader(e);var r=jQuery(this).data("value");e.data("sorting",r),um_set_url_from_data(e,"sort",r),um_ajax_get_members(e),jQuery(this).parents(".um-new-dropdown").find("a").data("selected",0).prop("data-selected",0).attr("data-selected",0),jQuery(this).data("selected",1).prop("data-selected",1).attr("data-selected",1),jQuery(this).parents(".um-member-directory-sorting-a").find("> a").html(jQuery(this).html())}}),jQuery(document.body).on("click",".um-directory .pagi:not(.current)",function(){if(!jQuery(this).hasClass("disabled")){var e,r=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(r))um_members_show_preloader(r),1===(e="first"===jQuery(this).data("page")?1:"prev"===jQuery(this).data("page")?1*r.data("page")-1:"next"===jQuery(this).data("page")?1*r.data("page")+1:"last"===jQuery(this).data("page")?parseInt(r.data("total_pages")):parseInt(jQuery(this).data("page")))?(r.find('.pagi[data-page="first"], .pagi[data-page="prev"]').addClass("disabled"),r.find('.pagi[data-page="prev"], .pagi[data-page="last"]').removeClass("disabled")):(e===parseInt(r.data("total_pages"))?r.find('.pagi[data-page="prev"], .pagi[data-page="last"]').addClass("disabled"):r.find('.pagi[data-page="prev"], .pagi[data-page="last"]').removeClass("disabled"),r.find('.pagi[data-page="first"], .pagi[data-page="prev"]').removeClass("disabled")),r.find(".pagi").removeClass("current"),r.find('.pagi[data-page="'+e+'"]').addClass("current"),r.data("page",e),um_set_url_from_data(r,"page",1===e?"":e),um_ajax_get_members(r)}}),jQuery(document.body).on("change",".um-directory .um-members-pagi-dropdown",function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)){um_members_show_preloader(e);var r=jQuery(this).val();e.find(".pagi").removeClass("current"),e.find('.pagi[data-page="'+r+'"]').addClass("current"),e.data("page",r),um_set_url_from_data(e,"page",1===r?"":r),um_ajax_get_members(e)}}),jQuery(document.body).on("click",".um-directory .um-members.um-members-list .um-member-more a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member");return r.find(".um-member-more").hide(),r.find(".um-member-meta-main").slideDown(),r.find(".um-member-less").fadeIn(),!1}),jQuery(document.body).on("click",".um-directory .um-members.um-members-list .um-member-less a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member");return r.find(".um-member-less").hide(),r.find(".um-member-meta-main").slideUp(),r.find(".um-member-more").fadeIn(),!1}),jQuery(document.body).on("click",".um-directory .um-members.um-members-grid .um-member-more a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member"),t=jQuery(this).parents(".um-members");return r.find(".um-member-more").hide(),r.find(".um-member-meta").slideDown(function(){UM_Member_Grid(t)}),r.find(".um-member-less").fadeIn(),setTimeout(function(){UM_Member_Grid(t)},100),!1}),jQuery(document.body).on("click",".um-directory .um-members.um-members-grid .um-member-less a",function(e){e.preventDefault();var r=jQuery(this).parents(".um-member"),t=jQuery(this).parents(".um-members");return r.find(".um-member-less").hide(),r.find(".um-member-meta").slideUp(function(){r.find(".um-member-more").fadeIn(),UM_Member_Grid(t)}),!1}),jQuery(".um-member-directory-filters-a").click(function(){var e=jQuery(this),r=e.parents(".um-directory").find(".um-search");r.is(":visible")?r.slideUp(250,function(){e.toggleClass("um-member-directory-filters-visible"),r.parents(".um-member-directory-header-row").toggleClass("um-header-row-invisible")}):r.slideDown({duration:250,start:function(){jQuery(this).css({display:"grid"}),e.toggleClass("um-member-directory-filters-visible"),r.parents(".um-member-directory-header-row").toggleClass("um-header-row-invisible")}})}),jQuery(document.body).on("change",".um-directory .um-search-filter select",function(){if(""!==jQuery(this).val()){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)){um_members_show_preloader(e);var r=jQuery(this).prop("name"),t=um_get_data_for_directory(e,"filter_"+r);t=void 0===t?[]:t.split("||"),-1===jQuery.inArray(jQuery(this).val(),t)&&(t.push(jQuery(this).val()),um_set_url_from_data(e,"filter_"+r,t=t.join("||")),e.data("page",1),um_set_url_from_data(e,"page","")),jQuery(this).find('option[value="'+jQuery(this).val()+'"]').prop("disabled",!0).hide(),1===jQuery(this).find("option:not(:disabled)").length&&jQuery(this).prop("disabled",!0),jQuery(this).select2("destroy").select2(),jQuery(this).val("").trigger("change"),um_ajax_get_members(e),um_change_tag(e),e.data("searched",1),e.find(".um-member-directory-sorting-options").prop("disabled",!1),e.find(".um-member-directory-view-type").removeClass("um-disabled")}}}),jQuery(document.body).on("blur",'.um-directory .um-search-filter.um-text-filter-type input[type="text"]',function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)){var r=jQuery(this).val(),t=jQuery(this).prop("name"),a=um_get_data_for_directory(e,"filter_"+t);void 0===a&&(a=""),r!==a&&(um_members_show_preloader(e),um_set_url_from_data(e,"filter_"+t,r),e.data("page",1),um_set_url_from_data(e,"page",""),um_ajax_get_members(e),um_change_tag(e),e.data("searched",1),e.find(".um-member-directory-sorting-options").prop("disabled",!1),e.find(".um-member-directory-view-type").removeClass("um-disabled"))}}),jQuery(document.body).on("keypress",'.um-directory .um-search-filter.um-text-filter-type input[type="text"]',function(e){if(13===e.which){var r=jQuery(this).parents(".um-directory");if(um_is_directory_busy(r))return;var t=jQuery(this).val(),a=jQuery(this).prop("name"),i=um_get_data_for_directory(r,"filter_"+a);if(void 0===i&&(i=""),t===i)return;um_members_show_preloader(r),um_set_url_from_data(r,"filter_"+a,t),r.data("page",1),um_set_url_from_data(r,"page",""),um_ajax_get_members(r),um_change_tag(r),r.data("searched",1),r.find(".um-member-directory-sorting-options").prop("disabled",!1),r.find(".um-member-directory-view-type").removeClass("um-disabled")}}),jQuery(document.body).on("click",".um-directory .um-members-filter-remove",function(){var e=jQuery(this).parents(".um-directory");if(!um_is_directory_busy(e)&&e){um_members_show_preloader(e);var r=jQuery(this).data("value"),t=jQuery(this).data("name"),a=jQuery(this).data("type");if("text"===a)um_set_url_from_data(e,"filter_"+t,""),jQuery('.um-search-filter input[name="'+t+'"]').val("");else if("select"===a){var i=um_get_data_for_directory(e,"filter_"+t);i=void 0===i?[]:i.split("||"),-1!==jQuery.inArray(r.toString(),i)&&(i=jQuery.grep(i,function(e){return e!==r.toString()})),i.length||(i=""),um_set_url_from_data(e,"filter_"+t,i);var m=jQuery('.um-search-filter select[name="'+t+'"]');m.find('option[value="'+r+'"]').prop("disabled",!1).show(),1d.data("total_pages")&&(r=d.data("total_pages")),d.data("page",r).attr("data-page",r),d.find(".um-member-directory-sorting").length){var t=um_get_data_for_directory(d,"sort");void 0===t&&(t=d.find('.um-new-dropdown[data-element=".um-member-directory-sorting-a"]').find('a[data-default="1"]').data("value")),d.data("sorting",t);var a=d.find('.um-new-dropdown[data-element=".um-member-directory-sorting-a"]');a.find("a").data("selected",0).prop("data-selected",0).attr("data-selected",0),a.find('a[data-value="'+t+'"]').data("selected",1).prop("data-selected",1).attr("data-selected",1),d.find(".um-member-directory-sorting-a").find("> a").html(a.find('a[data-value="'+t+'"]').html())}if(d.find(".um-member-directory-view-type").length){var i=um_get_data_for_directory(d,"view_type");void 0===i&&(i=d.find('.um-member-directory-view-type-a[data-default="1"]').data("type")),d.data("view_type",i),d.find(".um-member-directory-view-type .um-member-directory-view-type-a").hide(),d.find('.um-member-directory-view-type .um-member-directory-view-type-a[data-type="'+i+'"]').show()}d.find(".um-datepicker-filter").each(function(){var e=jQuery(this),r=e.pickadate("picker"),t=e.data("filter_name"),a=e.data("range"),i=um_get_data_for_directory(d,"filter_"+t+"_"+a);void 0!==i?r.set("select",1e3*i):r.clear()}),d.find(".um-slider").each(function(){var e=jQuery(this),r=e.data("field_name"),t=um_get_data_for_directory(d,"filter_"+r+"_from"),a=um_get_data_for_directory(d,"filter_"+r+"_to");void 0===t&&(t=e.data("min")),t=parseInt(t),void 0===a&&(a=e.data("max")),a=parseInt(a),e.slider("values",[t,a]),um_set_range_label(e)}),d.find(".um-timepicker-filter").each(function(){var e=jQuery(this),r=e.pickatime("picker"),t=e.data("filter_name"),a=e.data("range"),i=um_get_data_for_directory(d,"filter_"+t+"_"+a);if(void 0!==i){var m=i.split(":");r.set("select",60*m[0])}else r.clear()});var m=!1;if(!(m=wp.hooks.applyFilters("um_member_directory_ignore_after_search",m))&&1===d.data("must-search")){var u=um_get_search(d);if(!um_get_filters_data(d).length&&!u)return d.data("searched",0),void um_members_hide_preloader(d);d.data("searched",1)}um_ajax_get_members(d),um_change_tag(d)})})}); \ No newline at end of file diff --git a/includes/admin/core/class-admin-settings.php b/includes/admin/core/class-admin-settings.php index e1c490b4..482e54ac 100644 --- a/includes/admin/core/class-admin-settings.php +++ b/includes/admin/core/class-admin-settings.php @@ -1143,6 +1143,12 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) { '2.0' => __( '2.0 version', 'ultimate-member' ), ), ), + array( + 'id' => 'member_directory_own_table', + 'type' => 'checkbox', + 'label' => __( 'Enable custom table for usermeta', 'ultimate-member' ), + 'tooltip' => __( 'Check this box if you would like to enable the using custom table with user metadata. It can be solution for the complex search.', 'ultimate-member' ), + ), array( 'id' => 'uninstall_on_delete', 'type' => 'checkbox', @@ -1703,6 +1709,184 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) { } } } + } elseif ( ! empty( $_POST['um_options']['member_directory_own_table'] ) ) { + //first install metatable + global $wpdb; + + $metakeys = array(); + foreach ( UM()->builtin()->all_user_fields as $all_user_field ) { + if ( $all_user_field['type'] == 'user_location' ) { + $metakeys[] = $all_user_field['metakey'] . '_lat'; + $metakeys[] = $all_user_field['metakey'] . '_lng'; + $metakeys[] = $all_user_field['metakey'] . '_url'; + } else { + $metakeys[] = $all_user_field['metakey']; + } + } + + if ( is_multisite() ) { + + $sites = get_sites( array( 'fields' => 'ids' ) ); + foreach ( $sites as $blog_id ) { + $metakeys[] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; + } + + } else { + $blog_id = get_current_blog_id(); + $metakeys[] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; + } + + //member directory data + $metakeys[] = 'um_member_directory_data'; + + $skip_fields = UM()->builtin()->get_fields_without_metakey(); + $skip_fields = array_merge( $skip_fields, UM()->member_directory()->core_search_fields ); + + $real_usermeta = $wpdb->get_col( "SELECT DISTINCT meta_key FROM {$wpdb->usermeta}" ); + + $wp_usermeta_option = array(); + foreach ( $metakeys as $metakey ) { + if ( in_array( $metakey, $skip_fields ) ) { + continue; + } + + if ( ! in_array( $metakey, $real_usermeta ) && $metakey != 'um_member_directory_data' ) { + continue; + } + + $wp_usermeta_option[] = $metakey; + } + + update_option( 'um_usermeta_fields', $wp_usermeta_option ); + + $charset_collate = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE {$wpdb->prefix}um_metadata ( +umeta_id bigint(20) unsigned NOT NULL auto_increment, +user_id bigint(20) unsigned NOT NULL default '0', +um_key varchar(255) default NULL, +um_value longtext default NULL, +PRIMARY KEY (umeta_id), +KEY user_id_indx (user_id), +KEY meta_key_indx (um_key), +KEY meta_value_indx (um_value(191)) +) $charset_collate;"; + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + dbDelta( $sql ); + + $md_metadata = $wpdb->get_results( + "SELECT u.ID as user_id, um.meta_value AS account_status, um2.meta_value AS hide_in_members + FROM {$wpdb->users} u + LEFT JOIN {$wpdb->usermeta} um ON ( um.user_id = u.ID AND um.meta_key = 'account_status' ) + LEFT JOIN {$wpdb->usermeta} um2 ON ( um2.user_id = u.ID AND um2.meta_key = 'hide_in_members' )", + ARRAY_A ); + + $md_metadata2 = $wpdb->get_results( + "SELECT u.ID as user_id, um.meta_value AS synced_gravatar_hashed_id, um2.meta_value AS synced_profile_photo + FROM {$wpdb->users} u + LEFT JOIN {$wpdb->usermeta} um ON ( um.user_id = u.ID AND um.meta_key = 'synced_gravatar_hashed_id' ) + LEFT JOIN {$wpdb->usermeta} um2 ON ( um2.user_id = u.ID AND um2.meta_key = 'synced_profile_photo' )", + ARRAY_A ); + + $md_metadata3 = $wpdb->get_results( + "SELECT u.ID as user_id, um.meta_value AS profile_photo, um2.meta_value AS cover_photo + FROM {$wpdb->users} u + LEFT JOIN {$wpdb->usermeta} um ON ( um.user_id = u.ID AND um.meta_key = 'profile_photo' ) + LEFT JOIN {$wpdb->usermeta} um2 ON ( um2.user_id = u.ID AND um2.meta_key = 'cover_photo' )", + ARRAY_A ); + + $md_metadata4 = $wpdb->get_results( + "SELECT u.ID as user_id, um.meta_value AS verified + FROM {$wpdb->users} u + LEFT JOIN {$wpdb->usermeta} um ON ( um.user_id = u.ID AND um.meta_key = '_um_verified' )", + ARRAY_A ); + + + $users_map = array(); + foreach ( $md_metadata as $md_metadatarow ) { + $hide_in_members = false; + if ( ! empty( $md_metadatarow['hide_in_members'] ) ) { + if ( $md_metadatarow['hide_in_members'] == 'Yes' || $md_metadatarow['hide_in_members'] == __( 'Yes', 'ultimate-member' ) || + $md_metadatarow['hide_in_members'] == serialize( array( 'Yes' ) ) || $md_metadatarow['hide_in_members'] == serialize( array( __( 'Yes', 'ultimate-member' ) ) ) ) { + $hide_in_members = true; + } + } + + $users_map[ $md_metadatarow['user_id'] ] = array( + 'account_status' => $md_metadatarow['account_status'], + 'hide_in_members' => $hide_in_members, + ); + } + + foreach ( $md_metadata3 as $md_metadatarow ) { + if ( ! isset( $users_map[ $md_metadatarow['user_id'] ] ) ) { + $users_map[ $md_metadatarow['user_id'] ] = array(); + } + + $users_map[ $md_metadatarow['user_id'] ] = array_merge( $users_map[ $md_metadatarow['user_id'] ], array( + 'profile_photo' => ! empty( $md_metadatarow['profile_photo'] ), + 'cover_photo' => ! empty( $md_metadatarow['cover_photo'] ), + ) ); + } + + foreach ( $md_metadata2 as $md_metadatarow ) { + if ( ! isset( $users_map[ $md_metadatarow['user_id'] ] ) ) { + $users_map[ $md_metadatarow['user_id'] ] = array(); + } + + if ( ! empty( $users_map[ $md_metadatarow['user_id'] ]['profile_photo'] ) ) { + continue; + } else { + $users_map[ $md_metadatarow['user_id'] ]['profile_photo'] = ( ! empty( $md_metadatarow['synced_gravatar_hashed_id'] ) || ! empty( $md_metadatarow['synced_profile_photo'] ) ); + } + } + + foreach ( $md_metadata4 as $md_metadatarow ) { + if ( ! isset( $users_map[ $md_metadatarow['user_id'] ] ) ) { + $users_map[ $md_metadatarow['user_id'] ] = array(); + } + $users_map[ $md_metadatarow['user_id'] ] = array_merge( $users_map[ $md_metadatarow['user_id'] ], array( + 'verified' => $md_metadatarow['verified'] == 'verified' ? true : false, + ) ); + } + + + if ( ! empty( $users_map ) ) { + + remove_action( 'updated_user_meta', array( UM()->member_directory(), 'on_update_usermeta' ), 10 ); + remove_action( 'added_user_meta', array( UM()->member_directory(), 'on_update_usermeta' ), 10 ); + + foreach ( $users_map as $user_id => $metavalue ) { + update_user_meta( $user_id, 'um_member_directory_data', $metavalue ); + } + + add_action( 'updated_user_meta', array( UM()->member_directory(), 'on_update_usermeta' ), 10, 4 ); + add_action( 'added_user_meta', array( UM()->member_directory(), 'on_update_usermeta' ), 10, 4 ); + } + + + $metadata = $wpdb->get_results( + "SELECT * + FROM {$wpdb->usermeta} + WHERE meta_key IN ('" . implode( "','", $wp_usermeta_option ) . "')", + ARRAY_A ); + + foreach ( $metadata as $metarow ) { + $wpdb->insert( + "{$wpdb->prefix}um_metadata", + array( + 'user_id' => $metarow['user_id'], + 'um_key' => $metarow['meta_key'], + 'um_value' => $metarow['meta_value'], + ), + array( + '%d', + '%s', + '%s', + ) + ); + } } } } diff --git a/includes/class-config.php b/includes/class-config.php index f3f831fc..2aa63d7f 100644 --- a/includes/class-config.php +++ b/includes/class-config.php @@ -569,6 +569,7 @@ if ( ! class_exists( 'um\Config' ) ) { 'custom_roles_increment' => 1, 'um_profile_object_cache_stop' => 0, 'rest_api_version' => '2.0', + 'member_directory_own_table' => 0, 'profile_show_html_bio' => 0, ); diff --git a/includes/class-init.php b/includes/class-init.php index e50c75e7..784a8ee6 100644 --- a/includes/class-init.php +++ b/includes/class-init.php @@ -582,7 +582,14 @@ if ( ! class_exists( 'UM' ) ) { */ function member_directory() { if ( empty( $this->classes['member_directory'] ) ) { - $this->classes['member_directory'] = new um\core\Member_Directory(); + + $search_in_table = $this->options()->get( 'member_directory_own_table' ); + + if ( ! empty( $search_in_table ) ) { + $this->classes['member_directory'] = new um\core\Member_Directory_Meta(); + } else { + $this->classes['member_directory'] = new um\core\Member_Directory(); + } } return $this->classes['member_directory']; } diff --git a/includes/core/class-member-directory-meta.php b/includes/core/class-member-directory-meta.php new file mode 100644 index 00000000..4ec8f659 --- /dev/null +++ b/includes/core/class-member-directory-meta.php @@ -0,0 +1,871 @@ +get_var( $wpdb->prepare( "SELECT umeta_id FROM {$wpdb->prefix}um_metadata WHERE user_id = %d AND um_key = %s LIMIT 1", $object_id, $meta_key ) ); + + if ( empty( $result ) ) { + $wpdb->insert( + "{$wpdb->prefix}um_metadata", + array( + 'user_id' => $object_id, + 'um_key' => $meta_key, + 'um_value' => $_meta_value, + ), + array( + '%d', + '%s', + '%s', + ) + ); + } else { + $wpdb->update( + "{$wpdb->prefix}um_metadata", + array( + 'um_value' => $_meta_value, + ), + array( + 'umeta_id' => $result, + 'um_key' => $meta_key, + ), + array( + '%s', + ), + array( + '%d', + ) + ); + } + +// $wpdb->update( +// "{$wpdb->prefix}um_metadata", +// array( +// $meta_key => $_meta_value, +// ), +// array( +// 'user_id' => $object_id, +// ), +// array( +// '%s' +// ), +// array( +// '%d' +// ) +// ); + } + + + /** + * Main Query function for getting members via AJAX + */ + function ajax_get_members() { + UM()->check_ajax_nonce(); + + global $wpdb; + + $blog_id = get_current_blog_id(); + + $directory_id = $this->get_directory_by_hash( $_POST['directory_id'] ); + $directory_data = UM()->query()->post_data( $directory_id ); + + //predefined result for user without capabilities to see other members + $this->predefined_no_caps( $directory_data ); + + do_action( 'um_member_directory_before_query' ); + + // Prepare for BIG SELECT query + $wpdb->query( 'SET SQL_BIG_SELECTS=1' ); + + + if ( ! empty( $directory_data['show_these_users'] ) ) { + $show_these_users = maybe_unserialize( $directory_data['show_these_users'] ); + + if ( is_array( $show_these_users ) && ! empty( $show_these_users ) ) { + $users_array = array(); + foreach ( $show_these_users as $username ) { + if ( false !== ( $exists_id = username_exists( $username ) ) ) { + $users_array[] = $exists_id; + } + } + + if ( ! empty( $users_array ) ) { + $this->sql_where .= " AND u.ID IN ( '" . implode( "','", $users_array ) . "' )"; + } + } + } + + + $profile_photo_where = ''; + if ( $directory_data['has_profile_photo'] == 1 ) { +// $gravatars_query = ''; +// if ( UM()->options()->get( 'use_gravatars' ) ) { +// $gravatars_query = " OR ( umm_general.synced_gravatar_hashed_id != '' AND umm_general.synced_gravatar_hashed_id IS NOT NULL )"; +// } + + $profile_photo_where = " AND umm_general.um_value LIKE '%s:13:\"profile_photo\";b:1;%'"; + } + + $cover_photo_where = ''; + if ( $directory_data['has_cover_photo'] == 1 ) { + $cover_photo_where = " AND umm_general.um_value LIKE '%s:11:\"cover_photo\";b:1;%'"; + } + + if ( ! UM()->roles()->um_user_can( 'can_edit_everyone' ) ) { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_general ON umm_general.user_id = u.ID"; + + $this->sql_where .= " AND ( umm_general.um_key = 'um_member_directory_data' AND + umm_general.um_value LIKE '%s:14:\"account_status\";s:8:\"approved\";%' AND umm_general.um_value LIKE '%s:15:\"hide_in_members\";b:0;%'{$profile_photo_where}{$cover_photo_where} )"; + } else { + if ( ! empty( $cover_photo_where ) || ! empty( $profile_photo_where ) ) { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_general ON umm_general.user_id = u.ID"; + + $this->sql_where .= " AND ( umm_general.um_key = 'um_member_directory_data'{$profile_photo_where}{$cover_photo_where} )"; + } + } + + $roles = array(); + if ( UM()->roles()->um_user_can( 'can_view_all' ) ) { + $view_roles = um_user( 'can_view_roles' ); + + if ( ! $view_roles ) { + $view_roles = array(); + } + + $roles = array_merge( $roles, maybe_unserialize( $view_roles ) ); + } + + if ( ! empty( $directory_data['roles'] ) ) { + if ( ! empty( $roles ) ) { + $roles = array_intersect( $roles, maybe_unserialize( $directory_data['roles'] ) ); + } else { + $roles = array_merge( $roles, maybe_unserialize( $directory_data['roles'] ) ); + } + } + + if ( ! empty( $roles ) ) { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )"; + + $roles_clauses = array(); + foreach ( $roles as $role ) { + $roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'"; + } + + $roles_search = implode( ' OR ', $roles_clauses ); + + $this->sql_where .= " AND ( {$roles_search} )"; + } else { + if ( is_multisite() ) { + // select users who have capabilities for current blog + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )"; + $this->sql_where .= " AND umm_roles.um_value IS NOT NULL "; + } + } + + + if ( ! empty( $_POST['search'] ) ) { + $searches = array(); + foreach ( $this->core_search_fields as $field ) { + $searches[] = $wpdb->prepare( "u.{$field} LIKE %s", '%' . trim( $_POST['search'] ) . '%' ); + } + + $core_search = implode( ' OR ', $searches ); + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_search ON umm_search.user_id = u.ID"; + $this->sql_where .= " AND ( umm_search.um_value = '" . trim( $_POST['search'] ) . "' OR umm_search.um_value LIKE '%" . trim( $_POST['search'] ) . "%' OR umm_search.um_value LIKE '%" . trim( serialize( strval( $_POST['search'] ) ) ) . "%' OR {$core_search})"; + + $this->is_search = true; + } + + + //filters + $filter_query = array(); + if ( ! empty( $directory_data['search_fields'] ) ) { + $search_filters = maybe_unserialize( $directory_data['search_fields'] ); + if ( ! empty( $search_filters ) && is_array( $search_filters ) ) { + $filter_query = array_intersect_key( $_POST, array_flip( $search_filters ) ); + } + } + + // added for user tags extension integration on individual tag page + $ignore_empty_filters = apply_filters( 'um_member_directory_ignore_empty_filters', false ); + + if ( ! empty( $filter_query ) || $ignore_empty_filters ) { + $this->is_search = true; + + $i = 1; + foreach ( $filter_query as $field => $value ) { + + $attrs = UM()->fields()->get_field( $field ); + // skip private invisible fields + if ( ! um_can_view_field( $attrs ) ) { + continue; + } + + switch ( $field ) { + default: + + $filter_type = $this->filter_types[ $field ]; + + /** + * UM hook + * + * @type filter + * @title um_query_args_{$field}__filter + * @description Change field's query for search at Members Directory + * @input_vars + * [{"var":"$field_query","type":"array","desc":"Field query"}] + * @change_log + * ["Since: 2.0"] + * @usage + * + * @example + * + */ + $field_query = apply_filters( "um_query_args_{$field}__filter", false, $field, $value, $filter_type ); + + if ( ! $field_query ) { + + switch ( $filter_type ) { + default: + + $field_query = apply_filters( "um_query_args_{$field}_{$filter_type}__filter", false, $field, $value, $filter_type ); + + break; + case 'text': + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + + $value = trim( stripslashes( $value ) ); + + $this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value = '{$value}' )"; + + $this->custom_filters_in_query[ $field ] = $value; + + break; + + case 'select': + if ( is_array( $value ) ) { + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + + $values_array = array(); + foreach ( $value as $single_val ) { + $single_val = stripslashes( $single_val ); + + $values_array[] = "umm" . $i . ".um_value LIKE '%\"" . trim( $single_val ) . "\"%'"; + $values_array[] = "umm" . $i . ".um_value LIKE '%" . serialize( strval( trim( $single_val ) ) ) . "%'"; + $values_array[] = "umm" . $i . ".um_value = '" . trim( $single_val ) . "'"; + + if ( is_numeric( $single_val ) ) { + $values_array[] = "umm" . $i . ".um_value LIKE '%" . serialize( intval( trim( $single_val ) ) ) . "%'"; + } + } + + $values = implode( ' OR ', $values_array ); + + $this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND ( {$values} ) )"; + } + + $this->custom_filters_in_query[ $field ] = $value; + + break; + case 'slider': + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + + $min = min( $value ); + $max = max( $value ); + + $this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value BETWEEN {$min} AND {$max} )"; + + $this->custom_filters_in_query[ $field ] = $value; + + break; + case 'datepicker': + + $offset = 0; + if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) { + $offset = (int) $_POST['gmt_offset']; + } + + $from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset + $to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59 + $from_date = date( 'Y/m/d', $from_date ); + $to_date = date( 'Y/m/d', $to_date ); + + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + + $this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )"; + + $this->custom_filters_in_query[ $field ] = array( $from_date, $to_date ); + + break; + case 'timepicker': + + if ( $value[0] == $value[1] ) { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + $this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value = '{$value[0]}' )"; + } else { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + $this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND CAST( umm" . $i . ".um_value AS TIME ) BETWEEN {$value[0]} AND {$value[1]} )"; + } + + $this->custom_filters_in_query[ $field ] = $value; + + break; + } + + } + + if ( ! empty( $field_query ) && $field_query !== true ) { + $this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $field_query ) ); + } + + break; + case 'role': + $value = array_map( 'strtolower', $value ); + + if ( ! empty( $roles ) || is_multisite() ) { + $roles_clauses = array(); + foreach ( $value as $role ) { + $roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'"; + } + + $roles_search = implode( ' OR ', $roles_clauses ); + + $this->sql_where .= " AND ( {$roles_search} )"; + } else { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )"; + + $roles = $value; + + $roles_clauses = array(); + foreach ( $value as $role ) { + $roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'"; + } + + $roles_search = implode( ' OR ', $roles_clauses ); + + $this->sql_where .= " AND ( {$roles_search} )"; + } + + $this->custom_filters_in_query[ $field ] = $value; + + break; + case 'birth_date': + + $from_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ), date( 'Y', time() - min( $value ) * YEAR_IN_SECONDS ) ) ); + $to_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ) + 1, date( 'Y', time() - ( max( $value ) + 1 ) * YEAR_IN_SECONDS ) ) ); + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + + $this->sql_where .= " AND ( umm" . $i . ".um_key = 'birth_date' AND umm" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )"; + + $this->custom_filters_in_query[ $field ] = array( $to_date, $from_date ); + + break; + case 'user_registered': + + $offset = 0; + if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) { + $offset = (int) $_POST['gmt_offset']; + } + + $from_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', min( $value ) ) . "+$offset hours" ) ); + $to_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', max( $value ) ) . "+$offset hours" ) ); + + $this->sql_where .= " AND ( u.user_registered BETWEEN {$from_date} AND {$to_date} )"; + + $this->custom_filters_in_query[ $field ] = $value; + + break; + case 'last_login': + + $offset = 0; + if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) { + $offset = (int) $_POST['gmt_offset']; + } + + $from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset + $to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59 + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID"; + + $this->sql_where .= " AND ( umm" . $i . ".um_key = '_um_last_login' AND umm" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )"; + + $this->custom_filters_in_query[ $field ] = $value; + + break; + } + + $i++; + } + } + + + //unable default filter in case if we select other filters in frontend filters + if ( empty( $this->custom_filters_in_query ) ) { + $default_filters = array(); + if ( ! empty( $directory_data['search_filters'] ) ) { + $default_filters = maybe_unserialize( $directory_data['search_filters'] ); + } + + $gmt_offset = get_post_meta( $directory_data['form_id'], '_um_search_filters_gmt', true ); + + if ( ! empty( $default_filters ) ) { + $i = 1; + foreach ( $default_filters as $field => $value ) { + //unable default filter in case if we select other value in frontend filters + // if ( in_array( $field, array_keys( $this->custom_filters_in_query ) ) ) { + // continue; + // } + + switch ( $field ) { + default: + + $filter_type = $this->filter_types[ $field ]; + + /** + * UM hook + * + * @type filter + * @title um_query_args_{$field}__filter + * @description Change field's query for search at Members Directory + * @input_vars + * [{"var":"$field_query","type":"array","desc":"Field query"}] + * @change_log + * ["Since: 2.0"] + * @usage + * + * @example + * + */ + $field_query = apply_filters( "um_query_args_{$field}__filter", false, $field, $value, $filter_type ); + + if ( ! $field_query ) { + + switch ( $filter_type ) { + default: + + $field_query = apply_filters( "um_query_args_{$field}_{$filter_type}__filter", false, $field, $value, $filter_type ); + + break; + case 'text': + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + + $value = trim( stripslashes( $value ) ); + + $this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value = '{$value}' )"; + + $this->custom_filters_in_query[ $field ] = $value; + + break; + case 'select': + if ( ! is_array( $value ) ) { + $value = array( $value ); + } + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + + $values_array = array(); + foreach ( $value as $single_val ) { + $single_val = stripslashes( $single_val ); + + $values_array[] = "ummd" . $i . ".um_value LIKE '%\"" . trim( $single_val ) . "\"%'"; + $values_array[] = "ummd" . $i . ".um_value LIKE '%" . serialize( strval( trim( $single_val ) ) ) . "%'"; + $values_array[] = "ummd" . $i . ".um_value = '" . trim( $single_val ) . "'"; + + if ( is_numeric( $single_val ) ) { + $values_array[] = "ummd" . $i . ".um_value LIKE '%" . serialize( intval( trim( $single_val ) ) ) . "%'"; + } + } + + $values = implode( ' OR ', $values_array ); + + $this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ( {$values} ) )"; + + break; + case 'slider': + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + + $min = min( $value ); + $max = max( $value ); + + $this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value BETWEEN {$min} AND {$max} )"; + + break; + case 'datepicker': + + $offset = 0; + if ( is_numeric( $gmt_offset ) ) { + $offset = $gmt_offset; + } + + $from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset + $to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59 + $from_date = date( 'Y/m/d', $from_date ); + $to_date = date( 'Y/m/d', $to_date ); + + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + + $this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )"; + + break; + case 'timepicker': + + if ( $value[0] == $value[1] ) { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + $this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value = '{$value[0]}' )"; + } else { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + $this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND CAST( ummd" . $i . ".um_value AS TIME ) BETWEEN {$value[0]} AND {$value[1]} )"; + } + + break; + } + + } + + break; + case 'role': +// $value = explode( '||', $value ); +// $value = array_map( 'strtolower', $value ); + + $value = array_map( 'strtolower', $value ); + + if ( ! empty( $roles ) || is_multisite() ) { + $roles_clauses = array(); + foreach ( $value as $role ) { + $roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'"; + } + + $roles_search = implode( ' OR ', $roles_clauses ); + + $this->sql_where .= " AND ( {$roles_search} )"; + } else { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )"; + + $roles = $value; + + $roles_clauses = array(); + foreach ( $value as $role ) { + $roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'"; + } + + $roles_search = implode( ' OR ', $roles_clauses ); + + $this->sql_where .= " AND ( {$roles_search} )"; + } + + break; + case 'birth_date': + $from_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ), date( 'Y', time() - min( $value ) * YEAR_IN_SECONDS ) ) ); + $to_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ) + 1, date( 'Y', time() - ( max( $value ) + 1 ) * YEAR_IN_SECONDS ) ) ); + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + + $this->sql_where .= " AND ( ummd" . $i . ".um_key = 'birth_date' AND ummd" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )"; + + + break; + case 'user_registered': + $offset = 0; + if ( is_numeric( $gmt_offset ) ) { + $offset = $gmt_offset; + } + + $from_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', min( $value ) ) . "+$offset hours" ) ); + $to_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', max( $value ) ) . "+$offset hours" ) ); + + $this->sql_where .= " AND ( u.user_registered BETWEEN {$from_date} AND {$to_date} )"; + + break; + case 'last_login': + $offset = 0; + if ( is_numeric( $gmt_offset ) ) { + $offset = $gmt_offset; + } + + $from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset + $to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59 + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID"; + + $this->sql_where .= " AND ( ummd" . $i . ".um_key = '_um_last_login' AND ummd" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )"; + break; + } + + $i++; + } + } + } + + + $order = 'ASC'; + $sortby = ! empty( $_POST['sorting'] ) ? $_POST['sorting'] : $directory_data['sortby']; + + // handle sorting options + // sort members by + if ( $sortby == 'other' && $directory_data['sortby_custom'] ) { + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort ON ( umm_sort.user_id = u.ID AND umm_sort.um_key = '{$directory_data['sortby_custom']}' )"; + + $this->sql_order = " ORDER BY CAST( umm_sort.um_value AS CHAR ) {$order} "; + + } elseif ( 'display_name' == $sortby ) { + + $display_name = UM()->options()->get( 'display_name' ); + if ( $display_name == 'username' ) { + + $this->sql_order = " ORDER BY u.user_login {$order} "; + + } else { + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort ON ( umm_sort.user_id = u.ID AND umm_sort.um_key = 'full_name' )"; + + $this->sql_order = " ORDER BY CAST( umm_sort.um_value AS CHAR ) {$order}, u.display_name {$order} "; + + } + + } elseif ( in_array( $sortby, array( 'last_name', 'first_name', 'nickname' ) ) ) { + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort ON ( umm_sort.user_id = u.ID AND umm_sort.um_key = '{$sortby}' )"; + + $this->sql_order = " ORDER BY CAST( umm_sort.um_value AS CHAR ) {$order} "; + + } elseif ( $sortby == 'last_login' ) { + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort ON ( umm_sort.user_id = u.ID AND umm_sort.um_key = '_um_last_login' )"; + + $this->sql_order = " ORDER BY CAST( umm_sort.um_value AS NUMERIC ) {$order} "; + + } elseif ( $sortby == 'last_first_name' ) { + + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort ON ( umm_sort.user_id = u.ID AND umm_sort.um_key = 'last_name' )"; + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort2 ON ( umm_sort2.user_id = u.ID AND umm_sort2.um_key = 'first_name' )"; + + $this->sql_order = " ORDER BY CAST( umm_sort.um_value AS CHAR ) ASC, CAST( umm_sort2.um_value AS CHAR ) ASC "; + + } elseif ( $sortby == 'random' ) { + + if ( um_is_session_started() === false ) { + @session_start(); + } + + // Reset seed on load of initial + if ( empty( $_REQUEST['directory_id'] ) && isset( $_SESSION['um_member_directory_seed'] ) ) { + unset( $_SESSION['um_member_directory_seed'] ); + } + + // Get seed from session variable if it exists + $seed = false; + if ( isset( $_SESSION['um_member_directory_seed'] ) ) { + $seed = $_SESSION['um_member_directory_seed']; + } + + // Set new seed if none exists + if ( ! $seed ) { + $seed = rand(); + $_SESSION['um_member_directory_seed'] = $seed; + } + + $this->sql_order = 'ORDER by RAND(' . $seed . ')'; + + } else { + + if ( strstr( $sortby, '_desc' ) ) { + $sortby = str_replace( '_desc', '', $sortby ); + $order = 'DESC'; + } + + if ( strstr( $sortby, '_asc' ) ) { + $sortby = str_replace( '_asc', '', $sortby ); + $order = 'ASC'; + } + + $metakeys = get_option( 'um_usermeta_fields', array() ); + if ( false !== array_search( $sortby, $metakeys ) ) { + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort ON ( umm_sort.user_id = u.ID AND umm_sort.um_key = '{$sortby}' )"; + $this->sql_order = " ORDER BY CAST( umm_sort.um_value AS CHAR ) {$order} "; + } else { + $this->sql_order = " ORDER BY u.{$sortby} {$order} "; + } + } + + $this->sql_order = apply_filters( 'um_modify_sortby_parameter', $this->sql_order, $sortby ); + + + $profiles_per_page = $directory_data['profiles_per_page']; + if ( UM()->mobile()->isMobile() && isset( $directory_data['profiles_per_page_mobile'] ) ) { + $profiles_per_page = $directory_data['profiles_per_page_mobile']; + } + + $query_number = ( ! empty( $directory_data['max_users'] ) && $directory_data['max_users'] <= $profiles_per_page ) ? $directory_data['max_users'] : $profiles_per_page; + $query_paged = ! empty( $_POST['page'] ) ? $_POST['page'] : 1; + + $number = $query_number; + if ( ! empty( $directory_data['max_users'] ) && $query_paged*$query_number > $directory_data['max_users'] ) { + $number = ( $query_paged*$query_number - ( $query_paged*$query_number - $directory_data['max_users'] ) ) % $query_number; + } + + // limit + if ( isset( $query_number ) && $query_number > 0 ) { + $this->sql_limit .= $wpdb->prepare( 'LIMIT %d, %d', $query_number * ( $query_paged - 1 ), $number ); + } + + $sql_join = implode( ' ', $this->joins ); + + do_action( 'um_pre_users_query', $this, $directory_data, $sortby ); + + global $wpdb; + $user_ids = $wpdb->get_col( + "SELECT SQL_CALC_FOUND_ROWS DISTINCT u.ID + FROM {$wpdb->users} AS u + {$sql_join} + WHERE 1=1 {$this->sql_where} + {$this->sql_order} + {$this->sql_limit}" + ); + + $total_users = (int) $wpdb->get_var( 'SELECT FOUND_ROWS()' ); + + $pagination_data = $this->calculate_pagination( $directory_data, $total_users ); + + $sizes = UM()->options()->get( 'cover_thumb_sizes' ); + + $this->cover_size = UM()->mobile()->isTablet() ? $sizes[1] : end( $sizes ); + + $avatar_size = UM()->options()->get( 'profile_photosize' ); + $this->avatar_size = str_replace( 'px', '', $avatar_size ); + + $users = array(); + foreach ( $user_ids as $user_id ) { + $users[] = $this->build_user_card_data( $user_id, $directory_data ); + } + + um_reset_user(); + // end of user card + + wp_send_json_success( array( 'pagination' => $pagination_data, 'users' => $users, 'is_search' => $this->is_search ) ); + } + + + /** + * Get data array for pagination + * + * + * @param array $directory_data + * @param int $total_users + * + * @return array + */ + function calculate_pagination( $directory_data, $total_users ) { + + $current_page = ! empty( $_POST['page'] ) ? $_POST['page'] : 1; + + $total_users = ( ! empty( $directory_data['max_users'] ) && $directory_data['max_users'] <= $total_users ) ? $directory_data['max_users'] : $total_users; + + // number of profiles for mobile + $profiles_per_page = $directory_data['profiles_per_page']; + if ( UM()->mobile()->isMobile() && isset( $directory_data['profiles_per_page_mobile'] ) ) { + $profiles_per_page = $directory_data['profiles_per_page_mobile']; + } + + $total_pages = 1; + if ( ! empty( $profiles_per_page ) ) { + $total_pages = ceil( $total_users / $profiles_per_page ); + } + + if ( ! empty( $total_pages ) ) { + $index1 = 0 - ( $current_page - 2 ) + 1; + $to = $current_page + 2; + if ( $index1 > 0 ) { + $to += $index1; + } + + $index2 = $total_pages - ( $current_page + 2 ); + $from = $current_page - 2; + if ( $index2 < 0 ) { + $from += $index2; + } + + $pages_to_show = range( + ( $from > 0 ) ? $from : 1, + ( $to <= $total_pages ) ? $to : $total_pages + ); + } + + + $pagination_data = array( + 'pages_to_show' => ( ! empty( $pages_to_show ) && count( $pages_to_show ) > 1 ) ? array_values( $pages_to_show ) : array(), + 'current_page' => $current_page, + 'total_pages' => $total_pages, + 'total_users' => $total_users, + ); + + $pagination_data['header'] = $this->convert_tags( $directory_data['header'], $pagination_data ); + $pagination_data['header_single'] = $this->convert_tags( $directory_data['header_single'], $pagination_data ); + + return $pagination_data; + } + } +} \ No newline at end of file diff --git a/includes/core/class-member-directory.php b/includes/core/class-member-directory.php index 16a5077f..7670c922 100644 --- a/includes/core/class-member-directory.php +++ b/includes/core/class-member-directory.php @@ -539,7 +539,6 @@ PRIMARY KEY (id) return ''; } - // old if ( isset( $attrs['metakey'] ) && strstr( $attrs['metakey'], 'role_' ) ) { $shortcode_roles = get_post_meta( $directory_data['form_id'], '_um_roles', true ); $um_roles = UM()->roles()->get_roles( false ); @@ -552,6 +551,12 @@ PRIMARY KEY (id) $attrs['options'][ $key ] = $value; } } + } else { + $attrs['options'] = array(); + + foreach ( $um_roles as $key => $value ) { + $attrs['options'][ $key ] = $value; + } } } @@ -1607,7 +1612,7 @@ PRIMARY KEY (id) $meta_query = array( array( 'key' => 'birth_date', - 'value' => array( $to_date, $from_date ), + 'value' => array( $from_date, $to_date ), 'compare' => 'BETWEEN', 'type' => 'DATE', 'inclusive' => true, @@ -1616,7 +1621,7 @@ PRIMARY KEY (id) $this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $meta_query ) ); - $this->custom_filters_in_query[ $field ] = array( $to_date, $from_date ); + $this->custom_filters_in_query[ $field ] = array( $from_date, $to_date ); break; case 'user_registered': @@ -2067,6 +2072,7 @@ PRIMARY KEY (id) * @return array */ function build_user_card_data( $user_id, $directory_data ) { + um_fetch_user( $user_id ); $dropdown_actions = $this->build_user_actions_list( $user_id ); @@ -2156,6 +2162,7 @@ PRIMARY KEY (id) } $data_array = apply_filters( 'um_ajax_get_members_data', $data_array, $user_id, $directory_data ); + um_reset_user_clean(); return $data_array; @@ -2191,17 +2198,7 @@ PRIMARY KEY (id) } - /** - * Main Query function for getting members via AJAX - */ - function ajax_get_members() { - UM()->check_ajax_nonce(); - - global $wpdb; - - $directory_id = $this->get_directory_by_hash( $_POST['directory_id'] ); - $directory_data = UM()->query()->post_data( $directory_id ); - + function predefined_no_caps( $directory_data ) { //predefined result for user without capabilities to see other members if ( is_user_logged_in() && ! UM()->roles()->um_user_can( 'can_view_all' ) ) { $pagination_data = array( @@ -2216,6 +2213,22 @@ PRIMARY KEY (id) wp_send_json_success( array( 'users' => array(), 'pagination' => $pagination_data ) ); } + } + + + /** + * Main Query function for getting members via AJAX + */ + function ajax_get_members() { + UM()->check_ajax_nonce(); + + global $wpdb; + + $directory_id = $this->get_directory_by_hash( $_POST['directory_id'] ); + $directory_data = UM()->query()->post_data( $directory_id ); + + //predefined result for user without capabilities to see other members + $this->predefined_no_caps( $directory_data ); do_action( 'um_member_directory_before_query' ); diff --git a/includes/core/class-roles-capabilities.php b/includes/core/class-roles-capabilities.php index 8aefd485..c42c125b 100644 --- a/includes/core/class-roles-capabilities.php +++ b/includes/core/class-roles-capabilities.php @@ -566,8 +566,8 @@ if ( ! class_exists( 'um\core\Roles_Capabilities' ) ) { } if ( $exclude ) { - foreach( $exclude as $role ) { - unset( $roles[$role] ); + foreach ( $exclude as $role ) { + unset ( $roles[ $role ] ); } } diff --git a/includes/core/class-setup.php b/includes/core/class-setup.php index de825faa..d788f7fe 100644 --- a/includes/core/class-setup.php +++ b/includes/core/class-setup.php @@ -27,6 +27,7 @@ if ( ! class_exists( 'um\core\Setup' ) ) { * Run setup */ function run_setup() { + $this->create_db(); $this->install_basics(); $this->install_default_forms(); $this->set_default_settings(); @@ -34,6 +35,30 @@ if ( ! class_exists( 'um\core\Setup' ) ) { } + /** + * Create custom DB tables + */ + function create_db() { + global $wpdb; + + $charset_collate = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE {$wpdb->prefix}um_metadata ( +umeta_id bigint(20) unsigned NOT NULL auto_increment, +user_id bigint(20) unsigned NOT NULL default '0', +um_key varchar(255) default NULL, +um_value longtext default NULL, +PRIMARY KEY (umeta_id), +KEY user_id_indx (user_id), +KEY meta_key_indx (um_key), +KEY meta_value_indx (um_value(191)) +) $charset_collate;"; + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + dbDelta( $sql ); + } + + /** * Basics */