Merge branch 'development/2.6.1' into feature/um-blocks

This commit is contained in:
Nikita Sinelnikov
2023-05-23 11:14:37 +03:00
committed by GitHub
77 changed files with 2712 additions and 1488 deletions
+20 -15
View File
@@ -13,33 +13,44 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
*/
class Builtin {
/**
* @var array
*/
public $predefined_fields = array();
/**
* @var array
*/
public $all_user_fields = array();
/**
* @var array
*/
var $all_user_fields = array();
public $core_fields = array();
/**
* @var array
*/
var $core_fields = array();
public $saved_fields = array();
/**
* @var array
*/
public $custom_fields = array();
/**
* @var array
*/
public $fields_dropdown = array();
/**
* Builtin constructor.
*/
function __construct() {
public function __construct() {
add_action( 'init', array( &$this, 'set_core_fields' ), 1 );
add_action( 'init', array( &$this, 'set_predefined_fields' ), 1 );
add_action( 'init', array( &$this, 'set_custom_fields' ), 1 );
$this->saved_fields = get_option( 'um_fields' );
$this->saved_fields = get_option( 'um_fields', array() );
}
@@ -1337,26 +1348,20 @@ if ( ! class_exists( 'um\core\Builtin' ) ) {
* Custom Fields
*/
function set_custom_fields() {
if ( is_array( $this->saved_fields ) ) {
$this->custom_fields = $this->saved_fields;
} else {
$this->custom_fields = '';
$this->custom_fields = array();
}
$custom = $this->custom_fields;
$custom = $this->custom_fields;
$predefined = $this->predefined_fields;
if ( is_array( $custom ) ){
if ( is_array( $custom ) ) {
$this->all_user_fields = array_merge( $predefined, $custom );
} else {
$this->all_user_fields = $predefined;
}
}
+45 -8
View File
@@ -18,7 +18,7 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
/**
* @var string
*/
var $set_mode = '';
public $set_mode = '';
/**
@@ -26,17 +26,53 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
*/
public $set_id = null;
/**
* @var bool
*/
public $editing = false;
/**
* @var bool
*/
public $viewing = false;
/**
* @var int
*/
public $timestamp = null;
/**
* @var array
*/
public $global_args = array();
/**
* @var array
*/
public $field_icons = array();
/**
* @var array
*/
public $get_fields = array();
/**
* @var array
*/
public $rows = array();
/**
* @var array
*/
public $fields = array();
/**
* Fields constructor.
*/
function __construct() {
$this->editing = false;
$this->viewing = false;
public function __construct() {
$this->timestamp = current_time( 'timestamp' );
}
/**
* Standard checkbox field
*
@@ -248,7 +284,7 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
$fields = UM()->query()->get_attr( 'custom_fields', $form_id );
if ( isset( $fields[ $id ] ) ) {
$condition_fields = get_option( 'um_fields' );
$condition_fields = get_option( 'um_fields', array() );
if( ! is_array( $condition_fields ) ) $condition_fields = array();
@@ -2390,8 +2426,9 @@ if ( ! class_exists( 'um\core\Fields' ) ) {
}
$field_name = $key . $form_suffix;
$field_value = htmlspecialchars( $this->field_value( $key, $default, $data ) );
$field_name = $key . $form_suffix;
$field_value = $this->field_value( $key, $default, $data );
$field_value = ! is_null( $field_value ) ? htmlspecialchars( $field_value ) : null;
$output .= '<input ' . $disabled . ' autocomplete="' . esc_attr( $autocomplete ) . '" class="' . $this->get_class( $key, $data ) . '" type="' . esc_attr( $input ) . '" name="' . esc_attr( $field_name ) . '" id="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_value ) . '" placeholder="' . esc_attr( $placeholder ) . '" data-validate="' . esc_attr( $validate ) . '" data-key="' . esc_attr( $key ) . '" />
+25 -12
View File
@@ -13,30 +13,45 @@ if ( ! class_exists( 'um\core\Files' ) ) {
*/
class Files {
/**
* @var
*/
public $upload_temp;
/**
* @var
*/
var $upload_temp;
public $upload_baseurl;
/**
* @var
*/
var $upload_baseurl;
public $upload_basedir;
/**
* @var
* @var array|array[]
*/
var $upload_basedir;
public $fonticon = array();
/**
* @var null|string
*/
public $upload_dir = null;
/**
* @var null
*/
public $upload_temp_url = null;
/**
* @var string
*/
public $default_file_fonticon = 'um-faicon-file-o';
/**
* Files constructor.
*/
function __construct() {
public function __construct() {
$this->setup_paths();
add_action( 'template_redirect', array( &$this, 'download_routing' ), 1 );
@@ -63,8 +78,6 @@ if ( ! class_exists( 'um\core\Files' ) ) {
'tif' => array('icon' => 'um-icon-image' ),
'tiff' => array('icon' => 'um-icon-image' ),
);
$this->default_file_fonticon = 'um-faicon-file-o';
}
@@ -326,8 +339,8 @@ if ( ! class_exists( 'um\core\Files' ) ) {
$user_id = empty( $_REQUEST['user_id'] ) ? get_current_user_id() : absint( $_REQUEST['user_id'] );
UM()->fields()->set_id = filter_input( INPUT_POST, 'set_id', FILTER_SANITIZE_NUMBER_INT );
UM()->fields()->set_mode = filter_input( INPUT_POST, 'set_mode', FILTER_SANITIZE_STRING );
UM()->fields()->set_id = isset( $_POST['set_id'] ) ? absint( $_POST['set_id'] ) : null;
UM()->fields()->set_mode = isset( $_POST['set_mode'] ) ? sanitize_text_field( $_POST['set_mode'] ) : null;
if ( UM()->fields()->set_mode != 'register' && ! UM()->roles()->um_current_user_can( 'edit', $user_id ) ) {
$ret['error'] = esc_js( __( 'You have no permission to edit this user', 'ultimate-member' ) );
+21 -17
View File
@@ -13,43 +13,47 @@ if ( ! class_exists( 'um\core\Form' ) ) {
*/
class Form {
/**
* @var null
*/
public $form_suffix;
public $form_suffix = null;
/**
* @var
*/
var $form_id;
public $form_id;
/**
* @var null
*/
var $post_form = null;
public $post_form = null;
/**
* @var null
*/
public $nonce = null;
var $nonce = null;
/**
* @var null
*/
public $errors = null;
/**
* @var null
*/
public $processing = null;
/**
* @var array
*/
public $all_fields = array();
/**
* Form constructor.
*/
function __construct() {
$this->form_suffix = null;
$this->errors = null;
$this->processing = null;
public function __construct() {
add_action( 'template_redirect', array( &$this, 'form_init' ), 2 );
add_action( 'init', array( &$this, 'field_declare' ), 10 );
}
+38 -24
View File
@@ -1,37 +1,53 @@
<?php
namespace um\core;
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'um\core\Mail' ) ) {
/**
* Class Mail
* @package um\core
*/
class Mail {
/**
* @var array
*/
public $email_templates = array();
/**
* @var array
*/
var $email_templates = array();
public $path_by_slug = array();
/**
* @var array
*/
var $path_by_slug = array();
public $attachments = array();
/**
* @var string
*/
public $headers = '';
/**
* @var string
*/
public $subject = '';
/**
* @var string
*/
public $message = '';
/**
* Mail constructor.
*/
function __construct() {
public function __construct() {
//mandrill compatibility
add_filter( 'mandrill_nl2br', array( &$this, 'mandrill_nl2br' ) );
add_action( 'plugins_loaded', array( &$this, 'init_paths' ), 99 );
@@ -349,12 +365,10 @@ if ( ! class_exists( 'um\core\Mail' ) ) {
}
echo $plain_email_template;
}
$message = ob_get_clean();
/**
* UM hook
*
@@ -387,7 +401,6 @@ if ( ! class_exists( 'um\core\Mail' ) ) {
return um_convert_tags( $message, $args );
}
/**
* Send Email function
*
@@ -395,20 +408,27 @@ if ( ! class_exists( 'um\core\Mail' ) ) {
* @param null $template
* @param array $args
*/
function send( $email, $template, $args = array() ) {
public function send( $email, $template, $args = array() ) {
if ( ! is_email( $email ) ) {
return;
}
if ( UM()->options()->get( $template . '_on' ) != 1 ) {
if ( ! empty( UM()->options()->get( $template . '_on' ) ) ) {
return;
}
$hook_disabled = apply_filters( 'um_disable_email_notification_sending', false, $email, $template, $args );
if ( false !== $hook_disabled ) {
return;
}
do_action( 'um_before_email_notification_sending', $email, $template, $args );
$this->attachments = array();
$this->headers = 'From: '. stripslashes( UM()->options()->get('mail_from') ) .' <'. UM()->options()->get('mail_from_addr') .'>' . "\r\n";
$this->headers = 'From: ' . stripslashes( UM()->options()->get( 'mail_from' ) ) . ' <' . UM()->options()->get( 'mail_from_addr' ) . '>' . "\r\n";
add_filter( 'um_template_tags_patterns_hook', array( UM()->mail(), 'add_placeholder' ), 10, 1 );
add_filter( 'um_template_tags_replaces_hook', array( UM()->mail(), 'add_replace_placeholder' ), 10, 1 );
/**
* UM hook
@@ -432,15 +452,10 @@ if ( ! class_exists( 'um\core\Mail' ) ) {
* }
* ?>
*/
add_filter( 'um_template_tags_patterns_hook', array( UM()->mail(), 'add_placeholder' ), 10, 1 );
add_filter( 'um_template_tags_replaces_hook', array( UM()->mail(), 'add_replace_placeholder' ), 10, 1 );
$subject = apply_filters( 'um_email_send_subject', UM()->options()->get( $template . '_sub' ), $template );
$subject = wp_unslash( um_convert_tags( $subject, $args ) );
$subject = wp_unslash( um_convert_tags( $subject , $args ) );
$this->subject = html_entity_decode( $subject, ENT_QUOTES, 'UTF-8' );
$this->subject = html_entity_decode( $subject, ENT_QUOTES, 'UTF-8' );
$this->message = $this->prepare_template( $template, $args );
@@ -456,7 +471,6 @@ if ( ! class_exists( 'um\core\Mail' ) ) {
do_action( 'um_after_email_notification_sending', $email, $template, $args );
}
/**
* @param $template_name
*
+21 -1
View File
@@ -634,13 +634,16 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
if ( isset( $_GET[ 'filter_' . $attrs['parent_dropdown_relationship'] . '_' . $unique_hash ] ) ) {
$_POST['parent_option_name'] = $attrs['parent_dropdown_relationship'];
$_POST['parent_option'] = explode( '||', filter_input( INPUT_GET, 'filter_' . $attrs['parent_dropdown_relationship'] . '_' . $unique_hash ) );
$parent_option_value = sanitize_text_field( $_GET[ 'filter_' . $attrs['parent_dropdown_relationship'] . '_' . $unique_hash ] );
$_POST['parent_option'] = explode( '||', $parent_option_value );
}
}
$attrs['custom_dropdown_options_source'] = wp_unslash( $attrs['custom_dropdown_options_source'] );
$ajax_source = apply_filters( "um_custom_dropdown_options_source__{$filter}", $attrs['custom_dropdown_options_source'], $attrs );
$custom_dropdown .= ' data-um-ajax-source="' . esc_attr( $ajax_source ) . '" ';
$attrs['options'] = UM()->fields()->get_options_from_callback( $attrs, $attrs['type'] );
@@ -1580,6 +1583,17 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$meta_value = '%' . $wpdb->esc_like( $search ) . '%';
$search_meta = $wpdb->prepare( '%s', $meta_value );
preg_match( '~(?<=\{)(.*?)(?=\})~', $search_meta, $matches, PREG_OFFSET_CAPTURE, 0 );
// workaround for standard mySQL hashes which are used by $wpdb->prepare instead of the %symbol
// sometimes it breaks error for strings like that wp_postmeta.meta_value LIKE '{12f209b48a89eeab33424902879d05d503f251ca8812dde03b59484a2991dc74}AMS{12f209b48a89eeab33424902879d05d503f251ca8812dde03b59484a2991dc74}'
// {12f209b48a89eeab33424902879d05d503f251ca8812dde03b59484a2991dc74} isn't applied by the `preg_replace()` below
if ( $matches[0][0] ) {
$search_meta = str_replace( '{' . $matches[0][0] . '}', '#%&', $search_meta );
$sql['where'] = str_replace( '{' . $matches[0][0] . '}', '#%&', $sql['where'] );
}
// str_replace( '/', '\/', wp_slash( $search_meta ) ) means that we add backslashes to special symbols + add backslash to slash(/) symbol for proper regular pattern.
preg_match(
'/^(.*).meta_value LIKE ' . str_replace( '/', '\/', wp_slash( $search_meta ) ) . '[^\)]/im',
@@ -1587,12 +1601,18 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$join_matches
);
$sql['where'] = str_replace( '#%&', '{' . $matches[0][0] . '}', $sql['where'] );
if ( isset( $join_matches[1] ) ) {
$meta_join_for_search = trim( $join_matches[1] );
// skip private invisible fields
$custom_fields = array();
foreach ( array_keys( UM()->builtin()->all_user_fields ) as $field_key ) {
if ( empty( $field_key ) ) {
continue;
}
$data = UM()->fields()->get_field( $field_key );
if ( ! um_can_view_field( $data ) ) {
continue;
+5
View File
@@ -31,6 +31,11 @@ if ( ! class_exists( 'um\core\Profile' ) ) {
*/
var $active_tab;
/**
* @var null
*/
public $active_subnav = null;
/**
* Profile constructor.
+43 -13
View File
@@ -1,30 +1,62 @@
<?php
namespace um\core;
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'um\core\Shortcodes' ) ) {
/**
* Class Shortcodes
* @package um\core
*/
class Shortcodes {
var $profile_role = '';
/**
* @var string
*/
public $profile_role = '';
/**
* @var bool
*/
public $message_mode = false;
/**
* @var string
*/
public $custom_message = '';
/**
* @var array
*/
public $loop = array();
/**
* @var array
*/
public $emoji = array();
/**
* @var null|int
*/
public $form_id = null;
/**
* @var null|string
*/
public $form_status = null;
/**
* @var array
*/
public $set_args = array();
/**
* Shortcodes constructor.
*/
function __construct() {
$this->message_mode = false;
$this->custom_message = '';
$this->loop = array();
public function __construct() {
add_shortcode( 'ultimatemember', array( &$this, 'ultimatemember' ) );
add_shortcode( 'ultimatemember_login', array( &$this, 'ultimatemember_login' ) );
@@ -123,10 +155,8 @@ if ( ! class_exists( 'um\core\Shortcodes' ) ) {
$this->emoji[':innocent:'] = $base_uri . '72x72/1f607.png';
$this->emoji[':smirk:'] = $base_uri . '72x72/1f60f.png';
$this->emoji[':expressionless:'] = $base_uri . '72x72/1f611.png';
}
/**
* Conditional logout form
*
+72 -24
View File
@@ -22,35 +22,86 @@ if ( ! class_exists( 'um\core\User' ) ) {
*/
public $previous_data = null;
/**
* @var int
*/
public $id = 0;
/**
* @var null
*/
public $usermeta = null;
/**
* @var null
*/
public $data = null;
/**
* @var null
*/
public $profile = null;
/**
* @var null
*/
public $cannot_edit = null;
/**
* @var null
*/
public $deleted_user_id = null;
/**
* @var array|string[]
*/
public $banned_keys = array();
/**
* @var bool
*/
public $preview = false;
/**
* @var bool
*/
public $send_mail_on_delete = true;
/**
* A list of keys that should never be in wp_usermeta.
* @var array|string[]
*/
public $update_user_keys = array();
/**
* @var null
*/
public $target_id = null;
/**
* User constructor.
*/
function __construct() {
$this->id = 0;
$this->usermeta = null;
$this->data = null;
$this->profile = null;
$this->cannot_edit = null;
$this->deleted_user_id = null;
public function __construct() {
global $wpdb;
$this->banned_keys = array(
'metabox','postbox','meta-box',
'dismissed_wp_pointers', 'session_tokens',
'screen_layout', 'wp_user-', 'dismissed',
'cap_key', $wpdb->get_blog_prefix(). 'capabilities',
'managenav', 'nav_menu', 'user_activation_key',
'level_', $wpdb->get_blog_prefix() . 'user_level'
'metabox',
'postbox',
'meta-box',
'dismissed_wp_pointers',
'session_tokens',
'screen_layout',
'wp_user-',
'dismissed',
'cap_key',
$wpdb->get_blog_prefix() . 'capabilities',
'managenav',
'nav_menu',
'user_activation_key',
'level_',
$wpdb->get_blog_prefix() . 'user_level',
);
add_action( 'init', array( &$this, 'set' ), 1 );
$this->preview = false;
$this->send_mail_on_delete = true;
// a list of keys that should never be in wp_usermeta
$this->update_user_keys = array(
'user_email',
@@ -61,7 +112,7 @@ if ( ! class_exists( 'um\core\User' ) ) {
'role',
);
$this->target_id = null;
add_action( 'init', array( &$this, 'set' ), 1 );
// When the cache should be cleared
add_action( 'um_delete_user', array( &$this, 'remove_cache' ), 10, 1 );
@@ -88,7 +139,6 @@ if ( ! class_exists( 'um\core\User' ) ) {
add_action( 'user_register', array( &$this, 'user_register_via_admin' ), 10, 1 );
add_action( 'user_register', array( &$this, 'set_gravatar' ), 11, 1 );
if ( is_multisite() ) {
add_action( 'added_existing_user', array( &$this, 'add_um_role_existing_user' ), 10, 2 );
add_action( 'wpmu_activate_user', array( &$this, 'add_um_role_wpmu_new_user' ), 10, 1 );
@@ -102,13 +152,11 @@ if ( ! class_exists( 'um\core\User' ) ) {
add_action( 'delete_user', array( &$this, 'delete_user_handler' ), 10, 1 );
}
add_action( 'updated_user_meta', array( &$this, 'on_update_usermeta' ), 10, 4 );
add_action( 'added_user_meta', array( &$this, 'on_update_usermeta' ), 10, 4 );
add_action( 'deleted_user_meta', array( &$this, 'on_delete_usermeta' ), 10, 4 );
add_action( 'update_user_meta', array( &$this, 'flush_um_count_users_transient_update' ), 10, 4 );
add_action( 'added_user_meta', array( &$this, 'flush_um_count_users_transient_add' ), 10, 4 );
add_action( 'delete_user_meta', array( &$this, 'flush_um_count_users_transient_delete' ), 10, 4 );
+19 -10
View File
@@ -13,16 +13,25 @@ if ( ! class_exists( 'um\core\Validation' ) ) {
*/
class Validation {
/**
* @var string
*/
public $regex_safe = '/\A[\w\-\.]+\z/';
/**
* @var string
*/
public $regex_username_safe = '|[^a-z0-9 _.\-@]|i';
/**
* @var string
*/
public $regex_phone_number = '/\A[\d\-\.\+\(\)\ ]+\z/';
/**
* Validation constructor.
*/
function __construct() {
$this->regex_safe = '/\A[\w\-\.]+\z/';
$this->regex_username_safe = '|[^a-z0-9 _.\-@]|i';
$this->regex_phone_number = '/\A[\d\-\.\+\(\)\ ]+\z/';
public function __construct() {
add_filter( 'um_user_pre_updating_files_array', array( $this, 'validate_files' ), 10, 1 );
add_filter( 'um_before_save_filter_submitted', array( $this, 'validate_fields_values' ), 10, 2 );
}
@@ -91,7 +100,7 @@ if ( ! class_exists( 'um\core\Validation' ) ) {
}
// Dropdown options source from callback function
if ( in_array( $fields[ $key ]['type'], array( 'select','multiselect' ) ) &&
if ( in_array( $fields[ $key ]['type'], array( 'select','multiselect' ) ) &&
isset( $fields[ $key ]['custom_dropdown_options_source'] ) &&
! empty( $fields[ $key ]['custom_dropdown_options_source'] ) &&
function_exists( $fields[ $key ]['custom_dropdown_options_source'] ) ) {
@@ -100,7 +109,7 @@ if ( ! class_exists( 'um\core\Validation' ) ) {
$fields[ $key ]['options'] = array_keys( $arr_options );
}
}
// Unset changed value that doesn't match the option list
if ( in_array( $fields[ $key ]['type'], array( 'select' ) ) &&
! empty( $stripslashes ) && ! empty( $fields[ $key ]['options'] ) &&
@@ -297,10 +306,10 @@ if ( ! class_exists( 'um\core\Validation' ) ) {
if ( ! $string ) {
return true;
}
if ( substr_count( $string, '#' ) > 1 ) {
if ( strlen( $string ) < 2 || strlen( $string ) > 31 ) {
return false;
}
if ( ! preg_match( '/^(.+)#(\d+)$/', trim( $string ) ) ) {
if ( ! preg_match( '/^[a-z\d_]+(?:\.[a-z\d_]+)*(\.[a-z]*)?$/', trim( $string ) ) ) {
return false;
}
return true;
+2 -2
View File
@@ -71,7 +71,7 @@ function um_submit_form_errors_hook_login( $args ) {
if ( ! empty( $third_party_codes ) && in_array( $user->get_error_code(), $third_party_codes ) ) {
UM()->form()->add_error( $user->get_error_code(), $user->get_error_message() );
} else {
UM()->form()->add_error( $user->get_error_code(), __( 'Password is incorrect. Please try again.', 'ultimate-member' ) );
UM()->form()->add_error( 'user_password', __( 'Password is incorrect. Please try again.', 'ultimate-member' ) );
}
}
@@ -80,7 +80,7 @@ function um_submit_form_errors_hook_login( $args ) {
if ( ! empty( $third_party_codes ) && in_array( $user->get_error_code(), $third_party_codes ) ) {
UM()->form()->add_error( $user->get_error_code(), $user->get_error_message() );
} else {
UM()->form()->add_error( $user->get_error_code(), __( 'Password is incorrect. Please try again.', 'ultimate-member' ) );
UM()->form()->add_error( 'user_password', __( 'Password is incorrect. Please try again.', 'ultimate-member' ) );
}
}
+1 -1
View File
@@ -66,7 +66,7 @@ function um_dynamic_user_profile_title( $title, $id = '' ) {
return $title;
}
return ( strlen( $title ) !== mb_strlen( $title ) ) ? $title : utf8_encode( $title );
return ( strlen( $title ) !== mb_strlen( $title ) ) ? $title : mb_convert_encoding( $title, 'UTF-8' );
}
add_filter( 'the_title', 'um_dynamic_user_profile_title', 100000, 2 );