Files
ultimatemember/includes/core/um-actions-profile.php
T
Mykyta Synelnikov d107153244 Refactor profile image handling in Ultimate Member.
Simplified Gravatar image logic and improved code readability by restructuring the image processing flow. Removed redundant variable initialization and adjusted handling of `$image_info`. This ensures cleaner, more maintainable code while preserving existing functionality.
2025-02-28 11:22:24 +02:00

1876 lines
63 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* It renders the content of main profile tab.
*
* @param array $args
*/
function um_profile_content_main( $args ) {
if ( ! array_key_exists( 'mode', $args ) ) {
return;
}
$mode = $args['mode'];
// phpcs:ignore WordPress.Security.NonceVerification -- $_REQUEST is used for echo only
if ( ! isset( $_REQUEST['um_action'] ) && ! UM()->options()->get( 'profile_tab_main' ) ) {
return;
}
/**
* Filters user's ability to view a profile
*
* @since 1.3.x
* @hook um_profile_can_view_main
*
* @param {int} $can_view Can view profile. It's -1 by default.
* @param {int} $profile_id User Profile ID.
*
* @return {int} Can view profile. Set it to -1 for displaying and vice versa to hide.
*
* @example <caption>Make profile hidden.</caption>
* function my_profile_can_view_main( $can_view, $profile_id ) {
* $can_view = 1; // make profile hidden.
* return $can_view;
* }
* add_filter( 'um_profile_can_view_main', 'my_profile_can_view_main', 10, 2 );
*/
$can_view = apply_filters( 'um_profile_can_view_main', -1, um_profile_id() );
if ( -1 === (int) $can_view ) {
/**
* Fires before UM Form content.
*
* @since 1.3.x
* @hook um_before_form
*
* @param {array} $args UM Form shortcode arguments.
*
* @example <caption>Make any custom action before UM form.</caption>
* function my_before_form( $args ) {
* // your code here
* }
* add_action( 'um_before_form', 'my_before_form' );
*/
do_action( 'um_before_form', $args );
/**
* Fires before UM Form fields.
*
* Note: $mode can be equals to 'login', 'profile', 'register'.
*
* @since 1.3.x
* @hook um_before_{$mode}_fields
*
* @param {array} $args UM Form shortcode arguments.
*
* @example <caption>Make any custom action before UM Profile form fields.</caption>
* function my_before_profile_fields( $args ) {
* // your code here
* }
* add_action( 'um_before_profile_fields', 'my_before_profile_fields' );
* @example <caption>Make any custom action before UM Login form fields.</caption>
* function my_before_login_fields( $args ) {
* // your code here
* }
* add_action( 'um_before_login_fields', 'my_before_login_fields' );
* @example <caption>Make any custom action before UM Register form fields.</caption>
* function my_before_register_fields( $args ) {
* // your code here
* }
* add_action( 'um_before_register_fields', 'my_before_register_fields' );
*/
do_action( "um_before_{$mode}_fields", $args );
/**
* Fires for rendering UM Form fields.
*
* Note: $mode can be equals to 'login', 'profile', 'register'.
*
* @since 1.3.x
* @hook um_main_{$mode}_fields
*
* @param {array} $args UM Form shortcode arguments.
*
* @example <caption>Make any custom action when profile form fields are rendered.</caption>
* function my_main_profile_fields( $args ) {
* // your code here
* }
* add_action( 'um_main_profile_fields', 'my_main_profile_fields' );
* @example <caption>Make any custom action when login form fields are rendered.</caption>
* function my_main_login_fields( $args ) {
* // your code here
* }
* add_action( 'um_main_login_fields', 'my_main_login_fields' );
* @example <caption>Make any custom action when register form fields are rendered.</caption>
* function my_main_register_fields( $args ) {
* // your code here
* }
* add_action( 'um_main_register_fields', 'my_main_register_fields' );
*/
do_action( "um_main_{$mode}_fields", $args );
/**
* Fires after UM Form fields.
*
* @since 1.3.x
* @hook um_after_form_fields
*
* @param {array} $args UM Form shortcode arguments.
*
* @example <caption>Make any custom action after UM Form fields.</caption>
* function my_after_form_fields( $args ) {
* // your code here
* }
* add_action( 'um_after_form_fields', 'my_after_form_fields' );
*/
do_action( 'um_after_form_fields', $args );
/**
* Fires after UM Form fields.
*
* Note: $mode can be equals to 'login', 'profile', 'register'.
*
* @since 1.3.x
* @hook um_after_{$mode}_fields
*
* @param {array} $args UM Form shortcode arguments.
*
* @example <caption>Make any custom action after profile form fields.</caption>
* function my_after_profile_fields( $args ) {
* // your code here
* }
* add_action( 'um_after_profile_fields', 'my_after_profile_fields' );
* @example <caption>Make any custom action after login form fields.</caption>
* function my_after_login_fields( $args ) {
* // your code here
* }
* add_action( 'um_after_login_fields', 'my_after_login_fields' );
* @example <caption>Make any custom action after register form fields.</caption>
* function my_after_register_fields( $args ) {
* // your code here
* }
* add_action( 'um_after_register_fields', 'my_after_register_fields' );
*/
do_action( "um_after_{$mode}_fields", $args );
/**
* Fires after UM Form content.
*
* @since 1.3.x
* @hook um_after_form
*
* @param {array} $args UM Form shortcode arguments.
*
* @example <caption>Make any custom action after UM Form content.</caption>
* function my_after_form( $args ) {
* // your code here
* }
* add_action( 'um_after_form', 'my_after_form' );
*/
do_action( 'um_after_form', $args );
} else {
?>
<div class="um-profile-note">
<span>
<i class="um-faicon-lock"></i>
<?php echo esc_html( $can_view ); ?>
</span>
</div>
<?php
}
}
add_action( 'um_profile_content_main', 'um_profile_content_main' );
/**
* Update user's profile (frontend).
*
* @param array $args
* @param array $form_data
*/
function um_user_edit_profile( $args, $form_data ) {
$to_update = null;
$files = array();
$user_id = null;
if ( isset( $args['user_id'] ) ) {
$user_id = $args['user_id'];
} elseif ( isset( $args['_user_id'] ) ) {
$user_id = $args['_user_id'];
}
if ( UM()->roles()->um_current_user_can( 'edit', $user_id ) ) {
UM()->user()->set( $user_id );
} else {
wp_die( esc_html__( 'You are not allowed to edit this user.', 'ultimate-member' ) );
}
$userinfo = UM()->user()->profile;
/**
* Fires before collecting data to update on profile form submit.
*
* @since 1.3.x
* @hook um_user_before_updating_profile
*
* @param {array} $userinfo Userdata.
*
* @example <caption>Make any custom action before collecting data to update on profile form submit.</caption>
* function my_user_before_updating_profile( $role_key, $role_meta ) {
* // your code here
* }
* add_action( 'um_user_before_updating_profile', 'my_user_before_updating_profile', 10, 2 );
*/
do_action( 'um_user_before_updating_profile', $userinfo );
$fields = maybe_unserialize( $form_data['custom_fields'] );
$fields = apply_filters( 'um_user_edit_profile_fields', $fields, $args, $form_data );
// loop through fields
if ( ! empty( $fields ) ) {
$arr_restricted_fields = UM()->fields()->get_restricted_fields_for_edit( $user_id );
foreach ( $fields as $key => $array ) {
if ( ! isset( $array['type'] ) ) {
continue;
}
if ( isset( $array['edit_forbidden'] ) ) {
continue;
}
if ( is_array( $array ) ) {
$origin_data = UM()->fields()->get_field( $key );
if ( is_array( $origin_data ) ) {
// Merge data passed with original field data.
$array = array_merge( $origin_data, $array );
}
}
// required option? 'required_opt' - it's field attribute predefined in the field data in code
// @todo can be unnecessary. it's used in 1 place (user account).
if ( isset( $array['required_opt'] ) ) {
$opt = $array['required_opt'];
if ( UM()->options()->get( $opt[0] ) !== $opt[1] ) {
continue;
}
}
// fields that need to be disabled in edit mode (profile) (email, username, etc.)
if ( is_array( $arr_restricted_fields ) && in_array( $key, $arr_restricted_fields, true ) ) {
continue;
}
if ( ! um_can_edit_field( $array ) || ! um_can_view_field( $array ) ) {
continue;
}
// skip saving role here
if ( in_array( $key, array( 'role', 'role_select', 'role_radio' ), true ) ) {
continue;
}
//the same code in class-validation.php validate_fields_values for registration form
//rating field validation
if ( 'rating' === $array['type'] && isset( $args['submitted'][ $key ] ) ) {
if ( ! is_numeric( $args['submitted'][ $key ] ) ) {
continue;
} else {
if ( $array['number'] == 5 ) {
if ( ! in_array( $args['submitted'][ $key ], range( 1, 5 ) ) ) {
continue;
}
} elseif ( $array['number'] == 10 ) {
if ( ! in_array( $args['submitted'][ $key ], range( 1, 10 ) ) ) {
continue;
}
}
}
}
/**
* Returns dropdown/multi-select options keys from a callback function
* @since 2019-05-30
*/
$has_custom_source = apply_filters( "um_has_dropdown_options_source__{$key}", false );
if ( isset( $array['options'] ) && in_array( $array['type'], array( 'select', 'multiselect' ), true ) ) {
$options = $array['options'];
if ( ! empty( $array['custom_dropdown_options_source'] ) && function_exists( $array['custom_dropdown_options_source'] ) && ! $has_custom_source ) {
if ( ! UM()->fields()->is_source_blacklisted( $array['custom_dropdown_options_source'] ) ) {
$callback_result = call_user_func( $array['custom_dropdown_options_source'], $array['options'] );
if ( is_array( $callback_result ) ) {
$options = array_keys( $callback_result );
}
}
}
$array['options'] = apply_filters( "um_custom_dropdown_options__{$key}", $options );
}
//validation of correct values from options in wp-admin
$stripslashes = '';
if ( isset( $args['submitted'][ $key ] ) && is_string( $args['submitted'][ $key ] ) ) {
$stripslashes = wp_unslash( $args['submitted'][ $key ] );
}
if ( 'select' === $array['type'] ) {
if ( ! empty( $array['options'] ) && ! empty( $stripslashes ) && ! in_array( $stripslashes, array_map( 'trim', $array['options'] ) ) && ! $has_custom_source ) {
continue;
}
//update empty user meta
if ( ! isset( $args['submitted'][ $key ] ) || '' === $args['submitted'][ $key ] ) {
update_user_meta( $user_id, $key, '' );
}
}
//validation of correct values from options in wp-admin
//the user cannot set invalid value in the hidden input at the page
if ( in_array( $array['type'], array( 'multiselect', 'checkbox', 'radio' ), true ) ) {
if ( ! empty( $args['submitted'][ $key ] ) && ! empty( $array['options'] ) ) {
if ( is_array( $args['submitted'][ $key ] ) ) {
$args['submitted'][ $key ] = array_map( 'stripslashes', array_map( 'trim', $args['submitted'][ $key ] ) );
if ( is_array( $array['options'] ) ) {
$args['submitted'][ $key ] = array_intersect( $args['submitted'][ $key ], array_map( 'trim', $array['options'] ) );
} else {
$args['submitted'][ $key ] = array_intersect( $args['submitted'][ $key ], array( trim( $array['options'] ) ) );
}
} else {
if ( is_array( $array['options'] ) ) {
$args['submitted'][ $key ] = array_intersect( array( stripslashes( trim( $args['submitted'][ $key ] ) ) ), array_map( 'trim', $array['options'] ) );
} else {
$args['submitted'][ $key ] = array_intersect( array( stripslashes( trim( $args['submitted'][ $key ] ) ) ), array( trim( $array['options'] ) ) );
}
}
}
// update empty user meta
if ( ! isset( $args['submitted'][ $key ] ) || '' === $args['submitted'][ $key ] ) {
update_user_meta( $user_id, $key, array() );
}
}
if ( isset( $args['submitted'][ $key ] ) ) {
if ( in_array( $array['type'], array( 'image', 'file' ), true ) ) {
if ( um_is_temp_file( $args['submitted'][ $key ] ) || 'empty_file' === $args['submitted'][ $key ] ) {
$files[ $key ] = $args['submitted'][ $key ];
} elseif( um_is_file_owner( UM()->uploader()->get_upload_base_url() . $user_id . '/' . $args['submitted'][ $key ], $user_id ) ) {
} else {
$files[ $key ] = 'empty_file';
}
} else {
if ( 'password' === $array['type'] ) {
$to_update[ $key ] = wp_hash_password( $args['submitted'][ $key ] );
// translators: %s: title.
$args['submitted'][ $key ] = sprintf( __( 'Your choosed %s', 'ultimate-member' ), $array['title'] );
} else {
if ( isset( $userinfo[ $key ] ) && $args['submitted'][ $key ] !== $userinfo[ $key ] ) {
$to_update[ $key ] = $args['submitted'][ $key ];
} elseif ( '' !== $args['submitted'][ $key ] ) {
$to_update[ $key ] = $args['submitted'][ $key ];
}
}
}
// use this filter after all validations has been completed, and we can extend data based on key
$to_update = apply_filters( 'um_change_usermeta_for_update', $to_update, $args, $fields, $key );
}
}
}
$description_key = UM()->profile()->get_show_bio_key( $args );
if ( ! isset( $to_update[ $description_key ] ) && isset( $args['submitted'][ $description_key ] ) ) {
if ( ! empty( $form_data['use_custom_settings'] ) && ! empty( $form_data['show_bio'] ) ) {
$to_update[ $description_key ] = $args['submitted'][ $description_key ];
} else {
if ( UM()->options()->get( 'profile_show_bio' ) ) {
$to_update[ $description_key ] = $args['submitted'][ $description_key ];
}
}
}
// Secure selected role.
// It's for a legacy case `array_key_exists( 'editable', $fields['role'] )` and similar.
if ( ( isset( $fields['role'] ) && ( ! array_key_exists( 'editable', $fields['role'] ) || ! empty( $fields['role']['editable'] ) ) && um_can_view_field( $fields['role'] ) ) ||
( isset( $fields['role_select'] ) && ( ! array_key_exists( 'editable', $fields['role_select'] ) || ! empty( $fields['role_select']['editable'] ) ) && um_can_view_field( $fields['role_select'] ) ) ||
( isset( $fields['role_radio'] ) && ( ! array_key_exists( 'editable', $fields['role_radio'] ) || ! empty( $fields['role_radio']['editable'] ) ) && um_can_view_field( $fields['role_radio'] ) ) ) {
if ( ! empty( $args['submitted']['role'] ) ) {
global $wp_roles;
$exclude_roles = array_diff( array_keys( $wp_roles->roles ), UM()->roles()->get_editable_user_roles() );
if ( ! in_array( $args['submitted']['role'], $exclude_roles, true ) ) {
$to_update['role'] = $args['submitted']['role'];
}
$args['roles_before_upgrade'] = UM()->roles()->get_all_user_roles( $user_id );
}
}
/**
* UM hook
*
* @type action
* @title um_user_pre_updating_profile
* @description Some actions before profile submit
* @input_vars
* [{"var":"$userinfo","type":"array","desc":"Submitted User Data"},
* {"var":"$user_id","type":"int","desc":"User ID"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_user_pre_updating_profile', 'function_name', 10, 2 );
* @example
* <?php
* add_action( 'um_user_pre_updating_profile', 'my_user_pre_updating_profile', 10, 2 );
* function my_user_pre_updating_profile( $userinfo, $user_id ) {
* // your code here
* }
* ?>
*/
do_action( 'um_user_pre_updating_profile', $to_update, $user_id, $form_data );
/**
* UM hook
*
* @type filter
* @title um_user_pre_updating_profile_array
* @description Change submitted data before update profile
* @input_vars
* [{"var":"$to_update","type":"array","desc":"Profile data upgrade"},
* {"var":"$user_id","type":"int","desc":"User ID"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_user_pre_updating_profile_array', 'function_name', 10, 2 ); ?>
* @example
* <?php
* add_filter( 'um_user_pre_updating_profile_array', 'my_user_pre_updating_profile', 10, 2 );
* function my_user_pre_updating_profile( $to_update, $user_id ) {
* // your code here
* return $to_update;
* }
* ?>
*/
$to_update = apply_filters( 'um_user_pre_updating_profile_array', $to_update, $user_id, $form_data );
if ( is_array( $to_update ) ) {
if ( isset( $to_update['first_name'] ) || isset( $to_update['last_name'] ) || isset( $to_update['nickname'] ) ) {
$user = get_userdata( $user_id );
if ( ! empty( $user ) && ! is_wp_error( $user ) ) {
UM()->user()->previous_data['display_name'] = $user->display_name;
if ( isset( $to_update['first_name'] ) ) {
UM()->user()->previous_data['first_name'] = $user->first_name;
}
if ( isset( $to_update['last_name'] ) ) {
UM()->user()->previous_data['last_name'] = $user->last_name;
}
if ( isset( $to_update['nickname'] ) ) {
UM()->user()->previous_data['nickname'] = $user->nickname;
}
}
}
UM()->user()->update_profile( $to_update );
/**
* UM hook
*
* @type action
* @title um_after_user_updated
* @description Some actions after user profile updated
* @input_vars
* [{"var":"$user_id","type":"int","desc":"User ID"},
* {"var":"$args","type":"array","desc":"Form Data"},
* {"var":"$userinfo","type":"array","desc":"Submitted User Data"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_after_user_updated', 'function_name', 10, 33 );
* @example
* <?php
* add_action( 'um_after_user_updated', 'my_after_user_updated', 10, 3 );
* function my_after_user_updated( $user_id, $args, $userinfo ) {
* // your code here
* }
* ?>
*/
do_action( 'um_after_user_updated', $user_id, $args, $to_update );
}
/** This action is documented in ultimate-member/includes/core/um-actions-register.php */
$files = apply_filters( 'um_user_pre_updating_files_array', $files, $user_id );
if ( ! empty( $files ) && is_array( $files ) ) {
UM()->uploader()->replace_upload_dir = true;
UM()->uploader()->move_temporary_files( $user_id, $files );
UM()->uploader()->replace_upload_dir = false;
}
/** This action is documented in ultimate-member/includes/core/um-actions-register.php */
do_action( 'um_update_profile_full_name', $user_id, $to_update );
/**
* UM hook
*
* @type action
* @title um_user_after_updating_profile
* @description After upgrade user's profile
* @input_vars
* [{"var":"$submitted","type":"array","desc":"Form data"},
* {"var":"$user_id","type":"int","desc":"User Id"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_user_after_updating_profile', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_user_after_updating_profile', 'my_user_after_updating_profile'', 10, 2 );
* function my_user_after_updating_profile( $submitted, $user_id ) {
* // your code here
* }
* ?>
*/
do_action( 'um_user_after_updating_profile', $to_update, $user_id, $args );
// Finally redirect to profile.
$url = um_user_profile_url( $user_id );
$url = apply_filters( 'um_update_profile_redirect_after', $url, $user_id, $args );
// Not `um_safe_redirect()` because predefined user profile page is situated on the same host.
wp_safe_redirect( um_edit_my_profile_cancel_uri( $url ) );
exit;
}
add_action( 'um_user_edit_profile', 'um_user_edit_profile', 10, 2 );
/**
* Validate nonce when profile form submit.
*
* @param array $submitted_data
*/
function um_profile_validate_nonce( $submitted_data ) {
$user_id = isset( $submitted_data['user_id'] ) ? $submitted_data['user_id'] : '';
$nonce = isset( $submitted_data['profile_nonce'] ) ? $submitted_data['profile_nonce'] : '';
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'um-profile-nonce' . $user_id ) ) {
wp_die( esc_html__( 'This is not possible for security reasons.', 'ultimate-member' ) );
}
}
add_action( 'um_submit_form_errors_hook__profile', 'um_profile_validate_nonce', 1 );
// @todo maybe remove that because double validate
add_filter( 'um_user_pre_updating_files_array', array( UM()->validation(), 'validate_files' ) );
// @todo maybe remove that because double validate
add_filter( 'um_before_save_filter_submitted', array( UM()->validation(), 'validate_fields_values' ), 10, 3 );
/**
* Leave roles for User, which are not in the list of update profile (are default WP or 3rd plugins roles)
*
* @param $user_id
* @param $args
* @param $to_update
*/
function um_restore_default_roles( $user_id, $args, $to_update ) {
if ( ! empty( $args['submitted']['role'] ) && ! empty( $to_update['role'] ) ) {
$wp_user = new WP_User( $user_id );
$leave_roles = array_diff( $args['roles_before_upgrade'], UM()->roles()->get_editable_user_roles() );
if ( UM()->roles()->is_role_custom( $to_update['role'] ) ) {
$wp_user->remove_role( $to_update['role'] );
$roles = array_merge( $leave_roles, array( $to_update['role'] ) );
} else {
$roles = array_merge( array( $to_update['role'] ), $leave_roles );
}
foreach ( $roles as $role_k ) {
$wp_user->add_role( $role_k );
}
}
}
add_action( 'um_after_user_updated', 'um_restore_default_roles', 10, 3 );
/**
* If editing another user
*
* @param $args
*/
function um_editing_user_id_input( $args ) {
if ( true === UM()->fields()->editing && 'profile' === UM()->fields()->set_mode && UM()->user()->target_id ) {
?>
<input type="hidden" name="user_id" id="user_id" value="<?php echo esc_attr( UM()->user()->target_id ); ?>" />
<input type="hidden" name="profile_nonce" id="profile_nonce" value="<?php echo esc_attr( UM()->form()->nonce ); ?>" />
<?php
}
}
add_action( 'um_after_form_fields', 'um_editing_user_id_input' );
if ( ! function_exists( 'um_profile_remove_wpseo' ) ) {
/**
* Remove Yoast from front end for the Profile page
*
* @see https://gist.github.com/amboutwe/1c847f9c706ff6f8c9eca76abea23fb6
* @since 2.1.6
*/
function um_profile_remove_wpseo() {
if ( um_is_core_page( 'user' ) && um_get_requested_user() ) {
/* Yoast SEO 12.4 */
if ( isset( $GLOBALS['wpseo_front'] ) && is_object( $GLOBALS['wpseo_front'] ) ) {
remove_action( 'wp_head', array( $GLOBALS['wpseo_front'], 'head' ), 1 );
} elseif ( class_exists( 'WPSEO_Frontend' ) && is_callable( array( 'WPSEO_Frontend', 'get_instance' ) ) ) {
remove_action( 'wp_head', array( WPSEO_Frontend::get_instance(), 'head' ), 1 );
}
/* Yoast SEO 14.1 */
remove_all_filters( 'wpseo_head' );
/* Restore title and canonical if broken */
if ( ! has_action( 'wp_head', '_wp_render_title_tag' ) ) {
add_action( 'wp_head', '_wp_render_title_tag', 18 );
}
if ( ! has_action( 'wp_head', 'rel_canonical' ) ) {
add_action( 'wp_head', 'rel_canonical', 18 );
}
}
}
}
add_action( 'get_header', 'um_profile_remove_wpseo', 8 );
/**
* The profile page SEO tags
*
* @see https://ogp.me/ - The Open Graph protocol
* @see https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary - The Twitter Summary card
* @see https://schema.org/Person - The schema.org Person schema
*/
function um_profile_dynamic_meta_desc() {
if ( um_is_core_page( 'user' ) && um_get_requested_user() ) {
$user_id = um_get_requested_user();
if ( um_user( 'ID' ) !== $user_id ) {
um_fetch_user( $user_id );
}
/**
* Settings by the priority:
* "Search engine visibility" in [wp-admin > Settings > Reading]
* "Profile Privacy" in [Account > Privacy]
* "Avoid indexing my profile by search engines in [Account > Privacy]
* "Avoid indexing profile by search engines" in [wp-admin > Ultimate Member > User Roles > Edit Role]
* "Avoid indexing profile by search engines" in [wp-admin > Ultimate Member > Settings > General > Users]
*/
if ( UM()->user()->is_profile_noindex( $user_id ) ) {
echo '<meta name="robots" content="noindex, nofollow" />';
return;
}
$locale = get_user_locale( $user_id );
$site_name = get_bloginfo( 'name' );
$twitter = (string) um_user( 'twitter' );
if ( ! empty( $twitter ) ) {
$twitter = trim( str_replace( 'https://twitter.com/', '', $twitter ), "/ \n\r\t\v\0" );
}
$title = trim( um_user( 'display_name' ) );
$description = um_convert_tags( UM()->options()->get( 'profile_desc' ) );
$url = um_user_profile_url( $user_id );
/**
* Filters the profile SEO image type. Default 'profile_photo'. Available 'cover_photo', 'profile_photo'.
*
* @param {string} $image_type Image type - cover_photo or profile_photo.
* @param {int} $user_id User ID.
*
* @return {string} Changed image type
*
* @since 2.5.5
* @hook um_profile_dynamic_meta_image_type
*
* @example <caption>Change meta image to cover photo `cover_photo`.</caption>
* function my_um_profile_dynamic_meta_image_type( $image_type, $user_id ) {
* return 'cover_photo';
* }
* add_filter( 'um_profile_dynamic_meta_image_type', 'my_um_profile_dynamic_meta_image_type', 10, 2 );
*/
$image_type = apply_filters( 'um_profile_dynamic_meta_image_type', 'profile_photo', $user_id );
// The minimum size is 200 x 200 px, however, we recommend keeping it to 600 x 315 px.
// If your image is smaller than 600 x 315 pixels, it will appear as a small image in the link preview.
$default_image_size = 'cover_photo' === $image_type ? 600 : 200;
/**
* Filters the profile SEO image size. Default 190. Available 'original'.
*
* @param {string} $image_size Image size.
* @param {int} $user_id User ID.
*
* @return {array} Changed image type
*
* @since 2.5.5
* @hook um_profile_dynamic_meta_image_size
*
* @example <caption>Change meta image to cover photo `cover_photo`.</caption>
* function my_um_profile_dynamic_meta_image_size( $image_size, $user_id ) {
* return 'original';
* }
* add_filter( 'um_profile_dynamic_meta_image_size', 'my_um_profile_dynamic_meta_image_size', 10, 2 );
*/
$image_size = apply_filters( 'um_profile_dynamic_meta_image_size', $default_image_size, $user_id );
if ( 'cover_photo' === $image_type ) {
if ( is_numeric( $image_size ) ) {
$sizes = UM()->options()->get( 'cover_thumb_sizes' );
if ( is_array( $sizes ) ) {
$image_size = um_closest_num( $sizes, $image_size );
}
$image = um_get_cover_uri( um_profile( 'cover_photo' ), $image_size );
} else {
$image = um_get_cover_uri( um_profile( 'cover_photo' ), null );
}
} elseif ( is_numeric( $image_size ) ) {
$sizes = UM()->options()->get( 'photo_thumb_sizes' );
if ( is_array( $sizes ) ) {
$image_size = um_closest_num( $sizes, $image_size );
}
$image = um_get_user_avatar_url( $user_id, $image_size );
} else {
$image = um_get_user_avatar_url( $user_id, 'original' );
}
$image_info = array();
$image_width = $image_size;
$image_height = $image_size;
if ( false === strpos( $image, 'gravatar.com' ) ) {
// Ignore Gravatar image here and handler a real image.
$image = current( explode( '?', $image ) ); // strip $_GET attributes from photo URL.
$image_path = wp_normalize_path( ABSPATH . wp_parse_url( $image, PHP_URL_PATH ) );
$image_info = wp_check_filetype( $image_path );
$imagesizes = getimagesize( $image_path );
if ( is_array( $imagesizes ) ) {
list( $image_width, $image_height ) = $imagesizes;
}
} else {
// Gravatar image.
$image_path = esc_url_raw( $image );
}
$person = array(
'@context' => 'https://schema.org',
'@type' => 'ProfilePage',
'dateCreated' => um_user( 'user_registered' ),
'mainEntity' => array(
'@type' => 'Person',
'name' => esc_attr( $title ),
'alternateName' => um_user( 'user_login' ),
'description' => esc_attr( stripslashes( $description ) ),
'image' => esc_url( $image ),
'sameAs' => array(
$url,
),
),
);
$user_last_update = um_user( 'last_update' );
if ( ! empty( $user_last_update ) ) {
if ( is_numeric( $user_last_update ) ) {
$user_last_update = (int) $user_last_update; // cast numeric type to int
} else {
$user_last_update = strtotime( $user_last_update ); // cast string date type to int
}
if ( ! empty( $user_last_update ) ) {
$person['dateModified'] = gmdate( 'Y-m-d H:i:s', $user_last_update );
}
}
/**
* Filters changing the schema.org of profile's person.
*
* @param {array} $person Data of the profile person.
* @param {int} $user_id User ID.
*
* @return {array} Changed person's data.
*
* @since 2.8.7
* @hook um_profile_dynamic_meta_profile_schema
*
* @example <caption>Change name of person.</caption>
* function my_um_profile_dynamic_meta_profile_schema( $core_search_fields ) {
* $person['mainEntity']['name'] = 'John Doe';
* }
* add_filter( 'um_profile_dynamic_meta_profile_schema', 'my_um_profile_dynamic_meta_profile_schema' );
*/
$person = apply_filters( 'um_profile_dynamic_meta_profile_schema', $person, $user_id );
um_reset_user();
?>
<!-- START - Ultimate Member profile SEO meta tags -->
<link rel="image_src" href="<?php echo esc_url( $image ); ?>"/>
<meta name="description" content="<?php echo esc_attr( $description ); ?>"/>
<meta property="og:type" content="profile"/>
<meta property="og:locale" content="<?php echo esc_attr( $locale ); ?>"/>
<meta property="og:site_name" content="<?php echo esc_attr( $site_name ); ?>"/>
<meta property="og:title" content="<?php echo esc_attr( $title ); ?>"/>
<meta property="og:description" content="<?php echo esc_attr( $description ); ?>"/>
<meta property="og:image" content="<?php echo esc_url( $image ); ?>"/>
<meta property="og:image:alt" content="<?php esc_attr_e( 'Profile photo', 'ultimate-member' ); ?>"/>
<meta property="og:image:height" content="<?php echo absint( $image_height ); ?>"/>
<meta property="og:image:width" content="<?php echo absint( $image_width ); ?>"/>
<?php if ( is_ssl() ) { ?>
<meta property="og:image:secure_url" content="<?php echo esc_url( $image ); ?>"/>
<?php } ?>
<?php if ( ! empty( $image_info['type'] ) ) { ?>
<meta property="og:image:type" content="<?php echo esc_attr( $image_info['type'] ); ?>" />
<?php } ?>
<meta property="og:url" content="<?php echo esc_url( $url ); ?>"/>
<meta name="twitter:card" content="summary"/>
<?php if ( $twitter ) { ?>
<meta name="twitter:site" content="@<?php echo esc_attr( $twitter ); ?>"/>
<?php } ?>
<meta name="twitter:title" content="<?php echo esc_attr( $title ); ?>"/>
<meta name="twitter:description" content="<?php echo esc_attr( $description ); ?>"/>
<meta name="twitter:image" content="<?php echo esc_url( $image ); ?>"/>
<meta name="twitter:image:alt" content="<?php esc_attr_e( 'Profile photo', 'ultimate-member' ); ?>"/>
<meta name="twitter:url" content="<?php echo esc_url( $url ); ?>"/>
<script type="application/ld+json"><?php echo wp_json_encode( $person ); ?></script>
<!-- END - Ultimate Member profile SEO meta tags -->
<?php
}
}
add_action( 'wp_head', 'um_profile_dynamic_meta_desc', 20 );
/**
* Profile header cover
*
* @param $args
*/
function um_profile_header_cover_area( $args ) {
if ( empty( $args['cover_enabled'] ) ) {
return;
}
$default_cover = UM()->options()->get( 'default_cover' );
$user_cover = um_user( 'cover_photo' );
$cover_wrapper_classes = array( 'um-cover' );
if ( $user_cover || ! empty( $default_cover['url'] ) ) {
$cover_wrapper_classes[] = 'has-cover';
}
?>
<div class="<?php echo esc_attr( implode( ' ', $cover_wrapper_classes ) ); ?>"
data-user_id="<?php echo esc_attr( um_profile_id() ); ?>" data-ratio="<?php echo esc_attr( $args['cover_ratio'] ); ?>">
<?php
/**
* UM hook
*
* @type action
* @title um_cover_area_content
* @description Cover area content change
* @input_vars
* [{"var":"$user_id","type":"int","desc":"User ID"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_cover_area_content', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_cover_area_content', 'my_cover_area_content', 10, 1 );
* function my_cover_area_content( $user_id ) {
* // your code here
* }
* ?>
*/
do_action( 'um_cover_area_content', um_profile_id() );
if ( true === UM()->fields()->editing ) {
$hide_remove = ' style="display:none;"';
$remove_classes = array( 'um-reset-cover-photo' );
if ( $user_cover ) {
$hide_remove = '';
$remove_classes[] = 'um-is-visible';
}
$text = ! $user_cover ? __( 'Upload a cover photo', 'ultimate-member' ) : __( 'Change cover photo', 'ultimate-member' );
$alt_text = $user_cover ? __( 'Upload a cover photo', 'ultimate-member' ) : __( 'Change cover photo', 'ultimate-member' );
$items = array(
'<a href="javascript:void(0);" class="um-manual-trigger" data-parent=".um-cover" data-child=".um-btn-auto-width" data-alt_text="' . esc_attr( $alt_text ) . '">' . esc_html( $text ) . '</a>',
'<a href="javascript:void(0);" class="' . esc_attr( implode( ' ', $remove_classes ) ) . '" data-user_id="' . esc_attr( um_profile_id() ) . '" ' . $hide_remove . '>' . esc_html__( 'Remove cover photo', 'ultimate-member' ) . '</a>',
'<a href="javascript:void(0);" class="um-dropdown-hide">' . esc_html__( 'Cancel', 'ultimate-member' ) . '</a>',
);
$items = apply_filters( 'um_cover_area_content_dropdown_items', $items, um_profile_id() );
UM()->profile()->new_ui( 'bc', 'div.um-cover', 'click', $items );
} elseif ( ! $user_cover && ! isset( UM()->user()->cannot_edit ) ) {
$items = array(
'<a href="javascript:void(0);" class="um-manual-trigger" data-parent=".um-cover" data-child=".um-btn-auto-width">' . esc_html__( 'Upload a cover photo', 'ultimate-member' ) . '</a>',
'<a href="javascript:void(0);" class="um-dropdown-hide">' . esc_html__( 'Cancel', 'ultimate-member' ) . '</a>',
);
$items = apply_filters( 'um_cover_area_content_dropdown_items', $items, um_profile_id() );
UM()->profile()->new_ui( 'bc', 'div.um-cover', 'click', $items );
}
UM()->fields()->add_hidden_field( 'cover_photo' );
?>
<div class="um-cover-e" data-ratio="<?php echo esc_attr( $args['cover_ratio'] ); ?>">
<?php
if ( $user_cover ) {
$get_cover_size = $args['coversize'];
if ( ! $get_cover_size || 'original' === $get_cover_size ) {
$size = null;
} else {
$size = $get_cover_size;
}
if ( wp_is_mobile() ) {
// Set for mobile width = 300 by default but can be changed via filter
$size = 300;
/**
* UM hook
*
* @type filter
* @title um_mobile_cover_photo
* @description Add size for mobile device
* @input_vars
* [{"var":"$size","type":"int","desc":"Form's agrument - Cover Photo size"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_mobile_cover_photo', 'change_size', 10, 1 ); ?>
* @example
* <?php
* add_filter( 'um_mobile_cover_photo', 'um_change_cover_mobile_size', 10, 1 );
* function um_change_cover_mobile_size( $size ) {
* // your code here
* return $size;
* }
* ?>
*/
$size = apply_filters( 'um_mobile_cover_photo', $size );
}
echo um_user( 'cover_photo', $size );
} elseif ( ! empty( $default_cover['url'] ) ) {
echo '<img src="' . esc_url( $default_cover['url'] ) . '" alt="" />';
} elseif ( ! isset( UM()->user()->cannot_edit ) ) {
?>
<a href="javascript:void(0);" class="um-cover-add"><span class="um-cover-add-i"><i
class="um-icon-plus um-tip-n"
title="<?php esc_attr_e( 'Upload a cover photo', 'ultimate-member' ); ?>"></i></span></a>
<?php
}
?>
</div>
<?php if ( true === UM()->fields()->editing ) { ?>
<span class="um-cover-overlay">
<span class="um-cover-overlay-s">
<ins>
<i class="um-faicon-picture-o"></i>
<span class="um-cover-overlay-t"><?php esc_html_e( 'Change your cover photo', 'ultimate-member' ); ?></span>
</ins>
</span>
</span>
<?php } ?>
</div>
<?php
}
add_action( 'um_profile_header_cover_area', 'um_profile_header_cover_area', 9 );
/**
* Show social links as icons below profile name
*
* @param $args
*/
function um_social_links_icons( $args ) {
if ( ! empty( $args['show_social_links'] ) ) {
echo '<div class="um-profile-connect um-member-connect">';
UM()->fields()->show_social_urls();
echo '</div>';
}
}
add_action( 'um_after_profile_header_name_args', 'um_social_links_icons', 50 );
/**
* Profile header
*
* @param $args
*/
function um_profile_header( $args ) {
$classes = null;
if ( ! $args['cover_enabled'] ) {
$classes .= ' no-cover';
}
$default_size = str_replace( 'px', '', $args['photosize'] );
// Switch on/off the profile photo uploader
$disable_photo_uploader = empty( $args['use_custom_settings'] ) ? UM()->options()->get( 'disable_profile_photo_upload' ) : $args['disable_photo_upload'];
if ( ! empty( $disable_photo_uploader ) ) {
$args['disable_photo_upload'] = 1;
$overlay = '';
} else {
$overlay = '<span class="um-profile-photo-overlay">
<span class="um-profile-photo-overlay-s">
<ins>
<i class="um-faicon-camera"></i>
</ins>
</span>
</span>';
} ?>
<div class="um-header<?php echo esc_attr( $classes ); ?>">
<?php
/**
* UM hook
*
* @type action
* @title um_pre_header_editprofile
* @description Insert some content before edit profile header
* @input_vars
* [{"var":"$args","type":"array","desc":"Form Arguments"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_pre_header_editprofile', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_pre_header_editprofile', 'my_pre_header_editprofile', 10, 1 );
* function my_pre_header_editprofile( $args ) {
* // your code here
* }
* ?>
*/
do_action( 'um_pre_header_editprofile', $args ); ?>
<div class="um-profile-photo" data-user_id="<?php echo esc_attr( um_profile_id() ); ?>" <?php echo wp_kses( UM()->fields()->aria_valid_attributes( UM()->fields()->is_error( 'profile_photo' ), 'profile_photo' ), UM()->get_allowed_html( 'templates' ) ); ?>>
<a href="<?php echo esc_url( um_user_profile_url() ); ?>" class="um-profile-photo-img" title="<?php echo esc_attr( um_user( 'display_name' ) ); ?>">
<?php if ( ! $default_size || $default_size == 'original' ) {
$profile_photo = UM()->uploader()->get_upload_base_url() . um_user( 'ID' ) . "/" . um_profile( 'profile_photo' );
$data = um_get_user_avatar_data( um_user( 'ID' ) );
echo $overlay . sprintf( '<img src="%s" class="%s" alt="%s" data-default="%s" onerror="%s" />',
esc_url( $profile_photo ),
esc_attr( $data['class'] ),
esc_attr( $data['alt'] ),
esc_attr( $data['default'] ),
'if ( ! this.getAttribute(\'data-load-error\') ){ this.setAttribute(\'data-load-error\', \'1\');this.setAttribute(\'src\', this.getAttribute(\'data-default\'));}'
);
} else {
echo $overlay . get_avatar( um_user( 'ID' ), $default_size );
} ?>
</a>
<?php if ( empty( $disable_photo_uploader ) && empty( UM()->user()->cannot_edit ) ) {
UM()->fields()->add_hidden_field( 'profile_photo' );
if ( ! um_profile( 'profile_photo' ) ) { // has profile photo
$items = array(
'<a href="javascript:void(0);" class="um-manual-trigger" data-parent=".um-profile-photo" data-child=".um-btn-auto-width" data-alt_text="' . esc_attr__( 'Change photo', 'ultimate-member' ) . '">' . esc_html__( 'Upload photo', 'ultimate-member' ) . '</a>',
'<a href="javascript:void(0);" class="um-reset-profile-photo" data-user_id="' . esc_attr( um_profile_id() ) . '" data-default_src="' . esc_url( um_get_default_avatar_uri() ) . '" style="display:none;">' . esc_html__( 'Remove photo', 'ultimate-member' ) . '</a>',
'<a href="javascript:void(0);" class="um-dropdown-hide">' . esc_html__( 'Cancel', 'ultimate-member' ) . '</a>',
);
/**
* UM hook
*
* @type filter
* @title um_user_photo_menu_view
* @description Change user photo on menu view
* @input_vars
* [{"var":"$items","type":"array","desc":"User Photos"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_user_photo_menu_view', 'function_name', 10, 1 ); ?>
* @example
* <?php
* add_filter( 'um_user_photo_menu_view', 'my_user_photo_menu_view', 10, 1 );
* function my_user_photo_menu_view( $items ) {
* // your code here
* return $items;
* }
* ?>
*/
$items = apply_filters( 'um_user_photo_menu_view', $items );
UM()->profile()->new_ui( 'bc', 'div.um-profile-photo', 'click', $items );
} elseif ( true === UM()->fields()->editing ) {
$items = array(
'<a href="javascript:void(0);" class="um-manual-trigger" data-parent=".um-profile-photo" data-child=".um-btn-auto-width" data-alt_text="' . esc_attr__( 'Upload photo', 'ultimate-member' ) . '">' . esc_html__( 'Change photo', 'ultimate-member' ) . '</a>',
'<a href="javascript:void(0);" class="um-reset-profile-photo um-is-visible" data-user_id="' . esc_attr( um_profile_id() ) . '" data-default_src="' . esc_url( um_get_default_avatar_uri() ) . '">' . esc_html__( 'Remove photo', 'ultimate-member' ) . '</a>',
'<a href="javascript:void(0);" class="um-dropdown-hide">' . esc_html__( 'Cancel', 'ultimate-member' ) . '</a>',
);
/**
* UM hook
*
* @type filter
* @title um_user_photo_menu_edit
* @description Change user photo on menu edit
* @input_vars
* [{"var":"$items","type":"array","desc":"User Photos"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_user_photo_menu_edit', 'function_name', 10, 1 ); ?>
* @example
* <?php
* add_filter( 'um_user_photo_menu_edit', 'my_user_photo_menu_edit', 10, 1 );
* function my_user_photo_menu_edit( $items ) {
* // your code here
* return $items;
* }
* ?>
*/
$items = apply_filters( 'um_user_photo_menu_edit', $items );
UM()->profile()->new_ui( 'bc', 'div.um-profile-photo', 'click', $items );
}
} ?>
</div>
<div class="um-profile-meta">
<?php
/**
* UM hook
*
* @type action
* @title um_before_profile_main_meta
* @description Insert before profile main meta block
* @input_vars
* [{"var":"$args","type":"array","desc":"Form Arguments"}]
* @change_log
* ["Since: 2.0.1"]
* @usage add_action( 'um_before_profile_main_meta', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_before_profile_main_meta', 'my_before_profile_main_meta', 10, 1 );
* function my_before_profile_main_meta( $args ) {
* // your code here
* }
* ?>
*/
do_action( 'um_before_profile_main_meta', $args ); ?>
<div class="um-main-meta">
<?php if ( $args['show_name'] ) { ?>
<div class="um-name">
<a href="<?php echo esc_url( um_user_profile_url() ); ?>"
title="<?php echo esc_attr( um_user( 'display_name' ) ); ?>"><?php echo um_user( 'display_name', 'html' ); ?></a>
<?php
/**
* UM hook
*
* @type action
* @title um_after_profile_name_inline
* @description Insert after profile name some content
* @input_vars
* [{"var":"$args","type":"array","desc":"Form Arguments"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_after_profile_name_inline', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_after_profile_name_inline', 'my_after_profile_name_inline', 10, 1 );
* function my_after_profile_name_inline( $args ) {
* // your code here
* }
* ?>
*/
do_action( 'um_after_profile_name_inline', $args, um_user( 'ID' ) );
?>
</div>
<?php } ?>
<div class="um-clear"></div>
<?php
/**
* UM hook
*
* @type action
* @title um_after_profile_header_name_args
* @description Insert after profile header name some content
* @input_vars
* [{"var":"$args","type":"array","desc":"Form Arguments"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_after_profile_header_name_args', 'function_name', 10, 1 );
* @example
* <?php
* add_action( 'um_after_profile_header_name_args', 'my_after_profile_header_name_args', 10, 1 );
* function my_after_profile_header_name_args( $args ) {
* // your code here
* }
* ?>
*/
do_action( 'um_after_profile_header_name_args', $args, um_user( 'ID' ) );
/**
* UM hook
*
* @type action
* @title um_after_profile_name_inline
* @description Insert after profile name some content
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_after_profile_name_inline', 'function_name', 10 );
* @example
* <?php
* add_action( 'um_after_profile_name_inline', 'my_after_profile_name_inline', 10 );
* function my_after_profile_name_inline() {
* // your code here
* }
* ?>
*/
do_action( 'um_after_profile_header_name' ); ?>
</div>
<?php if ( ! empty( $args['metafields'] ) ) { ?>
<div class="um-meta">
<?php echo UM()->profile()->show_meta( $args['metafields'], $args ); ?>
</div>
<?php
}
$show_bio = false;
$bio_html = false;
$global_setting = UM()->options()->get( 'profile_show_html_bio' );
if ( ! empty( $args['use_custom_settings'] ) ) {
if ( ! empty( $args['show_bio'] ) ) {
$show_bio = true;
$bio_html = ! empty( $global_setting );
}
} else {
$global_show_bio = UM()->options()->get( 'profile_show_bio' );
if ( ! empty( $global_show_bio ) ) {
$show_bio = true;
$bio_html = ! empty( $global_setting );
}
}
if ( $show_bio ) {
$description_key = UM()->profile()->get_show_bio_key( $args );
if ( true === UM()->fields()->viewing && um_user( $description_key ) ) {
?>
<div class="um-meta-text">
<?php
$description = get_user_meta( um_user( 'ID' ), $description_key, true );
if ( $bio_html ) {
echo wp_kses_post( nl2br( make_clickable( wpautop( $description ) ) ) );
} else {
echo nl2br( esc_html( $description ) );
}
?>
</div>
<?php
} elseif ( true === UM()->fields()->editing ) {
if ( ! empty( $args['custom_fields'][ $description_key ] ) ) {
if ( ! empty( $args['custom_fields'][ $description_key ]['html'] ) && $bio_html ) {
$description_value = UM()->fields()->field_value( $description_key );
} else {
$description_value = wp_strip_all_tags( UM()->fields()->field_value( $description_key ) );
}
} else {
if ( $bio_html ) {
$description_value = UM()->fields()->field_value( $description_key );
} else {
$description_value = wp_strip_all_tags( UM()->fields()->field_value( $description_key ) );
}
}
if ( ! empty( $args['custom_fields'][ $description_key ]['max_chars'] ) ) {
$limit = $args['custom_fields'][ $description_key ]['max_chars'];
} else {
$limit = UM()->options()->get( 'profile_bio_maxchars' );
}
?>
<div class="um-meta-text">
<textarea id="um-meta-bio" data-html="<?php echo esc_attr( $bio_html ); ?>"
data-character-limit="<?php echo esc_attr( $limit ); ?>"
placeholder="<?php esc_attr_e( 'Tell us a bit about yourself...', 'ultimate-member' ); ?>"
name="<?php echo esc_attr( $description_key ); ?>" <?php echo wp_kses( UM()->fields()->aria_valid_attributes( UM()->fields()->is_error( $description_key ), 'um-meta-bio' ), UM()->get_allowed_html( 'templates' ) ); ?>><?php echo esc_textarea( $description_value ); ?></textarea>
<span class="um-meta-bio-character um-right">
<span class="um-bio-limit"><?php echo esc_html( $limit ); ?></span>
</span>
<?php
if ( UM()->fields()->is_error( $description_key ) ) {
echo wp_kses( UM()->fields()->field_error( UM()->fields()->show_error( $description_key ), 'um-meta-bio', true ), UM()->get_allowed_html( 'templates' ) );
}
?>
</div>
<?php
}
}
?>
<div class="um-profile-status <?php echo esc_attr( UM()->common()->users()->get_status( um_user( 'ID' ) ) ); ?>">
<span>
<?php
// translators: %s: profile status.
echo esc_html( sprintf( __( 'This user account status is %s', 'ultimate-member' ), UM()->common()->users()->get_status( um_user( 'ID' ), 'formatted' ) ) );
?>
</span>
</div>
<?php
/**
* UM hook
*
* @type action
* @title um_after_header_meta
* @description Insert after header meta some content
* @input_vars
* [{"var":"$user_id","type":"int","desc":"User ID"},
* {"var":"$args","type":"array","desc":"Form Arguments"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_after_header_meta', 'function_name', 10, 2 );
* @example
* <?php
* add_action( 'um_after_header_meta', 'my_after_header_meta', 10, 2 );
* function my_after_header_meta( $user_id, $args ) {
* // your code here
* }
* ?>
*/
do_action( 'um_after_header_meta', um_user( 'ID' ), $args );
?>
</div>
<div class="um-clear"></div>
<?php
if ( UM()->fields()->is_error( 'profile_photo' ) ) {
echo wp_kses( UM()->fields()->field_error( UM()->fields()->show_error( 'profile_photo' ), 'profile_photo', true ), UM()->get_allowed_html( 'templates' ) );
}
/**
* UM hook
*
* @type action
* @title um_after_header_info
* @description Insert after header info some content
* @input_vars
* [{"var":"$user_id","type":"int","desc":"User ID"},
* {"var":"$args","type":"array","desc":"Form Arguments"}]
* @change_log
* ["Since: 2.0"]
* @usage add_action( 'um_after_header_info', 'function_name', 10, 2 );
* @example
* <?php
* add_action( 'um_after_header_info', 'my_after_header_info', 10, 2 );
* function my_after_header_info( $user_id, $args ) {
* // your code here
* }
* ?>
*/
do_action( 'um_after_header_info', um_user( 'ID' ), $args ); ?>
</div>
<?php
}
add_action( 'um_profile_header', 'um_profile_header', 9 );
/**
* Adds profile permissions to view/edit.
*
* @param array $args
*/
function um_pre_profile_shortcode( $args ) {
// It handles only UM Profile forms.
if ( ! array_key_exists( 'mode', $args ) || 'profile' !== $args['mode'] ) {
return;
}
// disable for the REST API requests.
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
return;
}
if ( true === UM()->fields()->editing ) {
if ( um_get_requested_user() ) {
if ( ! UM()->roles()->um_current_user_can( 'edit', um_get_requested_user() ) ) {
um_redirect_home( um_get_requested_user(), um_is_myprofile() );
}
um_fetch_user( um_get_requested_user() );
}
} else {
UM()->fields()->viewing = true;
if ( um_get_requested_user() ) {
if ( ! um_is_myprofile() && ! um_can_view_profile( um_get_requested_user() ) ) {
um_redirect_home( um_get_requested_user(), um_is_myprofile() );
}
if ( ! UM()->roles()->um_current_user_can( 'edit', um_get_requested_user() ) ) {
UM()->user()->cannot_edit = 1;
}
um_fetch_user( um_get_requested_user() );
} else {
if ( ! is_user_logged_in() ) {
um_redirect_home( um_get_requested_user(), um_is_myprofile() );
}
if ( ! um_user( 'can_edit_profile' ) ) {
UM()->user()->cannot_edit = 1;
}
}
}
UM()->fields()->set_mode = 'profile';
}
add_action( 'um_pre_profile_shortcode', 'um_pre_profile_shortcode' );
/**
* Display the edit profile icon
*
* @param $args
*/
function um_add_edit_icon( $args ) {
if ( ! is_user_logged_in() ) {
// not allowed for guests
return;
}
// do not proceed if user cannot edit
if ( true === UM()->fields()->editing ) { ?>
<div class="um-profile-edit um-profile-headericon">
<a href="javascript:void(0);" class="um-profile-edit-a um-profile-save"><i class="um-faicon-check"></i></a>
</div>
<?php return;
}
if ( ! um_is_myprofile() ) {
if ( ! UM()->roles()->um_current_user_can( 'edit', um_profile_id() ) && ! UM()->roles()->um_current_user_can( 'delete', um_profile_id() ) ) {
return;
}
$items = UM()->user()->get_admin_actions();
if ( UM()->roles()->um_current_user_can( 'edit', um_profile_id() ) ) {
$items['editprofile'] = '<a href="' . esc_url( um_edit_profile_url() ) . '" class="real_url">' . __( 'Edit Profile', 'ultimate-member' ) . '</a>';
}
/**
* UM hook
*
* @type filter
* @title um_profile_edit_menu_items
* @description Edit menu items on profile page
* @input_vars
* [{"var":"$items","type":"array","desc":"User Menu"},
* {"var":"$user_id","type":"int","desc":"Profile ID"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_profile_edit_menu_items', 'function_name', 10, 2 ); ?>
* @example
* <?php
* add_filter( 'um_profile_edit_menu_items', 'my_profile_edit_menu_items', 10, 2 );
* function my_profile_edit_menu_items( $items, $user_id ) {
* // your code here
* return $items;
* }
* ?>
*/
$items = apply_filters( 'um_profile_edit_menu_items', $items, um_profile_id() );
$items['cancel'] = '<a href="javascript:void(0);" class="um-dropdown-hide">' . __( 'Cancel', 'ultimate-member' ) . '</a>';
} else {
$items = array(
'editprofile' => '<a href="' . esc_url( um_edit_profile_url() ) . '" class="real_url">' . __( 'Edit Profile', 'ultimate-member' ) . '</a>',
'myaccount' => '<a href="' . esc_url( um_get_core_page( 'account' ) ) . '" class="real_url">' . __( 'My Account', 'ultimate-member' ) . '</a>',
'logout' => '<a href="' . esc_url( um_get_core_page( 'logout' ) ) . '" class="real_url">' . __( 'Logout', 'ultimate-member' ) . '</a>',
'cancel' => '<a href="javascript:void(0);" class="um-dropdown-hide">' . __( 'Cancel', 'ultimate-member' ) . '</a>',
);
if ( ! empty( UM()->user()->cannot_edit ) ) {
unset( $items['editprofile'] );
}
/**
* UM hook
*
* @type filter
* @title um_myprofile_edit_menu_items
* @description Edit menu items on my profile page
* @input_vars
* [{"var":"$items","type":"array","desc":"User Menu"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_myprofile_edit_menu_items', 'function_name', 10, 1 ); ?>
* @example
* <?php
* add_filter( 'um_myprofile_edit_menu_items', 'my_myprofile_edit_menu_items', 10, 1 );
* function my_myprofile_edit_menu_items( $items ) {
* // your code here
* return $items;
* }
* ?>
*/
$items = apply_filters( 'um_myprofile_edit_menu_items', $items );
} ?>
<div class="um-profile-edit um-profile-headericon">
<a href="javascript:void(0);" class="um-profile-edit-a"><i class="um-faicon-cog"></i></a>
<?php UM()->profile()->new_ui( $args['header_menu'], 'div.um-profile-edit', 'click', $items ); ?>
</div>
<?php
}
add_action( 'um_pre_header_editprofile', 'um_add_edit_icon' );
/**
* Show Fields
*
* @param $args
*/
function um_add_profile_fields( $args ) {
if ( true === UM()->fields()->editing ) {
echo UM()->fields()->display( 'profile', $args );
} else {
UM()->fields()->viewing = true;
echo UM()->fields()->display_view( 'profile', $args );
}
}
add_action( 'um_main_profile_fields', 'um_add_profile_fields', 100 );
/**
* Form processing
*
* @param array $args
* @param array $form_data
*/
function um_submit_form_profile( $args, $form_data ) {
if ( isset( UM()->form()->errors ) ) {
return;
}
UM()->fields()->set_mode = 'profile';
UM()->fields()->editing = true;
if ( ! empty( $args['submitted'] ) ) {
$args['submitted'] = UM()->form()->clean_submitted_data( $args['submitted'] );
}
/**
* Fires on successful submit profile form.
*
* Internal Ultimate Member callbacks (Priority -> Callback name -> Excerpt):
* * 10 - `um_user_edit_profile()` Profile form main handler.
*
* @since 1.3.x
* @hook um_user_edit_profile
*
* @param {array} $post $_POST Submission array.
* @param {array} $form_data UM form data. Since 2.6.7
*
* @example <caption>Make any custom action on successful submit profile form.</caption>
* function my_user_edit_profile( $post, $form_data ) {
* // your code here
* }
* // Don't use priority >= 10 because there is native Ultimate Member handler on it.
* add_action( 'um_user_edit_profile', 'my_user_edit_profile', 9, 2 );
*/
do_action( 'um_user_edit_profile', $args, $form_data );
}
add_action( 'um_submit_form_profile', 'um_submit_form_profile', 10, 2 );
/**
* Show the submit button (highest priority)
*
* @param $args
*/
function um_add_submit_button_to_profile( $args ) {
// DO NOT add when reviewing user's details
if ( UM()->user()->preview == true && is_admin() ) {
return;
}
// only when editing
if ( false === UM()->fields()->editing ) {
return;
}
if ( ! isset( $args['primary_btn_word'] ) || $args['primary_btn_word'] == '' ){
$args['primary_btn_word'] = UM()->options()->get( 'profile_primary_btn_word' );
}
if ( ! isset( $args['secondary_btn_word'] ) || $args['secondary_btn_word'] == '' ){
$args['secondary_btn_word'] = UM()->options()->get( 'profile_secondary_btn_word' );
} ?>
<div class="um-col-alt">
<?php if ( ! empty( $args['secondary_btn'] ) ) { ?>
<div class="um-left um-half">
<input type="submit" value="<?php esc_attr_e( wp_unslash( $args['primary_btn_word'] ), 'ultimate-member' ); ?>" class="um-button" />
</div>
<div class="um-right um-half">
<a href="<?php echo esc_url( um_edit_my_profile_cancel_uri() ); ?>" class="um-button um-alt">
<?php _e( wp_unslash( $args['secondary_btn_word'] ), 'ultimate-member' ); ?>
</a>
</div>
<?php } else { ?>
<div class="um-center">
<input type="submit" value="<?php esc_attr_e( wp_unslash( $args['primary_btn_word'] ), 'ultimate-member' ); ?>" class="um-button" />
</div>
<?php } ?>
<div class="um-clear"></div>
</div>
<?php
}
add_action( 'um_after_profile_fields', 'um_add_submit_button_to_profile', 1000 );
/**
* Display the available profile tabs
*
* @param array $args
*/
function um_profile_menu( $args ) {
if ( ! UM()->options()->get( 'profile_menu' ) ) {
return;
}
// get active tabs
$tabs = UM()->profile()->tabs_active();
$all_tabs = $tabs;
$tabs = array_filter( $tabs, function( $item ) {
if ( ! empty( $item['hidden'] ) ) {
return false;
}
return true;
});
$active_tab = UM()->profile()->active_tab();
//check here tabs with hidden also, to make correct check of active tab
if ( ! isset( $all_tabs[ $active_tab ] ) || um_is_on_edit_profile() ) {
$active_tab = 'main';
UM()->profile()->active_tab = $active_tab;
UM()->profile()->active_subnav = null;
}
$has_subnav = false;
if ( count( $tabs ) == 1 ) {
foreach ( $tabs as $tab ) {
if ( isset( $tab['subnav'] ) ) {
$has_subnav = true;
}
}
}
// need enough tabs to continue
if ( count( $tabs ) <= 1 && ! $has_subnav && count( $all_tabs ) === count( $tabs ) ) {
return;
}
if ( count( $tabs ) > 1 || count( $all_tabs ) > count( $tabs ) ) {
// Move default tab priority
$default_tab = UM()->options()->get( 'profile_menu_default_tab' );
$dtab = ( isset( $tabs[ $default_tab ] ) ) ? $tabs[ $default_tab ] : 'main';
if ( isset( $tabs[ $default_tab ] ) ) {
unset( $tabs[ $default_tab ] );
$dtabs[ $default_tab ] = $dtab;
$tabs = $dtabs + $tabs;
}
if ( ! empty( $tabs ) ) { ?>
<div class="um-profile-nav">
<?php foreach ( $tabs as $id => $tab ) {
$nav_link = UM()->permalinks()->get_current_url( UM()->is_permalinks );
$nav_link = remove_query_arg( 'um_action', $nav_link );
$nav_link = remove_query_arg( 'subnav', $nav_link );
$nav_link = add_query_arg( 'profiletab', $id, $nav_link );
/**
* UM hook
*
* @type filter
* @title um_profile_menu_link_{$id}
* @description Change profile menu link by tab $id
* @input_vars
* [{"var":"$nav_link","type":"string","desc":"Profile Tab Link"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_profile_menu_link_{$id}', 'function_name', 10, 1 ); ?>
* @example
* <?php
* add_filter( 'um_profile_menu_link_{$id}', 'my_profile_menu_link', 10, 1 );
* function my_profile_menu_link( $nav_link ) {
* // your code here
* return $nav_link;
* }
* ?>
*/
$nav_link = apply_filters( "um_profile_menu_link_{$id}", $nav_link );
/**
* Filters a profile menu navigation links' tag attributes.
*
* @since 2.6.3
* @hook um_profile_menu_link_{$id}_attrs
*
* @param {string} $profile_nav_attrs Link's tag attributes.
* @param {array} $args Profile form arguments.
*
* @return {string} Link's tag attributes.
*
* @example <caption>Add a link's tag attributes.</caption>
* function um_profile_menu_link_attrs( $profile_nav_attrs ) {
* // your code here
* return $profile_nav_attrs;
* }
* add_filter( 'um_profile_menu_link_{$id}_attrs', 'um_profile_menu_link_attrs', 10, 1 );
*/
$profile_nav_attrs = apply_filters( "um_profile_menu_link_{$id}_attrs", '', $args );
$profile_nav_class = '';
if ( ! UM()->options()->get( 'profile_menu_icons' ) ) {
$profile_nav_class .= ' without-icon';
}
if ( $id == $active_tab ) {
$profile_nav_class .= ' active';
} ?>
<div class="um-profile-nav-item um-profile-nav-<?php echo esc_attr( $id . ' ' . $profile_nav_class ); ?>">
<?php if ( UM()->options()->get( 'profile_menu_icons' ) ) { ?>
<a href="<?php echo esc_url( $nav_link ); ?>" class="uimob800-show uimob500-show uimob340-show um-tip-n"
title="<?php echo esc_attr( $tab['name'] ); ?>" original-title="<?php echo esc_attr( $tab['name'] ); ?>" <?php echo esc_attr( $profile_nav_attrs ); ?>>
<i class="<?php echo esc_attr( $tab['icon'] ); ?>"></i>
<?php if ( isset( $tab['notifier'] ) && $tab['notifier'] > 0 ) { ?>
<span class="um-tab-notifier uimob800-show uimob500-show uimob340-show"><?php echo $tab['notifier']; ?></span>
<?php } ?>
<span class="uimob800-hide uimob500-hide uimob340-hide title"><?php echo esc_html( $tab['name'] ); ?></span>
</a>
<a href="<?php echo esc_url( $nav_link ); ?>" class="uimob800-hide uimob500-hide uimob340-hide"
title="<?php echo esc_attr( $tab['name'] ); ?>" <?php echo esc_attr( $profile_nav_attrs ); ?>>
<i class="<?php echo esc_attr( $tab['icon'] ); ?>"></i>
<?php if ( isset( $tab['notifier'] ) && $tab['notifier'] > 0 ) { ?>
<span class="um-tab-notifier"><?php echo $tab['notifier']; ?></span>
<?php } ?>
<span class="title"><?php echo esc_html( $tab['name'] ); ?></span>
</a>
<?php } else { ?>
<a href="<?php echo esc_url( $nav_link ); ?>" class="uimob800-show uimob500-show uimob340-show um-tip-n"
title="<?php echo esc_attr( $tab['name'] ); ?>" original-title="<?php echo esc_attr( $tab['name'] ); ?>" <?php echo esc_attr( $profile_nav_attrs ); ?>>
<i class="<?php echo esc_attr( $tab['icon'] ); ?>"></i>
<?php if ( isset( $tab['notifier'] ) && $tab['notifier'] > 0 ) { ?>
<span class="um-tab-notifier uimob800-show uimob500-show uimob340-show"><?php echo $tab['notifier']; ?></span>
<?php } ?>
</a>
<a href="<?php echo esc_url( $nav_link ); ?>" class="uimob800-hide uimob500-hide uimob340-hide"
title="<?php echo esc_attr( $tab['name'] ); ?>" <?php echo esc_attr( $profile_nav_attrs ); ?>>
<?php if ( isset( $tab['notifier'] ) && $tab['notifier'] > 0 ) { ?>
<span class="um-tab-notifier"><?php echo $tab['notifier']; ?></span>
<?php } ?>
<span class="title"><?php echo esc_html( $tab['name'] ); ?></span>
</a>
<?php } ?>
</div>
<?php } ?>
<div class="um-clear"></div>
</div>
<?php }
}
foreach ( $tabs as $id => $tab ) {
if ( isset( $tab['subnav'] ) && $active_tab == $id ) {
$active_subnav = ( UM()->profile()->active_subnav() ) ? UM()->profile()->active_subnav() : $tab['subnav_default']; ?>
<div class="um-profile-subnav">
<?php foreach ( $tab['subnav'] as $id_s => $subtab ) {
$subnav_link = add_query_arg( 'subnav', $id_s );
$subnav_link = apply_filters( 'um_user_profile_subnav_link', $subnav_link, $id_s, $subtab ); ?>
<a href="<?php echo esc_url( $subnav_link ); ?>" class="<?php echo $active_subnav == $id_s ? 'active' : ''; ?>">
<?php echo $subtab; ?>
</a>
<?php } ?>
</div>
<?php }
}
}
add_action( 'um_profile_menu', 'um_profile_menu', 9 );