").append(e.siblings(".um-hidden-multi-selects").clone()).html()+'
'+wp.i18n.__("Remove","ultimate-member")+"",e.append(i),e.find("li:last .um-hidden-multi-selects").attr("name",jQuery(this).data("name")).addClass("um-forms-field um-long-field").removeClass("um-hidden-multi-selects").attr("id",e.data("id_attr")+"-"+t))}),jQuery('.um-multi-selects-add-option[data-name="um_metadata[_um_search_exclude_fields][]"]').on("click",function(){jQuery('.um-multi-selects-list[data-field_id="_um_search_include_fields"] li.um-multi-selects-option-line').remove()}),jQuery('.um-multi-selects-add-option[data-name="um_metadata[_um_search_include_fields][]"]').on("click",function(){jQuery('.um-multi-selects-list[data-field_id="_um_search_exclude_fields"] li.um-multi-selects-option-line').remove()});var t,e=-(new Date).getTimezoneOffset()/60,i=(jQuery('input[name="um-gmt-offset"]').val(e),jQuery(".um-admin-metabox").find(".um-slider").each(function(){var e=jQuery(this),a=parseInt(e.data("min")),t=parseInt(e.data("max")),a=[a=void 0!==jQuery("#"+e.data("field_name")+"_min").val()?jQuery("#"+e.data("field_name")+"_min").val():a,t=void 0!==jQuery("#"+e.data("field_name")+"_max").val()?jQuery("#"+e.data("field_name")+"_max").val():t];e.slider({range:!0,min:parseInt(e.data("min")),max:parseInt(e.data("max")),values:a,create:function(e,a){},step:1,slide:function(e,a){s(jQuery(this),a)},stop:function(e,a){}}),s(e)}),jQuery(".um-admin-metabox").find(".um-datepicker-filter").each(function(){var e=jQuery(this),a=new Date(1e3*e.data("date_min")),t=new Date(1e3*e.data("date_max")),a=e.pickadate({selectYears:!0,min:a,max:t,formatSubmit:"yyyy/mm/dd",hiddenName:!0,onOpen:function(){e.blur(),e.siblings(".picker").find(".picker__button--close").addClass("button")},onClose:function(){e.blur()},onSet:function(e){}}).pickadate("picker");e.data("value")&&a.set("select",1e3*e.data("value"))}),jQuery(".um-admin-metabox").find(".um-timepicker-filter").each(function(){var e=jQuery(this),a=e.data("min"),t=e.data("max"),a=a.split(":"),t=t.split(":");e.pickatime({format:e.data("format"),interval:parseInt(e.data("intervals")),min:[a[0],a[1]],max:[t[0],t[1]],formatSubmit:"HH:i",hiddenName:!0,onOpen:function(){e.blur()},onClose:function(){e.blur()},onSet:function(e){}})}),!1);function s(e,a){var t,i="",s=e.siblings(".um-slider-range").data("placeholder-s"),l=e.siblings(".um-slider-range").data("placeholder-p"),a=a?(i=(a.values[0]===a.values[1]?s.replace("{value}",a.values[0]):l.replace("{min_range}",a.values[0]).replace("{max_range}",a.values[1])).replace("{field_label}",e.siblings(".um-slider-range").data("label")),t=a.values[0],a.values[1]):(i=(e.slider("values",0)===e.slider("values",1)?s.replace("{value}",e.slider("values",0)):l.replace("{min_range}",e.slider("values",0)).replace("{max_range}",e.slider("values",1))).replace("{field_label}",e.siblings(".um-slider-range").data("label")),t=e.slider("values",0),e.slider("values",1));e.siblings(".um-slider-range").html(i),e.siblings(".um_range_min").val(t),e.siblings(".um_range_max").val(a)}function a(){jQuery(".um-forms-line").removeClass("um-forms-line-conditioned").each(function(){void 0===jQuery(this).data("conditional")||jQuery(this).hasClass("um-forms-line-conditioned")||(!function i(e){e.addClass("um-forms-line-conditioned");var a=e.data("conditional");var t=a[1];var s=a[2];var l=e.data("prefix");var n=!0;{var u,r;"="===t||"!="===t?-1===a[0].indexOf("||")&&void 0!==(r=jQuery("#"+l+"_"+a[0])).parents(".um-forms-line").data("conditional")&&(n=i(r.parents(".um-forms-line"))):"~"===t?(m=a[0].split("|"),u=[],jQuery.each(m,function(e){u.push(jQuery("#"+l+"_"+m[e]))}),void 0!==u[0].parents(".um-forms-line").data("conditional")&&(n=i(u[0].parents(".um-forms-line")))):"><"===t&&void 0!==(r=jQuery("#"+l+"_"+a[0]+"_"+a[2])).parents(".um-forms-line").data("conditional")&&(n=i(r.parents(".um-forms-line")))}var d=!1;{var m,o,c,p,f,_,h,g;if("="===t)return-1!==a[0].indexOf("||")?(m=a[0].split("||"),o=!1,jQuery.each(m,function(e){var a,e=jQuery("#"+l+"_"+m[e]),t=(n=!(d=!1),void 0!==e.parents(".um-forms-line").data("conditional")&&(n=i(e.parents(".um-forms-line"))),e.prop("tagName").toLowerCase());"input"===t?(a=e.attr("type"),d="checkbox"===a?"1"==s?e.is(":checked"):!e.is(":checked"):Array.isArray(s)?-1!==s.indexOf(e.val()):e.val()==s):"select"===t&&(d=Array.isArray(s)?-1!==s.indexOf(e.val()):e.val()==s),d&&n&&(o=!0)}),o):("input"==(h=r.prop("tagName").toLowerCase())?(g=r.attr("type"),d="checkbox"==g?"1"==s?r.is(":checked"):!r.is(":checked"):Array.isArray(s)?-1!==s.indexOf(r.val()):r.val()==s):"select"==h&&(d=Array.isArray(s)?-1!==s.indexOf(r.val()):r.val()==s),d&&n);if("!="===t)return-1!==a[0].indexOf("||")?(m=a[0].split("||"),o=!1,jQuery.each(m,function(e){var a,e=jQuery("#"+l+"_"+m[e]),t=(n=!(d=!1),void 0!==e.parents(".um-forms-line").data("conditional")&&(n=i(e.parents(".um-forms-line"))),e.prop("tagName").toLowerCase());"input"===t?(a=e.attr("type"),d="checkbox"===a?"1"==s?!e.is(":checked"):e.is(":checked"):e.val()!=s):"select"===t&&(d=e.val()!=s),d&&n&&(o=!0)}),o):("input"==(h=r.prop("tagName").toLowerCase())?(g=r.attr("type"),d="checkbox"==g?"1"==s?!r.is(":checked"):r.is(":checked"):r.val()!=s):"select"==h&&(d=r.val()!=s),d&&n);if("~"===t)return p=[],"sortable_items"===e.data("field_type")?(c=e.find(".um-sortable-items-value").data("field_id"),jQuery.each(u,function(e){var e=u[e],a=e.prop("tagName").toLowerCase();"input"===a?"checkbox"===e.attr("type")&&"1"==s&&e.is(":checked")&&p.push(e.data("fill_"+c)):"select"==a&&!s&&e.val()&&(p=(p=p.concat(e.val())).filter(y))}),f=jQuery('[data-field_id="'+c+'"]'),p.length?(f.siblings(".um-sortable-items-field").find("li").addClass("um-hidden-item"),jQuery.each(p,function(e){f.siblings(".um-sortable-items-field").find('li[data-tab-id="'+p[e]+'"]').removeClass("um-hidden-item")}),_=[],f.siblings(".um-sortable-items-field").find("li").each(function(){jQuery(this).hasClass("um-hidden-item")||_.push(jQuery(this).data("tab-id"))}),f.val(_.join(",")),f.siblings(".um-sortable-items-field").sortable("refresh"),d=!0):f.val(null)):(c=e.find(e.data("field_type")).data("field_id"),jQuery.each(u,function(e){var e=u[e],a=e.prop("tagName").toLowerCase();"input"===a?"checkbox"===e.attr("type")&&"1"==s&&e.is(":checked")&&p.push(e.data("fill_"+c)):"select"==a&&!s&&e.val()&&(p=(p=p.concat(e.val())).filter(y))}),f=jQuery('[data-field_id="'+c+'"]'),p.length?(f.find("option").hide(),jQuery.each(p,function(e){f.find('option[value="'+p[e]+'"]').show()}),-1===p.indexOf(f.val())&&(f.val(p[0]),f.find("option").attr("selected",!1).prop("selected",!1),f.find('option[value="'+p[0]+'"]').attr("selected",!0).prop("selected",!0)),d=!0):(f.val(null),f.find("option").attr("selected",!1).prop("selected",!1))),d&&n;if("><"===t)return h=r.prop("tagName").toLowerCase(),(d="input"==h&&"checkbox"==(g=r.attr("type"))?r.is(":checked"):d)&&n}return!1}(jQuery(this))?jQuery(this).hide():(jQuery(this).show(),um_admin_init_users_select()))})}function y(e,a,t){return t.indexOf(e)===a}jQuery(document.body).on("change",".um-md-default-filters-option-line .um-field-wrapper select",function(){var t,e,a;i||(e=(t=jQuery(this)).val(),a=t.data("member_directory"),i=!0,wp.ajax.send("um_member_directory_default_filter_settings",{data:{key:e,directory_id:a,nonce:um_admin_scripts.nonce},success:function(e){var a=t.parents(".um-md-default-filters-option-line").find(".um-field-wrapper2");a.html(e.field_html),i=!1,a.find(".um-slider").each(function(){var e=jQuery(this),a=[parseInt(e.data("min")),parseInt(e.data("max"))];e.slider({range:!0,min:parseInt(e.data("min")),max:parseInt(e.data("max")),values:a,create:function(e,a){},step:1,slide:function(e,a){s(jQuery(this),a)},stop:function(e,a){}}),s(e)}),a.find(".um-datepicker-filter").each(function(){var e=jQuery(this),a=new Date(1e3*e.data("date_min")),t=new Date(1e3*e.data("date_max"));e.pickadate({selectYears:!0,min:a,max:t,formatSubmit:"yyyy/mm/dd",hiddenName:!0,onOpen:function(){e.blur(),e.siblings(".picker").find(".picker__button--close").addClass("button")},onClose:function(){e.blur()},onSet:function(e){}})}),a.find(".um-timepicker-filter").each(function(){var e=jQuery(this),a=e.data("min"),t=e.data("max"),a=a.split(":"),t=t.split(":");e.pickatime({format:e.data("format"),interval:parseInt(e.data("intervals")),min:[a[0],a[1]],max:[t[0],t[1]],formatSubmit:"HH:i",hiddenName:!0,onOpen:function(){e.blur()},onClose:function(){e.blur()},onSet:function(e){}})})},error:function(e){return!1}}))}),jQuery(".um-md-default-filters-add-option").on("click",function(){var e,a,t;i||((e=jQuery(this).siblings("ul.um-md-default-filters-list")).data("field_id"),(a=0)
").append(e.siblings(".um-hidden-md-default-filters").clone()).html(),e.append(''+t+''+wp.i18n.__("Remove","ultimate-member")+''),e.find("li:last .um-hidden-md-default-filters").attr("name",jQuery(this).data("name")).addClass("um-forms-field um-long-field").removeClass("um-hidden-md-default-filters").attr("id",e.data("id_attr")+"-"+a),e.find("li:last .um-field-wrapper select").trigger("change"))}),jQuery(document.body).on("click",".um-text-delete",function(){jQuery(this).parents("li.um-multi-text-option-line").remove()}),jQuery(".um-multi-text-add-option").on("click",function(){var e=jQuery(this).siblings("ul.um-multi-text-list"),a=0,t=(0").append(e.siblings(".um-hidden-multi-text").clone()).html()),i=e.data("item_class");e.append(''+t+''+wp.i18n.__("Remove","ultimate-member")+""),e.find("li:last .um-hidden-multi-text").attr("name",jQuery(this).data("name")).addClass("um-forms-field um-long-field").removeClass("um-hidden-multi-text").attr("id",e.data("id_attr")+"-"+a)}),jQuery(".um-media-upload").each(function(){var e=jQuery(this).find(".um-forms-field"),a=e.data("default");""!=e.val()&&e.val()!=a?(e.siblings(".um-set-image").hide(),e.siblings(".um-clear-image").show(),e.siblings(".icon_preview").show()):(e.val()==a&&e.siblings(".icon_preview").show(),e.siblings(".um-set-image").show(),e.siblings(".um-clear-image").hide())}),"undefined"!=typeof wp&&wp.media&&wp.media.editor&&(jQuery(".um-set-image").on("click",function(e){var a=jQuery(this);e.preventDefault(),t&&t.remove(),(t=wp.media({title:a.data("upload_frame"),button:{text:wp.i18n.__("Select","ultimate-member")},multiple:!1})).on("select",function(){var e=t.state().get("selection").first().toJSON();a.siblings(".icon_preview").attr("src",e.url).show(),a.siblings(".um-forms-field").val(e.url),a.siblings(".um-media-upload-data-id").val(e.id),a.siblings(".um-media-upload-data-width").val(e.width),a.siblings(".um-media-upload-data-height").val(e.height),a.siblings(".um-media-upload-data-thumbnail").val(e.thumbnail),a.siblings(".um-media-upload-data-url").trigger("change"),a.siblings(".um-media-upload-url").val(e.url),a.siblings(".um-clear-image").show(),a.hide(),jQuery(document).trigger("um_media_upload_select",[a,e])}),t.open()}),jQuery(".icon_preview").on("click",function(e){jQuery(this).siblings(".um-set-image").trigger("click")}),jQuery(".um-clear-image").on("click",function(e){var a=jQuery(this);let t=a.siblings(".um-forms-field").data("default");void 0===t&&(t=""),a.siblings(".um-set-image").show(),a.hide(),a.siblings(".icon_preview").attr("src",t),""===t&&a.siblings(".icon_preview").hide(),a.siblings(".um-media-upload-data-id").val(""),a.siblings(".um-media-upload-data-width").val(""),a.siblings(".um-media-upload-data-height").val(""),a.siblings(".um-media-upload-data-thumbnail").val(""),a.siblings(".um-forms-field").val(t),a.siblings(".um-media-upload-data-url").trigger("change"),a.siblings(".um-media-upload-url").val(t),jQuery(document).trigger("um_media_upload_clear",a)})),jQuery(document.body).on("change",".um-forms-field",function(){(0builder_input[ $k ] ) || ! array_key_exists( 'array', $this->builder_input[ $k ] ) ) {
+ continue 2;
+ }
+
+ $sanitized[ $k ] = ! in_array( absint( $v ), $this->builder_input[ $k ]['array'], true ) ? $this->builder_input[ $k ]['default'] : absint( $v );
+ break;
}
}
@@ -1565,14 +1572,26 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
case 'text':
$sanitized[ $k ] = sanitize_text_field( $v );
break;
+ case 'sanitize_array_key':
+ if ( ! array_key_exists( 'default', UM()->admin_settings()->settings_map[ $k ] ) || ! array_key_exists( 'array', UM()->admin_settings()->settings_map[ $k ] ) ) {
+ continue 2;
+ }
+
+ if ( is_array( $v ) ) {
+ $sanitized[ $k ] = array();
+ foreach ( $v as $v_v ) {
+ if ( in_array( sanitize_key( $v_v ), UM()->admin_settings()->settings_map[ $k ]['array'], true ) ) {
+ $sanitized[ $k ][] = sanitize_key( $v_v );
+ }
+ }
+ } else {
+ $sanitized[ $k ] = ! in_array( sanitize_key( $v ), UM()->admin_settings()->settings_map[ $k ]['array'], true ) ? UM()->admin_settings()->settings_map[ $k ]['default'] : sanitize_key( $v );
+ }
+ break;
}
}
- $data = $sanitized;
-
- $data = apply_filters( 'um_save_settings_sanitize', $data );
-
- return $data;
+ return apply_filters( 'um_save_settings_sanitize', $sanitized );
}
/**
@@ -2100,5 +2119,22 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
}
return UM()->classes['um\admin\users_columns'];
}
+
+ /**
+ * @since 2.10.6
+ *
+ * @param bool|array $data
+ * @return null|Extensions_Updater
+ */
+ public function extension_updater( $data = false ) {
+ if ( empty( $data['slug'] ) ) {
+ return null;
+ }
+ $class_index = 'um\admin\extensions_updater_' . $data['slug'];
+ if ( ! isset( UM()->classes[ $class_index ] ) || empty( UM()->classes[ $class_index ] ) ) {
+ UM()->classes[ $class_index ] = new Extensions_Updater( $data );
+ }
+ return UM()->classes[ $class_index ];
+ }
}
}
diff --git a/includes/admin/class-extensions-updater.php b/includes/admin/class-extensions-updater.php
new file mode 100644
index 00000000..11d3aa40
--- /dev/null
+++ b/includes/admin/class-extensions-updater.php
@@ -0,0 +1,124 @@
+updater_data = wp_parse_args(
+ $args,
+ array(
+ 'slug' => '',
+ 'version' => '0.0.0',
+ 'path' => '',
+ )
+ );
+
+ add_action( 'admin_init', array( $this, 'maybe_run_updater' ) );
+ }
+
+ /**
+ * Maybe run upgrade if needed.
+ */
+ public function maybe_run_updater() {
+ $last_version_upgrade = $this->get_last_version_upgrade();
+ if ( ! empty( $last_version_upgrade ) && version_compare( $last_version_upgrade, $this->updater_data['version'], '>=' ) ) {
+ // Don't need update.
+ return;
+ }
+
+ $packages = $this->get_packages();
+ if ( ! empty( $packages ) ) {
+ $packages_dir = $this->get_packages_dir();
+ foreach ( $packages as $package_version ) {
+ if ( version_compare( $package_version, $last_version_upgrade, '<=' ) ) {
+ continue;
+ }
+
+ if ( version_compare( $package_version, $this->updater_data['version'], '>' ) ) {
+ continue;
+ }
+
+ $file_path = $packages_dir . $package_version . '.php';
+ if ( ! file_exists( $file_path ) ) {
+ continue;
+ }
+
+ include_once $file_path;
+ $this->set_last_version_upgrade( $package_version );
+ }
+ }
+
+ $this->set_last_version_upgrade( $this->updater_data['version'] );
+ }
+
+ /**
+ * Get packages list, based on the files in packages dir.
+ */
+ private function get_packages() {
+ $packages = array();
+
+ $handle = opendir( $this->get_packages_dir() );
+ // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition, WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition -- reading folder's content here
+ while ( false !== ( $filename = readdir( $handle ) ) ) {
+ if ( '.' !== $filename && '..' !== $filename ) {
+ $packages[] = preg_replace( '/(.*?)\.php/i', '$1', $filename );
+ }
+ }
+ closedir( $handle );
+
+ usort(
+ $packages,
+ static function ( $a, $b ) {
+ return version_compare( $a, $b );
+ }
+ );
+
+ return $packages;
+ }
+
+ /**
+ * Retrieve the directory path where packages are stored for updates.
+ *
+ * @return string The normalized path to the packages' directory.
+ */
+ private function get_packages_dir() {
+ return wp_normalize_path( $this->updater_data['path'] . 'includes/updates/' );
+ }
+
+ /**
+ * Gets the last version upgrade from options.
+ *
+ * @return string The last version upgrade.
+ */
+ private function get_last_version_upgrade() {
+ return get_option( 'um_' . $this->updater_data['slug'] . '_last_version_upgrade', '0.0.0' );
+ }
+
+ /**
+ * Set the last version upgrade for the updater.
+ *
+ * @param string $version The version to set as the last upgrade version.
+ */
+ private function set_last_version_upgrade( $version ) {
+ update_option( 'um_' . $this->updater_data['slug'] . '_last_version_upgrade', $version );
+ }
+}
diff --git a/includes/admin/core/class-admin-forms.php b/includes/admin/core/class-admin-forms.php
index 298ea7b4..00de3271 100644
--- a/includes/admin/core/class-admin-forms.php
+++ b/includes/admin/core/class-admin-forms.php
@@ -1164,9 +1164,11 @@ if ( ! class_exists( 'um\admin\core\Admin_Forms' ) ) {
}
$button = '';
- $slug = str_replace( 'core_', '', $field_data['id'] );
- if ( ! um_get_predefined_page_id( $slug ) || 'publish' !== get_post_status( um_get_predefined_page_id( $slug ) ) ) {
- $button = ' ' . esc_html__( 'Create Default', 'ultimate-member' ) . '';
+ if ( ! array_key_exists( 'predefined', $field_data ) || false !== $field_data['predefined'] ) {
+ $slug = str_replace( 'core_', '', $field_data['id'] );
+ if ( ! um_get_predefined_page_id( $slug ) || 'publish' !== get_post_status( um_get_predefined_page_id( $slug ) ) ) {
+ $button = ' ' . esc_html__( 'Create Default', 'ultimate-member' ) . '';
+ }
}
$html = "$hidden$button";
diff --git a/includes/admin/core/class-admin-settings.php b/includes/admin/core/class-admin-settings.php
index 9821763c..13d66d89 100644
--- a/includes/admin/core/class-admin-settings.php
+++ b/includes/admin/core/class-admin-settings.php
@@ -2898,10 +2898,19 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) {
}
}
+ /**
+ * Check if license debug is enabled based on defined constants.
+ *
+ * @return bool
+ */
+ private static function is_license_debug_enabled() {
+ return defined( 'UM_LICENSE_REQUEST_DEBUG' ) && UM_LICENSE_REQUEST_DEBUG && defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG;
+ }
+
/**
*
*/
- function licenses_save() {
+ public function licenses_save() {
if ( empty( $_POST['um_options'] ) || empty( $_POST['licenses_settings'] ) ) {
return;
}
@@ -2931,48 +2940,63 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) {
$version = false;
$author = false;
foreach ( $this->settings_structure['licenses']['fields'] as $field_data ) {
- if ( $field_data['id'] == $key ) {
+ if ( $field_data['id'] === $key ) {
$item_name = ! empty( $field_data['item_name'] ) ? $field_data['item_name'] : false;
$version = ! empty( $field_data['version'] ) ? $field_data['version'] : false;
$author = ! empty( $field_data['author'] ) ? $field_data['author'] : false;
}
}
- $api_params = array(
- 'edd_action' => $edd_action,
- 'license' => $license_key,
- 'item_name' => $item_name,
- 'version' => $version,
- 'author' => $author,
- 'url' => home_url(),
+ $post_attr = array(
+ 'timeout' => UM()::$request_timeout,
+ 'sslverify' => false,
+ 'body' => array(
+ 'edd_action' => $edd_action,
+ 'license' => $license_key,
+ 'item_name' => $item_name,
+ 'version' => $version,
+ 'author' => $author,
+ 'url' => home_url(),
+ ),
);
- $request = wp_remote_post(
- UM()::$store_url,
- array(
- 'timeout' => UM()::$request_timeout,
- 'sslverify' => false,
- 'body' => $api_params,
- )
- );
+ // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Need to debug license requests sometimes.
+ if ( self::is_license_debug_enabled() ) {
+ error_log( '----- License handler starts below -----' );
+ error_log( '### Store URL: ' . UM()::$store_url );
+ error_log( '### Request:' );
+ error_log( maybe_serialize( $post_attr ) );
+ }
+ $request = wp_remote_post( UM()::$store_url, $post_attr );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ) );
} else {
- $request = wp_remote_post(
- UM()::$store_url,
- array(
- 'timeout' => UM()::$request_timeout,
- 'sslverify' => true,
- 'body' => $api_params,
- )
- );
+ if ( self::is_license_debug_enabled() ) {
+ error_log( '> Got `wp_error`, try again with `sslverify=true`' );
+ }
+ $post_attr['sslverify'] = true;
+
+ $request = wp_remote_post( UM()::$store_url, $post_attr );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ) );
}
}
+ if ( self::is_license_debug_enabled() ) {
+ if ( is_wp_error( $request ) ) {
+ error_log( '> Finally got `wp_error`. Details below.' );
+ error_log( '>> Error code: ' . $request->get_error_code() );
+ error_log( '>> Error message: ' . $request->get_error_message() );
+ } else {
+ error_log( '### Response from UM website:' );
+ error_log( '>' . maybe_serialize( $request ) );
+ }
+ error_log( '^^^^^^ End license handler ^^^^^^' );
+ }
+ // phpcs:enable WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Need to debug license requests sometimes.
+
$request = ( $request ) ? maybe_unserialize( $request ) : false;
if ( in_array( $edd_action, array( 'activate_license', 'check_license' ), true ) ) {
diff --git a/includes/admin/core/packages/2.0-beta1/um-cpt.php b/includes/admin/core/packages/2.0-beta1/um-cpt.php
index 6c073707..62e5502a 100644
--- a/includes/admin/core/packages/2.0-beta1/um-cpt.php
+++ b/includes/admin/core/packages/2.0-beta1/um-cpt.php
@@ -25,7 +25,7 @@ foreach ( $forms as $form_id ) {
delete_post_meta( $form_id, "_um_{$form_type}_use_globals" );
$role_slug = get_post_meta( $form_id, "_um_{$form_type}_role", true );
- if ( $role_slug && array_key_exists( $role_slug, $roles_associations ) ) {
+ if ( $role_slug && is_array( $roles_associations ) && array_key_exists( $role_slug, $roles_associations ) ) {
update_post_meta( $form_id, "_um_{$form_type}_role", $roles_associations[ $role_slug ] );
}
}
diff --git a/includes/ajax/class-pages.php b/includes/ajax/class-pages.php
index 60bd674b..a41b3877 100644
--- a/includes/ajax/class-pages.php
+++ b/includes/ajax/class-pages.php
@@ -1,6 +1,8 @@
admin()->check_ajax_nonce();
+ check_ajax_referer( 'um-admin-nonce', 'nonce' );
// we will pass post IDs and titles to this array
$return = array();
@@ -36,7 +38,7 @@ class Pages {
'post_status' => 'publish', // if you don't want drafts to be returned
'ignore_sticky_posts' => 1,
'posts_per_page' => 10, // how much to show at once
- 'paged' => absint( $_GET['page'] ),
+ 'paged' => ! empty( $_GET['page'] ) ? absint( $_GET['page'] ) : 1,
'orderby' => 'title',
'order' => 'asc',
);
@@ -45,7 +47,37 @@ class Pages {
$query_args['s'] = sanitize_text_field( $_GET['search'] ); // the search query
}
- $search_results = new \WP_Query( $query_args );
+ $field_id = ! empty( $_GET['field_id'] ) ? sanitize_text_field( $_GET['field_id'] ) : null;
+ if ( 'form__um_register_use_gdpr_content_id' === $field_id ) {
+ $predefined_ids = array();
+ $predefined_pages = array_keys( UM()->config()->get( 'predefined_pages' ) );
+ foreach ( $predefined_pages as $slug ) {
+ $p_id = um_get_predefined_page_id( $slug );
+ if ( empty( $p_id ) ) {
+ continue;
+ }
+ $predefined_ids[] = $p_id;
+ }
+ $predefined_ids = array_unique( $predefined_ids );
+ if ( ! empty( $predefined_ids ) ) {
+ $query_args['post__not_in'] = $predefined_ids;
+ }
+ }
+
+ /**
+ * Filters WP_Query arguments for getting pages visible in the dropdown fields in UM Settings.
+ *
+ * @since 2.10.6
+ * @hook um_admin_settings_get_pages_list_args
+ *
+ * @param {array} $query_args Get pages WP_Query arguments.
+ * @param {string} $field_id Dropdown field ID.
+ *
+ * @return {array} Get pages WP_Query arguments.
+ */
+ $query_args = apply_filters( 'um_admin_settings_get_pages_list_args', $query_args, $field_id );
+
+ $search_results = new WP_Query( $query_args );
if ( $search_results->have_posts() ) {
while ( $search_results->have_posts() ) {
diff --git a/includes/class-dependencies.php b/includes/class-dependencies.php
index cc02622c..8b93e386 100644
--- a/includes/class-dependencies.php
+++ b/includes/class-dependencies.php
@@ -72,6 +72,8 @@ if ( ! class_exists( 'um\Dependencies' ) ) {
'filesharing' => '1.0.0',
'beaver-builder' => '2.0',
'user-events' => '1.0.0',
+ 'ai-assistant' => '1.0.0',
+ 'ai-moderation' => '1.0.0',
// deprecated
'instagram' => '2.0.5',
diff --git a/includes/class-functions.php b/includes/class-functions.php
index bf861f15..61124c73 100644
--- a/includes/class-functions.php
+++ b/includes/class-functions.php
@@ -548,13 +548,35 @@ if ( ! class_exists( 'UM_Functions' ) ) {
break;
case 'templates':
$allowed_html = array(
- 'style' => array(),
- 'link' => array(
+ 'style' => array(),
+ 'link' => array(
'rel' => true,
'href' => true,
'media' => true,
),
- 'form' => array(
+ 'svg' => array(
+ 'xmlns' => true,
+ 'height' => true,
+ 'preserveaspectratio' => true,
+ 'viewbox' => true,
+ 'width' => true,
+ 'x' => true,
+ 'y' => true,
+ 'fill' => true,
+ 'stroke' => true,
+ 'stroke-linecap' => true,
+ 'stroke-linejoin' => true,
+ 'stroke-width' => true,
+ ),
+ 'path' => array(
+ 'd' => true,
+ 'stroke' => true,
+ 'stroke-width' => true,
+ 'stroke-linecap' => true,
+ 'stroke-linejoin' => true,
+ 'fill' => true,
+ ),
+ 'form' => array(
'action' => true,
'accept' => true,
'accept-charset' => true,
@@ -562,11 +584,12 @@ if ( ! class_exists( 'UM_Functions' ) ) {
'method' => true,
'name' => true,
'target' => true,
+ 'novalidate' => true,
),
- 'label' => array(
+ 'label' => array(
'for' => true,
),
- 'select' => array(
+ 'select' => array(
'name' => true,
'multiple' => true,
'disabled' => true,
@@ -574,12 +597,12 @@ if ( ! class_exists( 'UM_Functions' ) ) {
'required' => true,
'autocomplete' => true,
),
- 'option' => array(
+ 'option' => array(
'value' => true,
'selected' => true,
'disabled' => true,
),
- 'input' => array(
+ 'input' => array(
'type' => true,
'name' => true,
'value' => true,
@@ -598,7 +621,7 @@ if ( ! class_exists( 'UM_Functions' ) ) {
'maxlength' => true,
'pattern' => true,
),
- 'textarea' => array(
+ 'textarea' => array(
'cols' => true,
'rows' => true,
'disabled' => true,
@@ -606,8 +629,21 @@ if ( ! class_exists( 'UM_Functions' ) ) {
'readonly' => true,
'required' => true,
'autocomplete' => true,
+ 'placeholder' => true,
),
- 'img' => array(
+ 'button' => array(
+ 'type' => true,
+ 'name' => true,
+ 'value' => true,
+ 'placeholder' => true,
+ 'readonly' => true,
+ 'disabled' => true,
+ 'checked' => true,
+ 'selected' => true,
+ 'required' => true,
+ 'autocomplete' => true,
+ ),
+ 'img' => array(
'alt' => true,
'align' => true,
'border' => true,
@@ -621,26 +657,110 @@ if ( ! class_exists( 'UM_Functions' ) ) {
'usemap' => true,
'width' => true,
),
- 'h1' => array(
+ 'h1' => array(
'align' => true,
),
- 'h2' => array(
+ 'h2' => array(
'align' => true,
),
- 'h3' => array(
+ 'h3' => array(
'align' => true,
),
- 'p' => array(
+ 'h4' => array(
+ 'align' => true,
+ ),
+ 'h5' => array(
+ 'align' => true,
+ ),
+ 'h6' => array(
+ 'align' => true,
+ ),
+ 'p' => array(
'align' => true,
'dir' => true,
'lang' => true,
),
- 'ol' => array(),
- 'ul' => array(),
- 'li' => array(),
- 'time' => array(
+ 'ol' => array(),
+ 'ul' => array(),
+ 'li' => array(),
+ 'time' => array(
'datetime' => true,
),
+ 'section' => array(),
+ 'table' => array(
+ 'align' => true,
+ 'bgcolor' => true,
+ 'border' => true,
+ 'cellpadding' => true,
+ 'cellspacing' => true,
+ 'dir' => true,
+ 'rules' => true,
+ 'summary' => true,
+ 'width' => true,
+ ),
+ 'tbody' => array(
+ 'align' => true,
+ 'char' => true,
+ 'charoff' => true,
+ 'valign' => true,
+ ),
+ 'thead' => array(
+ 'align' => true,
+ 'char' => true,
+ 'charoff' => true,
+ 'valign' => true,
+ ),
+ 'th' => array(
+ 'abbr' => true,
+ 'align' => true,
+ 'axis' => true,
+ 'bgcolor' => true,
+ 'char' => true,
+ 'charoff' => true,
+ 'colspan' => true,
+ 'headers' => true,
+ 'height' => true,
+ 'nowrap' => true,
+ 'rowspan' => true,
+ 'scope' => true,
+ 'valign' => true,
+ 'width' => true,
+ ),
+ 'tr' => array(
+ 'align' => true,
+ 'bgcolor' => true,
+ 'char' => true,
+ 'charoff' => true,
+ 'valign' => true,
+ ),
+ 'td' => array(
+ 'abbr' => true,
+ 'align' => true,
+ 'axis' => true,
+ 'bgcolor' => true,
+ 'char' => true,
+ 'charoff' => true,
+ 'colspan' => true,
+ 'dir' => true,
+ 'headers' => true,
+ 'height' => true,
+ 'nowrap' => true,
+ 'rowspan' => true,
+ 'scope' => true,
+ 'valign' => true,
+ 'width' => true,
+ ),
+ 'tfoot' => array(
+ 'align' => true,
+ 'char' => true,
+ 'charoff' => true,
+ 'valign' => true,
+ ),
+ 'noscript' => array(),
+ 'del' => array(),
+ 'blockquote' => array(
+ 'cite' => true,
+ ),
);
break;
case 'admin_notice':
diff --git a/includes/common/class-screen.php b/includes/common/class-screen.php
index e9328e74..435662dc 100644
--- a/includes/common/class-screen.php
+++ b/includes/common/class-screen.php
@@ -19,6 +19,7 @@ if ( ! class_exists( 'um\common\Screen' ) ) {
*/
public function __construct() {
add_filter( 'body_class', array( &$this, 'remove_admin_bar' ), 1000 );
+ add_action( 'send_headers', array( &$this, 'avoid_mobile_cache' ) );
}
/**
@@ -40,5 +41,21 @@ if ( ! class_exists( 'um\common\Screen' ) ) {
return $classes;
}
+
+ /**
+ * Avoid caching for mobile devices on specific pages.
+ */
+ public function avoid_mobile_cache() {
+ if ( ! wp_is_mobile() ) {
+ return;
+ }
+
+ if ( um_is_predefined_page( 'login' ) || um_is_predefined_page( 'register' ) || um_is_predefined_page( 'account' ) ) {
+ header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0' );
+ header( 'Cache-Control: post-check=0, pre-check=0', false );
+ header( 'Pragma: no-cache' );
+ header( 'Expires: 0' );
+ }
+ }
}
}
diff --git a/includes/common/class-users.php b/includes/common/class-users.php
index 6505ec0e..d83d545e 100644
--- a/includes/common/class-users.php
+++ b/includes/common/class-users.php
@@ -979,14 +979,34 @@ class Users {
public static function get_empty_status_users() {
global $wpdb;
- $total_users = $wpdb->get_var(
- "SELECT COUNT(DISTINCT u.ID)
- FROM {$wpdb->users} u
- LEFT JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = 'account_status'
- LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = '_um_registration_in_progress'
- WHERE ( um.meta_value IS NULL OR um.meta_value = '' ) AND
- ( um2.meta_value IS NULL OR um2.meta_value != '1' )"
- );
+ /**
+ * Filters whitelisted usermeta keys that can be stored inside DB after UM Form submission.
+ *
+ * @param {int} $total_users Count of the users with empty status. Query result, by default is null.
+ *
+ * @return {int} Count of the users with empty status. Or null.
+ *
+ * @since 2.10.6
+ * @hook um_get_empty_status_users_query_result
+ *
+ * @example Customize the empty status users query.
+ * function my_get_empty_status_users_query( $total_users ) {
+ * $total_users = $wpdb->get_var( "your custom DB query here" );
+ * return $total_users;
+ * }
+ * add_filter( 'um_get_empty_status_users_query_result', 'my_get_empty_status_users_query' );
+ */
+ $total_users = apply_filters( 'um_get_empty_status_users_query_result', null );
+ if ( is_null( $total_users ) ) {
+ $total_users = $wpdb->get_var(
+ "SELECT COUNT(DISTINCT u.ID)
+ FROM {$wpdb->users} u
+ LEFT JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = 'account_status'
+ LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = '_um_registration_in_progress'
+ WHERE ( um.meta_value IS NULL OR um.meta_value = '' ) AND
+ ( um2.meta_value IS NULL OR um2.meta_value != '1' )"
+ );
+ }
$total_users = absint( $total_users );
if ( $total_users > 0 ) {
diff --git a/includes/core/class-cron.php b/includes/core/class-cron.php
index 63b0ad34..34244c41 100644
--- a/includes/core/class-cron.php
+++ b/includes/core/class-cron.php
@@ -80,7 +80,9 @@ if ( ! class_exists( 'um\core\Cron' ) ) {
*/
private function weekly_events() {
$sunday_start = wp_date( 'w' );
- $week_start = $sunday_start - absint( get_option( 'start_of_week' ) );
+ $start_of_week = get_option( 'start_of_week', 0 );
+ $start_of_week = is_numeric( $start_of_week ) ? $start_of_week : 0;
+ $week_start = $sunday_start - absint( $start_of_week );
$week_start_day = strtotime( '-' . $week_start . ' days' );
$time = mktime( 0, 0, 0, wp_date( 'm', $week_start_day ), wp_date( 'd', $week_start_day ), wp_date( 'Y', $week_start_day ) );
if ( ! wp_next_scheduled( 'um_weekly_scheduled_events' ) ) {
diff --git a/includes/core/class-fields.php b/includes/core/class-fields.php
index 7ad67b6f..d868345f 100644
--- a/includes/core/class-fields.php
+++ b/includes/core/class-fields.php
@@ -1982,7 +1982,7 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
$array['invalid_image'] = __( 'Please upload a valid image!', 'ultimate-member' );
}
if ( ! isset( $array['allowed_types'] ) ) {
- $array['allowed_types'] = 'gif,jpg,jpeg,png';
+ $array['allowed_types'] = 'gif,jpg,jpeg,png,webp';
} else {
$array['allowed_types'] = implode( ',', $array['allowed_types'] );
}
diff --git a/includes/core/class-files.php b/includes/core/class-files.php
index 3722d962..be091959 100644
--- a/includes/core/class-files.php
+++ b/includes/core/class-files.php
@@ -822,12 +822,15 @@ if ( ! class_exists( 'um\core\Files' ) ) {
* }
* ?>
*/
- return apply_filters( 'um_allowed_image_types', array(
- 'png' => 'PNG',
- 'jpeg' => 'JPEG',
- 'jpg' => 'JPG',
- 'gif' => 'GIF'
- ) );
+ return apply_filters(
+ 'um_allowed_image_types',
+ array(
+ 'png' => 'PNG',
+ 'jpeg' => 'JPEG',
+ 'jpg' => 'JPG',
+ 'webp' => 'WEBP',
+ )
+ );
}
diff --git a/includes/core/class-member-directory-meta.php b/includes/core/class-member-directory-meta.php
index 272fbe0d..6ebcefb1 100644
--- a/includes/core/class-member-directory-meta.php
+++ b/includes/core/class-member-directory-meta.php
@@ -1104,8 +1104,14 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
$pagination_data = $this->calculate_pagination( $directory_data, $total_users );
$sizes = UM()->options()->get( 'cover_thumb_sizes' );
+ // Ensure we have valid sizes array and handle case when only one size is defined
+ if ( ! is_array( $sizes ) || empty( $sizes ) ) {
+ $sizes = array( 300 ); // fallback to default
+ }
- $this->cover_size = wp_is_mobile() ? $sizes[1] : end( $sizes );
+ // For mobile, use second size if available, otherwise use first size
+ $available_mobile = isset( $sizes[1] ) ? $sizes[1] : $sizes[0];
+ $this->cover_size = wp_is_mobile() ? $available_mobile : end( $sizes );
$avatar_size = UM()->options()->get( 'profile_photosize' );
$this->avatar_size = str_replace( 'px', '', $avatar_size );
diff --git a/includes/core/class-member-directory.php b/includes/core/class-member-directory.php
index 81c825fc..4241720f 100644
--- a/includes/core/class-member-directory.php
+++ b/includes/core/class-member-directory.php
@@ -995,16 +995,15 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$range = false;
switch ( $filter ) {
-
- default: {
-
+ default:
$meta = $wpdb->get_row(
$wpdb->prepare(
"SELECT MIN( CONVERT( meta_value, DECIMAL ) ) as min_meta,
MAX( CONVERT( meta_value, DECIMAL ) ) as max_meta,
COUNT( DISTINCT meta_value ) as amount
FROM {$wpdb->usermeta}
- WHERE meta_key = %s",
+ WHERE meta_key = %s AND
+ meta_value != ''",
$filter
),
ARRAY_A
@@ -1016,10 +1015,9 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$range = apply_filters( 'um_member_directory_filter_slider_common', $range, $directory_data, $filter );
$range = apply_filters( "um_member_directory_filter_{$filter}_slider", $range, $directory_data );
-
break;
- }
- case 'birth_date': {
+
+ case 'birth_date':
$meta = $wpdb->get_row(
"SELECT MIN( meta_value ) as min_meta,
MAX( meta_value ) as max_meta,
@@ -1033,16 +1031,13 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
if ( isset( $meta['min_meta'] ) && isset( $meta['max_meta'] ) && isset( $meta['amount'] ) && $meta['amount'] > 1 ) {
$range = array( $this->borndate( strtotime( $meta['max_meta'] ) ), $this->borndate( strtotime( $meta['min_meta'] ) ) );
}
-
break;
- }
}
return $range;
}
-
/**
* @param $filter
*
@@ -2956,8 +2951,14 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$user_ids = apply_filters( 'um_prepare_user_results_array', $user_ids, $this->query_args );
$sizes = UM()->options()->get( 'cover_thumb_sizes' );
+ // Ensure we have valid sizes array and handle case when only one size is defined
+ if ( ! is_array( $sizes ) || empty( $sizes ) ) {
+ $sizes = array( 300 ); // fallback to default
+ }
- $this->cover_size = wp_is_mobile() ? $sizes[1] : end( $sizes );
+ // For mobile, use second size if available, otherwise use first size
+ $available_mobile = isset( $sizes[1] ) ? $sizes[1] : $sizes[0];
+ $this->cover_size = wp_is_mobile() ? $available_mobile : end( $sizes );
$this->cover_size = apply_filters( 'um_member_directory_cover_image_size', $this->cover_size, $directory_data );
diff --git a/includes/frontend/class-user-profile.php b/includes/frontend/class-user-profile.php
index a2fb176e..5a155640 100644
--- a/includes/frontend/class-user-profile.php
+++ b/includes/frontend/class-user-profile.php
@@ -1,6 +1,8 @@
common()->users()::user_exists( $uid ) ) {
return;
@@ -65,5 +71,30 @@ if ( ! class_exists( 'um\frontend\User_Profile' ) ) {
exit;
}
}
+
+ /**
+ * Returns the user profile edit link using Ultimate Member plugin.
+ *
+ * @param string $link The default edit user link.
+ * @param int $user_id The ID of the user.
+ *
+ * @return string The customized user profile edit link.
+ */
+ public function change_edit_user_link( $link, $user_id ) {
+ return um_edit_profile_url( $user_id );
+ }
+
+ /**
+ * Retrieves the user profile URL for the given comment author.
+ *
+ * @param string $comment_author_url The URL of the comment author.
+ * @param int $comment_id The ID of the comment.
+ * @param WP_Comment $comment The comment object.
+ *
+ * @return string The user profile URL for the comment author.
+ */
+ public function change_comment_author_url( $comment_author_url, $comment_id, $comment ) {
+ return um_user_profile_url( $comment->user_id );
+ }
}
}
diff --git a/includes/um-core-functions.php b/includes/um-core-functions.php
index d2d7c397..4940129a 100755
--- a/includes/um-core-functions.php
+++ b/includes/um-core-functions.php
@@ -20,6 +20,27 @@ function um_predefined_page_slug_exists( $slug ) {
return array_key_exists( $slug, $predefined_pages );
}
+/**
+ * @param int $post_id
+ *
+ * @return bool
+ */
+function um_post_is_predefined_page( $post_id ) {
+ $predefined_pages = UM()->config()->get( 'predefined_pages' );
+ $predefined_pages = array_keys( $predefined_pages );
+ if ( empty( $predefined_pages ) ) {
+ return false;
+ }
+
+ foreach ( $predefined_pages as $slug ) {
+ if ( um_is_predefined_page( $slug, $post_id ) ) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/**
* @param string $slug
*
diff --git a/includes/um-short-functions.php b/includes/um-short-functions.php
index 45ac1b56..c75af9b9 100644
--- a/includes/um-short-functions.php
+++ b/includes/um-short-functions.php
@@ -287,15 +287,14 @@ function um_field_conditions_are_met( $data ) {
return true;
}
- $state = ( isset( $data['conditional_action'] ) && $data['conditional_action'] == 'show' ) ? 1 : 0;
+ $state = ( isset( $data['conditional_action'] ) && 'show' === $data['conditional_action'] ) ? 1 : 0;
$first_group = 0;
$state_array = array();
- $count = count( $state_array );
+ $count = count( $state_array );
foreach ( $data['conditions'] as $k => $arr ) {
-
$val = $arr[3];
- $op = $arr[2];
+ $op = $arr[2];
if ( strstr( $arr[1], 'role_' ) ) {
$arr[1] = 'role';
@@ -303,70 +302,74 @@ function um_field_conditions_are_met( $data ) {
$field = um_profile( $arr[1] );
-
if ( ! isset( $arr[5] ) || $arr[5] != $first_group ) {
+ if ( 'show' === $arr[0] ) {
-
- if ( $arr[0] == 'show' ) {
-
- switch ($op) {
+ switch ( $op ) {
case 'equals to':
-
$field = maybe_unserialize( $field );
- if (is_array( $field ))
+ if ( is_array( $field ) ) {
$state = in_array( $val, $field ) ? 'show' : 'hide';
- else
+ } else {
$state = ( $field == $val ) ? 'show' : 'hide';
+ }
break;
case 'not equals':
-
$field = maybe_unserialize( $field );
- if (is_array( $field ))
- $state = !in_array( $val, $field ) ? 'show' : 'hide';
- else
+ if ( is_array( $field ) ) {
+ $state = ! in_array( $val, $field ) ? 'show' : 'hide';
+ } else {
$state = ( $field != $val ) ? 'show' : 'hide';
+ }
break;
case 'empty':
-
- $state = ( !$field ) ? 'show' : 'hide';
+ $state = ( ! $field ) ? 'show' : 'hide';
break;
case 'not empty':
-
$state = ( $field ) ? 'show' : 'hide';
break;
case 'greater than':
- if ($field > $val) {
+ if ( $field > $val ) {
$state = 'show';
} else {
$state = 'hide';
}
break;
case 'less than':
- if ($field < $val) {
+ if ( $field < $val ) {
$state = 'show';
} else {
$state = 'hide';
}
break;
case 'contains':
- if (strstr( $field, $val )) {
- $state = 'show';
+ $match = false;
+ if ( is_array( $field ) ) {
+ foreach ( $field as $item ) {
+ if ( is_string( $item ) && false !== strpos( $item, $val ) ) {
+ $match = true;
+ break;
+ }
+ }
} else {
- $state = 'hide';
+ if ( false !== strpos( $field, $val ) ) {
+ $match = true;
+ }
}
+
+ $state = $match ? 'show' : 'hide';
break;
}
- } elseif ( $arr[0] == 'hide' ) {
+ } elseif ( 'hide' === $arr[0] ) {
switch ( $op ) {
case 'equals to':
-
$field = maybe_unserialize( $field );
if ( is_array( $field ) ) {
@@ -377,7 +380,6 @@ function um_field_conditions_are_met( $data ) {
break;
case 'not equals':
-
$field = maybe_unserialize( $field );
if ( is_array( $field ) ) {
@@ -388,12 +390,10 @@ function um_field_conditions_are_met( $data ) {
break;
case 'empty':
-
$state = ( ! $field ) ? 'hide' : 'show';
break;
case 'not empty':
-
$state = ( $field ) ? 'hide' : 'show';
break;
@@ -412,19 +412,29 @@ function um_field_conditions_are_met( $data ) {
}
break;
case 'contains':
- if ( strstr( $field, $val ) ) {
- $state = 'hide';
+ $match = true;
+ if ( is_array( $field ) ) {
+ foreach ( $field as $item ) {
+ if ( is_string( $item ) && false !== strpos( $item, $val ) ) {
+ $match = false;
+ break;
+ }
+ }
} else {
- $state = 'show';
+ if ( false !== strpos( $field, $val ) ) {
+ $match = false;
+ }
}
+
+ $state = $match ? 'show' : 'hide';
+
break;
}
}
- $first_group++;
+ ++$first_group;
array_push( $state_array, $state );
} else {
-
- if ( $arr[0] == 'show' ) {
+ if ( 'show' === $arr[0] ) {
switch ( $op ) {
case 'equals to':
@@ -448,13 +458,11 @@ function um_field_conditions_are_met( $data ) {
break;
case 'empty':
-
$state = ( ! $field ) ? 'show' : 'not_show';
break;
case 'not empty':
-
- $state = ( $field ) ? 'show': 'not_show';
+ $state = ( $field ) ? 'show' : 'not_show';
break;
case 'greater than':
@@ -472,14 +480,25 @@ function um_field_conditions_are_met( $data ) {
}
break;
case 'contains':
- if ( strstr( $field, $val ) ) {
- $state = 'show';
+ $match = false;
+ if ( is_array( $field ) ) {
+ foreach ( $field as $item ) {
+ if ( is_string( $item ) && false !== strpos( $item, $val ) ) {
+ $match = true;
+ break;
+ }
+ }
} else {
- $state = 'not_show';
+ if ( false !== strpos( $field, $val ) ) {
+ $match = true;
+ }
}
+
+ $state = $match ? 'show' : 'not_show';
+
break;
}
- } elseif ( $arr[0] == 'hide' ) {
+ } elseif ( 'hide' === $arr[0] ) {
switch ( $op ) {
case 'equals to':
@@ -493,7 +512,6 @@ function um_field_conditions_are_met( $data ) {
break;
case 'not equals':
-
$field = maybe_unserialize( $field );
if ( is_array( $field ) ) {
@@ -504,12 +522,10 @@ function um_field_conditions_are_met( $data ) {
break;
case 'empty':
-
$state = ( ! $field ) ? 'hide' : 'not_hide';
break;
case 'not empty':
-
$state = ( $field ) ? 'hide' : 'not_hide';
break;
@@ -528,30 +544,41 @@ function um_field_conditions_are_met( $data ) {
}
break;
case 'contains':
- if ( strstr( $field, $val ) ) {
- $state = 'hide';
+ $match = true;
+ if ( is_array( $field ) ) {
+ foreach ( $field as $item ) {
+ if ( is_string( $item ) && false !== strpos( $item, $val ) ) {
+ $match = false;
+ break;
+ }
+ }
} else {
- $state = 'not_hide';
+ if ( false !== strpos( $field, $val ) ) {
+ $match = false;
+ }
}
+
+ $state = $match ? 'not_hide' : 'hide';
+
break;
}
}
if ( isset( $state_array[ $count ] ) ) {
- if ( $state_array[ $count ] == 'show' || $state_array[ $count ] == 'not_hide' ) {
- if ( $state == 'show' || $state == 'not_hide' ) {
+ if ( 'show' === $state_array[ $count ] || 'not_hide' === $state_array[ $count ] ) {
+ if ( 'show' === $state || 'not_hide' === $state ) {
$state_array[ $count ] = 'show';
} else {
$state_array[ $count ] = 'hide';
}
} else {
- if ( $state == 'hide' || $state == 'not_show' ) {
+ if ( 'hide' === $state || 'not_show' === $state ) {
$state_array[ $count ] = 'hide';
} else {
$state_array[ $count ] = 'hide';
}
}
} else {
- if ( $state == 'show' || $state == 'not_hide' ) {
+ if ( 'show' === $state || 'not_hide' === $state ) {
$state_array[ $count ] = 'show';
} else {
$state_array[ $count ] = 'hide';
@@ -559,10 +586,9 @@ function um_field_conditions_are_met( $data ) {
}
}
-
}
$result = array_unique( $state_array );
- if ( ! in_array( 'show', $result ) ) {
+ if ( ! in_array( 'show', $result, true ) ) {
return $state = false;
} else {
return $state = true;
@@ -2852,7 +2878,7 @@ function um_is_amp( $check_theme_support = true ) {
$is_amp = false;
if ( ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) ||
- ( function_exists( 'is_better_amp' ) && is_better_amp() ) ) {
+ ( function_exists( 'is_better_amp' ) && is_better_amp() ) ) {
$is_amp = true;
}
diff --git a/package.json b/package.json
index a7c73a87..546f2deb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ultimate-member",
- "version": "2.6.3",
+ "version": "2.10.6",
"author": {
"name": "Ultimate Member",
"email": "team@ultimatemember.com",
diff --git a/readme.txt b/readme.txt
index 5ac65f91..abe3d365 100644
--- a/readme.txt
+++ b/readme.txt
@@ -6,7 +6,7 @@ Tags: community, member, membership, user-profile, user-registration
Requires PHP: 7.0
Requires at least: 6.2
Tested up to: 6.8
-Stable tag: 2.10.5
+Stable tag: 2.10.6
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.txt
@@ -167,6 +167,30 @@ No specific extensions are needed. But we highly recommended keep active these P
IMPORTANT: PLEASE UPDATE THE PLUGIN TO AT LEAST VERSION 2.6.7 IMMEDIATELY. VERSION 2.6.7 PATCHES SECURITY PRIVILEGE ESCALATION VULNERABILITY. PLEASE SEE [THIS ARTICLE](https://docs.ultimatemember.com/article/1866-security-incident-update-and-recommended-actions) FOR MORE INFORMATION
+= 2.10.6 2025-09-30 =
+
+**Enhancements**
+
+* Added: Avoid caching of the UM Forms on the mobile devices via adding the nocache headers to the screens with UM Forms.
+* Added: Filter hook `um_get_empty_status_users_query_result` for changing default query on the different websites to optimize it.
+* Added: Filter hook `um_admin_settings_get_pages_list_args` for changing WP_Query arguments for getting pages visible in the dropdown fields in UM Settings.
+* Added: JS filter hook `um_admin_blocks_prefixes_excluded` for excluding 3rd-party Gutenberg blocks with predefined prefixes from UM restriction arguments.
+* Added: WebP file-extension support for UM uploader.
+* Added: `UM_LICENSE_REQUEST_DEBUG` constant for debugging license activation process when it's needed.
+* Added: `Extensions_Updater` class to standardize the upgrade process in UM extensions.
+* Added: Sanitize handlers `sanitize_array_key_int` and `sanitize_array_key` for making sanitize in UM extensions' settings.
+
+**Bugfixes**
+
+* Fixed: Changed the view and the edit user profile links in the comments section on the frontend.
+* Fixed: `Contains` conditional logic operand when value is array.
+* Fixed: Getting cover_size for displaying it in the member directory card.
+* Fixed: Filter's range for numeric-type fields to avoid getting the empty values.
+* Fixed: Integer validation for the 'start_of_week' WP native setting.
+* Fixed: Dependencies with Action Scheduler library.
+
+**Cached and optimized/minified assets(JS/CSS) must be flushed/re-generated after upgrade**
+
= 2.10.5 2025-06-25 =
**Enhancements**
diff --git a/ultimate-member.php b/ultimate-member.php
index cd65c785..74686686 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.10.5
+ * Version: 2.10.6
* Author: Ultimate Member
* Author URI: http://ultimatemember.com/
* License: GPLv3
@@ -35,6 +35,7 @@ define( 'UM_PLUGIN', plugin_basename( __FILE__ ) );
define( 'UM_VERSION', $plugin_data['Version'] );
define( 'UM_PLUGIN_NAME', $plugin_data['Name'] );
define( 'UM_WP_FUNCTIONS_VERSION', '6.8.0' ); // Updates every major WordPress release.
+define( 'UM_LICENSE_REQUEST_DEBUG', false ); // Set true then need to debug the license request.
// define( 'UM_DEV_MODE', true );
require_once 'includes/class-functions.php';