mirror of
https://github.com/10h30/ultimatemember.git
synced 2026-07-11 10:46:11 +09:00
Merge pull request #1714 from ultimatemember/development/2.9.x
Version 2.10.6
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
"step": "installPlugin",
|
||||
"pluginZipFile": {
|
||||
"resource": "url",
|
||||
"url": "https:\/\/downloads.wordpress.org\/plugin\/ultimate-member.2.10.5.zip"
|
||||
"url": "https:\/\/downloads.wordpress.org\/plugin\/ultimate-member.2.10.6.zip"
|
||||
},
|
||||
"options": {
|
||||
"activate": true
|
||||
|
||||
@@ -44,7 +44,7 @@ GNU Version 2 or Any Later Version
|
||||
|
||||
### 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
|
||||
|
||||
[Official Release Version: 2.10.5](https://github.com/ultimatemember/ultimatemember/releases/tag/2.10.5).
|
||||
[Official Release Version: 2.10.6](https://github.com/ultimatemember/ultimatemember/releases/tag/2.10.6).
|
||||
|
||||
## Changelog
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
margin: 0 0 5px 0;
|
||||
display: inline-block;
|
||||
}
|
||||
.um-form-table.um-top-label .um-forms-line td select.um-forms-field.um-pages-select2 ~ .select2-container {
|
||||
width: 100% !important;
|
||||
}
|
||||
.um-form-table.um-top-label .um-forms-line[data-field_type=icon] td label {
|
||||
width: 100%;
|
||||
display: block;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -85,6 +85,9 @@
|
||||
margin: 0 0 5px 0
|
||||
display: inline-block
|
||||
//font-weight: bold
|
||||
select.#{$prefix}forms-field.#{$prefix}pages-select2
|
||||
& ~ .select2-container
|
||||
width: 100% !important
|
||||
|
||||
&[data-field_type="icon"]
|
||||
td
|
||||
|
||||
@@ -9,6 +9,20 @@ function um_admin_blocks_custom_fields( um_condition_fields, props ) {
|
||||
return wp.hooks.applyFilters( 'um_admin_blocks_custom_fields', [], um_condition_fields, props );
|
||||
}
|
||||
function um_add_restriction_attributes( settings, name ) {
|
||||
// Some blocks have a strict attribute scheme.
|
||||
// They reject any attributes that were not originally defined in them.
|
||||
// When the editor tries to render such a block, the server sees an unfamiliar
|
||||
// attribute um_is_restrict and returns a 400 error, prohibiting "foreign" properties.
|
||||
let excludedPrefixes = [
|
||||
'llms/'
|
||||
];
|
||||
excludedPrefixes = wp.hooks.applyFilters( 'um_admin_blocks_prefixes_excluded', excludedPrefixes, settings, name );
|
||||
|
||||
// Check the blocklist of prefixes.
|
||||
if ( excludedPrefixes.some( prefix => name.startsWith( prefix ) ) ) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
// add attributes for all blocks
|
||||
const restrictionAttributes = {
|
||||
um_is_restrict: {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
var um_components=wp.components,umSelectControl=um_components.SelectControl,umTextareaControl=um_components.TextareaControl;function um_admin_blocks_custom_fields(e,t){return wp.hooks.applyFilters("um_admin_blocks_custom_fields",[],e,t)}function um_add_restriction_attributes(e,t){return e.attributes=Object.assign(e.attributes,{um_is_restrict:{type:"boolean",default:!1},um_who_access:{type:"string",default:"0"},um_roles_access:{type:"array",default:[]},um_message_type:{type:"string",default:"0"},um_message_content:{type:"string",default:""}}),e}wp.hooks.addFilter("blocks.registerBlockType","um-block/add-restriction-attributes",um_add_restriction_attributes);var um_block_restriction=wp.compose.createHigherOrderComponent(function(s){var _={um_who_access:"um_block_settings_hide",um_roles_access:"um_block_settings_hide",um_message_type:"um_block_settings_hide",um_message_content:"um_block_settings_hide"},_=wp.hooks.applyFilters("um_admin_blocks_condition_fields_default",_);return function(t){var e=void 0!==t.attributes.um_is_restrict&&t.attributes.um_is_restrict;return!0!==t.attributes.um_is_restrict?(_.um_who_access="um_block_settings_hide",_.um_roles_access="um_block_settings_hide",_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide"):(_.um_who_access="",0===parseInt(t.attributes.um_who_access)||void 0===t.attributes.um_who_access?(_.um_roles_access="um_block_settings_hide",_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide"):(1===parseInt(t.attributes.um_who_access)&&(_.um_roles_access=""),_.um_message_type="",2===parseInt(t.attributes.um_message_type)?_.um_message_content="":_.um_message_content="um_block_settings_hide")),_=wp.hooks.applyFilters("um_admin_blocks_condition_fields",_,t),wp.element.createElement(wp.element.Fragment,{},wp.element.createElement(s,t),wp.element.createElement(wp.blockEditor.InspectorControls,{},wp.element.createElement(wp.components.PanelBody,{title:wp.i18n.__("Ultimate Member: Content Restriction","ultimate-member"),className:"um_block_settings"},wp.element.createElement(wp.components.ToggleControl,{label:wp.i18n.__("Restrict access?","ultimate-member"),checked:e,onChange:function(e){t.setAttributes({um_is_restrict:e}),!1===e?(_.um_who_access="um_block_settings_hide",_.um_roles_access="um_block_settings_hide",_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide"):_.um_who_access="",_=wp.hooks.applyFilters("um_admin_blocks_condition_fields_on_change",_,"um_is_restrict",e)}}),wp.element.createElement(umSelectControl,{type:"number",className:_.um_who_access,label:wp.i18n.__("Who can access this block?","ultimate-member"),value:t.attributes.um_who_access,options:[{label:wp.i18n.__("Everyone","ultimate-member"),value:0},{label:wp.i18n.__("Logged in users","ultimate-member"),value:1},{label:wp.i18n.__("Logged out users","ultimate-member"),value:2}],onChange:function(e){t.setAttributes({um_who_access:e}),0===parseInt(e)?(_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide",_.um_roles_access="um_block_settings_hide"):1===parseInt(e)?(_.um_message_type="",_.um_roles_access=""):(_.um_message_type="",_.um_roles_access="um_block_settings_hide"),_=wp.hooks.applyFilters("um_admin_blocks_condition_fields_on_change",_,"um_who_access",e)}}),wp.element.createElement(umSelectControl,{multiple:!0,className:_.um_roles_access,label:wp.i18n.__("What roles can access this block?","ultimate-member"),value:t.attributes.um_roles_access,options:um_restrict_roles,onChange:function(e){t.setAttributes({um_roles_access:e})}}),wp.element.createElement(umSelectControl,{type:"number",className:_.um_message_type,label:wp.i18n.__("Restriction action","ultimate-member"),value:t.attributes.um_message_type,options:[{label:wp.i18n.__("Hide block","ultimate-member"),value:0},{label:wp.i18n.__("Show global default message","ultimate-member"),value:1},{label:wp.i18n.__("Show custom message","ultimate-member"),value:2}],onChange:function(e){t.setAttributes({um_message_type:e}),2===parseInt(e)?_.um_message_content="":_.um_message_content="um_block_settings_hide"}}),wp.element.createElement(umTextareaControl,{type:"number",className:_.um_message_content,label:wp.i18n.__("Custom restricted access message","ultimate-member"),value:t.attributes.um_message_content,onChange:function(e){t.setAttributes({um_message_content:e})}}),um_admin_blocks_custom_fields(_,t))))}},"um_block_restriction");wp.hooks.addFilter("editor.BlockEdit","um-block/um_block_restriction",um_block_restriction);
|
||||
var um_components=wp.components,umSelectControl=um_components.SelectControl,umTextareaControl=um_components.TextareaControl;function um_admin_blocks_custom_fields(e,t){return wp.hooks.applyFilters("um_admin_blocks_custom_fields",[],e,t)}function um_add_restriction_attributes(e,t){var s=["llms/"];return(s=wp.hooks.applyFilters("um_admin_blocks_prefixes_excluded",s,e,t)).some(e=>t.startsWith(e))||(e.attributes=Object.assign(e.attributes,{um_is_restrict:{type:"boolean",default:!1},um_who_access:{type:"string",default:"0"},um_roles_access:{type:"array",default:[]},um_message_type:{type:"string",default:"0"},um_message_content:{type:"string",default:""}})),e}wp.hooks.addFilter("blocks.registerBlockType","um-block/add-restriction-attributes",um_add_restriction_attributes);var um_block_restriction=wp.compose.createHigherOrderComponent(function(s){var _={um_who_access:"um_block_settings_hide",um_roles_access:"um_block_settings_hide",um_message_type:"um_block_settings_hide",um_message_content:"um_block_settings_hide"},_=wp.hooks.applyFilters("um_admin_blocks_condition_fields_default",_);return function(t){var e=void 0!==t.attributes.um_is_restrict&&t.attributes.um_is_restrict;return!0!==t.attributes.um_is_restrict?(_.um_who_access="um_block_settings_hide",_.um_roles_access="um_block_settings_hide",_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide"):(_.um_who_access="",0===parseInt(t.attributes.um_who_access)||void 0===t.attributes.um_who_access?(_.um_roles_access="um_block_settings_hide",_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide"):(1===parseInt(t.attributes.um_who_access)&&(_.um_roles_access=""),_.um_message_type="",2===parseInt(t.attributes.um_message_type)?_.um_message_content="":_.um_message_content="um_block_settings_hide")),_=wp.hooks.applyFilters("um_admin_blocks_condition_fields",_,t),wp.element.createElement(wp.element.Fragment,{},wp.element.createElement(s,t),wp.element.createElement(wp.blockEditor.InspectorControls,{},wp.element.createElement(wp.components.PanelBody,{title:wp.i18n.__("Ultimate Member: Content Restriction","ultimate-member"),className:"um_block_settings"},wp.element.createElement(wp.components.ToggleControl,{label:wp.i18n.__("Restrict access?","ultimate-member"),checked:e,onChange:function(e){t.setAttributes({um_is_restrict:e}),!1===e?(_.um_who_access="um_block_settings_hide",_.um_roles_access="um_block_settings_hide",_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide"):_.um_who_access="",_=wp.hooks.applyFilters("um_admin_blocks_condition_fields_on_change",_,"um_is_restrict",e)}}),wp.element.createElement(umSelectControl,{type:"number",className:_.um_who_access,label:wp.i18n.__("Who can access this block?","ultimate-member"),value:t.attributes.um_who_access,options:[{label:wp.i18n.__("Everyone","ultimate-member"),value:0},{label:wp.i18n.__("Logged in users","ultimate-member"),value:1},{label:wp.i18n.__("Logged out users","ultimate-member"),value:2}],onChange:function(e){t.setAttributes({um_who_access:e}),0===parseInt(e)?(_.um_message_type="um_block_settings_hide",_.um_message_content="um_block_settings_hide",_.um_roles_access="um_block_settings_hide"):1===parseInt(e)?(_.um_message_type="",_.um_roles_access=""):(_.um_message_type="",_.um_roles_access="um_block_settings_hide"),_=wp.hooks.applyFilters("um_admin_blocks_condition_fields_on_change",_,"um_who_access",e)}}),wp.element.createElement(umSelectControl,{multiple:!0,className:_.um_roles_access,label:wp.i18n.__("What roles can access this block?","ultimate-member"),value:t.attributes.um_roles_access,options:um_restrict_roles,onChange:function(e){t.setAttributes({um_roles_access:e})}}),wp.element.createElement(umSelectControl,{type:"number",className:_.um_message_type,label:wp.i18n.__("Restriction action","ultimate-member"),value:t.attributes.um_message_type,options:[{label:wp.i18n.__("Hide block","ultimate-member"),value:0},{label:wp.i18n.__("Show global default message","ultimate-member"),value:1},{label:wp.i18n.__("Show custom message","ultimate-member"),value:2}],onChange:function(e){t.setAttributes({um_message_type:e}),2===parseInt(e)?_.um_message_content="":_.um_message_content="um_block_settings_hide"}}),wp.element.createElement(umTextareaControl,{type:"number",className:_.um_message_content,label:wp.i18n.__("Custom restricted access message","ultimate-member"),value:t.attributes.um_message_content,onChange:function(e){t.setAttributes({um_message_content:e})}}),um_admin_blocks_custom_fields(_,t))))}},"um_block_restriction");wp.hooks.addFilter("editor.BlockEdit","um-block/um_block_restriction",um_block_restriction);
|
||||
@@ -105,10 +105,12 @@ function um_admin_init_pages_select() {
|
||||
dataType: 'json',
|
||||
delay: 250, // delay in ms while typing when to perform a AJAX search
|
||||
data: function( params ) {
|
||||
let fieldID = jQuery(this).attr('id');
|
||||
return {
|
||||
search: params.term, // search query
|
||||
action: 'um_get_pages_list', // AJAX action for admin-ajax.php
|
||||
page: params.page || 1, // infinite scroll pagination
|
||||
field_id: fieldID, // select ID
|
||||
nonce: um_admin_scripts.nonce
|
||||
};
|
||||
},
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,5 +1,29 @@
|
||||
== Changelog ==
|
||||
|
||||
= 2.10.6 September 30, 2025 =
|
||||
|
||||
* 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 June 25, 2025 =
|
||||
|
||||
* Enhancements:
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
"ext-iconv": "*",
|
||||
"ext-tidy": "*",
|
||||
"composer/installers": "^2.3",
|
||||
"woocommerce/action-scheduler": "3.9.2"
|
||||
"woocommerce/action-scheduler": "3.9.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"wp-cli/wp-cli": "*",
|
||||
|
||||
@@ -1405,6 +1405,13 @@ if ( ! class_exists( 'um\admin\Admin' ) ) {
|
||||
$sanitized[ $k ] = ( '' !== $v ) ? absint( $v ) : '';
|
||||
}
|
||||
break;
|
||||
case 'sanitize_array_key_int':
|
||||
if ( ! array_key_exists( 'default', $this->builder_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 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace um\admin;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles all functions that changes data structures and moving files
|
||||
*/
|
||||
class Extensions_Updater {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $updater_data;
|
||||
|
||||
/**
|
||||
* @param false|array $args
|
||||
*/
|
||||
public function __construct( $args = false ) {
|
||||
if ( empty( $args ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->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 );
|
||||
}
|
||||
}
|
||||
@@ -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 = ' <a href="' . esc_url( add_query_arg( array( 'um_adm_action' => 'install_predefined_page', 'um_page_slug' => $slug, '_wpnonce' => wp_create_nonce( 'install_predefined_page' ), ) ) ) . '" class="button button-primary">' . esc_html__( 'Create Default', 'ultimate-member' ) . '</a>';
|
||||
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 = ' <a href="' . esc_url( add_query_arg( array( 'um_adm_action' => 'install_predefined_page', 'um_page_slug' => $slug, '_wpnonce' => wp_create_nonce( 'install_predefined_page' ), ) ) ) . '" class="button button-primary">' . esc_html__( 'Create Default', 'ultimate-member' ) . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
$html = "$hidden<select $multiple $id_attr $name_attr $class_attr $data_attr>$options</select>$button";
|
||||
|
||||
@@ -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 ) ) {
|
||||
|
||||
@@ -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 ] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace um\ajax;
|
||||
|
||||
use WP_Query;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
@@ -23,7 +25,7 @@ class Pages {
|
||||
* AJAX callback for getting the pages list
|
||||
*/
|
||||
public function get_pages_list() {
|
||||
UM()->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() ) {
|
||||
|
||||
@@ -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',
|
||||
|
||||
+137
-17
@@ -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':
|
||||
|
||||
@@ -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' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <caption>Customize the empty status users query.</caption>
|
||||
* 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 ) {
|
||||
|
||||
@@ -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' ) ) {
|
||||
|
||||
@@ -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'] );
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace um\frontend;
|
||||
|
||||
use WP_Comment;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
@@ -19,6 +21,8 @@ if ( ! class_exists( 'um\frontend\User_Profile' ) ) {
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'template_redirect', array( $this, 'handle_edit_screen' ), 10000 );
|
||||
add_filter( 'get_edit_user_link', array( $this, 'change_edit_user_link' ), 10, 2 );
|
||||
add_filter( 'get_comment_author_url', array( $this, 'change_comment_author_url' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,6 +34,7 @@ if ( ! class_exists( 'um\frontend\User_Profile' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification
|
||||
if ( ! isset( $_REQUEST['um_action'] ) ) {
|
||||
return;
|
||||
}
|
||||
@@ -44,6 +49,7 @@ if ( ! class_exists( 'um\frontend\User_Profile' ) ) {
|
||||
if ( isset( $_REQUEST['uid'] ) ) {
|
||||
$uid = absint( $_REQUEST['uid'] );
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification
|
||||
|
||||
if ( ! empty( $uid ) && ! UM()->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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ultimate-member",
|
||||
"version": "2.6.3",
|
||||
"version": "2.10.6",
|
||||
"author": {
|
||||
"name": "Ultimate Member",
|
||||
"email": "team@ultimatemember.com",
|
||||
|
||||
+25
-1
@@ -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**
|
||||
|
||||
+2
-1
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user