diff --git a/includes/core/class-account.php b/includes/core/class-account.php index 1128a08e..65df44e9 100644 --- a/includes/core/class-account.php +++ b/includes/core/class-account.php @@ -576,7 +576,7 @@ if ( ! class_exists( 'um\core\Account' ) ) { case 'privacy': - $args = 'profile_privacy,profile_noindex,hide_in_members'; + $args = 'profile_privacy,profile_noindex,hide_in_members,um_show_last_login'; /** * UM hook * diff --git a/includes/core/class-builtin.php b/includes/core/class-builtin.php index 4939fbd2..cf3b7958 100644 --- a/includes/core/class-builtin.php +++ b/includes/core/class-builtin.php @@ -1336,6 +1336,23 @@ if ( ! class_exists( 'um\core\Builtin' ) ) { 'required_opt' => array( 'members_page', true ), ), + 'um_show_last_login' => array( + 'title' => __( 'Show my last login?', 'ultimate-member' ), + 'metakey' => 'um_show_last_login', + 'type' => 'radio', + 'label' => __( 'Show my last login?', 'ultimate-member' ), + 'help' => __( 'Here you can hide last login field on profile page and card in member directory', 'ultimate-member' ), + 'required' => 0, + 'public' => 1, + 'editable' => true, + 'default' => 'yes', + 'options' => array( + 'no' => __( 'No', 'ultimate-member' ), + 'yes' => __( 'Yes', 'ultimate-member' ), + ), + 'account_only' => true, + ), + 'delete_account' => array( 'title' => __( 'Delete Account', 'ultimate-member' ), 'metakey' => 'delete_account', diff --git a/includes/core/class-fields.php b/includes/core/class-fields.php index 19de34ab..209de055 100644 --- a/includes/core/class-fields.php +++ b/includes/core/class-fields.php @@ -4284,6 +4284,14 @@ if ( ! class_exists( 'um\core\Fields' ) ) { * @throws \Exception */ public function view_field( $key, $data, $rule = false ) { + if ( '_um_last_login' === $key ) { + $profile_id = um_user( 'ID' ); + $show_last_login = get_user_meta( $profile_id, 'um_show_last_login', true ); + if ( ! empty( $show_last_login ) && 'no' === $show_last_login[0] ) { + return ''; + } + } + $output = ''; // Get whole field data. diff --git a/includes/core/class-member-directory-meta.php b/includes/core/class-member-directory-meta.php index 563d8bcc..560b79fe 100644 --- a/includes/core/class-member-directory-meta.php +++ b/includes/core/class-member-directory-meta.php @@ -504,13 +504,22 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) { } } + $value = array_map( + function( $date ) { + return is_numeric( $date ) ? $date : strtotime( $date ); + }, + $value + ); + $from_date = gmdate( 'Y-m-d H:i:s', (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ) ); // client time zone offset $to_date = gmdate( 'Y-m-d H:i:s', (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1 ); // time 23:59 // $join_alias is pre-escaped. $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata {$join_alias} ON {$join_alias}.user_id = u.ID"; + $join_alias_ll = $join_alias . '_show_las_login'; + $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata {$join_alias_ll} ON {$join_alias_ll}.user_id = u.ID AND {$join_alias_ll}.um_key = 'um_show_last_login'"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $join_alias is pre-escaped. - $this->where_clauses[] = $wpdb->prepare( "( {$join_alias}.um_key = '_um_last_login' AND {$join_alias}.um_value BETWEEN %s AND %s )", $from_date, $to_date ); + $this->where_clauses[] = $wpdb->prepare( "( {$join_alias}.um_key = '_um_last_login' AND {$join_alias}.um_value BETWEEN %s AND %s AND ( {$join_alias_ll}.um_value IS NULL OR {$join_alias_ll}.um_value != %s ) )", $from_date, $to_date, 'a:1:{i:0;s:2:"no";}' ); if ( ! $is_default ) { $this->custom_filters_in_query[ $field ] = $value; diff --git a/includes/core/class-member-directory.php b/includes/core/class-member-directory.php index c73f6382..b93dea1a 100644 --- a/includes/core/class-member-directory.php +++ b/includes/core/class-member-directory.php @@ -2067,6 +2067,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { $from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset $to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59 $meta_query = array( + 'relation' => 'AND', array( 'key' => '_um_last_login', 'value' => array( gmdate( 'Y-m-d H:i:s', $from_date ), gmdate( 'Y-m-d H:i:s', $to_date ) ), @@ -2074,6 +2075,18 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { 'inclusive' => true, 'type' => 'DATETIME', ), + array( + 'relation' => 'OR', + array( + 'key' => 'um_show_last_login', + 'compare' => 'NOT EXISTS', + ), + array( + 'key' => 'um_show_last_login', + 'value' => 'a:1:{i:0;s:2:"no";}', + 'compare' => '!=', + ), + ), ); $this->custom_filters_in_query[ $field ] = $value; @@ -2344,9 +2357,18 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { $offset = $gmt_offset; } - $from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset - $to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59 + $value = array_map( + function( $date ) { + return is_numeric( $date ) ? $date : strtotime( $date ); + }, + $value + ); + + $from_date = gmdate( 'Y-m-d H:i:s', (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ) ); // client time zone offset + $to_date = gmdate( 'Y-m-d H:i:s', (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1 ); // time 23:59 + $meta_query = array( + 'relation' => 'AND', array( 'key' => '_um_last_login', 'value' => array( $from_date, $to_date ), @@ -2354,6 +2376,18 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { 'inclusive' => true, 'type' => 'DATETIME', ), + array( + 'relation' => 'OR', + array( + 'key' => 'um_show_last_login', + 'compare' => 'NOT EXISTS', + ), + array( + 'key' => 'um_show_last_login', + 'value' => 'a:1:{i:0;s:2:"no";}', + 'compare' => '!=', + ), + ), ); $this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $meta_query ) ); @@ -2559,6 +2593,13 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { continue; } + if ( '_um_last_login' === $key ) { + $show_last_login = get_user_meta( $user_id, 'um_show_last_login', true ); + if ( ! empty( $show_last_login ) && 'no' === $show_last_login[0] ) { + continue; + } + } + $value = um_filtered_value( $key ); if ( ! $value ) { @@ -2583,6 +2624,13 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { continue; } + if ( '_um_last_login' === $key ) { + $show_last_login = get_user_meta( $user_id, 'um_show_last_login', true ); + if ( ! empty( $show_last_login ) && 'no' === $show_last_login[0] ) { + continue; + } + } + $value = um_filtered_value( $key ); if ( ! $value ) { continue; diff --git a/includes/core/class-profile.php b/includes/core/class-profile.php index ca698a96..b469209e 100644 --- a/includes/core/class-profile.php +++ b/includes/core/class-profile.php @@ -418,6 +418,13 @@ if ( ! class_exists( 'um\core\Profile' ) ) { if ( ! empty( $array ) ) { foreach ( $array as $key ) { if ( $key ) { + if ( '_um_last_login' === $key ) { + $show_last_login = get_user_meta( um_user( 'ID' ), 'um_show_last_login', true ); + if ( ! empty( $show_last_login ) && 'no' === $show_last_login[0] ) { + continue; + } + } + $data = array(); if ( isset( UM()->builtin()->all_user_fields[ $key ] ) ) { $data = UM()->builtin()->all_user_fields[ $key ]; diff --git a/includes/core/um-actions-account.php b/includes/core/um-actions-account.php index 366bf0f5..0a2d9bfa 100644 --- a/includes/core/um-actions-account.php +++ b/includes/core/um-actions-account.php @@ -330,7 +330,7 @@ function um_submit_account_details( $args ) { $v = sanitize_text_field( $v ); } elseif ( 'user_email' === $k ) { $v = sanitize_email( $v ); - } elseif ( 'hide_in_members' === $k ) { + } elseif ( 'hide_in_members' === $k || 'um_show_last_login' === $k ) { $v = array_map( 'sanitize_text_field', $v ); } @@ -351,6 +351,13 @@ function um_submit_account_details( $args ) { } } + if ( isset( $changes['um_show_last_login'] ) ) { + if ( 'yes' === $changes['um_show_last_login'] || array_intersect( array( 'yes' ), $changes['um_show_last_login'] ) ) { + delete_user_meta( $user_id, 'um_show_last_login' ); + unset( $changes['um_show_last_login'] ); + } + } + /** * UM hook *